resetting manifest requested domain to floor
[platform/upstream/ccache.git] / hash.c
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 hash_start(struct mdfour *md)
26 {
27         mdfour_begin(md);
28 }
29
30 void
31 hash_buffer(struct mdfour *md, const void *s, size_t len)
32 {
33         mdfour_update(md, (unsigned char *)s, len);
34 }
35
36 /* Return the hash result as a hex string. Caller frees. */
37 char *
38 hash_result(struct mdfour *md)
39 {
40         unsigned char sum[16];
41
42         hash_result_as_bytes(md, sum);
43         return format_hash_as_string(sum, (unsigned) md->totalN);
44 }
45
46 /* return the hash result as 16 binary bytes */
47 void
48 hash_result_as_bytes(struct mdfour *md, unsigned char *out)
49 {
50         hash_buffer(md, NULL, 0);
51         mdfour_result(md, out);
52 }
53
54 bool
55 hash_equal(struct mdfour *md1, struct mdfour *md2)
56 {
57         unsigned char sum1[16], sum2[16];
58         hash_result_as_bytes(md1, sum1);
59         hash_result_as_bytes(md2, sum2);
60         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 hash_delimiter(struct mdfour *md, const char *type)
75 {
76         hash_buffer(md, HASH_DELIMITER, sizeof(HASH_DELIMITER));
77         hash_buffer(md, type, strlen(type) + 1); /* Include NUL. */
78 }
79
80 void
81 hash_string(struct mdfour *md, const char *s)
82 {
83         hash_buffer(md, s, strlen(s));
84 }
85
86 void
87 hash_int(struct mdfour *md, int x)
88 {
89         hash_buffer(md, (char *)&x, sizeof(x));
90 }
91
92 /*
93  * Add contents of an open file to the hash. Returns true on success, otherwise
94  * false.
95  */
96 bool
97 hash_fd(struct mdfour *md, int fd)
98 {
99         char buf[16384];
100         ssize_t n;
101
102         while ((n = read(fd, buf, sizeof(buf))) != 0) {
103                 if (n == -1 && errno != EINTR) {
104                         break;
105                 }
106                 if (n > 0) {
107                         hash_buffer(md, buf, n);
108                 }
109         }
110         return n == 0;
111 }
112
113 /*
114  * Add contents of a file to the hash. Returns true on success, otherwise
115  * false.
116  */
117 bool
118 hash_file(struct mdfour *md, const char *fname)
119 {
120         int fd;
121         bool ret;
122
123         fd = open(fname, O_RDONLY|O_BINARY);
124         if (fd == -1) {
125                 return false;
126         }
127
128         ret = hash_fd(md, fd);
129         close(fd);
130         return ret;
131 }