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