Mercurial > ~mikael > mcabber > hg
comparison mcabber/src/histolog.c @ 1437:071c8170b7de
Add option 'statefile' to keep track of unread messages across restarts
(Suggested by micressor)
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Mon, 25 Feb 2008 20:27:56 +0100 |
parents | 6fb141142388 |
children | ec55cdf44335 |
comparison
equal
deleted
inserted
replaced
1436:6fb141142388 | 1437:071c8170b7de |
---|---|
24 #include <time.h> | 24 #include <time.h> |
25 #include <ctype.h> | 25 #include <ctype.h> |
26 #include <sys/types.h> | 26 #include <sys/types.h> |
27 #include <sys/stat.h> | 27 #include <sys/stat.h> |
28 #include <fcntl.h> | 28 #include <fcntl.h> |
29 #include <unistd.h> | |
29 | 30 |
30 #include "histolog.h" | 31 #include "histolog.h" |
31 #include "hbuf.h" | 32 #include "hbuf.h" |
32 #include "jabglue.h" | 33 #include "jabglue.h" |
33 #include "utils.h" | 34 #include "utils.h" |
34 #include "logprint.h" | 35 #include "screen.h" |
35 #include "settings.h" | 36 #include "settings.h" |
36 #include "utils.h" | 37 #include "utils.h" |
38 #include "roster.h" | |
37 | 39 |
38 static guint UseFileLogging; | 40 static guint UseFileLogging; |
39 static guint FileLoadLogs; | 41 static guint FileLoadLogs; |
40 static char *RootDir; | 42 static char *RootDir; |
41 | 43 |
389 g_free(RootDir); | 391 g_free(RootDir); |
390 RootDir = NULL; | 392 RootDir = NULL; |
391 } | 393 } |
392 } | 394 } |
393 | 395 |
396 guint hlog_is_enabled(void) | |
397 { | |
398 return UseFileLogging; | |
399 } | |
400 | |
394 inline void hlog_write_message(const char *bjid, time_t timestamp, int sent, | 401 inline void hlog_write_message(const char *bjid, time_t timestamp, int sent, |
395 const char *msg) | 402 const char *msg) |
396 { | 403 { |
397 guchar info; | 404 guchar info; |
398 /* sent=1 message sent by mcabber | 405 /* sent=1 message sent by mcabber |
414 // XXX Check status value? | 421 // XXX Check status value? |
415 write_histo_line(bjid, timestamp, 'S', toupper(imstatus2char[status]), | 422 write_histo_line(bjid, timestamp, 'S', toupper(imstatus2char[status]), |
416 status_msg); | 423 status_msg); |
417 } | 424 } |
418 | 425 |
426 | |
427 // hlog_save_state() | |
428 // If enabled, save the current state of the roster | |
429 // (i.e. pending messages) to a temporary file. | |
430 void hlog_save_state(void) | |
431 { | |
432 gpointer unread_ptr, first_unread; | |
433 const char *bjid; | |
434 char *statefile_xp; | |
435 FILE *fp; | |
436 const char *statefile = settings_opt_get("statefile"); | |
437 | |
438 if (!statefile || !UseFileLogging) | |
439 return; | |
440 | |
441 statefile_xp = expand_filename(statefile); | |
442 fp = fopen(statefile_xp, "w"); | |
443 if (!fp) { | |
444 scr_LogPrint(LPRINT_NORMAL, "Cannot open state file [%s]", | |
445 strerror(errno)); | |
446 goto hlog_save_state_return; | |
447 } | |
448 | |
449 if (!jb_getonline()) { | |
450 // We're not connected. Let's use the unread_jids hash. | |
451 GList *unread_jid = unread_jid_get_list(); | |
452 unread_ptr = unread_jid; | |
453 for ( ; unread_jid ; unread_jid = g_list_next(unread_jid)) | |
454 fprintf(fp, "%s\n", (char*)unread_jid->data); | |
455 g_list_free(unread_ptr); | |
456 goto hlog_save_state_return; | |
457 } | |
458 | |
459 if (!current_buddy) // Safety check -- shouldn't happen. | |
460 goto hlog_save_state_return; | |
461 | |
462 // We're connected. Let's use unread_msg(). | |
463 unread_ptr = first_unread = unread_msg(NULL); | |
464 if (!first_unread) | |
465 goto hlog_save_state_return; | |
466 | |
467 do { | |
468 guint type = buddy_gettype(unread_ptr); | |
469 if (type & (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT)) { | |
470 bjid = buddy_getjid(unread_ptr); | |
471 if (bjid) | |
472 fprintf(fp, "%s\n", bjid); | |
473 } | |
474 unread_ptr = unread_msg(unread_ptr); | |
475 } while (unread_ptr && unread_ptr != first_unread); | |
476 | |
477 hlog_save_state_return: | |
478 if (fp) { | |
479 long filelen = ftell(fp); | |
480 fclose(fp); | |
481 if (!filelen) | |
482 unlink(statefile_xp); | |
483 } | |
484 g_free(statefile_xp); | |
485 } | |
486 | |
487 // hlog_load_state() | |
488 // If enabled, load the current state of the roster | |
489 // (i.e. pending messages) from a temporary file. | |
490 // This function adds the JIDs to the unread_jids hash table, | |
491 // so it should only be called at startup. | |
492 void hlog_load_state(void) | |
493 { | |
494 char bjid[1024]; | |
495 char *statefile_xp; | |
496 FILE *fp; | |
497 const char *statefile = settings_opt_get("statefile"); | |
498 | |
499 if (!statefile || !UseFileLogging) | |
500 return; | |
501 | |
502 statefile_xp = expand_filename(statefile); | |
503 fp = fopen(statefile_xp, "r"); | |
504 if (fp) { | |
505 char *eol; | |
506 while (!feof(fp)) { | |
507 if (fgets(bjid, sizeof bjid, fp) == NULL) | |
508 break; | |
509 // Let's remove the trailing newline. | |
510 // Also remove whitespace, if the file as been (badly) manually modified. | |
511 for (eol = bjid; *eol; eol++) ; | |
512 for (eol--; eol >= bjid && (*eol == '\n' || *eol == ' '); *eol-- = 0) ; | |
513 // Safety checks... | |
514 if (!bjid[0]) | |
515 continue; | |
516 if (check_jid_syntax(bjid)) { | |
517 scr_LogPrint(LPRINT_LOGNORM, | |
518 "ERROR: Invalid JID in state file. Corrupted file?"); | |
519 break; | |
520 } | |
521 // Display a warning if there are pending messages but the user | |
522 // won't see them because load_log isn't set. | |
523 if (!FileLoadLogs) { | |
524 scr_LogPrint(LPRINT_LOGNORM, "WARNING: unread message from <%s>.", | |
525 bjid); | |
526 scr_setmsgflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE); | |
527 } | |
528 // Add the JID to unread_jids. It will be used when the contact is | |
529 // added to the roster. | |
530 unread_jid_add(bjid); | |
531 } | |
532 fclose(fp); | |
533 } | |
534 g_free(statefile_xp); | |
535 } | |
536 | |
419 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ | 537 /* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */ |