IBR-DTN  1.0.0
ObservedFile.cpp
Go to the documentation of this file.
1 /*
2  * ObservedFile.cpp
3  *
4  * Copyright (C) 2013 IBR, TU Braunschweig
5  *
6  * Written-by: David Goltzsche <goltzsch@ibr.cs.tu-bs.de>
7  * Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  * Created on: Sep 30, 2013
22  */
23 
24 #include "config.h"
25 #include "io/ObservedFile.h"
26 #include <string.h>
27 #include <sstream>
28 #include <typeinfo>
29 #include <limits>
30 
31 #include <ibrcommon/ibrcommon.h>
32 #include <ibrcommon/Logger.h>
33 #ifdef IBRCOMMON_SUPPORT_SSL
34 #include <ibrcommon/ssl/MD5Stream.h>
35 #endif
36 
37 #ifdef HAVE_LIBTFFS
38 #include "io/FATFile.h"
39 #endif
40 
41 namespace io
42 {
43  const std::string ObservedFile::TAG = "ObservedFile";
44 
45  ObservedFile::ObservedFile(const ibrcommon::File &file)
46  : _file(__copy(file))
47  {
48  update();
49  }
50 
52  {
53  }
54 
56  {
57  return _last_hash;
58  }
59 
61  {
62  return _stable_counter;
63  }
64 
65  ibrcommon::File* ObservedFile::__copy(const ibrcommon::File &file)
66  {
67  // make a copy of the file object
68 #ifdef HAVE_LIBTFFS
69  try {
70  const io::FATFile &f = dynamic_cast<const io::FATFile&>(file);
71  return new io::FATFile(f);
72  } catch (const std::bad_cast&) { };
73 #endif
74 
75  return new ibrcommon::File(file);
76  }
77 
78  const ibrcommon::File& ObservedFile::getFile() const
79  {
80  return *_file;
81  }
82 
83  void ObservedFile::findFiles(std::set<ObservedFile> &files) const
84  {
85  if (!getFile().isDirectory()) return;
86 
87 #ifdef HAVE_LIBTFFS
88  try {
89  const io::FATFile &f = dynamic_cast<const io::FATFile&>(*_file);
90 
91  std::list<io::FATFile> filelist;
92  if (f.getFiles(filelist) == 0)
93  {
94  for (std::list<io::FATFile>::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
95  {
96  const io::ObservedFile of(*it);
97 
98  if (of.getFile().isSystem()) continue;
99 
100  if (of.getFile().isDirectory()) of.findFiles(files);
101  else files.insert(of);
102  }
103  }
104 
105  IBRCOMMON_LOGGER_TAG(TAG,notice) << "findFiles returning " << files.size() << " files" << IBRCOMMON_LOGGER_ENDL;
106  return;
107  } catch (const std::bad_cast&) { };
108 #endif
109 
110  const ibrcommon::File &f = dynamic_cast<const ibrcommon::File&>(*_file);
111 
112  std::list<ibrcommon::File> filelist;
113  if (f.getFiles(filelist) == 0)
114  {
115  for (std::list<ibrcommon::File>::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
116  {
117  const io::ObservedFile of(*it);
118 
119  if (of.getFile().isSystem()) continue;
120 
121  if (of.getFile().isDirectory()) of.findFiles(files);
122  else files.insert(of);
123  }
124  }
125  IBRCOMMON_LOGGER_TAG(TAG,notice) << "findFiles returning " << files.size() << " files" << IBRCOMMON_LOGGER_ENDL;
126  }
127 
129  {
130  const FileHash latest = __hash();
131 
132  if (_last_hash != latest) {
133  _last_hash = latest;
134  _stable_counter = 0;
135  } else {
136  // protect against overflow
137  if (_stable_counter < std::numeric_limits<size_t>::max()) _stable_counter++;
138  }
139  }
140 
141  bool ObservedFile::operator<(const ObservedFile &other) const
142  {
143  return getFile() < other.getFile();
144  }
145 
146  bool ObservedFile::operator==(const ObservedFile &other) const
147  {
148  return getFile() == other.getFile();
149  }
150 
151  io::FileHash ObservedFile::__hash() const
152  {
153 #ifdef IBRCOMMON_SUPPORT_SSL
154  IBRCOMMON_LOGGER_TAG(TAG,notice) << "using MD5-algorithm from SSL, inputs:" << "\n"
155  << "\t" << "timestamp: " << _file->lastmodify() << "\n"
156  << "\t" << "filesize : " << _file->size() << "\n"
157  << "\t" << "filepath : " << _file->getPath() << "\n"
158  << IBRCOMMON_LOGGER_ENDL;
159  // update hash
160  ibrcommon::MD5Stream md5;
161  md5 << _file->lastmodify() << "|" << _file->size() << "|" << _file->getPath() << std::flush;
162 
163  const std::string hash = ibrcommon::HashStream::extract(md5);
164 
165  return FileHash(_file->getPath(), hash);
166 #else
167  std::stringstream ss;
168  ss << _file->lastmodify() << "|" << _file->size() << "|" << _file->getPath();
169  IBRCOMMON_LOGGER_TAG(TAG,notice) << "not using MD5-algorithm from SSL, inputs:" << "\n"
170  << "\t" << "timestamp: " << _file->lastmodify() << "\n"
171  << "\t" << "filesize : " << _file->size() << "\n"
172  << "\t" << "filepath : " << _file->getPath() << "\n"
173  << IBRCOMMON_LOGGER_ENDL;
174  return FileHash(_file->getPath(), ss.str());
175 #endif
176 
177  }
178 }
void findFiles(std::set< ObservedFile > &files) const
size_t getStableCounter() const
int getFiles(std::list< FATFile > &files) const
Definition: FATFile.cpp:47
virtual ~ObservedFile()
std::list< io::ObservedFile > filelist
Definition: dtnoutbox.cpp:51
bool operator==(const ObservedFile &other) const
ObservedFile(const ibrcommon::File &file)
const io::FileHash & getHash() const
bool operator<(const ObservedFile &other) const
const ibrcommon::File & getFile() const