1 | // Copyright (C) 2005 Nathaniel Smith <njs@pobox.com>␊ |
2 | //␊ |
3 | // This program is made available under the GNU GPL version 2.0 or␊ |
4 | // greater. See the accompanying file COPYING for details.␊ |
5 | //␊ |
6 | // This program is distributed WITHOUT ANY WARRANTY; without even the␊ |
7 | // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR␊ |
8 | // PURPOSE.␊ |
9 | ␊ |
10 | #include "base.hh"␊ |
11 | #include <iterator>␊ |
12 | #include <sstream>␊ |
13 | #include <algorithm>␊ |
14 | #include <iterator>␊ |
15 | ␊ |
16 | #include "inodeprint.hh"␊ |
17 | #include "sanity.hh"␊ |
18 | #include "platform.hh"␊ |
19 | #include "transforms.hh"␊ |
20 | #include "constants.hh"␊ |
21 | #include "basic_io.hh"␊ |
22 | ␊ |
23 | #include "botan/botan.h"␊ |
24 | #include "botan/sha160.h"␊ |
25 | ␊ |
26 | using std::ostream;␊ |
27 | using std::ostringstream;␊ |
28 | using std::string;␊ |
29 | ␊ |
30 | // this file defines the inodeprint_map structure, and some operations on it.␊ |
31 | ␊ |
32 | namespace␊ |
33 | {␊ |
34 | namespace syms␊ |
35 | {␊ |
36 | // roster symbols␊ |
37 | symbol const format_version("format_version");␊ |
38 | symbol const file("file");␊ |
39 | symbol const print("print");␊ |
40 | }␊ |
41 | }␊ |
42 | // reading inodeprint_maps␊ |
43 | ␊ |
44 | void␊ |
45 | read_inodeprint_map(data const & dat,␊ |
46 | inodeprint_map & ipm)␊ |
47 | {␊ |
48 | // don't bomb out if it's just an old-style inodeprints file␊ |
49 | string start = dat().substr(0, syms::format_version().size());␊ |
50 | if (start != syms::format_version())␊ |
51 | {␊ |
52 | L(FL("inodeprints file format is wrong, skipping it"));␊ |
53 | return;␊ |
54 | }␊ |
55 | ␊ |
56 | basic_io::input_source src(dat(), "inodeprint");␊ |
57 | basic_io::tokenizer tok(src);␊ |
58 | basic_io::parser pa(tok);␊ |
59 | ␊ |
60 | {␊ |
61 | pa.esym(syms::format_version);␊ |
62 | string vers;␊ |
63 | pa.str(vers);␊ |
64 | if (vers != "1")␊ |
65 | {␊ |
66 | L(FL("inodeprints file version is unknown, skipping it"));␊ |
67 | return;␊ |
68 | }␊ |
69 | }␊ |
70 | ␊ |
71 | while(pa.symp())␊ |
72 | {␊ |
73 | string path, print;␊ |
74 | ␊ |
75 | pa.esym(syms::file);␊ |
76 | pa.str(path);␊ |
77 | pa.esym(syms::print);␊ |
78 | pa.hex(print);␊ |
79 | ␊ |
80 | ipm.insert(inodeprint_entry(file_path_internal(path),␊ |
81 | hexenc<inodeprint>(print)));␊ |
82 | }␊ |
83 | I(src.lookahead == EOF);␊ |
84 | }␊ |
85 | ␊ |
86 | void␊ |
87 | write_inodeprint_map(inodeprint_map const & ipm,␊ |
88 | data & dat)␊ |
89 | {␊ |
90 | basic_io::printer pr;␊ |
91 | {␊ |
92 | basic_io::stanza st;␊ |
93 | st.push_str_pair(syms::format_version, "1");␊ |
94 | pr.print_stanza(st);␊ |
95 | }␊ |
96 | for (inodeprint_map::const_iterator i = ipm.begin();␊ |
97 | i != ipm.end(); ++i)␊ |
98 | {␊ |
99 | basic_io::stanza st;␊ |
100 | st.push_file_pair(syms::file, i->first);␊ |
101 | st.push_hex_pair(syms::print, hexenc<id>(i->second()));␊ |
102 | pr.print_stanza(st);␊ |
103 | }␊ |
104 | dat = data(pr.buf);␊ |
105 | }␊ |
106 | ␊ |
107 | class my_iprint_calc : public inodeprint_calculator␊ |
108 | {␊ |
109 | std::string res;␊ |
110 | Botan::SHA_160 hash;␊ |
111 | bool too_close;␊ |
112 | void add_item(void *dat, size_t size)␊ |
113 | {␊ |
114 | hash.update(reinterpret_cast<Botan::byte const *>(&size),␊ |
115 | sizeof(size));␊ |
116 | hash.update(reinterpret_cast<Botan::byte const *>(dat),␊ |
117 | size);␊ |
118 | }␊ |
119 | public:␊ |
120 | my_iprint_calc() : too_close(false)␊ |
121 | {}␊ |
122 | std::string str()␊ |
123 | {␊ |
124 | char digest[constants::sha1_digest_length];␊ |
125 | hash.final(reinterpret_cast<Botan::byte *>(digest));␊ |
126 | return std::string(digest, constants::sha1_digest_length);␊ |
127 | }␊ |
128 | void note_nowish(bool n)␊ |
129 | {␊ |
130 | too_close = n;␊ |
131 | }␊ |
132 | void note_future(bool f)␊ |
133 | {␊ |
134 | inodeprint_calculator::add_item(f);␊ |
135 | }␊ |
136 | bool ok()␊ |
137 | {␊ |
138 | return !too_close;␊ |
139 | }␊ |
140 | };␊ |
141 | ␊ |
142 | bool inodeprint_file(file_path const & file, hexenc<inodeprint> & ip)␊ |
143 | {␊ |
144 | my_iprint_calc calc;␊ |
145 | bool ret = inodeprint_file(file.as_external(), calc);␊ |
146 | inodeprint ip_raw(calc.str());␊ |
147 | if (!ret)␊ |
148 | ip_raw = inodeprint("");␊ |
149 | encode_hexenc(ip_raw, ip);␊ |
150 | return ret && calc.ok();␊ |
151 | }␊ |
152 | ␊ |
153 | // Local Variables:␊ |
154 | // mode: C++␊ |
155 | // fill-column: 76␊ |
156 | // c-file-style: "gnu"␊ |
157 | // indent-tabs-mode: nil␊ |
158 | // End:␊ |
159 | // vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:␊ |