diff options
author | tony.luck@intel.com <tony.luck@intel.com> | 2005-04-29 20:27:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-29 20:27:04 -0700 |
commit | d167f147dc6995e452cdc374ffcd07f5d9abf0bc (patch) | |
tree | 8602fe7cb4bf668fd021ab3bfb2082ac7d535e57 /commit-tree.c | |
parent | e1a1388d858fa8522f187d3fdea92ff84e21528c (diff) | |
download | git-d167f147dc6995e452cdc374ffcd07f5d9abf0bc.tar.gz git-d167f147dc6995e452cdc374ffcd07f5d9abf0bc.tar.xz |
[PATCH] Fix AUTHOR_DATE timezone confusion
This switches git-commit-tree to using curl_getdate() for the
AUTHOR_DATE, and thus fixes the problem with "mktime()" parsing dates in
the local timezone. It also ends up being more permissive about the
format of the date.
Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'commit-tree.c')
-rw-r--r-- | commit-tree.c | 143 |
1 files changed, 10 insertions, 133 deletions
diff --git a/commit-tree.c b/commit-tree.c index 23de13361..7c23b9b50 100644 --- a/commit-tree.c +++ b/commit-tree.c @@ -10,6 +10,7 @@ #include <string.h> #include <ctype.h> #include <time.h> +#include <curl/curl.h> #define BLOCKING (1ul << 14) @@ -80,146 +81,22 @@ static void remove_special(char *p) } } -static const char *month_names[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -static const char *weekday_names[] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; - - -static char *skipfws(char *str) -{ - while (isspace(*str)) - str++; - return str; -} - - /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822 (i.e. English) day/month names, and it doesn't work correctly with %z. */ -static void parse_rfc2822_date(char *date, char *result, int maxlen) +static void parse_date(char *date, time_t *now, char *result, int maxlen) { - struct tm tm; char *p; - int i, offset; time_t then; - memset(&tm, 0, sizeof(tm)); - - /* Skip day-name */ - p = skipfws(date); - if (!isdigit(*p)) { - for (i=0; i<7; i++) { - if (!strncmp(p,weekday_names[i],3) && p[3] == ',') { - p = skipfws(p+4); - goto day; - } - } - return; - } - - /* day */ - day: - tm.tm_mday = strtoul(p, &p, 10); - - if (tm.tm_mday < 1 || tm.tm_mday > 31) - return; - - if (!isspace(*p)) - return; - - p = skipfws(p); - - /* month */ - - for (i=0; i<12; i++) { - if (!strncmp(p, month_names[i], 3) && isspace(p[3])) { - tm.tm_mon = i; - p = skipfws(p+strlen(month_names[i])); - goto year; - } - } - return; /* Error -- bad month */ - - /* year */ - year: - tm.tm_year = strtoul(p, &p, 10); - - if (!tm.tm_year && !isspace(*p)) - return; - - if (tm.tm_year > 1900) - tm.tm_year -= 1900; - - p=skipfws(p); - - /* hour */ - if (!isdigit(*p)) - return; - tm.tm_hour = strtoul(p, &p, 10); - - if (!tm.tm_hour > 23) - return; - - if (*p != ':') - return; /* Error -- bad time */ - p++; - - /* minute */ - if (!isdigit(*p)) - return; - tm.tm_min = strtoul(p, &p, 10); - - if (!tm.tm_min > 59) + if ((then = curl_getdate(date, now)) == 0) return; - if (isspace(*p)) - goto zone; - - if (*p != ':') - return; /* Error -- bad time */ - p++; - - /* second */ - if (!isdigit(*p)) - return; - tm.tm_sec = strtoul(p, &p, 10); - - if (!tm.tm_sec > 59) - return; - - if (!isspace(*p)) - return; - - zone: - p = skipfws(p); - - if (*p == '-') - offset = -60; - else if (*p == '+') - offset = 60; - else - return; - - if (!isdigit(p[1]) || !isdigit(p[2]) || !isdigit(p[3]) || !isdigit(p[4])) - return; - - i = strtoul(p+1, NULL, 10); - offset *= ((i % 100) + ((i / 100) * 60)); - - if (*(skipfws(p + 5))) - return; - - then = mktime(&tm); /* mktime appears to ignore the GMT offset, stupidly */ - if (then == -1) - return; - - then -= offset; - - snprintf(result, maxlen, "%lu %5.5s", then, p); + /* find the timezone at the end */ + p = date + strlen(date); + while (p > date && isdigit(*--p)) + ; + if ((*p == '+' || *p == '-') && strlen(p) == 5) + snprintf(result, maxlen, "%lu %5.5s", then, p); } static void check_valid(unsigned char *sha1, const char *expect) @@ -298,7 +175,7 @@ int main(int argc, char **argv) email = getenv("AUTHOR_EMAIL") ? : realemail; audate = getenv("AUTHOR_DATE"); if (audate) - parse_rfc2822_date(audate, date, sizeof(date)); + parse_date(audate, &now, date, sizeof(date)); remove_special(gecos); remove_special(realgecos); remove_special(commitgecos); remove_special(email); remove_special(realemail); remove_special(commitemail); |