source: perlwrap.pm @ 00f9a7d

barnowl_perlaimdebianrelease-1.10release-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 00f9a7d was 00f9a7d, checked in by Nelson Elhage <nelhage@mit.edu>, 17 years ago
Bring back the -c option, and no longer choke if .owlconf doesn't return true.
  • Property mode set to 100644
File size: 12.0 KB
RevLine 
[f1e629d]1# $Id$
2#
3# This is all linked into the binary and evaluated when perl starts up...
4#
5#####################################################################
6#####################################################################
7
8package owl;
9
[8862725]10
11BEGIN {
[f1e629d]12# bootstrap in C bindings and glue
[23be736]13    bootstrap owl 1.2;
[8862725]14};
15
16use lib(get_data_dir()."/owl/lib");
17use lib($::ENV{'HOME'}."/.owl/lib");
18
[f1e629d]19
[00f9a7d]20our $configfile;
21
22$configfile ||= $::ENV{'HOME'}."/.owlconf";
[d03091c]23
[f1e629d]24# populate global variable space for legacy owlconf files
25sub _format_msg_legacy_wrap {
26    my ($m) = @_;
27    $m->legacy_populate_global();
28    return &owl::format_msg($m);
29}
30
31# populate global variable space for legacy owlconf files
32sub _receive_msg_legacy_wrap {
33    my ($m) = @_;
34    $m->legacy_populate_global();
35    return &owl::receive_msg($m);
36}
37
38# make owl::<command>("foo") be aliases to owl::command("<command> foo");
39sub AUTOLOAD {
40    my $called = $AUTOLOAD;
41    $called =~ s/.*:://;
[e7ac2b6]42    $called =~ s/_/-/g;
[f1e629d]43    return &owl::command("$called ".join(" ",@_));
44}
45
[6922edd]46=head2 new_command NAME FUNC [{ARGS}]
47
48Add a new owl command. When owl executes the command NAME, FUNC will
49be called with the arguments passed to the command, with NAME as the
50first argument.
51
52ARGS should be a hashref containing any or all of C<summary>,
53C<usage>, or C<description> keys.
54
55=cut
56
57sub new_command {
58    my $name = shift;
59    my $func = shift;
60    my $args = shift || {};
61    my %args = (
62        summary     => undef,
63        usage       => undef,
64        description => undef,
65        %{$args}
66    );
67
68    owl::new_command_internal($name, $func, $args{summary}, $args{usage}, $args{description});
69}
70
[f1e629d]71#####################################################################
72#####################################################################
73
74package owl::Message;
75
[dd16bdd]76sub new {
77    my $class = shift;
78    my %args = (@_);
79    if($class eq __PACKAGE__ && $args{type}) {
80        $class = "owl::Message::" . ucfirst $args{type};
81    }
82    return bless {%args}, $class;
83}
84
[f1e629d]85sub type        { return shift->{"type"}; }
86sub direction   { return shift->{"direction"}; }
87sub time        { return shift->{"time"}; }
88sub id          { return shift->{"id"}; }
89sub body        { return shift->{"body"}; }
90sub sender      { return shift->{"sender"}; }
91sub recipient   { return shift->{"recipient"}; }
92sub login       { return shift->{"login"}; }
[216c734]93sub is_private  { return shift->{"private"}; }
[f1e629d]94
95sub is_login    { return shift->login eq "login"; }
96sub is_logout   { return shift->login eq "logout"; }
97sub is_loginout { my $m=shift; return ($m->is_login or $m->is_logout); }
98sub is_incoming { return (shift->{"direction"} eq "in"); }
99sub is_outgoing { return (shift->{"direction"} eq "out"); }
100
101sub is_deleted  { return shift->{"deleted"}; }
102
103sub is_admin    { return (shift->{"type"} eq "admin"); }
104sub is_generic  { return (shift->{"type"} eq "generic"); }
[421c8ef7]105sub is_zephyr   { return (shift->{"type"} eq "zephyr"); }
106sub is_aim      { return (shift->{"type"} eq "aim"); }
[dd16bdd]107sub is_jabber   { return (shift->{"type"} eq "jabber"); }
[421c8ef7]108sub is_icq      { return (shift->{"type"} eq "icq"); }
109sub is_yahoo    { return (shift->{"type"} eq "yahoo"); }
110sub is_msn      { return (shift->{"type"} eq "msn"); }
111sub is_loopback { return (shift->{"type"} eq "loopback"); }
[f1e629d]112
113# These are overridden by appropriate message types
114sub is_ping     { return 0; }
115sub is_mail     { return 0; }
[3c9012b]116sub is_personal { return shift->is_private; }
[f1e629d]117sub class       { return undef; }
118sub instance    { return undef; }
119sub realm       { return undef; }
120sub opcode      { return undef; }
121sub header      { return undef; }
122sub host        { return undef; }
123sub hostname    { return undef; }
124sub auth        { return undef; }
125sub fields      { return undef; }
126sub zsig        { return undef; }
127sub zwriteline  { return undef; }
[87c6ef1]128sub login_host  { return undef; }
129sub login_tty   { return undef; }
[f1e629d]130
131sub pretty_sender { return shift->sender; }
132
133sub delete {
134    my ($m) = @_;
135    &owl::command("delete --id ".$m->id);
136}
137
138sub undelete {
139    my ($m) = @_;
140    &owl::command("undelete --id ".$m->id);
141}
142
143# Serializes the message into something similar to the zwgc->vt format
144sub serialize {
145    my ($this) = @_;
146    my $s;
147    for my $f (keys %$this) {
148        my $val = $this->{$f};
149        if (ref($val) eq "ARRAY") {
150            for my $i (0..@$val-1) {
151                my $aval;
152                $aval = $val->[$i];
153                $aval =~ s/\n/\n$f.$i: /g;
154                $s .= "$f.$i: $aval\n";   
155            }
156        } else {
157            $val =~ s/\n/\n$f: /g;
158            $s .= "$f: $val\n";
159        }
160    }
161    return $s;
162}
163
164# Populate the annoying legacy global variables
165sub legacy_populate_global {
166    my ($m) = @_;
167    $owl::direction  = $m->direction ;
168    $owl::type       = $m->type      ;
169    $owl::id         = $m->id        ;
170    $owl::class      = $m->class     ;
171    $owl::instance   = $m->instance  ;
172    $owl::recipient  = $m->recipient ;
173    $owl::sender     = $m->sender    ;
174    $owl::realm      = $m->realm     ;
175    $owl::opcode     = $m->opcode    ;
176    $owl::zsig       = $m->zsig      ;
177    $owl::msg        = $m->body      ;
178    $owl::time       = $m->time      ;
179    $owl::host       = $m->host      ;
[282ec9b]180    $owl::login      = $m->login     ;
[87c6ef1]181    $owl::auth       = $m->auth      ;
[f1e629d]182    if ($m->fields) {
183        @owl::fields = @{$m->fields};
184        @main::fields = @{$m->fields};
185    } else {
186        @owl::fields = undef;
187        @main::fields = undef;
188    }
189}
190
[25729b2]191sub smartfilter {
192    die("smartfilter not supported for this message");
193}
194
[f1e629d]195#####################################################################
196#####################################################################
197
198package owl::Message::Admin;
199
200@ISA = qw( owl::Message );
201
202sub header       { return shift->{"header"}; }
203
204#####################################################################
205#####################################################################
206
207package owl::Message::Generic;
208
209@ISA = qw( owl::Message );
210
211#####################################################################
212#####################################################################
213
214package owl::Message::AIM;
215
216@ISA = qw( owl::Message );
217
218# all non-loginout AIM messages are personal for now...
219sub is_personal { 
220    return !(shift->is_loginout);
221}
222
223#####################################################################
224#####################################################################
225
226package owl::Message::Zephyr;
227
228@ISA = qw( owl::Message );
229
230sub login_tty { 
231    my ($m) = @_;
232    return undef if (!$m->is_loginout);
233    return $m->fields->[2];
234}
235
236sub login_host { 
237    my ($m) = @_;
238    return undef if (!$m->is_loginout);
239    return $m->fields->[0];
240}
241
242sub zwriteline  { return shift->{"zwriteline"}; }
243
244sub zsig        { return shift->{"zsig"}; }
245
246sub is_ping     { return (lc(shift->opcode) eq "ping"); }
247
248sub is_personal { 
249    my ($m) = @_;
250    return ((lc($m->class) eq "message")
251            && (lc($m->instance) eq "personal")
252            && $m->is_private);
253}
254
255sub is_mail { 
256    my ($m) = @_;
257    return ((lc($m->class) eq "mail") && $m->is_private);
258}
259
260sub pretty_sender {
261    my ($m) = @_;
262    my $sender = $m->sender;
263    my $realm = owl::zephyr_getrealm();
264    $sender =~ s/\@$realm$//;
265    return $sender;
266}
267
268# These are arguably zephyr-specific
269sub class       { return shift->{"class"}; }
270sub instance    { return shift->{"instance"}; }
271sub realm       { return shift->{"realm"}; }
272sub opcode      { return shift->{"opcode"}; }
273sub host        { return shift->{"hostname"}; }
274sub hostname    { return shift->{"hostname"}; }
275sub header      { return shift->{"header"}; }
276sub auth        { return shift->{"auth"}; }
277sub fields      { return shift->{"fields"}; }
278sub zsig        { return shift->{"zsig"}; }
279
280#####################################################################
281#####################################################################
[7e470da]282################################################################################
283package owl;
284
[f2f5815]285# Arrays of subrefs to be called at specific times.
[7e470da]286our @onStartSubs = ();
[f2f5815]287our @onReceiveMsg = ();
288our @onMainLoop = ();
289our @onGetBuddyList = ();
[7e470da]290
291################################################################################
292# Mainloop hook and threading.
293################################################################################
294
295use threads;
296use threads::shared;
297
298# Shared thread shutdown flag.
299# Consider adding a reload flag, so threads that should persist across reloads
300# can distinguish the two events. We wouldn't want a reload to cause us to
301# log out of and in to a perl-based IM session.
302our $shutdown : shared;
303$shutdown = 0;
304our $reload : shared;
305$reload = 0;
306
[f2f5815]307# Functions to call hook lists
308sub runHook($@)
[7e470da]309{
[f2f5815]310    my $hook = shift;
311    my @args = @_;
312    $_->(@args) for (@$hook);
313}
314
315sub runHook_accumulate($@)
316{
317    my $hook = shift;
318    my @args = @_;
319    return join("\n", map {$_->(@args)} @$hook);
320}
321
322sub mainloop_hook
323{
324    runHook(\@onMainLoop);
[7e470da]325}
326
327################################################################################
328# Startup and Shutdown code
329################################################################################
[f2f5815]330sub startup
[7e470da]331{
332# Modern versions of owl provides a great place to have startup stuff.
333# Put things in ~/.owl/startup
334    onStart();
335}
336
[f2f5815]337sub shutdown
[7e470da]338{
339# Modern versions of owl provides a great place to have shutdown stuff.
340# Put things in ~/.owl/shutdown
341
342# At this point I use owl::shutdown to tell any auxillary threads that they
343# should terminate.
344    $shutdown = 1;
[f2f5815]345    mainloop_hook();
[7e470da]346}
347
348#Run this on start and reload. Adds modules and runs their startup functions.
349sub onStart
350{
351    reload_init();
352    #So that the user's .owlconf can have startsubs, we don't clear
353    #onStartSubs; reload does however
354    @onReceiveMsg = ();
355    @onMainLoop = ();
356    @onGetBuddyList = ();
357
358    loadModules();
[f2f5815]359    runHook(\@onStartSubs);
[7e470da]360}
361################################################################################
362# Reload Code, taken from /afs/sipb/user/jdaniel/project/owl/perl
363################################################################################
364sub reload_hook (@) 
365{
366   
[3d18b30]367
[7e470da]368    onStart();
369    return 1;
370}
371
372sub reload 
373{
374    # Shutdown existing threads.
375    $reload = 1;
376    owl::mainloop_hook();
377    $reload = 0;
378    @onMainLoop = ();
[23be736]379    @onStartSubs = ();
[7e470da]380   
381    # Do reload
[591ea418]382    package main;
383    if (do "$ENV{HOME}/.owlconf" && owl::reload_hook(@_))
[7e470da]384    {
[23be736]385        return "owlconf reloaded";
[7e470da]386    } 
387    else
388    {
389        return "$ENV{HOME}/.owlconf load attempted, but error encountered:\n$@";
390    }
[23be736]391    package owl;
[7e470da]392}
393
394sub reload_init () 
395{
[591ea418]396    owl::command('alias reload perl owl::reload()');
[7e470da]397    owl::command('bindkey global "C-x C-r" command reload');
398}
399
400################################################################################
401# Loads modules from ~/.owl/modules and owl's data directory
402################################################################################
403
[f2f5815]404sub loadModules () {
405    my @modules;
[23be736]406    my $rv;
[f2f5815]407    foreach my $dir ( owl::get_data_dir() . "/owl/modules",
[23be736]408                      $ENV{HOME} . "/.owl/modules" )
[f2f5815]409    {
410        opendir( MODULES, $dir );
411
412        # source ./modules/*.pl
413        @modules = grep( /\.pl$/, readdir(MODULES) );
414
415        foreach my $mod (@modules) {
[23be736]416            unless ($rv = do "$dir/$mod") {
417                owl::error("Couldn't load $dir/$mod:\n $@") if $@;
418                owl::error("Couldn't run $dir/$mod:\n $!") unless defined $rv;
419            }
[f2f5815]420        }
421        closedir(MODULES);
422    }
[7e470da]423}
424
425
[f2f5815]426
[7e470da]427################################################################################
428# Hooks into receive_msg()
429################################################################################
430
[f2f5815]431sub receive_msg
[7e470da]432{
433    my $m = shift;
[f2f5815]434    runHook(\@onReceiveMsg, $m);
[7e470da]435}
436
437################################################################################
438# Hooks into get_blist()
439################################################################################
440
[f2f5815]441sub get_blist
[7e470da]442{
443    my $m = shift;
[f2f5815]444    return runHook_accumulate(\@onGetBuddyList, $m);
[7e470da]445}
[dd16bdd]446
[f1e629d]447# switch to package main when we're done
448package main;
[7e470da]449# alias the hooks
450foreach my $hook  qw (onStartSubs
451onReceiveMsg
452onMainLoop
453onGetBuddyList ) {
454  *{"main::".$hook} = \*{"owl::".$hook};
455}
[f1e629d]456
[d03091c]457# load the config  file
458if (-r $owl::configfile) {
[00f9a7d]459    undef $!;
460    undef $@;
461    do $owl::configfile;
462    die $@ if $@;
463    die $! if $!;
[d03091c]464}
465
[f1e629d]4661;
Note: See TracBrowser for help on using the repository browser.