]> git.cworth.org Git - notmuch/blob - lib/sha1.c
NEWS: set release date
[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 #define BLOCK_SIZE 4096
59     unsigned char block[BLOCK_SIZE];
60     size_t bytes_read;
61     GChecksum *sha1;
62     char *digest = NULL;
63
64     file = fopen (filename, "r");
65     if (file == NULL)
66         return NULL;
67
68     sha1 = g_checksum_new (G_CHECKSUM_SHA1);
69     if (sha1 == NULL)
70         goto DONE;
71
72     while (1) {
73         bytes_read = fread (block, 1, 4096, file);
74         if (bytes_read == 0) {
75             if (feof (file))
76                 break;
77             else if (ferror (file))
78                 goto DONE;
79         } else {
80             g_checksum_update (sha1, block, bytes_read);
81         }
82     }
83
84     digest = xstrdup (g_checksum_get_string (sha1));
85
86   DONE:
87     if (sha1)
88         g_checksum_free (sha1);
89     if (file)
90         fclose (file);
91
92     return digest;
93 }