Changeset b6c772b


Ignore:
Timestamp:
Oct 15, 2014, 2:50:26 AM (7 years ago)
Author:
Jason Gross <jasongross9@gmail.com>
Parents:
5f3f1e4 (diff), 4733d68 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:
Merge 4733d686e56e8962716de6fa664da9f55bcc2fab into 5f3f1e484f3c4b262b481efbd32602853bb41a27
Files:
2 added
20 edited

Legend:

Unmodified
Added
Removed
  • logging.c

    r7dcef03 rbf61c61  
    1212static GThread *logging_thread;
    1313
    14 /* This is now the one function that should be called to log a
    15  * message.  It will do all the work necessary by calling the other
    16  * functions in this file as necessary.
    17  */
    18 void owl_log_message(const owl_message *m) {
    19   owl_function_debugmsg("owl_log_message: entering");
    20 
    21   if (m == NULL) {
    22     owl_function_debugmsg("owl_log_message: passed null message");
    23     return;
    24   }
    25 
    26   /* should we be logging this message? */
    27   if (!owl_log_shouldlog_message(m)) {
    28     owl_function_debugmsg("owl_log_message: not logging message");
    29     return;
    30   }
    31 
    32   /* handle incmoing messages */
    33   if (owl_message_is_direction_in(m)) {
    34     owl_log_incoming(m);
    35     owl_function_debugmsg("owl_log_message: leaving");
    36     return;
    37   }
    38 
    39   /* handle outgoing messages */
    40   owl_log_outgoing(m);
    41 
    42   owl_function_debugmsg("owl_log_message: leaving");
    43 }
    44 
    45 /* Return 1 if we should log the given message, otherwise return 0 */
    46 int owl_log_shouldlog_message(const owl_message *m) {
    47   const owl_filter *f;
    48 
    49   /* If there's a logfilter and this message matches it, log */
    50   f=owl_global_get_filter(&g, owl_global_get_logfilter(&g));
    51   if (f && owl_filter_message_match(f, m)) return(1);
    52 
    53   /* otherwise we do things based on the logging variables */
    54 
    55   /* skip login/logout messages if appropriate */
    56   if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
    57      
    58   /* check direction */
    59   if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
    60     return(0);
    61   }
    62   if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) && owl_message_is_direction_in(m)) {
    63     return(0);
    64   }
    65 
    66   if (owl_message_is_type_zephyr(m)) {
    67     if (owl_message_is_personal(m) && !owl_global_is_logging(&g)) return(0);
    68     if (!owl_message_is_personal(m) && !owl_global_is_classlogging(&g)) return(0);
    69   } else {
    70     if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
    71       if (!owl_global_is_logging(&g)) return(0);
    72     } else {
    73       if (!owl_global_is_classlogging(&g)) return(0);
    74     }
    75   }
    76   return(1);
    77 }
    78 
    79 CALLER_OWN char *owl_log_zephyr(const owl_message *m)
    80 {
    81     char *tmp = NULL;
    82     GString *buffer = NULL;
    83     buffer = g_string_new("");
    84     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                            owl_message_get_instance(m));
    88     if (strcmp(owl_message_get_opcode(m), "")) {
    89       g_string_append_printf(buffer, " Opcode: %s",
    90                              owl_message_get_opcode(m));
    91     }
    92     g_string_append_printf(buffer, "\n");
    93     g_string_append_printf(buffer, "Time: %s Host: %s\n",
    94                            owl_message_get_timestr(m),
    95                            owl_message_get_hostname(m));
    96     g_string_append_printf(buffer, "From: %s <%s>\n\n",
    97                            owl_message_get_zsig(m), tmp);
    98     g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
    99     g_free(tmp);
    100     return g_string_free(buffer, FALSE);
    101 }
    102 
    103 CALLER_OWN char *owl_log_aim(const owl_message *m)
    104 {
    105     GString *buffer = NULL;
    106     buffer = g_string_new("");
    107     g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    108                            owl_message_get_sender(m), owl_message_get_recipient(m));
    109     g_string_append_printf(buffer, "Time: %s\n\n",
    110                            owl_message_get_timestr(m));
    111     if (owl_message_is_login(m)) {
    112         g_string_append_printf(buffer, "LOGIN\n\n");
    113     } else if (owl_message_is_logout(m)) {
    114         g_string_append_printf(buffer, "LOGOUT\n\n");
    115     } else {
    116         g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
    117     }
    118     return g_string_free(buffer, FALSE);
    119 }
    120 
    121 CALLER_OWN char *owl_log_jabber(const owl_message *m)
    122 {
    123     GString *buffer = NULL;
    124     buffer = g_string_new("");
    125     g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    126                            owl_message_get_sender(m),
    127                            owl_message_get_recipient(m));
    128     g_string_append_printf(buffer, "Time: %s\n\n",
    129                            owl_message_get_timestr(m));
    130     g_string_append_printf(buffer, "%s\n\n", owl_message_get_body(m));
    131     return g_string_free(buffer, FALSE);
    132 }
    133 
    134 CALLER_OWN char *owl_log_generic(const owl_message *m)
    135 {
    136     GString *buffer;
    137     buffer = g_string_new("");
    138     g_string_append_printf(buffer, "From: <%s> To: <%s>\n",
    139                            owl_message_get_sender(m),
    140                            owl_message_get_recipient(m));
    141     g_string_append_printf(buffer, "Time: %s\n\n",
    142                            owl_message_get_timestr(m));
    143     g_string_append_printf(buffer, "%s\n\n",
    144                            owl_message_get_body(m));
    145     return g_string_free(buffer, FALSE);
    146 }
    147 
    14814static void owl_log_error_main_thread(gpointer data)
    14915{
     
    15117}
    15218
    153 static void owl_log_error(const char *message)
     19static void G_GNUC_PRINTF(1, 2) owl_log_error(const char *fmt, ...)
    15420{
    155   char *data = g_strdup(message);
     21  va_list ap;
     22  char *data;
     23
     24  va_start(ap, fmt);
     25  data = g_strdup_vprintf(fmt, ap);
     26  va_end(ap);
     27
    15628  owl_select_post_task(owl_log_error_main_thread,
    157                        data, g_free, g_main_context_default());
     29                       data, g_free, g_main_context_default());
    15830}
    15931
     
    16436  file = fopen(msg->filename, "a");
    16537  if (!file) {
    166     owl_log_error("Unable to open file for logging");
     38    owl_log_error("Unable to open file for logging (%s)", msg->filename);
    16739    return;
    16840  }
     
    19163}
    19264
    193 void owl_log_append(const owl_message *m, const char *filename) {
    194   char *buffer = NULL;
    195   if (owl_message_is_type_zephyr(m)) {
    196     buffer = owl_log_zephyr(m);
    197   } else if (owl_message_is_type_jabber(m)) {
    198     buffer = owl_log_jabber(m);
    199   } else if (owl_message_is_type_aim(m)) {
    200     buffer = owl_log_aim(m);
    201   } else {
    202     buffer = owl_log_generic(m);
    203   }
    204   owl_log_enqueue_message(buffer, filename);
    205   g_free(buffer);
    206 }
    207 
    208 void owl_log_outgoing(const owl_message *m)
    209 {
    210   char *filename, *logpath;
    211   char *to, *temp;
    212   GList *cc;
    213 
    214   /* expand ~ in path names */
    215   logpath = owl_util_makepath(owl_global_get_logpath(&g));
    216 
    217   /* Figure out what path to log to */
    218   if (owl_message_is_type_zephyr(m)) {
    219     /* If this has CC's, do all but the "recipient" which we'll do below */
    220     cc = owl_message_get_cc_without_recipient(m);
    221     while (cc != NULL) {
    222       temp = short_zuser(cc->data);
    223       filename = g_build_filename(logpath, temp, NULL);
    224       owl_log_append(m, filename);
    225 
    226       g_free(filename);
    227       g_free(temp);
    228       g_free(cc->data);
    229       cc = g_list_delete_link(cc, cc);
    230     }
    231 
    232     to = short_zuser(owl_message_get_recipient(m));
    233   } else if (owl_message_is_type_jabber(m)) {
    234     to = g_strdup_printf("jabber:%s", owl_message_get_recipient(m));
    235     g_strdelimit(to, "/", '_');
    236   } else if (owl_message_is_type_aim(m)) {
    237     char *temp2;
    238     temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
    239     temp2 = g_utf8_strdown(temp,-1);
    240     to = g_strdup_printf("aim:%s", temp2);
    241     g_free(temp2);
    242     g_free(temp);
    243   } else {
    244     to = g_strdup("loopback");
    245   }
    246 
    247   filename = g_build_filename(logpath, to, NULL);
    248   owl_log_append(m, filename);
    249   g_free(to);
    250   g_free(filename);
    251 
    252   filename = g_build_filename(logpath, "all", NULL);
    253   owl_log_append(m, filename);
    254   g_free(logpath);
    255   g_free(filename);
    256 }
    257 
    258 
    25965void owl_log_outgoing_zephyr_error(const owl_zwrite *zw, const char *text)
    26066{
    261   char *filename, *logpath;
    262   char *tobuff, *recip;
    263   owl_message *m;
    264   GString *msgbuf;
    265   /* create a present message so we can pass it to
    266    * owl_log_shouldlog_message(void)
    267    */
    268   m = g_slice_new(owl_message);
     67  owl_message *m = g_slice_new(owl_message);
    26968  /* recip_index = 0 because there can only be one recipient anyway */
    27069  owl_message_create_from_zwrite(m, zw, text, 0);
    271   if (!owl_log_shouldlog_message(m)) {
    272     owl_message_delete(m);
    273     return;
    274   }
     70  g_free(owl_perlconfig_call_with_message("BarnOwl::Logging::log_outgoing_error", m));
    27571  owl_message_delete(m);
    276 
    277   /* chop off a local realm */
    278   recip = owl_zwrite_get_recip_n_with_realm(zw, 0);
    279   tobuff = short_zuser(recip);
    280   g_free(recip);
    281 
    282   /* expand ~ in path names */
    283   logpath = owl_util_makepath(owl_global_get_logpath(&g));
    284   filename = g_build_filename(logpath, tobuff, NULL);
    285   msgbuf = g_string_new("");
    286   g_string_printf(msgbuf, "ERROR (owl): %s\n%s\n", tobuff, text);
    287   if (text[strlen(text)-1] != '\n') {
    288     g_string_append_printf(msgbuf, "\n");
    289   }
    290   owl_log_enqueue_message(msgbuf->str, filename);
    291   g_string_free(msgbuf, TRUE);
    292 
    293   filename = g_build_filename(logpath, "all", NULL);
    294   g_free(logpath);
    295   msgbuf = g_string_new("");
    296   g_string_printf(msgbuf, "ERROR (owl): %s\n%s\n", tobuff, text);
    297   if (text[strlen(text)-1] != '\n') {
    298     g_string_append_printf(msgbuf, "\n");
    299   }
    300   owl_log_enqueue_message(msgbuf->str, filename);
    301   g_string_free(msgbuf, TRUE);
    302 
    303   g_free(tobuff);
    304 }
    305 
    306 void owl_log_incoming(const owl_message *m)
    307 {
    308   char *filename, *allfilename, *logpath;
    309   const char *from=NULL;
    310   char *frombuff=NULL;
    311   int len, ch, i, personal;
    312 
    313   /* figure out if it's a "personal" message or not */
    314   if (owl_message_is_type_zephyr(m)) {
    315     if (owl_message_is_personal(m)) {
    316       personal = 1;
    317     } else {
    318       personal = 0;
    319     }
    320   } else if (owl_message_is_type_jabber(m)) {
    321     /* This needs to be fixed to handle groupchat */
    322     const char* msgtype = owl_message_get_attribute_value(m,"jtype");
    323     if (msgtype && !strcmp(msgtype,"groupchat")) {
    324       personal = 0;
    325     } else {
    326       personal = 1;
    327     }
    328   } else {
    329     if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
    330       personal = 1;
    331     } else {
    332       personal = 0;
    333     }
    334   }
    335 
    336 
    337   if (owl_message_is_type_zephyr(m)) {
    338     if (personal) {
    339       from=frombuff=short_zuser(owl_message_get_sender(m));
    340     } else {
    341       from=frombuff=g_strdup(owl_message_get_class(m));
    342     }
    343   } else if (owl_message_is_type_aim(m)) {
    344     /* we do not yet handle chat rooms */
    345     char *normalto, *temp;
    346     temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
    347     normalto = g_utf8_strdown(temp, -1);
    348     from=frombuff=g_strdup_printf("aim:%s", normalto);
    349     g_free(normalto);
    350     g_free(temp);
    351   } else if (owl_message_is_type_loopback(m)) {
    352     from=frombuff=g_strdup("loopback");
    353   } else if (owl_message_is_type_jabber(m)) {
    354     if (personal) {
    355       from=frombuff=g_strdup_printf("jabber:%s",
    356                                     owl_message_get_sender(m));
    357     } else {
    358       from=frombuff=g_strdup_printf("jabber:%s",
    359                                     owl_message_get_recipient(m));
    360     }
    361   } else {
    362     from=frombuff=g_strdup("unknown");
    363   }
    364  
    365   /* check for malicious sender formats */
    366   len=strlen(frombuff);
    367   if (len<1 || len>35) from="weird";
    368   if (strchr(frombuff, '/')) from="weird";
    369 
    370   ch=frombuff[0];
    371   if (!g_ascii_isalnum(ch)) from="weird";
    372 
    373   for (i=0; i<len; i++) {
    374     if (frombuff[i]<'!' || frombuff[i]>='~') from="weird";
    375   }
    376 
    377   if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird";
    378 
    379   if (!personal) {
    380     if (strcmp(from, "weird")) {
    381       char* temp = g_utf8_strdown(frombuff, -1);
    382       if (temp) {
    383         g_free(frombuff);
    384         from = frombuff = temp;
    385       }
    386     }
    387   }
    388 
    389   /* create the filename (expanding ~ in path names) */
    390   if (personal) {
    391     logpath = owl_util_makepath(owl_global_get_logpath(&g));
    392     filename = g_build_filename(logpath, from, NULL);
    393     allfilename = g_build_filename(logpath, "all", NULL);
    394     owl_log_append(m, allfilename);
    395     g_free(allfilename);
    396   } else {
    397     logpath = owl_util_makepath(owl_global_get_classlogpath(&g));
    398     filename = g_build_filename(logpath, from, NULL);
    399   }
    400 
    401   owl_log_append(m, filename);
    402   g_free(filename);
    403 
    404   if (personal && owl_message_is_type_zephyr(m)) {
    405     /* We want to log to all of the CC'd people who were not us, or
    406      * the sender, as well.
    407      */
    408     char *temp;
    409     GList *cc;
    410     cc = owl_message_get_cc_without_recipient(m);
    411     while (cc != NULL) {
    412       temp = short_zuser(cc->data);
    413       if (strcasecmp(temp, frombuff) != 0) {
    414         filename = g_build_filename(logpath, temp, NULL);
    415         owl_log_append(m, filename);
    416         g_free(filename);
    417       }
    418 
    419       g_free(temp);
    420       g_free(cc->data);
    421       cc = g_list_delete_link(cc, cc);
    422     }
    423   }
    424 
    425   g_free(frombuff);
    426   g_free(logpath);
    42772}
    42873
  • message.c

    r7dcef03 re38cc20  
    396396{
    397397  return owl_message_is_type(m, "aim");
    398 }
    399 
    400 /* XXX TODO: deprecate this */
    401 int owl_message_is_type_jabber(const owl_message *m)
    402 {
    403   return owl_message_is_type(m, "jabber");
    404398}
    405399
  • owl.c

    r441fd42 rbf61c61  
    230230  /* let perl know about it */
    231231  owl_perlconfig_newmsg(m, NULL);
    232   /* log the message if we need to */
    233   owl_log_message(m);
    234232  /* redraw the sepbar; TODO: don't violate layering */
    235233  owl_global_sepbar_dirty(&g);
  • perl/Makefile.am

    ra870319 rdca6255  
    1313        lib/BarnOwl/Hook.pm \
    1414        lib/BarnOwl/Hooks.pm \
     15        lib/BarnOwl/Logging.pm \
    1516        lib/BarnOwl/MainLoopCompatHook.pm \
    1617        lib/BarnOwl/Message.pm \
  • perl/lib/BarnOwl.pm

    recd4edf rdca6255  
    3838use BarnOwl::Hook;
    3939use BarnOwl::Hooks;
     40use BarnOwl::Logging;
    4041use BarnOwl::Message;
    4142use BarnOwl::Style;
  • perl/lib/BarnOwl/Message.pm

    r0adbce1 r611236e  
    33
    44package BarnOwl::Message;
     5
     6use File::Spec;
    57
    68use BarnOwl::Message::Admin;
     
    115117    }
    116118    return $s;
     119}
     120
     121=head2 log MESSAGE
     122
     123Returns the text that should be written to a file to log C<MESSAGE>.
     124
     125=cut
     126
     127sub log {
     128    my ($m) = @_;
     129    return $m->log_header . "\n\n" . $m->log_body . "\n\n";
     130}
     131
     132=head2 log_header MESSAGE
     133
     134Returns the header of the message, for logging purposes.
     135If you override L<BarnOwl::Message::log>, this method is not called.
     136
     137=cut
     138
     139sub log_header {
     140    my ($m) = @_;
     141    my $sender = $m->sender;
     142    my $recipient = $m->recipient;
     143    my $timestr = $m->time;
     144    return "From: <$sender> To: <$recipient>\n"
     145         . "Time: $timestr";
     146}
     147
     148=head2 log_body MESSAGE
     149
     150Returns the body of the message, for logging purposes.
     151If you override L<BarnOwl::Message::log>, this method is not called.
     152
     153=cut
     154
     155sub log_body {
     156    my ($m) = @_;
     157    if ($m->is_loginout) {
     158        return uc($m->login)
     159            . $m->login_type
     160            . ($m->login_extra ? ' at ' . $m->login_extra : '');
     161    } else {
     162        return $m->body;
     163    }
     164}
     165
     166=head2 log_filenames MESSAGE
     167
     168Returns a list of filenames to which this message should be logged.
     169The filenames should be relative to the path returned by C<log_path>.
     170See L<BarnOwl::Logging::get_filenames> for the specification of valid
     171filenames, and for what happens if this method returns an invalid
     172filename.
     173
     174=cut
     175
     176sub log_filenames {
     177    my ($m) = @_;
     178    my $filename;
     179    if ($m->is_incoming) {
     180        $filename = $m->pretty_sender;
     181    } elsif ($m->is_outgoing) {
     182        $filename = $m->pretty_recipient;
     183    }
     184    $filename = "unknown" if !defined($filename) || $filename eq '';
     185    if (BarnOwl::getvar('log-to-subdirectories') eq 'on') {
     186        return ($filename);
     187    } else {
     188        return ($m->log_subfolder . ':' . $filename);
     189    }
     190}
     191
     192=head2 log_to_all_file MESSAGE
     193
     194There is an C<all> file.  This method determines if C<MESSAGE>
     195should get logged to it, in addition to any files returned by
     196C<log_filenames>.
     197
     198It defaults to returning true if and only if C<MESSAGE> is outgoing.
     199
     200=cut
     201
     202sub log_to_all_file {
     203    my ($m) = @_;
     204    return $m->is_outgoing;
     205}
     206
     207=head2 log_path MESSAGE
     208
     209Returns the folder in which all messages of this class get logged.
     210
     211Defaults to C<log_base_path/log_subfolder> if C<log-to-subdirectories>
     212is enabled, or to the C<logpath> BarnOwl variable if it is not.
     213
     214Most protocols should override C<log_subfolder> rather than
     215C<log_path>, in order to properly take into account the value of
     216C<log-to-subdirectories>.
     217
     218=cut
     219
     220sub log_path {
     221    my ($m) = @_;
     222    if (BarnOwl::getvar('log-to-subdirectories') eq 'on') {
     223        return File::Spec->catfile($m->log_base_path, $m->log_subfolder);
     224    } else {
     225        return BarnOwl::getvar('logpath');
     226    }
     227}
     228
     229=head2 log_base_path MESSAGE
     230
     231Returns the base path for logging.  See C<log_path> for more information.
     232
     233Defaults to the BarnOwl variable C<logbasepath>.
     234
     235=cut
     236
     237sub log_base_path {
     238    return BarnOwl::getvar('logbasepath');
     239}
     240
     241=head2 log_subfolder MESSAGE
     242
     243Returns the subfolder of C<log_base_path> to log messages in.
     244
     245Defaults to C<lc($m->type)>.
     246
     247=cut
     248
     249sub log_subfolder {
     250    return lc(shift->type);
     251}
     252
     253=head2 log_outgoing_error MESSAGE
     254
     255Returns the string that should be logged if there is an error sending
     256an outgoing message.
     257
     258=cut
     259
     260sub log_outgoing_error {
     261    my ($m) = @_;
     262    my $recipient = $m->pretty_recipient;
     263    my $body = $m->body;
     264    chomp $body;
     265    return "ERROR (BarnOwl): $recipient\n$body\n\n";
     266}
     267
     268=head2 should_log MESSAGE
     269
     270Returns true if we should log C<MESSAGE>.  This does not override
     271user settings; if the BarnOwl variable C<loggingdirection> is in,
     272and C<MESSAGE> is outgoing and does not match the C<logfilter>, it
     273will not get logged regardless of what this method returns.
     274
     275Note that this method I<does> override the BarnOwl C<logging>
     276variable; if a derived class overrides this method and does not
     277provide an alternative BarnOwl variable (such as C<classlogging>),
     278the overriding method should check the BarnOwl C<logging> variable.
     279
     280Defaults to returning the value of the BarnOwl variable C<logging>.
     281
     282=cut
     283
     284sub should_log {
     285    return BarnOwl::getvar('logging') eq 'on';
    117286}
    118287
  • perl/lib/BarnOwl/Message/AIM.pm

    r7011c3dc rdca6255  
    2424}
    2525
     26sub normalize_screenname {
     27    my ($screenname) = @_;
     28    $screenname =~ s/\s+//g;
     29    return lc($screenname);
     30}
     31
     32sub log_filenames {
     33    return map { normalize_screenname($_) } BarnOwl::Message::log_filenames(@_);
     34}
    2635
    27361;
  • perl/lib/BarnOwl/Message/Loopback.pm

    ree183be r2688bd5  
    1414sub replysendercmd {return 'loopwrite';}
    1515
     16sub log_subfolder { return ''; }
     17sub log_filenames { return ('loopback'); }
    1618
    17191;
  • perl/lib/BarnOwl/Message/Zephyr.pm

    r0adbce1 rcc27237  
    2121    my ($user, $realm) = split(/@/,$principal);
    2222    return $realm;
     23}
     24
     25sub casefold_principal {
     26    my $principal = shift;
     27    # split the principal right after the final @, without eating any
     28    # characters; this way, we always get at least '@' in $user
     29    my ($user, $realm) = split(/(?<=@)(?=[^@]+$)/, $principal);
     30    return lc($user) . uc($realm);
    2331}
    2432
     
    132140    return $1 if $self->body =~ /^\s*cc:\s+([^\n]+)/i;
    133141    return undef;
     142}
     143
     144sub zephyr_cc_without_recipient {
     145    my $self = shift;
     146    my $recipient = lc(strip_realm($self->recipient));
     147    my $cc = $self->zephyr_cc;
     148    return grep { lc(strip_realm($_)) ne $recipient } split(/\s+/, $cc) if defined $cc;
     149    return ();
    134150}
    135151
     
    223239}
    224240
     241# Logging
     242sub log_header {
     243    my ($m) = @_;
     244    my $class = $m->class;
     245    my $instance = $m->instance;
     246    my $opcode = $m->opcode;
     247    my $timestr = $m->time;
     248    my $host = $m->host;
     249    my $sender = $m->pretty_sender;
     250    my $zsig = $m->zsig;
     251    my $rtn = "Class: $class Instance: $instance";
     252    $rtn .= " Opcode: $opcode" unless !defined $opcode || $opcode eq '';
     253    $rtn .= "\nTime: $timestr Host: $host"
     254          . "\nFrom: $zsig <$sender>";
     255    return $rtn;
     256}
     257
     258sub log_filenames {
     259    my ($m) = @_;
     260    my @filenames = ();
     261    if ($m->is_personal) {
     262        @filenames = $m->zephyr_cc_without_recipient;
     263    }
     264    if ($m->is_incoming) {
     265        if ($m->is_personal) {
     266            push @filenames, $m->sender;
     267        } else {
     268            my $realm = '';
     269            $realm .= '@' . $m->realm if $m->realm ne BarnOwl::zephyr_getrealm();
     270            return (BarnOwl::compat_casefold($m->class) . uc($realm));
     271        }
     272    } else {
     273        push @filenames, $m->recipient;
     274    }
     275    return map { casefold_principal(BarnOwl::zephyr_smartstrip_user(strip_realm($_))) } @filenames;
     276}
     277
     278sub log_to_class_file {
     279    my ($m) = @_;
     280    return !$m->is_personal;
     281}
     282
     283sub log_path {
     284    my ($m) = @_;
     285    if ($m->log_to_class_file) {
     286        return BarnOwl::getvar('classlogpath');
     287    } else {
     288        return BarnOwl::getvar('logpath');
     289    }
     290}
     291
     292sub should_log {
     293    my ($m) = @_;
     294    if ($m->log_to_class_file) {
     295        return BarnOwl::getvar('classlogging') eq 'on';
     296    } else {
     297        return BarnOwl::getvar('logging') eq 'on';
     298    }
     299}
    225300
    2263011;
  • perl/modules/IRC/lib/BarnOwl/Message/IRC.pm

    r60b49a7 r4b9c3b9  
    9292}
    9393
     94# logging
     95sub log_filenames {
     96    my ($m) = @_;
     97    die "IRC should not be handling non-IRC messages" if lc($m->type) ne "irc";
     98    BarnOwl::error("IRC message without a network") if !defined($m->network) || $m->network eq '';
     99    my $filename = lc($m->network);
     100    if ($m->is_personal) {
     101        if ($m->is_incoming) {
     102            $filename .= ":" . $m->sender;
     103        } elsif ($m->is_outgoing) {
     104            $filename .= ":" . $m->recipient;
     105        }
     106    } else {
     107        $filename .= ":" . $m->channel;
     108    }
     109    return ($filename);
     110}
     111
     112sub log {
     113    my ($m) = @_;
     114    my $sender = $m->sender;
     115    my $timestr = $m->time;
     116    my $body = $m->body;
     117    if ($m->is_loginout) {
     118        return BarnOwl::Message::log($m);
     119    } else {
     120        return "[$timestr] <$sender> $body\n";
     121    }
     122}
     123
    941241;
  • perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm

    ra27acf7 rcc27237  
    172172}
    173173
     174sub log_filenames {
     175    return map { BarnOwl::compat_casefold($_) } BarnOwl::Message::log_filenames(@_);
     176}
     177
    174178=head1 SEE ALSO
    175179
  • perlglue.xs

    r7dcef03 rcc27237  
    385385                RETVAL
    386386
     387const utf8 *
     388compat_casefold(in)
     389        const char * in
     390        PREINIT:
     391                char *rv;
     392        CODE:
     393                rv = owl_util_compat_casefold(in);
     394                RETVAL = rv;
     395        OUTPUT:
     396                RETVAL
     397        CLEANUP:
     398                g_free(rv);
     399
    387400
    388401MODULE = BarnOwl                PACKAGE = BarnOwl::Zephyr
     
    407420        OUTPUT:
    408421                RETVAL
     422
     423const utf8 *
     424makepath(in)
     425        const char * in
     426        PREINIT:
     427                char *rv;
     428        CODE:
     429                rv = owl_util_makepath(in);
     430                RETVAL = rv;
     431        OUTPUT:
     432                RETVAL
     433        CLEANUP:
     434                g_free(rv);
    409435
    410436void
     
    642668        OUTPUT:
    643669                RETVAL
     670
     671MODULE = BarnOwl                PACKAGE = BarnOwl::Logging
     672
     673void
     674enqueue_text(log_text, filename)
     675        const char * log_text
     676        const char * filename
     677        CODE:
     678                owl_log_enqueue_message(log_text, filename);
  • tester.c

    r21dc927 r1210b54  
    357357
    358358
    359   FAIL_UNLESS("get string var", NULL != (var = owl_variable_get_var(&vd, "logpath")));
    360   FAIL_UNLESS("get string", 0 == strcmp("~/zlog/people", owl_variable_get_string(var)));
     359  FAIL_UNLESS("get string var", NULL != (var = owl_variable_get_var(&vd, "personalbell")));
     360  FAIL_UNLESS("get string", 0 == strcmp("off", owl_variable_get_string(var)));
    361361  FAIL_UNLESS("set string 7", 0 == owl_variable_set_string(var, "whee"));
    362362  FAIL_UNLESS("get string", !strcmp("whee", owl_variable_get_string(var)));
  • util.c

    rcba6b9c rb6c772b  
    643643}
    644644
     645CALLER_OWN char *owl_util_compat_casefold(const char *str)
     646{
     647  /*
     648   * Quoting Anders Kaseorg at https://github.com/barnowl/barnowl/pull/54#issuecomment-31452543:
     649   *
     650   * The Unicode specification calls this compatibility caseless matching, and
     651   * the correct transformation actually has five calls:
     652   * NFKC(toCasefold(NFKD(toCasefold(NFD(string))))) Zephyr’s current
     653   * implementation incorrectly omits the innermost NFD, but that difference
     654   * only matters for characters including U+0345 ◌ͅ COMBINING GREEK
     655   * YPOGEGRAMMENI. I think we should just write the correct version and get
     656   * Zephyr fixed.
     657   *
     658   * Neither of these operations should be called toNFKC_Casefold, because that
     659   * has slightly different behavior regarding Default_Ignorable_Code_Point. I
     660   * propose compat_casefold. And I guess if Jabber wants it too, we should
     661   * move it to util.c.
     662   */
     663  char *tmp0 = g_utf8_normalize(str, -1, G_NORMALIZE_NFD);
     664  char *tmp1 = g_utf8_casefold(tmp0, -1);
     665  char *tmp2 = g_utf8_normalize(tmp1, -1, G_NORMALIZE_NFKD);
     666  char *tmp3 = g_utf8_casefold(tmp2, -1);
     667  char *out = g_utf8_normalize(tmp3, -1, G_NORMALIZE_NFKC);
     668  g_free(tmp0);
     669  g_free(tmp1);
     670  g_free(tmp2);
     671  g_free(tmp3);
     672
     673  return out;
     674}
     675
    645676/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
    646677int owl_util_can_break_after(gunichar c)
  • variable.c

    r94b9ee0 rb6c772b  
    136136               "load logins from .anyone on startup", "" );
    137137
    138   OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
    139                "turn personal logging on or off",
    140                "If this is set to on, personal messages are\n"
    141                "logged in the directory specified\n"
    142                "by the 'logpath' variable.  The filename in that\n"
    143                "directory is derived from the sender of the message.\n" );
    144 
    145   OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
    146                "turn class logging on or off",
    147                "If this is set to on, class messages are\n"
    148                "logged in the directory specified\n"
    149                "by the 'classlogpath' variable.\n"
    150                "The filename in that directory is derived from\n"
    151                "the name of the class to which the message was sent.\n" );
    152 
    153   OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
    154                "specifies which kind of messages should be logged",
    155                "Can be one of 'both', 'in', or 'out'.  If 'in' is\n"
    156                "selected, only incoming messages are logged, if 'out'\n"
    157                "is selected only outgoing messages are logged.  If 'both'\n"
    158                "is selected both incoming and outgoing messages are\n"
    159                "logged.",
    160                "both,in,out");
    161 
    162138  OWLVAR_BOOL_FULL( "colorztext" /* %OwlVarStub */, 1,
    163139                    "allow @color() in zephyrs to change color",
     
    185161               "Enable printing of login notifications",
    186162               "When this is enabled, BarnOwl will print login and logout notifications\n"
    187                "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
    188                "login or logout notifications.\n");
    189 
    190   OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
    191                  "name of a filter controlling which messages to log",
    192 
    193                  "If non empty, any messages matching the given filter will be logged.\n"
    194                  "This is a completely separate mechanism from the other logging\n"
    195                  "variables like logging, classlogging, loglogins, loggingdirection,\n"
    196                  "etc.  If you want this variable to control all logging, make sure\n"
    197                  "all other logging variables are in their default state.\n");
    198 
    199   OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
    200                "Enable logging of login notifications",
    201                "When this is enabled, BarnOwl will log login and logout notifications\n"
    202163               "for AIM, zephyr, or other protocols.  If disabled BarnOwl will not print\n"
    203164               "login or logout notifications.\n");
     
    214175                    "off,middle,on",
    215176                    NULL, owl_variable_disable_ctrl_d_set, NULL);
    216 
    217   OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
    218                "path for logging personal zephyrs",
    219                "Specifies a directory which must exist.\n"
    220                "Files will be created in the directory for each sender.\n");
    221 
    222   OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
    223                "path for logging class zephyrs",
    224                "Specifies a directory which must exist.\n"
    225                "Files will be created in the directory for each class.\n");
    226177
    227178  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
  • .travis.yml

    r48c09d4 r5f3f1e4  
     1
    12language: perl
    23compiler:
     
    910  - "5.16"
    1011  - "5.18"
    11   - "5.19"
     12  - "5.20"
    1213install:
    1314  - sudo apt-get update -q
  • functions.c

    r7dcef03 rb61ad80  
    12271227  time_t now;
    12281228  va_list ap;
    1229   va_start(ap, fmt);
    12301229
    12311230  if (!owl_global_is_debug_fast(&g))
     
    12421241          (int) getpid(), tmpbuff, now - owl_global_get_starttime(&g));
    12431242  g_free(tmpbuff);
     1243
     1244  va_start(ap, fmt);
    12441245  vfprintf(file, fmt, ap);
     1246  va_end(ap);
     1247
    12451248  putc('\n', file);
    12461249  fflush(file);
    1247 
    1248   va_end(ap);
    12491250}
    12501251
  • perl/modules/Twitter/lib/BarnOwl/Module/Twitter.pm

    rb8a3e00 r140429f  
    137137        my $twitter_args = { username   => $cfg->{user},
    138138                             password   => $cfg->{password},
    139                              source     => 'barnowl',
     139                             source     => 'barnowl',
     140                             ssl        => 1,
     141                             legacy_lists_api => 0,
    140142                         };
    141143        if (defined $cfg->{service}) {
     
    274276);
    275277
     278BarnOwl::new_command( 'twitter-favorite' => sub { cmd_twitter_favorite(@_) },
     279    {
     280    summary     => 'Favorite the current Twitter message',
     281    usage       => 'twitter-favorite [ACCOUNT]',
     282    description => <<END_DESCRIPTION
     283Favorite the current Twitter message using ACCOUNT (defaults to the
     284account that received the tweet).
     285END_DESCRIPTION
     286    }
     287);
     288
    276289BarnOwl::new_command( 'twitter-follow' => sub { cmd_twitter_follow(@_); },
    277290    {
     
    355368    $account = $m->account unless defined($account);
    356369    find_account($account)->twitter_retweet($m);
     370    return;
     371}
     372
     373sub cmd_twitter_favorite {
     374    my $cmd = shift;
     375    my $account = shift;
     376    my $m = BarnOwl::getcurmsg();
     377    if(!$m || $m->type ne 'Twitter') {
     378        die("$cmd must be used with a Twitter message selected.\n");
     379    }
     380
     381    $account = $m->account unless defined($account);
     382    find_account($account)->twitter_favorite($m);
    357383    return;
    358384}
  • perl/modules/Twitter/lib/BarnOwl/Module/Twitter/Handle.pm

    r4ebbfbc r140429f  
    371371        $self->twitter_direct($1, $2);
    372372    } elsif(defined $self->{twitter}) {
    373         if(length($msg) > 140) {
    374             die("Twitter: Message over 140 characters long.\n");
    375         }
    376373        $self->twitter_command('update', {
    377374            status => $msg,
     
    432429}
    433430
     431sub twitter_favorite {
     432    my $self = shift;
     433    my $msg = shift;
     434
     435    if($msg->service ne $self->{cfg}->{service}) {
     436        die("Cannot favorite a message from a different service.\n");
     437    }
     438    $self->twitter_command(create_favorite => $msg->{status_id});
     439}
     440
     441
    434442sub twitter_follow {
    435443    my $self = shift;
  • zephyr.c

    r7dcef03 r18380fd  
    283283#ifdef HAVE_LIBZEPHYR
    284284  FILE *file;
     285  int fopen_errno;
    285286  char *tmp, *start;
    286287  char *buffer = NULL;
     
    289290  int subSize = 1024;
    290291  int count;
    291   struct stat statbuff;
    292292
    293293  subsfile = owl_zephyr_dotfile(".zephyr.subs", filename);
    294294
    295   if (stat(subsfile, &statbuff) != 0) {
    296     g_free(subsfile);
    297     if (error_on_nofile == 1)
     295  count = 0;
     296  file = fopen(subsfile, "r");
     297  fopen_errno = errno;
     298  g_free(subsfile);
     299  if (!file) {
     300    if (error_on_nofile == 1 || fopen_errno != ENOENT)
    298301      return -1;
    299302    return 0;
    300303  }
    301 
    302   ZResetAuthentication();
    303   count = 0;
    304   file = fopen(subsfile, "r");
    305   g_free(subsfile);
    306   if (!file)
    307     return -1;
    308304
    309305  subs = g_new(ZSubscription_t, subSize);
     
    348344    g_free(buffer);
    349345
     346  ZResetAuthentication();
    350347  return owl_zephyr_loadsubs_helper(subs, count);
    351348#else
     
    412409  char *buffer = NULL;
    413410  int count;
    414   struct stat statbuff;
    415411
    416412  subs = g_new(ZSubscription_t, numSubs);
    417413  subsfile = owl_zephyr_dotfile(".anyone", filename);
    418414
    419   if (stat(subsfile, &statbuff) == -1) {
    420     g_free(subs);
    421     g_free(subsfile);
    422     return 0;
    423   }
    424 
    425   ZResetAuthentication();
    426415  count = 0;
    427416  file = fopen(subsfile, "r");
     
    445434    fclose(file);
    446435  } else {
     436    g_free(subs);
    447437    return 0;
    448438  }
    449439  g_free(buffer);
    450440
     441  ZResetAuthentication();
    451442  return owl_zephyr_loadsubs_helper(subs, count);
    452443#else
Note: See TracChangeset for help on using the changeset viewer.