Mercurial > pidgin.yaz
annotate src/log.c @ 7612:3ae88e96dde2
[gaim-migrate @ 8236]
This is an attempt to both fix the directory creation permissions
and simplify the creation of nested directories from within gaim at the
same time. If you need nested directories, simply call gaim_build_dir
with the same arguments you would have given to mkdir and it will
recursively create the tree for you. I spent way too much time on
this.
committer: Tailor Script <tailor@pidgin.im>
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sun, 23 Nov 2003 18:41:11 +0000 |
parents | 54b370f7d9bf |
children | 62d11301b8a6 |
rev | line source |
---|---|
7431 | 1 /** |
2 * @file log.c Logging API | |
3 * @ingroup core | |
4 * | |
5 * gaim | |
6 * | |
7 * Copyright (C) 2003 Buzz Lightyear | |
7436 | 8 * |
7431 | 9 * This program is free software; you can redistribute it and/or modify |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
4184 | 22 */ |
4195 | 23 |
7431 | 24 #include "account.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
25 #include "debug.h" |
7431 | 26 #include "internal.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
27 #include "log.h" |
5548 | 28 #include "prefs.h" |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
29 #include "util.h" |
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
30 |
7457 | 31 static GaimLogLogger html_logger; |
7431 | 32 static GaimLogLogger txt_logger; |
33 static GaimLogLogger old_logger; | |
5872
059d95c67cda
[gaim-migrate @ 6304]
Christian Hammond <chipx86@chipx86.com>
parents:
5839
diff
changeset
|
34 |
7431 | 35 /************************************************************************** |
36 * PUBLIC LOGGING FUNCTIONS *********************************************** | |
37 **************************************************************************/ | |
4184 | 38 |
7431 | 39 GaimLog *gaim_log_new(GaimLogType type, const char *name, GaimAccount *account, time_t time) |
40 { | |
41 GaimLog *log = g_new0(GaimLog, 1); | |
42 log->name = g_strdup(name); | |
43 log->account = account; | |
44 log->time = time; | |
45 log->logger = gaim_log_logger_get(); | |
7440 | 46 if (log->logger && log->logger->create) |
47 log->logger->create(log); | |
7431 | 48 return log; |
4184 | 49 } |
50 | |
7431 | 51 void gaim_log_free(GaimLog *log) |
4184 | 52 { |
7431 | 53 g_return_if_fail(log); |
54 if (log->logger && log->logger->finalize) | |
55 log->logger->finalize(log); | |
56 g_free(log->name); | |
57 g_free(log); | |
58 } | |
7436 | 59 |
4184 | 60 |
7436 | 61 void gaim_log_write(GaimLog *log, GaimMessageFlags type, |
7431 | 62 const char *from, time_t time, const char *message) |
63 { | |
64 g_return_if_fail(log); | |
65 g_return_if_fail(log->logger); | |
7442 | 66 g_return_if_fail(log->logger->write); |
7431 | 67 |
7555 | 68 if ((log->type == GAIM_LOG_IM && gaim_prefs_get_bool("/core/logging/log_ims")) || |
69 (log->type == GAIM_LOG_CHAT && gaim_prefs_get_bool("/core/logging/log_chats"))) | |
7553 | 70 (log->logger->write)(log, type, from, time, message); |
4184 | 71 } |
72 | |
7431 | 73 char *gaim_log_read(GaimLog *log, GaimLogReadFlags *flags) |
4184 | 74 { |
7542 | 75 GaimLogReadFlags mflags; |
7431 | 76 g_return_val_if_fail(log && log->logger, NULL); |
7462 | 77 if (log->logger->read) { |
7535 | 78 char *ret = (log->logger->read)(log, flags ? flags : &mflags); |
7478
3c21f3084ff0
[gaim-migrate @ 8091]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
7473
diff
changeset
|
79 gaim_str_strip_cr(ret); |
7462 | 80 return ret; |
81 } | |
7470 | 82 return (_("<b><font color=\"red\">The logger has no read function</font></b>")); |
4184 | 83 } |
7556 | 84 |
85 int gaim_log_get_size(GaimLog *log) | |
86 { | |
87 g_return_val_if_fail(log && log->logger, 0); | |
88 if (log->logger->size) | |
89 return log->logger->size(log); | |
90 return 0; | |
91 } | |
92 | |
93 int gaim_log_get_total_size(const char *name, GaimAccount *account) | |
94 { | |
95 GList *logs = gaim_log_get_logs(name, account); | |
96 int size = 0; | |
97 | |
98 while (logs) { | |
99 GList *logs2 = logs->next; | |
100 GaimLog *log = (GaimLog*)(logs->data); | |
101 size += gaim_log_get_size(log); | |
102 g_free(log->name); | |
103 g_free(log); | |
104 g_list_free_1(logs); | |
105 logs = logs2; | |
106 } | |
107 return size; | |
108 } | |
4184 | 109 |
7431 | 110 /**************************************************************************** |
111 * LOGGER FUNCTIONS ********************************************************* | |
112 ****************************************************************************/ | |
4184 | 113 |
7431 | 114 static GaimLogLogger *current_logger = NULL; |
115 static GSList *loggers = NULL; | |
7436 | 116 |
7431 | 117 static void logger_pref_cb(const char *name, GaimPrefType type, |
118 gpointer value, gpointer data) | |
119 { | |
120 GaimLogLogger *logger; | |
121 GSList *l = loggers; | |
122 while (l) { | |
123 logger = l->data; | |
124 if (!strcmp(logger->id, value)) { | |
125 gaim_log_logger_set(logger); | |
126 return; | |
4184 | 127 } |
7431 | 128 l = l->next; |
129 } | |
130 gaim_log_logger_set(&txt_logger); | |
131 } | |
4184 | 132 |
133 | |
7440 | 134 GaimLogLogger *gaim_log_logger_new(void(*create)(GaimLog *), |
7436 | 135 void(*write)(GaimLog *, GaimMessageFlags, const char *, |
7431 | 136 time_t, const char *), |
137 void(*finalize)(GaimLog *), GList*(*list)(const char*, GaimAccount*), | |
7556 | 138 char*(*read)(GaimLog*, GaimLogReadFlags*), |
139 int(*size)(GaimLog*)) | |
7431 | 140 { |
141 GaimLogLogger *logger = g_new0(GaimLogLogger, 1); | |
7440 | 142 logger->create = create; |
7431 | 143 logger->write = write; |
144 logger->finalize = finalize; | |
145 logger->list = list; | |
146 logger->read = read; | |
7556 | 147 logger->size = size; |
7431 | 148 return logger; |
4184 | 149 } |
150 | |
7431 | 151 void gaim_log_logger_free(GaimLogLogger *logger) |
4184 | 152 { |
7431 | 153 g_free(logger); |
154 } | |
4184 | 155 |
7431 | 156 void gaim_log_logger_add (GaimLogLogger *logger) |
157 { | |
158 g_return_if_fail(logger); | |
159 if (g_slist_find(loggers, logger)) | |
160 return; | |
161 loggers = g_slist_append(loggers, logger); | |
162 } | |
163 | |
164 void gaim_log_logger_remove (GaimLogLogger *logger) | |
165 { | |
166 g_return_if_fail(logger); | |
167 g_slist_remove(loggers, logger); | |
4184 | 168 } |
169 | |
7431 | 170 void gaim_log_logger_set (GaimLogLogger *logger) |
4184 | 171 { |
7431 | 172 g_return_if_fail(logger); |
173 current_logger = logger; | |
7436 | 174 } |
4184 | 175 |
7431 | 176 GaimLogLogger *gaim_log_logger_get() |
177 { | |
178 return current_logger; | |
179 } | |
4184 | 180 |
7431 | 181 GList *gaim_log_logger_get_options(void) |
182 { | |
183 GSList *n; | |
184 GList *list = NULL; | |
185 GaimLogLogger *data; | |
4184 | 186 |
7431 | 187 for (n = loggers; n; n = n->next) { |
188 data = n->data; | |
189 if (!data->write) | |
190 continue; | |
7494 | 191 list = g_list_append(list, _(data->name)); |
7431 | 192 list = g_list_append(list, data->id); |
4184 | 193 } |
194 | |
7431 | 195 return list; |
196 } | |
197 | |
7436 | 198 static gint log_compare(gconstpointer y, gconstpointer z) |
7431 | 199 { |
7436 | 200 const GaimLog *a = y; |
201 const GaimLog *b = z; | |
202 | |
7431 | 203 return b->time - a->time; |
204 } | |
205 | |
206 GList *gaim_log_get_logs(const char *name, GaimAccount *account) | |
207 { | |
208 GList *logs = NULL; | |
209 GSList *n; | |
210 for (n = loggers; n; n = n->next) { | |
211 GaimLogLogger *logger = n->data; | |
212 if (!logger->list) | |
213 continue; | |
214 logs = g_list_concat(logs, logger->list(name, account)); | |
215 } | |
7436 | 216 |
7431 | 217 return g_list_sort(logs, log_compare); |
218 } | |
219 | |
220 void gaim_log_init(void) | |
7436 | 221 { |
7431 | 222 gaim_prefs_add_none("/core/logging"); |
7555 | 223 gaim_prefs_add_bool("/core/logging/log_ims", FALSE); |
224 gaim_prefs_add_bool("/core/logging/log_chats", FALSE); | |
7431 | 225 gaim_prefs_add_string("/core/logging/format", "txt"); |
7457 | 226 gaim_log_logger_add(&html_logger); |
7431 | 227 gaim_log_logger_add(&txt_logger); |
228 gaim_log_logger_add(&old_logger); | |
229 gaim_prefs_connect_callback("/core/logging/format", | |
230 logger_pref_cb, NULL); | |
231 gaim_prefs_trigger_callback("/core/logging/format"); | |
232 } | |
233 | |
234 /**************************************************************************** | |
235 * LOGGERS ****************************************************************** | |
236 ****************************************************************************/ | |
237 | |
238 static GList *log_lister_common(const char *screenname, GaimAccount *account, const char *ext, GaimLogLogger *logger) | |
239 { | |
240 GDir *dir; | |
241 GList *list = NULL; | |
7501 | 242 const char *filename, *tmp; |
7431 | 243 char *me = g_strdup(gaim_normalize(account, gaim_account_get_username(account))); |
4184 | 244 |
7431 | 245 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
246 (gaim_find_prpl(gaim_account_get_protocol(account)))->list_icon(account, NULL); | |
247 char *path = g_build_filename(gaim_user_dir(), "logs", prpl, me, gaim_normalize(account, screenname), NULL); | |
248 | |
7447 | 249 g_free(me); |
250 | |
7431 | 251 if (!(dir = g_dir_open(path, 0, NULL))) { |
252 g_free(path); | |
253 return NULL; | |
254 } | |
255 while ((filename = g_dir_read_name(dir))) { | |
7501 | 256 tmp = filename + (strlen(filename) - strlen(ext)); |
257 if (tmp > filename && !strcmp(tmp, ext)) { | |
7431 | 258 const char *l = filename; |
259 struct tm time; | |
260 GaimLog *log; | |
261 char d[5]; | |
7436 | 262 |
7431 | 263 strncpy(d, l, 4); |
264 d[4] = '\0'; | |
265 time.tm_year = atoi(d) - 1900; | |
266 l = l + 5; | |
267 | |
268 strncpy(d, l, 2); | |
269 d[2] = '\0'; | |
270 time.tm_mon = atoi(d) - 1; | |
271 l = l + 3; | |
272 | |
273 strncpy(d, l, 2); | |
274 time.tm_mday = atoi(d); | |
275 l = l + 3; | |
276 | |
277 strncpy(d, l, 2); | |
278 time.tm_hour = atoi(d); | |
279 l = l + 2; | |
7436 | 280 |
7431 | 281 strncpy(d, l, 2); |
282 time.tm_min = atoi(d); | |
283 l = l + 2; | |
284 | |
285 strncpy(d, l, 2); | |
286 time.tm_sec = atoi(d); | |
287 l = l + 2; | |
288 log = gaim_log_new(GAIM_LOG_IM, screenname, account, mktime(&time)); | |
289 log->logger = logger; | |
290 log->logger_data = g_build_filename(path, filename, NULL); | |
291 list = g_list_append(list, log); | |
4184 | 292 } |
293 } | |
7431 | 294 g_dir_close(dir); |
7447 | 295 g_free(path); |
7431 | 296 return list; |
297 } | |
4184 | 298 |
7556 | 299 /* Only to be used with logs listed from log_lister_common */ |
300 int log_sizer_common(GaimLog *log) | |
301 { | |
302 struct stat st; | |
303 | |
304 if (stat((char*)(log->logger_data), &st)) | |
305 st.st_size = 0; | |
306 | |
307 return st.st_size; | |
308 } | |
309 | |
7431 | 310 #if 0 /* Maybe some other time. */ |
7443 | 311 /**************** |
7431 | 312 ** XML LOGGER ** |
313 ****************/ | |
314 | |
315 static const char *str_from_msg_type (GaimMessageFlags type) | |
316 { | |
7443 | 317 |
7431 | 318 return ""; |
7443 | 319 |
7431 | 320 } |
321 | |
7443 | 322 static void xml_logger_write(GaimLog *log, |
323 GaimMessageFlags type, | |
7431 | 324 const char *from, time_t time, const char *message) |
325 { | |
326 char date[64]; | |
327 char *xhtml = NULL; | |
328 if (!log->logger_data) { | |
329 /* This log is new. We could use the loggers 'new' function, but | |
330 * creating a new file there would result in empty files in the case | |
331 * that you open a convo with someone, but don't say anything. | |
332 */ | |
333 char *ud = gaim_user_dir(); | |
334 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
335 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
336 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
337 char *dir; | |
338 FILE *file; | |
339 | |
7453 | 340 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.xml", localtime(&log->time)); |
7443 | 341 |
342 dir = g_build_filename(ud, "logs", | |
7431 | 343 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
7612 | 344 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
7447 | 345 g_free(guy); |
7443 | 346 |
7431 | 347 char *filename = g_build_filename(dir, date, NULL); |
348 g_free(dir); | |
7443 | 349 |
7431 | 350 log->logger_data = fopen(filename, "a"); |
351 if (!log->logger_data) { | |
352 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
7564 | 353 g_free(filename); |
7431 | 354 return; |
355 } | |
7564 | 356 g_free(filename); |
7431 | 357 fprintf(log->logger_data, "<?xml version='1.0' encoding='UTF-8' ?>\n" |
358 "<?xml-stylesheet href='file:///usr/src/web/htdocs/log-stylesheet.xsl' type='text/xml' ?>\n"); | |
7443 | 359 |
7453 | 360 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
7431 | 361 fprintf(log->logger_data, "<conversation time='%s' screenname='%s' protocol='%s'>\n", |
362 date, log->name, prpl); | |
363 } | |
7443 | 364 |
7453 | 365 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); |
7431 | 366 gaim_markup_html_to_xhtml(message, &xhtml, NULL); |
367 if (from) | |
7443 | 368 fprintf(log->logger_data, "<message %s %s from='%s' time='%s'>%s</message>\n", |
369 str_from_msg_type(type), | |
7431 | 370 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
371 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
372 from, date, xhtml); | |
373 else | |
7443 | 374 fprintf(log->logger_data, "<message %s %s time='%s'>%s</message>\n", |
375 str_from_msg_type(type), | |
7431 | 376 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
377 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
7443 | 378 date, xhtml): |
7431 | 379 fflush(log->logger_data); |
380 g_free(xhtml); | |
7443 | 381 } |
382 | |
7431 | 383 static void xml_logger_finalize(GaimLog *log) |
384 { | |
385 if (log->logger_data) { | |
386 fprintf(log->logger_data, "</conversation>\n"); | |
387 fclose(log->logger_data); | |
388 log->logger_data = NULL; | |
389 } | |
390 } | |
7443 | 391 |
7431 | 392 static GList *xml_logger_list(const char *sn, GaimAccount *account) |
393 { | |
394 return log_lister_common(sn, account, ".xml", &xml_logger); | |
4184 | 395 } |
396 | |
7431 | 397 static GaimLogLogger xml_logger = { |
398 N_("XML"), "xml", | |
399 NULL, | |
400 xml_logger_write, | |
401 xml_logger_finalize, | |
402 xml_logger_list, | |
403 NULL | |
404 }; | |
405 #endif | |
5563
9eb5b13fd412
[gaim-migrate @ 5965]
Christian Hammond <chipx86@chipx86.com>
parents:
5560
diff
changeset
|
406 |
7431 | 407 /**************************** |
7457 | 408 ** HTML LOGGER ************* |
409 ****************************/ | |
410 | |
411 static void html_logger_write(GaimLog *log, GaimMessageFlags type, | |
412 const char *from, time_t time, const char *message) | |
413 { | |
7489 | 414 GaimConnection *gc = gaim_account_get_connection(log->account); |
7457 | 415 char date[64]; |
416 if(!log->logger_data) { | |
417 /* This log is new */ | |
418 char *ud = gaim_user_dir(); | |
419 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
7553 | 420 char *chat; |
7457 | 421 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
422 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
423 char *dir; | |
424 char *filename; | |
425 | |
7553 | 426 if (log->type == GAIM_LOG_CHAT) { |
427 chat = g_strdup_printf("%s.chat", guy); | |
428 g_free(guy); | |
429 guy = chat; | |
430 } | |
431 | |
7457 | 432 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.html", localtime(&log->time)); |
433 | |
434 dir = g_build_filename(ud, "logs", | |
435 prpl, guy, gaim_normalize(log->account, log->name), NULL); | |
7612 | 436 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
7457 | 437 g_free(guy); |
438 | |
439 filename = g_build_filename(dir, date, NULL); | |
440 g_free(dir); | |
441 | |
442 log->logger_data = fopen(filename, "a"); | |
443 if (!log->logger_data) { | |
444 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
7564 | 445 g_free(filename); |
7457 | 446 return; |
447 } | |
448 g_free(filename); | |
449 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); | |
450 fprintf(log->logger_data, "<html><head><title>"); | |
451 fprintf(log->logger_data, "Conversation with %s at %s on %s (%s)", | |
452 log->name, date, gaim_account_get_username(log->account), prpl); | |
453 fprintf(log->logger_data, "</title></head><body>"); | |
454 fprintf(log->logger_data, | |
455 "<h3>Conversation with %s at %s on %s (%s)</h3>\n", | |
456 log->name, date, gaim_account_get_username(log->account), prpl); | |
457 } | |
458 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); | |
7489 | 459 if (type & GAIM_MESSAGE_SYSTEM) |
460 fprintf(log->logger_data, "(%s)<b> %s</b><br/>\n", date, message); | |
461 else if (type & GAIM_MESSAGE_WHISPER) | |
462 fprintf(log->logger_data, "<font color=\"#6C2585\">(%s)<b> %s:</b></font> %s<br/>\n", | |
463 date, from, message); | |
464 else if (type & GAIM_MESSAGE_AUTO_RESP) { | |
465 if (type & GAIM_MESSAGE_SEND) | |
7540 | 466 fprintf(log->logger_data, _("<font color=\"#16569E\">(%s) <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, from, message); |
7489 | 467 else if (type & GAIM_MESSAGE_RECV) |
7540 | 468 fprintf(log->logger_data, _("<font color=\"#A82F2F\">(%s) <b>%s <AUTO-REPLY>:</b></font> %s<br/>\n"), date, from, message); |
7564 | 469 } else if (type & GAIM_MESSAGE_RECV) { |
470 char *msg = g_strdup(message); | |
471 if(gaim_message_meify(msg, -1)) | |
472 fprintf(log->logger_data, "<font color=\"#6C2585\">(%s) <b>***%s</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
473 date, from, gc->prpl->info->name, msg); | |
474 else | |
475 fprintf(log->logger_data, "<font color=\"#A82F2F\">(%s) <b>%s:</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
476 date, from, gc->prpl->info->name, msg); | |
477 g_free(msg); | |
478 } else if (type & GAIM_MESSAGE_SEND) { | |
479 char *msg = g_strdup(message); | |
480 if(gaim_message_meify(msg, -1)) | |
481 fprintf(log->logger_data, "<font color=\"#6C2585\">(%s) <b>***%s</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
482 date, from, gc->prpl->info->name, msg); | |
483 else | |
484 fprintf(log->logger_data, "<font color=\"#16569E\">(%s) <b>%s:</b></font> <font sml=\"%s\">%s</font><br/>\n", | |
485 date, from, gc->prpl->info->name, msg); | |
486 g_free(msg); | |
487 } | |
7457 | 488 fflush(log->logger_data); |
489 } | |
490 | |
491 static void html_logger_finalize(GaimLog *log) | |
492 { | |
7463 | 493 if (log->logger_data) { |
494 fprintf(log->logger_data, "</body></html>"); | |
7457 | 495 fclose(log->logger_data); |
7463 | 496 } |
7457 | 497 } |
498 | |
499 static GList *html_logger_list(const char *sn, GaimAccount *account) | |
500 { | |
501 return log_lister_common(sn, account, ".html", &html_logger); | |
502 } | |
503 | |
504 static char *html_logger_read(GaimLog *log, GaimLogReadFlags *flags) | |
505 { | |
506 char *read, *minus_header; | |
507 *flags = GAIM_LOG_READ_NO_NEWLINE; | |
508 if (!log->logger_data) | |
7472 | 509 return g_strdup(_("<font color=\"red\"><b>log->logger_data was NULL!</b></font>")); |
7457 | 510 if (g_file_get_contents((char *)log->logger_data, &read, NULL, NULL)) { |
511 minus_header = strchr(read, '\n'); | |
512 if (!minus_header) | |
513 minus_header = g_strdup(read); | |
514 else | |
515 minus_header = g_strdup(minus_header + 1); | |
516 g_free(read); | |
517 return minus_header; | |
518 } | |
7471 | 519 return g_strdup(_("<font color=\"red\"><b>Could not read file: %s</b></font>")); |
7457 | 520 } |
521 | |
522 static GaimLogLogger html_logger = { | |
523 N_("HTML"), "html", | |
524 NULL, | |
525 html_logger_write, | |
526 html_logger_finalize, | |
527 html_logger_list, | |
7556 | 528 html_logger_read, |
529 log_sizer_common | |
7457 | 530 }; |
531 | |
532 | |
533 | |
534 | |
535 /**************************** | |
7431 | 536 ** PLAIN TEXT LOGGER ******* |
537 ****************************/ | |
4184 | 538 |
7436 | 539 static void txt_logger_write(GaimLog *log, |
540 GaimMessageFlags type, | |
7431 | 541 const char *from, time_t time, const char *message) |
542 { | |
543 char date[64]; | |
544 char *stripped = NULL; | |
545 if (!log->logger_data) { | |
546 /* This log is new. We could use the loggers 'new' function, but | |
547 * creating a new file there would result in empty files in the case | |
548 * that you open a convo with someone, but don't say anything. | |
549 */ | |
550 char *ud = gaim_user_dir(); | |
7473 | 551 char *filename; |
7431 | 552 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); |
7553 | 553 char *chat; |
7431 | 554 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
555 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
556 char *dir; | |
7436 | 557 |
7553 | 558 if (log->type == GAIM_LOG_CHAT) { |
559 chat = g_strdup_printf("%s.chat", guy); | |
560 g_free(guy); | |
561 guy = chat; | |
562 } | |
7453 | 563 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.txt", localtime(&log->time)); |
7436 | 564 |
565 dir = g_build_filename(ud, "logs", | |
7431 | 566 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
7612 | 567 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); |
7447 | 568 g_free(guy); |
7436 | 569 |
7473 | 570 filename = g_build_filename(dir, date, NULL); |
7431 | 571 g_free(dir); |
7436 | 572 |
7431 | 573 log->logger_data = fopen(filename, "a"); |
574 if (!log->logger_data) { | |
575 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
7564 | 576 g_free(filename); |
7431 | 577 return; |
4184 | 578 } |
7447 | 579 g_free(filename); |
7453 | 580 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
7431 | 581 fprintf(log->logger_data, "Conversation with %s at %s on %s (%s)\n", |
582 log->name, date, gaim_account_get_username(log->account), prpl); | |
583 } | |
7436 | 584 |
7453 | 585 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); |
7431 | 586 stripped = gaim_markup_strip_html(message); |
7489 | 587 if (type & GAIM_MESSAGE_SEND || |
7541 | 588 type & GAIM_MESSAGE_RECV) { |
7564 | 589 if (type & GAIM_MESSAGE_AUTO_RESP) { |
7541 | 590 fprintf(log->logger_data, _("(%s) %s <AUTO-REPLY>: %s\n"), date, from, stripped); |
7564 | 591 } else { |
592 if(gaim_message_meify(stripped, -1)) | |
593 fprintf(log->logger_data, "(%s) ***%s %s\n", date, from, | |
594 stripped); | |
595 else | |
596 fprintf(log->logger_data, "(%s) %s: %s\n", date, from, | |
597 stripped); | |
598 } | |
599 } else if (type & GAIM_MESSAGE_SYSTEM) | |
7489 | 600 fprintf(log->logger_data, "(%s) %s\n", date, stripped); |
601 else if (type & GAIM_MESSAGE_NO_LOG) { | |
602 /* This shouldn't happen */ | |
603 g_free(stripped); | |
604 return; | |
605 } else if (type & GAIM_MESSAGE_WHISPER) | |
606 fprintf(log->logger_data, "(%s) *%s* %s", date, from, stripped); | |
607 else | |
608 fprintf(log->logger_data, "(%s) %s%s %s\n", date, from ? from : "", from ? ":" : "", stripped); | |
609 | |
7431 | 610 fflush(log->logger_data); |
611 g_free(stripped); | |
612 } | |
613 | |
614 static void txt_logger_finalize(GaimLog *log) | |
615 { | |
616 if (log->logger_data) | |
617 fclose(log->logger_data); | |
618 } | |
619 | |
620 static GList *txt_logger_list(const char *sn, GaimAccount *account) | |
621 { | |
622 return log_lister_common(sn, account, ".txt", &txt_logger); | |
623 } | |
624 | |
625 static char *txt_logger_read(GaimLog *log, GaimLogReadFlags *flags) | |
626 { | |
627 char *read, *minus_header; | |
7457 | 628 *flags = 0; |
7431 | 629 if (!log->logger_data) |
7472 | 630 return g_strdup(_("<font color=\"red\"><b>log->logger_data was NULL!</b></font>")); |
7431 | 631 if (g_file_get_contents((char *)log->logger_data, &read, NULL, NULL)) { |
632 minus_header = strchr(read, '\n'); | |
633 if (!minus_header) | |
634 minus_header = g_strdup(read); | |
7436 | 635 else |
7431 | 636 minus_header = g_strdup(minus_header + 1); |
637 g_free(read); | |
638 return minus_header; | |
639 } | |
7471 | 640 return g_strdup(_("<font color=\"red\"><b>Could not read file: %s</b></font>")); |
7436 | 641 } |
7431 | 642 |
643 static GaimLogLogger txt_logger = { | |
644 N_("Plain text"), "txt", | |
645 NULL, | |
646 txt_logger_write, | |
647 txt_logger_finalize, | |
648 txt_logger_list, | |
7556 | 649 txt_logger_read, |
650 log_sizer_common | |
7431 | 651 }; |
652 | |
653 /**************** | |
654 * OLD LOGGER *** | |
655 ****************/ | |
656 | |
657 /* The old logger doesn't write logs, only reads them. This is to include | |
658 * old logs in the log viewer transparently. | |
659 */ | |
660 | |
661 struct old_logger_data { | |
662 char *path; | |
663 int offset; | |
664 int length; | |
665 }; | |
666 | |
7436 | 667 static GList *old_logger_list(const char *sn, GaimAccount *account) |
7431 | 668 { |
669 FILE *file; | |
670 char buf[BUF_LONG]; | |
671 struct tm tm; | |
672 struct old_logger_data *data = NULL; | |
673 char day[4], month[4], year[5]; | |
674 char *logfile = g_strdup_printf("%s.log", gaim_normalize(account, sn)); | |
675 char *date; | |
676 char *path = g_build_filename(gaim_user_dir(), "logs", logfile, NULL); | |
677 char *newlog; | |
678 | |
679 GaimLog *log = NULL; | |
680 GList *list = NULL; | |
681 | |
7473 | 682 g_free(logfile); |
683 | |
7461 | 684 if (!(file = fopen(path, "rb"))) { |
7447 | 685 g_free(path); |
7431 | 686 return NULL; |
7447 | 687 } |
7436 | 688 |
7431 | 689 while (fgets(buf, BUF_LONG, file)) { |
690 if ((newlog = strstr(buf, "---- New C"))) { | |
691 int length; | |
692 int offset; | |
693 GDate gdate; | |
694 char convostart[32]; | |
695 char *temp = strchr(buf, '@'); | |
7436 | 696 |
7431 | 697 if (temp == NULL || strlen(temp) < 2) |
698 continue; | |
7436 | 699 |
7431 | 700 temp++; |
701 length = strcspn(temp, "-"); | |
702 if (length > 31) length = 31; | |
7436 | 703 |
7431 | 704 offset = ftell(file); |
7436 | 705 |
7431 | 706 if (data) { |
7436 | 707 data->length = offset - data->offset - length; |
708 if(strstr(buf, "----</H3><BR>")) { | |
709 data->length -= | |
710 strlen("<HR><BR><H3 Align=Center> ---- New Conversation @ ") + | |
711 strlen("----</H3><BR>"); | |
712 } else { | |
713 data->length -= | |
714 strlen("---- New Conversation @ ") + strlen("----"); | |
715 } | |
716 | |
7461 | 717 if(strchr(buf, '\r')) |
718 data->length--; | |
719 | |
7431 | 720 if (data->length != 0) |
721 list = g_list_append(list, log); | |
722 else | |
723 gaim_log_free(log); | |
724 } | |
725 | |
726 log = gaim_log_new(GAIM_LOG_IM, sn, account, -1); | |
727 log->logger = &old_logger; | |
728 | |
7436 | 729 data = g_new0(struct old_logger_data, 1); |
7431 | 730 data->offset = offset; |
731 data->path = path; | |
732 log->logger_data = data; | |
733 | |
7436 | 734 |
7431 | 735 g_snprintf(convostart, length, "%s", temp); |
736 sscanf(convostart, "%*s %s %s %d:%d:%d %s", | |
737 month, day, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, year); | |
738 date = g_strdup_printf("%s %s %s", month, day, year); | |
739 g_date_set_parse(&gdate, date); | |
740 tm.tm_mday = g_date_get_day(&gdate); | |
741 tm.tm_mon = g_date_get_month(&gdate) - 1; | |
742 tm.tm_year = g_date_get_year(&gdate) - 1900; | |
743 log->time = mktime(&tm); | |
744 | |
4184 | 745 } |
746 } | |
7431 | 747 fclose(file); |
748 return list; | |
4184 | 749 } |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
750 |
7431 | 751 char * old_logger_read (GaimLog *log, GaimLogReadFlags *flags) |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
752 { |
7431 | 753 struct old_logger_data *data = log->logger_data; |
7461 | 754 FILE *file = fopen(data->path, "rb"); |
7431 | 755 char *read = g_malloc(data->length + 1); |
756 fseek(file, data->offset, SEEK_SET); | |
757 fread(read, data->length, 1, file); | |
758 read[data->length] = '\0'; | |
7436 | 759 *flags = 0; |
760 if(strstr(read, "<BR>")) | |
761 *flags |= GAIM_LOG_READ_NO_NEWLINE; | |
7431 | 762 return read; |
763 } | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
764 |
7556 | 765 int old_logger_size (GaimLog *log) |
766 { | |
767 struct old_logger_data *data = log->logger_data; | |
768 return data->length; | |
769 } | |
770 | |
7431 | 771 static GaimLogLogger old_logger = { |
772 "old logger", "old", | |
773 NULL, NULL, NULL, | |
774 old_logger_list, | |
775 old_logger_read | |
776 }; |