admserv/cgi-src40/viewdata.c | 130 ++++++++++++++++++++++++++++++++++++-------
1 file changed, 110 insertions(+), 20 deletions(-)
New commits:
commit 3d218e2ac488244c2aed2feacca66ed54f4bdb4c
Author: Mark Reynolds <mreynolds(a)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);