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* 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 28static 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 43typedef 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 57typedef 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 72typedef struct Integral_s 73{ 74 _SUM_PUBLIC_ 75 _SUM_PRIVATE_ 76 _INTEGRAL_PRIVATE_ 77} Integral_t; 78 79static Sum_t* 80long_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 92static int 93long_init(Sum_t* p) 94{ 95 ((Integral_t*)p)->sum = 0; 96 return 0; 97} 98 99static int 100long_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 108static int 109short_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 117static int 118long_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 139static int 140long_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 177static 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 204static 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 239static int 240match(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 273Sum_t* 274sumopen(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 296int 297suminit(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 307int 308sumblock(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 318int 319sumdone(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 330int 331sumprint(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 340int 341sumdata(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 350int 351sumclose(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 361int 362sumusage(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