From 2e82b095cd2ebd3ecc1635bb5cbe65eb99de7ae7 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 27 Oct 2010 11:26:53 +0000 Subject: [PATCH] Better support unsigned time_t --- ChangeLog | 6 ++++++ acinclude.m4 | 27 +++++++++++++++++++++++++-- common/ChangeLog | 8 ++++++++ common/gettime.c | 44 +++++++++++++++++++++++++++----------------- configure.ac | 2 ++ g10/ChangeLog | 7 +++++++ g10/keygen.c | 2 +- g10/keyid.c | 15 +++++++++------ 8 files changed, 85 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8e0e1155..49724a969 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-10-27 Werner Koch + + * 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 Release 2.1.0beta1. diff --git a/acinclude.m4 b/acinclude.m4 index 28366ee38..a37e0f528 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -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 +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# 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 diff --git a/common/ChangeLog b/common/ChangeLog index 38856f6f2..9f4db9b81 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,11 @@ +2010-10-27 Werner Koch + + * 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 * logging.c (do_log): Rename to log_log and make global. diff --git a/common/gettime.c b/common/gettime.c index e54c3a628..1ccbbc654 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -29,6 +29,14 @@ #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; @@ -59,7 +67,7 @@ gnupg_get_isotime (gnupg_isotime_t timebuf) { time_t atime = gnupg_get_time (); - if (atime < 0) + if (atime == (time_t)(-1)) *timebuf = 0; else { @@ -223,7 +231,7 @@ isotime2epoch (const char *string) void epoch2isotime (gnupg_isotime_t timebuf, time_t atime) { - if (atime < 0) + if (atime == (time_t)(-1)) *timebuf = 0; else { @@ -283,21 +291,23 @@ strtimevalue( u32 value ) * 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 ); } - return buffer; + return buffer; } @@ -311,16 +321,16 @@ isotimestamp (u32 stamp) struct tm *tp; time_t atime = stamp; - if (atime < 0) + if (IS_INVALID_TIME_T (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; } @@ -339,7 +349,7 @@ asctimestamp (u32 stamp) struct tm *tp; time_t atime = stamp; - if (atime < 0) + if (IS_INVALID_TIME_T (atime)) { strcpy (buffer, "????" "-??" "-??"); return buffer; diff --git a/configure.ac b/configure.ac index cc13a13c0..0bb69d2f3 100644 --- a/configure.ac +++ b/configure.ac @@ -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_HEADER_TIME AC_CHECK_SIZEOF(time_t,,[[ #include #if TIME_WITH_SYS_TIME @@ -1173,6 +1174,7 @@ AC_CHECK_SIZEOF(time_t,,[[ # endif #endif ]]) +GNUPG_TIME_T_UNSIGNED # Ensure that we have UINT64_C before we bother to check for uint64_t diff --git a/g10/ChangeLog b/g10/ChangeLog index 65f9117c1..2da7b3c4f 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,10 @@ +2010-10-27 Werner Koch + + * 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 * keyedit.c (change_passphrase): Handle the passwd_nonce. diff --git a/g10/keygen.c b/g10/keygen.c index 03d53ce0b..e718a83e8 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -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) ) ); -#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" diff --git a/g10/keyid.c b/g10/keyid.c index 128428720..62ce03685 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -37,6 +37,13 @@ #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 @@ -446,12 +453,8 @@ mk_datestr (char *buffer, time_t atime) { 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);