/** * e2k_parse_timestamp: * @timestamp: an ISO8601 timestamp returned by the Exchange server * * Converts @timestamp to a %time_t value. @timestamp must be in one * of the two ISO8601 variants used by Exchange. * * Note that the timestamps used (in most contexts) by Exchange have * millisecond resolution, so converting them to %time_t loses * resolution. Since ISO8601 timestamps can be compared using * strcmp(), it is often best to keep them as strings. * * Return value: the %time_t corresponding to @timestamp, or -1 on * error. **/ time_t e2k_parse_timestamp (const char *timestamp) { struct tm tm; tm.tm_year = strtoul (timestamp, (char **)×tamp, 10) - 1900; if (*timestamp++ != '-') return -1; tm.tm_mon = strtoul (timestamp, (char **)×tamp, 10) - 1; if (*timestamp++ != '-') return -1; tm.tm_mday = strtoul (timestamp, (char **)×tamp, 10); if (*timestamp++ != 'T') return -1; tm.tm_hour = strtoul (timestamp, (char **)×tamp, 10); if (*timestamp++ != ':') return -1; tm.tm_min = strtoul (timestamp, (char **)×tamp, 10); if (*timestamp++ != ':') return -1; tm.tm_sec = strtoul (timestamp, (char **)×tamp, 10); if (*timestamp != '.' && *timestamp != 'Z') return -1; return e_mktime_utc (&tm); }
static void add_data_for_status (E2kFreebusy *fb, GPtrArray *monthyears, GPtrArray *fbdatas, GArray *events) { E2kFreebusyEvent evt; int i, monthyear; GByteArray *fbdata; unsigned char *p; struct tm tm; if (!monthyears || !fbdatas) return; memset (&tm, 0, sizeof (tm)); for (i = 0; i < monthyears->len && i < fbdatas->len; i++) { monthyear = atoi (monthyears->pdata[i]); fbdata = fbdatas->pdata[i]; tm.tm_year = (monthyear >> 4) - 1900; tm.tm_mon = (monthyear & 0xF) - 1; for (p = fbdata->data; p + 3 < fbdata->data + fbdata->len; p += 4) { tm.tm_mday = 1; tm.tm_hour = 0; tm.tm_min = p[0] + p[1] * 256; evt.start = e_mktime_utc (&tm); tm.tm_mday = 1; tm.tm_hour = 0; tm.tm_min = p[2] + p[3] * 256; evt.end = e_mktime_utc (&tm); g_array_append_val (events, evt); } } merge_events (events); }
static void add_events (GArray *events_array, E2kProperties *props, const char *month_list_prop, const char *data_list_prop) { E2kFreebusyEvent *events = (E2kFreebusyEvent *)events_array->data; int i, evt_start, evt_end, monthyear; struct tm start_tm, end_tm; time_t start, end; GPtrArray *monthyears, *datas; GByteArray *data; char startend[4]; if (!events_array->len) { e2k_properties_remove (props, month_list_prop); e2k_properties_remove (props, data_list_prop); return; } monthyears = g_ptr_array_new (); start_tm = *gmtime (&events[0].start); end_tm = *gmtime (&events[events_array->len - 1].end); while (start_tm.tm_year <= end_tm.tm_year || start_tm.tm_mon <= end_tm.tm_mon) { monthyear = ((start_tm.tm_year + 1900) * 16) + (start_tm.tm_mon + 1); g_ptr_array_add (monthyears, g_strdup_printf ("%d", monthyear)); start_tm.tm_mon++; if (start_tm.tm_mon == 12) { start_tm.tm_year++; start_tm.tm_mon = 0; } } e2k_properties_set_int_array (props, month_list_prop, monthyears); datas = g_ptr_array_new (); start = events[0].start; i = 0; while (i < events_array->len) { start_tm = *gmtime (&start); start_tm.tm_mon++; end = e_mktime_utc (&start_tm); data = g_byte_array_new (); while (i << events_array->len && events[i].end > start && events[i].start < end) { if (events[i].start < start) evt_start = 0; else evt_start = (events[i].start - start) / 60; if (events[i].end > end) evt_end = (end - start) / 60; else evt_end = (events[i].end - start) / 60; startend[0] = evt_start & 0xFF; startend[1] = evt_start >> 8; startend[2] = evt_end & 0xFF; startend[3] = evt_end >> 8; g_byte_array_append (data, startend, 4); i++; } g_ptr_array_add (datas, data); start = end; } e2k_properties_set_binary_array (props, data_list_prop, datas); }
static time_t decode_broken_date (struct _date_token *tokens, int *tzone) { gboolean got_wday, got_month, got_tzone; int hour, min, sec, offset, n; struct _date_token *token; struct tm tm; time_t time; memset ((void *) &tm, 0, sizeof (struct tm)); got_wday = got_month = got_tzone = FALSE; offset = 0; token = tokens; while (token) { if (is_weekday (token) && !got_wday) { if ((n = get_wday (token->start, token->len)) != -1) { d(printf ("weekday; ")); got_wday = TRUE; tm.tm_wday = n; goto next_token; } } if (is_month (token) && !got_month) { if ((n = get_month (token->start, token->len)) != -1) { d(printf ("month; ")); got_month = TRUE; tm.tm_mon = n; goto next_token; } } if (is_time (token) && !tm.tm_hour && !tm.tm_min && !tm.tm_sec) { if (get_time (token->start, token->len, &hour, &min, &sec)) { d(printf ("time; ")); tm.tm_hour = hour; tm.tm_min = min; tm.tm_sec = sec; goto next_token; } } if (is_tzone (token) && !got_tzone) { struct _date_token *t = token; if ((n = get_tzone (&t)) != -1) { d(printf ("tzone; ")); got_tzone = TRUE; offset = n; goto next_token; } } if (is_numeric (token)) { if (token->len == 4 && !tm.tm_year) { if ((n = get_year (token->start, token->len)) != -1) { d(printf ("year; ")); tm.tm_year = n - 1900; goto next_token; } } else { if (!got_month && !got_wday && token->next && is_numeric (token->next)) { d(printf ("mon; ")); n = decode_int (token->start, token->len); got_month = TRUE; tm.tm_mon = n - 1; goto next_token; } else if (!tm.tm_mday && (n = get_mday (token->start, token->len)) != -1) { d(printf ("mday; ")); tm.tm_mday = n; goto next_token; } else if (!tm.tm_year) { d(printf ("2-digit year; ")); n = get_year (token->start, token->len); tm.tm_year = n - 1900; goto next_token; } } } d(printf ("???; ")); next_token: token = token->next; } d(printf ("\n")); time = e_mktime_utc (&tm); /* time is now GMT of the time we want, but not offset by the timezone ... */ /* this should convert the time to the GMT equiv time */ time -= ((offset / 100) * 60 * 60) + (offset % 100) * 60; if (tzone) *tzone = offset; return time; }