summaryrefslogtreecommitdiff
path: root/src/lib/libsum/sumlib.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libsum/sumlib.c
downloadksh-upstream.tar.gz
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libsum/sumlib.c')
-rw-r--r--src/lib/libsum/sumlib.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/src/lib/libsum/sumlib.c b/src/lib/libsum/sumlib.c
new file mode 100644
index 0000000..49c4c19
--- /dev/null
+++ b/src/lib/libsum/sumlib.c
@@ -0,0 +1,376 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1996-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * man this is sum library
+ */
+
+static const char id[] = "\n@(#)$Id: sumlib (AT&T Research) 2009-09-28 $\0\n";
+
+#define _SUM_PRIVATE_ \
+ struct Method_s* method; \
+ uintmax_t total_count; \
+ uintmax_t total_size; \
+ uintmax_t size;
+
+#include <sum.h>
+#include <ctype.h>
+#include <swap.h>
+#include <hashpart.h>
+
+#define SCALE(n,m) (((n)+(m)-1)/(m))
+
+typedef struct Method_s
+{
+ const char* match;
+ const char* description;
+ const char* options;
+ Sum_t* (*open)(const struct Method_s*, const char*);
+ int (*init)(Sum_t*);
+ int (*block)(Sum_t*, const void*, size_t);
+ int (*data)(Sum_t*, Sumdata_t*);
+ int (*print)(Sum_t*, Sfio_t*, int, size_t);
+ int (*done)(Sum_t*);
+ int scale;
+} Method_t;
+
+typedef struct Map_s
+{
+ const char* match;
+ const char* description;
+ const char* map;
+} Map_t;
+
+/*
+ * 16 and 32 bit common code
+ */
+
+#define _INTEGRAL_PRIVATE_ \
+ uint32_t sum; \
+ uint32_t total_sum;
+
+typedef struct Integral_s
+{
+ _SUM_PUBLIC_
+ _SUM_PRIVATE_
+ _INTEGRAL_PRIVATE_
+} Integral_t;
+
+static Sum_t*
+long_open(const Method_t* method, const char* name)
+{
+ Integral_t* p;
+
+ if (p = newof(0, Integral_t, 1, 0))
+ {
+ p->method = (Method_t*)method;
+ p->name = name;
+ }
+ return (Sum_t*)p;
+}
+
+static int
+long_init(Sum_t* p)
+{
+ ((Integral_t*)p)->sum = 0;
+ return 0;
+}
+
+static int
+long_done(Sum_t* p)
+{
+ register Integral_t* x = (Integral_t*)p;
+
+ x->total_sum ^= (x->sum &= 0xffffffff);
+ return 0;
+}
+
+static int
+short_done(Sum_t* p)
+{
+ register Integral_t* x = (Integral_t*)p;
+
+ x->total_sum ^= (x->sum &= 0xffff);
+ return 0;
+}
+
+static int
+long_print(Sum_t* p, Sfio_t* sp, register int flags, size_t scale)
+{
+ register Integral_t* x = (Integral_t*)p;
+ register uint32_t c;
+ register uintmax_t z;
+ register size_t n;
+
+ c = (flags & SUM_TOTAL) ? x->total_sum : x->sum;
+ sfprintf(sp, "%.*I*u", (flags & SUM_LEGACY) ? 5 : 1, sizeof(c), c);
+ if (flags & SUM_SIZE)
+ {
+ z = (flags & SUM_TOTAL) ? x->total_size : x->size;
+ if ((flags & SUM_SCALE) && ((n = scale) || (n = x->method->scale)))
+ z = SCALE(z, n);
+ sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(z), z);
+ }
+ if (flags & SUM_TOTAL)
+ sfprintf(sp, " %*I*u", (flags & SUM_LEGACY) ? 6 : 0, sizeof(x->total_count), x->total_count);
+ return 0;
+}
+
+static int
+long_data(Sum_t* p, Sumdata_t* data)
+{
+ register Integral_t* x = (Integral_t*)p;
+
+ data->size = sizeof(data->num);
+ data->num = x->sum;
+ data->buf = 0;
+ return 0;
+}
+
+#include "FEATURE/sum"
+
+#include "sum-att.c"
+#include "sum-ast4.c"
+#include "sum-bsd.c"
+#include "sum-crc.c"
+#include "sum-prng.c"
+
+#if _LIB_md && _lib_MD5Init && _hdr_md5 && _lib_SHA2Init && _hdr_sha2
+
+#include "sum-lmd.c"
+
+#else
+
+#include "sum-md5.c"
+#include "sum-sha1.c"
+#include "sum-sha2.c"
+
+#endif
+
+/*
+ * now the library interface
+ */
+
+#undef METHOD /* solaris <sys/localedef.h>! */
+#define METHOD(x) x##_match,x##_description,x##_options,x##_open,x##_init,x##_block,x##_data,x##_print,x##_done,x##_scale
+
+static const Method_t methods[] =
+{
+ METHOD(att),
+ METHOD(ast4),
+ METHOD(bsd),
+ METHOD(crc),
+ METHOD(prng),
+#ifdef md4_description
+ METHOD(md4),
+#endif
+#ifdef md5_description
+ METHOD(md5),
+#endif
+#ifdef sha1_description
+ METHOD(sha1),
+#endif
+#ifdef sha256_description
+ METHOD(sha256),
+#endif
+#ifdef sha384_description
+ METHOD(sha384),
+#endif
+#ifdef sha512_description
+ METHOD(sha512),
+#endif
+};
+
+static const Map_t maps[] =
+{
+ {
+ "posix|cksum|std|standard",
+ "The posix 1003.2-1992 32 bit crc checksum. This is the"
+ " default \bcksum\b(1) method.",
+ "crc-0x04c11db7-rotate-done-size"
+ },
+ {
+ "zip",
+ "The \bzip\b(1) crc.",
+ "crc-0xedb88320-init-done"
+ },
+ {
+ "fddi",
+ "The FDDI crc.",
+ "crc-0xedb88320-size=0xcc55cc55"
+ },
+ {
+ "fnv|fnv1",
+ "The Fowler-Noll-Vo 32 bit PRNG hash with non-zero"
+ " initializer (FNV-1).",
+ "prng-0x01000193-init=0x811c9dc5"
+ },
+ {
+ "ast|strsum",
+ "The \bast\b \bstrsum\b(3) PRNG hash.",
+ "prng-0x63c63cd9-add=0x9c39c33d"
+ },
+};
+
+/*
+ * simple alternation prefix match
+ */
+
+static int
+match(register const char* s, register const char* p)
+{
+ register const char* b = s;
+
+ for (;;)
+ {
+ do
+ {
+ if (*p == '|' || *p == 0)
+ return 1;
+ } while (*s++ == *p++);
+ for (;;)
+ {
+ switch (*p++)
+ {
+ case 0:
+ return 0;
+ case '|':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ s = b;
+ }
+ return 0;
+}
+
+/*
+ * open sum method name
+ */
+
+Sum_t*
+sumopen(register const char* name)
+{
+ register int n;
+
+ if (!name || !name[0] || name[0] == '-' && !name[1])
+ name = "default";
+ for (n = 0; n < elementsof(maps); n++)
+ if (match(name, maps[n].match))
+ {
+ name = maps[n].map;
+ break;
+ }
+ for (n = 0; n < elementsof(methods); n++)
+ if (match(name, methods[n].match))
+ return (*methods[n].open)(&methods[n], name);
+ return 0;
+}
+
+/*
+ * initialize for a new run of blocks
+ */
+
+int
+suminit(Sum_t* p)
+{
+ p->size = 0;
+ return (*p->method->init)(p);
+}
+
+/*
+ * compute the running sum on buf
+ */
+
+int
+sumblock(Sum_t* p, const void* buf, size_t siz)
+{
+ p->size += siz;
+ return (*p->method->block)(p, buf, siz);
+}
+
+/*
+ * done with this run of blocks
+ */
+
+int
+sumdone(Sum_t* p)
+{
+ p->total_count++;
+ p->total_size += p->size;
+ return (*p->method->done)(p);
+}
+
+/*
+ * print the sum [size] on sp
+ */
+
+int
+sumprint(Sum_t* p, Sfio_t* sp, int flags, size_t scale)
+{
+ return (*p->method->print)(p, sp, flags, scale);
+}
+
+/*
+ * return the current sum (internal) data
+ */
+
+int
+sumdata(Sum_t* p, Sumdata_t* d)
+{
+ return (*p->method->data)(p, d);
+}
+
+/*
+ * close an open sum handle
+ */
+
+int
+sumclose(Sum_t* p)
+{
+ free(p);
+ return 0;
+}
+
+/*
+ * print the checksum method optget(3) usage on sp and return the length
+ */
+
+int
+sumusage(Sfio_t* sp)
+{
+ register int i;
+ register int n;
+
+ for (i = n = 0; i < elementsof(methods); i++)
+ {
+ n += sfprintf(sp, "[+%s?%s]", methods[i].match, methods[i].description);
+ if (methods[i].options)
+ n += sfprintf(sp, "{\n%s\n}", methods[i].options);
+ }
+ for (i = 0; i < elementsof(maps); i++)
+ n += sfprintf(sp, "[+%s?%s Shorthand for \b%s\b.]", maps[i].match, maps[i].description, maps[i].map);
+ return n;
+}