MADARA  3.4.1
FragmentsToFilesFilter.cpp
Go to the documentation of this file.
1 
3 
4 #include <string>
5 #include <vector>
13 
14 namespace madara
15 {
16 namespace filters
17 {
20 {
21  std::string last_file;
22  std::string str_crc;
23  uint32_t last_crc = 0;
24  int64_t last_size = 0;
25  std::string last_file_path;
26 
27  // because of the usage of erase, don't auto inc record in for loop
28  for (auto record = records.begin(); record != records.end();)
29  {
30  bool is_fragment = false;
31  std::string path;
32  std::string prefix;
33  std::string filename;
34 
35  // if the file is malicious, pretend it doesn't exist
36  if (utility::filename_has_redirect(record->first))
37  {
40  "FragmentsToFilesFilter::filter: "
41  "WARNING: record %s has abnormal name. Skipping.\n",
42  record->first.c_str())
43 
44  continue;
45  }
46 
47  if (record->second.is_binary_file_type())
48  {
49  // try to find an appropriate mapping for the record
50  for (auto map : map_)
51  {
52  if (utility::begins_with(record->first, map.first))
53  {
54  prefix = map.first;
55  path = map.second;
56  std::string number =
57  record->first.substr(record->first.find_last_of('.') + 1);
58  std::string base_name = record->first.substr(prefix.size() + 1);
59  base_name.erase(base_name.find_last_of('.'));
60  base_name.erase(base_name.find_last_of('.'));
61  std::size_t last_period = record->first.find_last_of('.');
62 
63  // 1 thing missing: we need to remove contents from filename
64  // utility::string_replace (base_name, ".contents", "");
65 
66  filename = path + "/" + base_name + ".";
67  filename += number;
68  // base_name.erase (
69  // (base_name.find_last_of ('.'),
70  // base_name.find_last_of ('.') - 1));
71 
72  if (last_file == "" || last_file.compare(0, last_file.size(),
73  record->first.substr(0, last_period)) != 0)
74  {
75  if (last_file_path != "")
76  {
78  last_file_path, last_crc, true, false))
79  {
82  "FragmentsToFilesFilter::filter: "
83  "SUCCESS: file %s is recreated\n",
84  last_file_path.c_str())
85  }
86  else
87  {
90  "FragmentsToFilesFilter::filter: "
91  "FAIL: file %s is incomplete\n",
92  last_file_path.c_str())
93  }
94  }
95 
96  // setup the next file
97  last_file_path = path + "/" +
98  record->first.substr(prefix.size() + 1,
99  last_period - prefix.size() - 1 - 9);
100  last_file = prefix + "." + base_name;
101  auto crc_record = records.find(last_file + ".crc");
102  auto size_record = records.find(last_file + ".size");
103 
104  if (crc_record != records.end())
105  {
106  last_crc = (uint32_t)crc_record->second.to_integer();
107  str_crc = crc_record->second.to_string();
108  } // end if crc record exists in the incoming records
109 
110  if (size_record != records.end())
111  {
112  last_size = size_record->second.to_integer();
113  } // end if size exists in the incoming records
114  } // if we need to set a new crc and last record
115 
116  if (str_crc != "")
117  {
118  filename += "." + str_crc + ".frag";
119  is_fragment = true;
120 
121  // create directory that file needs to exist in
122  std::string directory = utility::extract_path(filename);
123 
124  utility::recursive_mkdir(directory);
125 
126  record->second.to_file(filename);
127 
130  "FragmentsToFilesFilter::filter: "
131  "found fragment %s:\n"
132  " base_name=%s\n"
133  " last_file=%s\n"
134  " last_file_path=%s\n"
135  " str_crc=%s\n"
136  " last_size=%" PRId64 "\n"
137  " saved to %s\n",
138  record->first.c_str(), base_name.c_str(), last_file.c_str(),
139  last_file_path.c_str(), str_crc.c_str(), last_size,
140  filename.c_str())
141  } // end if str_crc is not null
142  else
143  {
146  "FragmentsToFilesFilter::filter: "
147  "not fragment %s:\n"
148  " base_name=%s\n"
149  " last_file=%s\n"
150  " last_file_path=%s\n"
151  " str_crc=%s\n"
152  " last_size=%" PRId64 "\n"
153  " saved to %s\n",
154  record->first.c_str(), base_name.c_str(), last_file.c_str(),
155  last_file_path.c_str(), str_crc.c_str(), last_size,
156  filename.c_str())
157  }
158  } // end if begins with a prefix mapping to directory
159  else
160  {
163  "FragmentsToFilesFilter::filter: "
164  "%s is not a fragment of %s\n",
165  record->first.c_str(), map.first.c_str())
166  } // end does not begin with a known prefix
167  } // end iteration over directory mappings
168  }
169 
170  // if this is a fragment, check for delection
171  if (is_fragment && clear_fragments_)
172  {
175  "FragmentsToFilesFilter::filter: "
176  "removing variable %s\n",
177  record->first.c_str())
178 
179  record = records.erase(record);
180  } // end if is fragment and clear fragments enabled
181  else
182  {
185  "FragmentsToFilesFilter::filter: "
186  "%s is not being deleted\n",
187  record->first.c_str())++ record;
188  } // end no clear fragments needed
189  } // end iteration over incoming records
190 
191  if (last_file_path != "")
192  {
193  if (utility::file_from_fragments(last_file_path, last_crc, true, false))
194  {
197  "FragmentsToFilesFilter::filter: "
198  "SUCCESS: file %s is recreated\n",
199  last_file_path.c_str())
200  }
201  else
202  {
205  "FragmentsToFilesFilter::filter: "
206  "FAIL: file %s is incomplete\n",
207  last_file_path.c_str())
208  }
209  }
210 } // end filter method
211 
212 } // end filters namespace
213 } // end madara namespace
#define madara_logger_ptr_log(loggering, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:41
std::map< std::string, std::string > map_
map of variable prefixes to directories
bool clear_fragments_
if true, clear fragments after sent to file
virtual MADARA_EXPORT void filter(knowledge::KnowledgeMap &records, const transport::TransportContext &, knowledge::Variables &)
Filters the fragments and converts them to files.
Provides an interface for external functions into the MADARA KaRL variable settings.
Definition: Variables.h:53
Provides context about the transport.
constexpr string_t string
T get(const KnowledgeRecord &kr)
Get the value of a KnowlegeRecord.
Definition: GetRecord.h:121
::std::map< std::string, KnowledgeRecord > KnowledgeMap
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
MADARA_EXPORT bool file_from_fragments(const std::string &filename, uint32_t crc, bool delete_incomplete=true, bool delete_fragments=true)
Builds a file from fragments that have the format: filename.
Definition: Utility.inl:466
bool recursive_mkdir(const std::string &path)
Definition: Utility.inl:336
MADARA_EXPORT std::string extract_path(const std::string &name)
Extracts the path of a filename.
Definition: Utility.inl:374
MADARA_EXPORT bool begins_with(const std::string &input, const std::string &prefix)
Check if input contains prefix at the beginning.
Definition: Utility.inl:638
MADARA_EXPORT bool filename_has_redirect(const std::string &filename)
Checks the filename for abnormal redirects such as "..".
Definition: Utility.inl:445
Copyright(c) 2020 Galois.