admserv/cgi-src40/viewdata.c | 130 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 20 deletions(-)
New commits: commit 3d218e2ac488244c2aed2feacca66ed54f4bdb4c Author: Mark Reynolds mreynolds@redhat.com Date: Wed Aug 27 15:19:44 2014 -0400
Ticket 47495 - admin express: wrong instance creation time
Bug Description: Admin express attempted to convert a gmtime value as if it was in the format: YYYYmmddHHMMSS
This gave the wrong value in Admin Express.
Fix Description: Propeperly convert gmtime - reused the same functions 389-ds-base uses to convert a gmtime to a nice string.
https://fedorahosted.org/389/ticket/47495
Reviewed by: nhosoi(Thanks!)
diff --git a/admserv/cgi-src40/viewdata.c b/admserv/cgi-src40/viewdata.c index 5cba168..a4043fd 100644 --- a/admserv/cgi-src40/viewdata.c +++ b/admserv/cgi-src40/viewdata.c @@ -266,9 +266,111 @@ int get_product_url(LDAP *server, char *sie, char **text, char **url) { return 1; }
+/* + * These functions: strntoul, read_genTime, and parse_genTime, are taken + * from 389-ds-base source (time.c) + */ +static unsigned long +strntoul( char *from, size_t len, int base ) +{ + unsigned long result; + char c = from[ len ];
-void output_data(LDAP *server, char *sie) { + from[ len ] = '\0'; + result = strtoul( from, NULL, base ); + from[ len ] = c; + + return result; +}
+static time_t +read_genTime(struct berval *from) +{ + struct tm t; + time_t retTime; + time_t diffsec = 0; + int i, gflag = 0, havesec = 0; + + memset (&t, 0, sizeof(t)); + t.tm_isdst = -1; + t.tm_year = strntoul (from->bv_val , 4, 10) - 1900L; + t.tm_mon = strntoul (from->bv_val + 4, 2, 10) - 1; + t.tm_mday = strntoul (from->bv_val + 6, 2, 10); + t.tm_hour = strntoul (from->bv_val + 8, 2, 10); + t.tm_min = strntoul (from->bv_val + 10, 2, 10); + i = 12; + /* + * the string can end with Z or -xxxx or +xxxx + * or before to have the Z/+/- we may have two digits for the seconds. + * If there's no Z/+/-, it means it's been expressed as local time + * (not standard). + */ + while (from->bv_val[i]) { + switch (from->bv_val[i]) { + case 'Z': + case 'z': + gflag = 1; + ++i; + break; + case '+': /* Offset from GMT is on 4 digits */ + i++; + diffsec -= strntoul (from->bv_val + i, 4, 10); + gflag = 1; + i += 4; + break; + case '-': /* Offset from GMT is on 4 digits */ + i++; + diffsec += strntoul (from->bv_val + i, 4, 10); + gflag = 1; + i += 4; + break; + default: + if (havesec){ + /* Ignore milliseconds */ + i++; + } else { + t.tm_sec = strntoul (from->bv_val + i, 2, 10); + havesec = 1; + i += 2; + } + } /* end switch */ + } + if (gflag){ + PRTime pt; + PRExplodedTime expt = {0}; + unsigned long year = strntoul (from->bv_val , 4, 10); + + expt.tm_year = (PRInt16)year; + expt.tm_month = t.tm_mon; + expt.tm_mday = t.tm_mday; + expt.tm_hour = t.tm_hour; + expt.tm_min = t.tm_min; + expt.tm_sec = t.tm_sec; + /* This is a GMT time */ + expt.tm_params.tp_gmt_offset = 0; + expt.tm_params.tp_dst_offset = 0; + /* PRTime is expressed in microseconds */ + pt = PR_ImplodeTime(&expt) / 1000000L; + retTime = (time_t)pt; + return (retTime + diffsec); + } else { + return mktime (&t); + } +} + +static time_t +parse_genTime (char* from) +{ + struct berval tbv; + tbv.bv_val = from; + tbv.bv_len = strlen (from); + + return read_genTime(&tbv); +} + +void +output_data(LDAP *server, char *sie) +{ LDAPMessage *entry; char **vals; int ldapError; @@ -291,29 +393,17 @@ void output_data(LDAP *server, char *sie) {
if((vals = util_ldap_get_values(server, entry, "installationtimestamp"))) { - struct tm tm = {0}; + time_t parsed_time; char buf[BIG_LINE]; - int rc; - - /* only PARSE YYYYmmddHHMMSS */ - rc = sscanf(vals[0], "%4d%2d%2d%2d%2d%2d", &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + char *inst_time;
- if (rc < 6) { - PR_snprintf(buf, sizeof(buf), "Error: date [%s] not in YYYYmmddHHMMSS format", vals[0]); + if( (parsed_time = parse_genTime (vals[0])) && + (inst_time = ctime_r(&parsed_time, buf)) ) + { + PR_snprintf(buf, sizeof(buf), "%s %s", inst_time, daylight ? tzname[1] : tzname[0]); } else { - tm.tm_year -= 1900; /* the number of years since 1900 */ - tm.tm_mon -= 1; /* The number of month since January, in the range 0 to 11 */ - -#ifdef LINUX - strftime(buf, BIG_LINE, "%b %d, %Y %T %p", &tm); - tzset(); - PR_snprintf(buf, sizeof(buf), "%s %s", buf, daylight ? tzname[1] : tzname[0]); -#else - strftime(buf, sizeof(buf), "%b %d, %Y %T %p %Z", &tm); -#endif + PR_snprintf(buf, sizeof(buf), "Error: date [%s] not in correct format", vals[0]); } - util_ldap_value_free(vals); vals = NULL; fprintf(stdout, (const char*)getResourceString(DBT_OUTPUT_DATA_DATE), buf);
389-commits@lists.fedoraproject.org