Changeset eea7bed4


Ignore:
Timestamp:
Aug 16, 2017, 12:53:41 PM (7 years ago)
Author:
Jason Gross <jasongross9@gmail.com>
Branches:
master
Children:
ff528e6
Parents:
da7341e
git-author:
Jason Gross <jgross@mit.edu> (07/12/11 14:42:39)
git-committer:
Jason Gross <jasongross9@gmail.com> (08/16/17 12:53:41)
Message:
Moved log file name generation to perl

I don't think that the class/personal distinction is the best for
general protocols, but I don't know what should replace it.  I've made
class-logging default to only zephyr (a slight change from previous
behavior, where jabber MUC's would be logged to $classlogpath, as well
as all non-private non-login messages from other protocols), but made
logging path generation overridable.

TODO: Decide whether or not to filter out more 'bad' characters.
Perhaps we should remove '!' because it indicates history in some shells
and makes things obnoxious, or '~' becase it indicates homedirs in many
shells.
* '/' is for separating directories, and we don't want to accidentally
  make subdirectories

We first NFKC for zephyrs, and then apply lc.  The zephyr servers
apply case-folded NFKC (so says
http://zephyr.1ts.org/browser/zephyr/server/zstring.c).  We should
probably use Unicode::CaseFold instead of lc.  I'm also not sure what
the order case-adjustment and normalization should be.

We first NFKC, then apply lc, to jabbers, as per
http://xmpp.org/internet-drafts/attic/draft-ietf-xmpp-nodeprep-03.html
(though I can't actually find anything that specifies the case-folding
algorithm, nor the ordering).

We now use lc instead of g_utf8_strdown to normalize AIM screennames.
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • logging.c

    r7f463cf reea7bed4  
    3636  }
    3737
    38   /* handle incmoing messages */
    39   if (owl_message_is_direction_in(m)) {
    40     owl_log_incoming(m);
    41     owl_function_debugmsg("owl_log_message: leaving");
    42     return;
    43   }
    44 
    45   /* handle outgoing messages */
    46   owl_log_outgoing(m);
     38  owl_log_perl(m);
    4739
    4840  owl_function_debugmsg("owl_log_message: leaving");
     
    316308}
    317309
    318 void owl_log_outgoing(const owl_message *m)
    319 {
    320   char *filename, *logpath;
    321   char *to, *temp;
    322   GList *cc;
    323 
    324   /* expand ~ in path names */
    325   logpath = owl_util_makepath(owl_global_get_logpath(&g));
    326 
    327   /* Figure out what path to log to */
    328   if (owl_message_is_type_zephyr(m)) {
    329     /* If this has CC's, do all but the "recipient" which we'll do below */
    330     cc = owl_message_get_cc_without_recipient(m);
    331     while (cc != NULL) {
    332       temp = short_zuser(cc->data);
    333       filename = g_build_filename(logpath, temp, NULL);
    334       owl_log_append(m, filename);
    335 
    336       g_free(filename);
    337       g_free(temp);
    338       g_free(cc->data);
    339       cc = g_list_delete_link(cc, cc);
    340     }
    341 
    342     to = short_zuser(owl_message_get_recipient(m));
    343   } else if (owl_message_is_type_jabber(m)) {
    344     to = g_strdup_printf("jabber:%s", owl_message_get_recipient(m));
    345     g_strdelimit(to, "/", '_');
    346   } else if (owl_message_is_type_aim(m)) {
    347     char *temp2;
    348     temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
    349     temp2 = g_utf8_strdown(temp,-1);
    350     to = g_strdup_printf("aim:%s", temp2);
    351     g_free(temp2);
    352     g_free(temp);
    353   } else {
    354     to = g_strdup("loopback");
    355   }
    356 
    357   filename = g_build_filename(logpath, to, NULL);
    358   owl_log_append(m, filename);
    359   g_free(to);
    360   g_free(filename);
    361 
    362   filename = g_build_filename(logpath, "all", NULL);
    363   owl_log_append(m, filename);
    364   g_free(logpath);
    365   g_free(filename);
    366 }
    367 
    368 
    369310void owl_log_outgoing_zephyr_error(const owl_zwrite *zw, const char *text)
    370311{
     
    414355}
    415356
    416 void owl_log_incoming(const owl_message *m)
    417 {
    418   char *filename, *allfilename, *logpath;
    419   const char *from=NULL;
    420   char *frombuff=NULL;
    421   int len, ch, i, personal;
    422 
    423   /* figure out if it's a "personal" message or not */
    424   if (owl_message_is_type_zephyr(m)) {
    425     if (owl_message_is_personal(m)) {
    426       personal = 1;
    427     } else {
    428       personal = 0;
    429     }
    430   } else if (owl_message_is_type_jabber(m)) {
    431     /* This needs to be fixed to handle groupchat */
    432     const char* msgtype = owl_message_get_attribute_value(m,"jtype");
    433     if (msgtype && !strcmp(msgtype,"groupchat")) {
    434       personal = 0;
    435     } else {
    436       personal = 1;
    437     }
    438   } else {
    439     if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
    440       personal = 1;
    441     } else {
    442       personal = 0;
    443     }
    444   }
    445 
    446 
    447   if (owl_message_is_type_zephyr(m)) {
    448     if (personal) {
    449       from=frombuff=short_zuser(owl_message_get_sender(m));
    450     } else {
    451       from=frombuff=g_strdup(owl_message_get_class(m));
    452     }
    453   } else if (owl_message_is_type_aim(m)) {
    454     /* we do not yet handle chat rooms */
    455     char *normalto, *temp;
    456     temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
    457     normalto = g_utf8_strdown(temp, -1);
    458     from=frombuff=g_strdup_printf("aim:%s", normalto);
    459     g_free(normalto);
    460     g_free(temp);
    461   } else if (owl_message_is_type_loopback(m)) {
    462     from=frombuff=g_strdup("loopback");
    463   } else if (owl_message_is_type_jabber(m)) {
    464     if (personal) {
    465       from=frombuff=g_strdup_printf("jabber:%s",
    466                                     owl_message_get_sender(m));
    467     } else {
    468       from=frombuff=g_strdup_printf("jabber:%s",
    469                                     owl_message_get_recipient(m));
    470     }
    471   } else {
    472     from=frombuff=g_strdup("unknown");
    473   }
    474  
    475   /* check for malicious sender formats */
    476   len=strlen(frombuff);
    477   if (len<1 || len>35) from="weird";
    478   if (strchr(frombuff, '/')) from="weird";
    479 
    480   ch=frombuff[0];
    481   if (!g_ascii_isalnum(ch)) from="weird";
    482 
    483   for (i=0; i<len; i++) {
    484     if (frombuff[i]<'!' || frombuff[i]>='~') from="weird";
    485   }
    486 
    487   if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird";
    488 
    489   if (!personal) {
    490     if (strcmp(from, "weird")) {
    491       char* temp = g_utf8_strdown(frombuff, -1);
    492       if (temp) {
    493         g_free(frombuff);
    494         from = frombuff = temp;
    495       }
    496     }
    497   }
    498 
    499   /* create the filename (expanding ~ in path names) */
    500   if (personal) {
    501     logpath = owl_util_makepath(owl_global_get_logpath(&g));
    502     filename = g_build_filename(logpath, from, NULL);
    503     allfilename = g_build_filename(logpath, "all", NULL);
    504     owl_log_append(m, allfilename);
    505     g_free(allfilename);
    506   } else {
    507     logpath = owl_util_makepath(owl_global_get_classlogpath(&g));
    508     filename = g_build_filename(logpath, from, NULL);
    509   }
    510 
    511   owl_log_append(m, filename);
    512   g_free(filename);
    513 
    514   if (personal && owl_message_is_type_zephyr(m)) {
    515     /* We want to log to all of the CC'd people who were not us, or
    516      * the sender, as well.
    517      */
    518     char *temp;
    519     GList *cc;
    520     cc = owl_message_get_cc_without_recipient(m);
    521     while (cc != NULL) {
    522       temp = short_zuser(cc->data);
    523       if (strcasecmp(temp, frombuff) != 0) {
    524         filename = g_build_filename(logpath, temp, NULL);
    525         owl_log_append(m, filename);
    526         g_free(filename);
    527       }
    528 
    529       g_free(temp);
    530       g_free(cc->data);
    531       cc = g_list_delete_link(cc, cc);
    532     }
    533   }
    534 
    535   g_free(frombuff);
    536   g_free(logpath);
     357void owl_log_perl(const owl_message *m)
     358{
     359  char *filenames_string = owl_perlconfig_call_with_message("BarnOwl::Logging::get_filenames_as_string", m);
     360  char **filenames = g_strsplit(filenames_string, "\n", 0);
     361  char **filename_ptr;
     362  g_free(filenames_string);
     363
     364  for (filename_ptr = filenames; *filename_ptr != NULL; filename_ptr++) {
     365    owl_log_append(m, *filename_ptr);
     366  }
     367
     368  g_strfreev(filenames);
    537369}
    538370
  • perl/Makefile.am

    r9d6e37c reea7bed4  
    1414        lib/BarnOwl/Hook.pm \
    1515        lib/BarnOwl/Hooks.pm \
     16        lib/BarnOwl/Logging.pm \
    1617        lib/BarnOwl/MainLoopCompatHook.pm \
    1718        lib/BarnOwl/Message.pm \
  • perl/lib/BarnOwl.pm

    ra619eda reea7bed4  
    3939use BarnOwl::Hook;
    4040use BarnOwl::Hooks;
     41use BarnOwl::Logging;
    4142use BarnOwl::Message;
    4243use BarnOwl::Style;
  • perl/lib/BarnOwl/Message.pm

    r7f463cf reea7bed4  
    160160        return $m->body;
    161161    }
     162}
     163
     164=head2 log_filenames MESSAGE
     165
     166Returns a list of filenames to which this message should be logged.
     167The filenames should be relative to the path returned by
     168C<log_base_path>.  See L<BarnOwl::Logging::get_filenames> for the
     169specification of valid filenames, and for what happens if this
     170method returns an invalid filename.
     171
     172=cut
     173
     174sub log_filenames {
     175    my ($m) = @_;
     176    my $filename = lc($m->type);
     177    $filename = "unknown" if !defined $filename || $filename eq '';
     178    if ($m->is_incoming && $m->pretty_sender) {
     179        $filename .= ":" . $m->pretty_sender;
     180    } elsif ($m->is_outgoing && $m->pretty_recipient) {
     181        $filename .= ":" . $m->pretty_recipient;
     182    }
     183    return ($filename);
     184}
     185
     186=head2 log_to_all_file MESSAGE
     187
     188There is an C<all> file.  This method determines if C<MESSAGE>
     189should get logged to it, in addition to any files returned by
     190C<log_filenames>.
     191
     192It defaults to returning true if and only if C<MESSAGE> is outgoing.
     193
     194=cut
     195
     196sub log_to_all_file {
     197    my ($m) = @_;
     198    return $m->is_outgoing;
     199}
     200
     201=head2 log_base_path MESSAGE
     202
     203Returns the base path for logging, the folder in which all messages
     204of this class get logged.
     205
     206Defaults to the BarnOwl variable C<logpath>.
     207
     208=cut
     209
     210sub log_base_path {
     211    return BarnOwl::getvar('logpath');
    162212}
    163213
  • perl/lib/BarnOwl/Message/AIM.pm

    r7011c3dc reea7bed4  
    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/Zephyr.pm

    r7f463cf reea7bed4  
    99
    1010use base qw( BarnOwl::Message );
     11use Unicode::Normalize qw( NFKC );
    1112
    1213sub strip_realm {
     
    132133    return $1 if $self->body =~ /^\s*cc:\s+([^\n]+)/i;
    133134    return undef;
     135}
     136
     137sub zephyr_cc_without_recipient {
     138    my $self = shift;
     139    my $recipient = lc(strip_realm($self->recipient));
     140    my $cc = $self->zephyr_cc;
     141    return grep { lc(strip_realm($_)) ne $recipient } split(/\s+/, $cc) if defined $cc;
     142    return ();
    134143}
    135144
     
    240249}
    241250
     251sub log_filenames {
     252    my ($m) = @_;
     253    my @filenames = ();
     254    if ($m->is_personal) {
     255        @filenames = $m->zephyr_cc_without_recipient;
     256    }
     257    if ($m->is_incoming) {
     258        if ($m->is_personal) {
     259            push @filenames, $m->sender;
     260        } else {
     261            return (lc(NFKC($m->class)));
     262        }
     263    } else {
     264        push @filenames, $m->recipient;
     265    }
     266    return map { lc(NFKC(strip_realm($_))) } @filenames;
     267}
     268
     269sub log_to_class_file {
     270    my ($m) = @_;
     271    return !$m->is_personal;
     272}
     273
     274sub log_base_path {
     275    my ($m) = @_;
     276    if ($m->log_to_class_file) {
     277        return BarnOwl::getvar('classlogpath');
     278    } else {
     279        return BarnOwl::getvar('logpath');
     280    }
     281}
     282
    2422831;
  • perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm

    ra27acf7 reea7bed4  
    1515
    1616use base qw( BarnOwl::Message );
     17use Unicode::Normalize qw( NFKC );
    1718
    1819sub jtype { shift->{jtype} };
     
    172173}
    173174
     175sub log_filenames {
     176    return map { lc(NFKC($_)) } BarnOwl::Message::log_filenames(@_);
     177}
     178
    174179=head1 SEE ALSO
    175180
Note: See TracChangeset for help on using the changeset viewer.