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