Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • logging.c

    r0792d99 rf809cad  
    1111static GMainLoop *log_loop;
    1212static GThread *logging_thread;
     13bool defer_logs;
     14static GQueue *deferred_entry_queue;
    1315
    1416/* This is now the one function that should be called to log a
     
    5557  /* skip login/logout messages if appropriate */
    5658  if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
    57      
     59
    5860  /* check direction */
    5961  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
     
    8385    buffer = g_string_new("");
    8486    tmp = short_zuser(owl_message_get_sender(m));
    85     g_string_append_printf(buffer, "Class: %s Instance: %s", 
    86                            owl_message_get_class(m), 
     87    g_string_append_printf(buffer, "Class: %s Instance: %s",
     88                           owl_message_get_class(m),
    8789                           owl_message_get_instance(m));
    8890    if (strcmp(owl_message_get_opcode(m), "")) {
    89       g_string_append_printf(buffer, " Opcode: %s", 
     91      g_string_append_printf(buffer, " Opcode: %s",
    9092                             owl_message_get_opcode(m));
    9193    }
    9294    g_string_append_printf(buffer, "\n");
    93     g_string_append_printf(buffer, "Time: %s Host: %s\n", 
    94                            owl_message_get_timestr(m), 
     95    g_string_append_printf(buffer, "Time: %s Host: %s\n",
     96                           owl_message_get_timestr(m),
    9597                           owl_message_get_hostname(m));
    96     g_string_append_printf(buffer, "From: %s <%s>\n\n", 
     98    g_string_append_printf(buffer, "From: %s <%s>\n\n",
    9799                           owl_message_get_zsig(m), tmp);
    98100    g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
     
    105107    GString *buffer = NULL;
    106108    buffer = g_string_new("");
    107     g_string_append_printf(buffer, "From: <%s> To: <%s>\n", 
     109    g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    108110                           owl_message_get_sender(m), owl_message_get_recipient(m));
    109     g_string_append_printf(buffer, "Time: %s\n\n", 
     111    g_string_append_printf(buffer, "Time: %s\n\n",
    110112                           owl_message_get_timestr(m));
    111113    if (owl_message_is_login(m)) {
     
    124126    buffer = g_string_new("");
    125127    g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    126                            owl_message_get_sender(m), 
     128                           owl_message_get_sender(m),
    127129                           owl_message_get_recipient(m));
    128     g_string_append_printf(buffer, "Time: %s\n\n", 
     130    g_string_append_printf(buffer, "Time: %s\n\n",
    129131                           owl_message_get_timestr(m));
    130132    g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
     
    136138    GString *buffer;
    137139    buffer = g_string_new("");
    138     g_string_append_printf(buffer, "From: <%s> To: <%s>\n", 
    139                            owl_message_get_sender(m), 
     140    g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
     141                           owl_message_get_sender(m),
    140142                           owl_message_get_recipient(m));
    141     g_string_append_printf(buffer, "Time: %s\n\n", 
     143    g_string_append_printf(buffer, "Time: %s\n\n",
    142144                           owl_message_get_timestr(m));
    143     g_string_append_printf(buffer, "%s\n\n", 
     145    g_string_append_printf(buffer, "%s\n\n",
    144146                           owl_message_get_body(m));
    145147    return g_string_free(buffer, FALSE);
     
    158160}
    159161
    160 static void owl_log_write_entry(gpointer data)
    161 {
    162   owl_log_entry *msg = (owl_log_entry*)data;
     162static CALLER_OWN owl_log_entry *owl_log_new_entry(const char *buffer, const char *filename)
     163{
     164  owl_log_entry *log_msg = g_new(owl_log_entry, 1);
     165  log_msg->message = g_strdup(buffer);
     166  log_msg->filename = g_strdup(filename);
     167  return log_msg;
     168}
     169
     170static void owl_log_deferred_enqueue_message(const char *buffer, const char *filename)
     171{
     172  g_queue_push_tail(deferred_entry_queue, owl_log_new_entry(buffer, filename));
     173}
     174
     175/* write out the entry if possible
     176 * return 0 on success, errno on failure to open
     177 */
     178static int owl_log_try_write_entry(owl_log_entry *msg)
     179{
    163180  FILE *file = NULL;
    164181  file = fopen(msg->filename, "a");
    165182  if (!file) {
    166     owl_log_error("Unable to open file for logging");
    167     return;
     183    return errno;
    168184  }
    169185  fprintf(file, "%s", msg->message);
    170186  fclose(file);
     187  return 0;
    171188}
    172189
     
    181198}
    182199
     200static void owl_log_entry_free_gfunc(gpointer data, gpointer user_data)
     201{
     202  owl_log_entry_free(data);
     203}
     204
     205/* If we are deferring log messages, enqueue this entry for
     206 * writing.  Otherwise, try to write this log message, and,
     207 * if it fails with EPERM or EACCES, go into deferred logging
     208 * mode and queue an admin message.  If it fails with anything
     209 * else, display an error message, but do not go into deferred
     210 * logging mode. */
     211static void owl_log_eventually_write_entry(gpointer data)
     212{
     213  int ret;
     214  gchar *errmsg;
     215  owl_log_entry *msg = (owl_log_entry*)data;
     216  if (defer_logs) {
     217    owl_log_deferred_enqueue_message(msg->message, msg->filename);
     218  } else {
     219    ret = owl_log_try_write_entry(msg);
     220    if (ret == EPERM || ret == EACCES) {
     221      defer_logs = true;
     222      owl_log_error("Unable to open file for logging; you do not have \n"
     223                    "permission.  Consider renewing your tickets.  \n"
     224                    "Logging has been suspended, and your messages \n"
     225                    "will be saved.  To resume logging, use the \n"
     226                    "command :flush-logs.\n\n");
     227      owl_log_deferred_enqueue_message(msg->message, msg->filename);
     228    } else if (ret != 0) {
     229      errmsg = g_strdup_printf("Unable to open file for logging: %s", g_strerror(ret));
     230      owl_log_error(errmsg);
     231      g_free(errmsg);
     232    }
     233  }
     234}
     235
     236/* tries to the deferred log entries */
     237static void owl_log_write_deferred_entries(gpointer data)
     238{
     239  owl_log_entry *entry;
     240
     241  defer_logs = false;
     242  while (!g_queue_is_empty(deferred_entry_queue) && !defer_logs) {
     243    entry = (owl_log_entry*)g_queue_pop_head(deferred_entry_queue);
     244    owl_log_eventually_write_entry(entry);
     245    owl_log_entry_free(entry);
     246  }
     247}
     248
     249void owl_log_flush_logs(void)
     250{
     251  owl_select_post_task(owl_log_write_deferred_entries, NULL, NULL, log_context);
     252}
     253
    183254void owl_log_enqueue_message(const char *buffer, const char *filename)
    184255{
    185   owl_log_entry *log_msg = NULL;
    186   log_msg = g_new(owl_log_entry,1);
    187   log_msg->message = g_strdup(buffer);
    188   log_msg->filename = g_strdup(filename);
    189   owl_select_post_task(owl_log_write_entry, log_msg,
     256  owl_log_entry *log_msg = owl_log_new_entry(buffer, filename);
     257  owl_select_post_task(owl_log_eventually_write_entry, log_msg,
    190258                       owl_log_entry_free, log_context);
    191259}
     
    353421  } else if (owl_message_is_type_jabber(m)) {
    354422    if (personal) {
    355       from=frombuff=g_strdup_printf("jabber:%s", 
     423      from=frombuff=g_strdup_printf("jabber:%s",
    356424                                    owl_message_get_sender(m));
    357425    } else {
    358       from=frombuff=g_strdup_printf("jabber:%s", 
     426      from=frombuff=g_strdup_printf("jabber:%s",
    359427                                    owl_message_get_recipient(m));
    360428    }
     
    362430    from=frombuff=g_strdup("unknown");
    363431  }
    364  
     432
    365433  /* check for malicious sender formats */
    366434  len=strlen(frombuff);
     
    429497static gpointer owl_log_thread_func(gpointer data)
    430498{
     499  log_context = g_main_context_new();
    431500  log_loop = g_main_loop_new(log_context, FALSE);
    432501  g_main_loop_run(log_loop);
     
    434503}
    435504
    436 void owl_log_init(void) 
     505void owl_log_init(void)
    437506{
    438507  log_context = g_main_context_new();
     
    454523  }
    455524#endif
    456  
     525
     526  deferred_entry_queue = g_queue_new();
    457527}
    458528
    459529static void owl_log_quit_func(gpointer data)
    460530{
     531  /* flush the deferred logs queue, trying to write the
     532   * entries to the disk one last time */
     533  owl_log_write_deferred_entries(NULL);
     534#if GLIB_CHECK_VERSION(2, 32, 0)
     535  g_queue_free_full(deferred_entry_queue, owl_log_entry_free_gfunc);
     536#else
     537  g_queue_foreach(deferred_entry_queue, owl_log_entry_free_gfunc, NULL);
     538  g_queue_free(deferred_entry_queue);
     539#endif
     540
    461541  g_main_loop_quit(log_loop);
    462542}
Note: See TracChangeset for help on using the changeset viewer.