IBR-DTNSuite  0.12
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 #ifdef HAVE_OPENSSL
32 #include <openssl/md5.h>
33 #endif
34 
35 #ifdef HAVE_LIBTFFS
36 #include "io/FATFile.h"
37 #endif
38 
39 namespace io
40 {
42  : _file(__copy(file))
43  {
44  update();
45  }
46 
48  {
49  }
50 
52  {
53  return _last_hash;
54  }
55 
57  {
58  return _stable_counter;
59  }
60 
61  ibrcommon::File* ObservedFile::__copy(const ibrcommon::File &file)
62  {
63  // make a copy of the file object
64 #ifdef HAVE_LIBTFFS
65  try {
66  const io::FATFile &f = dynamic_cast<const io::FATFile&>(file);
67  return new io::FATFile(f);
68  } catch (const std::bad_cast&) { };
69 #endif
70 
71  return new ibrcommon::File(file);
72  }
73 
75  {
76  return *_file;
77  }
78 
79  void ObservedFile::findFiles(std::set<ObservedFile> &files) const
80  {
81  if (!getFile().isDirectory()) return;
82 
83 #ifdef HAVE_LIBTFFS
84  try {
85  const io::FATFile &f = dynamic_cast<const io::FATFile&>(*_file);
86 
87  std::list<io::FATFile> filelist;
88  if (f.getFiles(filelist) == 0)
89  {
90  for (std::list<io::FATFile>::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
91  {
92  const io::ObservedFile of(*it);
93 
94  if (of.getFile().isSystem()) continue;
95 
96  if (of.getFile().isDirectory()) of.findFiles(files);
97  else files.insert(of);
98  }
99  }
100 
101  return;
102  } catch (const std::bad_cast&) { };
103 #endif
104 
105  const ibrcommon::File &f = dynamic_cast<const ibrcommon::File&>(*_file);
106 
107  std::list<ibrcommon::File> filelist;
108  if (f.getFiles(filelist) == 0)
109  {
110  for (std::list<ibrcommon::File>::const_iterator it = filelist.begin(); it != filelist.end(); ++it)
111  {
112  const io::ObservedFile of(*it);
113 
114  if (of.getFile().isSystem()) continue;
115 
116  if (of.getFile().isDirectory()) of.findFiles(files);
117  else files.insert(of);
118  }
119  }
120  }
121 
123  {
124  const FileHash latest = __hash();
125 
126  if (_last_hash != latest) {
127  _last_hash = latest;
128  _stable_counter = 0;
129  } else {
130  // protect against overflow
131  if (_stable_counter < std::numeric_limits<size_t>::max()) _stable_counter++;
132  }
133  }
134 
135  bool ObservedFile::operator<(const ObservedFile &other) const
136  {
137  return getFile() < other.getFile();
138  }
139 
140  bool ObservedFile::operator==(const ObservedFile &other) const
141  {
142  return getFile() == other.getFile();
143  }
144 
145  io::FileHash ObservedFile::__hash() const
146  {
147  //update hash
148  std::stringstream ss;
149  ss << _file->lastmodify() << "|" << _file->size() << "|" << _file->getPath();
150  const std::string toHash = ss.str();
151  char hash[MD5_DIGEST_LENGTH];
152  MD5((unsigned char*)toHash.c_str(), toHash.length(), (unsigned char*) hash);
153  return FileHash(_file->getPath(), std::string(hash, MD5_DIGEST_LENGTH));
154  }
155 }