Better support unsigned time_t
authorWerner Koch <wk@gnupg.org>
Wed, 27 Oct 2010 11:26:53 +0000 (11:26 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 27 Oct 2010 11:26:53 +0000 (11:26 +0000)
ChangeLog
acinclude.m4
common/ChangeLog
common/gettime.c
configure.ac
g10/ChangeLog
g10/keygen.c
g10/keyid.c

index e8e0e11..49724a9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * acinclude.m4 (GNUPG_TIME_T_UNSIGNED): New.
+       * configure.ac (AC_HEADER_TIME): Include before checking time_t.
+       (GNUPG_TIME_T_UNSIGNED): Add.
+
 2010-10-26  Werner Koch  <wk@g10code.com>
 
        Release 2.1.0beta1.
 2010-10-26  Werner Koch  <wk@g10code.com>
 
        Release 2.1.0beta1.
index 28366ee..a37e0f5 100644 (file)
@@ -305,5 +305,28 @@ fi
 ])
 
 
 ])
 
 
-
-
+# GNUPG_TIME_T_UNSIGNED
+# Check whether time_t is unsigned
+#
+AC_DEFUN([GNUPG_TIME_T_UNSIGNED],
+  [ AC_CACHE_CHECK(whether time_t is unsigned, gnupg_cv_time_t_unsigned,
+     [AC_REQUIRE([AC_HEADER_TIME])dnl
+      AC_COMPILE_IFELSE([AC_LANG_BOOL_COMPILE_TRY(
+       [AC_INCLUDES_DEFAULT([])
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+],
+       [((time_t)-1) < 0])],
+       gnupg_cv_time_t_unsigned=no, gnupg_cv_time_t_unsigned=yes)])
+    if test $gnupg_cv_time_t_unsigned = yes; then
+      AC_DEFINE(HAVE_UNSIGNED_TIME_T,1,[Defined if time_t is an unsigned type])
+    fi
+])# GNUPG_TIME_T_UNSIGNED
index 38856f6..9f4db9b 100644 (file)
@@ -1,3 +1,11 @@
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * gettime.c (gnupg_get_isotime): Compare to (time_t)-1.
+       (epoch2isotime): Ditto.
+       (IS_INVALID_TIME_T): New.
+       (asctimestamp): Use lNew macro.
+       (strtimestamp, isotimestamp): Ditto.  Use snprintf.
+
 2010-10-25  Werner Koch  <wk@g10code.com>
 
        * logging.c (do_log): Rename to log_log and make global.
 2010-10-25  Werner Koch  <wk@g10code.com>
 
        * logging.c (do_log): Rename to log_log and make global.
index e54c3a6..1ccbbc6 100644 (file)
 #include "i18n.h"
 #include "gettime.h"
 
 #include "i18n.h"
 #include "gettime.h"
 
+#ifdef HAVE_UNSIGNED_TIME_T
+# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
+#else 
+  /* Error or 32 bit time_t and value after 2038-01-19.  */
+# define IS_INVALID_TIME_T(a) ((a) < 0)
+#endif
+
+
 static unsigned long timewarp;
 static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode;
 
 static unsigned long timewarp;
 static enum { NORMAL = 0, FROZEN, FUTURE, PAST } timemode;
 
@@ -59,7 +67,7 @@ gnupg_get_isotime (gnupg_isotime_t timebuf)
 {
   time_t atime = gnupg_get_time ();
     
 {
   time_t atime = gnupg_get_time ();
     
-  if (atime < 0)
+  if (atime == (time_t)(-1))
     *timebuf = 0;
   else 
     {
     *timebuf = 0;
   else 
     {
@@ -223,7 +231,7 @@ isotime2epoch (const char *string)
 void
 epoch2isotime (gnupg_isotime_t timebuf, time_t atime)
 {
 void
 epoch2isotime (gnupg_isotime_t timebuf, time_t atime)
 {
-  if (atime < 0)
+  if (atime == (time_t)(-1))
     *timebuf = 0;
   else 
     {
     *timebuf = 0;
   else 
     {
@@ -283,21 +291,23 @@ strtimevalue( u32 value )
  * Note: this function returns GMT
  */
 const char *
  * Note: this function returns GMT
  */
 const char *
-strtimestamp( u32 stamp )
+strtimestamp (u32 stamp)
 {
 {
-    static char buffer[11+5];
-    struct tm *tp;
-    time_t atime = stamp;
+  static char buffer[11+5];
+  struct tm *tp;
+  time_t atime = stamp;
     
     
-    if (atime < 0) {
-        strcpy (buffer, "????" "-??" "-??");
+  if (IS_INVALID_TIME_T (atime))
+    {
+      strcpy (buffer, "????" "-??" "-??");
     }
     }
-    else {
-        tp = gmtime( &atime );
-        sprintf(buffer,"%04d-%02d-%02d",
+  else
+    {
+      tp = gmtime( &atime );
+      snprintf (buffer, sizeof buffer, "%04d-%02d-%02d",
                 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     }
                 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     }
-    return buffer;
+  return buffer;
 }
 
 
 }
 
 
@@ -311,16 +321,16 @@ isotimestamp (u32 stamp)
   struct tm *tp;
   time_t atime = stamp;
   
   struct tm *tp;
   time_t atime = stamp;
   
-  if (atime < 0)
+  if (IS_INVALID_TIME_T (atime))
     {
       strcpy (buffer, "????" "-??" "-??" " " "??" ":" "??" ":" "??");
     }
   else
     {
       tp = gmtime ( &atime );
     {
       strcpy (buffer, "????" "-??" "-??" " " "??" ":" "??" ":" "??");
     }
   else
     {
       tp = gmtime ( &atime );
-      sprintf (buffer,"%04d-%02d-%02d %02d:%02d:%02d",
-               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
-               tp->tm_hour, tp->tm_min, tp->tm_sec);
+      snprintf (buffer, sizeof buffer, "%04d-%02d-%02d %02d:%02d:%02d",
+                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+                tp->tm_hour, tp->tm_min, tp->tm_sec);
     }
   return buffer;
 }
     }
   return buffer;
 }
@@ -339,7 +349,7 @@ asctimestamp (u32 stamp)
   struct tm *tp;
   time_t atime = stamp;
 
   struct tm *tp;
   time_t atime = stamp;
 
-  if (atime < 0)
+  if (IS_INVALID_TIME_T (atime))
     {
       strcpy (buffer, "????" "-??" "-??");
       return buffer;
     {
       strcpy (buffer, "????" "-??" "-??");
       return buffer;
index cc13a13..0bb69d2 100644 (file)
@@ -1160,6 +1160,7 @@ AC_CHECK_SIZEOF(unsigned short)
 AC_CHECK_SIZEOF(unsigned int)
 AC_CHECK_SIZEOF(unsigned long)
 AC_CHECK_SIZEOF(unsigned long long)
 AC_CHECK_SIZEOF(unsigned int)
 AC_CHECK_SIZEOF(unsigned long)
 AC_CHECK_SIZEOF(unsigned long long)
+AC_HEADER_TIME
 AC_CHECK_SIZEOF(time_t,,[[
 #include <stdio.h>
 #if TIME_WITH_SYS_TIME
 AC_CHECK_SIZEOF(time_t,,[[
 #include <stdio.h>
 #if TIME_WITH_SYS_TIME
@@ -1173,6 +1174,7 @@ AC_CHECK_SIZEOF(time_t,,[[
 # endif
 #endif
 ]])
 # endif
 #endif
 ]])
+GNUPG_TIME_T_UNSIGNED
 
 
 # Ensure that we have UINT64_C before we bother to check for uint64_t
 
 
 # Ensure that we have UINT64_C before we bother to check for uint64_t
index 65f9117..2da7b3c 100644 (file)
@@ -1,3 +1,10 @@
+2010-10-27  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (ask_expire_interval): Do not print the y2038 if we
+       have an unsigned time_t.
+       * keyid.c (IS_INVALID_TIME_T): New.
+       (mk_datestr): Use it to detect the y2038 problem.
+
 2010-10-26  Werner Koch  <wk@g10code.com>
 
        * keyedit.c (change_passphrase): Handle the passwd_nonce.
 2010-10-26  Werner Koch  <wk@g10code.com>
 
        * keyedit.c (change_passphrase): Handle the passwd_nonce.
index 03d53ce..e718a83 100644 (file)
@@ -1854,7 +1854,7 @@ ask_expire_interval(int object,const char *def_expire)
                       ? _("Key expires at %s\n")
                       : _("Signature expires at %s\n"),
                       asctimestamp((ulong)(curtime + interval) ) );
                       ? _("Key expires at %s\n")
                       : _("Signature expires at %s\n"),
                       asctimestamp((ulong)(curtime + interval) ) );
-#if SIZEOF_TIME_T <= 4
+#if SIZEOF_TIME_T <= 4 && !defined (HAVE_UNSIGNED_TIME_T)
            if ( (time_t)((ulong)(curtime+interval)) < 0 )
              tty_printf (_("Your system can't display dates beyond 2038.\n"
                             "However, it will be correctly handled up to"
            if ( (time_t)((ulong)(curtime+interval)) < 0 )
              tty_printf (_("Your system can't display dates beyond 2038.\n"
                             "However, it will be correctly handled up to"
index 1284287..62ce036 100644 (file)
 
 #define KEYID_STR_SIZE 19
 
 
 #define KEYID_STR_SIZE 19
 
+#ifdef HAVE_UNSIGNED_TIME_T
+# define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
+#else 
+  /* Error or 32 bit time_t and value after 2038-01-19.  */
+# define IS_INVALID_TIME_T(a) ((a) < 0)
+#endif
+
 
 /* Return a letter describing the public key algorithms.  */
 int
 
 /* Return a letter describing the public key algorithms.  */
 int
@@ -446,12 +453,8 @@ mk_datestr (char *buffer, time_t atime)
 {
   struct tm *tp;
 
 {
   struct tm *tp;
 
-  /* Note: VMS uses an unsigned time_t thus the compiler yields a
-     warning here.  You may ignore this warning or def out this test
-     for VMS.  The proper way to handle this would be a configure test
-     to a detect properly implemented unsigned time_t.  */
-  if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
-    strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
+  if (IS_INVALID_TIME_T (atime))
+    strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
   else 
     {
       tp = gmtime (&atime);
   else 
     {
       tp = gmtime (&atime);