Mercurial > pidgin
annotate src/log.c @ 9251:45d2ad4ac1c1
[gaim-migrate @ 10050]
Stu Tomlinson has provided a nice patch to move the separation of IM
and Chat windows back into the core from the extplacement plugin.
It's awesome to have crazy patch writers, and even better to have
crazy patch writers who write what I want to write before I do it,
thus saving me the effort.
committer: Tailor Script <tailor@pidgin.im>
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Wed, 09 Jun 2004 20:47:07 +0000 |
parents | de87e510ff9a |
children | db95a6641ec1 |
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 | |
8898 | 135 int gaim_log_get_total_size(GaimLogType type, const char *name, GaimAccount *account) |
7556 | 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){ |
8898 | 153 size += (logger->total_size)(type, name, account); |
8635 | 154 } else if(logger->list) { |
8898 | 155 GList *logs = (logger->list)(type, name, account); |
8635 | 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 | |
8898 | 199 GaimLogLogger *gaim_log_logger_new( |
200 void(*create)(GaimLog *), | |
201 void(*write)(GaimLog *, GaimMessageFlags, const char *, time_t, const char *), | |
202 void(*finalize)(GaimLog *), | |
203 GList*(*list)(GaimLogType type, const char*, GaimAccount*), | |
204 char*(*read)(GaimLog*, GaimLogReadFlags*), | |
205 int(*size)(GaimLog*)) | |
7431 | 206 { |
207 GaimLogLogger *logger = g_new0(GaimLogLogger, 1); | |
7440 | 208 logger->create = create; |
7431 | 209 logger->write = write; |
210 logger->finalize = finalize; | |
211 logger->list = list; | |
212 logger->read = read; | |
7556 | 213 logger->size = size; |
7431 | 214 return logger; |
4184 | 215 } |
216 | |
7431 | 217 void gaim_log_logger_free(GaimLogLogger *logger) |
4184 | 218 { |
7431 | 219 g_free(logger); |
220 } | |
4184 | 221 |
7431 | 222 void gaim_log_logger_add (GaimLogLogger *logger) |
223 { | |
224 g_return_if_fail(logger); | |
225 if (g_slist_find(loggers, logger)) | |
226 return; | |
227 loggers = g_slist_append(loggers, logger); | |
228 } | |
229 | |
230 void gaim_log_logger_remove (GaimLogLogger *logger) | |
231 { | |
232 g_return_if_fail(logger); | |
233 g_slist_remove(loggers, logger); | |
4184 | 234 } |
235 | |
7431 | 236 void gaim_log_logger_set (GaimLogLogger *logger) |
4184 | 237 { |
7431 | 238 g_return_if_fail(logger); |
239 current_logger = logger; | |
7436 | 240 } |
4184 | 241 |
7431 | 242 GaimLogLogger *gaim_log_logger_get() |
243 { | |
244 return current_logger; | |
245 } | |
4184 | 246 |
7431 | 247 GList *gaim_log_logger_get_options(void) |
248 { | |
249 GSList *n; | |
250 GList *list = NULL; | |
251 GaimLogLogger *data; | |
4184 | 252 |
7431 | 253 for (n = loggers; n; n = n->next) { |
254 data = n->data; | |
255 if (!data->write) | |
256 continue; | |
7494 | 257 list = g_list_append(list, _(data->name)); |
7431 | 258 list = g_list_append(list, data->id); |
4184 | 259 } |
260 | |
7431 | 261 return list; |
262 } | |
263 | |
8573 | 264 gint gaim_log_compare(gconstpointer y, gconstpointer z) |
7431 | 265 { |
7436 | 266 const GaimLog *a = y; |
267 const GaimLog *b = z; | |
268 | |
7431 | 269 return b->time - a->time; |
270 } | |
271 | |
8898 | 272 GList *gaim_log_get_logs(GaimLogType type, const char *name, GaimAccount *account) |
7431 | 273 { |
274 GList *logs = NULL; | |
275 GSList *n; | |
276 for (n = loggers; n; n = n->next) { | |
277 GaimLogLogger *logger = n->data; | |
278 if (!logger->list) | |
279 continue; | |
8898 | 280 logs = g_list_concat(logs, logger->list(type, name, account)); |
7431 | 281 } |
7436 | 282 |
8573 | 283 return g_list_sort(logs, gaim_log_compare); |
284 } | |
285 | |
286 GList *gaim_log_get_system_logs(GaimAccount *account) | |
287 { | |
288 GList *logs = NULL; | |
289 GSList *n; | |
290 for (n = loggers; n; n = n->next) { | |
291 GaimLogLogger *logger = n->data; | |
292 if (!logger->list_syslog) | |
293 continue; | |
294 logs = g_list_concat(logs, logger->list_syslog(account)); | |
295 } | |
296 | |
297 return g_list_sort(logs, gaim_log_compare); | |
7431 | 298 } |
299 | |
300 void gaim_log_init(void) | |
7436 | 301 { |
7431 | 302 gaim_prefs_add_none("/core/logging"); |
7555 | 303 gaim_prefs_add_bool("/core/logging/log_ims", FALSE); |
304 gaim_prefs_add_bool("/core/logging/log_chats", FALSE); | |
8573 | 305 gaim_prefs_add_bool("/core/logging/log_system", FALSE); |
306 gaim_prefs_add_bool("/core/logging/log_signon_signoff", FALSE); | |
307 gaim_prefs_add_bool("/core/logging/log_idle_state", FALSE); | |
308 gaim_prefs_add_bool("/core/logging/log_away_state", FALSE); | |
309 gaim_prefs_add_bool("/core/logging/log_own_states", FALSE); | |
310 | |
7431 | 311 gaim_prefs_add_string("/core/logging/format", "txt"); |
7457 | 312 gaim_log_logger_add(&html_logger); |
7431 | 313 gaim_log_logger_add(&txt_logger); |
314 gaim_log_logger_add(&old_logger); | |
315 gaim_prefs_connect_callback("/core/logging/format", | |
316 logger_pref_cb, NULL); | |
317 gaim_prefs_trigger_callback("/core/logging/format"); | |
8635 | 318 |
319 logsize_users = g_hash_table_new_full((GHashFunc)_gaim_logsize_user_hash, | |
320 (GEqualFunc)_gaim_logsize_user_equal, | |
321 (GDestroyNotify)_gaim_logsize_user_free_key, NULL); | |
7431 | 322 } |
323 | |
324 /**************************************************************************** | |
325 * LOGGERS ****************************************************************** | |
326 ****************************************************************************/ | |
327 | |
7616 | 328 struct generic_logger_data { |
329 char *path; | |
330 FILE *file; | |
331 }; | |
332 | |
8898 | 333 static GList *log_lister_common(GaimLogType type, const char *name, GaimAccount *account, const char *ext, GaimLogLogger *logger) |
7431 | 334 { |
335 GDir *dir; | |
336 GList *list = NULL; | |
7628 | 337 const char *filename; |
8111 | 338 char *me; |
339 const char *prpl; | |
340 char *path; | |
341 | |
342 if(!account) | |
343 return NULL; | |
344 | |
8898 | 345 if (type == GAIM_LOG_CHAT) |
346 me = g_strdup_printf("%s.chat", gaim_normalize(account, gaim_account_get_username(account))); | |
347 else | |
348 me = g_strdup(gaim_normalize(account, gaim_account_get_username(account))); | |
4184 | 349 |
7956 | 350 /* does this seem like a bad way to get this component of the path to anyone else? --Nathan */ |
8111 | 351 prpl = GAIM_PLUGIN_PROTOCOL_INFO |
7956 | 352 (gaim_find_prpl(gaim_account_get_protocol_id(account)))->list_icon(account, NULL); |
8898 | 353 path = g_build_filename(gaim_user_dir(), "logs", prpl, me, gaim_normalize(account, name), NULL); |
7447 | 354 g_free(me); |
355 | |
7431 | 356 if (!(dir = g_dir_open(path, 0, NULL))) { |
357 g_free(path); | |
358 return NULL; | |
359 } | |
8898 | 360 |
7431 | 361 while ((filename = g_dir_read_name(dir))) { |
8577 | 362 if (gaim_str_has_suffix(filename, ext) && |
363 strlen(filename) == 17 + strlen(ext)) { | |
7431 | 364 GaimLog *log; |
7616 | 365 struct generic_logger_data *data; |
8577 | 366 time_t stamp = gaim_str_to_time(filename, FALSE); |
7431 | 367 |
8898 | 368 log = gaim_log_new(type, name, account, stamp); |
7431 | 369 log->logger = logger; |
7616 | 370 log->logger_data = data = g_new0(struct generic_logger_data, 1); |
371 data->path = g_build_filename(path, filename, NULL); | |
7431 | 372 list = g_list_append(list, log); |
4184 | 373 } |
374 } | |
7431 | 375 g_dir_close(dir); |
7447 | 376 g_free(path); |
7431 | 377 return list; |
378 } | |
4184 | 379 |
7556 | 380 /* Only to be used with logs listed from log_lister_common */ |
7616 | 381 int log_sizer_common(GaimLog *log) |
7556 | 382 { |
383 struct stat st; | |
7616 | 384 struct generic_logger_data *data = log->logger_data; |
7556 | 385 |
7616 | 386 if (!data->path || stat(data->path, &st)) |
7556 | 387 st.st_size = 0; |
388 | |
389 return st.st_size; | |
390 } | |
391 | |
7431 | 392 #if 0 /* Maybe some other time. */ |
7443 | 393 /**************** |
7431 | 394 ** XML LOGGER ** |
395 ****************/ | |
396 | |
397 static const char *str_from_msg_type (GaimMessageFlags type) | |
398 { | |
7443 | 399 |
7431 | 400 return ""; |
7443 | 401 |
7431 | 402 } |
403 | |
7443 | 404 static void xml_logger_write(GaimLog *log, |
405 GaimMessageFlags type, | |
7431 | 406 const char *from, time_t time, const char *message) |
407 { | |
408 char date[64]; | |
409 char *xhtml = NULL; | |
410 if (!log->logger_data) { | |
411 /* This log is new. We could use the loggers 'new' function, but | |
412 * creating a new file there would result in empty files in the case | |
413 * that you open a convo with someone, but don't say anything. | |
414 */ | |
415 char *ud = gaim_user_dir(); | |
416 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
417 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
418 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
419 char *dir; | |
420 FILE *file; | |
421 | |
8898 | 422 if (log->type == GAIM_LOG_CHAT) { |
423 char *chat = g_strdup_printf("%s.chat", guy); | |
424 g_free(guy); | |
425 guy = chat; | |
426 } | |
427 | |
7453 | 428 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.xml", localtime(&log->time)); |
7443 | 429 |
430 dir = g_build_filename(ud, "logs", | |
7431 | 431 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
7612 | 432 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
7447 | 433 g_free(guy); |
7443 | 434 |
7431 | 435 char *filename = g_build_filename(dir, date, NULL); |
436 g_free(dir); | |
7443 | 437 |
7431 | 438 log->logger_data = fopen(filename, "a"); |
439 if (!log->logger_data) { | |
440 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
7564 | 441 g_free(filename); |
7431 | 442 return; |
443 } | |
7564 | 444 g_free(filename); |
7431 | 445 fprintf(log->logger_data, "<?xml version='1.0' encoding='UTF-8' ?>\n" |
446 "<?xml-stylesheet href='file:///usr/src/web/htdocs/log-stylesheet.xsl' type='text/xml' ?>\n"); | |
7443 | 447 |
7453 | 448 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
7431 | 449 fprintf(log->logger_data, "<conversation time='%s' screenname='%s' protocol='%s'>\n", |
450 date, log->name, prpl); | |
451 } | |
7443 | 452 |
7453 | 453 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); |
7431 | 454 gaim_markup_html_to_xhtml(message, &xhtml, NULL); |
455 if (from) | |
7443 | 456 fprintf(log->logger_data, "<message %s %s from='%s' time='%s'>%s</message>\n", |
457 str_from_msg_type(type), | |
7431 | 458 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
459 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
460 from, date, xhtml); | |
461 else | |
7443 | 462 fprintf(log->logger_data, "<message %s %s time='%s'>%s</message>\n", |
463 str_from_msg_type(type), | |
7431 | 464 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
465 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
7443 | 466 date, xhtml): |
7431 | 467 fflush(log->logger_data); |
468 g_free(xhtml); | |
7443 | 469 } |
470 | |
7431 | 471 static void xml_logger_finalize(GaimLog *log) |
472 { | |
473 if (log->logger_data) { | |
474 fprintf(log->logger_data, "</conversation>\n"); | |
475 fclose(log->logger_data); | |
476 log->logger_data = NULL; | |
477 } | |
478 } | |
7443 | 479 |
8898 | 480 static GList *xml_logger_list(GaimLogType type, const char *sn, GaimAccount *account) |
7431 | 481 { |
8898 | 482 return log_lister_common(type, sn, account, ".xml", &xml_logger); |
4184 | 483 } |
484 | |
7431 | 485 static GaimLogLogger xml_logger = { |
486 N_("XML"), "xml", | |
487 NULL, | |
488 xml_logger_write, | |
489 xml_logger_finalize, | |
490 xml_logger_list, | |
8096 | 491 NULL, |
7431 | 492 NULL |
493 }; | |
494 #endif | |
5563
9eb5b13fd412
[gaim-migrate @ 5965]
Christian Hammond <chipx86@chipx86.com>
parents:
5560
diff
changeset
|
495 |
7431 | 496 /**************************** |
7457 | 497 ** HTML LOGGER ************* |
498 ****************************/ | |
499 | |
500 static void html_logger_write(GaimLog *log, GaimMessageFlags type, | |
501 const char *from, time_t time, const char *message) | |
502 { | |
7489 | 503 GaimConnection *gc = gaim_account_get_connection(log->account); |
7457 | 504 char date[64]; |
7882 | 505 char *msg_fixed; |
7616 | 506 struct generic_logger_data *data = log->logger_data; |
7618 | 507 if(!data) { |
7457 | 508 /* This log is new */ |
509 char *ud = gaim_user_dir(); | |
510 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
7553 | 511 char *chat; |
7457 | 512 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
7956 | 513 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); |
7457 | 514 char *dir; |
515 char *filename; | |
516 | |
7553 | 517 if (log->type == GAIM_LOG_CHAT) { |
518 chat = g_strdup_printf("%s.chat", guy); | |
519 g_free(guy); | |
520 guy = chat; | |
521 } | |
522 | |
7457 | 523 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.html", localtime(&log->time)); |
524 | |
525 dir = g_build_filename(ud, "logs", | |
526 prpl, guy, gaim_normalize(log->account, log->name), NULL); | |
7612 | 527 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
7457 | 528 g_free(guy); |
529 | |
530 filename = g_build_filename(dir, date, NULL); | |
531 g_free(dir); | |
532 | |
7616 | 533 log->logger_data = data = g_new0(struct generic_logger_data, 1); |
534 | |
535 data->file = fopen(filename, "a"); | |
536 if (!data->file) { | |
7623 | 537 gaim_debug(GAIM_DEBUG_ERROR, "log", |
538 "Could not create log file %s\n", filename); | |
7564 | 539 g_free(filename); |
7457 | 540 return; |
541 } | |
542 g_free(filename); | |
543 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); | |
7616 | 544 fprintf(data->file, "<html><head><title>"); |
545 fprintf(data->file, "Conversation with %s at %s on %s (%s)", | |
7457 | 546 log->name, date, gaim_account_get_username(log->account), prpl); |
7616 | 547 fprintf(data->file, "</title></head><body>"); |
548 fprintf(data->file, | |
7457 | 549 "<h3>Conversation with %s at %s on %s (%s)</h3>\n", |
550 log->name, date, gaim_account_get_username(log->account), prpl); | |
551 } | |
7623 | 552 |
553 /* if we can't write to the file, give up before we hurt ourselves */ | |
554 if(!data->file) | |
555 return; | |
556 | |
7882 | 557 gaim_markup_html_to_xhtml(message, &msg_fixed, NULL); |
558 | |
8577 | 559 if(log->type == GAIM_LOG_SYSTEM){ |
560 strftime(date, sizeof(date), "%c", localtime(&time)); | |
561 fprintf(data->file, "---- %s @ %s ----<br/>\n", msg_fixed, date); | |
562 } else { | |
563 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); | |
564 if (type & GAIM_MESSAGE_SYSTEM) | |
565 fprintf(data->file, "<font size=\"2\">(%s)</font><b> %s</b><br/>\n", date, msg_fixed); | |
566 else if (type & GAIM_MESSAGE_WHISPER) | |
567 fprintf(data->file, "<font color=\"#6C2585\"><font size=\"2\">(%s)</font><b> %s:</b></font> %s<br/>\n", | |
568 date, from, msg_fixed); | |
569 else if (type & GAIM_MESSAGE_AUTO_RESP) { | |
570 if (type & GAIM_MESSAGE_SEND) | |
571 fprintf(data->file, _("<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, from, msg_fixed); | |
572 else if (type & GAIM_MESSAGE_RECV) | |
573 fprintf(data->file, _("<font color=\"#A82F2F\"><font size=\"2\">(%s)</font> <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, from, msg_fixed); | |
574 } else if (type & GAIM_MESSAGE_RECV) { | |
575 if(gaim_message_meify(msg_fixed, -1)) | |
576 fprintf(data->file, "<font color=\"#6C2585\"><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 else | |
579 fprintf(data->file, "<font color=\"#A82F2F\"><font size=\"2\">(%s)</font> <b>%s:</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
580 date, from, gc->prpl->info->name, msg_fixed); | |
581 } else if (type & GAIM_MESSAGE_SEND) { | |
582 if(gaim_message_meify(msg_fixed, -1)) | |
583 fprintf(data->file, "<font color=\"#6C2585\"><font size=\"2\">(%s)</font> <b>***%s</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
584 date, from, gc->prpl->info->name, msg_fixed); | |
585 else | |
586 fprintf(data->file, "<font color=\"#16569E\"><font size=\"2\">(%s)</font> <b>%s:</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
587 date, from, gc->prpl->info->name, msg_fixed); | |
588 } | |
7564 | 589 } |
8573 | 590 |
7882 | 591 g_free(msg_fixed); |
7616 | 592 fflush(data->file); |
7457 | 593 } |
594 | |
595 static void html_logger_finalize(GaimLog *log) | |
596 { | |
7616 | 597 struct generic_logger_data *data = log->logger_data; |
598 if (data) { | |
599 if(data->file) { | |
600 fprintf(data->file, "</body></html>"); | |
601 fclose(data->file); | |
602 } | |
603 g_free(data->path); | |
7752 | 604 g_free(data); |
7463 | 605 } |
7457 | 606 } |
607 | |
8898 | 608 static GList *html_logger_list(GaimLogType type, const char *sn, GaimAccount *account) |
7457 | 609 { |
8898 | 610 return log_lister_common(type, sn, account, ".html", &html_logger); |
7457 | 611 } |
612 | |
8573 | 613 static GList *html_logger_list_syslog(GaimAccount *account) |
614 { | |
8898 | 615 return log_lister_common(GAIM_LOG_SYSTEM, ".system", account, ".html", &html_logger); |
8573 | 616 } |
617 | |
7457 | 618 static char *html_logger_read(GaimLog *log, GaimLogReadFlags *flags) |
619 { | |
620 char *read, *minus_header; | |
7616 | 621 struct generic_logger_data *data = log->logger_data; |
7457 | 622 *flags = GAIM_LOG_READ_NO_NEWLINE; |
7616 | 623 if (!data || !data->path) |
624 return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>")); | |
625 if (g_file_get_contents(data->path, &read, NULL, NULL)) { | |
7457 | 626 minus_header = strchr(read, '\n'); |
627 if (!minus_header) | |
628 minus_header = g_strdup(read); | |
629 else | |
630 minus_header = g_strdup(minus_header + 1); | |
631 g_free(read); | |
632 return minus_header; | |
633 } | |
8578 | 634 return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path); |
7457 | 635 } |
636 | |
8573 | 637 static void html_logger_create(GaimLog *log) |
638 { | |
639 if(log->type == GAIM_LOG_SYSTEM){ | |
640 char date[64]; | |
641 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
642 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); | |
643 char *ud = gaim_user_dir(); | |
644 char *dir = g_build_filename(ud, "logs", prpl, log->name, ".system", NULL); | |
645 char *filename; | |
646 struct generic_logger_data *data; | |
647 | |
648 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
649 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.html", localtime(&log->time)); | |
650 filename = g_build_filename(dir, date, NULL); | |
651 g_free(dir); | |
652 | |
653 log->logger_data = data = g_new0(struct generic_logger_data, 1); | |
654 | |
655 data->file = fopen(filename, "a"); | |
656 if (!data->file) { | |
657 gaim_debug(GAIM_DEBUG_ERROR, "log", | |
658 "Could not create log file %s\n", filename); | |
659 g_free(filename); | |
660 return; | |
661 } | |
662 fprintf(data->file, "<html><head><title>"); | |
663 fprintf(data->file, "System Log for %s (%s)", | |
664 gaim_account_get_username(log->account), prpl); | |
665 fprintf(data->file, "</title></head><body>"); | |
666 g_free(filename); | |
667 } | |
668 } | |
669 | |
7457 | 670 static GaimLogLogger html_logger = { |
671 N_("HTML"), "html", | |
8573 | 672 html_logger_create, |
7457 | 673 html_logger_write, |
674 html_logger_finalize, | |
675 html_logger_list, | |
7556 | 676 html_logger_read, |
8096 | 677 log_sizer_common, |
8573 | 678 NULL, |
679 html_logger_list_syslog | |
7457 | 680 }; |
681 | |
682 | |
683 | |
684 | |
685 /**************************** | |
7431 | 686 ** PLAIN TEXT LOGGER ******* |
687 ****************************/ | |
4184 | 688 |
7436 | 689 static void txt_logger_write(GaimLog *log, |
690 GaimMessageFlags type, | |
7431 | 691 const char *from, time_t time, const char *message) |
692 { | |
693 char date[64]; | |
694 char *stripped = NULL; | |
7616 | 695 struct generic_logger_data *data = log->logger_data; |
696 if (!data) { | |
7431 | 697 /* This log is new. We could use the loggers 'new' function, but |
698 * creating a new file there would result in empty files in the case | |
699 * that you open a convo with someone, but don't say anything. | |
8573 | 700 * |
8898 | 701 * The log is also not a system log. Because if it is, data would |
702 * be created in txt_logger_create | |
7431 | 703 */ |
704 char *ud = gaim_user_dir(); | |
705 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
7553 | 706 char *chat; |
7431 | 707 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
7956 | 708 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); |
7431 | 709 char *dir; |
8898 | 710 char *filename; |
7436 | 711 |
7553 | 712 if (log->type == GAIM_LOG_CHAT) { |
713 chat = g_strdup_printf("%s.chat", guy); | |
714 g_free(guy); | |
715 guy = chat; | |
716 } | |
8898 | 717 |
7453 | 718 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.txt", localtime(&log->time)); |
7436 | 719 |
720 dir = g_build_filename(ud, "logs", | |
7431 | 721 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
7612 | 722 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
7447 | 723 g_free(guy); |
7436 | 724 |
7473 | 725 filename = g_build_filename(dir, date, NULL); |
7431 | 726 g_free(dir); |
7436 | 727 |
7616 | 728 log->logger_data = data = g_new0(struct generic_logger_data, 1); |
729 | |
730 data->file = fopen(filename, "a"); | |
731 if (!data->file) { | |
7431 | 732 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); |
7564 | 733 g_free(filename); |
7431 | 734 return; |
4184 | 735 } |
7447 | 736 g_free(filename); |
7453 | 737 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
7616 | 738 fprintf(data->file, "Conversation with %s at %s on %s (%s)\n", |
7431 | 739 log->name, date, gaim_account_get_username(log->account), prpl); |
740 } | |
7436 | 741 |
7623 | 742 /* if we can't write to the file, give up before we hurt ourselves */ |
743 if(!data->file) | |
744 return; | |
745 | |
8573 | 746 stripped = gaim_markup_strip_html(message); |
747 | |
748 if(log->type == GAIM_LOG_SYSTEM){ | |
749 strftime(date, sizeof(date), "%c", localtime(&time)); | |
750 fprintf(data->file, "---- %s @ %s ----\n", stripped, date); | |
751 } else { | |
752 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); | |
753 if (type & GAIM_MESSAGE_SEND || | |
754 type & GAIM_MESSAGE_RECV) { | |
755 if (type & GAIM_MESSAGE_AUTO_RESP) { | |
756 fprintf(data->file, _("(%s) %s <AUTO-REPLY>: %s\n"), date, | |
757 from, stripped); | |
758 } else { | |
759 if(gaim_message_meify(stripped, -1)) | |
760 fprintf(data->file, "(%s) ***%s %s\n", date, from, | |
761 stripped); | |
762 else | |
763 fprintf(data->file, "(%s) %s: %s\n", date, from, | |
764 stripped); | |
765 } | |
766 } else if (type & GAIM_MESSAGE_SYSTEM) | |
767 fprintf(data->file, "(%s) %s\n", date, stripped); | |
768 else if (type & GAIM_MESSAGE_NO_LOG) { | |
769 /* This shouldn't happen */ | |
770 g_free(stripped); | |
771 return; | |
772 } else if (type & GAIM_MESSAGE_WHISPER) | |
773 fprintf(data->file, "(%s) *%s* %s", date, from, stripped); | |
774 else | |
775 fprintf(data->file, "(%s) %s%s %s\n", date, from ? from : "", | |
776 from ? ":" : "", stripped); | |
777 } | |
778 | |
779 fflush(data->file); | |
780 g_free(stripped); | |
7431 | 781 } |
782 | |
783 static void txt_logger_finalize(GaimLog *log) | |
784 { | |
7616 | 785 struct generic_logger_data *data = log->logger_data; |
786 if (data) { | |
787 if(data->file) | |
788 fclose(data->file); | |
789 if(data->path) | |
790 g_free(data->path); | |
7752 | 791 g_free(data); |
7616 | 792 } |
7431 | 793 } |
794 | |
8898 | 795 static GList *txt_logger_list(GaimLogType type, const char *sn, GaimAccount *account) |
7431 | 796 { |
8898 | 797 return log_lister_common(type, sn, account, ".txt", &txt_logger); |
7431 | 798 } |
799 | |
8573 | 800 static GList *txt_logger_list_syslog(GaimAccount *account) |
801 { | |
8898 | 802 return log_lister_common(GAIM_LOG_SYSTEM, ".system", account, ".txt", &txt_logger); |
8573 | 803 } |
804 | |
7431 | 805 static char *txt_logger_read(GaimLog *log, GaimLogReadFlags *flags) |
806 { | |
8517 | 807 char *read, *minus_header, *minus_header2; |
7616 | 808 struct generic_logger_data *data = log->logger_data; |
7457 | 809 *flags = 0; |
7616 | 810 if (!data || !data->path) |
811 return g_strdup(_("<font color=\"red\"><b>Unable to find log path!</b></font>")); | |
812 if (g_file_get_contents(data->path, &read, NULL, NULL)) { | |
7431 | 813 minus_header = strchr(read, '\n'); |
814 if (!minus_header) | |
815 minus_header = g_strdup(read); | |
7436 | 816 else |
7431 | 817 minus_header = g_strdup(minus_header + 1); |
818 g_free(read); | |
8517 | 819 minus_header2 = gaim_escape_html(minus_header); |
820 g_free(minus_header); | |
821 return minus_header2; | |
7431 | 822 } |
8578 | 823 return g_strdup_printf(_("<font color=\"red\"><b>Could not read file: %s</b></font>"), data->path); |
7436 | 824 } |
7431 | 825 |
8573 | 826 static void txt_logger_create(GaimLog *log) |
827 { | |
828 if(log->type == GAIM_LOG_SYSTEM){ | |
829 char date[64]; | |
830 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
831 (gaim_find_prpl(gaim_account_get_protocol_id(log->account)))->list_icon(log->account, NULL); | |
832 char *ud = gaim_user_dir(); | |
833 char *dir = g_build_filename(ud, "logs", prpl, log->name, ".system", NULL); | |
834 char *filename; | |
835 struct generic_logger_data *data; | |
836 | |
837 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
838 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.txt", localtime(&log->time)); | |
839 filename = g_build_filename(dir, date, NULL); | |
840 g_free(dir); | |
841 | |
842 log->logger_data = data = g_new0(struct generic_logger_data, 1); | |
843 | |
844 data->file = fopen(filename, "a"); | |
845 if (!data->file) { | |
846 gaim_debug(GAIM_DEBUG_ERROR, "log", | |
847 "Could not create log file %s\n", filename); | |
848 g_free(filename); | |
849 return; | |
850 } | |
851 g_free(filename); | |
852 } | |
853 } | |
854 | |
7431 | 855 static GaimLogLogger txt_logger = { |
856 N_("Plain text"), "txt", | |
8573 | 857 txt_logger_create, |
7431 | 858 txt_logger_write, |
859 txt_logger_finalize, | |
860 txt_logger_list, | |
7556 | 861 txt_logger_read, |
8096 | 862 log_sizer_common, |
8573 | 863 NULL, |
864 txt_logger_list_syslog | |
7431 | 865 }; |
866 | |
867 /**************** | |
868 * OLD LOGGER *** | |
869 ****************/ | |
870 | |
871 /* The old logger doesn't write logs, only reads them. This is to include | |
872 * old logs in the log viewer transparently. | |
873 */ | |
874 | |
875 struct old_logger_data { | |
7764 | 876 GaimStringref *pathref; |
7431 | 877 int offset; |
878 int length; | |
879 }; | |
880 | |
8898 | 881 static GList *old_logger_list(GaimLogType type, const char *sn, GaimAccount *account) |
7431 | 882 { |
883 FILE *file; | |
884 char buf[BUF_LONG]; | |
885 struct tm tm; | |
7761 | 886 char month[4]; |
7431 | 887 struct old_logger_data *data = NULL; |
888 char *logfile = g_strdup_printf("%s.log", gaim_normalize(account, sn)); | |
7764 | 889 char *pathstr = g_build_filename(gaim_user_dir(), "logs", logfile, NULL); |
890 GaimStringref *pathref = gaim_stringref_new(pathstr); | |
7431 | 891 char *newlog; |
7761 | 892 int logfound = 0; |
893 int lastoff = 0; | |
894 int newlen; | |
7791 | 895 time_t lasttime = 0; |
7431 | 896 |
897 GaimLog *log = NULL; | |
898 GList *list = NULL; | |
899 | |
7473 | 900 g_free(logfile); |
7764 | 901 g_free(pathstr); |
7473 | 902 |
7764 | 903 if (!(file = fopen(gaim_stringref_value(pathref), "rb"))) { |
904 gaim_stringref_unref(pathref); | |
7431 | 905 return NULL; |
7447 | 906 } |
7436 | 907 |
7431 | 908 while (fgets(buf, BUF_LONG, file)) { |
909 if ((newlog = strstr(buf, "---- New C"))) { | |
910 int length; | |
911 int offset; | |
912 char convostart[32]; | |
913 char *temp = strchr(buf, '@'); | |
7436 | 914 |
7431 | 915 if (temp == NULL || strlen(temp) < 2) |
916 continue; | |
7436 | 917 |
7431 | 918 temp++; |
919 length = strcspn(temp, "-"); | |
920 if (length > 31) length = 31; | |
7436 | 921 |
7431 | 922 offset = ftell(file); |
7436 | 923 |
7761 | 924 if (logfound) { |
925 newlen = offset - lastoff - length; | |
7436 | 926 if(strstr(buf, "----</H3><BR>")) { |
7761 | 927 newlen -= |
928 sizeof("<HR><BR><H3 Align=Center> ---- New Conversation @ ") + | |
929 sizeof("----</H3><BR>") - 2; | |
7436 | 930 } else { |
7761 | 931 newlen -= |
932 sizeof("---- New Conversation @ ") + sizeof("----") - 2; | |
7436 | 933 } |
934 | |
7461 | 935 if(strchr(buf, '\r')) |
7770 | 936 newlen--; |
7461 | 937 |
7761 | 938 if (newlen != 0) { |
939 log = gaim_log_new(GAIM_LOG_IM, sn, account, -1); | |
940 log->logger = &old_logger; | |
941 log->time = lasttime; | |
942 data = g_new0(struct old_logger_data, 1); | |
943 data->offset = lastoff; | |
944 data->length = newlen; | |
7764 | 945 data->pathref = gaim_stringref_ref(pathref); |
7761 | 946 log->logger_data = data; |
7431 | 947 list = g_list_append(list, log); |
7761 | 948 } |
7431 | 949 } |
950 | |
7761 | 951 logfound = 1; |
952 lastoff = offset; | |
7436 | 953 |
7431 | 954 g_snprintf(convostart, length, "%s", temp); |
7676 | 955 sscanf(convostart, "%*s %s %d %d:%d:%d %d", |
956 month, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &tm.tm_year); | |
957 /* Ugly hack, in case current locale is not English */ | |
958 if (strcmp(month, "Jan") == 0) { | |
959 tm.tm_mon= 0; | |
960 } else if (strcmp(month, "Feb") == 0) { | |
961 tm.tm_mon = 1; | |
962 } else if (strcmp(month, "Mar") == 0) { | |
963 tm.tm_mon = 2; | |
964 } else if (strcmp(month, "Apr") == 0) { | |
965 tm.tm_mon = 3; | |
966 } else if (strcmp(month, "May") == 0) { | |
967 tm.tm_mon = 4; | |
968 } else if (strcmp(month, "Jun") == 0) { | |
969 tm.tm_mon = 5; | |
970 } else if (strcmp(month, "Jul") == 0) { | |
971 tm.tm_mon = 6; | |
972 } else if (strcmp(month, "Aug") == 0) { | |
973 tm.tm_mon = 7; | |
974 } else if (strcmp(month, "Sep") == 0) { | |
975 tm.tm_mon = 8; | |
976 } else if (strcmp(month, "Oct") == 0) { | |
977 tm.tm_mon = 9; | |
978 } else if (strcmp(month, "Nov") == 0) { | |
979 tm.tm_mon = 10; | |
980 } else if (strcmp(month, "Dec") == 0) { | |
981 tm.tm_mon = 11; | |
982 } | |
983 tm.tm_year -= 1900; | |
7761 | 984 lasttime = mktime(&tm); |
4184 | 985 } |
986 } | |
7613 | 987 |
7761 | 988 if (logfound) { |
989 if ((newlen = ftell(file) - lastoff) != 0) { | |
990 log = gaim_log_new(GAIM_LOG_IM, sn, account, -1); | |
991 log->logger = &old_logger; | |
992 log->time = lasttime; | |
993 data = g_new0(struct old_logger_data, 1); | |
994 data->offset = lastoff; | |
995 data->length = newlen; | |
7764 | 996 data->pathref = gaim_stringref_ref(pathref); |
7761 | 997 log->logger_data = data; |
7613 | 998 list = g_list_append(list, log); |
7761 | 999 } |
7613 | 1000 } |
1001 | |
7764 | 1002 gaim_stringref_unref(pathref); |
7431 | 1003 fclose(file); |
1004 return list; | |
4184 | 1005 } |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
1006 |
8898 | 1007 static int old_logger_total_size(GaimLogType type, const char *name, GaimAccount *account) |
8096 | 1008 { |
1009 char *logfile = g_strdup_printf("%s.log", gaim_normalize(account, name)); | |
1010 char *pathstr = g_build_filename(gaim_user_dir(), "logs", logfile, NULL); | |
1011 int size; | |
1012 struct stat st; | |
1013 | |
1014 if (stat(pathstr, &st)) | |
1015 size = 0; | |
1016 else | |
1017 size = st.st_size; | |
1018 | |
1019 g_free(logfile); | |
1020 g_free(pathstr); | |
1021 | |
1022 return size; | |
1023 } | |
1024 | |
7616 | 1025 static char * old_logger_read (GaimLog *log, GaimLogReadFlags *flags) |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
1026 { |
7431 | 1027 struct old_logger_data *data = log->logger_data; |
7764 | 1028 FILE *file = fopen(gaim_stringref_value(data->pathref), "rb"); |
7431 | 1029 char *read = g_malloc(data->length + 1); |
1030 fseek(file, data->offset, SEEK_SET); | |
1031 fread(read, data->length, 1, file); | |
8370 | 1032 fclose(file); |
7431 | 1033 read[data->length] = '\0'; |
7436 | 1034 *flags = 0; |
1035 if(strstr(read, "<BR>")) | |
1036 *flags |= GAIM_LOG_READ_NO_NEWLINE; | |
7431 | 1037 return read; |
1038 } | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
1039 |
7616 | 1040 static int old_logger_size (GaimLog *log) |
7556 | 1041 { |
1042 struct old_logger_data *data = log->logger_data; | |
7616 | 1043 return data ? data->length : 0; |
1044 } | |
1045 | |
1046 static void old_logger_finalize(GaimLog *log) | |
1047 { | |
1048 struct old_logger_data *data = log->logger_data; | |
7764 | 1049 gaim_stringref_unref(data->pathref); |
7616 | 1050 g_free(data); |
7556 | 1051 } |
1052 | |
7431 | 1053 static GaimLogLogger old_logger = { |
1054 "old logger", "old", | |
7616 | 1055 NULL, NULL, |
1056 old_logger_finalize, | |
7431 | 1057 old_logger_list, |
7616 | 1058 old_logger_read, |
8096 | 1059 old_logger_size, |
8573 | 1060 old_logger_total_size, |
1061 NULL | |
7431 | 1062 }; |