aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_hash_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_hash_file.c')
-rw-r--r--src/util/crypto_hash_file.c243
1 files changed, 0 insertions, 243 deletions
diff --git a/src/util/crypto_hash_file.c b/src/util/crypto_hash_file.c
deleted file mode 100644
index 8e46d71fd..000000000
--- a/src/util/crypto_hash_file.c
+++ /dev/null
@@ -1,243 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2001-2013 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19
20 */
21/**
22 * @file util/crypto_hash_file.c
23 * @brief incremental hashing of files
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include <gcrypt.h>
29
30#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-hash-file", \
31 __VA_ARGS__)
32
33#define LOG_STRERROR_FILE(kind, syscall, \
34 filename) GNUNET_log_from_strerror_file (kind, \
35 "util-crypto-hash-file", \
36 syscall, \
37 filename)
38
39
40/**
41 * Context used when hashing a file.
42 */
43struct GNUNET_CRYPTO_FileHashContext
44{
45 /**
46 * Function to call upon completion.
47 */
48 GNUNET_CRYPTO_HashCompletedCallback callback;
49
50 /**
51 * Closure for callback.
52 */
53 void *callback_cls;
54
55 /**
56 * IO buffer.
57 */
58 unsigned char *buffer;
59
60 /**
61 * Name of the file we are hashing.
62 */
63 char *filename;
64
65 /**
66 * File descriptor.
67 */
68 struct GNUNET_DISK_FileHandle *fh;
69
70 /**
71 * Cummulated hash.
72 */
73 gcry_md_hd_t md;
74
75 /**
76 * Size of the file.
77 */
78 uint64_t fsize;
79
80 /**
81 * Current offset.
82 */
83 uint64_t offset;
84
85 /**
86 * Current task for hashing.
87 */
88 struct GNUNET_SCHEDULER_Task *task;
89
90 /**
91 * Priority we use.
92 */
93 enum GNUNET_SCHEDULER_Priority priority;
94
95 /**
96 * Blocksize.
97 */
98 size_t bsize;
99};
100
101
102/**
103 * Report result of hash computation to callback
104 * and free associated resources.
105 */
106static void
107file_hash_finish (struct GNUNET_CRYPTO_FileHashContext *fhc,
108 const struct GNUNET_HashCode *res)
109{
110 fhc->callback (fhc->callback_cls, res);
111 GNUNET_free (fhc->filename);
112 if (! GNUNET_DISK_handle_invalid (fhc->fh))
113 GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fhc->fh));
114 gcry_md_close (fhc->md);
115 GNUNET_free (fhc); /* also frees fhc->buffer */
116}
117
118
119/**
120 * File hashing task.
121 *
122 * @param cls closure
123 */
124static void
125file_hash_task (void *cls)
126{
127 struct GNUNET_CRYPTO_FileHashContext *fhc = cls;
128 struct GNUNET_HashCode *res;
129 size_t delta;
130 ssize_t sret;
131
132 fhc->task = NULL;
133 GNUNET_assert (fhc->offset <= fhc->fsize);
134 delta = fhc->bsize;
135 if (fhc->fsize - fhc->offset < delta)
136 delta = fhc->fsize - fhc->offset;
137 sret = GNUNET_DISK_file_read (fhc->fh,
138 fhc->buffer,
139 delta);
140 if ((sret < 0) ||
141 (delta != (size_t) sret))
142 {
143 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING,
144 "read",
145 fhc->filename);
146 file_hash_finish (fhc,
147 NULL);
148 return;
149 }
150 gcry_md_write (fhc->md,
151 fhc->buffer,
152 delta);
153 fhc->offset += delta;
154 if (fhc->offset == fhc->fsize)
155 {
156 res = (struct GNUNET_HashCode *) gcry_md_read (fhc->md,
157 GCRY_MD_SHA512);
158 file_hash_finish (fhc, res);
159 return;
160 }
161 fhc->task = GNUNET_SCHEDULER_add_with_priority (fhc->priority,
162 &file_hash_task,
163 fhc);
164}
165
166
167/**
168 * Compute the hash of an entire file.
169 *
170 * @param priority scheduling priority to use
171 * @param filename name of file to hash
172 * @param blocksize number of bytes to process in one task
173 * @param callback function to call upon completion
174 * @param callback_cls closure for @a callback
175 * @return NULL on (immediate) error
176 */
177struct GNUNET_CRYPTO_FileHashContext *
178GNUNET_CRYPTO_hash_file (enum GNUNET_SCHEDULER_Priority priority,
179 const char *filename,
180 size_t blocksize,
181 GNUNET_CRYPTO_HashCompletedCallback callback,
182 void *callback_cls)
183{
184 struct GNUNET_CRYPTO_FileHashContext *fhc;
185
186 GNUNET_assert (blocksize > 0);
187 fhc =
188 GNUNET_malloc (sizeof(struct GNUNET_CRYPTO_FileHashContext) + blocksize);
189 fhc->callback = callback;
190 fhc->callback_cls = callback_cls;
191 fhc->buffer = (unsigned char *) &fhc[1];
192 fhc->filename = GNUNET_strdup (filename);
193 if (GPG_ERR_NO_ERROR != gcry_md_open (&fhc->md, GCRY_MD_SHA512, 0))
194 {
195 GNUNET_break (0);
196 GNUNET_free (fhc);
197 return NULL;
198 }
199 fhc->bsize = blocksize;
200 if (GNUNET_OK !=
201 GNUNET_DISK_file_size (filename,
202 &fhc->fsize,
203 GNUNET_NO,
204 GNUNET_YES))
205 {
206 GNUNET_free (fhc->filename);
207 GNUNET_free (fhc);
208 return NULL;
209 }
210 fhc->fh = GNUNET_DISK_file_open (filename,
211 GNUNET_DISK_OPEN_READ,
212 GNUNET_DISK_PERM_NONE);
213 if (! fhc->fh)
214 {
215 GNUNET_free (fhc->filename);
216 GNUNET_free (fhc);
217 return NULL;
218 }
219 fhc->priority = priority;
220 fhc->task = GNUNET_SCHEDULER_add_with_priority (priority,
221 &file_hash_task,
222 fhc);
223 return fhc;
224}
225
226
227/**
228 * Cancel a file hashing operation.
229 *
230 * @param fhc operation to cancel (callback must not yet have been invoked)
231 */
232void
233GNUNET_CRYPTO_hash_file_cancel (struct GNUNET_CRYPTO_FileHashContext *fhc)
234{
235 GNUNET_SCHEDULER_cancel (fhc->task);
236 GNUNET_free (fhc->filename);
237 GNUNET_break (GNUNET_OK ==
238 GNUNET_DISK_file_close (fhc->fh));
239 GNUNET_free (fhc);
240}
241
242
243/* end of crypto_hash_file.c */