1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1996-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
21 /*
22 * Glenn Fowler
23 * AT&T Research
24 *
25 * man this is sum library
26 */
27
28 static const char id[] = "\n@(#)$Id: sumlib (AT&T Research) 2009-09-28 $\0\n";
29
30 #define _SUM_PRIVATE_ \
31 struct Method_s* method; \
32 uintmax_t total_count; \
33 uintmax_t total_size; \
34 uintmax_t size;
35
36 #include <sum.h>
37 #include <ctype.h>
38 #include <swap.h>
39 #include <hashpart.h>
40
41 #define SCALE(n,m) (((n)+(m)-1)/(m))
42
43 typedef struct Method_s
44 {
45 const char* match;
46 const char* description;
47 const char* options;
48 Sum_t* (*open)(const struct Method_s*, const char*);
49 int (*init)(Sum_t*);
50 int (*block)(Sum_t*, const void*, size_t);
51 int (*data)(Sum_t*, Sumdata_t*);
52 int (*print)(Sum_t*, Sfio_t*, int, size_t);
53 int (*done)(Sum_t*);
54 int scale;
55 } Method_t;
56
57 typedef struct Map_s
58 {
59 const char* match;
60 const char* description;
61 const char* map;
62 } Map_t;
63
64 /*
65 * 16 and 32 bit common code
66 */
67
68 #define _INTEGRAL_PRIVATE_ \
69 uint32_t sum; \
70 uint32_t total_sum;
71
72 typedef struct Integral_s
73 {
74 _SUM_PUBLIC_
75 _SUM_PRIVATE_
76 _INTEGRAL_PRIVATE_
77 } Integral_t;
78
79 static Sum_t*
long_open(const Method_t * method,const char * name)80 long_open(const Method_t* method, const char* name)
81 {
82 Integral_t* p;
83
84 if (p = newof(0, Integral_t, 1, 0))
85 {
86 p->method = (Method_t*)method;
87 p->name = name;
88 }
89 return (Sum_t*)p;
90 }
91
92 static int
long_init(Sum_t * p)93 long_init(Sum_t* p)
94 {
95 ((Integral_t*)p)->sum = 0;
96 return 0;
97 }
98
99 static int
long_done(Sum_t * p)100 long_done(Sum_t* p)
101 {
102 register Integral_t* x = (Integral_t*)p;
103
104 x->total_sum ^= (x->sum &= 0xffffffff);
105 return 0;
106 }
107
108 static int
short_done(Sum_t * p)109 short_done(Sum_t* p)
110 {
111 register Integral_t* x = (Integral_t*)p;
112
113 x->total_sum ^= (x->sum &= 0xffff);
114 return 0;
115 }
116
117 static int
long_print(Sum_t * p,Sfio_t * sp,register int flags,size_t scale)118 long_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
119 {
120 register Integral_t* x = (Integral_t*)p;
121 register uint32_t c;
122 register uintmax_t z;
123 register size_t n;
124
125 c = (flags & SUM_TOTAL) ? x->total_sum : x->sum;
126 sfprintf(sp, "%.*I*u", (flags & SUM_LEGACY) ? 5 : 1, sizeof(c), c);
127 if (flags & SUM_SIZE)
128 {
129 z = (flags & SUM_TOTAL) ? x->total_size : x->size;
130 if ((flags & SUM_SCALE) && ((n = scale) || (n = x->method->scale)))
131 z = SCALE(z, n);
132 sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(z), z);
133 }
134 if (flags & SUM_TOTAL)
135 sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(x->total_count), x->total_count);
136 return 0;
137 }
138
139 static int
long_data(Sum_t * p,Sumdata_t * data)140 long_data(Sum_t* p, Sumdata_t* data)
141 {
142 register Integral_t* x = (Integral_t*)p;
143
144 data->size = sizeof(data->num);
145 data->num = x->sum;
146 data->buf = 0;
147 return 0;
148 }
149
150 #include "FEATURE/sum"
151
152 #include "sum-att.c"
153 #include "sum-ast4.c"
154 #include "sum-bsd.c"
155 #include "sum-crc.c"
156 #include "sum-prng.c"
157
158 #if _LIB_md && _lib_MD5Init && _hdr_md5 && _lib_SHA2Init && _hdr_sha2
159
160 #include "sum-lmd.c"
161
162 #else
163
164 #include "sum-md5.c"
165 #include "sum-sha1.c"
166 #include "sum-sha2.c"
167
168 #endif
169
170 /*
171 * now the library interface
172 */
173
174 #undef METHOD /* solaris <sys/localedef.h>! */
175 #define METHOD(x) x##_match,x##_description,x##_options,x##_open,x##_init,x##_block,x##_data,x##_print,x##_done,x##_scale
176
177 static const Method_t methods[] =
178 {
179 METHOD(att),
180 METHOD(ast4),
181 METHOD(bsd),
182 METHOD(crc),
183 METHOD(prng),
184 #ifdef md4_description
185 METHOD(md4),
186 #endif
187 #ifdef md5_description
188 METHOD(md5),
189 #endif
190 #ifdef sha1_description
191 METHOD(sha1),
192 #endif
193 #ifdef sha256_description
194 METHOD(sha256),
195 #endif
196 #ifdef sha384_description
197 METHOD(sha384),
198 #endif
199 #ifdef sha512_description
200 METHOD(sha512),
201 #endif
202 };
203
204 static const Map_t maps[] =
205 {
206 {
207 "posix|cksum|std|standard",
208 "The posix 1003.2-1992 32 bit crc checksum. This is the"
209 " default \bcksum\b(1) method.",
210 "crc-0x04c11db7-rotate-done-size"
211 },
212 {
213 "zip",
214 "The \bzip\b(1) crc.",
215 "crc-0xedb88320-init-done"
216 },
217 {
218 "fddi",
219 "The FDDI crc.",
220 "crc-0xedb88320-size=0xcc55cc55"
221 },
222 {
223 "fnv|fnv1",
224 "The Fowler-Noll-Vo 32 bit PRNG hash with non-zero"
225 " initializer (FNV-1).",
226 "prng-0x01000193-init=0x811c9dc5"
227 },
228 {
229 "ast|strsum",
230 "The \bast\b \bstrsum\b(3) PRNG hash.",
231 "prng-0x63c63cd9-add=0x9c39c33d"
232 },
233 };
234
235 /*
236 * simple alternation prefix match
237 */
238
239 static int
match(register const char * s,register const char * p)240 match(register const char* s, register const char* p)
241 {
242 register const char* b = s;
243
244 for (;;)
245 {
246 do
247 {
248 if (*p == '|' || *p == 0)
249 return 1;
250 } while (*s++ == *p++);
251 for (;;)
252 {
253 switch (*p++)
254 {
255 case 0:
256 return 0;
257 case '|':
258 break;
259 default:
260 continue;
261 }
262 break;
263 }
264 s = b;
265 }
266 return 0;
267 }
268
269 /*
270 * open sum method name
271 */
272
273 Sum_t*
sumopen(register const char * name)274 sumopen(register const char* name)
275 {
276 register int n;
277
278 if (!name || !name[0] || name[0] == '-' && !name[1])
279 name = "default";
280 for (n = 0; n < elementsof(maps); n++)
281 if (match(name, maps[n].match))
282 {
283 name = maps[n].map;
284 break;
285 }
286 for (n = 0; n < elementsof(methods); n++)
287 if (match(name, methods[n].match))
288 return (*methods[n].open)(&methods[n], name);
289 return 0;
290 }
291
292 /*
293 * initialize for a new run of blocks
294 */
295
296 int
suminit(Sum_t * p)297 suminit(Sum_t* p)
298 {
299 p->size = 0;
300 return (*p->method->init)(p);
301 }
302
303 /*
304 * compute the running sum on buf
305 */
306
307 int
sumblock(Sum_t * p,const void * buf,size_t siz)308 sumblock(Sum_t* p, const void* buf, size_t siz)
309 {
310 p->size += siz;
311 return (*p->method->block)(p, buf, siz);
312 }
313
314 /*
315 * done with this run of blocks
316 */
317
318 int
sumdone(Sum_t * p)319 sumdone(Sum_t* p)
320 {
321 p->total_count++;
322 p->total_size += p->size;
323 return (*p->method->done)(p);
324 }
325
326 /*
327 * print the sum [size] on sp
328 */
329
330 int
sumprint(Sum_t * p,Sfio_t * sp,int flags,size_t scale)331 sumprint(Sum_t* p, Sfio_t* sp, int flags, size_t scale)
332 {
333 return (*p->method->print)(p, sp, flags, scale);
334 }
335
336 /*
337 * return the current sum (internal) data
338 */
339
340 int
sumdata(Sum_t * p,Sumdata_t * d)341 sumdata(Sum_t* p, Sumdata_t* d)
342 {
343 return (*p->method->data)(p, d);
344 }
345
346 /*
347 * close an open sum handle
348 */
349
350 int
sumclose(Sum_t * p)351 sumclose(Sum_t* p)
352 {
353 free(p);
354 return 0;
355 }
356
357 /*
358 * print the checksum method optget(3) usage on sp and return the length
359 */
360
361 int
sumusage(Sfio_t * sp)362 sumusage(Sfio_t* sp)
363 {
364 register int i;
365 register int n;
366
367 for (i = n = 0; i < elementsof(methods); i++)
368 {
369 n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description);
370 if (methods[i].options)
371 n += sfprintf(sp, "{\n%s\n}", methods[i].options);
372 }
373 for (i = 0; i < elementsof(maps); i++)
374 n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map);
375 return n;
376 }
377