Tue, 11 Jul 2017 23:43:33 -0400
Change purple_log_new to use GDateTime.
| finch/gntlog.c | file | annotate | diff | comparison | revisions | |
| libpurple/account.c | file | annotate | diff | comparison | revisions | |
| libpurple/conversation.c | file | annotate | diff | comparison | revisions | |
| libpurple/log.c | file | annotate | diff | comparison | revisions | |
| libpurple/log.h | file | annotate | diff | comparison | revisions | |
| libpurple/plugins/log_reader.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtklog.c | file | annotate | diff | comparison | revisions | |
| pidgin/plugins/history.c | file | annotate | diff | comparison | revisions |
--- a/finch/gntlog.c Tue Jul 11 05:27:50 2017 -0400 +++ b/finch/gntlog.c Tue Jul 11 23:43:33 2017 -0400 @@ -96,12 +96,14 @@ return ret; } -static const char *log_get_date(PurpleLog *log) +static gchar *log_get_date(PurpleLog *log) { - if (log->tm) - return purple_date_format_full(log->tm); - else - return purple_date_format_full(localtime(&log->time)); + GDateTime *dt; + gchar *ret; + dt = g_date_time_to_local(log->time); + ret = g_date_time_format(dt, "%c"); + g_date_time_unref(dt); + return ret; } static void search_cb(GntWidget *button, FinchLogViewer *lv) @@ -132,11 +134,13 @@ char *read = purple_log_read((PurpleLog*)logs->data, NULL); if (read && *read && purple_strcasestr(read, search_term)) { PurpleLog *log = logs->data; + gchar *log_date = log_get_date(log); gnt_tree_add_row_last(GNT_TREE(lv->tree), log, - gnt_tree_create_row(GNT_TREE(lv->tree), log_get_date(log)), + gnt_tree_create_row(GNT_TREE(lv->tree), log_date), NULL); + g_free(log_date); } g_free(read); } @@ -183,15 +187,17 @@ return; if (log->type != PURPLE_LOG_SYSTEM) { + gchar *log_date = log_get_date(log); char *title; if (log->type == PURPLE_LOG_CHAT) title = g_strdup_printf(_("Conversation in %s on %s"), - log->name, log_get_date(log)); + log->name, log_date); else title = g_strdup_printf(_("Conversation with %s on %s"), - log->name, log_get_date(log)); + log->name, log_date); gnt_label_set_text(GNT_LABEL(viewer->label), title); + g_free(log_date); g_free(title); } @@ -223,16 +229,18 @@ /* Logs are made from trees in real life. This is a tree made from logs */ { - const char *pmonth; - char *month = NULL; + gchar *pmonth; + gchar *month = NULL; char prev_top_month[30] = ""; GList *logs = lv->logs; while (logs != NULL) { PurpleLog *log = logs->data; + GDateTime *dt; + gchar *log_date; - pmonth = purple_utf8_strftime(_("%B %Y"), - log->tm ? log->tm : localtime(&log->time)); + dt = g_date_time_to_local(log->time); + pmonth = g_date_time_format(dt, _("%B %Y")); if (!purple_strequal(pmonth, prev_top_month)) { month = g_strdup(pmonth); @@ -247,11 +255,15 @@ } /* sub */ + log_date = g_date_time_format(dt, "%c"); gnt_tree_add_row_last(GNT_TREE(lv->tree), log, - gnt_tree_create_row(GNT_TREE(lv->tree), log_get_date(log)), + gnt_tree_create_row(GNT_TREE(lv->tree), log_date), month); + g_free(log_date); + g_free(pmonth); + g_date_time_unref(dt); logs = logs->next; } }
--- a/libpurple/account.c Tue Jul 11 05:27:50 2017 -0400 +++ b/libpurple/account.c Tue Jul 11 23:43:33 2017 -0400 @@ -2218,13 +2218,20 @@ if(!priv->system_log && create){ PurplePresence *presence; int login_time; + GDateTime *dt; presence = purple_account_get_presence(account); login_time = purple_presence_get_login_time(presence); - - priv->system_log = purple_log_new(PURPLE_LOG_SYSTEM, - purple_account_get_username(account), account, NULL, - (login_time != 0) ? login_time : time(NULL), NULL); + if (login_time != 0) { + dt = g_date_time_new_from_unix_local(login_time); + } else { + dt = g_date_time_new_now_local(); + } + + priv->system_log = purple_log_new(PURPLE_LOG_SYSTEM, + purple_account_get_username(account), + account, NULL, dt); + g_date_time_unref(dt); } return priv->system_log;
--- a/libpurple/conversation.c Tue Jul 11 05:27:50 2017 -0400 +++ b/libpurple/conversation.c Tue Jul 11 23:43:33 2017 -0400 @@ -197,12 +197,15 @@ open_log(PurpleConversation *conv) { PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv); + GDateTime *dt; g_return_if_fail(priv != NULL); + dt = g_date_time_new_now_local(); priv->logs = g_list_append(NULL, purple_log_new(PURPLE_IS_CHAT_CONVERSATION(conv) ? PURPLE_LOG_CHAT : PURPLE_LOG_IM, priv->name, priv->account, - conv, time(NULL), NULL)); + conv, dt)); + g_date_time_unref(dt); } /* Functions that deal with PurpleMessage history */
--- a/libpurple/log.c Tue Jul 11 05:27:50 2017 -0400 +++ b/libpurple/log.c Tue Jul 11 23:43:33 2017 -0400 @@ -75,7 +75,7 @@ **************************************************************************/ PurpleLog *purple_log_new(PurpleLogType type, const char *name, PurpleAccount *account, - PurpleConversation *conv, time_t time, const struct tm *tm) + PurpleConversation *conv, GDateTime *time) { PurpleLog *log; @@ -87,33 +87,13 @@ log->name = g_strdup(purple_normalize(account, name)); log->account = account; log->conv = conv; - log->time = time; + if (time) + log->time = g_date_time_ref(time); + else + log->time = NULL; log->logger = purple_log_logger_get(); log->logger_data = NULL; - if (tm == NULL) - log->tm = NULL; - else - { - /* There's no need to zero this as we immediately do a direct copy. */ - log->tm = g_slice_new(struct tm); - - *(log->tm) = *tm; - -#ifdef HAVE_STRUCT_TM_TM_ZONE - /* XXX: This is so wrong... */ - if (log->tm->tm_zone != NULL) - { - char *tmp = g_locale_from_utf8(log->tm->tm_zone, -1, NULL, NULL, NULL); - if (tmp != NULL) - log->tm->tm_zone = tmp; - else - /* Just shove the UTF-8 bytes in and hope... */ - log->tm->tm_zone = g_strdup(log->tm->tm_zone); - } -#endif - } - if (log->logger && log->logger->create) log->logger->create(log); return log; @@ -125,15 +105,7 @@ if (log->logger && log->logger->finalize) log->logger->finalize(log); g_free(log->name); - - if (log->tm != NULL) - { -#ifdef HAVE_STRUCT_TM_TM_ZONE - /* XXX: This is so wrong... */ - g_free((char *)log->tm->tm_zone); -#endif - g_slice_free(struct tm, log->tm); - } + g_date_time_unref(log->time); PURPLE_DBUS_UNREGISTER_POINTER(log); g_slice_free(PurpleLog, log); @@ -266,8 +238,6 @@ int score; GSList *n; struct _purple_logsize_user *lu; - time_t now; - time(&now); lu = g_new(struct _purple_logsize_user, 1); lu->name = g_strdup(purple_normalize(account, name)); @@ -278,6 +248,7 @@ g_free(lu->name); g_free(lu); } else { + GDateTime *now = g_date_time_new_now_utc(); double score_double = 0.0; for (n = loggers; n; n = n->next) { PurpleLogLogger *logger = n->data; @@ -294,12 +265,13 @@ /* Activity score counts bytes in the log, exponentially decayed with a half-life of 14 days. */ score_double += purple_log_get_size(log) * - pow(0.5, difftime(now, log->time)/1209600.0); + pow(0.5, g_date_time_difference(now, log->time)/(14LL*G_TIME_SPAN_DAY)); purple_log_free(log); logs = g_list_delete_link(logs, logs); } } } + g_date_time_unref(now); score = (gint) ceil(score_double); g_hash_table_replace(logsize_users_decayed, lu, GINT_TO_POINTER(score)); @@ -508,7 +480,7 @@ const PurpleLog *a = y; const PurpleLog *b = z; - return b->time - a->time; + return g_date_time_compare(b->time, a->time); // TODO: swap? } GList *purple_log_get_logs(PurpleLogType type, const char *name, PurpleAccount *account) @@ -910,9 +882,9 @@ { /* This log is new */ char *dir; - struct tm *tm; + GDateTime *dt; const char *tz; - const char *date; + gchar *date; char *filename; char *path; @@ -922,14 +894,16 @@ purple_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); - tm = localtime(&log->time); - tz = purple_escape_filename(purple_utf8_strftime("%Z", tm)); - date = purple_utf8_strftime("%Y-%m-%d.%H%M%S%z", tm); + dt = g_date_time_to_local(log->time); + tz = purple_escape_filename(g_date_time_get_timezone_abbreviation(dt)); + date = g_date_time_format(dt, "%Y-%m-%d.%H%M%S%z"); + g_date_time_unref(dt); filename = g_strdup_printf("%s%s%s", date, tz, ext ? ext : ""); path = g_build_filename(dir, filename, NULL); g_free(dir); + g_free(date); g_free(filename); log->logger_data = data = g_slice_new0(PurpleLogCommonLoggerData); @@ -979,39 +953,16 @@ { PurpleLog *log; PurpleLogCommonLoggerData *data; - struct tm tm; -#if defined (HAVE_TM_GMTOFF) && defined (HAVE_STRUCT_TM_TM_ZONE) - long tz_off; - const char *rest, *end; - time_t stamp = purple_str_to_time(purple_unescape_filename(filename), FALSE, &tm, &tz_off, &rest); - - /* As zero is a valid offset, PURPLE_NO_TZ_OFF means no offset was - * provided. See util.h. Yes, it's kinda ugly. */ - if (tz_off != PURPLE_NO_TZ_OFF) - tm.tm_gmtoff = tz_off - tm.tm_gmtoff; + GDateTime *stamp = purple_str_to_date_time(purple_unescape_filename(filename), FALSE); - if (stamp == 0 || rest == NULL || (end = strchr(rest, '.')) == NULL || strchr(rest, ' ') != NULL) - { - log = purple_log_new(type, name, account, NULL, stamp, NULL); - } - else - { - char *tmp = g_strndup(rest, end - rest); - tm.tm_zone = tmp; - log = purple_log_new(type, name, account, NULL, stamp, &tm); - g_free(tmp); - } -#else - time_t stamp = purple_str_to_time(filename, FALSE, &tm, NULL, NULL); - - log = purple_log_new(type, name, account, NULL, stamp, (stamp != 0) ? &tm : NULL); -#endif - + log = purple_log_new(type, name, account, NULL, stamp); log->logger = logger; log->logger_data = data = g_slice_new0(PurpleLogCommonLoggerData); data->path = g_build_filename(path, filename, NULL); list = g_list_prepend(list, log); + + g_date_time_unref(stamp); } } g_dir_close(dir); @@ -1303,7 +1254,8 @@ if(!data) { const char *proto = purple_protocol_class_list_icon(protocol, log->account, NULL); - const char *date; + GDateTime *dt; + gchar *date; purple_log_common_writer(log, ".html"); data = log->logger_data; @@ -1312,7 +1264,9 @@ if(!data->file) return 0; - date = purple_date_format_full(localtime(&log->time)); + dt = g_date_time_to_local(log->time); + date = g_date_time_format(dt, "%c"); + g_date_time_unref(dt); written += fprintf(data->file, "<html><head>"); written += fprintf(data->file, "<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">"); @@ -1327,6 +1281,7 @@ written += fprintf(data->file, "%s", header); written += fprintf(data->file, "</title></head><body>"); written += fprintf(data->file, "<h3>%s</h3>\n", header); + g_free(date); g_free(header); } @@ -1462,6 +1417,8 @@ * that you open a convo with someone, but don't say anything. */ const char *proto = purple_protocol_class_list_icon(protocol, log->account, NULL); + GDateTime *dt; + gchar *date; purple_log_common_writer(log, ".txt"); data = log->logger_data; @@ -1470,14 +1427,18 @@ if(!data || !data->file) return 0; + dt = g_date_time_to_local(log->time); + date = g_date_time_format(dt, "%c"); if (log->type == PURPLE_LOG_SYSTEM) written += fprintf(data->file, "System log for account %s (%s) connected at %s\n", purple_account_get_username(log->account), proto, - purple_date_format_full(localtime(&log->time))); + date); else written += fprintf(data->file, "Conversation with %s at %s on %s (%s)\n", - log->name, purple_date_format_full(localtime(&log->time)), + log->name, date, purple_account_get_username(log->account), proto); + g_free(date); + g_date_time_unref(dt); } /* if we can't write to the file, give up before we hurt ourselves */ @@ -1594,13 +1555,13 @@ int file_fd, index_fd; char *index_tmp; char buf[BUF_LONG]; - struct tm tm; - char month[4]; + gint year, month, day, hour, minute, second; + char month_str[4]; struct old_logger_data *data = NULL; int logfound = 0; int lastoff = 0; int newlen; - time_t lasttime = 0; + GDateTime *lasttime = NULL; PurpleLog *log = NULL; GList *list = NULL; @@ -1657,9 +1618,9 @@ unsigned long idx_time; if (sscanf(buf, "%d\t%d\t%lu", &lastoff, &newlen, &idx_time) == 3) { - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, -1, NULL); + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, NULL); log->logger = old_logger; - log->time = (time_t)idx_time; + log->time = g_date_time_new_from_unix_local(idx_time); /* IMPORTANT: Always set all members of struct old_logger_data */ data = g_slice_new(struct old_logger_data); @@ -1734,9 +1695,9 @@ newlen--; if (newlen != 0) { - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, -1, NULL); + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, NULL); log->logger = old_logger; - log->time = lasttime; + log->time = g_date_time_ref(lasttime); /* IMPORTANT: Always set all members of struct old_logger_data */ data = g_slice_new(struct old_logger_data); @@ -1757,49 +1718,48 @@ lastoff = offset; g_snprintf(convostart, length, "%s", temp); - memset(&tm, 0, sizeof(tm)); - if (sscanf(convostart, "%*s %3s %d %d:%d:%d %d", month, - &tm.tm_mday, &tm.tm_hour, &tm.tm_min, - &tm.tm_sec, &tm.tm_year) != 6) + year = month = day = hour = minute = second = 0; + if (sscanf(convostart, "%*s %3s %d %d:%d:%d %d", month_str, + &day, &hour, &minute, &second, &year) != 6) { purple_debug_warning("log", "invalid date format\n"); } /* Ugly hack, in case current locale is not English */ - if (purple_strequal(month, "Jan")) { - tm.tm_mon= 0; - } else if (purple_strequal(month, "Feb")) { - tm.tm_mon = 1; - } else if (purple_strequal(month, "Mar")) { - tm.tm_mon = 2; - } else if (purple_strequal(month, "Apr")) { - tm.tm_mon = 3; - } else if (purple_strequal(month, "May")) { - tm.tm_mon = 4; - } else if (purple_strequal(month, "Jun")) { - tm.tm_mon = 5; - } else if (purple_strequal(month, "Jul")) { - tm.tm_mon = 6; - } else if (purple_strequal(month, "Aug")) { - tm.tm_mon = 7; - } else if (purple_strequal(month, "Sep")) { - tm.tm_mon = 8; - } else if (purple_strequal(month, "Oct")) { - tm.tm_mon = 9; - } else if (purple_strequal(month, "Nov")) { - tm.tm_mon = 10; - } else if (purple_strequal(month, "Dec")) { - tm.tm_mon = 11; + if (purple_strequal(month_str, "Jan")) { + month = 1; + } else if (purple_strequal(month_str, "Feb")) { + month = 2; + } else if (purple_strequal(month_str, "Mar")) { + month = 3; + } else if (purple_strequal(month_str, "Apr")) { + month = 4; + } else if (purple_strequal(month_str, "May")) { + month = 5; + } else if (purple_strequal(month_str, "Jun")) { + month = 6; + } else if (purple_strequal(month_str, "Jul")) { + month = 7; + } else if (purple_strequal(month_str, "Aug")) { + month = 8; + } else if (purple_strequal(month_str, "Sep")) { + month = 9; + } else if (purple_strequal(month_str, "Oct")) { + month = 10; + } else if (purple_strequal(month_str, "Nov")) { + month = 11; + } else if (purple_strequal(month_str, "Dec")) { + month = 12; } - tm.tm_year -= 1900; - lasttime = mktime(&tm); + lasttime = g_date_time_new_local(year, month, day, + hour, minute, second); } } if (logfound) { if ((newlen = ftell(file) - lastoff) != 0) { - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, -1, NULL); + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, NULL); log->logger = old_logger; - log->time = lasttime; + log->time = g_date_time_ref(lasttime); /* IMPORTANT: Always set all members of struct old_logger_data */ data = g_slice_new(struct old_logger_data);
--- a/libpurple/log.h Tue Jul 11 05:27:50 2017 -0400 +++ b/libpurple/log.h Tue Jul 11 23:43:33 2017 -0400 @@ -139,10 +139,6 @@ * timezone * @logger: The logging mechanism this log is to use * @logger_data: Data used by the log logger - * @tm: The time this conversation started, saved with original - * timezone data, if available and if struct tm has the BSD - * timezone fields, else %NULL. Do NOT modify anything in this - * struct. * * A log. Not the wooden type. */ @@ -151,11 +147,10 @@ char *name; PurpleAccount *account; PurpleConversation *conv; - time_t time; + GDateTime *time; PurpleLogLogger *logger; void *logger_data; - struct tm *tm; /* IMPORTANT: Some code in log.c allocates these without zeroing them. * IMPORTANT: Update that code if you add members here. */ @@ -225,15 +220,13 @@ * @account: The account the conversation is occurring on * @conv: The conversation being logged * @time: The time this conversation started - * @tm: The time this conversation started, with timezone data, - * if available and if struct tm has the BSD timezone fields. * * Creates a new log * * Returns: The new log */ PurpleLog *purple_log_new(PurpleLogType type, const char *name, PurpleAccount *account, - PurpleConversation *conv, time_t time, const struct tm *tm); + PurpleConversation *conv, GDateTime *time); /** * purple_log_free:
--- a/libpurple/plugins/log_reader.c Tue Jul 11 05:27:50 2017 -0400 +++ b/libpurple/plugins/log_reader.c Tue Jul 11 23:43:33 2017 -0400 @@ -95,12 +95,12 @@ if (!purple_str_has_prefix(file, sn)) continue; if (purple_str_has_suffix(file, ".html") || purple_str_has_suffix(file, ".AdiumHTMLLog")) { - struct tm tm; + GDateTime *dt; + gint year, month, day, hour, minute, second; const char *date = file; date += strlen(sn) + 2; - if (sscanf(date, "%u|%u|%u", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday) != 3) { + if (sscanf(date, "%u|%u|%u", &year, &month, &day) != 3) { purple_debug_error("Adium log parse", "Filename timestamp parsing error\n"); @@ -134,7 +134,7 @@ contents2++; if (sscanf(contents2, "%u.%u.%u", - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 3) { + &hour, &minute, &second) != 3) { purple_debug_error("Adium log parse", "Contents timestamp parsing error\n"); @@ -146,23 +146,24 @@ data->path = filename; data->type = ADIUM_HTML; - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - /* XXX: Look into this later... Should we pass in a struct tm? */ - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL); + /* XXX: Look into this later... Should we figure out a timezone? */ + dt = g_date_time_new_local(year, month, day, hour, minute, second); + + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, dt); log->logger = adium_logger; log->logger_data = data; + g_date_time_unref(dt); + list = g_list_prepend(list, log); } } else if (purple_str_has_suffix(file, ".adiumLog")) { - struct tm tm; + GDateTime *dt; + gint year, month, day, hour, minute, second; const char *date = file; date += strlen(sn) + 2; - if (sscanf(date, "%u|%u|%u", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday) != 3) { + if (sscanf(date, "%u|%u|%u", &year, &month, &day) != 3) { purple_debug_error("Adium log parse", "Filename timestamp parsing error\n"); @@ -190,8 +191,7 @@ if (*contents2) contents2++; - if (sscanf(contents2, "%u.%u.%u", - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 3) { + if (sscanf(contents2, "%u.%u.%u", &hour, &minute, &second) != 3) { purple_debug_error("Adium log parse", "Contents timestamp parsing error\n"); @@ -199,18 +199,19 @@ continue; } - tm.tm_year -= 1900; - tm.tm_mon -= 1; - data = g_new0(struct adium_logger_data, 1); data->path = filename; data->type = ADIUM_TEXT; - /* XXX: Look into this later... Should we pass in a struct tm? */ - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL); + /* XXX: Look into this later... Should we figure out a timezone? */ + dt = g_date_time_new_local(year, month, day, hour, minute, second); + + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, dt); log->logger = adium_logger; log->logger_data = data; + g_date_time_unref(dt); + list = g_list_prepend(list, log); } } @@ -337,11 +338,11 @@ /* This function is really confusing. It makes baby rlaager cry... In other news: "You lost a lot of blood but we found most of it." */ -static time_t msn_logger_parse_timestamp(PurpleXmlNode *message, struct tm **tm_out) +static GDateTime * +msn_logger_parse_timestamp(PurpleXmlNode *message) { const char *datetime; - static struct tm tm2; - time_t stamp; + GDateTime *stamp; const char *date; const char *time; int month; @@ -352,47 +353,26 @@ int sec; char am_pm; char *str; - static struct tm tm; - time_t t; - time_t diff; - -#ifndef G_DISABLE_CHECKS - if (message != NULL) - { - *tm_out = NULL; - - /* Trigger the usual warning. */ - g_return_val_if_fail(message != NULL, (time_t)0); - } -#endif + GDateTime *t; + GTimeSpan diff; + + g_return_val_if_fail(message != NULL, NULL); datetime = purple_xmlnode_get_attrib(message, "DateTime"); if (!(datetime && *datetime)) { purple_debug_error("MSN log timestamp parse", "Attribute missing: %s\n", "DateTime"); - return (time_t)0; + return NULL; } - stamp = purple_str_to_time(datetime, TRUE, &tm2, NULL, NULL); -#ifdef HAVE_TM_GMTOFF - tm2.tm_gmtoff = 0; -#endif -#ifdef HAVE_STRUCT_TM_TM_ZONE - /* This is used in the place of a timezone abbreviation if the - * offset is way off. The user should never really see it, but - * it's here just in case. The parens are to make it clear it's - * not a real timezone. */ - tm2.tm_zone = _("(UTC)"); -#endif - + stamp = purple_str_to_date_time(datetime, TRUE); date = purple_xmlnode_get_attrib(message, "Date"); if (!(date && *date)) { purple_debug_error("MSN log timestamp parse", "Attribute missing: %s\n", "Date"); - *tm_out = &tm2; return stamp; } @@ -401,7 +381,6 @@ { purple_debug_error("MSN log timestamp parse", "Attribute missing: %s\n", "Time"); - *tm_out = &tm2; return stamp; } @@ -409,7 +388,6 @@ { purple_debug_error("MSN log timestamp parse", "%s parsing error\n", "Date"); - *tm_out = &tm2; return stamp; } else @@ -426,7 +404,6 @@ { purple_debug_error("MSN log timestamp parse", "%s parsing error\n", "Time"); - *tm_out = &tm2; return stamp; } @@ -438,34 +415,30 @@ } str = g_strdup_printf("%04i-%02i-%02iT%02i:%02i:%02i", year, month, day, hour, min, sec); - t = purple_str_to_time(str, TRUE, &tm, NULL, NULL); - - - if (stamp > t) - diff = stamp - t; + t = purple_str_to_date_time(str, TRUE); + + if (g_date_time_compare(stamp, t) > 0) + diff = g_date_time_difference(stamp, t); else - diff = t - stamp; - - if (diff > (14 * 60 * 60)) - { + diff = g_date_time_difference(t, stamp); + + if (diff > (14LL * G_TIME_SPAN_HOUR)) { if (day <= 12) { /* Swap day & month variables, to see if it's a non-US date. */ g_free(str); str = g_strdup_printf("%04i-%02i-%02iT%02i:%02i:%02i", year, month, day, hour, min, sec); - t = purple_str_to_time(str, TRUE, &tm, NULL, NULL); - - if (stamp > t) - diff = stamp - t; + t = purple_str_to_date_time(str, TRUE); + + if (g_date_time_compare(stamp, t) > 0) + diff = g_date_time_difference(stamp, t); else - diff = t - stamp; - - if (diff > (14 * 60 * 60)) - { + diff = g_date_time_difference(t, stamp); + + if (diff > (14LL * G_TIME_SPAN_HOUR)) { /* We got a time, it's not impossible, but * the diff is too large. Display the UTC time. */ g_free(str); - *tm_out = &tm2; return stamp; } else @@ -479,26 +452,19 @@ /* We got a time, it's not impossible, but * the diff is too large. Display the UTC time. */ g_free(str); - *tm_out = &tm2; return stamp; } } /* If we got here, the time is legal with a reasonable offset. * Let's find out if it's in our TZ. */ - if (purple_str_to_time(str, FALSE, &tm, NULL, NULL) == stamp) + if (purple_str_to_date_time(str, FALSE) == stamp) { g_free(str); - *tm_out = &tm; return stamp; } g_free(str); - /* The time isn't in our TZ, but it's reasonable. */ -#ifdef HAVE_STRUCT_TM_TM_ZONE - tm.tm_zone = " "; -#endif - *tm_out = &tm; return stamp; } @@ -737,8 +703,7 @@ * The session ID differs from the last message. * Thus, this is the start of a new conversation. */ - struct tm *tm; - time_t stamp; + GDateTime *stamp; PurpleLog *log; data = g_new0(struct msn_logger_data, 1); @@ -748,12 +713,14 @@ data->text = NULL; data->last_log = FALSE; - stamp = msn_logger_parse_timestamp(message, &tm); - - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, stamp, tm); + stamp = msn_logger_parse_timestamp(message); + + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, stamp); log->logger = msn_logger; log->logger_data = data; + g_date_time_unref(stamp); + list = g_list_prepend(list, log); } old_session_id = session_id; @@ -808,7 +775,7 @@ PurpleXmlNode *to; enum name_guesses name_guessed = NAME_GUESS_UNKNOWN; const char *their_name; - struct tm *tm = NULL; + GDateTime *dt = NULL; char *timestamp; char *tmp; const char *style; @@ -987,12 +954,13 @@ text = g_string_append(text, ";\">"); } - if (msn_logger_parse_timestamp(message, &tm)) { - timestamp = g_strdup_printf( - "<font size=\"2\">(%02u:%02u:%02u)</font> ", - tm->tm_hour, tm->tm_min, tm->tm_sec); + if ((dt = msn_logger_parse_timestamp(message)) != NULL) { + timestamp = g_date_time_format( + dt, + "<font size=\"2\">(%H:%M:%s)</font> "); text = g_string_append(text, timestamp); g_free(timestamp); + g_date_time_unref(dt); } else { text = g_string_append(text, "<font size=\"2\">(00:00:00)</font> "); @@ -1208,8 +1176,9 @@ timestamp++; if (*timestamp == ')') { - char *month; - struct tm tm; + char *month_str; + gint year, month, day, hour, minute, second; + GDateTime *dt; *timestamp = '\0'; if (line[0] && line[1] && line[2]) @@ -1224,7 +1193,7 @@ timestamp++; /* Parse out the month. */ - month = timestamp; + month_str = timestamp; while (*timestamp && (*timestamp != ' ')) timestamp++; *timestamp = '\0'; @@ -1232,22 +1201,16 @@ /* Parse the day, time, and year. */ if (sscanf(timestamp, "%u %u:%u:%u %u", - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec, - &tm.tm_year) != 5) { + &day, &hour, + &minute, &second, + &year) != 5) { purple_debug_error("Trillian log timestamp parse", "Session Start parsing error\n"); } else { PurpleLog *log; - tm.tm_year -= 1900; - - /* Let the C library deal with - * daylight savings time. - */ - tm.tm_isdst = -1; - tm.tm_mon = get_month(month); + month = get_month(month_str); data = g_new0( struct trillian_logger_data, 1); @@ -1257,12 +1220,16 @@ data->their_nickname = g_strdup(their_nickname); - /* XXX: Look into this later... Should we pass in a struct tm? */ + /* XXX: Look into this later... Should we figure out a timezone? */ + dt = g_date_time_new_local(year, month, day, hour, minute, second); + log = purple_log_new(PURPLE_LOG_IM, - sn, account, NULL, mktime(&tm), NULL); + sn, account, NULL, dt); log->logger = trillian_logger; log->logger_data = data; + g_date_time_unref(dt); + list = g_list_prepend(list, log); } } @@ -1634,7 +1601,7 @@ #define QIP_LOG_OUT_MESSAGE (QIP_LOG_DELIMITER ">-") #define QIP_LOG_IN_MESSAGE_ESC (QIP_LOG_DELIMITER "<-") #define QIP_LOG_OUT_MESSAGE_ESC (QIP_LOG_DELIMITER ">-") -#define QIP_LOG_TIMEOUT (60*60) +#define QIP_LOG_TIMEOUT (G_TIME_SPAN_HOUR) static PurpleLogLogger *qip_logger; @@ -1655,9 +1622,9 @@ char *path; char *contents; struct qip_logger_data *data = NULL; - struct tm prev_tm; - struct tm tm; - gboolean prev_tm_init = FALSE; + GDateTime *prev_dt = NULL; + GDateTime *dt = NULL; + gint year, month, day, hour, minute, second; gboolean main_cycle = TRUE; char *c; char *start_log; @@ -1668,8 +1635,6 @@ g_return_val_if_fail(sn != NULL, NULL); g_return_val_if_fail(account != NULL, NULL); - memset(&tm, 0, sizeof(tm)); - /* QIP only supports ICQ. */ if (!purple_strequal(purple_account_get_protocol_id(account), "prpl-icq")) return NULL; @@ -1740,24 +1705,18 @@ /* Parse the time, day, month and year */ if (sscanf(timestamp, "%u:%u:%u %u/%u/%u", - &tm.tm_hour, &tm.tm_min, &tm.tm_sec, - &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 6) { + &hour, &minute, &second, + &day, &month, &year) != 6) { purple_debug_error("QIP logger list", "Parsing timestamp error\n"); } else { - tm.tm_mon -= 1; - tm.tm_year -= 1900; - - /* Let the C library deal with - * daylight savings time. */ - tm.tm_isdst = -1; - - if (!prev_tm_init) { - prev_tm = tm; - prev_tm_init = TRUE; + g_date_time_unref(dt); + dt = g_date_time_new_local(year, month, day, hour, minute, second); + if (!prev_dt) { + prev_dt = dt; } else { - add_new_log = difftime(mktime(&tm), mktime(&prev_tm)) > QIP_LOG_TIMEOUT; + add_new_log = g_date_time_difference(dt, prev_dt) > QIP_LOG_TIMEOUT; } } } @@ -1769,7 +1728,7 @@ } /* adding log */ - if (add_new_log && prev_tm_init) { + if (add_new_log && prev_dt) { PurpleLog *log; /* filling data */ @@ -1782,16 +1741,18 @@ "Creating log: path = (%s); length = (%d); offset = (%d)\n", data->path, data->length, data->offset); - /* XXX: Look into this later... Should we pass in a struct tm? */ + /* XXX: Look into this later... Should we figure out a timezone? */ + dt = g_date_time_new_local(year, month, day, hour, minute, second); log = purple_log_new(PURPLE_LOG_IM, sn, account, - NULL, mktime(&prev_tm), NULL); + NULL, prev_dt); log->logger = qip_logger; log->logger_data = data; list = g_list_prepend(list, log); - prev_tm = tm; + g_date_time_unref(prev_dt); + prev_dt = dt; start_log = new_line; } @@ -2042,26 +2003,21 @@ gboolean found_start = FALSE; char *start_log = c; int offset = 0; - struct tm tm; + gint year, month, day, hour, minute, second; + GDateTime *dt; while (c && *c) { if (purple_str_has_prefix(c, AMSN_LOG_CONV_START)) { - char month[4]; + char month_str[4]; if (sscanf(c + strlen(AMSN_LOG_CONV_START), "%u %3s %u %u:%u:%u", - &tm.tm_mday, (char*)&month, &tm.tm_year, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { + &day, (char*)&month_str, &year, + &hour, &minute, &second) != 6) { found_start = FALSE; purple_debug_error("aMSN logger", "Error parsing start date for %s\n", filename); } else { - tm.tm_year -= 1900; - - /* Let the C library deal with - * daylight savings time. - */ - tm.tm_isdst = -1; - tm.tm_mon = get_month(month); + month = get_month(month_str); found_start = TRUE; offset = c - contents; @@ -2074,11 +2030,13 @@ data->length = c - start_log + strlen(AMSN_LOG_CONV_END) + strlen(AMSN_LOG_CONV_EXTRA); - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL); + dt = g_date_time_new_local(year, month, day, hour, minute, second); + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, dt); log->logger = amsn_logger; log->logger_data = data; list = g_list_prepend(list, log); found_start = FALSE; + g_date_time_unref(dt); purple_debug_info("aMSN logger", "Found log for %s:" @@ -2100,10 +2058,12 @@ data->length = c - start_log + strlen(AMSN_LOG_CONV_END) + strlen(AMSN_LOG_CONV_EXTRA); - log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, mktime(&tm), NULL); + dt = g_date_time_new_local(year, month, day, hour, minute, second); + log = purple_log_new(PURPLE_LOG_IM, sn, account, NULL, dt); log->logger = amsn_logger; log->logger_data = data; list = g_list_prepend(list, log); + g_date_time_unref(dt); purple_debug_info("aMSN logger", "Found log for %s:" @@ -2522,7 +2482,7 @@ g_free(path); path = NULL; } - + if (path && !g_file_get_contents(path, &contents, NULL, &error)) { purple_debug_error("Trillian talk.ini read", "Error reading talk.ini: %s\n",
--- a/pidgin/gtklog.c Tue Jul 11 05:27:50 2017 -0400 +++ b/pidgin/gtklog.c Tue Jul 11 23:43:33 2017 -0400 @@ -108,12 +108,14 @@ gtk_tree_path_free(path); } -static const char *log_get_date(PurpleLog *log) +static gchar *log_get_date(PurpleLog *log) { - if (log->tm) - return purple_date_format_full(log->tm); - else - return purple_date_format_full(localtime(&log->time)); + GDateTime *dt; + gchar *ret; + dt = g_date_time_to_local(log->time); + ret = g_date_time_format(dt, "%c"); + g_date_time_unref(dt); + return ret; } static void search_cb(GtkWidget *button, PidginLogViewer *lv) @@ -152,11 +154,13 @@ if (read && *read && purple_strcasestr(read, search_term)) { GtkTreeIter iter; PurpleLog *log = logs->data; + gchar *log_date = log_get_date(log); gtk_tree_store_append (lv->treestore, &iter, NULL); gtk_tree_store_set(lv->treestore, &iter, - 0, log_get_date(log), + 0, log_date, 1, log, -1); + g_free(log_date); } g_free(read); } @@ -270,7 +274,7 @@ { PidginLogViewer *lv = data[0]; PurpleLog *log = data[1]; - const char *time = log_get_date(log); + gchar *time = log_get_date(log); const char *name; char *tmp; gpointer *data2; @@ -302,8 +306,10 @@ tmp = g_strdup_printf(_("Are you sure you want to permanently delete the system log " "which started at %s?"), time); } - else + else { + g_free(time); g_return_if_reached(); + } /* The only way to free data in all cases is to tie it to the menuitem with * g_object_set_data_full(). But, since we need to get some data down to @@ -319,6 +325,7 @@ data2, 2, _("Delete"), delete_log_cb, _("Cancel"), delete_log_cleanup_cb); + g_free(time); g_free(tmp); } @@ -444,15 +451,17 @@ pidgin_set_cursor(viewer->window, GDK_WATCH); if (log->type != PURPLE_LOG_SYSTEM) { + gchar *log_date = log_get_date(log); char *title; if (log->type == PURPLE_LOG_CHAT) title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation in %s on %s</span>"), - log->name, log_get_date(log)); + log->name, log_date); else title = g_strdup_printf(_("<span size='larger' weight='bold'>Conversation with %s on %s</span>"), - log->name, log_get_date(log)); + log->name, log_date); gtk_label_set_markup(viewer->label, title); + g_free(log_date); g_free(title); } @@ -492,19 +501,20 @@ /* Logs are made from trees in real life. This is a tree made from logs */ { - const char *month; + gchar *month; char prev_top_month[30] = ""; GtkTreeIter toplevel, child; GList *logs = lv->logs; while (logs != NULL) { PurpleLog *log = logs->data; + GDateTime *dt; + gchar *log_date; - month = purple_utf8_strftime(_("%B %Y"), - log->tm ? log->tm : localtime(&log->time)); + dt = g_date_time_to_local(log->time); + month = g_date_time_format(dt, _("%B %Y")); - if (!purple_strequal(month, prev_top_month)) - { + if (!purple_strequal(month, prev_top_month)) { /* top level */ gtk_tree_store_append(lv->treestore, &toplevel, NULL); gtk_tree_store_set(lv->treestore, &toplevel, 0, month, 1, NULL, -1); @@ -513,12 +523,16 @@ } /* sub */ + log_date = g_date_time_format(dt, "%c"); gtk_tree_store_append(lv->treestore, &child, &toplevel); gtk_tree_store_set(lv->treestore, &child, - 0, log_get_date(log), + 0, log_date, 1, log, -1); + g_free(log_date); + g_free(month); + g_date_time_unref(dt); logs = logs->next; } }
--- a/pidgin/plugins/history.c Tue Jul 11 05:27:50 2017 -0400 +++ b/pidgin/plugins/history.c Tue Jul 11 23:43:33 2017 -0400 @@ -48,7 +48,8 @@ char *protocol; #endif char *escaped_alias; - const char *header_date; + GDateTime *dt; + gchar *header_date; gtkconv = PIDGIN_CONVERSATION(c); g_return_if_fail(gtkconv != NULL); @@ -141,13 +142,13 @@ escaped_alias = g_markup_escape_text(alias, -1); - if (((PurpleLog *)logs->data)->tm) - header_date = purple_date_format_full(((PurpleLog *)logs->data)->tm); - else - header_date = purple_date_format_full(localtime(&((PurpleLog *)logs->data)->time)); + dt = g_date_time_to_local(((PurpleLog *)logs->data)->time); + header_date = g_date_time_format(dt, "%c"); + g_date_time_unref(dt); header = g_strdup_printf(_("<b>Conversation with %s on %s:</b><br>"), escaped_alias, header_date); pidgin_webview_append_html(PIDGIN_WEBVIEW(gtkconv->webview), header); + g_free(header_date); g_free(header); g_free(escaped_alias);