Mercurial > pidgin.yaz
annotate src/log.c @ 7469:603a58cd23dc
[gaim-migrate @ 8082]
This should fix the problem where some MSN users in the buddy list were
showing the offline emblem, indicating that gaim and the server disagree as
to whether or not the buddy should be there. That icon was for testing
purposes, and should never have been seen by a user. The problem was that
in the code, we were looking for a list of all buddies, and would add new
ones if not found. The problem was that we'd get duplicates, as some would
be in foo@bar.com form, and some in FOO@bar.com form, or mixed-case, or
whatever. Now, our msn_normalize() converts a string to lowercase first.
We'll see how well this works, but it fixed the problem here.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Mon, 10 Nov 2003 22:13:18 +0000 |
parents | f2d82df37252 |
children | ad6435eccf2b |
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 |
7442 | 68 (log->logger->write)(log, type, from, time, message); |
4184 | 69 } |
70 | |
7431 | 71 char *gaim_log_read(GaimLog *log, GaimLogReadFlags *flags) |
4184 | 72 { |
7431 | 73 g_return_val_if_fail(log && log->logger, NULL); |
7462 | 74 if (log->logger->read) { |
75 char *ret = (log->logger->read)(log, flags); | |
76 gaim_str_strip_linefeed(ret); | |
77 return ret; | |
78 } | |
7431 | 79 return (_("<b><font color\"=red\">The logger has no read function</font></b>")); |
4184 | 80 } |
81 | |
7431 | 82 /**************************************************************************** |
83 * LOGGER FUNCTIONS ********************************************************* | |
84 ****************************************************************************/ | |
4184 | 85 |
7431 | 86 static GaimLogLogger *current_logger = NULL; |
87 static GSList *loggers = NULL; | |
7436 | 88 |
7431 | 89 static void logger_pref_cb(const char *name, GaimPrefType type, |
90 gpointer value, gpointer data) | |
91 { | |
92 GaimLogLogger *logger; | |
93 GSList *l = loggers; | |
94 while (l) { | |
95 logger = l->data; | |
96 if (!strcmp(logger->id, value)) { | |
97 gaim_log_logger_set(logger); | |
98 return; | |
4184 | 99 } |
7431 | 100 l = l->next; |
101 } | |
102 gaim_log_logger_set(&txt_logger); | |
103 } | |
4184 | 104 |
105 | |
7440 | 106 GaimLogLogger *gaim_log_logger_new(void(*create)(GaimLog *), |
7436 | 107 void(*write)(GaimLog *, GaimMessageFlags, const char *, |
7431 | 108 time_t, const char *), |
109 void(*finalize)(GaimLog *), GList*(*list)(const char*, GaimAccount*), | |
110 char*(*read)(GaimLog*, GaimLogReadFlags*)) | |
111 { | |
112 GaimLogLogger *logger = g_new0(GaimLogLogger, 1); | |
7440 | 113 logger->create = create; |
7431 | 114 logger->write = write; |
115 logger->finalize = finalize; | |
116 logger->list = list; | |
117 logger->read = read; | |
118 return logger; | |
4184 | 119 } |
120 | |
7431 | 121 void gaim_log_logger_free(GaimLogLogger *logger) |
4184 | 122 { |
7431 | 123 g_free(logger); |
124 } | |
4184 | 125 |
7431 | 126 void gaim_log_logger_add (GaimLogLogger *logger) |
127 { | |
128 g_return_if_fail(logger); | |
129 if (g_slist_find(loggers, logger)) | |
130 return; | |
131 loggers = g_slist_append(loggers, logger); | |
132 } | |
133 | |
134 void gaim_log_logger_remove (GaimLogLogger *logger) | |
135 { | |
136 g_return_if_fail(logger); | |
137 g_slist_remove(loggers, logger); | |
4184 | 138 } |
139 | |
7431 | 140 void gaim_log_logger_set (GaimLogLogger *logger) |
4184 | 141 { |
7431 | 142 g_return_if_fail(logger); |
143 current_logger = logger; | |
7436 | 144 } |
4184 | 145 |
7431 | 146 GaimLogLogger *gaim_log_logger_get() |
147 { | |
148 return current_logger; | |
149 } | |
4184 | 150 |
7431 | 151 GList *gaim_log_logger_get_options(void) |
152 { | |
153 GSList *n; | |
154 GList *list = NULL; | |
155 GaimLogLogger *data; | |
4184 | 156 |
7431 | 157 for (n = loggers; n; n = n->next) { |
158 data = n->data; | |
159 if (!data->write) | |
160 continue; | |
161 list = g_list_append(list, data->name); | |
162 list = g_list_append(list, data->id); | |
4184 | 163 } |
164 | |
7431 | 165 return list; |
166 } | |
167 | |
7436 | 168 static gint log_compare(gconstpointer y, gconstpointer z) |
7431 | 169 { |
7436 | 170 const GaimLog *a = y; |
171 const GaimLog *b = z; | |
172 | |
7431 | 173 return b->time - a->time; |
174 } | |
175 | |
176 GList *gaim_log_get_logs(const char *name, GaimAccount *account) | |
177 { | |
178 GList *logs = NULL; | |
179 GSList *n; | |
180 for (n = loggers; n; n = n->next) { | |
181 GaimLogLogger *logger = n->data; | |
182 if (!logger->list) | |
183 continue; | |
184 logs = g_list_concat(logs, logger->list(name, account)); | |
185 } | |
7436 | 186 |
7431 | 187 return g_list_sort(logs, log_compare); |
188 } | |
189 | |
190 void gaim_log_init(void) | |
7436 | 191 { |
7431 | 192 gaim_prefs_add_none("/core/logging"); |
193 gaim_prefs_add_string("/core/logging/format", "txt"); | |
7457 | 194 gaim_log_logger_add(&html_logger); |
7431 | 195 gaim_log_logger_add(&txt_logger); |
196 gaim_log_logger_add(&old_logger); | |
197 gaim_prefs_connect_callback("/core/logging/format", | |
198 logger_pref_cb, NULL); | |
199 gaim_prefs_trigger_callback("/core/logging/format"); | |
200 } | |
201 | |
202 /**************************************************************************** | |
203 * LOGGERS ****************************************************************** | |
204 ****************************************************************************/ | |
205 | |
206 static GList *log_lister_common(const char *screenname, GaimAccount *account, const char *ext, GaimLogLogger *logger) | |
207 { | |
208 GDir *dir; | |
209 GList *list = NULL; | |
210 const char *filename; | |
211 char *me = g_strdup(gaim_normalize(account, gaim_account_get_username(account))); | |
4184 | 212 |
7431 | 213 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO |
214 (gaim_find_prpl(gaim_account_get_protocol(account)))->list_icon(account, NULL); | |
215 char *path = g_build_filename(gaim_user_dir(), "logs", prpl, me, gaim_normalize(account, screenname), NULL); | |
216 | |
7447 | 217 g_free(me); |
218 | |
7431 | 219 if (!(dir = g_dir_open(path, 0, NULL))) { |
220 g_free(path); | |
221 return NULL; | |
222 } | |
223 while ((filename = g_dir_read_name(dir))) { | |
224 if (g_str_has_suffix(filename, ext)) { | |
225 const char *l = filename; | |
226 struct tm time; | |
227 GaimLog *log; | |
228 char d[5]; | |
7436 | 229 |
7431 | 230 strncpy(d, l, 4); |
231 d[4] = '\0'; | |
232 time.tm_year = atoi(d) - 1900; | |
233 l = l + 5; | |
234 | |
235 strncpy(d, l, 2); | |
236 d[2] = '\0'; | |
237 time.tm_mon = atoi(d) - 1; | |
238 l = l + 3; | |
239 | |
240 strncpy(d, l, 2); | |
241 time.tm_mday = atoi(d); | |
242 l = l + 3; | |
243 | |
244 strncpy(d, l, 2); | |
245 time.tm_hour = atoi(d); | |
246 l = l + 2; | |
7436 | 247 |
7431 | 248 strncpy(d, l, 2); |
249 time.tm_min = atoi(d); | |
250 l = l + 2; | |
251 | |
252 strncpy(d, l, 2); | |
253 time.tm_sec = atoi(d); | |
254 l = l + 2; | |
255 log = gaim_log_new(GAIM_LOG_IM, screenname, account, mktime(&time)); | |
256 log->logger = logger; | |
257 log->logger_data = g_build_filename(path, filename, NULL); | |
258 list = g_list_append(list, log); | |
4184 | 259 } |
260 } | |
7431 | 261 g_dir_close(dir); |
7447 | 262 g_free(path); |
7431 | 263 return list; |
264 } | |
4184 | 265 |
7431 | 266 #if 0 /* Maybe some other time. */ |
7443 | 267 /**************** |
7431 | 268 ** XML LOGGER ** |
269 ****************/ | |
270 | |
271 static const char *str_from_msg_type (GaimMessageFlags type) | |
272 { | |
7443 | 273 |
7431 | 274 return ""; |
7443 | 275 |
7431 | 276 } |
277 | |
7443 | 278 static void xml_logger_write(GaimLog *log, |
279 GaimMessageFlags type, | |
7431 | 280 const char *from, time_t time, const char *message) |
281 { | |
282 char date[64]; | |
283 char *xhtml = NULL; | |
284 if (!log->logger_data) { | |
285 /* This log is new. We could use the loggers 'new' function, but | |
286 * creating a new file there would result in empty files in the case | |
287 * that you open a convo with someone, but don't say anything. | |
288 */ | |
289 char *ud = gaim_user_dir(); | |
290 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
291 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
292 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
293 char *dir; | |
294 FILE *file; | |
295 | |
7453 | 296 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.xml", localtime(&log->time)); |
7443 | 297 |
7431 | 298 dir = g_build_filename(ud, "logs", NULL); |
299 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
300 g_free(dir); | |
7443 | 301 dir = g_build_filename(ud, "logs", |
7431 | 302 prpl, NULL); |
303 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
304 g_free(dir); | |
7443 | 305 dir = g_build_filename(ud, "logs", |
7431 | 306 prpl, guy, NULL); |
307 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
7443 | 308 g_free(dir); |
309 dir = g_build_filename(ud, "logs", | |
7431 | 310 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
311 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
7447 | 312 g_free(guy); |
7443 | 313 |
7431 | 314 char *filename = g_build_filename(dir, date, NULL); |
315 g_free(dir); | |
7443 | 316 |
7431 | 317 file = fopen(dir, "r"); |
318 if(!file) | |
319 mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
320 else | |
321 fclose(file); | |
7443 | 322 |
7431 | 323 log->logger_data = fopen(filename, "a"); |
324 if (!log->logger_data) { | |
325 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
326 return; | |
327 } | |
328 fprintf(log->logger_data, "<?xml version='1.0' encoding='UTF-8' ?>\n" | |
329 "<?xml-stylesheet href='file:///usr/src/web/htdocs/log-stylesheet.xsl' type='text/xml' ?>\n"); | |
7443 | 330 |
7453 | 331 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
7431 | 332 fprintf(log->logger_data, "<conversation time='%s' screenname='%s' protocol='%s'>\n", |
333 date, log->name, prpl); | |
334 } | |
7443 | 335 |
7453 | 336 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); |
7431 | 337 gaim_markup_html_to_xhtml(message, &xhtml, NULL); |
338 if (from) | |
7443 | 339 fprintf(log->logger_data, "<message %s %s from='%s' time='%s'>%s</message>\n", |
340 str_from_msg_type(type), | |
7431 | 341 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
342 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
343 from, date, xhtml); | |
344 else | |
7443 | 345 fprintf(log->logger_data, "<message %s %s time='%s'>%s</message>\n", |
346 str_from_msg_type(type), | |
7431 | 347 type & GAIM_MESSAGE_SEND ? "direction='sent'" : |
348 type & GAIM_MESSAGE_RECV ? "direction='received'" : "", | |
7443 | 349 date, xhtml): |
7431 | 350 fflush(log->logger_data); |
351 g_free(xhtml); | |
7443 | 352 } |
353 | |
7431 | 354 static void xml_logger_finalize(GaimLog *log) |
355 { | |
356 if (log->logger_data) { | |
357 fprintf(log->logger_data, "</conversation>\n"); | |
358 fclose(log->logger_data); | |
359 log->logger_data = NULL; | |
360 } | |
361 } | |
7443 | 362 |
7431 | 363 static GList *xml_logger_list(const char *sn, GaimAccount *account) |
364 { | |
365 return log_lister_common(sn, account, ".xml", &xml_logger); | |
4184 | 366 } |
367 | |
7431 | 368 static GaimLogLogger xml_logger = { |
369 N_("XML"), "xml", | |
370 NULL, | |
371 xml_logger_write, | |
372 xml_logger_finalize, | |
373 xml_logger_list, | |
374 NULL | |
375 }; | |
376 #endif | |
5563
9eb5b13fd412
[gaim-migrate @ 5965]
Christian Hammond <chipx86@chipx86.com>
parents:
5560
diff
changeset
|
377 |
7431 | 378 /**************************** |
7457 | 379 ** HTML LOGGER ************* |
380 ****************************/ | |
381 | |
382 static void html_logger_write(GaimLog *log, GaimMessageFlags type, | |
383 const char *from, time_t time, const char *message) | |
384 { | |
385 char date[64]; | |
386 if(!log->logger_data) { | |
387 /* This log is new */ | |
388 char *ud = gaim_user_dir(); | |
389 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
390 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
391 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
392 char *dir; | |
393 char *filename; | |
394 FILE *file; | |
395 | |
396 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.html", localtime(&log->time)); | |
397 | |
398 dir = g_build_filename(ud, "logs", NULL); | |
399 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
400 g_free(dir); | |
401 dir = g_build_filename(ud, "logs", | |
402 prpl, NULL); | |
403 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
404 g_free(dir); | |
405 dir = g_build_filename(ud, "logs", | |
406 prpl, guy, NULL); | |
407 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
408 g_free(dir); | |
409 dir = g_build_filename(ud, "logs", | |
410 prpl, guy, gaim_normalize(log->account, log->name), NULL); | |
411 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
412 g_free(guy); | |
413 | |
414 filename = g_build_filename(dir, date, NULL); | |
415 g_free(dir); | |
416 | |
417 file = fopen(dir, "r"); | |
418 if(!file) | |
419 mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
420 else | |
421 fclose(file); | |
422 | |
423 log->logger_data = fopen(filename, "a"); | |
424 if (!log->logger_data) { | |
425 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
426 return; | |
427 } | |
428 g_free(filename); | |
429 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); | |
430 fprintf(log->logger_data, "<html><head><title>"); | |
431 fprintf(log->logger_data, "Conversation with %s at %s on %s (%s)", | |
432 log->name, date, gaim_account_get_username(log->account), prpl); | |
433 fprintf(log->logger_data, "</title></head><body>"); | |
434 fprintf(log->logger_data, | |
435 "<h3>Conversation with %s at %s on %s (%s)</h3>\n", | |
436 log->name, date, gaim_account_get_username(log->account), prpl); | |
437 } | |
438 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); | |
439 fprintf(log->logger_data, "(%s) %s%s %s<br/>\n", date, from ? from : "", from ? ":" : "", message); | |
440 fflush(log->logger_data); | |
441 } | |
442 | |
443 static void html_logger_finalize(GaimLog *log) | |
444 { | |
7463 | 445 if (log->logger_data) { |
446 fprintf(log->logger_data, "</body></html>"); | |
7457 | 447 fclose(log->logger_data); |
7463 | 448 } |
7457 | 449 } |
450 | |
451 static GList *html_logger_list(const char *sn, GaimAccount *account) | |
452 { | |
453 return log_lister_common(sn, account, ".html", &html_logger); | |
454 } | |
455 | |
456 static char *html_logger_read(GaimLog *log, GaimLogReadFlags *flags) | |
457 { | |
458 char *read, *minus_header; | |
459 *flags = GAIM_LOG_READ_NO_NEWLINE; | |
460 if (!log->logger_data) | |
461 return g_strdup("<font color='red'><b>log->logger_data was NULL!</b></font>"); | |
462 if (g_file_get_contents((char *)log->logger_data, &read, NULL, NULL)) { | |
463 minus_header = strchr(read, '\n'); | |
464 if (!minus_header) | |
465 minus_header = g_strdup(read); | |
466 else | |
467 minus_header = g_strdup(minus_header + 1); | |
468 g_free(read); | |
469 return minus_header; | |
470 } | |
471 return g_strdup(_("<font color='red'><b>Could not read file: %s</b></font>")); | |
472 } | |
473 | |
474 static GaimLogLogger html_logger = { | |
475 N_("HTML"), "html", | |
476 NULL, | |
477 html_logger_write, | |
478 html_logger_finalize, | |
479 html_logger_list, | |
480 html_logger_read | |
481 }; | |
482 | |
483 | |
484 | |
485 | |
486 /**************************** | |
7431 | 487 ** PLAIN TEXT LOGGER ******* |
488 ****************************/ | |
4184 | 489 |
7436 | 490 static void txt_logger_write(GaimLog *log, |
491 GaimMessageFlags type, | |
7431 | 492 const char *from, time_t time, const char *message) |
493 { | |
494 char date[64]; | |
495 char *stripped = NULL; | |
496 if (!log->logger_data) { | |
497 /* This log is new. We could use the loggers 'new' function, but | |
498 * creating a new file there would result in empty files in the case | |
499 * that you open a convo with someone, but don't say anything. | |
500 */ | |
501 char *ud = gaim_user_dir(); | |
502 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account))); | |
503 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO | |
504 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL); | |
505 char *dir; | |
506 FILE *file; | |
7436 | 507 |
7453 | 508 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.txt", localtime(&log->time)); |
7436 | 509 |
7431 | 510 dir = g_build_filename(ud, "logs", NULL); |
511 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
512 g_free(dir); | |
7436 | 513 dir = g_build_filename(ud, "logs", |
7431 | 514 prpl, NULL); |
515 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
516 g_free(dir); | |
7436 | 517 dir = g_build_filename(ud, "logs", |
7431 | 518 prpl, guy, NULL); |
519 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
7436 | 520 g_free(dir); |
521 dir = g_build_filename(ud, "logs", | |
7431 | 522 prpl, guy, gaim_normalize(log->account, log->name), NULL); |
523 mkdir (dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
7447 | 524 g_free(guy); |
7436 | 525 |
7431 | 526 char *filename = g_build_filename(dir, date, NULL); |
527 g_free(dir); | |
7436 | 528 |
7431 | 529 file = fopen(dir, "r"); |
530 if(!file) | |
531 mkdir(dir, S_IRUSR | S_IWUSR | S_IXUSR); | |
532 else | |
533 fclose(file); | |
7436 | 534 |
7431 | 535 log->logger_data = fopen(filename, "a"); |
536 if (!log->logger_data) { | |
537 gaim_debug(GAIM_DEBUG_ERROR, "log", "Could not create log file %s\n", filename); | |
538 return; | |
4184 | 539 } |
7447 | 540 g_free(filename); |
7453 | 541 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); |
7431 | 542 fprintf(log->logger_data, "Conversation with %s at %s on %s (%s)\n", |
543 log->name, date, gaim_account_get_username(log->account), prpl); | |
544 } | |
7436 | 545 |
7453 | 546 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); |
7431 | 547 stripped = gaim_markup_strip_html(message); |
548 fprintf(log->logger_data, "(%s) %s%s %s\n", date, from ? from : "", from ? ":" : "", stripped); | |
549 fflush(log->logger_data); | |
550 g_free(stripped); | |
551 } | |
552 | |
553 static void txt_logger_finalize(GaimLog *log) | |
554 { | |
555 if (log->logger_data) | |
556 fclose(log->logger_data); | |
557 } | |
558 | |
559 static GList *txt_logger_list(const char *sn, GaimAccount *account) | |
560 { | |
561 return log_lister_common(sn, account, ".txt", &txt_logger); | |
562 } | |
563 | |
564 static char *txt_logger_read(GaimLog *log, GaimLogReadFlags *flags) | |
565 { | |
566 char *read, *minus_header; | |
7457 | 567 *flags = 0; |
7431 | 568 if (!log->logger_data) |
569 return g_strdup("<font color='red'><b>log->logger_data was NULL!</b></font>"); | |
570 if (g_file_get_contents((char *)log->logger_data, &read, NULL, NULL)) { | |
571 minus_header = strchr(read, '\n'); | |
572 if (!minus_header) | |
573 minus_header = g_strdup(read); | |
7436 | 574 else |
7431 | 575 minus_header = g_strdup(minus_header + 1); |
576 g_free(read); | |
577 return minus_header; | |
578 } | |
579 return g_strdup(_("<font color='red'><b>Could not read file: %s</b></font>")); | |
7436 | 580 } |
7431 | 581 |
582 static GaimLogLogger txt_logger = { | |
583 N_("Plain text"), "txt", | |
584 NULL, | |
585 txt_logger_write, | |
586 txt_logger_finalize, | |
587 txt_logger_list, | |
588 txt_logger_read | |
589 }; | |
590 | |
591 /**************** | |
592 * OLD LOGGER *** | |
593 ****************/ | |
594 | |
595 /* The old logger doesn't write logs, only reads them. This is to include | |
596 * old logs in the log viewer transparently. | |
597 */ | |
598 | |
599 struct old_logger_data { | |
600 char *path; | |
601 int offset; | |
602 int length; | |
603 }; | |
604 | |
7436 | 605 static GList *old_logger_list(const char *sn, GaimAccount *account) |
7431 | 606 { |
607 FILE *file; | |
608 char buf[BUF_LONG]; | |
609 struct tm tm; | |
610 struct old_logger_data *data = NULL; | |
611 char day[4], month[4], year[5]; | |
612 char *logfile = g_strdup_printf("%s.log", gaim_normalize(account, sn)); | |
613 char *date; | |
614 char *path = g_build_filename(gaim_user_dir(), "logs", logfile, NULL); | |
615 char *newlog; | |
616 | |
7447 | 617 g_free(logfile); |
618 | |
7431 | 619 GaimLog *log = NULL; |
620 GList *list = NULL; | |
621 | |
7461 | 622 if (!(file = fopen(path, "rb"))) { |
7447 | 623 g_free(path); |
7431 | 624 return NULL; |
7447 | 625 } |
7436 | 626 |
7431 | 627 while (fgets(buf, BUF_LONG, file)) { |
628 if ((newlog = strstr(buf, "---- New C"))) { | |
629 int length; | |
630 int offset; | |
631 GDate gdate; | |
632 char convostart[32]; | |
633 char *temp = strchr(buf, '@'); | |
7436 | 634 |
7431 | 635 if (temp == NULL || strlen(temp) < 2) |
636 continue; | |
7436 | 637 |
7431 | 638 temp++; |
639 length = strcspn(temp, "-"); | |
640 if (length > 31) length = 31; | |
7436 | 641 |
7431 | 642 offset = ftell(file); |
7436 | 643 |
7431 | 644 if (data) { |
7436 | 645 data->length = offset - data->offset - length; |
646 if(strstr(buf, "----</H3><BR>")) { | |
647 data->length -= | |
648 strlen("<HR><BR><H3 Align=Center> ---- New Conversation @ ") + | |
649 strlen("----</H3><BR>"); | |
650 } else { | |
651 data->length -= | |
652 strlen("---- New Conversation @ ") + strlen("----"); | |
653 } | |
654 | |
7461 | 655 if(strchr(buf, '\r')) |
656 data->length--; | |
657 | |
7431 | 658 if (data->length != 0) |
659 list = g_list_append(list, log); | |
660 else | |
661 gaim_log_free(log); | |
662 } | |
663 | |
664 log = gaim_log_new(GAIM_LOG_IM, sn, account, -1); | |
665 log->logger = &old_logger; | |
666 | |
7436 | 667 data = g_new0(struct old_logger_data, 1); |
7431 | 668 data->offset = offset; |
669 data->path = path; | |
670 log->logger_data = data; | |
671 | |
7436 | 672 |
7431 | 673 g_snprintf(convostart, length, "%s", temp); |
674 sscanf(convostart, "%*s %s %s %d:%d:%d %s", | |
675 month, day, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, year); | |
676 date = g_strdup_printf("%s %s %s", month, day, year); | |
677 g_date_set_parse(&gdate, date); | |
678 tm.tm_mday = g_date_get_day(&gdate); | |
679 tm.tm_mon = g_date_get_month(&gdate) - 1; | |
680 tm.tm_year = g_date_get_year(&gdate) - 1900; | |
681 log->time = mktime(&tm); | |
682 | |
4184 | 683 } |
684 } | |
7431 | 685 fclose(file); |
686 return list; | |
4184 | 687 } |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
688 |
7431 | 689 char * old_logger_read (GaimLog *log, GaimLogReadFlags *flags) |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
690 { |
7431 | 691 struct old_logger_data *data = log->logger_data; |
7461 | 692 FILE *file = fopen(data->path, "rb"); |
7431 | 693 char *read = g_malloc(data->length + 1); |
694 fseek(file, data->offset, SEEK_SET); | |
695 fread(read, data->length, 1, file); | |
696 read[data->length] = '\0'; | |
7436 | 697 *flags = 0; |
698 if(strstr(read, "<BR>")) | |
699 *flags |= GAIM_LOG_READ_NO_NEWLINE; | |
7431 | 700 return read; |
701 } | |
4359
5fb47ec9bfe4
[gaim-migrate @ 4625]
Christian Hammond <chipx86@chipx86.com>
parents:
4227
diff
changeset
|
702 |
7431 | 703 static GaimLogLogger old_logger = { |
704 "old logger", "old", | |
705 NULL, NULL, NULL, | |
706 old_logger_list, | |
707 old_logger_read | |
708 }; |