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* 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 91 long_init(Sum_t* p) 92 { 93 ((Integral_t*)p)->sum = 0; 94 return 0; 95 } 96 97 static int 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 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 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 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 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* 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 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 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 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 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 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 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 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