Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2002 Andrew Tridgell
3 : : * Copyright (C) 2010 Joel Rosdahl
4 : : *
5 : : * This program is free software; you can redistribute it and/or modify it
6 : : * under the terms of the GNU General Public License as published by the Free
7 : : * Software Foundation; either version 3 of the License, or (at your option)
8 : : * any later version.
9 : : *
10 : : * This program is distributed in the hope that it will be useful, but WITHOUT
11 : : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 : : * more details.
14 : : *
15 : : * You should have received a copy of the GNU General Public License along with
16 : : * this program; if not, write to the Free Software Foundation, Inc., 51
17 : : * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 : : */
19 : :
20 : : #include "ccache.h"
21 : :
22 : : #define HASH_DELIMITER "\000cCaChE"
23 : :
24 : : void
25 : 20 : hash_start(struct mdfour *md)
26 : : {
27 : 20 : mdfour_begin(md);
28 : 20 : }
29 : :
30 : : void
31 : 65 : hash_buffer(struct mdfour *md, const void *s, size_t len)
32 : : {
33 : 65 : mdfour_update(md, (unsigned char *)s, len);
34 : 65 : }
35 : :
36 : : /* Return the hash result as a hex string. Caller frees. */
37 : : char *
38 : 6 : hash_result(struct mdfour *md)
39 : : {
40 : : unsigned char sum[16];
41 : :
42 : 6 : hash_result_as_bytes(md, sum);
43 : 6 : return format_hash_as_string(sum, (unsigned) md->totalN);
44 : : }
45 : :
46 : : /* return the hash result as 16 binary bytes */
47 : : void
48 : 19 : hash_result_as_bytes(struct mdfour *md, unsigned char *out)
49 : : {
50 : 19 : hash_buffer(md, NULL, 0);
51 : 19 : mdfour_result(md, out);
52 : 19 : }
53 : :
54 : : bool
55 : 6 : hash_equal(struct mdfour *md1, struct mdfour *md2)
56 : : {
57 : : unsigned char sum1[16], sum2[16];
58 : 6 : hash_result_as_bytes(md1, sum1);
59 : 6 : hash_result_as_bytes(md2, sum2);
60 : 6 : return memcmp(sum1, sum2, sizeof(sum1)) == 0;
61 : : }
62 : :
63 : : /*
64 : : * Hash some data that is unlikely to occur in the input. The idea is twofold:
65 : : *
66 : : * - Delimit things like arguments from each other (e.g., so that -I -O2 and
67 : : * -I-O2 hash differently).
68 : : * - Tag different types of hashed information so that it's possible to do
69 : : * conditional hashing of information in a safe way (e.g., if we want to hash
70 : : * information X if CCACHE_A is set and information Y if CCACHE_B is set,
71 : : * there should never be a hash collision risk).
72 : : */
73 : : void
74 : 6 : hash_delimiter(struct mdfour *md, const char *type)
75 : : {
76 : 6 : hash_buffer(md, HASH_DELIMITER, sizeof(HASH_DELIMITER));
77 : 6 : hash_buffer(md, type, strlen(type) + 1); /* Include NUL. */
78 : 6 : }
79 : :
80 : : void
81 : 13 : hash_string(struct mdfour *md, const char *s)
82 : : {
83 : 13 : hash_string_length(md, s, strlen(s));
84 : 13 : }
85 : :
86 : : void
87 : 13 : hash_string_length(struct mdfour *md, const char *s, int length)
88 : : {
89 : 13 : hash_buffer(md, s, length);
90 : 13 : }
91 : :
92 : : void
93 : 2 : hash_int(struct mdfour *md, int x)
94 : : {
95 : 2 : hash_buffer(md, (char *)&x, sizeof(x));
96 : 2 : }
97 : :
98 : : /*
99 : : * Add contents of an open file to the hash. Returns true on success, otherwise
100 : : * false.
101 : : */
102 : : bool
103 : 16 : hash_fd(struct mdfour *md, int fd)
104 : : {
105 : : char buf[16384];
106 : : ssize_t n;
107 : :
108 [ + + ]: 30 : while ((n = read(fd, buf, sizeof(buf))) != 0) {
109 [ - + ][ # # ]: 14 : if (n == -1 && errno != EINTR) {
110 : 0 : break;
111 : : }
112 [ + - ]: 14 : if (n > 0) {
113 : 14 : hash_buffer(md, buf, n);
114 : : }
115 : : }
116 : 16 : return n == 0;
117 : : }
118 : :
119 : : /*
120 : : * Add contents of a file to the hash. Returns true on success, otherwise
121 : : * false.
122 : : */
123 : : bool
124 : 1 : hash_file(struct mdfour *md, const char *fname)
125 : : {
126 : : int fd;
127 : : bool ret;
128 : :
129 : 1 : fd = open(fname, O_RDONLY|O_BINARY);
130 [ - + ]: 1 : if (fd == -1) {
131 : 0 : cc_log("Failed to open %s: %s", fname, strerror(errno));
132 : 0 : return false;
133 : : }
134 : :
135 : 1 : ret = hash_fd(md, fd);
136 : 1 : close(fd);
137 : 1 : return ret;
138 : : }
|