]> err.no Git - yubikey-server-c/commitdiff
Add utility functions
authorTollef Fog Heen <tfheen@err.no>
Mon, 12 Oct 2009 08:25:38 +0000 (10:25 +0200)
committerTollef Fog Heen <tfheen@err.no>
Mon, 12 Oct 2009 08:25:38 +0000 (10:25 +0200)
src/util.c [new file with mode: 0644]
src/util.h [new file with mode: 0644]

diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..94d7793
--- /dev/null
@@ -0,0 +1,172 @@
+
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <assert.h>
+#include "util.h"
+
+void *ysc_memdup(void *p, size_t len)
+{
+       void *r;
+       r = malloc(len);
+       assert(r != NULL);
+       memcpy(r, p, len);
+       return r;
+}
+
+size_t ysc_nstrstr(const char *haystack, const char *needle)
+{
+       size_t n = 0;
+       while ((haystack = strstr(haystack, needle)) != NULL) {
+               n++;
+               haystack += strlen(needle);
+       }
+       return n;
+}
+
+
+/* Like strftime, but better, calls strftime under the hood
+   %N => nanoseconds (not implemented)
+   %v => milliseconds
+
+   if tv is null, call gettimeofday for you
+*/
+
+size_t ysc_strftime(char *s, size_t max, const char *format,
+                   const struct timeval *tv) {
+       struct tm tm;
+       int i, j, flen;
+       struct timeval tvv;
+       /* '%v' is two bytes less than what a %v needs */
+       size_t fdup_len = strlen(format) + ysc_nstrstr(format, "%v") * 2;
+       char *fdup = malloc(fdup_len); /* XXX check failure */
+       size_t r;
+
+       if (tv == NULL)
+         assert(gettimeofday(&tvv, NULL) == 0);
+       else {
+         memcpy(&tvv, tv, sizeof(struct timeval));
+       }
+       gmtime_r(&tvv.tv_sec, &tm);
+       /* Do %N and %v first, then hand off to strftime */
+       flen = strlen(format);
+       for (i = 0, j = 0; i < flen; i++, j++) {
+               if (format[i] == '%') {
+                       switch (format[i+1]) {
+/*                     case 'N':
+                               break;
+*/
+                       case 'v':
+                               j += snprintf(fdup+j, 4, "%.3zd",
+                                             tvv.tv_usec / 1000);
+                               i++;
+                               continue;
+                               break;
+                       default:
+                               fdup[j] = format[i];
+                               continue;
+                       }
+               } else {
+                       fdup[j] = format[i];
+               }
+       }
+       r = strftime(s, max, fdup, &tm);
+       free(fdup);
+       return r;
+}
+
+/* Base 64 functions */
+
+/*
+ * AUTHOR:         Bob Trower 08/04/01
+ *
+ * COPYRIGHT:      Copyright (c) Trantor Standard Systems Inc., 2001
+ *
+ * LICENCE:        Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+unsigned char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static void ysc_b64_encodeblock(unsigned char in[3], unsigned char out[4], int len)
+{
+       out[0] = cb64[in[0] >> 2];
+       out[1] = cb64[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
+       out[2] = (unsigned char) (len > 1 ? cb64[((in[1] & 0x0f) << 2) |
+                                                ((in[2] & 0xc0) >> 6)] : '=');
+       out[3] = (unsigned char) (len > 2 ? cb64[in[2] & 0x3f] : '=');
+}
+
+char *ysc_b64_encode(char *s, ssize_t len)
+{
+       char *r = malloc((len/3+1)*4+1);
+       char *tmp = r;
+       unsigned char out[4];
+
+       while (len > 0) {
+               ysc_b64_encodeblock((unsigned char*)s, out, len);
+               memcpy(tmp, out, 4);
+               tmp += 4;
+               len -= 3;
+               s += 3;
+       }
+       return r;
+}
+
+static void ysc_b64_decodeblock(unsigned const char in[4], unsigned char out[3])
+{
+       out[0] = (unsigned char) ((in[0] - 'A') << 2 | (in[1] - 'A') >> 4);
+       out[1] = (unsigned char) ((in[1] - 'A') << 4 | (in[2] - 'A') >> 2);
+       out[2] = (unsigned char) ((((in[2] - 'A') << 6) & 0xc0) | (in[3] - 'A'));
+}
+
+ssize_t ysc_b64_decode(char *s, char **decoded)
+{
+       ssize_t len = strlen(s);
+       char *tmp;
+       unsigned char out[3];
+       ssize_t r = 0;
+
+       *decoded = malloc((len/4+1)*3+1);
+       tmp = *decoded;
+       if ((len % 4) != 0) {
+               return 0;
+               /* XXX free memory */
+       }
+
+       while (*s != '\0') {
+               ysc_b64_decodeblock((unsigned char*)s, out);
+               memcpy(tmp, out, 3);
+               tmp += 3;
+               if (s[2] == '=') {
+                       r += 1;
+               } else if (s[3] == '=') {
+                       r += 2;
+               } else {
+                       r += 3;
+               }
+               s += 4;
+       }
+       return r;
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644 (file)
index 0000000..5a2e8dc
--- /dev/null
@@ -0,0 +1,17 @@
+
+#ifndef ysc_util_h__
+#define ysc_util_h__
+
+#include <sys/types.h>
+
+void *ysc_memdup(void *p, size_t len);
+size_t ysc_nstrstr(const char *haystack, const char *needle);
+
+size_t ysc_strftime(char *s, size_t max, const char *format,
+                   const struct timeval *tv);
+
+char *ysc_b64_encode(char *s, ssize_t len);
+ssize_t ysc_b64_decode(char *s, char **r);
+
+
+#endif /* ysc_util_h */