source: perl/lib/BarnOwl/Message/Zephyr.pm @ 9625c55

Last change on this file since 9625c55 was 9625c55, checked in by Jason Gross <jasongross9@gmail.com>, 7 years ago
Silence "Use of uninitialized value $realm in uc"
  • Property mode set to 100644
File size: 7.7 KB
Line 
1use strict;
2use warnings;
3
4package BarnOwl::Message::Zephyr;
5
6use constant WEBZEPHYR_PRINCIPAL => "daemon/webzephyr.mit.edu";
7use constant WEBZEPHYR_CLASS     => "webzephyr";
8use constant WEBZEPHYR_OPCODE    => "webzephyr";
9
10use base qw( BarnOwl::Message );
11
12sub strip_realm {
13    my $sender = shift;
14    my $realm = BarnOwl::zephyr_getrealm();
15    $sender =~ s/\@\Q$realm\E$//;
16    return $sender;
17}
18
19sub principal_realm {
20    my $principal = shift;
21    my ($user, $realm) = split(/@/,$principal);
22    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    $user = '' if !defined $user;
31    $user = lc($user);
32    $user = $user . uc($realm) if defined $realm;
33    return $user;
34}
35
36sub login_type {
37    return (shift->zsig eq "") ? "(PSEUDO)" : "";
38}
39
40sub login_extra {
41    my $m = shift;
42    return undef if (!$m->is_loginout);
43    my $s = lc($m->host);
44    $s .= " " . $m->login_tty if defined $m->login_tty;
45    return $s;
46}
47
48sub long_sender {
49    my $m = shift;
50    return $m->zsig;
51}
52
53sub context {
54    return shift->class;
55}
56
57sub subcontext {
58    return shift->instance;
59}
60
61sub login_tty {
62    my ($m) = @_;
63    return undef if (!$m->is_loginout);
64    return undef if (!defined($m->fields));
65    return $m->fields->[2];
66}
67
68sub login_host {
69    my ($m) = @_;
70    return undef if (!$m->is_loginout);
71    return undef if (!defined($m->fields));
72    return $m->fields->[0];
73}
74
75sub zwriteline  { return shift->{"zwriteline"}; }
76
77sub is_ping     { return (lc(shift->opcode) eq "ping"); }
78
79sub is_mail {
80    my ($m) = @_;
81    return ((lc($m->class) eq "mail") && $m->is_private);
82}
83
84sub pretty_sender {
85    my ($m) = @_;
86    return strip_realm($m->sender);
87}
88
89sub pretty_recipient {
90    my ($m) = @_;
91    return strip_realm($m->recipient);
92}
93
94# Portion of the reply command that preserves the context
95sub context_reply_cmd {
96    my $mclass = shift;
97    my $minstance = shift;
98    my @class;
99    if (lc($mclass) ne "message") {
100        @class = ('-c', $mclass);
101    }
102    my @instance;
103    if (lc($minstance) ne "personal") {
104        @instance = ('-i', $minstance);
105    }
106    return (@class, @instance);
107}
108
109sub personal_context {
110    my ($m) = @_;
111    return BarnOwl::quote(context_reply_cmd($m->class, $m->instance));
112}
113
114sub short_personal_context {
115    my ($m) = @_;
116    if(lc($m->class) eq 'message')
117    {
118        if(lc($m->instance) eq 'personal')
119        {
120            return '';
121        } else {
122            return $m->instance;
123        }
124    } else {
125        return $m->class;
126    }
127}
128
129# These are arguably zephyr-specific
130sub class       { return shift->{"class"}; }
131sub instance    { return shift->{"instance"}; }
132sub realm       { return shift->{"realm"}; }
133sub opcode      { return shift->{"opcode"}; }
134sub host        { return shift->{"hostname"}; }
135sub hostname    { return shift->{"hostname"}; }
136sub header      { return shift->{"header"}; }
137sub auth        { return shift->{"auth"}; }
138sub fields      { return shift->{"fields"}; }
139sub zsig        { return shift->{"zsig"}; }
140
141sub zephyr_cc {
142    my $self = shift;
143    return $1 if $self->body =~ /^\s*cc:\s+([^\n]+)/i;
144    return undef;
145}
146
147sub zephyr_cc_without_recipient {
148    my $self = shift;
149    my $recipient = lc(strip_realm($self->recipient));
150    my $cc = $self->zephyr_cc;
151    return grep { lc(strip_realm($_)) ne $recipient } split(/\s+/, $cc) if defined $cc;
152    return ();
153}
154
155sub replycmd {
156    my $self = shift;
157    my $sender = shift;
158    $sender = 0 unless defined $sender;
159    my ($class, $instance, $to, $cc);
160    if($self->is_outgoing) {
161        return $self->{zwriteline};
162    }
163
164    if($sender && $self->opcode eq WEBZEPHYR_OPCODE) {
165        $class = WEBZEPHYR_CLASS;
166        $instance = $self->pretty_sender;
167        $instance =~ s/-webzephyr$//;
168        $to = WEBZEPHYR_PRINCIPAL;
169    } elsif($self->class eq WEBZEPHYR_CLASS
170            && $self->is_loginout) {
171        $class = WEBZEPHYR_CLASS;
172        $instance = $self->instance;
173        $to = WEBZEPHYR_PRINCIPAL;
174    } elsif($self->is_loginout) {
175        $class = 'MESSAGE';
176        $instance = 'PERSONAL';
177        $to = $self->sender;
178    } elsif($sender && !$self->is_private) {
179        # Possible future feature: (Optionally?) include the class and/or
180        # instance of the message being replied to in the instance of the
181        # outgoing personal reply
182        $class = 'MESSAGE';
183        $instance = 'PERSONAL';
184        $to = $self->sender;
185    } else {
186        $class = $self->class;
187        $instance = $self->instance;
188        if ($self->recipient eq '' || $self->recipient =~ /^@/) {
189            $to = $self->recipient;
190        } else {
191            $to = $self->sender;
192            $cc = $self->zephyr_cc();
193        }
194    }
195
196    my @cmd;
197    if(lc $self->opcode eq 'crypt' and ( not $sender or $self->is_private)) {
198        # Responses to zcrypted messages should be zcrypted, so long as we
199        # aren't switching to personals
200        @cmd = ('zcrypt');
201    } else {
202        @cmd = ('zwrite');
203    }
204
205    push @cmd, context_reply_cmd($class, $instance);
206
207    if ($to ne '') {
208        $to = strip_realm($to);
209        if (defined $cc and not $sender) {
210            my @cc = grep /^[^-]/, ($to, split /\s+/, $cc);
211            my %cc = map {$_ => 1} @cc;
212            # this isn't quite right - it doesn't strip off the
213            # user if the message was addressed to them by fully qualified
214            # name
215            delete $cc{strip_realm(BarnOwl::zephyr_getsender())};
216            @cc = keys %cc;
217
218            my $sender_realm = principal_realm($self->sender);
219            if (BarnOwl::zephyr_getrealm() ne $sender_realm) {
220                @cc = map {
221                    if($_ !~ /@/) {
222                       "${_}\@${sender_realm}";
223                    } else {
224                        $_;
225                    }
226                } @cc;
227            }
228            push @cmd, '-C', @cc;
229        } else {
230            if(BarnOwl::getvar('smartstrip') eq 'on') {
231                $to = BarnOwl::zephyr_smartstrip_user($to);
232            }
233            push @cmd, $to;
234        }
235    }
236    return BarnOwl::quote(@cmd);
237}
238
239sub replysendercmd {
240    my $self = shift;
241    return $self->replycmd(1);
242}
243
244# Logging
245sub log_header {
246    my ($m) = @_;
247    my $class = $m->class;
248    my $instance = $m->instance;
249    my $opcode = $m->opcode;
250    my $timestr = $m->time;
251    my $host = $m->host;
252    my $sender = $m->pretty_sender;
253    my $zsig = $m->zsig;
254    my $rtn = "Class: $class Instance: $instance";
255    $rtn .= " Opcode: $opcode" unless !defined $opcode || $opcode eq '';
256    $rtn .= "\nTime: $timestr Host: $host"
257          . "\nFrom: $zsig <$sender>";
258    return $rtn;
259}
260
261sub log_filenames {
262    my ($m) = @_;
263    my @filenames = ();
264    if ($m->is_personal) {
265        @filenames = $m->zephyr_cc_without_recipient;
266    }
267    if ($m->is_incoming) {
268        if ($m->is_personal) {
269            push @filenames, $m->sender;
270        } else {
271            my $realm = '';
272            $realm .= '@' . $m->realm if $m->realm ne BarnOwl::zephyr_getrealm();
273            return (BarnOwl::compat_casefold($m->class) . uc($realm));
274        }
275    } else {
276        push @filenames, $m->recipient;
277    }
278    return map { casefold_principal(BarnOwl::zephyr_smartstrip_user(strip_realm($_))) } @filenames;
279}
280
281sub log_to_class_file {
282    my ($m) = @_;
283    return !$m->is_personal;
284}
285
286sub log_path {
287    my ($m) = @_;
288    if ($m->log_to_class_file) {
289        return BarnOwl::getvar('classlogpath');
290    } else {
291        return BarnOwl::getvar('logpath');
292    }
293}
294
295sub should_log {
296    my ($m) = @_;
297    if ($m->log_to_class_file) {
298        return BarnOwl::getvar('classlogging') eq 'on';
299    } else {
300        return BarnOwl::getvar('logging') eq 'on';
301    }
302}
303
3041;
Note: See TracBrowser for help on using the repository browser.