* conversion.c (_gpgme_parse_timestamp): New.
authorWerner Koch <wk@gnupg.org>
Wed, 19 Nov 2003 15:15:21 +0000 (15:15 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 19 Nov 2003 15:15:21 +0000 (15:15 +0000)
(atoi_1, atoi_2, atoi_4): New.
* keylist.c (parse_timestamp): Removed. Changed all callers to use
the new function.
* verify.c (parse_valid_sig): Ditto.  Repalced the errno check.
* sign.c (parse_sig_created): Ditto.

gpgme/ChangeLog
gpgme/conversion.c
gpgme/gpgme.h
gpgme/keylist.c
gpgme/sign.c
gpgme/util.h
gpgme/verify.c

index 2966d6b..9621e0b 100644 (file)
@@ -1,3 +1,12 @@
+2003-11-19  Werner Koch  <wk@gnupg.org>
+
+       * conversion.c (_gpgme_parse_timestamp): New.
+       (atoi_1, atoi_2, atoi_4): New.
+       * keylist.c (parse_timestamp): Removed. Changed all callers to use
+       the new function.
+       * verify.c (parse_valid_sig): Ditto.  Repalced the errno check.
+       * sign.c (parse_sig_created): Ditto.
+
 2003-10-31  Werner Koch  <wk@gnupg.org>
 
        * keylist.c (parse_timestamp): Detect ISO 8601 timestamps and try
index 25de269..f55e9a6 100644 (file)
 
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <errno.h>
 
 #include "gpgme.h"
 #include "util.h"
 
+
+#define atoi_1(p)   (*(p) - '0' )
+#define atoi_2(p)   ((atoi_1(p) * 10) + atoi_1((p)+1))
+#define atoi_4(p)   ((atoi_2(p) * 100) + atoi_2((p)+2))
+
+
 \f
 /* Convert two hexadecimal digits from STR to the value they
    represent.  Returns -1 if one of the characters is not a
@@ -232,6 +239,67 @@ _gpgme_decode_percent_string (const char *src, char **destp, size_t len)
   return 0;
 }
 
+
+/* Parse the string TIMESTAMP into a time_t.  The string may either be
+   seconds since Epoch or in the ISO 8601 format like
+   "20390815T143012".  Returns 0 for an empty string or seconds since
+   Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
+   point to the next non-parsed character in TIMESTRING. */
+time_t
+_gpgme_parse_timestamp (const char *timestamp, char **endp)
+{
+  /* Need to skip leading spaces, because that is what strtoul does
+     but not our ISO 8601 checking code. */
+  while (*timestamp && *timestamp== ' ')
+    timestamp++;
+  if (!*timestamp)
+    return 0;
+
+  if (strlen (timestamp) >= 15 && timestamp[8] == 'T')
+    {
+      struct tm buf;
+      int year;
+
+      year = atoi_4 (timestamp);
+      if (year < 1900)
+        return (time_t)(-1);
+
+      /* Fixme: We would better use a configure test to see whether
+         mktime can handle dates beyond 2038. */
+      if (sizeof (time_t) <= 4 && year >= 2038)
+        return (time_t)2145914603; /* 2037-12-31 23:23:23 */
+
+      memset (&buf, 0, sizeof buf);
+      buf.tm_year = year - 1900;
+      buf.tm_mon = atoi_2 (timestamp+4) - 1; 
+      buf.tm_mday = atoi_2 (timestamp+6);
+      buf.tm_hour = atoi_2 (timestamp+9);
+      buf.tm_min = atoi_2 (timestamp+11);
+      buf.tm_sec = atoi_2 (timestamp+13);
+
+      if (endp)
+        *endp = (char*)(timestamp + 15);
+#ifdef HAVE_TIMEGM
+      return timegm (&buf);
+#else
+      {
+        time_t tim;
+        
+        putenv ("TZ=UTC");
+        tim = mktime (&buf);
+#ifdef __GNUC__
+#warning fixme: we must somehow reset TZ here.  It is not threadsafe anyway.
+#endif
+        return tim;
+      }
+#endif /* !HAVE_TIMEGM */
+    }
+  else
+    return (time_t)strtoul (timestamp, endp, 10);
+}
+
+
+
 \f
 static struct
 {
index aa46fe8..1e17488 100644 (file)
@@ -71,7 +71,7 @@ extern "C" {
    AM_PATH_GPGME macro) check that this header matches the installed
    library.  Warning: Do not edit the next line.  configure will do
    that for you!  */
-#define GPGME_VERSION "0.4.3"
+#define GPGME_VERSION "0.4.4"
 
 \f
 /* Some opaque data types used by GPGME.  */
index 9bb5e47..88ce7ca 100644 (file)
@@ -116,53 +116,6 @@ keylist_status_handler (void *priv, gpgme_status_code_t code, char *args)
 }
 
 \f
-static time_t
-parse_timestamp (char *timestamp)
-{
-  if (!*timestamp)
-    return 0;
-
-  if (strlen (timestamp) >= 15 && timestamp[8] == 'T')
-    {
-      struct tm buf;
-      int year;
-
-      year = atoi_4 (timestamp);
-      if (year < 1900)
-        return (time_t)(-1);
-
-      /* Fixme: We would better use a configure test to see whether
-         mktime can handle dates beyond 2038. */
-      if (sizeof (time_t) <= 4 && year >= 2038)
-        return (time_t)2145914603; /* 2037-12-31 23:23:23 */
-
-      memset (&buf, 0, sizeof buf);
-      buf.tm_year = year - 1900;
-      buf.tm_mon = atoi_2 (timestamp+4) - 1; 
-      buf.tm_mday = atoi_2 (timestamp+6);
-      buf.tm_hour = atoi_2 (timestamp+9);
-      buf.tm_min = atoi_2 (timestamp+11);
-      buf.tm_sec = atoi_2 (timestamp+13);
-
-#ifdef HAVE_TIMEGM
-      return timegm (&buf);
-#else
-      {
-        time_t tim;
-        
-        putenv ("TZ=UTC");
-        tim = mktime (&buf);
-#ifdef __GNUC__
-#warning fixme: we must somehow reset TZ here.  It is not threadsafe anyway.
-#endif
-        return tim;
-      }
-#endif /* !HAVE_TIMEGM */
-    }
-  else
-    return (time_t) strtoul (timestamp, NULL, 10);
-}
-
 
 static void
 set_mainkey_trust_info (gpgme_key_t key, const char *src)
@@ -519,11 +472,11 @@ keylist_colon_handler (void *priv, char *line)
 
       /* Field 6 has the timestamp (seconds).  */
       if (fields >= 6)
-       subkey->timestamp = parse_timestamp (field[5]);
+       subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
 
       /* Field 7 has the expiration time (seconds).  */
       if (fields >= 7)
-       subkey->expires = parse_timestamp (field[6]);
+       subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
 
       /* Field 8 has the X.509 serial number.  */
       if (fields >= 8 && (rectype == RT_CRT || rectype == RT_CRS))
@@ -587,11 +540,11 @@ keylist_colon_handler (void *priv, char *line)
 
       /* Field 6 has the timestamp (seconds).  */
       if (fields >= 6)
-       subkey->timestamp = parse_timestamp (field[5]);
+       subkey->timestamp = _gpgme_parse_timestamp (field[5], NULL);
 
       /* Field 7 has the expiration time (seconds).  */
       if (fields >= 7)
-       subkey->expires = parse_timestamp (field[6]);
+       subkey->expires = _gpgme_parse_timestamp (field[6], NULL);
 
       /* Field 8 is reserved (LID).  */
       /* Field 9 has the ownertrust.  */
@@ -687,11 +640,11 @@ keylist_colon_handler (void *priv, char *line)
       
       /* Field 6 has the timestamp (seconds).  */
       if (fields >= 6)
-       keysig->timestamp = parse_timestamp (field[5]);
+       keysig->timestamp = _gpgme_parse_timestamp (field[5], NULL);
 
       /* Field 7 has the expiration time (seconds).  */
       if (fields >= 7)
-       keysig->expires = parse_timestamp (field[6]);
+       keysig->expires = _gpgme_parse_timestamp (field[6], NULL);
 
       /* Field 11 has the signature class (eg, 0x30 means revoked).  */
       if (fields >= 11)
index 089b34c..4c71f80 100644 (file)
@@ -153,8 +153,8 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp)
     }
   args = tail;
 
-  sig->timestamp = strtol (args, &tail, 0);
-  if (errno || args == tail || *tail != ' ')
+  sig->timestamp = _gpgme_parse_timestamp (args, &tail);
+  if (sig->timestamp == -1 || args == tail || *tail != ' ')
     {
       /* The crypto backend does not behave.  */
       free (sig);
index c087355..085b37c 100644 (file)
@@ -70,6 +70,15 @@ gpgme_error_t _gpgme_decode_c_string (const char *src, char **destp,
 gpgme_error_t _gpgme_decode_percent_string (const char *src, char **destp,
                                            size_t len);
 
+
+/* Parse the string TIMESTAMP into a time_t.  The string may either be
+   seconds since Epoch or in the ISO 8601 format like
+   "20390815T143012".  Returns 0 for an empty string or seconds since
+   Epoch. Leading spaces are skipped. If ENDP is not NULL, it will
+   point to the next non-parsed character in TIMESTRING. */
+time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);
+
+
 gpgme_error_t _gpgme_map_gnupg_error (char *err);
 
 \f
index b92e753..b3287bd 100644 (file)
@@ -258,16 +258,14 @@ parse_valid_sig (gpgme_signature_t sig, char *args)
   if (end)
     {
       char *tail;
-      errno = 0;
 
-      /* FIXME: We need to cope with ISO time strings here. */
-      sig->timestamp = strtol (end, &tail, 0);
-      if (errno || end == tail || (*tail && *tail != ' '))
+      sig->timestamp = _gpgme_parse_timestamp (end, &tail);
+      if (sig->timestamp == -1 || end == tail || (*tail && *tail != ' '))
        return gpg_error (GPG_ERR_INV_ENGINE);
       end = tail;
      
-      sig->exp_timestamp = strtol (end, &tail, 0);
-      if (errno || end == tail || (*tail && *tail != ' '))
+      sig->exp_timestamp = _gpgme_parse_timestamp (end, &tail);
+      if (sig->exp_timestamp == -1 || end == tail || (*tail && *tail != ' '))
        return gpg_error (GPG_ERR_INV_ENGINE);
     }
   return 0;