]> git.cworth.org Git - notmuch/blob - lib/sha1.c
lib: publish API for notmuch_database_reopen
[notmuch] / lib / sha1.c
1 /* sha1.c - Interfaces to SHA-1 hash for the notmuch mail system
2  *
3  * Copyright © 2009 Carl Worth
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see https://www.gnu.org/licenses/ .
17  *
18  * Author: Carl Worth <cworth@cworth.org>
19  */
20
21 #include "notmuch-private.h"
22
23 #include <glib.h>
24
25 /* Create a hexadecimal string version of the SHA-1 digest of 'str'
26  * (including its null terminating character).
27  *
28  * This function returns a newly allocated string which the caller
29  * should free() when finished.
30  */
31 char *
32 _notmuch_sha1_of_string (const char *str)
33 {
34     GChecksum *sha1;
35     char *digest;
36
37     sha1 = g_checksum_new (G_CHECKSUM_SHA1);
38     g_checksum_update (sha1, (const guchar *) str, strlen (str) + 1);
39     digest = xstrdup (g_checksum_get_string (sha1));
40     g_checksum_free (sha1);
41
42     return digest;
43 }
44
45 /* Create a hexadecimal string version of the SHA-1 digest of the
46  * contents of the named file.
47  *
48  * This function returns a newly allocated string which the caller
49  * should free() when finished.
50  *
51  * If any error occurs while reading the file, (permission denied,
52  * file not found, etc.), this function returns NULL.
53  */
54 char *
55 _notmuch_sha1_of_file (const char *filename)
56 {
57     FILE *file;
58
59 #define BLOCK_SIZE 4096
60     unsigned char block[BLOCK_SIZE];
61     size_t bytes_read;
62     GChecksum *sha1;
63     char *digest = NULL;
64
65     file = fopen (filename, "r");
66     if (file == NULL)
67         return NULL;
68
69     sha1 = g_checksum_new (G_CHECKSUM_SHA1);
70     if (sha1 == NULL)
71         goto DONE;
72
73     while (1) {
74         bytes_read = fread (block, 1, 4096, file);
75         if (bytes_read == 0) {
76             if (feof (file))
77                 break;
78             else if (ferror (file))
79                 goto DONE;
80         } else {
81             g_checksum_update (sha1, block, bytes_read);
82         }
83     }
84
85     digest = xstrdup (g_checksum_get_string (sha1));
86
87   DONE:
88     if (sha1)
89         g_checksum_free (sha1);
90     if (file)
91         fclose (file);
92
93     return digest;
94 }