This source file includes following definitions.
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <config.h>
30
31 #include <limits.h>
32 #include <stdarg.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/stat.h>
38
39 #include <sysstdio.h>
40
41 #include <fingerprint.h>
42 #include <getopt.h>
43 #include <intprops.h>
44 #include <min-max.h>
45 #include <sha256.h>
46
47 #ifndef SSIZE_MAX
48 # define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
49 #endif
50
51 #ifdef WINDOWSNT
52
53
54 #undef fopen
55 #include <direct.h>
56
57 #ifndef MINGW_W64
58 # undef fseeko
59 # define fseeko fseeko64
60 #endif
61 #endif
62
63
64 static char *buf;
65
66 int
67 main (int argc, char **argv)
68 {
69 int c;
70 bool raw = false;
71 while (0 <= (c = getopt (argc, argv, "rh")))
72 {
73 switch (c)
74 {
75 case 'r':
76 raw = true;
77 break;
78 case 'h':
79 printf ("make-fingerprint [-r] FILE: replace or compute a hash\n");
80 return EXIT_SUCCESS;
81 default:
82 return EXIT_FAILURE;
83 }
84 }
85
86 struct sha256_ctx ctx;
87 sha256_init_ctx (&ctx);
88
89 char *prog = argv[0];
90 char *file = argv[optind];
91 if (argc - optind != 1)
92 {
93 fprintf (stderr, "%s: missing or extra file operand\n", prog);
94 return EXIT_FAILURE;
95 }
96
97 FILE *f = fopen (file, raw ? "r" FOPEN_BINARY : "r+" FOPEN_BINARY);
98 struct stat st;
99 if (!f || fstat (fileno (f), &st) != 0)
100 {
101 perror (file);
102 return EXIT_FAILURE;
103 }
104
105 if (!S_ISREG (st.st_mode))
106 {
107 fprintf (stderr, "%s: Error: %s is not a regular file\n",
108 prog, file);
109 return EXIT_FAILURE;
110 }
111
112 ptrdiff_t maxlen = min (min (TYPE_MAXIMUM (off_t), PTRDIFF_MAX),
113 min (SIZE_MAX, SSIZE_MAX));
114 if (maxlen <= st.st_size)
115 {
116 fprintf (stderr, "%s: %s: file too big\n", prog, file);
117 return EXIT_FAILURE;
118 }
119
120 buf = malloc (st.st_size + 1);
121 if (!buf)
122 {
123 perror ("malloc");
124 return EXIT_FAILURE;
125 }
126
127 size_t chunksz = fread (buf, 1, st.st_size + 1, f);
128 if (ferror (f) || chunksz != st.st_size)
129 {
130 fprintf (stderr, "%s: Error: could not read %s\n", prog, file);
131 return EXIT_FAILURE;
132 }
133
134 sha256_process_bytes (buf, chunksz, &ctx);
135
136 unsigned char digest[32];
137 sha256_finish_ctx (&ctx, digest);
138
139 if (raw)
140 {
141 for (int i = 0; i < 32; ++i)
142 printf ("%02X", digest[i]);
143 }
144 else
145 {
146 bool fingered = false;
147
148 for (char *finger = buf;
149 (finger = memmem (finger, buf + chunksz - finger,
150 (unsigned char *) fingerprint,
151 sizeof fingerprint));
152 finger++)
153 {
154 if (! (fseeko (f, finger - buf, SEEK_SET) == 0
155 && fwrite (digest, 1, sizeof digest, f) == sizeof digest))
156 {
157 perror (file);
158 return EXIT_FAILURE;
159 }
160 fingered = true;
161 }
162
163 if (!fingered)
164 {
165 fprintf (stderr, "%s: %s: missing fingerprint\n", prog, file);
166 return EXIT_FAILURE;
167 }
168 }
169
170 if (fclose (f) != 0)
171 {
172 perror (file);
173 return EXIT_FAILURE;
174 }
175
176 return EXIT_SUCCESS;
177 }
178
179