Included LIBICONV in all Makefiles.
[gnupg.git] / common / sexputil.c
index 853d7e5..fe0870c 100644 (file)
@@ -15,7 +15,8 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
  */
 
 /* This file implements a few utility functions useful when working
@@ -52,7 +53,7 @@ keygrip_from_canon_sexp (const unsigned char *key, size_t keylen,
 
   if (!grip)
     return gpg_error (GPG_ERR_INV_VALUE);
-  err = gcry_sexp_sscan (&sexp, NULL, key, keylen);
+  err = gcry_sexp_sscan (&sexp, NULL, (const char *)key, keylen);
   if (err)
     return err;
   if (!gcry_pk_get_keygrip (sexp, grip))
@@ -61,3 +62,84 @@ 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_orig,
+                       const unsigned char *b_orig)
+{
+  const char *a = (const char *)a_orig;
+  const char *b = (const char *)b_orig;
+  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 = (unsigned char *)stpcpy ((char *)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;
+}