aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/ChangeLog5
-rw-r--r--common/sexputil.c78
-rw-r--r--common/util.h3
3 files changed, 86 insertions, 0 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index a42b07b4d..4688d2765 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,8 @@
+2005-04-17 Werner Koch <[email protected]>
+
+ * sexputil.c (cmp_simple_canon_sexp): New.
+ (make_simple_sexp_from_hexstr): New.
+
2005-04-07 Werner Koch <[email protected]>
* sexputil.c: New.
diff --git a/common/sexputil.c b/common/sexputil.c
index 853d7e58a..802916b44 100644
--- a/common/sexputil.c
+++ b/common/sexputil.c
@@ -61,3 +61,81 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
return err;
}
+
+/* Compare two simple S-expressions like "(3:foo)". Returns 0 if they
+ are identical or !0 if they are not. Not that this function can't
+ be used for sorting. */
+int
+cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b)
+{
+ unsigned long n1, n2;
+ char *endp;
+
+ if (!a && !b)
+ return 0; /* Both are NULL, they are identical. */
+ if (!a || !b)
+ return 1; /* One is NULL, they are not identical. */
+ if (*a != '(' || *b != '(')
+ log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
+
+ a++;
+ n1 = strtoul (a, &endp, 10);
+ a = endp;
+ b++;
+ n2 = strtoul (b, &endp, 10);
+ b = endp;
+
+ if (*a != ':' || *b != ':' )
+ log_bug ("invalid S-exp in cmp_simple_canon_sexp\n");
+ if (n1 != n2)
+ return 1; /* Not the same. */
+
+ for (a++, b++; n1; n1--, a++, b++)
+ if (*a != *b)
+ return 1; /* Not the same. */
+ return 0;
+}
+
+
+/* Create a simple S-expression from the hex string at LIBNE. Returns
+ a newly allocated buffer with that canonical encoded S-expression
+ or NULL in case of an error. On return the number of characters
+ scanned in LINE will be stored at NSCANNED. This fucntions stops
+ converting at the first character not representing a hexdigit. Odd
+ numbers of hex digits are allowed; a leading zero is then
+ assumed. If no characters have been found, NULL is returned.*/
+unsigned char *
+make_simple_sexp_from_hexstr (const char *line, size_t *nscanned)
+{
+ size_t n, len;
+ const char *s;
+ unsigned char *buf;
+ unsigned char *p;
+ char numbuf[50];
+
+ for (n=0, s=line; hexdigitp (s); s++, n++)
+ ;
+ if (nscanned)
+ *nscanned = n;
+ if (!n)
+ return NULL;
+ len = ((n+1) & ~0x01)/2;
+ sprintf (numbuf, "(%u:", (unsigned int)len);
+ buf = xtrymalloc (strlen (numbuf) + len + 1 + 1);
+ if (!buf)
+ return NULL;
+ p = stpcpy (buf, numbuf);
+ s = line;
+ if ((n&1))
+ {
+ *p++ = xtoi_1 (s);
+ s++;
+ n--;
+ }
+ for (; n > 1; n -=2, s += 2)
+ *p++ = xtoi_2 (s);
+ *p++ = ')';
+ *p = 0; /* (Not really neaded.) */
+
+ return buf;
+}
diff --git a/common/util.h b/common/util.h
index 14180bec4..6a9b54ef5 100644
--- a/common/util.h
+++ b/common/util.h
@@ -123,6 +123,9 @@ gpg_error_t b64enc_finish (struct b64state *state);
/*-- sexputil.c */
gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
unsigned char *grip);
+int cmp_simple_canon_sexp (const unsigned char *a, const unsigned char *b);
+unsigned char *make_simple_sexp_from_hexstr (const char *line,
+ size_t *nscanned);
/*-- homedir. c --*/
const char *default_homedir (void);