src/log.c

changeset 9923
f3060096e964
parent 9892
281f62b8824e
child 9926
9957e01fd88a
equal deleted inserted replaced
9922:e3f1db29b022 9923:f3060096e964
176 g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(size)); 176 g_hash_table_replace(logsize_users, lu, GINT_TO_POINTER(size));
177 } 177 }
178 return size; 178 return size;
179 } 179 }
180 180
181 #if 0
182 static char* unescape_filename(const char *escaped) {
183 const char *c = escaped;
184 GString *ret;
185
186 if (escaped == NULL)
187 return NULL;
188
189 ret = g_string_new("");
190
191 /**
192 * <>:"/\ |?*'&$
193 * The above chars are "taboo" for gaim log names and are URL escaped
194 * % is also escaped so we can convert back easily
195 */
196
197 while (*c) {
198 if (*c == '%') {
199 if (*(c + 1) && *(c + 2)) {
200 char hex[2];
201 hex[0] = *(c + 1);
202 hex[1] = *(c + 2);
203 unsigned char *nonhex;
204 gaim_base16_decode(hex, &nonhex);
205 ret = g_string_append_c(ret, *nonhex);
206 g_free(nonhex);
207 c += 2;
208 }
209 } else {
210 ret = g_string_append_c(ret, *c);
211 }
212 c++;
213 }
214
215 return g_string_free(ret, FALSE);
216 }
217 #endif
218
219 static char* escape_filename(const char *unescaped) {
220 const char *c = unescaped;
221 char *hex;
222 GString *ret;
223
224 if (unescaped == NULL)
225 return NULL;
226
227 ret = g_string_new("");
228
229 /**
230 * <>:"/\ |?*'&$
231 * The above chars are "taboo" for gaim log names and are URL escaped
232 * % is also escaped so we can convert back easily
233 */
234
235 while (*c) {
236 switch (*c) {
237 case '<':
238 case '>':
239 case ':':
240 case '"':
241 case '/':
242 case '\\':
243 case ' ':
244 case '|':
245 case '?':
246 case '*':
247 case '\'':
248 case '&':
249 case '$':
250 case '%':
251 hex = g_strdup_printf ("%%%X", (int) *c);
252 ret = g_string_append(ret, hex);
253 g_free(hex);
254 break;
255 default:
256 ret = g_string_append_c(ret, *c);
257 }
258 c++;
259 }
260
261 return g_string_free(ret, FALSE);
262 }
263
264 static char* gaim_log_get_log_dir(GaimLogType type, const char *name, GaimAccount *account) {
265 char *acct_name = escape_filename(gaim_normalize(account,
266 gaim_account_get_username(account)));
267 char *target;
268 /* does this seem like a bad way to get this component of the path to anyone else? --Nathan */
269 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO(
270 gaim_find_prpl(gaim_account_get_protocol_id(account))
271 )->list_icon(account, NULL);
272
273 char *dir;
274
275 if (type == GAIM_LOG_CHAT) {
276 char *temp = g_strdup_printf("%s.chat", gaim_normalize(account, name));
277 target = escape_filename(temp);
278 g_free(temp);
279 } else if(type == GAIM_LOG_SYSTEM) {
280 target = g_strdup(".system");
281 } else {
282 target = escape_filename(gaim_normalize(account, name));
283 }
284
285
286 dir = g_build_filename(gaim_user_dir(), "logs", prpl, acct_name, target, NULL);
287 g_free(target);
288 g_free(acct_name);
289
290 return dir;
291 }
292
181 /**************************************************************************** 293 /****************************************************************************
182 * LOGGER FUNCTIONS ********************************************************* 294 * LOGGER FUNCTIONS *********************************************************
183 ****************************************************************************/ 295 ****************************************************************************/
184 296
185 static GaimLogLogger *current_logger = NULL; 297 static GaimLogLogger *current_logger = NULL;
334 char *path; 446 char *path;
335 FILE *file; 447 FILE *file;
336 }; 448 };
337 449
338 static void log_writer_common(GaimLog *log, GaimMessageFlags type, 450 static void log_writer_common(GaimLog *log, GaimMessageFlags type,
339 const char *prpl, time_t time, 451 time_t time, const char *ext)
340 const char *ext)
341 { 452 {
342 char date[64]; 453 char date[64];
343 struct generic_logger_data *data = log->logger_data; 454 struct generic_logger_data *data = log->logger_data;
344 455
345 if(!data) { 456 if(!data) {
346 /* This log is new */ 457 /* This log is new */
347 char *ud = gaim_user_dir(); 458 char *dir, *filename, *path;
348 char *acct_name = g_strdup(gaim_normalize(log->account, 459
349 gaim_account_get_username(log->account))); 460 dir = gaim_log_get_log_dir(log->type, log->name, log->account);
350 char *target; 461 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR);
351 char *dir;
352 char *filename, *path;
353
354 if (log->type == GAIM_LOG_CHAT) {
355 target = g_strdup_printf("%s.chat", gaim_normalize(log->account,
356 log->name));
357 } else if(log->type == GAIM_LOG_SYSTEM) {
358 target = g_strdup(".system");
359 } else {
360 target = g_strdup(gaim_normalize(log->account, log->name));
361 }
362 462
363 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S", localtime(&log->time)); 463 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S", localtime(&log->time));
364
365 dir = g_build_filename(ud, "logs",
366 prpl, acct_name, target, NULL);
367 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR);
368 g_free(target);
369 g_free(acct_name);
370 464
371 filename = g_strdup_printf("%s%s", date, ext ? ext : ""); 465 filename = g_strdup_printf("%s%s", date, ext ? ext : "");
372 466
373 path = g_build_filename(dir, filename, NULL); 467 path = g_build_filename(dir, filename, NULL);
374 g_free(dir); 468 g_free(dir);
390 static GList *log_lister_common(GaimLogType type, const char *name, GaimAccount *account, const char *ext, GaimLogLogger *logger) 484 static GList *log_lister_common(GaimLogType type, const char *name, GaimAccount *account, const char *ext, GaimLogLogger *logger)
391 { 485 {
392 GDir *dir; 486 GDir *dir;
393 GList *list = NULL; 487 GList *list = NULL;
394 const char *filename; 488 const char *filename;
395 char *me;
396 const char *prpl;
397 char *path; 489 char *path;
398 490
399 if(!account) 491 if(!account)
400 return NULL; 492 return NULL;
401 493
402 if (type == GAIM_LOG_CHAT) 494 path = gaim_log_get_log_dir(type, name, account);
403 me = g_strdup_printf("%s.chat", gaim_normalize(account, gaim_account_get_username(account)));
404 else
405 me = g_strdup(gaim_normalize(account, gaim_account_get_username(account)));
406
407 /* does this seem like a bad way to get this component of the path to anyone else? --Nathan */
408 prpl = GAIM_PLUGIN_PROTOCOL_INFO
409 (gaim_find_prpl(gaim_account_get_protocol_id(account)))->list_icon(account, NULL);
410 if(type == GAIM_LOG_SYSTEM)
411 path = g_build_filename(gaim_user_dir(),"logs", prpl, me, name, NULL);
412 else
413 path = g_build_filename(gaim_user_dir(),"logs", prpl, me, gaim_normalize(account, name), NULL);
414 g_free(me);
415 495
416 if (!(dir = g_dir_open(path, 0, NULL))) { 496 if (!(dir = g_dir_open(path, 0, NULL))) {
417 g_free(path); 497 g_free(path);
418 return NULL; 498 return NULL;
419 } 499 }
470 if (!log->logger_data) { 550 if (!log->logger_data) {
471 /* This log is new. We could use the loggers 'new' function, but 551 /* This log is new. We could use the loggers 'new' function, but
472 * creating a new file there would result in empty files in the case 552 * creating a new file there would result in empty files in the case
473 * that you open a convo with someone, but don't say anything. 553 * that you open a convo with someone, but don't say anything.
474 */ 554 */
475 char *ud = gaim_user_dir(); 555 char *dir = gaim_log_get_log_dir(log->type, log->name, log->account);
476 char *guy = g_strdup(gaim_normalize(log->account, gaim_account_get_username(log->account)));
477 const char *prpl = GAIM_PLUGIN_PROTOCOL_INFO
478 (gaim_find_prpl(gaim_account_get_protocol(log->account)))->list_icon(log->account, NULL);
479 char *dir;
480 FILE *file; 556 FILE *file;
481
482 if (log->type == GAIM_LOG_CHAT) {
483 char *chat = g_strdup_printf("%s.chat", guy);
484 g_free(guy);
485 guy = chat;
486 }
487
488 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.xml", localtime(&log->time)); 557 strftime(date, sizeof(date), "%Y-%m-%d.%H%M%S.xml", localtime(&log->time));
489 558
490 dir = g_build_filename(ud, "logs",
491 prpl, guy, gaim_normalize(log->account, log->name), NULL);
492 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR); 559 gaim_build_dir (dir, S_IRUSR | S_IWUSR | S_IXUSR);
493 g_free(guy);
494 560
495 char *filename = g_build_filename(dir, date, NULL); 561 char *filename = g_build_filename(dir, date, NULL);
496 g_free(dir); 562 g_free(dir);
497 563
498 log->logger_data = fopen(filename, "a"); 564 log->logger_data = fopen(filename, "a");
507 573
508 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time)); 574 strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&log->time));
509 fprintf(log->logger_data, "<conversation time='%s' screenname='%s' protocol='%s'>\n", 575 fprintf(log->logger_data, "<conversation time='%s' screenname='%s' protocol='%s'>\n",
510 date, log->name, prpl); 576 date, log->name, prpl);
511 } 577 }
578
579 /* if we can't write to the file, give up before we hurt ourselves */
580 if(!data->file)
581 return;
512 582
513 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time)); 583 strftime(date, sizeof(date), "%H:%M:%S", localtime(&time));
514 gaim_markup_html_to_xhtml(message, &xhtml, NULL); 584 gaim_markup_html_to_xhtml(message, &xhtml, NULL);
515 if (from) 585 if (from)
516 fprintf(log->logger_data, "<message %s %s from='%s' time='%s'>%s</message>\n", 586 fprintf(log->logger_data, "<message %s %s from='%s' time='%s'>%s</message>\n",
567 struct generic_logger_data *data = log->logger_data; 637 struct generic_logger_data *data = log->logger_data;
568 638
569 if(!data) { 639 if(!data) {
570 const char *prpl = 640 const char *prpl =
571 GAIM_PLUGIN_PROTOCOL_INFO(plugin)->list_icon(log->account, NULL); 641 GAIM_PLUGIN_PROTOCOL_INFO(plugin)->list_icon(log->account, NULL);
572 log_writer_common(log, type, prpl, time, ".html"); 642 log_writer_common(log, type, time, ".html");
573 643
574 data = log->logger_data; 644 data = log->logger_data;
575 645
576 /* if we can't write to the file, give up before we hurt ourselves */ 646 /* if we can't write to the file, give up before we hurt ourselves */
577 if(!data->file) 647 if(!data->file)
705 * creating a new file there would result in empty files in the case 775 * creating a new file there would result in empty files in the case
706 * that you open a convo with someone, but don't say anything. 776 * that you open a convo with someone, but don't say anything.
707 */ 777 */
708 const char *prpl = 778 const char *prpl =
709 GAIM_PLUGIN_PROTOCOL_INFO(plugin)->list_icon(log->account, NULL); 779 GAIM_PLUGIN_PROTOCOL_INFO(plugin)->list_icon(log->account, NULL);
710 log_writer_common(log, type, prpl, time, ".txt"); 780 log_writer_common(log, type, time, ".txt");
711 781
712 data = log->logger_data; 782 data = log->logger_data;
713 783
714 /* if we can't write to the file, give up before we hurt ourselves */ 784 /* if we can't write to the file, give up before we hurt ourselves */
715 if(!data->file) 785 if(!data->file)

mercurial