Mercurial > pidgin
annotate src/log.c @ 8804:ef1e60f82be0
[gaim-migrate @ 9566]
nosnilmot GOT HIS FREAK ON and made smileys show up as smileys
in the create away message dialog (instead of the envelope thing).
"Someone should make URLs clickable in editable imhtmls"
committer: Tailor Script <tailor@pidgin.im>
| author | Mark Doliner <mark@kingant.net> |
|---|---|
| date | Sat, 24 Apr 2004 20:44:41 +0000 |
| parents | 4aee5a47937d |
| children | de87e510ff9a |
| rev | line source |
|---|---|
| 7431 | 1 /** |
| 2 * @file log.c Logging API | |
| 3 * @ingroup core | |
| 4 * | |
| 5 * gaim | |
| 6 * | |
| 8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
| 8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 9 * source distribution. | |
| 7436 | 10 * |
| 7431 | 11 * This program is free software; you can redistribute it and/or modify |
| 12 * it under the terms of the GNU General Public License as published by | |
| 13 * the Free Software Foundation; either version 2 of the License, or | |
| 14 * (at your option) any later version. | |
| 15 * | |
| 16 * This program is distributed in the hope that it will be useful, | |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 19 * GNU General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU General Public License | |
| 22 * along with this program; if not, write to the Free Software | |
| 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 4184 | 24 */ |
| 4195 | 25 |
| 7431 | 26 #include "account.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
27 #include "debug.h" |
| 7431 | 28 #include "internal.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
29 #include "log.h" |
| 5548 | 30 #include "prefs.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
31 #include "util.h" |
| 7764 | 32 #include "stringref.h" |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
33 |
| 8096 | 34 static GSList *loggers = NULL; |
| 35 | |
| 7457 | 36 static GaimLogLogger html_logger; |
| 7431 | 37 static GaimLogLogger txt_logger; |
| 38 static GaimLogLogger old_logger; | |
|
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
39 |
| 8635 | 40 struct _gaim_logsize_user { |
| 41 char *name; | |
| 42 GaimAccount *account; | |
| 43 }; | |
| 44 static GHashTable *logsize_users = NULL; | |
| 45 | |
| 46 | |
| 7431 | 47 /************************************************************************** |
| 48 * PUBLIC LOGGING FUNCTIONS *********************************************** | |
| 49 **************************************************************************/ | |
| 4184 | 50 |
| 7431 | 51 GaimLog *gaim_log_new(GaimLogType type, const char *name, GaimAccount *account, time_t time) |
| 52 { | |
| 53 GaimLog *log = g_new0(GaimLog, 1); | |
| 8635 | 54 log->name = g_strdup(gaim_normalize(account, name)); |
| 7431 | 55 log->account = account; |
| 56 log->time = time; | |
| 8573 | 57 log->type = type; |
| 8096 | 58 log->logger_data = NULL; |
| 7431 | 59 log->logger = gaim_log_logger_get(); |
| 7440 | 60 if (log->logger && log->logger->create) |
| 61 log->logger->create(log); | |
| 7431 | 62 return log; |
| 4184 | 63 } |
| 64 | |
| 7431 | 65 void gaim_log_free(GaimLog *log) |
| 4184 | 66 { |
| 7431 | 67 g_return_if_fail(log); |
| 68 if (log->logger && log->logger->finalize) | |
| 69 log->logger->finalize(log); | |
| 70 g_free(log->name); | |
| 71 g_free(log); | |
| 72 } | |
| 7436 | 73 |
| 74 void gaim_log_write(GaimLog *log, GaimMessageFlags type, | |
| 7431 | 75 const char *from, time_t time, const char *message) |
| 76 { | |
| 8635 | 77 struct _gaim_logsize_user lu; |
| 78 | |
| 7431 | 79 g_return_if_fail(log); |
| 80 g_return_if_fail(log->logger); | |
| 7442 | 81 g_return_if_fail(log->logger->write); |
| 7431 | 82 |
| 8635 | 83 if ((log->type == GAIM_LOG_IM && |
| 84 gaim_prefs_get_bool("/core/logging/log_ims")) || | |
| 85 (log->type == GAIM_LOG_CHAT && | |
| 86 gaim_prefs_get_bool("/core/logging/log_chats")) || | |
| 87 (log->type == GAIM_LOG_SYSTEM && | |
| 88 gaim_prefs_get_bool("/core/logging/log_system"))) { | |
| 7553 | 89 (log->logger->write)(log, type, from, time, message); |
| 8635 | 90 lu.name = g_strdup(gaim_normalize(log->account, log->name)); |
| 91 lu.account = log->account; | |
| 92 g_hash_table_remove(logsize_users, &lu); | |
| 93 g_free(lu.name); | |
| 94 } | |
| 4184 | 95 } |
| 96 | |
| 7431 | 97 char *gaim_log_read(GaimLog *log, GaimLogReadFlags *flags) |
| 4184 | 98 { |
| 7542 | 99 GaimLogReadFlags mflags; |
| 7431 | 100 g_return_val_if_fail(log && log->logger, NULL); |
| 7462 | 101 if (log->logger->read) { |
| 7535 | 102 char *ret = (log->logger->read)(log, flags ? flags : &mflags); |
|
7478
3c21f3084ff0
[gaim-migrate @ 8091]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7473
diff
changeset
|
103 gaim_str_strip_cr(ret); |
| 7462 | 104 return ret; |
| 105 } | |
| 7470 | 106 return (_("<b><font color=\"red\">The logger has no read function</font></b>")); |
| 4184 | 107 } |
| 7616 | 108 |
| 7556 | 109 int gaim_log_get_size(GaimLog *log) |
| 110 { | |
| 111 g_return_val_if_fail(log && log->logger, 0); | |
| 8096 | 112 |
| 7556 | 113 if (log->logger->size) |
| 114 return log->logger->size(log); | |
| 115 return 0; | |
| 116 } | |
| 117 | |
| 8635 | 118 static guint _gaim_logsize_user_hash(struct _gaim_logsize_user *lu) |
| 119 { | |
| 120 return g_str_hash(lu->name); | |
| 121 } | |
| 122 | |
| 123 static guint _gaim_logsize_user_equal(struct _gaim_logsize_user *lu1, | |
| 124 struct _gaim_logsize_user *lu2) | |
| 125 { | |
| 126 return ((!strcmp(lu1->name, lu2->name)) && lu1->account == lu2->account); | |
| 127 } | |
| 128 | |
| 129 static void _gaim_logsize_user_free_key(struct _gaim_logsize_user *lu) | |
| 130 { | |
| 131 g_free(lu->name); | |
| 132 g_free(lu); | |
| 133 } | |
| 134 | |
| 7556 | 135 int gaim_log_get_total_size(const char *name, GaimAccount *account) |
| 136 { | |
| 8635 | 137 int size; |
| 8096 | 138 GSList *n; |
| 8635 | 139 struct _gaim_logsize_user *lu; |
| 8096 | 140 |
| 8635 | 141 lu = g_new(struct _gaim_logsize_user, 1); |
| 142 lu->name = g_strdup(gaim_normalize(account, name)); | |
| 143 lu->account = account; | |
| 144 | |
| 145 if((size = GPOINTER_TO_INT(g_hash_table_lookup(logsize_users, lu)))) { | |
| 146 g_free(lu->name); | |
| 147 g_free(lu); | |
| 148 } else { | |
| 149 for (n = loggers; n; n = n->next) { | |
| 150 GaimLogLogger *logger = n->data; | |
| 7616 | 151 |
| 8635 | 152 if(logger->total_size){ |
| 153 size += (logger->total_size)(name, account); | |
| 154 } else if(logger->list) { | |
| 155 GList *logs = (logger->list)(name, account); | |
| 156 int this_size = 0; | |
| 157 | |
| 158 while (logs) { | |
| 159 GList *logs2 = logs->next; | |
| 160 GaimLog *log = (GaimLog*)(logs->data); | |
| 161 this_size += gaim_log_get_size(log); | |
| 162 gaim_log_free(log); | |
| 163 g_list_free_1(logs); | |
| 164 logs = logs2; | |
| 165 } | |
| 166 | |
| 167 size += this_size; | |
| 8096 | 168 } |
| 8635 | 169 } |
| 8096 | 170 |
| 8635 | 171 g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(size)); |
| 7556 | 172 } |
| 173 return size; | |
| 174 } | |
| 4184 | 175 |
| 7431 | 176 /**************************************************************************** |
| 177 * LOGGER FUNCTIONS ********************************************************* | |
| 178 ****************************************************************************/ | |
| 4184 | 179 |
| 7431 | 180 static GaimLogLogger *current_logger = NULL; |
| 7436 | 181 |
| 7431 | 182 static void logger_pref_cb(const char *name, GaimPrefType type, |
| 183 gpointer value, gpointer data) | |
| 184 { | |
| 185 GaimLogLogger *logger; | |
| 186 GSList *l = loggers; | |
| 187 while (l) { | |
| 188 logger = l->data; | |
| 189 if (!strcmp(logger->id, value)) { | |
| 190 gaim_log_logger_set(logger); | |
| 191 return; | |
| 4184 | 192 } |
| 7431 | 193 l = l->next; |
| 194 } | |
| 195 gaim_log_logger_set(&txt_logger); | |
| 196 } | |
| 4184 | 197 |
| 198 | |
| 7440 | 199 GaimLogLogger *gaim_log_logger_new(void(*create)(GaimLog *), |
| 7436 | 200 void(*write)(GaimLog *, GaimMessageFlags, const char *, |
| 7431 | 201 time_t, const char *), |
| 202 void(*finalize)(GaimLog *), GList*(*list)(const char*, GaimAccount*), | |
| 7556 | 203 char*(*read)(GaimLog*, GaimLogReadFlags*), |
| 204 int(*size)(GaimLog*)) | |
| 7431 | 205 { |
| 206 GaimLogLogger *logger = g_new0(GaimLogLogger, 1); | |
| 7440 | 207 logger->create = create; |
| 7431 | 208 logger->write = write; |
| 209 logger->finalize = finalize; | |
| 210 logger->list = list; | |
| 211 logger->read = read; | |
| 7556 | 212 logger->size = size; |
| 7431 | 213 return logger; |
| 4184 | 214 } |
| 215 | |
| 7431 | 216 void gaim_log_logger_free(GaimLogLogger *logger) |
| 4184 | 217 { |
| 7431 | 218 g_free(logger); |
| 219 } | |
| 4184 | 220 |
| 7431 | 221 void gaim_log_logger_add (GaimLogLogger *logger) |
| 222 { | |
| 223 g_return_if_fail(logger); | |
| 224 if (g_slist_find(loggers, logger)) | |
| 225 return; | |
| 226 loggers = g_slist_append(loggers, logger); | |
| 227 } | |
| 228 | |
| 229 void gaim_log_logger_remove (GaimLogLogger *logger) | |
| 230 { | |
| 231 g_return_if_fail(logger); | |
| 232 g_slist_remove(loggers, logger); | |
| 4184 | 233 } |
| 234 | |
| 7431 | 235 void gaim_log_logger_set (GaimLogLogger *logger) |
| 4184 | 236 { |
| 7431 | 237 g_return_if_fail(logger); |
| 238 current_logger = logger; | |
| 7436 | 239 } |
| 4184 | 240 |
| 7431 | 241 GaimLogLogger *gaim_log_logger_get() |
| 242 { | |
| 243 return current_logger; | |
| 244 } | |
| 4184 | 245 |
| 7431 | 246 GList *gaim_log_logger_get_options(void) |
| 247 { | |
| 248 GSList *n; | |
| 249 GList *list = NULL; | |
| 250 GaimLogLogger *data; | |
| 4184 | 251 |
| 7431 | 252 for (n = loggers; n; n = n->next) { |
| 253 data = n->data; | |
| 254 if (!data->write) | |
| 255 continue; | |
| 7494 | 256 list = g_list_append(list, _(data->name)); |
| 7431 | 257 list = g_list_append(list, data->id); |
| 4184 | 258 } |
| 259 | |
| 7431 | 260 return list; |
| 261 } | |
| 262 | |
| 8573 | 263 gint gaim_log_compare(gconstpointer y, gconstpointer z) |
| 7431 | 264 { |
| 7436 | 265 const GaimLog *a = y; |
| 266 const GaimLog *b = z; | |
| 267 | |
| 7431 | 268 return b->time - a->time; |
| 269 } | |
| 270 | |
| 271 GList *gaim_log_get_logs(const char *name, GaimAccount *account) | |
| 272 { | |
| 273 GList *logs = NULL; | |
| 274 GSList *n; | |
| 275 for (n = loggers; n; n = n->next) { | |
| 276 GaimLogLogger *logger = n->data; | |
| 277 if (!logger->list) | |
| 278 continue; | |
| 279 logs = g_list_concat(logs, logger->list(name, account)); | |
| 280 } | |
| 7436 | 281 |
| 8573 | 282 return g_list_sort(logs, gaim_log_compare); |
| 283 } | |
| 284 | |
| 285 GList *gaim_log_get_system_logs(GaimAccount *account) | |
| 286 { | |
| 287 GList *logs = NULL; | |
| 288 GSList *n; | |
| 289 for (n = loggers; n; n = n->next) { | |
| 290 GaimLogLogger *logger = n->data; | |
| 291 if (!logger->list_syslog) | |
| 292 continue; | |
| 293 logs = g_list_concat(logs, logger->list_syslog(account)); | |
| 294 } | |
| 295 | |
| 296 return g_list_sort(logs, gaim_log_compare); | |
| 7431 | 297 } |
| 298 | |
| 299 void gaim_log_init(void) | |
| 7436 | 300 { |
| 7431 | 301 gaim_prefs_add_none("/core/logging"); |
| 7555 | 302 gaim_prefs_add_bool("/core/logging/log_ims", FALSE); |
| 303 gaim_prefs_add_bool("/core/logging/log_chats", FALSE); | |
| 8573 | 304 gaim_prefs_add_bool("/core/logging/log_system", FALSE); |
| 305 gaim_prefs_add_bool("/core/logging/log_signon_signoff", FALSE); | |
| 306 gaim_prefs_add_bool("/core/logging/log_idle_state", FALSE); | |
| 307 gaim_prefs_add_bool("/core/logging/log_away_state", FALSE); | |
| 308 gaim_prefs_add_bool("/core/logging/log_own_states", FALSE); | |
| 309 | |
| 7431 | 310 gaim_prefs_add_string("/core/logging/format", "txt"); |
| 7457 | 311 gaim_log_logger_add(&html_logger); |
| 7431 | 312 gaim_log_logger_add(&txt_logger); |
| 313 gaim_log_logger_add(&old_logger); | |
| 314 gaim_prefs_connect_callback("/core/logging/format", | |
| 315 logger_pref_cb, NULL); | |
| 316 gaim_prefs_trigger_callback("/core/logging/format"); | |
| 8635 | 317 |
| 318 logsize_users = g_hash_table_new_full((GHashFunc)_gaim_logsize_user_hash, | |
| 319 (GEqualFunc)_gaim_logsize_user_equal, | |
| 320 (GDestroyNotify)_gaim_logsize_user_free_key, NULL); | |
| 7431 | 321 } |
| 322 | |
| 323 /**************************************************************************** | |
| 324 * LOGGERS ****************************************************************** | |
| 325 ****************************************************************************/ | |
| 326 | |
| 7616 | 327 struct generic_logger_data { |
| 328 char *path; | |
| 329 FILE *file; | |
| 330 }; | |
| 331 | |
| 7431 | 332 static GList *log_lister_common(const char *screenname, GaimAccount *account, const char *ext, GaimLogLogger *logger) |
| 333 { | |
| 334 GDir *dir; | |
| 335 GList *list = NULL; | |
| 7628 | 336 const char *filename; |
| 8111 | 337 char *me; |
| 338 | |
| 339 const char *prpl; | |
| 340 char *path; | |
| 341 | |
| 342 if(!account) | |
| 343 return NULL; | |
| 344 | |
| 345 me = g_strdup(gaim_normalize(account, gaim_account_get_username(account))); | |
| 4184 | 346 |
| 7956 | 347 /* does this seem like a bad way to get this component of the path to anyone else? --Nathan */ |
| 8111 | 348 prpl = GAIM_PLUGIN_PROTOCOL_INFO |
| 7956 | 349 (gaim_find_prpl(gaim_account_get_protocol_id(account)))->list_icon(account, NULL); |
| 8111 | 350 path = g_build_filename(gaim_user_dir(), "logs", prpl, me, gaim_normalize(account, screenname), NULL); |
| 7447 | 351 g_free(me); |
| 352 | |
| 7431 | 353 if (!(dir = g_dir_open(path, 0, NULL))) { |
| 354 g_free(path); | |
| 355 return NULL; | |
| 356 } | |
| 357 while ((filename = g_dir_read_name(dir))) { | |
| 8577 | 358 if (gaim_str_has_suffix(filename, ext) && |
| 359 strlen(filename) == 17 + strlen(ext)) { | |
| 7431 | 360 GaimLog *log; |
| 7616 | 361 struct generic_logger_data *data; |
| 8577 | 362 time_t stamp = gaim_str_to_time(filename, FALSE); |
| 7431 | 363 |
| 8577 | 364 log = gaim_log_new(GAIM_LOG_IM, screenname, account, stamp); |
| 7431 | 365 log->logger = logger; |
| 7616 | 366 log->logger_data = data = g_new0(struct generic_logger_data, 1); |
| 367 data->path = g_build_filename(path, filename, NULL); | |
| 7431 | 368 list = g_list_append(list, log); |
| 4184 | 369 } |
| 370 } | |
| 7431 | 371 g_dir_close(dir); |
| 7447 | 372 g_free(path); |
| 7431 | 373 return list; |
| 374 } | |
| 4184 | 375 |
| 7556 | 376 /* Only to be used with logs listed from log_lister_common */ |
| 7616 | 377 int log_sizer_common(GaimLog *log) |
| 7556 | 378 { |
| 379 struct stat st; | |
| 7616 | 380 struct generic_logger_data *data = log->logger_data; |
| 7556 | 381 |
| 7616 | 382 if (!data->path || stat(data->path, &st)) |
| 7556 | 383 st.st_size = 0; |
| 384 | |
| 385 return st.st_size; | |
| 386 } | |
| 387 | |
| 7431 | 388 #if 0 /* Maybe some other time. */ |
| 7443 | 389 /**************** |
| 7431 | 390 ** XML LOGGER ** |
| 391 ****************/ | |
| 392 | |
| 393 static const char *str_from_msg_type (GaimMessageFlags type) | |
| 394 { | |
| 7443 | 395 |
| 7431 | 396 return ""; |
| 7443 | 397 |
| 7431 | 398 } |
| 399 | |
| 7443 | 400 static void xml_logger_write(GaimLog *log, |
| 401 GaimMessageFlags type, | |
| 7431 | 402 const char *from, time_t time, const char *message) |
| 403 { | |
| 404 char date[64]; | |
| 405 char *xhtml = NULL; | |
| 406 if (!log->logger_data) { | |
| 407 /* This log is new. We could use the loggers 'new' function, but | |
| 408 * creating a new file there would result in empty files in the case | |
| 409 * that you open a convo with someone, but don't say anything. | |
| 410 */ | |
| 411 char *ud = gaim_user_dir(); | |
| 412 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
| 413 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
| 414 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
| 415 char *dir; | |
| 416 FILE *file; | |
| 417 | |
| 7453 | 418 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.xml", localtime(&log->time)); |
| 7443 | 419 |
| 420 dir = g_build_filename(ud, "logs", | |
| 7431 | 421 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
| 7612 | 422 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
| 7447 | 423 g_free(guy); |
| 7443 | 424 |
| 7431 | 425 char *filename = g_build_filename(dir, date, NULL); |
| 426 g_free(dir); | |
| 7443 | 427 |
| 7431 | 428 log->logger_data = fopen(filename, "a"); |
| 429 if (!log->logger_data) { | |
| 430 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
| 7564 | 431 g_free(filename); |
| 7431 | 432 return; |
| 433 } | |
| 7564 | 434 g_free(filename); |
| 7431 | 435 fprintf(log->logger_data, "<?xml version='1.0' encoding='UTF-8' ?>\n" |
| 436 "<?xml-stylesheet href='file:///usr/src/web/htdocs/log-stylesheet.xsl' type='text/xml' ?>\n"); | |
| 7443 | 437 |
| 7453 | 438 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
| 7431 | 439 fprintf(log->logger_data, "<conversation time='%s' screenname='%s' protocol='%s'>\n", |
| 440 date, log->name, prpl); | |
| 441 } | |
| 7443 | 442 |
| 7453 | 443 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); |
| 7431 | 444 gaim_markup_html_to_xhtml(message, &xhtml, NULL); |
| 445 if (from) | |
| 7443 | 446 fprintf(log->logger_data, "<message %s %s from='%s' time='%s'>%s</message>\n", |
| 447 str_from_msg_type(type), | |
| 7431 | 448 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
| 449 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
| 450 from, date, xhtml); | |
| 451 else | |
| 7443 | 452 fprintf(log->logger_data, "<message %s %s time='%s'>%s</message>\n", |
| 453 str_from_msg_type(type), | |
| 7431 | 454 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
| 455 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
| 7443 | 456 date, xhtml): |
| 7431 | 457 fflush(log->logger_data); |
| 458 g_free(xhtml); | |
| 7443 | 459 } |
| 460 | |
| 7431 | 461 static void xml_logger_finalize(GaimLog *log) |
| 462 { | |
| 463 if (log->logger_data) { | |
| 464 fprintf(log->logger_data, "</conversation>\n"); | |
| 465 fclose(log->logger_data); | |
| 466 log->logger_data = NULL; | |
| 467 } | |
| 468 } | |
| 7443 | 469 |
| 7431 | 470 static GList *xml_logger_list(const char *sn, GaimAccount *account) |
| 471 { | |
| 472 return log_lister_common(sn, account, ".xml", &xml_logger); | |
| 4184 | 473 } |
| 474 | |
| 7431 | 475 static GaimLogLogger xml_logger = { |
| 476 N_("XML"), "xml", | |
| 477 NULL, | |
| 478 xml_logger_write, | |
| 479 xml_logger_finalize, | |
| 480 xml_logger_list, | |
| 8096 | 481 NULL, |
| 7431 | 482 NULL |
| 483 }; | |
| 484 #endif | |
|
5563
9eb5b13fd412
[gaim-migrate @ 5965]
Christian Hammond <chipx86@chipx86.com>
parents:
5560
diff
changeset
|
485 |
| 7431 | 486 /**************************** |
| 7457 | 487 ** HTML LOGGER ************* |
| 488 ****************************/ | |
| 489 | |
| 490 static void html_logger_write(GaimLog *log, GaimMessageFlags type, | |
| 491 const char *from, time_t time, const char *message) | |
| 492 { | |
| 7489 | 493 GaimConnection *gc = gaim_account_get_connection(log->account); |
| 7457 | 494 char date[64]; |
| 7882 | 495 char *msg_fixed; |
| 7616 | 496 struct generic_logger_data *data = log->logger_data; |
| 7618 | 497 if(!data) { |
| 7457 | 498 /* This log is new */ |
| 499 char *ud = gaim_user_dir(); | |
| 500 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
| 7553 | 501 char *chat; |
| 7457 | 502 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
| 7956 | 503 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); |
| 7457 | 504 char *dir; |
| 505 char *filename; | |
| 506 | |
| 7553 | 507 if (log->type == GAIM_LOG_CHAT) { |
| 508 chat = g_strdup_printf("%s.chat", guy); | |
| 509 g_free(guy); | |
| 510 guy = chat; | |
| 511 } | |
| 512 | |
| 7457 | 513 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.html", localtime(&log->time)); |
| 514 | |
| 515 dir = g_build_filename(ud, "logs", | |
| 516 prpl, guy, gaim_normalize(log->account, log->name), NULL); | |
| 7612 | 517 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
| 7457 | 518 g_free(guy); |
| 519 | |
| 520 filename = g_build_filename(dir, date, NULL); | |
| 521 g_free(dir); | |
| 522 | |
| 7616 | 523 log->logger_data = data = g_new0(struct generic_logger_data, 1); |
| 524 | |
| 525 data->file = fopen(filename, "a"); | |
| 526 if (!data->file) { | |
| 7623 | 527 gaim_debug(GAIM_DEBUG_ERROR, "log", |
| 528 "Could not create log file %s\n", filename); | |
| 7564 | 529 g_free(filename); |
| 7457 | 530 return; |
| 531 } | |
| 532 g_free(filename); | |
| 533 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); | |
| 7616 | 534 fprintf(data->file, "<html><head><title>"); |
| 535 fprintf(data->file, "Conversation with %s at %s on %s (%s)", | |
| 7457 | 536 log->name, date, gaim_account_get_username(log->account), prpl); |
| 7616 | 537 fprintf(data->file, "</title></head><body>"); |
| 538 fprintf(data->file, | |
| 7457 | 539 "<h3>Conversation with %s at %s on %s (%s)</h3>\n", |
| 540 log->name, date, gaim_account_get_username(log->account), prpl); | |
| 541 } | |
| 7623 | 542 |
| 543 /* if we can't write to the file, give up before we hurt ourselves */ | |
| 544 if(!data->file) | |
| 545 return; | |
| 546 | |
| 7882 | 547 gaim_markup_html_to_xhtml(message, &msg_fixed, NULL); |
| 548 | |
| 8577 | 549 if(log->type == GAIM_LOG_SYSTEM){ |
| 550 strftime(date, sizeof(date), "%c", localtime(&time)); | |
| 551 fprintf(data->file, "---- %s @ %s ----<br/>\n", msg_fixed, date); | |
| 552 } else { | |
| 553 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); | |
| 554 if (type & GAIM_MESSAGE_SYSTEM) | |
| 555 fprintf(data->file, "<font size=\"2\">(%s)</font><b> %s</b><br/>\n", date, msg_fixed); | |
| 556 else if (type & GAIM_MESSAGE_WHISPER) | |
| 557 fprintf(data->file, "<font color=\"#6C2585\"><font size=\"2\">(%s)</font><b> %s:</b></font> %s<br/>\n", | |
| 558 date, from, msg_fixed); | |
| 559 else if (type & GAIM_MESSAGE_AUTO_RESP) { | |
| 560 if (type & GAIM_MESSAGE_SEND) | |
| 561 fprintf(data->file, _("<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, from, msg_fixed); | |
| 562 else if (type & GAIM_MESSAGE_RECV) | |
| 563 fprintf(data->file, _("<font color=\"#A82F2F\"><font size=\"2\">(%s)</font> <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, from, msg_fixed); | |
| 564 } else if (type & GAIM_MESSAGE_RECV) { | |
| 565 if(gaim_message_meify(msg_fixed, -1)) | |
| 566 fprintf(data->file, "<font color=\"#6C2585\"><font size=\"2\">(%s)</font> <b>***%s</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
| 567 date, from, gc->prpl->info->name, msg_fixed); | |
| 568 else | |
| 569 fprintf(data->file, "<font color=\"#A82F2F\"><font size=\"2\">(%s)</font> <b>%s:</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
| 570 date, from, gc->prpl->info->name, msg_fixed); | |
| 571 } else if (type & GAIM_MESSAGE_SEND) { | |
| 572 if(gaim_message_meify(msg_fixed, -1)) | |
| 573 fprintf(data->file, "<font color=\"#6C2585\"><font size=\"2\">(%s)</font> <b>***%s</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
| 574 date, from, gc->prpl->info->name, msg_fixed); | |
| 575 else | |
| 576 fprintf(data->file, "<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s:</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
| 577 date, from, gc->prpl->info->name, msg_fixed); | |
| 578 } | |
| 7564 | 579 } |
| 8573 | 580 |
| 7882 | 581 g_free(msg_fixed); |
| 7616 | 582 fflush(data->file); |
| 7457 | 583 } |
| 584 | |
| 585 static void html_logger_finalize(GaimLog *log) | |
| 586 { | |
| 7616 | 587 struct generic_logger_data *data = log->logger_data; |
| 588 if (data) { | |
| 589 if(data->file) { | |
| 590 fprintf(data->file, "</body></html>"); | |
| 591 fclose(data->file); | |
| 592 } | |
| 593 g_free(data->path); | |
| 7752 | 594 g_free(data); |
| 7463 | 595 } |
| 7457 | 596 } |
| 597 | |
| 598 static GList *html_logger_list(const char *sn, GaimAccount *account) | |
| 599 { | |
| 600 return log_lister_common(sn, account, ".html", &html_logger); | |
| 601 } | |
| 602 | |
| 8573 | 603 static GList *html_logger_list_syslog(GaimAccount *account) |
| 604 { | |
| 605 return log_lister_common(".system", account, ".html", &html_logger); | |
| 606 } | |
| 607 | |
| 7457 | 608 static char *html_logger_read(GaimLog *log, GaimLogReadFlags *flags) |
| 609 { | |
| 610 char *read, *minus_header; | |
| 7616 | 611 struct generic_logger_data *data = log->logger_data; |
| 7457 | 612 *flags = GAIM_LOG_READ_NO_NEWLINE; |
| 7616 | 613 if (!data || !data->path) |
| 614 return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>")); | |
| 615 if (g_file_get_contents(data->path, &read, NULL, NULL)) { | |
| 7457 | 616 minus_header = strchr(read, '\n'); |
| 617 if (!minus_header) | |
| 618 minus_header = g_strdup(read); | |
| 619 else | |
| 620 minus_header = g_strdup(minus_header + 1); | |
| 621 g_free(read); | |
| 622 return minus_header; | |
| 623 } | |
| 8578 | 624 return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path); |
| 7457 | 625 } |
| 626 | |
| 8573 | 627 static void html_logger_create(GaimLog *log) |
| 628 { | |
| 629 if(log->type == GAIM_LOG_SYSTEM){ | |
| 630 char date[64]; | |
| 631 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
| 632 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); | |
| 633 char *ud = gaim_user_dir(); | |
| 634 char *dir = g_build_filename(ud, "logs", prpl, log->name, ".system", NULL); | |
| 635 char *filename; | |
| 636 struct generic_logger_data *data; | |
| 637 | |
| 638 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
| 639 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.html", localtime(&log->time)); | |
| 640 filename = g_build_filename(dir, date, NULL); | |
| 641 g_free(dir); | |
| 642 | |
| 643 log->logger_data = data = g_new0(struct generic_logger_data, 1); | |
| 644 | |
| 645 data->file = fopen(filename, "a"); | |
| 646 if (!data->file) { | |
| 647 gaim_debug(GAIM_DEBUG_ERROR, "log", | |
| 648 "Could not create log file %s\n", filename); | |
| 649 g_free(filename); | |
| 650 return; | |
| 651 } | |
| 652 fprintf(data->file, "<html><head><title>"); | |
| 653 fprintf(data->file, "System Log for %s (%s)", | |
| 654 gaim_account_get_username(log->account), prpl); | |
| 655 fprintf(data->file, "</title></head><body>"); | |
| 656 g_free(filename); | |
| 657 } | |
| 658 } | |
| 659 | |
| 7457 | 660 static GaimLogLogger html_logger = { |
| 661 N_("HTML"), "html", | |
| 8573 | 662 html_logger_create, |
| 7457 | 663 html_logger_write, |
| 664 html_logger_finalize, | |
| 665 html_logger_list, | |
| 7556 | 666 html_logger_read, |
| 8096 | 667 log_sizer_common, |
| 8573 | 668 NULL, |
| 669 html_logger_list_syslog | |
| 7457 | 670 }; |
| 671 | |
| 672 | |
| 673 | |
| 674 | |
| 675 /**************************** | |
| 7431 | 676 ** PLAIN TEXT LOGGER ******* |
| 677 ****************************/ | |
| 4184 | 678 |
| 7436 | 679 static void txt_logger_write(GaimLog *log, |
| 680 GaimMessageFlags type, | |
| 7431 | 681 const char *from, time_t time, const char *message) |
| 682 { | |
| 683 char date[64]; | |
| 684 char *stripped = NULL; | |
| 7616 | 685 struct generic_logger_data *data = log->logger_data; |
| 686 if (!data) { | |
| 7431 | 687 /* This log is new. We could use the loggers 'new' function, but |
| 688 * creating a new file there would result in empty files in the case | |
| 689 * that you open a convo with someone, but don't say anything. | |
| 8573 | 690 * |
| 691 * The log is also not system log. Because if it is, data would be | |
| 692 * created in txt_logger_create | |
| 7431 | 693 */ |
| 694 char *ud = gaim_user_dir(); | |
| 7473 | 695 char *filename; |
| 7431 | 696 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); |
| 7553 | 697 char *chat; |
| 7431 | 698 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
| 7956 | 699 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); |
| 7431 | 700 char *dir; |
| 7436 | 701 |
| 7553 | 702 if (log->type == GAIM_LOG_CHAT) { |
| 703 chat = g_strdup_printf("%s.chat", guy); | |
| 704 g_free(guy); | |
| 705 guy = chat; | |
| 706 } | |
| 7453 | 707 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.txt", localtime(&log->time)); |
| 7436 | 708 |
| 709 dir = g_build_filename(ud, "logs", | |
| 7431 | 710 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
| 7612 | 711 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
| 7447 | 712 g_free(guy); |
| 7436 | 713 |
| 7473 | 714 filename = g_build_filename(dir, date, NULL); |
| 7431 | 715 g_free(dir); |
| 7436 | 716 |
| 7616 | 717 log->logger_data = data = g_new0(struct generic_logger_data, 1); |
| 718 | |
| 719 data->file = fopen(filename, "a"); | |
| 720 if (!data->file) { | |
| 7431 | 721 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); |
| 7564 | 722 g_free(filename); |
| 7431 | 723 return; |
| 4184 | 724 } |
| 7447 | 725 g_free(filename); |
| 7453 | 726 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
| 7616 | 727 fprintf(data->file, "Conversation with %s at %s on %s (%s)\n", |
| 7431 | 728 log->name, date, gaim_account_get_username(log->account), prpl); |
| 729 } | |
| 7436 | 730 |
| 7623 | 731 /* if we can't write to the file, give up before we hurt ourselves */ |
| 732 if(!data->file) | |
| 733 return; | |
| 734 | |
| 8573 | 735 stripped = gaim_markup_strip_html(message); |
| 736 | |
| 737 if(log->type == GAIM_LOG_SYSTEM){ | |
| 738 strftime(date, sizeof(date), "%c", localtime(&time)); | |
| 739 fprintf(data->file, "---- %s @ %s ----\n", stripped, date); | |
| 740 } else { | |
| 741 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); | |
| 742 if (type & GAIM_MESSAGE_SEND || | |
| 743 type & GAIM_MESSAGE_RECV) { | |
| 744 if (type & GAIM_MESSAGE_AUTO_RESP) { | |
| 745 fprintf(data->file, _("(%s) %s <AUTO-REPLY>: %s\n"), date, | |
| 746 from, stripped); | |
| 747 } else { | |
| 748 if(gaim_message_meify(stripped, -1)) | |
| 749 fprintf(data->file, "(%s) ***%s %s\n", date, from, | |
| 750 stripped); | |
| 751 else | |
| 752 fprintf(data->file, "(%s) %s: %s\n", date, from, | |
| 753 stripped); | |
| 754 } | |
| 755 } else if (type & GAIM_MESSAGE_SYSTEM) | |
| 756 fprintf(data->file, "(%s) %s\n", date, stripped); | |
| 757 else if (type & GAIM_MESSAGE_NO_LOG) { | |
| 758 /* This shouldn't happen */ | |
| 759 g_free(stripped); | |
| 760 return; | |
| 761 } else if (type & GAIM_MESSAGE_WHISPER) | |
| 762 fprintf(data->file, "(%s) *%s* %s", date, from, stripped); | |
| 763 else | |
| 764 fprintf(data->file, "(%s) %s%s %s\n", date, from ? from : "", | |
| 765 from ? ":" : "", stripped); | |
| 766 } | |
| 767 | |
| 768 fflush(data->file); | |
| 769 g_free(stripped); | |
| 7431 | 770 } |
| 771 | |
| 772 static void txt_logger_finalize(GaimLog *log) | |
| 773 { | |
| 7616 | 774 struct generic_logger_data *data = log->logger_data; |
| 775 if (data) { | |
| 776 if(data->file) | |
| 777 fclose(data->file); | |
| 778 if(data->path) | |
| 779 g_free(data->path); | |
| 7752 | 780 g_free(data); |
| 7616 | 781 } |
| 7431 | 782 } |
| 783 | |
| 784 static GList *txt_logger_list(const char *sn, GaimAccount *account) | |
| 785 { | |
| 786 return log_lister_common(sn, account, ".txt", &txt_logger); | |
| 787 } | |
| 788 | |
| 8573 | 789 static GList *txt_logger_list_syslog(GaimAccount *account) |
| 790 { | |
| 791 return log_lister_common(".system", account, ".txt", &txt_logger); | |
| 792 } | |
| 793 | |
| 7431 | 794 static char *txt_logger_read(GaimLog *log, GaimLogReadFlags *flags) |
| 795 { | |
| 8517 | 796 char *read, *minus_header, *minus_header2; |
| 7616 | 797 struct generic_logger_data *data = log->logger_data; |
| 7457 | 798 *flags = 0; |
| 7616 | 799 if (!data || !data->path) |
| 800 return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>")); | |
| 801 if (g_file_get_contents(data->path, &read, NULL, NULL)) { | |
| 7431 | 802 minus_header = strchr(read, '\n'); |
| 803 if (!minus_header) | |
| 804 minus_header = g_strdup(read); | |
| 7436 | 805 else |
| 7431 | 806 minus_header = g_strdup(minus_header + 1); |
| 807 g_free(read); | |
| 8517 | 808 minus_header2 = gaim_escape_html(minus_header); |
| 809 g_free(minus_header); | |
| 810 return minus_header2; | |
| 7431 | 811 } |
| 8578 | 812 return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path); |
| 7436 | 813 } |
| 7431 | 814 |
| 8573 | 815 static void txt_logger_create(GaimLog *log) |
| 816 { | |
| 817 if(log->type == GAIM_LOG_SYSTEM){ | |
| 818 char date[64]; | |
| 819 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
| 820 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); | |
| 821 char *ud = gaim_user_dir(); | |
| 822 char *dir = g_build_filename(ud, "logs", prpl, log->name, ".system", NULL); | |
| 823 char *filename; | |
| 824 struct generic_logger_data *data; | |
| 825 | |
| 826 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
| 827 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.txt", localtime(&log->time)); | |
| 828 filename = g_build_filename(dir, date, NULL); | |
| 829 g_free(dir); | |
| 830 | |
| 831 log->logger_data = data = g_new0(struct generic_logger_data, 1); | |
| 832 | |
| 833 data->file = fopen(filename, "a"); | |
| 834 if (!data->file) { | |
| 835 gaim_debug(GAIM_DEBUG_ERROR, "log", | |
| 836 "Could not create log file %s\n", filename); | |
| 837 g_free(filename); | |
| 838 return; | |
| 839 } | |
| 840 g_free(filename); | |
| 841 } | |
| 842 } | |
| 843 | |
| 7431 | 844 static GaimLogLogger txt_logger = { |
| 845 N_("Plain text"), "txt", | |
| 8573 | 846 txt_logger_create, |
| 7431 | 847 txt_logger_write, |
| 848 txt_logger_finalize, | |
| 849 txt_logger_list, | |
| 7556 | 850 txt_logger_read, |
| 8096 | 851 log_sizer_common, |
| 8573 | 852 NULL, |
| 853 txt_logger_list_syslog | |
| 7431 | 854 }; |
| 855 | |
| 856 /**************** | |
| 857 * OLD LOGGER *** | |
| 858 ****************/ | |
| 859 | |
| 860 /* The old logger doesn't write logs, only reads them. This is to include | |
| 861 * old logs in the log viewer transparently. | |
| 862 */ | |
| 863 | |
| 864 struct old_logger_data { | |
| 7764 | 865 GaimStringref *pathref; |
| 7431 | 866 int offset; |
| 867 int length; | |
| 868 }; | |
| 869 | |
| 7436 | 870 static GList *old_logger_list(const char *sn, GaimAccount *account) |
| 7431 | 871 { |
| 872 FILE *file; | |
| 873 char buf[BUF_LONG]; | |
| 874 struct tm tm; | |
| 7761 | 875 char month[4]; |
| 7431 | 876 struct old_logger_data *data = NULL; |
| 877 char *logfile = g_strdup_printf("%s.log", gaim_normalize(account, sn)); | |
| 7764 | 878 char *pathstr = g_build_filename(gaim_user_dir(), "logs", logfile, NULL); |
| 879 GaimStringref *pathref = gaim_stringref_new(pathstr); | |
| 7431 | 880 char *newlog; |
| 7761 | 881 int logfound = 0; |
| 882 int lastoff = 0; | |
| 883 int newlen; | |
| 7791 | 884 time_t lasttime = 0; |
| 7431 | 885 |
| 886 GaimLog *log = NULL; | |
| 887 GList *list = NULL; | |
| 888 | |
| 7473 | 889 g_free(logfile); |
| 7764 | 890 g_free(pathstr); |
| 7473 | 891 |
| 7764 | 892 if (!(file = fopen(gaim_stringref_value(pathref), "rb"))) { |
| 893 gaim_stringref_unref(pathref); | |
| 7431 | 894 return NULL; |
| 7447 | 895 } |
| 7436 | 896 |
| 7431 | 897 while (fgets(buf, BUF_LONG, file)) { |
| 898 if ((newlog = strstr(buf, "---- New C"))) { | |
| 899 int length; | |
| 900 int offset; | |
| 901 char convostart[32]; | |
| 902 char *temp = strchr(buf, '@'); | |
| 7436 | 903 |
| 7431 | 904 if (temp == NULL || strlen(temp) < 2) |
| 905 continue; | |
| 7436 | 906 |
| 7431 | 907 temp++; |
| 908 length = strcspn(temp, "-"); | |
| 909 if (length > 31) length = 31; | |
| 7436 | 910 |
| 7431 | 911 offset = ftell(file); |
| 7436 | 912 |
| 7761 | 913 if (logfound) { |
| 914 newlen = offset - lastoff - length; | |
| 7436 | 915 if(strstr(buf, "----</H3><BR>")) { |
| 7761 | 916 newlen -= |
| 917 sizeof("<HR><BR><H3 Align=Center> ---- New Conversation @ ") + | |
| 918 sizeof("----</H3><BR>") - 2; | |
| 7436 | 919 } else { |
| 7761 | 920 newlen -= |
| 921 sizeof("---- New Conversation @ ") + sizeof("----") - 2; | |
| 7436 | 922 } |
| 923 | |
| 7461 | 924 if(strchr(buf, '\r')) |
| 7770 | 925 newlen--; |
| 7461 | 926 |
| 7761 | 927 if (newlen != 0) { |
| 928 log = gaim_log_new(GAIM_LOG_IM, sn, account, -1); | |
| 929 log->logger = &old_logger; | |
| 930 log->time = lasttime; | |
| 931 data = g_new0(struct old_logger_data, 1); | |
| 932 data->offset = lastoff; | |
| 933 data->length = newlen; | |
| 7764 | 934 data->pathref = gaim_stringref_ref(pathref); |
| 7761 | 935 log->logger_data = data; |
| 7431 | 936 list = g_list_append(list, log); |
| 7761 | 937 } |
| 7431 | 938 } |
| 939 | |
| 7761 | 940 logfound = 1; |
| 941 lastoff = offset; | |
| 7436 | 942 |
| 7431 | 943 g_snprintf(convostart, length, "%s", temp); |
| 7676 | 944 sscanf(convostart, "%*s %s %d %d:%d:%d %d", |
| 945 month, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year); | |
| 946 /* Ugly hack, in case current locale is not English */ | |
| 947 if (strcmp(month, "Jan") == 0) { | |
| 948 tm.tm_mon= 0; | |
| 949 } else if (strcmp(month, "Feb") == 0) { | |
| 950 tm.tm_mon = 1; | |
| 951 } else if (strcmp(month, "Mar") == 0) { | |
| 952 tm.tm_mon = 2; | |
| 953 } else if (strcmp(month, "Apr") == 0) { | |
| 954 tm.tm_mon = 3; | |
| 955 } else if (strcmp(month, "May") == 0) { | |
| 956 tm.tm_mon = 4; | |
| 957 } else if (strcmp(month, "Jun") == 0) { | |
| 958 tm.tm_mon = 5; | |
| 959 } else if (strcmp(month, "Jul") == 0) { | |
| 960 tm.tm_mon = 6; | |
| 961 } else if (strcmp(month, "Aug") == 0) { | |
| 962 tm.tm_mon = 7; | |
| 963 } else if (strcmp(month, "Sep") == 0) { | |
| 964 tm.tm_mon = 8; | |
| 965 } else if (strcmp(month, "Oct") == 0) { | |
| 966 tm.tm_mon = 9; | |
| 967 } else if (strcmp(month, "Nov") == 0) { | |
| 968 tm.tm_mon = 10; | |
| 969 } else if (strcmp(month, "Dec") == 0) { | |
| 970 tm.tm_mon = 11; | |
| 971 } | |
| 972 tm.tm_year -= 1900; | |
| 7761 | 973 lasttime = mktime(&tm); |
| 4184 | 974 } |
| 975 } | |
| 7613 | 976 |
| 7761 | 977 if (logfound) { |
| 978 if ((newlen = ftell(file) - lastoff) != 0) { | |
| 979 log = gaim_log_new(GAIM_LOG_IM, sn, account, -1); | |
| 980 log->logger = &old_logger; | |
| 981 log->time = lasttime; | |
| 982 data = g_new0(struct old_logger_data, 1); | |
| 983 data->offset = lastoff; | |
| 984 data->length = newlen; | |
| 7764 | 985 data->pathref = gaim_stringref_ref(pathref); |
| 7761 | 986 log->logger_data = data; |
| 7613 | 987 list = g_list_append(list, log); |
| 7761 | 988 } |
| 7613 | 989 } |
| 990 | |
| 7764 | 991 gaim_stringref_unref(pathref); |
| 7431 | 992 fclose(file); |
| 993 return list; | |
| 4184 | 994 } |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
995 |
| 8096 | 996 static int old_logger_total_size(const char *name, GaimAccount *account) |
| 997 { | |
| 998 char *logfile = g_strdup_printf("%s.log", gaim_normalize(account, name)); | |
| 999 char *pathstr = g_build_filename(gaim_user_dir(), "logs", logfile, NULL); | |
| 1000 int size; | |
| 1001 struct stat st; | |
| 1002 | |
| 1003 if (stat(pathstr, &st)) | |
| 1004 size = 0; | |
| 1005 else | |
| 1006 size = st.st_size; | |
| 1007 | |
| 1008 g_free(logfile); | |
| 1009 g_free(pathstr); | |
| 1010 | |
| 1011 return size; | |
| 1012 } | |
| 1013 | |
| 7616 | 1014 static char * old_logger_read (GaimLog *log, GaimLogReadFlags *flags) |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
1015 { |
| 7431 | 1016 struct old_logger_data *data = log->logger_data; |
| 7764 | 1017 FILE *file = fopen(gaim_stringref_value(data->pathref), "rb"); |
| 7431 | 1018 char *read = g_malloc(data->length + 1); |
| 1019 fseek(file, data->offset, SEEK_SET); | |
| 1020 fread(read, data->length, 1, file); | |
| 8370 | 1021 fclose(file); |
| 7431 | 1022 read[data->length] = '\0'; |
| 7436 | 1023 *flags = 0; |
| 1024 if(strstr(read, "<BR>")) | |
| 1025 *flags |= GAIM_LOG_READ_NO_NEWLINE; | |
| 7431 | 1026 return read; |
| 1027 } | |
|
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
1028 |
| 7616 | 1029 static int old_logger_size (GaimLog *log) |
| 7556 | 1030 { |
| 1031 struct old_logger_data *data = log->logger_data; | |
| 7616 | 1032 return data ? data->length : 0; |
| 1033 } | |
| 1034 | |
| 1035 static void old_logger_finalize(GaimLog *log) | |
| 1036 { | |
| 1037 struct old_logger_data *data = log->logger_data; | |
| 7764 | 1038 gaim_stringref_unref(data->pathref); |
| 7616 | 1039 g_free(data); |
| 7556 | 1040 } |
| 1041 | |
| 7431 | 1042 static GaimLogLogger old_logger = { |
| 1043 "old logger", "old", | |
| 7616 | 1044 NULL, NULL, |
| 1045 old_logger_finalize, | |
| 7431 | 1046 old_logger_list, |
| 7616 | 1047 old_logger_read, |
| 8096 | 1048 old_logger_size, |
| 8573 | 1049 old_logger_total_size, |
| 1050 NULL | |
| 7431 | 1051 }; |
