1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1996-2008 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) 2008-05-01 $\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 * open sum method name 237 */ 238 239 Sum_t* 240 sumopen(register const char* name) 241 { 242 register int n; 243 char pat[256]; 244 245 if (!name || !name[0] || name[0] == '-' && !name[1]) 246 name = "default"; 247 for (n = 0; n < elementsof(maps); n++) 248 { 249 sfsprintf(pat, sizeof(pat), "*@(%s)*", maps[n].match); 250 if (strmatch(name, pat)) 251 { 252 name = maps[n].map; 253 break; 254 } 255 } 256 for (n = 0; n < elementsof(methods); n++) 257 { 258 sfsprintf(pat, sizeof(pat), "*@(%s)*", methods[n].match); 259 if (strmatch(name, pat)) 260 return (*methods[n].open)(&methods[n], name); 261 } 262 return 0; 263 } 264 265 /* 266 * initialize for a new run of blocks 267 */ 268 269 int 270 suminit(Sum_t* p) 271 { 272 p->size = 0; 273 return (*p->method->init)(p); 274 } 275 276 /* 277 * compute the running sum on buf 278 */ 279 280 int 281 sumblock(Sum_t* p, const void* buf, size_t siz) 282 { 283 p->size += siz; 284 return (*p->method->block)(p, buf, siz); 285 } 286 287 /* 288 * done with this run of blocks 289 */ 290 291 int 292 sumdone(Sum_t* p) 293 { 294 p->total_count++; 295 p->total_size += p->size; 296 return (*p->method->done)(p); 297 } 298 299 /* 300 * print the sum [size] on sp 301 */ 302 303 int 304 sumprint(Sum_t* p, Sfio_t* sp, int flags, size_t scale) 305 { 306 return (*p->method->print)(p, sp, flags, scale); 307 } 308 309 /* 310 * return the current sum (internal) data 311 */ 312 313 int 314 sumdata(Sum_t* p, Sumdata_t* d) 315 { 316 return (*p->method->data)(p, d); 317 } 318 319 /* 320 * close an open sum handle 321 */ 322 323 int 324 sumclose(Sum_t* p) 325 { 326 free(p); 327 return 0; 328 } 329 330 /* 331 * print the checksum method optget(3) usage on sp and return the length 332 */ 333 334 int 335 sumusage(Sfio_t* sp) 336 { 337 register int i; 338 register int n; 339 340 for (i = n = 0; i < elementsof(methods); i++) 341 { 342 n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description); 343 if (methods[i].options) 344 n += sfprintf(sp, "{\n%s\n}", methods[i].options); 345 } 346 for (i = 0; i < elementsof(maps); i++) 347 n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map); 348 return n; 349 } 350