1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1996-2009 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*
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
93 long_init(Sum_t* p)
94 {
95 	((Integral_t*)p)->sum = 0;
96 	return 0;
97 }
98 
99 static int
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
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
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
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
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*
274 sumopen(register const char* name)
275 {
276 	register int	n;
277 	char		pat[256];
278 
279 	if (!name || !name[0] || name[0] == '-' && !name[1])
280 		name = "default";
281 	for (n = 0; n < elementsof(maps); n++)
282 		if (match(name, maps[n].match))
283 		{
284 			name = maps[n].map;
285 			break;
286 		}
287 	for (n = 0; n < elementsof(methods); n++)
288 		if (match(name, methods[n].match))
289 			return (*methods[n].open)(&methods[n], name);
290 	return 0;
291 }
292 
293 /*
294  * initialize for a new run of blocks
295  */
296 
297 int
298 suminit(Sum_t* p)
299 {
300 	p->size = 0;
301 	return (*p->method->init)(p);
302 }
303 
304 /*
305  * compute the running sum on buf
306  */
307 
308 int
309 sumblock(Sum_t* p, const void* buf, size_t siz)
310 {
311 	p->size += siz;
312 	return (*p->method->block)(p, buf, siz);
313 }
314 
315 /*
316  * done with this run of blocks
317  */
318 
319 int
320 sumdone(Sum_t* p)
321 {
322 	p->total_count++;
323 	p->total_size += p->size;
324 	return (*p->method->done)(p);
325 }
326 
327 /*
328  * print the sum [size] on sp
329  */
330 
331 int
332 sumprint(Sum_t* p, Sfio_t* sp, int flags, size_t scale)
333 {
334 	return (*p->method->print)(p, sp, flags, scale);
335 }
336 
337 /*
338  * return the current sum (internal) data
339  */
340 
341 int
342 sumdata(Sum_t* p, Sumdata_t* d)
343 {
344 	return (*p->method->data)(p, d);
345 }
346 
347 /*
348  * close an open sum handle
349  */
350 
351 int
352 sumclose(Sum_t* p)
353 {
354 	free(p);
355 	return 0;
356 }
357 
358 /*
359  * print the checksum method optget(3) usage on sp and return the length
360  */
361 
362 int
363 sumusage(Sfio_t* sp)
364 {
365 	register int	i;
366 	register int	n;
367 
368 	for (i = n = 0; i < elementsof(methods); i++)
369 	{
370 		n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description);
371 		if (methods[i].options)
372 			n += sfprintf(sp, "{\n%s\n}", methods[i].options);
373 	}
374 	for (i = 0; i < elementsof(maps); i++)
375 		n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map);
376 	return n;
377 }
378