Changeset 5832433
- Timestamp:
- Aug 8, 2013, 5:00:24 PM (12 years ago)
- Parents:
- ecd4edf (diff), f421190 (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. - Files:
-
- 9 added
- 50 deleted
- 54 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm
r8258ea5 r5832433 16 16 use BarnOwl; 17 17 use BarnOwl::Hooks; 18 use BarnOwl::Message::Jabber;19 use BarnOwl::Module::Jabber::Connection;20 use BarnOwl::Module::Jabber::ConnectionManager;21 use BarnOwl::Completion::Util qw(complete_flags);22 23 use Authen::SASL qw(Perl);24 use Net::Jabber;25 use Net::Jabber::MUC;26 use Net::DNS;27 use Getopt::Long;28 Getopt::Long::Configure(qw(no_getopt_compat prefix_pattern=-|--));29 18 30 19 use utf8; … … 32 21 our $VERSION = 0.1; 33 22 34 BEGIN { 35 if(eval {require IO::Socket::SSL;}) { 36 if($IO::Socket::SSL::VERSION eq "0.97") { 37 BarnOwl::error("You are using IO::Socket:SSL 0.97, which \n" . 38 "contains bugs causing it not to work with BarnOwl's\n" .39 "Jabber support. We recommend updating to the latest\n" .40 "IO::Socket::SSL from CPAN. \n");41 die("Not loading Jabber.par\n");42 }23 our $impl_loaded; 24 $impl_loaded = 0 unless defined($impl_loaded); 25 26 sub _load_impl { 27 unless ($impl_loaded) { 28 BarnOwl::debug("_load_impl"); 29 require BarnOwl::Module::Jabber::Impl; 30 $impl_loaded = 1; 31 BarnOwl::Module::Jabber::Impl::onStart(); 43 32 } 44 33 } 45 46 no warnings 'redefine';47 48 ################################################################################49 # owl perl jabber support50 #51 # XXX Todo:52 # Rosters for MUCs53 # More user feedback54 # * joining MUC55 # * parting MUC56 # * presence (Roster and MUC)57 # Implementing formatting and logging callbacks for C58 # Appropriate callbacks for presence subscription messages.59 #60 ################################################################################61 62 our $conn;63 $conn ||= BarnOwl::Module::Jabber::ConnectionManager->new;64 our %vars;65 our %completion_jids;66 34 67 35 sub onStart { … … 70 38 register_keybindings(); 71 39 register_filters(); 72 $BarnOwl::Hooks::getBuddyList->add("BarnOwl::Module::Jabber::onGetBuddyList");73 40 $BarnOwl::Hooks::getQuickstart->add("BarnOwl::Module::Jabber::onGetQuickstart"); 74 $vars{show} = ''; 41 75 42 BarnOwl::new_variable_bool("jabber:show_offline_buddies", 76 43 { default => 1, … … 94 61 summary => 'Auto-reconnect when disconnected from servers.' 95 62 }); 96 # Force these. Reload can screw them up. 97 # Taken from Net::Jabber::Protocol.98 $Net::XMPP::Protocol::NEWOBJECT{'iq'} = "Net::Jabber::IQ";99 $Net::XMPP::Protocol::NEWOBJECT{'message'} = "Net::Jabber::Message";100 $Net::XMPP::Protocol::NEWOBJECT{'presence'} = "Net::Jabber::Presence";101 $Net::XMPP::Protocol::NEWOBJECT{'jid'} = "Net::Jabber::JID";63 64 # If we're called as part of module reload, let Impl's reload 65 # code run too. 66 if ($impl_loaded) { 67 BarnOwl::Module::Jabber::Impl::onStart(); 68 } 102 69 } else { 103 70 # Our owl doesn't support queue_message. Unfortunately, this … … 109 76 $BarnOwl::Hooks::startup->add("BarnOwl::Module::Jabber::onStart"); 110 77 111 sub do_keep_alive_and_auto_away { 112 if ( !$conn->connected() ) { 113 # We don't need this timer any more. 114 if (defined $vars{keepAliveTimer}) { 115 $vars{keepAliveTimer}->stop; 116 } 117 delete $vars{keepAliveTimer}; 118 return; 119 } 120 121 $vars{status_changed} = 0; 122 my $auto_away = BarnOwl::getvar('jabber:auto_away_timeout'); 123 my $auto_xa = BarnOwl::getvar('jabber:auto_xa_timeout'); 124 my $idletime = BarnOwl::getidletime(); 125 if ($auto_xa != 0 && $idletime >= (60 * $auto_xa) && ($vars{show} eq 'away' || $vars{show} eq '' )) { 126 $vars{show} = 'xa'; 127 $vars{status} = 'Auto extended-away after '.$auto_xa.' minute'.($auto_xa == 1 ? '' : 's').' idle.'; 128 $vars{status_changed} = 1; 129 } elsif ($auto_away != 0 && $idletime >= (60 * $auto_away) && $vars{show} eq '') { 130 $vars{show} = 'away'; 131 $vars{status} = 'Auto away after '.$auto_away.' minute'.($auto_away == 1 ? '' : 's').' idle.'; 132 $vars{status_changed} = 1; 133 } elsif ($idletime <= $vars{idletime} && $vars{show} ne '') { 134 $vars{show} = ''; 135 $vars{status} = ''; 136 $vars{status_changed} = 1; 137 } 138 $vars{idletime} = $idletime; 139 140 foreach my $jid ( $conn->getJIDs() ) { 141 next if $conn->jidActive($jid); 142 $conn->tryReconnect($jid); 143 } 144 145 foreach my $jid ( $conn->getJIDs() ) { 146 next unless $conn->jidActive($jid); 147 148 my $client = $conn->getConnectionFromJID($jid); 149 unless($client) { 150 $conn->removeConnection($jid); 151 BarnOwl::error("Connection for $jid undefined -- error in reload?"); 152 } 153 my $status = $client->Process(0); # keep-alive 154 if ( !defined($status) ) { 155 $conn->scheduleReconnect($jid); 156 } 157 if ($::shutdown) { 158 do_logout($jid); 159 next; 160 } 161 162 if ($vars{status_changed}) { 163 my $p = new Net::Jabber::Presence; 164 $p->SetShow($vars{show}) if $vars{show}; 165 $p->SetStatus($vars{status}) if $vars{status}; 166 $client->Send($p); 167 } 78 sub _make_stub { 79 my $func = shift; 80 return sub { 81 _load_impl(); 82 no strict 'refs'; 83 &{"BarnOwl::Module::Jabber::Impl::$func"}; 168 84 } 169 85 } 170 86 171 our $showOffline = 0;172 173 sub blist_listBuddy {174 my $roster = shift;175 my $buddy = shift;176 my $blistStr .= " ";177 my %jq = $roster->query($buddy);178 my $res = $roster->resource($buddy);179 180 my $name = $jq{name} || $buddy->GetUserID();181 182 $blistStr .= sprintf '%-15s %s', $name, $buddy->GetJID();183 $completion_jids{$name} = 1;184 $completion_jids{$buddy->GetJID()} = 1;185 186 if ($res) {187 my %rq = $roster->resourceQuery( $buddy, $res );188 $blistStr .= " [" . ( $rq{show} ? $rq{show} : 'online' ) . "]";189 $blistStr .= " " . $rq{status} if $rq{status};190 $blistStr = BarnOwl::Style::boldify($blistStr) if $showOffline;191 }192 else {193 return '' unless $showOffline;194 if ($jq{ask}) {195 $blistStr .= " [pending]";196 }197 elsif ($jq{subscription} eq 'none' || $jq{subscription} eq 'from') {198 $blistStr .= " [not subscribed]";199 }200 else {201 $blistStr .= " [offline]";202 }203 }204 return $blistStr . "\n";205 }206 207 # Sort, ignoring markup.208 sub blistSort {209 return uc(BarnOwl::ztext_stylestrip($a)) cmp uc(BarnOwl::ztext_stylestrip($b));210 }211 212 sub getSingleBuddyList {213 my $jid = shift;214 $jid = resolveConnectedJID($jid);215 return "" unless $jid;216 my $blist = "";217 my $roster = $conn->getRosterFromJID($jid);218 if ($roster) {219 $blist .= BarnOwl::Style::boldify("Jabber roster for $jid\n");220 221 my @gTexts = ();222 foreach my $group ( $roster->groups() ) {223 my @buddies = $roster->jids( 'group', $group );224 my @bTexts = ();225 foreach my $buddy ( @buddies ) {226 push(@bTexts, blist_listBuddy( $roster, $buddy ));227 }228 push(@gTexts, " Group: $group\n".join('',sort blistSort @bTexts));229 }230 # Sort groups before adding ungrouped entries.231 @gTexts = sort blistSort @gTexts;232 233 my @unsorted = $roster->jids('nogroup');234 if (@unsorted) {235 my @bTexts = ();236 foreach my $buddy (@unsorted) {237 push(@bTexts, blist_listBuddy( $roster, $buddy ));238 }239 push(@gTexts, " [unsorted]\n".join('',sort blistSort @bTexts));240 }241 $blist .= join('', @gTexts);242 }243 return $blist;244 }245 246 sub onGetBuddyList {247 $showOffline = BarnOwl::getvar('jabber:show_offline_buddies') eq 'on';248 my $blist = "";249 foreach my $jid ($conn->getJIDs()) {250 $blist .= getSingleBuddyList($jid);251 }252 return $blist;253 }254 255 sub onGetQuickstart {256 return <<'EOF'257 @b(Jabber:)258 Type ':jabberlogin @b(username@mit.edu)' to log in to Jabber. The command259 ':jroster sub @b(somebody@gmail.com)' will request that they let you message260 them. Once you get a message saying you are subscribed, you can message261 them by typing ':jwrite @b(somebody@gmail.com)' or just 'j @b(somebody)'.262 EOF263 }264 265 ################################################################################266 ### Owl Commands267 87 sub register_owl_commands() { 268 88 BarnOwl::new_command( 269 jabberlogin => \&cmd_login,89 jabberlogin => _make_stub("cmd_login"), 270 90 { 271 91 summary => "Log in to Jabber", … … 274 94 ); 275 95 BarnOwl::new_command( 276 jabberlogout => \&cmd_logout,96 jabberlogout => _make_stub("cmd_logout"), 277 97 { 278 98 summary => "Log out of Jabber", … … 285 105 ); 286 106 BarnOwl::new_command( 287 jwrite => \&cmd_jwrite,107 jwrite => _make_stub("cmd_jwrite"), 288 108 { 289 109 summary => "Send a Jabber Message", … … 292 112 ); 293 113 BarnOwl::new_command( 294 jaway => \&cmd_jaway,114 jaway => _make_stub("cmd_jaway"), 295 115 { 296 116 summary => "Set Jabber away / presence information", … … 299 119 ); 300 120 BarnOwl::new_command( 301 jlist => \&cmd_jlist,121 jlist => _make_stub("cmd_jlist"), 302 122 { 303 123 summary => "Show your Jabber roster.", … … 306 126 ); 307 127 BarnOwl::new_command( 308 jmuc => \&cmd_jmuc,128 jmuc => _make_stub("cmd_jmuc"), 309 129 { 310 130 summary => "Jabber MUC related commands.", … … 332 152 ); 333 153 BarnOwl::new_command( 334 jroster => \&cmd_jroster,154 jroster => _make_stub("cmd_jroster"), 335 155 { 336 156 summary => "Jabber roster related commands.", … … 366 186 } 367 187 368 sub cmd_login { 369 my $cmd = shift; 370 my $jidStr = shift; 371 my $jid = new Net::Jabber::JID; 372 $jid->SetJID($jidStr); 373 my $password = ''; 374 $password = shift if @_; 375 376 my $uid = $jid->GetUserID(); 377 my $componentname = $jid->GetServer(); 378 my $resource = $jid->GetResource(); 379 380 if ($resource eq '') { 381 my $cjidStr = $conn->baseJIDExists($jidStr); 382 if ($cjidStr) { 383 die("Already logged in as $cjidStr.\n"); 384 } 385 } 386 387 $resource ||= 'barnowl'; 388 $jid->SetResource($resource); 389 $jidStr = $jid->GetJID('full'); 390 391 if ( !$uid || !$componentname ) { 392 die("usage: $cmd JID\n"); 393 } 394 395 if ( $conn->jidActive($jidStr) ) { 396 die("Already logged in as $jidStr.\n"); 397 } elsif ($conn->jidExists($jidStr)) { 398 return $conn->tryReconnect($jidStr, 1); 399 } 400 401 my ( $server, $port ) = getServerFromJID($jid); 402 403 $vars{jlogin_jid} = $jidStr; 404 $vars{jlogin_connhash} = { 405 hostname => $server, 406 tls => 1, 407 port => $port, 408 componentname => $componentname 409 }; 410 $vars{jlogin_authhash} = 411 { username => $uid, 412 resource => $resource, 413 }; 414 415 return do_login($password); 188 sub onGetQuickstart { 189 return <<'EOF' 190 @b(Jabber:) 191 Type ':jabberlogin @b(username@mit.edu)' to log in to Jabber. The command 192 ':jroster sub @b(somebody@gmail.com)' will request that they let you message 193 them. Once you get a message saying you are subscribed, you can message 194 them by typing ':jwrite @b(somebody@gmail.com)' or just 'j @b(somebody)'. 195 EOF 416 196 } 417 197 418 sub do_login {419 $vars{jlogin_password} = shift;420 $vars{jlogin_authhash}->{password} = sub { return $vars{jlogin_password} || '' };421 my $jidStr = $vars{jlogin_jid};422 if ( !$jidStr && $vars{jlogin_havepass}) {423 BarnOwl::error("Got password but have no JID!");424 }425 else426 {427 my $client = $conn->addConnection($jidStr);428 429 #XXX Todo: Add more callbacks.430 # * MUC presence handlers431 # We use the anonymous subrefs in order to have the correct behavior432 # when we reload433 $client->SetMessageCallBacks(434 chat => sub { BarnOwl::Module::Jabber::process_incoming_chat_message(@_) },435 error => sub { BarnOwl::Module::Jabber::process_incoming_error_message(@_) },436 groupchat => sub { BarnOwl::Module::Jabber::process_incoming_groupchat_message(@_) },437 headline => sub { BarnOwl::Module::Jabber::process_incoming_headline_message(@_) },438 normal => sub { BarnOwl::Module::Jabber::process_incoming_normal_message(@_) }439 );440 $client->SetPresenceCallBacks(441 available => sub { BarnOwl::Module::Jabber::process_presence_available(@_) },442 unavailable => sub { BarnOwl::Module::Jabber::process_presence_available(@_) },443 subscribe => sub { BarnOwl::Module::Jabber::process_presence_subscribe(@_) },444 subscribed => sub { BarnOwl::Module::Jabber::process_presence_subscribed(@_) },445 unsubscribe => sub { BarnOwl::Module::Jabber::process_presence_unsubscribe(@_) },446 unsubscribed => sub { BarnOwl::Module::Jabber::process_presence_unsubscribed(@_) },447 error => sub { BarnOwl::Module::Jabber::process_presence_error(@_) });448 449 my $status = $client->Connect( %{ $vars{jlogin_connhash} } );450 if ( !$status ) {451 $conn->removeConnection($jidStr);452 BarnOwl::error("We failed to connect.");453 } else {454 my @result = $client->AuthSend( %{ $vars{jlogin_authhash} } );455 456 if ( !@result || $result[0] ne 'ok' ) {457 if ( !$vars{jlogin_havepass} && ( !@result || $result[0] eq '401' || $result[0] eq 'error') ) {458 $vars{jlogin_havepass} = 1;459 $conn->removeConnection($jidStr);460 BarnOwl::start_password("Password for $jidStr: ", \&do_login );461 return "";462 }463 $conn->removeConnection($jidStr);464 BarnOwl::error( "Error in connect: " . join( " ", @result ) );465 } else {466 $conn->setAuth(467 $jidStr,468 { %{ $vars{jlogin_authhash} },469 password => $vars{jlogin_password}470 }471 );472 $client->onConnect($conn, $jidStr);473 }474 }475 }476 delete $vars{jlogin_jid};477 $vars{jlogin_password} =~ tr/\0-\377/x/ if $vars{jlogin_password};478 delete $vars{jlogin_password};479 delete $vars{jlogin_havepass};480 delete $vars{jlogin_connhash};481 delete $vars{jlogin_authhash};482 483 return "";484 }485 486 sub do_logout {487 my $jid = shift;488 my $disconnected = $conn->removeConnection($jid);489 queue_admin_msg("Jabber disconnected ($jid).") if $disconnected;490 }491 492 sub cmd_logout {493 return "You are not logged into Jabber." unless ($conn->connected() > 0);494 # Logged into multiple accounts495 if ( $conn->connected() > 1 ) {496 # Logged into multiple accounts, no accout specified.497 if ( !$_[1] ) {498 my $errStr =499 "You are logged into multiple accounts. Please specify an account to log out of.\n";500 foreach my $jid ( $conn->getJIDs() ) {501 $errStr .= "\t$jid\n";502 }503 queue_admin_msg($errStr);504 }505 # Logged into multiple accounts, account specified.506 else {507 if ( $_[1] eq '-A' ) #All accounts.508 {509 foreach my $jid ( $conn->getJIDs() ) {510 do_logout($jid);511 }512 }513 else #One account.514 {515 my $jid = resolveConnectedJID( $_[1] );516 do_logout($jid) if ( $jid ne '' );517 }518 }519 }520 else # Only one account logged in.521 {522 do_logout( ( $conn->getJIDs() )[0] );523 }524 return "";525 }526 527 sub cmd_jlist {528 if ( !( scalar $conn->getJIDs() ) ) {529 die("You are not logged in to Jabber.\n");530 }531 BarnOwl::popless_ztext( onGetBuddyList() );532 }533 534 sub cmd_jwrite {535 if ( !$conn->connected() ) {536 die("You are not logged in to Jabber.\n");537 }538 539 my $jwrite_to = "";540 my $jwrite_from = "";541 my $jwrite_sid = "";542 my $jwrite_thread = "";543 my $jwrite_subject = "";544 my $jwrite_body;545 my ($to, $from);546 my $jwrite_type = "chat";547 548 my @args = @_;549 shift;550 local @ARGV = @_;551 my $gc;552 GetOptions(553 'thread=s' => \$jwrite_thread,554 'subject=s' => \$jwrite_subject,555 'account=s' => \$from,556 'id=s' => \$jwrite_sid,557 'message=s' => \$jwrite_body,558 ) or die("Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]\n");559 $jwrite_type = 'groupchat' if $gc;560 561 if ( scalar @ARGV != 1 ) {562 die("Usage: jwrite <jid> [-t <thread>] [-s <subject>] [-a <account>]\n");563 }564 else {565 $to = shift @ARGV;566 }567 568 my @candidates = guess_jwrite($from, $to);569 570 unless(scalar @candidates) {571 die("Unable to resolve JID $to\n");572 }573 574 @candidates = grep {defined $_->[0]} @candidates;575 576 unless(scalar @candidates) {577 if(!$from) {578 die("You must specify an account with -a\n");579 } else {580 die("Unable to resolve account $from\n");581 }582 }583 584 585 ($jwrite_from, $jwrite_to, $jwrite_type) = @{$candidates[0]};586 587 $vars{jwrite} = {588 to => $jwrite_to,589 from => $jwrite_from,590 sid => $jwrite_sid,591 subject => $jwrite_subject,592 thread => $jwrite_thread,593 type => $jwrite_type594 };595 596 if (defined($jwrite_body)) {597 process_owl_jwrite($jwrite_body);598 return;599 }600 601 if(scalar @candidates > 1) {602 BarnOwl::message(603 "Warning: Guessing account and/or destination JID"604 );605 } else {606 BarnOwl::message(607 "Type your message below. End with a dot on a line by itself. ^C will quit."608 );609 }610 611 my @cmd = ('jwrite', $jwrite_to, '-a', $jwrite_from);612 push @cmd, '-t', $jwrite_thread if $jwrite_thread;613 push @cmd, '-s', $jwrite_subject if $jwrite_subject;614 615 BarnOwl::start_edit_win(BarnOwl::quote(@cmd), \&process_owl_jwrite);616 }617 618 sub cmd_jmuc {619 die "You are not logged in to Jabber" unless $conn->connected();620 my $ocmd = shift;621 my $cmd = shift;622 if ( !$cmd ) {623 624 #XXX TODO: Write general usage for jmuc command.625 return;626 }627 628 my %jmuc_commands = (629 join => \&jmuc_join,630 part => \&jmuc_part,631 invite => \&jmuc_invite,632 configure => \&jmuc_configure,633 presence => \&jmuc_presence634 );635 my $func = $jmuc_commands{$cmd};636 if ( !$func ) {637 die("jmuc: Unknown command: $cmd\n");638 }639 640 {641 local @ARGV = @_;642 my $jid;643 my $muc;644 my $m = BarnOwl::getcurmsg();645 if ( $m && $m->is_jabber && $m->{jtype} eq 'groupchat' ) {646 $muc = $m->{room};647 $jid = $m->{to};648 }649 650 my $getopt = Getopt::Long::Parser->new;651 $getopt->configure('pass_through', 'no_getopt_compat');652 $getopt->getoptions( 'account=s' => \$jid );653 $jid ||= defaultJID();654 if ($jid) {655 $jid = resolveConnectedJID($jid);656 return unless $jid;657 }658 else {659 die("You must specify an account with -a <jid>\n");660 }661 return $func->( $jid, $muc, @ARGV );662 }663 }664 665 sub jmuc_join {666 my ( $jid, $muc, @args ) = @_;667 local @ARGV = @args;668 my $password;669 GetOptions( 'password=s' => \$password );670 671 $muc = shift @ARGV672 or die("Usage: jmuc join <muc> [-p <password>] [-a <account>]\n");673 674 die("Error: Must specify a fully-qualified MUC name (e.g. barnowl\@conference.mit.edu)\n")675 unless $muc =~ /@/;676 $muc = Net::Jabber::JID->new($muc);677 $jid = Net::Jabber::JID->new($jid);678 $muc->SetResource($jid->GetJID('full')) unless length $muc->GetResource();679 680 $conn->getConnectionFromJID($jid)->MUCJoin(JID => $muc,681 Password => $password,682 History => {683 MaxChars => 0684 });685 $completion_jids{$muc->GetJID('base')} = 1;686 return;687 }688 689 sub jmuc_part {690 my ( $jid, $muc, @args ) = @_;691 692 $muc = shift @args if scalar @args;693 die("Usage: jmuc part [<muc>] [-a <account>]\n") unless $muc;694 695 if($conn->getConnectionFromJID($jid)->MUCLeave(JID => $muc)) {696 queue_admin_msg("$jid has left $muc.");697 } else {698 die("Error: Not joined to $muc\n");699 }700 }701 702 sub jmuc_invite {703 my ( $jid, $muc, @args ) = @_;704 705 my $invite_jid = shift @args;706 $muc = shift @args if scalar @args;707 708 die("Usage: jmuc invite <jid> [<muc>] [-a <account>]\n")709 unless $muc && $invite_jid;710 711 my $message = Net::Jabber::Message->new();712 $message->SetTo($muc);713 my $x = $message->NewChild('http://jabber.org/protocol/muc#user');714 $x->AddInvite();715 $x->GetInvite()->SetTo($invite_jid);716 $conn->getConnectionFromJID($jid)->Send($message);717 queue_admin_msg("$jid has invited $invite_jid to $muc.");718 }719 720 sub jmuc_configure {721 my ( $jid, $muc, @args ) = @_;722 $muc = shift @args if scalar @args;723 die("Usage: jmuc configure [<muc>]\n") unless $muc;724 my $iq = Net::Jabber::IQ->new();725 $iq->SetTo($muc);726 $iq->SetType('set');727 my $query = $iq->NewQuery("http://jabber.org/protocol/muc#owner");728 my $x = $query->NewChild("jabber:x:data");729 $x->SetType('submit');730 731 $conn->getConnectionFromJID($jid)->Send($iq);732 queue_admin_msg("Accepted default instant configuration for $muc");733 }734 735 sub jmuc_presence_single {736 my $m = shift;737 my @jids = $m->Presence();738 739 my $presence = "JIDs present in " . $m->BaseJID;740 $completion_jids{$m->BaseJID} = 1;741 if($m->Anonymous) {742 $presence .= " [anonymous MUC]";743 }744 $presence .= "\n\t";745 $presence .= join("\n\t", map {pp_jid($m, $_);} @jids) . "\n";746 return $presence;747 }748 749 sub pp_jid {750 my ($m, $jid) = @_;751 my $nick = $jid->GetResource;752 my $full = $m->GetFullJID($jid);753 if($full && $full ne $nick) {754 return "$nick ($full)";755 } else {756 return "$nick";757 }758 }759 760 sub jmuc_presence {761 my ( $jid, $muc, @args ) = @_;762 763 $muc = shift @args if scalar @args;764 die("Usage: jmuc presence [<muc>]\n") unless $muc;765 766 if ($muc eq '-a') {767 my $str = "";768 foreach my $jid ($conn->getJIDs()) {769 $str .= BarnOwl::Style::boldify("Conferences for $jid:\n");770 my $connection = $conn->getConnectionFromJID($jid);771 foreach my $muc ($connection->MUCs) {772 $str .= jmuc_presence_single($muc)."\n";773 }774 }775 BarnOwl::popless_ztext($str);776 }777 else {778 my $m = $conn->getConnectionFromJID($jid)->FindMUC(jid => $muc);779 die("No such muc: $muc\n") unless $m;780 BarnOwl::popless_ztext(jmuc_presence_single($m));781 }782 }783 784 785 #XXX TODO: Consider merging this with jmuc and selecting off the first two args.786 sub cmd_jroster {787 die "You are not logged in to Jabber" unless $conn->connected();788 my $ocmd = shift;789 my $cmd = shift;790 if ( !$cmd ) {791 792 #XXX TODO: Write general usage for jroster command.793 return;794 }795 796 my %jroster_commands = (797 sub => \&jroster_sub,798 unsub => \&jroster_unsub,799 add => \&jroster_add,800 remove => \&jroster_remove,801 auth => \&jroster_auth,802 deauth => \&jroster_deauth803 );804 my $func = $jroster_commands{$cmd};805 if ( !$func ) {806 die("jroster: Unknown command: $cmd\n");807 }808 809 {810 local @ARGV = @_;811 my $jid;812 my $name;813 my @groups;814 my $purgeGroups;815 my $getopt = Getopt::Long::Parser->new;816 $getopt->configure('pass_through', 'no_getopt_compat');817 $getopt->getoptions(818 'account=s' => \$jid,819 'group=s' => \@groups,820 'purgegroups' => \$purgeGroups,821 'name=s' => \$name822 );823 $jid ||= defaultJID();824 if ($jid) {825 $jid = resolveConnectedJID($jid);826 return unless $jid;827 }828 else {829 die("You must specify an account with -a <jid>\n");830 }831 return $func->( $jid, $name, \@groups, $purgeGroups, @ARGV );832 }833 }834 835 sub cmd_jaway {836 my $cmd = shift;837 local @ARGV = @_;838 my $getopt = Getopt::Long::Parser->new;839 my ($jid, $show);840 my $p = new Net::Jabber::Presence;841 842 $getopt->configure('pass_through', 'no_getopt_compat');843 $getopt->getoptions(844 'account=s' => \$jid,845 'show=s' => \$show846 );847 $jid ||= defaultJID();848 if ($jid) {849 $jid = resolveConnectedJID($jid);850 return unless $jid;851 }852 else {853 die("You must specify an account with -a <jid>\n");854 }855 856 $p->SetShow($show eq "online" ? "" : $show) if $show;857 $p->SetStatus(join(' ', @ARGV)) if @ARGV;858 $conn->getConnectionFromJID($jid)->Send($p);859 }860 861 862 sub jroster_sub {863 my $jid = shift;864 my $name = shift;865 my @groups = @{ shift() };866 my $purgeGroups = shift;867 my $baseJID = baseJID($jid);868 869 my $roster = $conn->getRosterFromJID($jid);870 871 # Adding lots of users with the same name is a bad idea.872 $name = "" unless (1 == scalar(@ARGV));873 874 my $p = new Net::Jabber::Presence;875 $p->SetType('subscribe');876 877 foreach my $to (@ARGV) {878 jroster_add($jid, $name, \@groups, $purgeGroups, ($to)) unless ($roster->exists($to));879 880 $p->SetTo($to);881 $conn->getConnectionFromJID($jid)->Send($p);882 queue_admin_msg("You ($baseJID) have requested a subscription to ($to)'s presence.");883 }884 }885 886 sub jroster_unsub {887 my $jid = shift;888 my $name = shift;889 my @groups = @{ shift() };890 my $purgeGroups = shift;891 my $baseJID = baseJID($jid);892 893 my $p = new Net::Jabber::Presence;894 $p->SetType('unsubscribe');895 foreach my $to (@ARGV) {896 $p->SetTo($to);897 $conn->getConnectionFromJID($jid)->Send($p);898 queue_admin_msg("You ($baseJID) have unsubscribed from ($to)'s presence.");899 }900 }901 902 sub jroster_add {903 my $jid = shift;904 my $name = shift;905 my @groups = @{ shift() };906 my $purgeGroups = shift;907 my $baseJID = baseJID($jid);908 909 my $roster = $conn->getRosterFromJID($jid);910 911 # Adding lots of users with the same name is a bad idea.912 $name = "" unless (1 == scalar(@ARGV));913 914 $completion_jids{$baseJID} = 1;915 $completion_jids{$name} = 1 if $name;916 917 foreach my $to (@ARGV) {918 my %jq = $roster->query($to);919 my $iq = new Net::Jabber::IQ;920 $iq->SetType('set');921 my $item = new XML::Stream::Node('item');922 $iq->NewChild('jabber:iq:roster')->AddChild($item);923 924 my %allGroups = ();925 926 foreach my $g (@groups) {927 $allGroups{$g} = $g;928 }929 930 unless ($purgeGroups) {931 foreach my $g (@{$jq{groups}}) {932 $allGroups{$g} = $g;933 }934 }935 936 foreach my $g (keys %allGroups) {937 $item->add_child('group')->add_cdata($g);938 }939 940 $item->put_attrib(jid => $to);941 $item->put_attrib(name => $name) if $name;942 $conn->getConnectionFromJID($jid)->Send($iq);943 my $msg = "$baseJID: "944 . ($name ? "$name ($to)" : "($to)")945 . " is on your roster in the following groups: { "946 . join(" , ", keys %allGroups)947 . " }";948 queue_admin_msg($msg);949 }950 }951 952 sub jroster_remove {953 my $jid = shift;954 my $name = shift;955 my @groups = @{ shift() };956 my $purgeGroups = shift;957 my $baseJID = baseJID($jid);958 959 my $iq = new Net::Jabber::IQ;960 $iq->SetType('set');961 my $item = new XML::Stream::Node('item');962 $iq->NewChild('jabber:iq:roster')->AddChild($item);963 $item->put_attrib(subscription=> 'remove');964 foreach my $to (@ARGV) {965 $item->put_attrib(jid => $to);966 $conn->getConnectionFromJID($jid)->Send($iq);967 queue_admin_msg("You ($baseJID) have removed ($to) from your roster.");968 }969 }970 971 sub jroster_auth {972 my $jid = shift;973 my $name = shift;974 my @groups = @{ shift() };975 my $purgeGroups = shift;976 my $baseJID = baseJID($jid);977 978 my $p = new Net::Jabber::Presence;979 $p->SetType('subscribed');980 foreach my $to (@ARGV) {981 $p->SetTo($to);982 $conn->getConnectionFromJID($jid)->Send($p);983 queue_admin_msg("($to) has been subscribed to your ($baseJID) presence.");984 }985 }986 987 sub jroster_deauth {988 my $jid = shift;989 my $name = shift;990 my @groups = @{ shift() };991 my $purgeGroups = shift;992 my $baseJID = baseJID($jid);993 994 my $p = new Net::Jabber::Presence;995 $p->SetType('unsubscribed');996 foreach my $to (@ARGV) {997 $p->SetTo($to);998 $conn->getConnectionFromJID($jid)->Send($p);999 queue_admin_msg("($to) has been unsubscribed from your ($baseJID) presence.");1000 }1001 }1002 1003 ################################################################################1004 ### Owl Callbacks1005 sub process_owl_jwrite {1006 my $body = shift;1007 1008 my $j = new Net::Jabber::Message;1009 $body =~ s/\n\z//;1010 $j->SetMessage(1011 to => $vars{jwrite}{to},1012 from => $vars{jwrite}{from},1013 type => $vars{jwrite}{type},1014 body => $body1015 );1016 1017 $j->SetThread( $vars{jwrite}{thread} ) if ( $vars{jwrite}{thread} );1018 $j->SetSubject( $vars{jwrite}{subject} ) if ( $vars{jwrite}{subject} );1019 1020 my $m = j2o( $j, { direction => 'out' } );1021 if ( $vars{jwrite}{type} ne 'groupchat') {1022 BarnOwl::queue_message($m);1023 }1024 1025 $j->RemoveFrom(); # Kludge to get around gtalk's random bits after the resource.1026 if ($vars{jwrite}{sid} && $conn->sidExists( $vars{jwrite}{sid} )) {1027 $conn->getConnectionFromSid($vars{jwrite}{sid})->Send($j);1028 }1029 else {1030 $conn->getConnectionFromJID($vars{jwrite}{from})->Send($j);1031 }1032 1033 delete $vars{jwrite};1034 BarnOwl::message(""); # Kludge to make the ``type your message...'' message go away1035 }1036 1037 ### XMPP Callbacks1038 1039 sub process_incoming_chat_message {1040 my ( $sid, $j ) = @_;1041 if ($j->DefinedBody() || BarnOwl::getvar('jabber:spew') eq 'on') {1042 BarnOwl::queue_message( j2o( $j, { direction => 'in',1043 sid => $sid } ) );1044 }1045 }1046 1047 sub process_incoming_error_message {1048 my ( $sid, $j ) = @_;1049 my %jhash = j2hash( $j, { direction => 'in',1050 sid => $sid } );1051 $jhash{type} = 'admin';1052 1053 BarnOwl::queue_message( BarnOwl::Message->new(%jhash) );1054 }1055 1056 sub process_incoming_groupchat_message {1057 my ( $sid, $j ) = @_;1058 1059 # HACK IN PROGRESS (ignoring delayed messages)1060 return if ( $j->DefinedX('jabber:x:delay') && $j->GetX('jabber:x:delay') );1061 BarnOwl::queue_message( j2o( $j, { direction => 'in',1062 sid => $sid } ) );1063 }1064 1065 sub process_incoming_headline_message {1066 my ( $sid, $j ) = @_;1067 BarnOwl::queue_message( j2o( $j, { direction => 'in',1068 sid => $sid } ) );1069 }1070 1071 sub process_incoming_normal_message {1072 my ( $sid, $j ) = @_;1073 my %jhash = j2hash( $j, { direction => 'in',1074 sid => $sid } );1075 1076 # XXX TODO: handle things such as MUC invites here.1077 1078 # if ($j->HasX('http://jabber.org/protocol/muc#user'))1079 # {1080 # my $x = $j->GetX('http://jabber.org/protocol/muc#user');1081 # if ($x->HasChild('invite'))1082 # {1083 # $props1084 # }1085 # }1086 #1087 if ($j->DefinedBody() || BarnOwl::getvar('jabber:spew') eq 'on') {1088 BarnOwl::queue_message( BarnOwl::Message->new(%jhash) );1089 }1090 }1091 1092 sub process_muc_presence {1093 my ( $sid, $p ) = @_;1094 return unless ( $p->HasX('http://jabber.org/protocol/muc#user') );1095 }1096 1097 1098 sub process_presence_available {1099 my ( $sid, $p ) = @_;1100 my $from = $p->GetFrom('jid')->GetJID('base');1101 $completion_jids{$from} = 1;1102 return unless (BarnOwl::getvar('jabber:show_logins') eq 'on');1103 my $to = $p->GetTo();1104 my $type = $p->GetType();1105 my %props = (1106 to => $to,1107 from => $p->GetFrom(),1108 recipient => $to,1109 sender => $from,1110 type => 'jabber',1111 jtype => $p->GetType(),1112 status => $p->GetStatus(),1113 show => $p->GetShow(),1114 xml => $p->GetXML(),1115 direction => 'in');1116 1117 if ($type eq '' || $type eq 'available') {1118 $props{body} = "$from is now online. ";1119 $props{loginout} = 'login';1120 }1121 else {1122 $props{body} = "$from is now offline. ";1123 $props{loginout} = 'logout';1124 }1125 BarnOwl::queue_message(BarnOwl::Message->new(%props));1126 }1127 1128 sub process_presence_subscribe {1129 my ( $sid, $p ) = @_;1130 my $from = $p->GetFrom();1131 my $to = $p->GetTo();1132 my %props = (1133 to => $to,1134 from => $from,1135 xml => $p->GetXML(),1136 type => 'admin',1137 adminheader => 'Jabber presence: subscribe',1138 direction => 'in');1139 1140 $props{body} = "Allow user ($from) to subscribe to your ($to) presence?\n" .1141 "(Answer with the `yes' or `no' commands)";1142 $props{yescommand} = BarnOwl::quote('jroster', 'auth', $from, '-a', $to);1143 $props{nocommand} = BarnOwl::quote('jroster', 'deauth', $from, '-a', $to);1144 $props{question} = "true";1145 BarnOwl::queue_message(BarnOwl::Message->new(%props));1146 }1147 1148 sub process_presence_unsubscribe {1149 my ( $sid, $p ) = @_;1150 my $from = $p->GetFrom();1151 my $to = $p->GetTo();1152 my %props = (1153 to => $to,1154 from => $from,1155 xml => $p->GetXML(),1156 type => 'admin',1157 adminheader => 'Jabber presence: unsubscribe',1158 direction => 'in');1159 1160 $props{body} = "The user ($from) has been unsubscribed from your ($to) presence.\n";1161 BarnOwl::queue_message(BarnOwl::Message->new(%props));1162 1163 # Find a connection to reply with.1164 foreach my $jid ($conn->getJIDs()) {1165 my $cJID = new Net::Jabber::JID;1166 $cJID->SetJID($jid);1167 if ($to eq $cJID->GetJID('base') ||1168 $to eq $cJID->GetJID('full')) {1169 my $reply = $p->Reply(type=>"unsubscribed");1170 $conn->getConnectionFromJID($jid)->Send($reply);1171 return;1172 }1173 }1174 }1175 1176 sub process_presence_subscribed {1177 my ( $sid, $p ) = @_;1178 queue_admin_msg("ignoring:".$p->GetXML()) if BarnOwl::getvar('jabber:spew') eq 'on';1179 # RFC 3921 says we should respond to this with a "subscribe"1180 # but this causes a flood of sub/sub'd presence packets with1181 # some servers, so we won't. We may want to detect this condition1182 # later, and have per-server settings.1183 return;1184 }1185 1186 sub process_presence_unsubscribed {1187 my ( $sid, $p ) = @_;1188 queue_admin_msg("ignoring:".$p->GetXML()) if BarnOwl::getvar('jabber:spew') eq 'on';1189 # RFC 3921 says we should respond to this with a "subscribe"1190 # but this causes a flood of unsub/unsub'd presence packets with1191 # some servers, so we won't. We may want to detect this condition1192 # later, and have per-server settings.1193 return;1194 }1195 1196 sub process_presence_error {1197 my ( $sid, $p ) = @_;1198 my $code = $p->GetErrorCode();1199 my $error = $p->GetError();1200 BarnOwl::error("Jabber: $code $error");1201 }1202 1203 1204 ### Helper functions1205 1206 sub j2hash {1207 my $j = shift;1208 my %props = (type => 'jabber',1209 dir => 'none',1210 %{$_[0]});1211 1212 my $dir = $props{direction};1213 1214 my $jtype = $props{jtype} = $j->GetType();1215 my $from = $j->GetFrom('jid');1216 my $to = $j->GetTo('jid');1217 1218 $props{from} = $from->GetJID('full');1219 $props{to} = $to->GetJID('full');1220 1221 $props{recipient} = $to->GetJID('base');1222 $props{sender} = $from->GetJID('base');1223 $props{subject} = $j->GetSubject() if ( $j->DefinedSubject() );1224 $props{thread} = $j->GetThread() if ( $j->DefinedThread() );1225 if ( $j->DefinedBody() ) {1226 $props{body} = $j->GetBody();1227 $props{body} =~ s/\xEF\xBB\xBF//g; # Strip stray Byte-Order-Marks.1228 }1229 $props{error} = $j->GetError() if ( $j->DefinedError() );1230 $props{error_code} = $j->GetErrorCode() if ( $j->DefinedErrorCode() );1231 $props{xml} = $j->GetXML();1232 1233 if ( $jtype eq 'groupchat' ) {1234 my $nick = $props{nick} = $from->GetResource();1235 my $room = $props{room} = $from->GetJID('base');1236 $completion_jids{$room} = 1;1237 1238 my $muc;1239 if ($dir eq 'in') {1240 my $connection = $conn->getConnectionFromSid($props{sid});1241 $muc = $connection->FindMUC(jid => $from);1242 } else {1243 my $connection = $conn->getConnectionFromJID($props{from});1244 $muc = $connection->FindMUC(jid => $to);1245 }1246 $props{from} = $muc->GetFullJID($from) || $props{from};1247 $props{sender} = $nick || $room;1248 $props{recipient} = $room;1249 1250 if ( $props{subject} && !$props{body} ) {1251 $props{body} =1252 '[' . $nick . " has set the topic to: " . $props{subject} . "]";1253 }1254 }1255 elsif ( $jtype eq 'headline' ) {1256 ;1257 }1258 elsif ( $jtype eq 'error' ) {1259 $props{body} = "Error "1260 . $props{error_code}1261 . " sending to "1262 . $props{from} . "\n"1263 . $props{error};1264 }1265 else { # chat, or normal (default)1266 $props{private} = 1;1267 1268 my $connection;1269 if ($dir eq 'in') {1270 $connection = $conn->getConnectionFromSid($props{sid});1271 }1272 else {1273 $connection = $conn->getConnectionFromJID($props{from});1274 }1275 1276 # Check to see if we're doing personals with someone in a muc.1277 # If we are, show the full jid because the base jid is the room.1278 if ($connection) {1279 $props{sender} = $props{from}1280 if ($connection->FindMUC(jid => $from));1281 $props{recipient} = $props{to}1282 if ($connection->FindMUC(jid => $to));1283 }1284 1285 # Populate completion.1286 if ($dir eq 'in') {1287 $completion_jids{ $props{sender} }= 1;1288 }1289 else {1290 $completion_jids{ $props{recipient} } = 1;1291 }1292 }1293 1294 return %props;1295 }1296 1297 sub j2o {1298 return BarnOwl::Message->new( j2hash(@_) );1299 }1300 1301 sub queue_admin_msg {1302 my $err = shift;1303 BarnOwl::admin_message("Jabber", $err);1304 }1305 1306 sub getServerFromJID {1307 my $jid = shift;1308 my $res = new Net::DNS::Resolver;1309 my $packet =1310 $res->search( '_xmpp-client._tcp.' . $jid->GetServer(), 'srv' );1311 1312 if ($packet) # Got srv record.1313 {1314 my @answer = $packet->answer;1315 return $answer[0]{target}, $answer[0]{port};1316 }1317 1318 return $jid->GetServer(), 5222;1319 }1320 1321 sub defaultJID {1322 return ( $conn->getJIDs() )[0] if ( $conn->connected() == 1 );1323 return;1324 }1325 1326 sub baseJID {1327 my $givenJIDStr = shift;1328 my $givenJID = new Net::Jabber::JID;1329 $givenJID->SetJID($givenJIDStr);1330 return $givenJID->GetJID('base');1331 }1332 1333 sub resolveConnectedJID {1334 my $givenJIDStr = shift;1335 my $loose = shift || 0;1336 my $givenJID = new Net::Jabber::JID;1337 $givenJID->SetJID($givenJIDStr);1338 1339 # Account fully specified.1340 if ( $givenJID->GetResource() ) {1341 # Specified account exists1342 return $givenJIDStr if ($conn->jidExists($givenJIDStr) );1343 return resolveConnectedJID($givenJID->GetJID('base')) if $loose;1344 die("Invalid account: $givenJIDStr\n");1345 }1346 1347 # Disambiguate.1348 else {1349 my $JIDMatchingJID = "";1350 my $strMatchingJID = "";1351 my $JIDMatches = "";1352 my $strMatches = "";1353 my $JIDAmbiguous = 0;1354 my $strAmbiguous = 0;1355 1356 foreach my $jid ( $conn->getJIDs() ) {1357 my $cJID = new Net::Jabber::JID;1358 $cJID->SetJID($jid);1359 if ( $givenJIDStr eq $cJID->GetJID('base') ) {1360 $JIDAmbiguous = 1 if ( $JIDMatchingJID ne "" );1361 $JIDMatchingJID = $jid;1362 $JIDMatches .= "\t$jid\n";1363 }1364 if ( $cJID->GetJID('base') =~ /$givenJIDStr/ ) {1365 $strAmbiguous = 1 if ( $strMatchingJID ne "" );1366 $strMatchingJID = $jid;1367 $strMatches .= "\t$jid\n";1368 }1369 }1370 1371 # Need further disambiguation.1372 if ($JIDAmbiguous) {1373 my $errStr =1374 "Ambiguous account reference. Please specify a resource.\n";1375 die($errStr.$JIDMatches);1376 }1377 1378 # It's this one.1379 elsif ($JIDMatchingJID ne "") {1380 return $JIDMatchingJID;1381 }1382 1383 # Further resolution by substring.1384 elsif ($strAmbiguous) {1385 my $errStr =1386 "Ambiguous account reference. Please be more specific.\n";1387 die($errStr.$strMatches);1388 }1389 1390 # It's this one, by substring.1391 elsif ($strMatchingJID ne "") {1392 return $strMatchingJID;1393 }1394 1395 # Not one of ours.1396 else {1397 die("Invalid account: $givenJIDStr\n");1398 }1399 1400 }1401 return "";1402 }1403 1404 sub resolveDestJID {1405 my ($to, $from) = @_;1406 my $jid = Net::Jabber::JID->new($to);1407 1408 my $roster = $conn->getRosterFromJID($from);1409 my @jids = $roster->jids('all');1410 for my $j (@jids) {1411 if(($roster->query($j, 'name') || $j->GetUserID()) eq $to) {1412 return $j->GetJID('full');1413 } elsif($j->GetJID('base') eq baseJID($to)) {1414 return $jid->GetJID('full');1415 }1416 }1417 1418 # If we found nothing being clever, check to see if our input was1419 # sane enough to look like a jid with a UserID.1420 return $jid->GetJID('full') if $jid->GetUserID();1421 return undef;1422 }1423 1424 sub resolveType {1425 my $to = shift;1426 my $from = shift;1427 return unless $from;1428 my @mucs = $conn->getConnectionFromJID($from)->MUCs;1429 if(grep {$_->BaseJID eq $to } @mucs) {1430 return 'groupchat';1431 } else {1432 return 'chat';1433 }1434 }1435 1436 sub guess_jwrite {1437 # Heuristically guess what jids a jwrite was meant to be going to/from1438 my ($from, $to) = (@_);1439 my ($from_jid, $to_jid);1440 my @matches;1441 if($from) {1442 $from_jid = resolveConnectedJID($from, 1);1443 die("Unable to resolve account $from\n") unless $from_jid;1444 $to_jid = resolveDestJID($to, $from_jid);1445 push @matches, [$from_jid, $to_jid] if $to_jid;1446 } else {1447 for my $f ($conn->getJIDs) {1448 $to_jid = resolveDestJID($to, $f);1449 if(defined($to_jid)) {1450 push @matches, [$f, $to_jid];1451 }1452 }1453 if($to =~ /@/) {1454 push @matches, [$_, $to]1455 for ($conn->getJIDs);1456 }1457 }1458 1459 for my $m (@matches) {1460 my $type = resolveType($m->[1], $m->[0]);1461 push @$m, $type;1462 }1463 1464 return @matches;1465 }1466 1467 ################################################################################1468 ### Completion1469 1470 sub complete_user_or_muc { return keys %completion_jids; }1471 sub complete_account { return $conn->getJIDs(); }1472 1473 sub complete_jwrite {1474 my $ctx = shift;1475 return complete_flags($ctx,1476 [qw(-t -i -s)],1477 {1478 "-a" => \&complete_account,1479 },1480 \&complete_user_or_muc1481 );1482 }1483 1484 sub complete_jabberlogout {1485 my $ctx = shift;1486 if($ctx->word == 1) {1487 return ("-A", complete_account() );1488 } else {1489 return ();1490 }1491 }1492 1493 BarnOwl::Completion::register_completer(jwrite => sub { BarnOwl::Module::Jabber::complete_jwrite(@_) });1494 BarnOwl::Completion::register_completer(jabberlogout => sub { BarnOwl::Module::Jabber::complete_jabberlogout(@_) });1495 1496 198 1; -
perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm
rc6adf17 r3e34a69 146 146 my $status = $self->Process(0); 147 147 if ( !defined($status) ) { 148 $BarnOwl::Module::Jabber:: conn->scheduleReconnect($jid);148 $BarnOwl::Module::Jabber::Impl::conn->scheduleReconnect($jid); 149 149 } 150 150 } … … 191 191 my %jq = $roster->query($buddy); 192 192 my $name = $jq{name} || $buddy->GetUserID(); 193 $BarnOwl::Module::Jabber:: completion_jids{$name} = 1;194 $BarnOwl::Module::Jabber:: completion_jids{$buddy->GetJID()} = 1;195 } 196 $BarnOwl::Module::Jabber:: vars{idletime} |= BarnOwl::getidletime();197 unless (exists $BarnOwl::Module::Jabber:: vars{keepAliveTimer}) {198 $BarnOwl::Module::Jabber:: vars{keepAliveTimer} =193 $BarnOwl::Module::Jabber::Impl::completion_jids{$name} = 1; 194 $BarnOwl::Module::Jabber::Impl::completion_jids{$buddy->GetJID()} = 1; 195 } 196 $BarnOwl::Module::Jabber::Impl::vars{idletime} |= BarnOwl::getidletime(); 197 unless (exists $BarnOwl::Module::Jabber::Impl::vars{keepAliveTimer}) { 198 $BarnOwl::Module::Jabber::Impl::vars{keepAliveTimer} = 199 199 BarnOwl::Timer->new({ 200 200 'name' => "Jabber ($fullJid) keepAliveTimer", 201 201 'after' => 5, 202 202 'interval' => 5, 203 'cb' => sub { BarnOwl::Module::Jabber:: do_keep_alive_and_auto_away(@_) }203 'cb' => sub { BarnOwl::Module::Jabber::Impl::do_keep_alive_and_auto_away(@_) } 204 204 }); 205 205 } -
.gitignore
rf93cc34 r1c22155 2 2 *.o 3 3 *.par 4 *~5 .#*6 .*.swp7 4 .deps 5 /bin/ 8 6 META.yml 7 MYMETA.yml 9 8 Makefile 10 9 Makefile.in 11 10 Makefile.old 12 11 TAGS 13 \#*#14 12 aclocal.m4 15 13 autom4te.cache 16 barnowl.bin 17 tester.bin 18 zcrypt 14 barnowl 19 15 blib 20 16 config.cache 21 17 config.h 22 18 config.h.in 19 config.h.in~ 23 20 config.log 24 21 config.status … … 26 23 core 27 24 depcomp 25 gmarshal_funcs.c 26 gmarshal_funcs.h 27 inc/ 28 28 install-sh 29 29 jabber.log … … 32 32 owl_prototypes.h.new 33 33 perlglue.c 34 perlwrap.c35 34 pm_to_blib 35 runtests.sh.log 36 runtests.sh.trs 36 37 stamp-h1 38 test-driver 39 test-suite.log 40 tester 37 41 varstubs.c 42 zcrypt -
AUTHORS
r1d2c4c3 r80c0fc7 3 3 4 4 The following people have provided patches or other contributions: 5 Alex Vandiver 6 Kevin Chen 7 Arun Tharuvai 5 8 Sam Hartman 6 Alex Vandiver7 Geoffrey Thomas8 9 Derrick Brashear 9 10 David Glasser 11 Eric Price 10 12 Matthew Goldstein 11 Arun Tharuvai 12 Kevin Chen 13 Eric Price 13 Geoffrey Thomas 14 Anders Kaseorg 15 Greg Price 16 Chris Lesniewski-Laas 17 Alex Dehnert 18 Edward Z. Yang 19 Karl Ramm 20 Evan Broder 21 David Benjamin 22 Cathy Zhang 23 Joshua Oreman 24 Leonid Grinberg 25 Kevin Riggle 26 Brian Sniffen 27 William Throwe 28 Jason Gross 29 Adam Glasgall 30 Tim Hill 31 DD Liu 32 Betsy Riley 33 Robert Jacobs 14 34 15 BarnOwl is based on code from Owl, which was originally primar ly35 BarnOwl is based on code from Owl, which was originally primarily 16 36 written by James Kretchmar. Erik Nygren also made substantial 17 contributions and improvem nts to the program.37 contributions and improvements to the program. 18 38 19 The following people provided patches and other tech incal support for39 The following people provided patches and other technical support for 20 40 Owl: 21 41 … … 30 50 Mark Eichin 31 51 32 Mark Eichin is also maintaining the debian package of Owl.52 Mark Eichin is also maintaining the Debian package of Owl. 33 53 34 54 The following people helped with beta testing the earliest versions of -
COPYING
rbbd0cf1 rccc182c 552 552 ====================================================================== 553 553 554 Files under perl/modules/Facebook/lib/Facebook and 555 perl/modules/Facebook/lib/Ouch.pm are copyright (c) 2010 Plain Black 556 Corporation. 554 Files under perl/modules/Facebook/lib/Facebook are copyright (c) 2010 Plain 555 Black Corporation. 557 556 558 557 This software is copyright (c) 2010 by Plain Black Corporation. … … 934 933 935 934 The End 936 937 ======================================================================938 939 The file perl/modules/Facebook/lib/AnyEvent/HTTP.pm is copyright (c)940 Marc Lehmann.941 942 This module is licensed under the same terms as perl itself.943 944 ======================================================================945 946 The file perl/modules/Facebook/lib/URI/Encode.pm is copyright (c)947 2010, Mithun Ayachit ``<mithun@cpan.org>''. All rights reserved.948 949 This module is free software; you can redistribute it and/or modify it950 under the same terms as Perl itself. See perlartistic. -
ChangeLog
r65ff3f4 r1b17f50 1 1.9 2 * Add getnumlines() to perl interface -asedeno@mit.edu 3 * Include names of invalid filters on filter errors -adehnert@mit.edu 4 * Don't incorrectly mark decryption failures as decrypted -davidben@mit.edu 5 * Hide the default cursor when possible -davidben@mit.edu 6 * Complete viewperson and vp as viewuser and vu -davidben@mit.edu 7 * Set z_charset = ZCHARSET_UTF_8 -andersk@mit.edu 8 * Allow zsender spoofing on cross-realm classes -andersk@mit.edu 9 * Append the realm to the zsender if missing -andersk@mit.edu 10 * Redisplay on setting colorztext -jgross@mit.edu 11 * Rename default config file to .owl/init.pl -kevinr@free-dissociation.com 12 * Add completion for jabberlogout -adehnert@mit.edu 13 * Switch to interactive context before sourcing the startup file -davidben@mit.edu 14 * Add completion for reload-module -adehnert@mit.edu 15 * editwin callback for canceling the editwin -jgross@mit.edu 16 * Fix dirtying windows inside a redraw handler -davidben@mit.edu 17 * Facebook module -ezyang@mit.edu 18 * Complete unstartup command just like startup command -jgross@mit.edu 19 * Fix the description of disable-ctrl-d -jgross@mit.edu 20 * Use wbkgrndset instead of wbkgdset in _owl_fmtext_wcolor_set -davidben@mit.edu 21 * Show the time zone in :info -jgross@mit.edu 22 * Treat [!.?]" as end of sentence in edit:fill-paragraph -jgross@mit.edu 23 * Correctly display multiline fields in :info -jgross@mit.edu 24 25 1.8.1 26 * Only add outgoing messages for personal part of half-personal messages -andersk@mit.edu 27 * Don’t write CC: line on zwrite -C '' -andersk@mit.edu 28 * Don’t send public pings on zwrite '' or zwrite @REALM -andersk@mit.edu 29 * Don’t treat zwrite '' as personal -andersk@mit.edu 30 * Stop pretending to support zwrite * -andersk@mit.edu 31 * Show foreign realms on non-personal zephyrs like Owl did -andersk@mit.edu 32 * Fix memory leak in zcrypt -davidben@mit.edu 33 * Don't attempt to switch filters in :view -d if invalid -davidben@mit.edu 34 * Fixed typo in unbindkey usage error -rileyb@mit.edu 35 * Fix bug generating filter text in 256-color mode -asedeno@mit.edu 36 * Remove ^noc from reply-lockout -geofft@mit.edu 37 * Avoid quadratic loops when receiving zephyrs -andersk@mit.edu 38 * Fix hang on empty zcrypt messages -adehnert@MIT.EDU 39 1 40 1.8 2 41 * Compute the home directory in zcrypt consistently with BarnOwl -davidben@mit.edu -
Makefile.am
rc266281 ra223b6b 4 4 GIT_FLAGS := $(if $(GIT_DESCRIPTION),-DGIT_VERSION=$(GIT_DESCRIPTION:barnowl-%=%)) 5 5 6 bin_PROGRAMS = b arnowl.bin6 bin_PROGRAMS = bin/barnowl 7 7 if ENABLE_ZCRYPT 8 8 bin_PROGRAMS += zcrypt … … 11 11 zcrypt_SOURCES = zcrypt.c filterproc.c 12 12 13 check_PROGRAMS = tester.bin 13 check_PROGRAMS = bin/tester 14 dist_check_DATA = t 15 dist_check_SCRIPTS = runtests.sh 14 16 15 barnowl_bin_SOURCES = $(BASE_SRCS) \ 16 owl.h owl_perl.h config.h \ 17 owl.c \ 18 $(GEN_C) $(GEN_H) 17 noinst_SCRIPTS = barnowl 18 check_SCRIPTS = tester 19 19 20 man_MANS = doc/barnowl.1 21 doc_DATA = doc/intro.txt doc/advanced.txt 20 barnowl tester: %: barnowl-wrapper.in bin/% Makefile 21 sed \ 22 -e 's,[@]abs_srcdir[@],$(abs_srcdir),g' \ 23 -e 's,[@]abs_builddir[@],$(abs_builddir),g' \ 24 $< > $@ 25 chmod +x $@ 22 26 23 barnowl_bin_LDADD = compat/libcompat.a libfaim/libfaim.a 27 bin_barnowl_SOURCES = $(BASE_SRCS) \ 28 owl.h owl_perl.h \ 29 owl.c 30 nodist_bin_barnowl_SOURCES = $(GEN_C) $(GEN_H) 24 31 25 tester_bin_SOURCES = $(BASE_SRCS) \ 26 owl.h owl_perl.h config.h \ 27 $(GEN_C) $(GEN_H) \ 32 dist_man_MANS = doc/barnowl.1 33 dist_doc_DATA = doc/intro.txt doc/advanced.txt 34 35 bin_barnowl_LDADD = compat/libcompat.a libfaim/libfaim.a 36 37 bin_tester_SOURCES = $(BASE_SRCS) \ 38 owl.h owl_perl.h \ 28 39 tester.c 40 nodist_bin_tester_SOURCES = $(GEN_C) $(GEN_H) 29 41 30 tester_bin_LDADD = compat/libcompat.a libfaim/libfaim.a42 bin_tester_LDADD = compat/libcompat.a libfaim/libfaim.a 31 43 32 44 TESTS=runtests.sh 33 45 34 AM_CPPFLAGS = -I$(top_srcdir)/\46 AM_CPPFLAGS = \ 35 47 -I$(top_srcdir)/libfaim/ \ 36 48 -DDATADIR='"$(pkgdatadir)"' \ … … 39 51 40 52 CODELIST_SRCS=message.c mainwin.c popwin.c zephyr.c messagelist.c \ 41 commands.c global.c text.c fmtext.c editwin.c util.c logging.c \ 53 commands.c global.c text.c fmtext.c editwin.c \ 54 util.c logging.c \ 42 55 perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \ 43 56 regex.c history.c view.c dict.c variable.c filterelement.c pair.c \ … … 45 58 aim.c buddy.c buddylist.c style.c errqueue.c \ 46 59 zbuddylist.c popexec.c select.c wcwidth.c \ 47 mainpanel.c msgwin.c sepbar.c editcontext.c signal.c 60 mainpanel.c msgwin.c sepbar.c editcontext.c signal.c closures.c 48 61 49 NORMAL_SRCS = filterproc.c window.cwindowcb.c62 NORMAL_SRCS = filterproc.c filterproc.h window.c window.h windowcb.c 50 63 51 64 BASE_SRCS = $(CODELIST_SRCS) $(NORMAL_SRCS) 52 65 53 GEN_C = varstubs.c perlglue.c 54 GEN_H = owl_prototypes.h 66 GEN_C = varstubs.c perlglue.c gmarshal_funcs.c 67 GEN_H = owl_prototypes.h owl_prototypes.h.new gmarshal_funcs.h 55 68 56 69 BUILT_SOURCES = $(GEN_C) $(GEN_H) … … 65 78 proto: owl_prototypes.h 66 79 67 perlglue.c: perlglue.xs $(TYPEMAP)68 $(AM_V_GEN)perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes perlglue.xs > perlglue.c80 perlglue.c: perlglue.xs typemap 81 $(AM_V_GEN)perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes $< > $@ 69 82 70 83 varstubs.c: stubgen.pl variable.c … … 74 87 $(AM_V_GEN)perl $< $(sort $(filter-out $<,$+)) > $@ 75 88 89 gmarshal_funcs.h: marshal_types 90 glib-genmarshal --header $< > $@ 91 gmarshal_funcs.c: marshal_types 92 glib-genmarshal --body $< > $@ 93 76 94 # For emacs flymake-mode 77 95 check-syntax: proto 78 96 $(COMPILE) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES) 79 97 80 install-data-local: 81 $(mkinstalldirs) ${DESTDIR}${pkgdatadir}/lib 82 (cd perl/lib && tar -cf - . ) | (cd ${DESTDIR}${pkgdatadir}/lib && tar -xf - ) 83 84 do_transform = $(shell echo '$(1)' | sed '$(transform)') 85 install-exec-hook: 86 mv -f $(DESTDIR)$(bindir)/$(call do_transform,barnowl.bin) \ 87 $(DESTDIR)$(bindir)/$(call do_transform,barnowl) 98 CLEANFILES = $(BUILT_SOURCES) $(noinst_SCRIPTS) $(check_SCRIPTS) 99 EXTRA_DIST = \ 100 autogen.sh \ 101 barnowl-wrapper.in \ 102 codelist.pl \ 103 doc/code.txt \ 104 doc/owl-window.txt \ 105 doc/releasing-barnowl.txt \ 106 examples \ 107 marshal_types \ 108 perlglue.xs \ 109 scripts \ 110 stubgen.pl \ 111 typemap 88 112 89 113 SUBDIRS = compat libfaim perl -
README
rbbd0cf1 r1c22155 10 10 following CPAN modules: 11 11 12 AnyEvent::HTTP13 12 Facebook::Graph 14 13 Net::Jabber 15 14 Net::XMPP 16 Ouch17 URI::Encode18 15 XML::Stream 19 16 … … 24 21 AnyEvent 25 22 Class::Accessor 23 ExtUtils::Depends 26 24 Glib 25 Module::Install 27 26 PAR 28 27 … … 30 29 We plan to soon add targets to the Makefile to check for and install 31 30 these for you. 31 32 The Facebook module requires: 33 34 Any::Moose 35 AnyEvent::HTTP 36 DateTime 37 DateTime::Format::Strptime 38 JSON 39 MIME::Base64::URLSafe 40 Ouch 41 URI 42 URI::Encode 32 43 33 44 The IRC module requires: … … 40 51 Authen::SASL::Perl 41 52 IO::Socket::SSL 42 Digest::SHA 153 Digest::SHA 43 54 44 55 The Twitter module requires: -
aim.c
rf271129 r8258ea5 707 707 { 708 708 aim_clientready(sess, fr->conn); 709 owl_function_debugmsg("conninitdone_admin: initializ tion done for admin connection");709 owl_function_debugmsg("conninitdone_admin: initialization done for admin connection"); 710 710 return(1); 711 711 } … … 836 836 params = va_arg(ap, struct aim_icbmparameters *); 837 837 va_end(ap); 838 839 owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08x, max msg len = %d, max sender evil = %f, max rec iever evil = %f, min msg interval = %u",838 839 owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08x, max msg len = %d, max sender evil = %f, max receiver evil = %f, min msg interval = %u", 840 840 params->maxchan, params->flags, params->maxmsglen, ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, params->minmsginterval); 841 841 -
barnowl-wrapper.in
- Property mode changed from 100755 to 100644
rf5f6ec0 ra223b6b 1 1 #!/bin/sh 2 2 # This is a wrapper script to point BARNOWL_DATA_DIR at the source dir 3 # if we're running from a build tree. b arnowl.binis the actual built3 # if we're running from a build tree. bin/barnowl is the actual built 4 4 # binary. 5 5 6 SRCDIR=`dirname "${0}"` 7 EXE="$0.bin" 6 EXE="@abs_builddir@/bin/$(basename "$0")" 8 7 9 8 if test ! -x "$EXE"; then … … 12 11 fi 13 12 14 BARNOWL_DATA_DIR=" $SRCDIR/perl/"15 BARNOWL_BIN_DIR=" $SRCDIR/"13 BARNOWL_DATA_DIR="@abs_srcdir@/perl" 14 BARNOWL_BIN_DIR="@abs_builddir@" 16 15 export BARNOWL_DATA_DIR 17 16 export BARNOWL_BIN_DIR -
commands.c
r39a531d ra38becd 479 479 480 480 OWLCMD_ARGS("away", owl_command_away, OWL_CTX_INTERACTIVE, 481 "Set, enable or disable both AIM and zephyraway messages",481 "Set, enable or disable all away messages", 482 482 "away [ on | off | toggle ]\n" 483 483 "away <message>", 484 "Turn on or off the AIM and zephyr away message. If\n"484 "Turn on or off all away messages. If\n" 485 485 "'message' is specified turn them on with that message,\n" 486 486 "otherwise use the default.\n" 487 "\n"488 "This command really just runs the 'aaway' and 'zaway'\n"489 "commands together\n"490 487 "\n" 491 488 "SEE ALSO: aaway, zaway"), … … 1033 1030 OWLCMD_ARGS_CTX("popless:start-search", owl_viewwin_command_start_search, OWL_CTX_POPLESS, 1034 1031 "starts a command line to search for particular string", 1035 "popless:start-search [-r] [init al-value]",1032 "popless:start-search [-r] [initial-value]", 1036 1033 "Initializes the command-line to search for initial-value. If\n" 1037 1034 "-r is used, the search will be performed backwards.\n\n" … … 1531 1528 char *owl_command_away(int argc, const char *const *argv, const char *buff) 1532 1529 { 1533 if ((argc==1) || 1534 ((argc==2) && !strcmp(argv[1], "on"))) { 1530 bool away_off; 1531 const char *message = NULL; 1532 1533 if (argc == 1 || 1534 (argc == 2 && !strcmp(argv[1], "on"))) { 1535 away_off = false; 1535 1536 owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g)); 1536 1537 owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g)); 1538 } else if (argc == 2 && !strcmp(argv[1], "off")) { 1539 away_off = true; 1540 } else if (argc == 2 && !strcmp(argv[1], "toggle")) { 1541 away_off = owl_function_is_away(); 1542 } else { 1543 away_off = false; 1544 message = skiptokens(buff, 1); 1545 } 1546 1547 if (away_off) { 1548 owl_function_aaway_off(); 1549 owl_function_zaway_off(); 1550 owl_perlconfig_perl_call_norv("BarnOwl::Hooks::_away_off", 0, NULL); 1551 owl_function_makemsg("Away messages off."); 1552 } else if (message != NULL) { 1553 owl_global_set_aaway_msg(&g, message); 1554 owl_global_set_zaway_msg(&g, message); 1537 1555 owl_function_aaway_on(); 1538 1556 owl_function_zaway_on(); 1557 owl_perlconfig_perl_call_norv("BarnOwl::Hooks::_away_on", 1, &message); 1558 owl_function_makemsg("Away messages set (%s).", message); 1559 } else { 1560 owl_function_aaway_on(); 1561 owl_function_zaway_on(); 1562 owl_perlconfig_perl_call_norv("BarnOwl::Hooks::_away_on", 0, NULL); 1539 1563 owl_function_makemsg("Away messages set."); 1540 return NULL; 1541 } 1542 1543 if (argc==2 && !strcmp(argv[1], "off")) { 1544 owl_function_aaway_off(); 1545 owl_function_zaway_off(); 1546 return NULL; 1547 } 1548 1549 if (argc==2 && !strcmp(argv[1], "toggle")) { 1550 /* if either one is on, turn it off, otherwise toggle both (turn 1551 * them both on) 1552 */ 1553 if (!owl_global_is_zaway(&g) && !owl_global_is_aaway(&g)) { 1554 owl_function_aaway_toggle(); 1555 owl_function_zaway_toggle(); 1556 owl_function_makemsg("Away messages set."); 1557 } else { 1558 if (owl_global_is_zaway(&g)) owl_function_zaway_toggle(); 1559 if (owl_global_is_aaway(&g)) owl_function_aaway_toggle(); 1560 owl_function_makemsg("Away messages off."); 1561 } 1562 return NULL; 1563 } 1564 1565 buff = skiptokens(buff, 1); 1566 owl_global_set_aaway_msg(&g, buff); 1567 owl_global_set_zaway_msg(&g, buff); 1568 owl_function_aaway_on(); 1569 owl_function_zaway_on(); 1570 owl_function_makemsg("Away messages set."); 1564 } 1565 1571 1566 return NULL; 1572 1567 } … … 1604 1599 if (v == NULL) { 1605 1600 if (!silent) owl_function_error("Unknown variable '%s'", var); 1606 } else if (requirebool && owl_variable_get_type(v) != OWL_VARIABLE_BOOL) {1601 } else if (requirebool && !v->takes_on_off) { 1607 1602 if (!silent) owl_function_error("Variable '%s' is not a boolean", var); 1608 1603 } else { … … 1633 1628 if (v == NULL) { 1634 1629 if (!silent) owl_function_error("Unknown variable '%s'", var); 1635 } else if ( owl_variable_get_type(v) != OWL_VARIABLE_BOOL) {1630 } else if (!v->takes_on_off) { 1636 1631 if (!silent) owl_function_error("Variable '%s' is not a boolean", var); 1637 1632 } else { … … 2190 2185 if (!strcmp(argv[0], "-f")) { 2191 2186 if (argc<2) { 2192 owl_function_makemsg("Too few arg ments to the view command");2187 owl_function_makemsg("Too few arguments to the view command"); 2193 2188 return(NULL); 2194 2189 } … … 2202 2197 } else if (!strcmp(argv[0], "-s")) { 2203 2198 if (argc<2) { 2204 owl_function_makemsg("Too few arg ments to the view command");2199 owl_function_makemsg("Too few arguments to the view command"); 2205 2200 return(NULL); 2206 2201 } … … 2209 2204 argv+=2; 2210 2205 } else { 2211 owl_function_makemsg("Too few arg ments to the view command");2206 owl_function_makemsg("Too few arguments to the view command"); 2212 2207 return(NULL); 2213 2208 } -
compat/Makefile.am
r12a6616 rb80bae0 1 1 noinst_LIBRARIES = libcompat.a 2 2 3 libcompat_a_SOURCES = 3 libcompat_a_SOURCES = compat.h 4 4 libcompat_a_LIBADD = $(LIBOBJS) -
compat/compat.h
r4dde585 r6249a88f 2 2 #define INC_BARNOWL_COMPAT_COMPAT_H 3 3 4 #include "../config.h"4 #include <config.h> 5 5 6 6 #include <stddef.h> -
configure.ac
r883502d r77dfeb1 1 1 dnl Process this file with autoconf to produce a configure script. 2 AC_INIT([BarnOwl],[1.9dev],[bug-barnowl@mit.edu]) 3 AM_INIT_AUTOMAKE([1.7.0 -Wall -Wno-portability foreign]) 2 AC_INIT([BarnOwl],[1.10dev],[bug-barnowl@mit.edu]) 3 AM_INIT_AUTOMAKE([1.7.0 foreign std-options -Wall -Wno-portability]) 4 AM_MAINTAINER_MODE([enable]) 4 5 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) 5 6 … … 9 10 AC_PROG_CC 10 11 AC_PROG_CC_C99 12 AC_PROG_LN_S 13 14 AC_ARG_WITH([zephyr-default-format], 15 [AS_HELP_STRING([--with-zephyr-default-format], 16 [value for the default format zephyrgram field])], 17 [ 18 case $withval in 19 yes) withval='Config error: see http://mit.edu/df';; 20 no) withval='';; 21 esac 22 zephyr_default_format=$withval 23 ], 24 [zephyr_default_format='Config error: see http://mit.edu/df']) 25 AC_DEFINE_UNQUOTED( 26 [ZEPHYR_DEFAULT_FORMAT], ["$zephyr_default_format"], 27 [Value for the default format zephyrgram field] 28 ) 11 29 12 30 AC_ARG_WITH([stack-protector], … … 41 59 42 60 AS_IF([test "x$with_zephyr" != xno], 43 [AS_IF([test "x$with_krb4" != "xno"], 61 [have_krb4=no 62 63 AS_IF([test "x$with_krb4" != "xno"], 44 64 [AC_MSG_CHECKING([for Kerberos IV]) 45 65 AS_IF([krb5-config krb4 --libs >/dev/null 2>&1], 46 66 [AC_MSG_RESULT([yes]) 67 have_krb4=yes 47 68 AC_DEFINE([HAVE_KERBEROS_IV], [1], [Define if you have kerberos IV]) 48 69 AM_CFLAGS="${AM_CFLAGS} `krb5-config krb4 --cflags`" … … 51 72 [AC_MSG_RESULT([no]) 52 73 AS_IF([test "x$with_krb4" = "xyes"], 53 [AC_MSG_ERROR([Kerberos IV requested but not found])]) 54 PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto]) 55 AM_CFLAGS="${AM_CFLAGS} ${LIBCRYPTO_CFLAGS}" 56 LIBS="${LIBS} ${LIBCRYPTO_LIBS}" 57 ])]) 74 [AC_MSG_ERROR([Kerberos IV requested but not found])])])]) 75 76 AS_IF([test "x$have_krb4" != xyes], 77 [PKG_CHECK_MODULES([LIBCRYPTO], [libcrypto], 78 [AM_CFLAGS="${AM_CFLAGS} ${LIBCRYPTO_CFLAGS}" 79 LIBS="${LIBS} ${LIBCRYPTO_LIBS}" 80 ], 81 [PKG_CHECK_MODULES([OPENSSL], [openssl], 82 [AM_CFLAGS="${AM_CFLAGS} ${OPENSSL_CFLAGS}" 83 LIBS="${LIBS} ${OPENSSL_LIBS}" 84 ])])]) 85 58 86 AC_CHECK_LIB([zephyr], [ZGetSender], 59 87 [LIBS="$LIBS -lzephyr" … … 90 118 dnl Find the location of perl XSUBPP 91 119 AC_MSG_CHECKING(for the perl xsubpp precompiler) 92 XSUBPPDIR="` (perl -MExtUtils::MakeMaker -e 'print ExtUtils::MakeMaker->new({NAME => qw(owl)})->tool_xsubpp;')| grep \^XSUBPPDIR | sed -e 's/XSUBPPDIR = //g;'`"120 XSUBPPDIR="`cd "$srcdir" && perl -MExtUtils::MakeMaker -e 'print ExtUtils::MakeMaker->new({NAME => qw(owl)})->tool_xsubpp;' | grep \^XSUBPPDIR | sed -e 's/XSUBPPDIR = //g;'`" 93 121 if test -n "${XSUBPPDIR}"; then 94 122 AC_MSG_RESULT(${XSUBPPDIR}) … … 113 141 AX_PROG_PERL_MODULES([Class::Accessor::Fast],, 114 142 [AC_MSG_ERROR([cannot find perl module Class::Accessor::Fast.])]) 143 AX_PROG_PERL_MODULES([ExtUtils::Depends],, 144 [AC_MSG_ERROR([cannot find perl module ExtUtils::Depends])]) 115 145 AX_PROG_PERL_MODULES([Glib],, 116 146 [AC_MSG_ERROR([cannot find perl module Glib.])]) 147 AX_PROG_PERL_MODULES([Module::Install::Base],, 148 [AC_MSG_ERROR([cannot find perl module Module::Install::Base])]) 117 149 AX_PROG_PERL_MODULES([PAR],, 118 150 [AC_MSG_WARN([PAR.pm not found. Loadable modules will be disabled.])]) … … 129 161 prefix="${ac_default_prefix}" 130 162 fi 163 164 dnl Add CFLAGS for glib-perl 165 GLIB_PERL_CFLAGS=`perl -MExtUtils::Depends -e 'my $e = ExtUtils::Depends->new("BarnOwl","Glib"); my %h = $e->get_makefile_vars; print $h{"INC"}'` 166 AC_MSG_NOTICE([Adding glib-perl CFLAGS ${GLIB_PERL_CFLAGS}]) 167 AM_CFLAGS="${GLIB_PERL_CFLAGS} ${AM_CFLAGS}" 131 168 132 169 dnl Checks for typedefs, structures, and compiler characteristics. … … 150 187 dnl Define __EXTENSIONS__ for strcasecmp on Solaris. 151 188 AM_CFLAGS="$AM_CFLAGS -D__EXTENSIONS__" 189 dnl Define _XOPEN_SOURCE_EXTENDED for some features in ncurses, 190 dnl including cchar_t. This should not be necessary with 191 dnl _XOPEN_SOURCE=600, but some versions of ncurses 192 dnl apparently still need it. 193 AM_CFLAGS="$AM_CFLAGS -D_XOPEN_SOURCE_EXTENDED" 152 194 153 195 AC_SUBST([AM_CFLAGS]) … … 168 210 AC_REPLACE_FUNCS([memrchr]) 169 211 212 AC_SUBST([abs_builddir]) 213 AC_SUBST([abs_srcdir]) 214 170 215 AC_CONFIG_FILES([Makefile compat/Makefile libfaim/Makefile perl/Makefile perl/modules/Makefile]) 171 216 AC_OUTPUT -
doc/releasing-barnowl.txt
r5f08dbe rd995ff3 16 16 - [ ] Do a locker build (See DOING A LOCKER BUILD) 17 17 - [ ] Update configure.ac on master to bump the version to 1.(N+1)dev 18 - [ ] Add the barnowl-1.(N+1)dev git tag 18 19 - [ ] Push git git: 19 20 - [ ] The RC commit 20 21 - [ ] The configure.ac change on master 21 22 - [ ] A release-1.N branch pointing at the RC commit 23 - [ ] the new git tags 24 - [ ] Update debian/changelog on the launchpad build using `dch -v 1.(N+1)` 25 - [ ] bzr branch lp:~barnowl/barnowl/packaging && cd packaging && dch -v 1.(N+1) 26 - [ ] Add relevant changelog entries such as "New upstream release" or 27 "Placeholder version number for daily builds."; fix your name and email 28 if necessary 29 - [ ] bzr commit && bzr push 22 30 - [ ] Copy tarball into /mit/barnowl/web_scripts/dist 23 31 - [ ] Send mail announcing the RC to barnowl-dev@mit.edu … … 31 39 * DOING THE ACTUAL RELEASE 32 40 - [ ] Update the changelog and configure.ac for barnowl 1.N 41 - [ ] Copy the changelog changes to the master branch 33 42 - [ ] run ./scripts/do-release 34 43 - [ ] Do the locker build -
editwin.c
r7803326 r8258ea5 619 619 620 620 if (!g_utf8_validate(s, -1, NULL)) { 621 owl_function_debugmsg("owl_editwin_insert_string: received non- utf-8 string.");621 owl_function_debugmsg("owl_editwin_insert_string: received non-UTF-8 string."); 622 622 return 0; 623 623 } -
filter.c
r30781f6 rc068c03 124 124 125 125 op1 = owl_filter_parse_primitive_expression(argc-i, argv+i, &skip); 126 if(!op1) goto err; 126 127 i += skip; 127 if(!op1) goto err;128 128 129 129 while(i < argc) { -
filterproc.c
r97cdbaf5 r7155955 1 #include " owl.h"1 #include "filterproc.h" 2 2 #include <sys/wait.h> 3 #include <fcntl.h> 4 #include <glib.h> 3 5 #include <poll.h> 6 #include <string.h> 7 #include <unistd.h> 4 8 5 9 /* Even in case of error, send_receive is responsible for closing wfd … … 81 85 &child_pid, &child_stdin, &child_stdout, NULL, 82 86 NULL)) { 87 *out = NULL; 83 88 return 1; 84 89 } -
functions.c
rd199207 ra38becd 855 855 void owl_function_unsuball(void) 856 856 { 857 unsuball();858 owl_function_makemsg("Unsubscribed from all messages.");857 if (unsuball()) 858 owl_function_makemsg("Unsubscribed from all messages."); 859 859 } 860 860 … … 871 871 void owl_function_loadsubs(const char *file) 872 872 { 873 int ret, ret2; 874 const char *foo; 873 int ret, ret2, ret3; 875 874 char *path; 876 875 … … 884 883 885 884 /* for backwards compatibility for now */ 886 ret2=owl_zephyr_loaddefaultsubs(); 885 ret2 = owl_zephyr_loaddefaultsubs(); 886 ret3 = owl_zephyr_loadbarnowldefaultsubs(); 887 887 888 888 if (!owl_context_is_interactive(owl_global_get_context(&g))) return; 889 889 890 foo=file?file:"file"; 891 if (ret==0 && ret2==0) { 890 if (ret == 0 && ret2 == 0 && ret3 == 0) { 892 891 if (!file) { 893 892 owl_function_makemsg("Subscribed to messages."); … … 895 894 owl_function_makemsg("Subscribed to messages from %s", file); 896 895 } 897 } else if (ret ==-1) {898 owl_function_error("Could not read %s", f oo);899 } else {896 } else if (ret == -1) { 897 owl_function_error("Could not read %s", file ? file : "file"); 898 } else if (ret2 == -1) { 900 899 owl_function_error("Error subscribing to messages"); 900 } else { 901 owl_function_error("Error subscribing to instanced personals"); 901 902 } 902 903 } … … 990 991 /* owl_aim_set_awaymsg(""); */ 991 992 owl_function_makemsg("AIM away off"); 993 } 994 995 bool owl_function_is_away(void) 996 { 997 return owl_global_is_zaway(&g) || 998 owl_global_is_aaway(&g) || 999 owl_perlconfig_perl_call_bool("BarnOwl::Hooks::_get_is_away", 0, NULL); 992 1000 } 993 1001 … … 2186 2194 f = owl_filter_new(argv[1], argc-2, argv+2); 2187 2195 if (f == NULL) { 2188 owl_function_error("Invalid filter ");2196 owl_function_error("Invalid filter: %s", argv[1]); 2189 2197 return false; 2190 2198 } -
global.c
r219f52c r120dac7 9 9 const char *homedir; 10 10 11 #if !GLIB_CHECK_VERSION(2, 35, 0) 11 12 g_type_init(); 13 #endif 14 #if !GLIB_CHECK_VERSION(2, 31, 0) 12 15 g_thread_init(NULL); 16 #endif 13 17 14 18 owl_select_init(); … … 52 56 g->starttime=time(NULL); /* assumes we call init only a start time */ 53 57 g->lastinputtime=g->starttime; 58 g->last_wakeup_time = g->starttime; 54 59 g->newmsgproc_pid=0; 55 60 … … 100 105 101 106 g->interrupt_count = 0; 107 #if GLIB_CHECK_VERSION(2, 31, 0) 108 g_mutex_init(&g->interrupt_lock); 109 #else 102 110 g->interrupt_lock = g_mutex_new(); 111 #endif 103 112 } 104 113 … … 476 485 } 477 486 487 void owl_global_wakeup(owl_global *g) 488 { 489 if (time(NULL) - g->last_wakeup_time >= 1) { 490 g_free(owl_perlconfig_execute("BarnOwl::Hooks::_wakeup()")); 491 g->last_wakeup_time = time(NULL); 492 } 493 } 494 478 495 /* viewwin */ 479 496 … … 841 858 } filters[] = { 842 859 { "personal", 843 "isprivate ^true$ and ( not type ^zephyr$ or ( class ^message 860 "isprivate ^true$ and ( not type ^zephyr$ or ( class ^message$ ) )" }, 844 861 { "trash", 845 862 "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )" }, … … 848 865 { "auto", "opcode ^auto$" }, 849 866 { "login", "not login ^none$" }, 850 { "reply-lockout", "class ^mail$ " },867 { "reply-lockout", "class ^mail$ or class ^filsrv$" }, 851 868 { "out", "direction ^out$" }, 852 869 { "aim", "type ^aim$" }, … … 899 916 } 900 917 918 static GMutex *owl_global_get_interrupt_lock(owl_global *g) 919 { 920 #if GLIB_CHECK_VERSION(2, 31, 0) 921 return &g->interrupt_lock; 922 #else 923 return g->interrupt_lock; 924 #endif 925 } 926 901 927 void owl_global_add_interrupt(owl_global *g) { 902 928 /* TODO: This can almost certainly be done with atomic 903 929 * operations. Whatever. */ 904 g_mutex_lock( g->interrupt_lock);930 g_mutex_lock(owl_global_get_interrupt_lock(g)); 905 931 g->interrupt_count++; 906 g_mutex_unlock( g->interrupt_lock);932 g_mutex_unlock(owl_global_get_interrupt_lock(g)); 907 933 } 908 934 909 935 bool owl_global_take_interrupt(owl_global *g) { 910 936 bool ans = false; 911 g_mutex_lock( g->interrupt_lock);937 g_mutex_lock(owl_global_get_interrupt_lock(g)); 912 938 if (g->interrupt_count > 0) { 913 939 ans = true; 914 940 g->interrupt_count--; 915 941 } 916 g_mutex_unlock( g->interrupt_lock);942 g_mutex_unlock(owl_global_get_interrupt_lock(g)); 917 943 return ans; 918 944 } -
help.c
rf271129 r8258ea5 73 73 " : , M-x Enter command mode\n" 74 74 "\n" 75 " / Fo ward search\n"75 " / Forward search\n" 76 76 " ? Reverse search\n" 77 77 "\n\n" … … 107 107 " unsuball Unsubscribe from all zephyr classes\n" 108 108 " load-subs Load zephyr subscriptions from a file\n" 109 " zpunt Sup ress messages from a zephyr triplet\n"109 " zpunt Suppress messages from a zephyr triplet\n" 110 110 " zlog Send a login or logout notification\n" 111 111 " zlist Print a list of zephyr buddies logged in\n" -
libfaim/Makefile.am
r215c119 rb80bae0 13 13 libfaim_a_CPPFLAGS = -DAIM_BUILDDATE=\"x\" -DAIM_BUILDTIME=\"x\" \ 14 14 -I${top_srcdir}/libfaim 15 16 EXTRA_DIST = oscar.c -
logging.c
rf271129 r0792d99 429 429 static gpointer owl_log_thread_func(gpointer data) 430 430 { 431 log_context = g_main_context_new();432 431 log_loop = g_main_loop_new(log_context, FALSE); 433 432 g_main_loop_run(log_loop); … … 437 436 void owl_log_init(void) 438 437 { 438 log_context = g_main_context_new(); 439 #if GLIB_CHECK_VERSION(2, 31, 0) 440 logging_thread = g_thread_new("logging", 441 owl_log_thread_func, 442 NULL); 443 #else 439 444 GError *error = NULL; 440 445 logging_thread = g_thread_create(owl_log_thread_func, … … 448 453 exit(1); 449 454 } 455 #endif 450 456 451 457 } -
m4/ax_cflags_warn_all.m4
r378ede7 re9b4a2c 25 25 # - $3 action-if-found : add value to shellvariable 26 26 # - $4 action-if-not-found : nothing 27 # 28 # NOTE: These macros depend on AX_APPEND_FLAG. 27 29 # 28 30 # LICENSE … … 57 59 # exception to the GPL to apply to your modified version as well. 58 60 59 #serial 1 061 #serial 14 60 62 61 AC_DEFUN([AX_ CFLAGS_WARN_ALL],[dnl62 AS_VAR_PUSHDEF([FLAGS],[ CFLAGS])dnl63 AS_VAR_PUSHDEF([VAR],[ac_cv_ cflags_warn_all])dnl63 AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl 64 AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl 65 AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl 64 66 AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], 65 67 VAR,[VAR="no, unknown" 66 AC_LANG_PUSH([C]) 67 ac_save_[]FLAGS="$[]FLAGS" 68 for ac_arg dnl 69 in "-pedantic % -Wall" dnl GCC 70 "-xstrconst % -v" dnl Solaris C 71 "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix 72 "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX 73 "-ansi -ansiE % -fullwarn" dnl IRIX 74 "+ESlit % +w1" dnl HP-UX C 75 "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) 76 "-h conform % -h msglevel 2" dnl Cray C (Unicos) 77 # 78 do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` 79 AC_COMPILE_IFELSE([AC_LANG_PROGRAM], 80 [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 81 done 82 FLAGS="$ac_save_[]FLAGS" 83 AC_LANG_POP([C]) 84 ]) 85 case ".$VAR" in 86 .ok|.ok,*) m4_ifvaln($3,$3) ;; 87 .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[ 88 AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"]) 89 m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;; 90 *) m4_ifvaln($3,$3,[ 91 if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 92 then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) 93 else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) 94 m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" 95 fi ]) ;; 96 esac 97 AS_VAR_POPDEF([VAR])dnl 98 AS_VAR_POPDEF([FLAGS])dnl 99 ]) 100 101 dnl the only difference - the LANG selection... and the default FLAGS 102 103 AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl 104 AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl 105 AS_VAR_PUSHDEF([VAR],[ax_cv_cxxflags_warn_all])dnl 106 AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], 107 VAR,[VAR="no, unknown" 108 AC_LANG_PUSH([C++]) 109 ac_save_[]FLAGS="$[]FLAGS" 110 for ac_arg dnl 111 in "-pedantic % -Wall" dnl GCC 112 "-xstrconst % -v" dnl Solaris C 113 "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix 114 "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX 115 "-ansi -ansiE % -fullwarn" dnl IRIX 116 "+ESlit % +w1" dnl HP-UX C 117 "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10) 118 "-h conform % -h msglevel 2" dnl Cray C (Unicos) 119 # 120 do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` 121 AC_COMPILE_IFELSE([AC_LANG_PROGRAM], 122 [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 123 done 124 FLAGS="$ac_save_[]FLAGS" 125 AC_LANG_POP([C++]) 126 ]) 127 case ".$VAR" in 128 .ok|.ok,*) m4_ifvaln($3,$3) ;; 129 .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[ 130 AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"]) 131 m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;; 132 *) m4_ifvaln($3,$3,[ 133 if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 134 then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) 135 else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) 136 m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" 137 fi ]) ;; 138 esac 139 AS_VAR_POPDEF([VAR])dnl 140 AS_VAR_POPDEF([FLAGS])dnl 141 ]) 142 143 dnl the only difference - the LANG selection... and the default FLAGS 144 145 AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl 146 AS_VAR_PUSHDEF([FLAGS],[FCFLAGS])dnl 147 AS_VAR_PUSHDEF([VAR],[ax_cv_fcflags_warn_all])dnl 148 AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings], 149 VAR,[VAR="no, unknown" 150 AC_LANG_PUSH([Fortran]) 151 ac_save_[]FLAGS="$[]FLAGS" 68 ac_save_[]FLAGS="$[]FLAGS" 152 69 for ac_arg dnl 153 70 in "-warn all % -warn all" dnl Intel … … 165 82 [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 166 83 done 167 FLAGS="$ac_save_[]FLAGS" 168 AC_LANG_POP([Fortran]) 84 FLAGS="$ac_save_[]FLAGS" 169 85 ]) 86 AS_VAR_POPDEF([FLAGS])dnl 87 AC_REQUIRE([AX_APPEND_FLAG]) 170 88 case ".$VAR" in 171 89 .ok|.ok,*) m4_ifvaln($3,$3) ;; 172 .|.no|.no,*) m4_ifvaln($4,$4,[m4_ifval($2,[ 173 AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"]) 174 m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $2"])]) ;; 175 *) m4_ifvaln($3,$3,[ 176 if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 177 then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) 178 else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) 179 m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" 180 fi ]) ;; 90 .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;; 91 *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;; 181 92 esac 182 93 AS_VAR_POPDEF([VAR])dnl 183 AS_VAR_POPDEF([FLAGS])dnl 184 ]) 185 94 ])dnl AX_FLAGS_WARN_ALL 186 95 dnl implementation tactics: 187 96 dnl the for-argument contains a list of options. The first part of … … 194 103 dnl delimiter. A non-option comment can be given after "%%" marks 195 104 dnl which will be shown but not added to the respective C/CXXFLAGS. 105 106 AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl 107 AC_LANG_PUSH([C]) 108 AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) 109 AC_LANG_POP([C]) 110 ]) 111 112 AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl 113 AC_LANG_PUSH([C++]) 114 AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) 115 AC_LANG_POP([C++]) 116 ]) 117 118 AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl 119 AC_LANG_PUSH([Fortran]) 120 AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4]) 121 AC_LANG_POP([Fortran]) 122 ]) -
m4/pkg.m4
r650fb2c r13a39ae8 158 158 fi[]dnl 159 159 ])# PKG_CHECK_MODULES 160 161 162 # PKG_INSTALLDIR(DIRECTORY) 163 # ------------------------- 164 # Substitutes the variable pkgconfigdir as the location where a module 165 # should install pkg-config .pc files. By default the directory is 166 # $libdir/pkgconfig, but the default can be changed by passing 167 # DIRECTORY. The user can override through the --with-pkgconfigdir 168 # parameter. 169 AC_DEFUN([PKG_INSTALLDIR], 170 [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) 171 m4_pushdef([pkg_description], 172 [pkg-config installation directory @<:@]pkg_default[@:>@]) 173 AC_ARG_WITH([pkgconfigdir], 174 [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, 175 [with_pkgconfigdir=]pkg_default) 176 AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) 177 m4_popdef([pkg_default]) 178 m4_popdef([pkg_description]) 179 ]) dnl PKG_INSTALLDIR 180 181 182 # PKG_NOARCH_INSTALLDIR(DIRECTORY) 183 # ------------------------- 184 # Substitutes the variable noarch_pkgconfigdir as the location where a 185 # module should install arch-independent pkg-config .pc files. By 186 # default the directory is $datadir/pkgconfig, but the default can be 187 # changed by passing DIRECTORY. The user can override through the 188 # --with-noarch-pkgconfigdir parameter. 189 AC_DEFUN([PKG_NOARCH_INSTALLDIR], 190 [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) 191 m4_pushdef([pkg_description], 192 [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) 193 AC_ARG_WITH([noarch-pkgconfigdir], 194 [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, 195 [with_noarch_pkgconfigdir=]pkg_default) 196 AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) 197 m4_popdef([pkg_default]) 198 m4_popdef([pkg_description]) 199 ]) dnl PKG_NOARCH_INSTALLDIR 200 201 202 # PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, 203 # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) 204 # ------------------------------------------- 205 # Retrieves the value of the pkg-config variable for the given module. 206 AC_DEFUN([PKG_CHECK_VAR], 207 [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl 208 AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl 209 210 _PKG_CONFIG([$1], [variable="][$3]["], [$2]) 211 AS_VAR_COPY([$1], [pkg_cv_][$1]) 212 213 AS_VAR_IF([$1], [""], [$5], [$4])dnl 214 ])# PKG_CHECK_VAR -
message.c
r97cdbaf5 r2354e9a 881 881 NULL 882 882 }; 883 char *out ;883 char *out = NULL; 884 884 int rv; 885 885 int status; … … 898 898 } 899 899 owl_message_set_body(m, out); 900 g_free(out); 901 } else if(out) { 902 g_free(out); 903 } 900 } else { 901 /* Replace the opcode. Otherwise the UI and other bits of code think the 902 * message was encrypted. */ 903 owl_message_set_opcode(m, "failed-decrypt"); 904 } 905 g_free(out); 904 906 } 905 907 -
owl.c
r8135737 r120dac7 12 12 #include <sys/stat.h> 13 13 #include <locale.h> 14 #include <unistd.h> 14 15 15 16 #if OWL_STDERR_REDIR … … 33 34 } owl_options; 34 35 35 void usage( void)36 void usage(FILE *file) 36 37 { 37 fprintf( stderr, "Barnowl version %s\n", OWL_VERSION_STRING);38 fprintf( stderr, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n");39 fprintf( stderr, " -n,--no-subs don't load zephyr subscriptions\n");40 fprintf( stderr, " -d,--debug enable debugging\n");41 fprintf( stderr, " -v,--version print the Barnowl version number and exit\n");42 fprintf( stderr, " -h,--help print this help message\n");43 fprintf( stderr, " -s,--config-dir specify an alternate config dir (default ~/.owl)\n");44 fprintf( stderr, " -c,--config-file specify an alternate config file (default ~/.owl/init.pl)\n");45 fprintf( stderr, " -t,--tty set the tty name\n");38 fprintf(file, "Barnowl version %s\n", OWL_VERSION_STRING); 39 fprintf(file, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n"); 40 fprintf(file, " -n,--no-subs don't load zephyr subscriptions\n"); 41 fprintf(file, " -d,--debug enable debugging\n"); 42 fprintf(file, " -v,--version print the Barnowl version number and exit\n"); 43 fprintf(file, " -h,--help print this help message\n"); 44 fprintf(file, " -s,--config-dir specify an alternate config dir (default ~/.owl)\n"); 45 fprintf(file, " -c,--config-file specify an alternate config file (default ~/.owl/init.pl)\n"); 46 fprintf(file, " -t,--tty set the tty name\n"); 46 47 } 47 48 … … 82 83 exit(0); 83 84 case 'h': 85 usage(stdout); 86 exit(0); 84 87 default: 85 usage( );88 usage(stderr); 86 89 exit(1); 87 90 } … … 286 289 287 290 owl_global_set_lastinputtime(&g, time(NULL)); 291 owl_global_wakeup(&g); 288 292 ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j); 289 293 if (ret!=0 && ret!=1) { … … 427 431 if (0 != pipe(pipefds)) { 428 432 perror("pipe"); 429 owl_function_debugmsg("stderr_replace: pipe FAILED \n");433 owl_function_debugmsg("stderr_replace: pipe FAILED"); 430 434 return -1; 431 435 } 432 owl_function_debugmsg("stderr_replace: pipe: %d,%d \n", pipefds[0], pipefds[1]);433 if (-1 == dup2(pipefds[1], 2 /*stderr*/)) {434 owl_function_debugmsg("stderr_replace: dup2 FAILED (%s) \n", strerror(errno));436 owl_function_debugmsg("stderr_replace: pipe: %d,%d", pipefds[0], pipefds[1]); 437 if (-1 == dup2(pipefds[1], STDERR_FILENO)) { 438 owl_function_debugmsg("stderr_replace: dup2 FAILED (%s)", strerror(errno)); 435 439 perror("dup2"); 436 440 return -1; … … 514 518 #if OWL_STDERR_REDIR 515 519 /* Do this only after we've started curses up... */ 516 owl_function_debugmsg("startup: doing stderr redirection"); 517 channel = g_io_channel_unix_new(stderr_replace()); 518 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, &stderr_redirect_handler, NULL); 519 g_io_channel_unref(channel); 520 if (isatty(STDERR_FILENO)) { 521 owl_function_debugmsg("startup: doing stderr redirection"); 522 channel = g_io_channel_unix_new(stderr_replace()); 523 g_io_add_watch(channel, G_IO_IN | G_IO_HUP | G_IO_ERR, &stderr_redirect_handler, NULL); 524 g_io_channel_unref(channel); 525 } 520 526 #endif 521 527 -
owl.h
r219f52c r120dac7 10 10 #define INC_BARNOWL_OWL_H 11 11 12 #include "config.h"12 #include <config.h> 13 13 14 14 #include "compat/compat.h" … … 47 47 /* Perl and curses don't play nice. */ 48 48 #ifdef OWL_PERL 49 typedef voidWINDOW;50 typedef voidPANEL;49 typedef struct _owl_fake_WINDOW WINDOW; 50 typedef struct _owl_fake_PANEL PANEL; 51 51 /* logout is defined in FreeBSD. */ 52 52 #define logout logout_ … … 57 57 #include "XSUB.h" 58 58 #else 59 typedef voidSV;60 typedef voidAV;61 typedef voidHV;59 typedef struct _owl_fake_SV SV; 60 typedef struct _owl_fake_AV AV; 61 typedef struct _owl_fake_HV HV; 62 62 #endif 63 63 … … 235 235 char *name; 236 236 int type; /* OWL_VARIABLE_* */ 237 void *pval_default; /* for types other and string */ 238 int ival_default; /* for types int and bool */ 239 const char *validsettings; /* documentation of valid settings */ 237 char *default_str; /* the default value as a string */ 238 char *validsettings; /* documentation of valid settings */ 240 239 char *summary; /* summary of usage */ 241 240 char *description; /* detailed description */ 242 void *val; /* current value */ 243 int (*validate_fn)(const struct _owl_variable *v, const void *newval); 241 bool takes_on_off; /* allow passing on/off in argument-less set/unset */ 242 GClosure *set_fromstring_fn; 243 /* sets the variable to a value 244 * of the appropriate type. 245 * unless documented, this 246 * should make a copy. 247 * returns 0 on success. */ 248 GClosure *get_tostring_fn; 249 /* converts val to a string; 250 * caller must free the result */ 251 252 /* These are only valid for OWL_VARIABLE_{INT,BOOL,STRING} */ 253 GValue val; /* current value, if default get_fn/set_fn */ 254 255 GCallback get_fn; 256 /* returns a reference to the current value. 257 * WARNING: this approach is hard to make 258 * thread-safe... */ 259 GCallback validate_fn; 244 260 /* returns 1 if newval is valid */ 245 int (*set_fn)(struct _owl_variable *v, const void *newval);261 GCallback set_fn; 246 262 /* sets the variable to a value 247 * of the appropriate type. 248 * unless documented, this 249 * should make a copy. 250 * returns 0 on success. */ 251 int (*set_fromstring_fn)(struct _owl_variable *v, const char *newval); 252 /* sets the variable to a value 253 * of the appropriate type. 254 * unless documented, this 255 * should make a copy. 256 * returns 0 on success. */ 257 const void *(*get_fn)(const struct _owl_variable *v); 258 /* returns a reference to the current value. 259 * WARNING: this approach is hard to make 260 * thread-safe... */ 261 CALLER_OWN char *(*get_tostring_fn)(const struct _owl_variable *v, const void *val); 262 /* converts val to a string; 263 * caller must free the result */ 264 void (*delete_fn)(struct _owl_variable *v); 265 /* frees val as needed */ 263 * of the appropriate type. 264 * unless documented, this 265 * should make a copy. 266 * returns 0 on success. */ 266 267 } owl_variable; 268 267 269 268 270 typedef struct _owl_input { … … 569 571 time_t starttime; 570 572 time_t lastinputtime; 573 time_t last_wakeup_time; 571 574 char *startupargs; 572 575 int nextmsgid; … … 596 599 char *kill_buffer; 597 600 int interrupt_count; 601 #if GLIB_CHECK_VERSION(2, 31, 0) 602 GMutex interrupt_lock; 603 #else 598 604 GMutex *interrupt_lock; 605 #endif 599 606 } owl_global; 600 607 … … 602 609 extern owl_global g; 603 610 604 #include "owl_prototypes.h"611 #include <owl_prototypes.h> 605 612 606 613 /* These were missing from the Zephyr includes before Zephyr 3. */ … … 610 617 #endif 611 618 619 /* We have to dynamically bind these ourselves */ 620 extern gboolean (*gvalue_from_sv) (GValue * value, SV * sv); 621 extern SV * (*sv_from_gvalue) (const GValue * value); 622 extern GClosure * (*perl_closure_new) (SV * callback, SV * data, gboolean swap); 623 624 612 625 #endif /* INC_BARNOWL_OWL_H */ -
owl_perl.h
rf271129 r92ffd89 4 4 #include <stdio.h> 5 5 6 #define OWL_PERL_VOID_CALL (void)POPs; 6 /* 7 * This macro defines a convenience wrapper around the boilerplate 8 * of pushing char * arguments on to the stack for perl calling. 9 * 10 * Arguments are 11 * * i - the counter variable to use, which must be declared prior 12 * to calling this macro 13 * * argc - the number of arguments 14 * * argv - an array of char*s, of length at least argc; the arguments 15 * to push on to the stack 16 */ 17 #define OWL_PERL_PUSH_ARGS(i, argc, argv) { \ 18 for (i = 0; i < argc; i++) { \ 19 XPUSHs(sv_2mortal(owl_new_sv(argv[i]))); \ 20 } \ 21 } 7 22 8 23 /* 9 24 * This macro defines a convenience wrapper around the boilerplate of 10 * calling a method on a perl object (SV*) from C.25 * the perlcall methods. 11 26 * 12 27 * Arguments are 13 * * obj - the SV* to call the method on 14 * * meth - a char* method name 15 * * args - a code block responsible for pushing args (other than the object) 16 * * err - a string with a %s format specifier to log in case of error 17 * * fatalp - if true, perl errors terminate BarnOwl 18 * * ret - a code block executed if the call succeeded 28 * * call - the line of code to make the perl call 29 * * args - a code block responsible for pushing args 30 * * err - a string with a %s format specifier to log in case of error 31 * * fatalp - if true, perl errors terminate BarnOwl 32 * * discardret - should be true if no return is expected 33 * (if the call is passed the flag G_DISCARD or G_VOID) 34 * * ret - a code block executed if the call succeeded 19 35 * 20 36 * See also: `perldoc perlcall', `perldoc perlapi' 21 37 */ 22 #define OWL_PERL_CALL_METHOD(obj, meth, args, err, fatalp, ret) { \ 23 int count; \ 24 dSP; \ 25 ENTER; \ 26 SAVETMPS; \ 27 PUSHMARK(SP); \ 28 XPUSHs(obj); \ 29 {args} \ 30 PUTBACK; \ 31 \ 32 count = call_method(meth, G_SCALAR|G_EVAL); \ 33 \ 34 SPAGAIN; \ 35 \ 36 if(count != 1) { \ 37 fprintf(stderr, "perl returned wrong count: %d\n", count); \ 38 abort(); \ 38 #define OWL_PERL_CALL(call, args, err, fatalp, discardret, ret) { \ 39 int count; \ 40 dSP; \ 41 \ 42 ENTER; \ 43 SAVETMPS; \ 44 \ 45 PUSHMARK(SP); \ 46 {args} \ 47 PUTBACK; \ 48 \ 49 count = call; \ 50 \ 51 SPAGAIN; \ 52 \ 53 if (!discardret && count != 1) { \ 54 croak("Perl returned wrong count: %d\n", count); \ 55 } \ 56 \ 57 if (SvTRUE(ERRSV)) { \ 58 if (fatalp) { \ 59 fprintf(stderr, err, SvPV_nolen(ERRSV)); \ 60 exit(-1); \ 61 } else { \ 62 owl_function_error(err, SvPV_nolen(ERRSV)); \ 63 if (!discardret) (void)POPs; \ 64 sv_setsv(ERRSV, &PL_sv_undef); \ 39 65 } \ 40 if (SvTRUE(ERRSV)) { \ 41 if(fatalp) { \ 42 printf(err, SvPV_nolen(ERRSV)); \ 43 exit(-1); \ 44 } else { \ 45 owl_function_error(err, SvPV_nolen(ERRSV)); \ 46 (void)POPs; \ 47 sv_setsv(ERRSV, &PL_sv_undef); \ 48 } \ 49 } else { \ 50 ret; \ 51 } \ 52 PUTBACK; \ 53 FREETMPS; \ 54 LEAVE; \ 66 } else if (!discardret) { \ 67 ret; \ 68 } \ 69 PUTBACK; \ 70 FREETMPS; \ 71 LEAVE; \ 55 72 } 56 73 -
perl/Makefile.am
r10557e6 ra870319 1 1 SUBDIRS = modules 2 nobase_dist_pkgdata_DATA = \ 3 lib/BarnOwl.pm \ 4 lib/BarnOwl/Complete/AIM.pm \ 5 lib/BarnOwl/Complete/Client.pm \ 6 lib/BarnOwl/Complete/Filter.pm \ 7 lib/BarnOwl/Complete/Zephyr.pm \ 8 lib/BarnOwl/Completion.pm \ 9 lib/BarnOwl/Completion/Context.pm \ 10 lib/BarnOwl/Completion/Util.pm \ 11 lib/BarnOwl/Editwin.pm \ 12 lib/BarnOwl/Help.pm \ 13 lib/BarnOwl/Hook.pm \ 14 lib/BarnOwl/Hooks.pm \ 15 lib/BarnOwl/MainLoopCompatHook.pm \ 16 lib/BarnOwl/Message.pm \ 17 lib/BarnOwl/Message/AIM.pm \ 18 lib/BarnOwl/Message/Admin.pm \ 19 lib/BarnOwl/Message/Generic.pm \ 20 lib/BarnOwl/Message/Loopback.pm \ 21 lib/BarnOwl/Message/Zephyr.pm \ 22 lib/BarnOwl/ModuleLoader.pm \ 23 lib/BarnOwl/Parse.pm \ 24 lib/BarnOwl/Style.pm \ 25 lib/BarnOwl/Style/Basic.pm \ 26 lib/BarnOwl/Style/Default.pm \ 27 lib/BarnOwl/Style/Legacy.pm \ 28 lib/BarnOwl/Style/OneLine.pm \ 29 lib/BarnOwl/Timer.pm \ 30 lib/BarnOwl/Zephyr.pm \ 31 lib/Module/Install/BarnOwl.pm -
perl/lib/BarnOwl.pm
r8135737 recd4edf 5 5 6 6 use base qw(Exporter); 7 our @EXPORT_OK = qw(command getcurmsg getnumcols getidletime 7 our @EXPORT_OK = qw(command getcurmsg getnumcols getnumlines getidletime 8 register_idle_watcher unregister_idle_watcher 8 9 zephyr_getsender zephyr_getrealm zephyr_zwrite 9 10 zephyr_stylestrip zephyr_smartstrip_user zephyr_getsubs … … 14 15 error debug 15 16 create_style getnumcolors wordwrap 17 message_matches_filter 16 18 add_dispatch remove_dispatch 17 19 add_io_dispatch remove_io_dispatch 18 20 new_command 19 21 new_variable_int new_variable_bool new_variable_string 22 new_variable_enum 20 23 quote redisplay); 21 24 our %EXPORT_TAGS = (all => \@EXPORT_OK); … … 44 47 45 48 use List::Util qw(max); 49 use Tie::RefHash; 46 50 47 51 =head1 NAME … … 92 96 Sends a zephyr programmatically. C<COMMAND> should be a C<zwrite> 93 97 command line, and C<MESSAGE> is the zephyr body to send. 98 99 =cut 100 101 sub zephyr_zwrite { 102 my ($command, $message) = @_; 103 my $ret = BarnOwl::Internal::zephyr_zwrite($command, $message); 104 die "Error sending zephyr" unless $ret == 0; 105 } 94 106 95 107 =head2 ztext_stylestrip STRING … … 230 242 231 243 Returns the number of colors this BarnOwl is capable of displaying 244 245 =head2 message_matches_filter MESSAGE FILTER_NAME [QUIET = 0] 246 247 Returns 1 if C<FILTER_NAME> is the name of a valid filter, and 248 C<MESSAGE> matches that filter. Returns 0 otherwise. If 249 C<QUIET> is false, this method displays an error message if 250 if C<FILTER_NAME> does not name a valid filter. 232 251 233 252 =head2 add_dispatch FD CALLBACK … … 394 413 =head2 new_variable_string NAME [{ARGS}] 395 414 396 Add a new owl variable, either an int, a bool, or a string, with the 415 =head2 new_variable_enum NAME [{ARGS}] 416 417 Add a new owl variable, either an int, a bool, a string, or an enum with the 397 418 specified name. 398 419 399 ARGS can optionally contain the following keys: 420 For new_variable_enum, ARGS is required to contain a validsettings key pointing 421 to an array reference. For all four, it can optionally contain the following 422 keys: 400 423 401 424 =over 4 … … 415 438 =back 416 439 440 In addition, new_variable_string optionally accepts a string validsettings 441 parameter, in case people want to set it to "<path>". 442 417 443 =cut 418 444 419 445 sub new_variable_int { 420 unshift @_, \&BarnOwl::Internal::new_variable_int, 0; 421 goto \&_new_variable; 446 my ($name, $args) = @_; 447 my $storage = defined($args->{default}) ? $args->{default} : 0; 448 BarnOwl::new_variable_full($name, { 449 %{$args}, 450 get_tostring => sub { "$storage" }, 451 set_fromstring => sub { 452 die "Expected integer" unless $_[0] =~ /^-?[0-9]+$/; 453 $storage = 0 + $_[0]; 454 }, 455 validsettings => "<int>", 456 takes_on_off => 0, 457 }); 422 458 } 423 459 424 460 sub new_variable_bool { 425 unshift @_, \&BarnOwl::Internal::new_variable_bool, 0; 426 goto \&_new_variable; 461 my ($name, $args) = @_; 462 my $storage = defined($args->{default}) ? $args->{default} : 0; 463 BarnOwl::new_variable_full($name, { 464 %{$args}, 465 get_tostring => sub { $storage ? "on" : "off" }, 466 set_fromstring => sub { 467 die "Valid settings are on/off" unless $_[0] eq "on" || $_[0] eq "off"; 468 $storage = $_[0] eq "on"; 469 }, 470 validsettings => "on,off", 471 takes_on_off => 1, 472 }); 427 473 } 428 474 429 475 sub new_variable_string { 430 unshift @_, \&BarnOwl::Internal::new_variable_string, ""; 431 goto \&_new_variable; 432 } 433 434 sub _new_variable { 435 my $func = shift; 436 my $default_default = shift; 476 my ($name, $args) = @_; 477 my $storage = defined($args->{default}) ? $args->{default} : ""; 478 BarnOwl::new_variable_full($name, { 479 # Allow people to override this one if they /reaaally/ want to for 480 # some reason. Though we still reserve the right to interpret this 481 # value in interesting ways for tab-completion purposes. 482 validsettings => "<string>", 483 %{$args}, 484 get_tostring => sub { $storage }, 485 set_fromstring => sub { $storage = $_[0]; }, 486 takes_on_off => 0, 487 }); 488 } 489 490 sub new_variable_enum { 491 my ($name, $args) = @_; 492 493 # Gather the valid settings. 494 die "validsettings is required" unless defined($args->{validsettings}); 495 my %valid; 496 map { $valid{$_} = 1 } @{$args->{validsettings}}; 497 498 my $storage = (defined($args->{default}) ? 499 $args->{default} : 500 $args->{validsettings}->[0]); 501 BarnOwl::new_variable_full($name, { 502 %{$args}, 503 get_tostring => sub { $storage }, 504 set_fromstring => sub { 505 die "Invalid input" unless $valid{$_[0]}; 506 $storage = $_[0]; 507 }, 508 validsettings => join(",", @{$args->{validsettings}}) 509 }); 510 } 511 512 =head2 new_variable_full NAME {ARGS} 513 514 Create a variable, in full generality. The keyword arguments have types below: 515 516 get_tostring : () -> string 517 set_fromstring : string -> int 518 -- optional -- 519 summary : string 520 description : string 521 validsettings : string 522 takes_on_off : int 523 524 The get/set functions are required. Note that the caller manages storage for the 525 variable. get_tostring/set_fromstring both convert AND store the value. 526 set_fromstring dies on failure. 527 528 If the variable takes parameters 'on' and 'off' (i.e. is boolean-looking), set 529 takes_on_off to 1. This makes :set VAR and :unset VAR work. set_fromstring will 530 be called with those arguments. 531 532 =cut 533 534 sub new_variable_full { 437 535 my $name = shift; 438 536 my $args = shift || {}; 439 537 my %args = ( 440 summary 538 summary => "", 441 539 description => "", 442 default => $default_default, 540 takes_on_off => 0, 541 validsettings => "<string>", 443 542 %{$args}); 444 $func->($name, $args{default}, $args{summary}, $args{description}); 543 544 die "get_tostring required" unless $args{get_tostring}; 545 die "set_fromstring required" unless $args{set_fromstring}; 546 547 # Strip off the bogus dummy argument. Aargh perl-Glib. 548 my $get_tostring_fn = sub { $args{get_tostring}->() }; 549 my $set_fromstring_fn = sub { 550 my ($dummy, $val) = @_; 551 # Translate from user-supplied die-on-failure callback to expected 552 # non-zero on error. Less of a nuisance than interacting with ERRSV. 553 eval { $args{set_fromstring}->($val) }; 554 # TODO: Consider changing B::I::new_variable to expect string|NULL with 555 # string as the error message. That can then be translated to a GError in 556 # owl_variable_set_fromstring. For now the string is ignored. 557 return ($@ ? -1 : 0); 558 }; 559 560 BarnOwl::Internal::new_variable($name, $args{summary}, $args{description}, $args{validsettings}, 561 $args{takes_on_off}, $get_tostring_fn, $set_fromstring_fn, undef); 445 562 } 446 563 … … 678 795 } 679 796 797 =head3 register_idle_watcher %ARGS 798 799 Call a callback whenever the amount of time the user becomes idle or comes 800 back from being idle. 801 802 You must include the following parameters: 803 804 =over 4 805 806 =item name 807 808 The name given to the idle watcher 809 810 =item after 811 812 How long the user must be idle, in seconds, before the callback is called. 813 If the value is too small, you may have spurious or inaccurate calls. 814 (The current lower limit is about 1 second.) 815 816 =item callback 817 818 The Perl subroutine that gets called when the user has been idle for C<AFTER> 819 seconds, or comes back from being idle. The subroutine is passed one parameter, 820 which is true if the user is currently idle, and false otherwise. 821 822 =back 823 824 This method returns a unique identifier which may be passed to 825 L<BarnOwl::unregister_idle_watcher>. 826 827 =cut 828 829 =head3 unregister_idle_watcher UNIQUE_ID [...] 830 831 Removed and returns the idle watcher specified by C<UNIQUE_ID>. 832 You may specify multiple unique ids. 833 834 =cut 835 836 my %idle_watchers; 837 tie %idle_watchers, 'Tie::RefHash'; 838 839 $BarnOwl::Hooks::wakeup->add(sub { 840 foreach my $idle_watcher (values %idle_watchers) { 841 _wakeup_idle_watcher($idle_watcher); 842 } 843 }); 844 845 sub _wakeup_idle_watcher { 846 my ($idle_watcher, $offset) = @_; 847 $offset = 0 unless defined $offset; 848 # go unidle 849 $idle_watcher->{idle_timer}->stop if $idle_watcher->{idle_timer}; 850 undef $idle_watcher->{idle_timer}; 851 $idle_watcher->{callback}->(0) if $idle_watcher->{is_idle}; 852 $idle_watcher->{is_idle} = 0; 853 854 # queue going idle 855 $idle_watcher->{idle_timer} = BarnOwl::Timer->new({ 856 name => $idle_watcher->{name}, 857 after => $idle_watcher->{after} - $offset, 858 cb => sub { 859 $idle_watcher->{is_idle} = 1; 860 $idle_watcher->{callback}->(1); 861 } 862 }); 863 } 864 865 sub register_idle_watcher { 866 my %args = (@_); 867 $idle_watchers{\%args} = \%args; 868 _wakeup_idle_watcher(\%args, BarnOwl::getidletime); # make sure to queue up the idle/unidle events from this idle watcher 869 return \%args; 870 } 871 872 sub unregister_idle_watcher { 873 my ($id) = @_; 874 $idle_watchers{$id}->{idle_timer}->stop if $idle_watchers{$id}->{idle_timer}; 875 return delete $idle_watchers{$id}; 876 } 877 680 878 # Stub for owl::startup / BarnOwl::startup, so it isn't bound to the 681 879 # startup command. This may be redefined in a user's configfile. -
perl/lib/BarnOwl/Complete/Client.pm
rd973a73 r4626016 20 20 21 21 my %show = ( 22 information => undef,23 22 colors => undef, 24 23 commands => undef, -
perl/lib/BarnOwl/Complete/Zephyr.pm
r3e8625f re6e7842 64 64 BarnOwl::Completion::register_completer(viewuser => \&complete_viewuser); 65 65 BarnOwl::Completion::register_completer(vu => \&complete_viewuser); 66 BarnOwl::Completion::register_completer(viewperson => \&complete_viewuser); 67 BarnOwl::Completion::register_completer(vp => \&complete_viewuser); 66 68 67 69 BarnOwl::Completion::register_completer(unsub => \&complete_unsub); -
perl/lib/BarnOwl/Hooks.pm
rb8a3e00 r120dac7 36 36 Called before BarnOwl shutdown 37 37 38 =item $wakeup 39 40 Called, at most once per second, on user input 41 38 42 =item $receiveMessage 39 43 … … 57 61 from every function registered with this hook will be appended and 58 62 displayed in a popup window, with zephyr formatting parsed. 63 64 =item $awayOn 65 66 Called, for all protocol handlers, to go away, with the away message, 67 if any. 68 69 =item $awayOff 70 71 Called, for all protocol handlers, to come back from away. 72 73 =item $getIsAway 74 75 Called to check away status for all protocol handlers. Protocol 76 handlers should return a true value if any account of the user is away 77 for the given protocol, and a false value otherwise. 59 78 60 79 =item $getQuickstart … … 73 92 74 93 our @EXPORT_OK = qw($startup $shutdown 94 $wakeup 75 95 $receiveMessage $newMessage 76 96 $mainLoop $getBuddyList 97 $awayOn $awayOff $getIsAway 77 98 $getQuickstart); 78 99 … … 83 104 our $startup = BarnOwl::Hook->new; 84 105 our $shutdown = BarnOwl::Hook->new; 106 our $wakeup = BarnOwl::Hook->new; 85 107 our $receiveMessage = BarnOwl::Hook->new; 86 108 our $newMessage = BarnOwl::Hook->new; … … 88 110 our $getBuddyList = BarnOwl::Hook->new; 89 111 our $getQuickstart = BarnOwl::Hook->new; 112 our $awayOn = BarnOwl::Hook->new; 113 our $awayOff = BarnOwl::Hook->new; 114 our $getIsAway = BarnOwl::Hook->new; 90 115 91 116 # Internal startup/shutdown routines called by the C code … … 175 200 } 176 201 202 sub _wakeup { 203 $wakeup->run; 204 } 205 177 206 sub _receive_msg { 178 207 my $m = shift; … … 199 228 sub _get_quickstart { 200 229 return join("\n", $getQuickstart->run); 230 } 231 232 sub _away_on { 233 $awayOn->run(@_); 234 } 235 236 sub _away_off { 237 $awayOff->run(); 238 } 239 240 sub _get_is_away { 241 my @is_away = grep { $_ } $getIsAway->run(); 242 return scalar @is_away; 201 243 } 202 244 -
perl/lib/BarnOwl/Message.pm
ra130fc5 r0adbce1 51 51 sub is_ping { return 0; } 52 52 sub is_mail { return 0; } 53 sub is_personal { return shift->is_private; }53 sub is_personal { return BarnOwl::message_matches_filter(shift, "personal"); } 54 54 sub class { return undef; } 55 55 sub instance { return undef; } -
perl/lib/BarnOwl/Message/Zephyr.pm
rbf70350 r0adbce1 51 51 my ($m) = @_; 52 52 return undef if (!$m->is_loginout); 53 return undef if (!defined($m->fields)); 53 54 return $m->fields->[2]; 54 55 } … … 57 58 my ($m) = @_; 58 59 return undef if (!$m->is_loginout); 60 return undef if (!defined($m->fields)); 59 61 return $m->fields->[0]; 60 62 } … … 63 65 64 66 sub is_ping { return (lc(shift->opcode) eq "ping"); } 65 66 sub is_personal {67 my ($m) = @_;68 return ((lc($m->class) eq "message")69 && $m->is_private);70 }71 67 72 68 sub is_mail { -
perl/lib/BarnOwl/Zephyr.pm
rdf569c5 r53151d4 12 12 use BarnOwl::Hook; 13 13 14 my$zephyrStartup = BarnOwl::Hook->new;14 our $zephyrStartup = BarnOwl::Hook->new; 15 15 16 16 sub _zephyr_startup { -
perl/lib/Module/Install/BarnOwl.pm
rb8a3e00 re4b8f93 41 41 my $class = ref $self; 42 42 43 my $srcdir = $ENV{BARNOWL_SRCDIR} || '.'; 44 43 45 $self->name("BarnOwl-Module-$name"); 44 $self->all_from("lib/BarnOwl/Module/$name.pm"); 46 $self->all_from("$srcdir/lib/BarnOwl/Module/$name.pm"); 47 $self->makemaker_args(PMLIBDIRS => ["$srcdir/lib"], 48 PMLIBPARENTDIRS => ["$srcdir/lib"]); 45 49 46 50 $self->postamble(<<"END_MAKEFILE"); 47 51 48 52 # --- $class section: 53 54 BARNOWL_SRCDIR = $srcdir 55 export BARNOWL_SRCDIR 49 56 50 57 $name.par: pm_to_blib -
perl/modules/IRC/lib/BarnOwl/Module/IRC.pm
rb8a3e00 r4f7b1f4 23 23 use Getopt::Long; 24 24 use Encode; 25 use Text::Wrap; 25 26 26 27 our $VERSION = 0.02; … … 67 68 }); 68 69 70 BarnOwl::new_variable_int('irc:max-message-length', { 71 default => 450, 72 summary => 'Split messages to at most this many characters.' . 73 "If non-positive, don't split messages", 74 description => 'If set to a positive number, any paragraph in an ' . 75 'IRC message will be split after this many characters.' 76 }); 77 69 78 register_commands(); 70 79 BarnOwl::filter(qw{irc type ^IRC$ or ( type ^admin$ and adminheader ^IRC$ )}); … … 129 138 argument listed above, and die if no channel argument can be found. 130 139 140 =item C<CHANNEL_OR_USER> 141 142 Pass the channel argument, but accept it if it's a username (e.g. 143 has no hash). Only relevant with C<CHANNEL_ARG>. 144 131 145 =item C<CHANNEL_OPTIONAL> 132 146 … … 145 159 use constant CHANNEL_ARG => 1; 146 160 use constant CHANNEL_OPTIONAL => 2; 147 148 use constant ALLOW_DISCONNECTED => 4; 161 use constant CHANNEL_OR_USER => 4; 162 163 use constant ALLOW_DISCONNECTED => 8; 149 164 150 165 sub register_commands { … … 188 203 189 204 BarnOwl::new_command( 190 'irc-msg' => mk_irc_command( \&cmd_msg ),205 'irc-msg' => mk_irc_command( \&cmd_msg, CHANNEL_OR_USER|CHANNEL_ARG|CHANNEL_OPTIONAL ), 191 206 { 192 207 summary => 'Send an IRC message', … … 427 442 @msgs = split "\n\n", $fullbody; 428 443 map { tr/\n/ / } @msgs; 444 # split each body at irc:max-message-length characters, if that number 445 # is positive. Only split at space boundaries. Start counting a-fresh 446 # at the beginning of each paragraph 447 my $max_len = BarnOwl::getvar('irc:max-message-length'); 448 if ($max_len > 0) { 449 local($Text::Wrap::columns) = $max_len; 450 @msgs = split "\n", wrap("", "", join "\n", @msgs); 451 } 429 452 for my $body (@msgs) { 430 453 if ($body =~ /^\/me (.*)/) { … … 591 614 $conn ||= $c; 592 615 } 616 } elsif (defined($channel) && ($flags & CHANNEL_OR_USER)) { 617 shift @ARGV; 593 618 } elsif ($m && $m->type eq 'IRC' && !$m->is_private) { 594 619 $channel = $m->channel; … … 598 623 } 599 624 600 if(! $channel&&625 if(!defined($channel) && 601 626 ($flags & CHANNEL_ARG) && 602 627 !($flags & CHANNEL_OPTIONAL)) { -
perl/modules/Jabber/lib/Net/Jabber/Component.pm
rc2bed55 ra8c55b5 220 220 $self->{STREAM}->SetCallBacks(node=>undef); 221 221 222 $self->Send("<handshake>".Digest::SHA 1::sha1_hex($self->{SESSION}->{id}.$args{secret})."</handshake>");222 $self->Send("<handshake>".Digest::SHA::sha1_hex($self->{SESSION}->{id}.$args{secret})."</handshake>"); 223 223 my $handshake = $self->Process(); 224 224 -
perl/modules/Jabber/lib/Net/Jabber/Key.pm
rc2bed55 ra8c55b5 104 104 $self->{CACHE} = {}; 105 105 106 if (eval "require Digest::SHA 1")106 if (eval "require Digest::SHA") 107 107 { 108 108 $self->{DIGEST} = 1; 109 Digest::SHA 1->import(qw(sha1 sha1_hex sha1_base64));109 Digest::SHA->import(qw(sha1 sha1_hex sha1_base64)); 110 110 } 111 111 else 112 112 { 113 print "ERROR: You cannot use Key.pm unless you have Digest::SHA 1installed.\n";113 print "ERROR: You cannot use Key.pm unless you have Digest::SHA installed.\n"; 114 114 exit(0); 115 115 } … … 132 132 133 133 my $string = $$.time.rand(1000000); 134 $string = Digest::SHA 1::sha1_hex($string);134 $string = Digest::SHA::sha1_hex($string); 135 135 $self->{DEBUG}->Log1("Generate: key($string)"); 136 136 return $string; -
perl/modules/Jabber/lib/Net/XMPP.pm
rc2bed55 ra8c55b5 213 213 use Time::Local; 214 214 use Carp; 215 use Digest::SHA 1;215 use Digest::SHA; 216 216 use Authen::SASL; 217 217 use MIME::Base64; -
perl/modules/Jabber/lib/Net/XMPP/Protocol.pm
r7f33c18 ra8c55b5 1849 1849 if ($authType eq "zerok") 1850 1850 { 1851 my $hashA = Digest::SHA 1::sha1_hex($password);1852 $args{hash} = Digest::SHA 1::sha1_hex($hashA.$token);1851 my $hashA = Digest::SHA::sha1_hex($password); 1852 $args{hash} = Digest::SHA::sha1_hex($hashA.$token); 1853 1853 1854 1854 for (1..$sequence) 1855 1855 { 1856 $args{hash} = Digest::SHA 1::sha1_hex($args{hash});1856 $args{hash} = Digest::SHA::sha1_hex($args{hash}); 1857 1857 } 1858 1858 } … … 1868 1868 if ($authType eq "digest") 1869 1869 { 1870 $args{digest} = Digest::SHA 1::sha1_hex($self->GetStreamID().$password);1870 $args{digest} = Digest::SHA::sha1_hex($self->GetStreamID().$password); 1871 1871 } 1872 1872 -
perl/modules/Makefile.am
r35c5bd8 re4b8f93 1 1 MODULES = Jabber IRC WordWrap Twitter Facebook 2 2 3 EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/inc) $(MODULES:=/lib) 3 EXTRA_DIST = $(MODULES:=/Makefile.PL) $(MODULES:=/lib) 4 EXTRA_DIST += \ 5 Facebook/README \ 6 Twitter/README \ 7 Twitter/twitter.example 4 8 5 9 all-local: $(MODULES) … … 7 11 (cd $* && $(MAKE) $*.par) 8 12 13 BARNOWL_PERL := $(shell which perl) -I$(abs_srcdir)/../lib 14 9 15 MODULES_MAKEFILE = $(MODULES:=/Makefile) 10 $(MODULES_MAKEFILE): %/Makefile: %/Makefile.PL 11 $(AM_V_GEN)(cd $* && perl -I../../lib Makefile.PL) 16 $(MODULES_MAKEFILE): %/Makefile: %/Makefile.PL ../lib/Module/Install/BarnOwl.pm 17 $(AM_V_GEN)test -d $* || mkdir $* 18 $(AM_V_at)test $(srcdir) = . || $(LN_S) $(abs_srcdir)/$*/Makefile.PL $*/Makefile.PL 19 $(AM_V_at)(cd $* && BARNOWL_SRCDIR='$(abs_srcdir)/$*' && export BARNOWL_SRCDIR && $(BARNOWL_PERL) Makefile.PL 'PERL=$(BARNOWL_PERL)') 12 20 13 21 MODULES_CLEAN = $(MODULES:%=clean_%) 14 22 clean-local: $(MODULES_CLEAN) 15 23 $(MODULES_CLEAN): clean_%: 16 (cd $* && (test ! -f Makefile || $(MAKE) clean)) 24 (cd $* && { test ! -f Makefile || $(MAKE) realclean; }) 25 rm -f $*/$*.par 26 rm -rf $*/inc 27 test $(srcdir) = . || rm -f $*/Makefile.PL 17 28 18 29 MODULES_INSTALL = $(MODULES:%=module_install_%) … … 23 34 ${INSTALL_DATA} $*/$*.par ${DESTDIR}${pkgdatadir}/modules/$*.par 24 35 36 uninstall-local: 37 rm -f $(MODULES:%=${DESTDIR}${pkgdatadir}/modules/%.par) 38 25 39 .PHONY: $(MODULES) $(MODULES_CLEAN) $(MODULES_INSTALL) -
perlconfig.c
rd199207 r96d80e9 92 92 owl_new_sv(owl_message_get_##field(m)), 0) 93 93 94 if (owl_message_ get_notice(m)) {94 if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) { 95 95 /* Handle zephyr-specific fields... */ 96 AV *av_zfields; 97 98 av_zfields = newAV(); 99 for (f = owl_zephyr_first_raw_field(owl_message_get_notice(m)); f != NULL; 100 f = owl_zephyr_next_raw_field(owl_message_get_notice(m), f)) { 101 ptr=owl_zephyr_field_as_utf8(owl_message_get_notice(m), f); 102 av_push(av_zfields, owl_new_sv(ptr)); 103 g_free(ptr); 96 AV *av_zfields = newAV(); 97 if (owl_message_get_notice(m)) { 98 for (f = owl_zephyr_first_raw_field(owl_message_get_notice(m)); f != NULL; 99 f = owl_zephyr_next_raw_field(owl_message_get_notice(m), f)) { 100 ptr = owl_zephyr_field_as_utf8(owl_message_get_notice(m), f); 101 av_push(av_zfields, owl_new_sv(ptr)); 102 g_free(ptr); 103 } 104 (void)hv_store(h, "auth", strlen("auth"), 105 owl_new_sv(owl_zephyr_get_authstr(owl_message_get_notice(m))), 0); 106 } else { 107 /* Incoming zephyrs without a ZNotice_t are pseudo-logins. To appease 108 * existing styles, put in bogus 'auth' and 'fields' keys. */ 109 (void)hv_store(h, "auth", strlen("auth"), owl_new_sv("NO"), 0); 104 110 } 105 111 (void)hv_store(h, "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0); 106 107 (void)hv_store(h, "auth", strlen("auth"),108 owl_new_sv(owl_zephyr_get_authstr(owl_message_get_notice(m))),0);109 112 } 110 113 … … 225 228 CALLER_OWN char *owl_perlconfig_call_with_message(const char *subname, const owl_message *m) 226 229 { 227 dSP ; 228 int count; 229 SV *msgref, *srv; 230 char *out; 231 232 ENTER ; 233 SAVETMPS; 234 235 PUSHMARK(SP) ; 230 SV *msgref, *rv; 231 char *out = NULL; 232 236 233 msgref = owl_perlconfig_message2hashref(m); 237 XPUSHs(sv_2mortal(msgref)); 238 PUTBACK ; 239 240 count = call_pv(subname, G_SCALAR|G_EVAL); 241 242 SPAGAIN ; 243 244 if (SvTRUE(ERRSV)) { 245 owl_function_error("Perl Error: '%s'", SvPV_nolen(ERRSV)); 246 /* and clear the error */ 247 sv_setsv (ERRSV, &PL_sv_undef); 248 } 249 250 if (count != 1) { 251 fprintf(stderr, "bad perl! no biscuit! returned wrong count!\n"); 252 abort(); 253 } 254 255 srv = POPs; 256 257 if (srv) { 258 out = g_strdup(SvPV_nolen(srv)); 259 } else { 260 out = NULL; 261 } 262 263 PUTBACK ; 264 FREETMPS ; 265 LEAVE ; 266 234 235 OWL_PERL_CALL((call_pv(subname, G_SCALAR|G_EVAL)) 236 , 237 XPUSHs(sv_2mortal(msgref)); 238 , 239 "Perl Error: '%s'" 240 , 241 false 242 , 243 false 244 , 245 rv = POPs; 246 if (rv && SvPOK(rv)) 247 out = g_strdup(SvPV_nolen(rv)); 248 ); 267 249 return out; 268 250 } … … 274 256 CALLER_OWN char *owl_perlconfig_message_call_method(const owl_message *m, const char *method, int argc, const char **argv) 275 257 { 276 dSP; 277 unsigned int count, i; 278 SV *msgref, *srv; 279 char *out; 258 SV *msgref, *rv; 259 char *out = NULL; 260 int i; 280 261 281 262 msgref = owl_perlconfig_message2hashref(m); 282 263 283 ENTER; 284 SAVETMPS; 285 286 PUSHMARK(SP); 287 XPUSHs(sv_2mortal(msgref)); 288 for(i=0;i<argc;i++) { 289 XPUSHs(sv_2mortal(owl_new_sv(argv[i]))); 290 } 291 PUTBACK; 292 293 count = call_method(method, G_SCALAR|G_EVAL); 294 295 SPAGAIN; 296 297 if(count != 1) { 298 fprintf(stderr, "perl returned wrong count %u\n", count); 299 abort(); 300 } 301 302 if (SvTRUE(ERRSV)) { 303 owl_function_error("Error: '%s'", SvPV_nolen(ERRSV)); 304 /* and clear the error */ 305 sv_setsv (ERRSV, &PL_sv_undef); 306 } 307 308 srv = POPs; 309 310 if (srv) { 311 out = g_strdup(SvPV_nolen(srv)); 312 } else { 313 out = NULL; 314 } 315 316 PUTBACK; 317 FREETMPS; 318 LEAVE; 319 264 OWL_PERL_CALL(call_method(method, G_SCALAR|G_EVAL) 265 , 266 XPUSHs(sv_2mortal(msgref)); 267 OWL_PERL_PUSH_ARGS(i, argc, argv); 268 , 269 "Perl Error: '%s'" 270 , 271 false 272 , 273 false 274 , 275 rv = POPs; 276 if (rv && SvPOK(rv)) 277 out = g_strdup(SvPV_nolen(rv)); 278 ); 320 279 return out; 321 280 } … … 328 287 char *err; 329 288 const char *args[4] = {"", "-e", "0;", NULL}; 289 const char *dlerr; 330 290 AV *inc; 331 291 char *path; … … 385 345 g_free(path); 386 346 347 /* Load up perl-Glib. */ 348 eval_pv("use Glib;", FALSE); 349 350 /* Now, before BarnOwl tries to use them, get the relevant function pointers out. */ 351 dlerr = owl_closure_init(); 352 if (dlerr) { 353 return g_strdup(dlerr); 354 } 355 356 /* And now it's safe to import BarnOwl. */ 387 357 eval_pv("use BarnOwl;", FALSE); 388 358 … … 456 426 void owl_perlconfig_new_command(const char *name) 457 427 { 458 dSP; 459 460 ENTER; 461 SAVETMPS; 462 463 PUSHMARK(SP); 464 XPUSHs(sv_2mortal(owl_new_sv(name))); 465 PUTBACK; 466 467 call_pv("BarnOwl::Hooks::_new_command", G_VOID|G_EVAL); 468 469 SPAGAIN; 470 471 if(SvTRUE(ERRSV)) { 472 owl_function_error("%s", SvPV_nolen(ERRSV)); 473 } 474 475 FREETMPS; 476 LEAVE; 428 OWL_PERL_CALL(call_pv("BarnOwl::Hooks::_new_command", G_VOID|G_EVAL); 429 , 430 XPUSHs(sv_2mortal(owl_new_sv(name))); 431 , 432 "Perl Error: '%s'" 433 , 434 false 435 , 436 true 437 , 438 ); 439 } 440 441 CALLER_OWN char *owl_perlconfig_perl_call(const char *method, int argc, const char *const *argv) 442 { 443 SV *rv; 444 char *out = NULL; 445 int i; 446 OWL_PERL_CALL(call_pv(method, G_SCALAR|G_EVAL) 447 , 448 OWL_PERL_PUSH_ARGS(i, argc, argv); 449 , 450 "Perl Error: '%s'" 451 , 452 false 453 , 454 false 455 , 456 rv = POPs; 457 if (rv && SvPOK(rv)) 458 out = g_strdup(SvPV_nolen(rv)); 459 ); 460 return out; 461 } 462 463 int owl_perlconfig_perl_call_int(const char *method, int argc, const char *const *argv) 464 { 465 SV *rv; 466 int ret = -1; 467 int i; 468 OWL_PERL_CALL(call_pv(method, G_SCALAR|G_EVAL) 469 , 470 OWL_PERL_PUSH_ARGS(i, argc, argv); 471 , 472 "Perl Error: '%s'" 473 , 474 false 475 , 476 false 477 , 478 rv = POPs; 479 if (rv && SvIOK(rv)) 480 ret = SvIV(rv); 481 ); 482 return ret; 483 } 484 485 bool owl_perlconfig_perl_call_bool(const char *method, int argc, const char *const *argv) 486 { 487 SV *rv; 488 bool ret = false; 489 int i; 490 OWL_PERL_CALL(call_pv(method, G_SCALAR|G_EVAL) 491 , 492 OWL_PERL_PUSH_ARGS(i, argc, argv); 493 , 494 "Perl Error: '%s'" 495 , 496 false 497 , 498 false 499 , 500 rv = POPs; 501 if (rv) 502 ret = SvTRUE(rv); 503 ); 504 return ret; 505 } 506 507 void owl_perlconfig_perl_call_norv(const char *method, int argc, const char *const *argv) 508 { 509 int i; 510 OWL_PERL_CALL(call_pv(method, G_DISCARD|G_EVAL) 511 , 512 OWL_PERL_PUSH_ARGS(i, argc, argv); 513 , 514 "Perl Error: '%s'" 515 , 516 false 517 , 518 true 519 , 520 ); 477 521 } 478 522 … … 480 524 CALLER_OWN char *owl_perlconfig_perlcmd(const owl_cmd *cmd, int argc, const char *const *argv) 481 525 { 482 int i, count; 483 char * ret = NULL; 484 SV *rv; 485 dSP; 486 487 ENTER; 488 SAVETMPS; 489 490 PUSHMARK(SP); 491 for(i=0;i<argc;i++) { 492 XPUSHs(sv_2mortal(owl_new_sv(argv[i]))); 493 } 494 PUTBACK; 495 496 count = call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL); 497 498 SPAGAIN; 499 500 if(SvTRUE(ERRSV)) { 501 owl_function_error("%s", SvPV_nolen(ERRSV)); 502 (void)POPs; 503 } else { 504 if(count != 1) 505 croak("Perl command %s returned more than one value!", cmd->name); 506 rv = POPs; 507 if(SvTRUE(rv)) { 508 ret = g_strdup(SvPV_nolen(rv)); 509 } 510 } 511 512 FREETMPS; 513 LEAVE; 514 515 return ret; 526 int i; 527 SV* rv; 528 char *out = NULL; 529 530 OWL_PERL_CALL(call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL) 531 , 532 OWL_PERL_PUSH_ARGS(i, argc, argv); 533 , 534 "Perl Error: '%s'" 535 , 536 false 537 , 538 false 539 , 540 rv = POPs; 541 if (rv && SvPOK(rv)) 542 out = g_strdup(SvPV_nolen(rv)); 543 ); 544 return out; 516 545 } 517 546 … … 524 553 { 525 554 SV *cb = owl_editwin_get_cbdata(e); 526 SV *text; 527 dSP; 528 529 if(cb == NULL) { 555 SV *text = owl_new_sv(owl_editwin_get_text(e)); 556 557 if (cb == NULL) { 530 558 owl_function_error("Perl callback is NULL!"); 531 559 return; 532 560 } 533 text = owl_new_sv(owl_editwin_get_text(e)); 534 535 ENTER; 536 SAVETMPS; 537 538 PUSHMARK(SP); 539 XPUSHs(sv_2mortal(text)); 540 XPUSHs(sv_2mortal(newSViv(success))); 541 PUTBACK; 542 543 call_sv(cb, G_DISCARD|G_EVAL); 544 545 if(SvTRUE(ERRSV)) { 546 owl_function_error("%s", SvPV_nolen(ERRSV)); 547 } 548 549 FREETMPS; 550 LEAVE; 561 562 OWL_PERL_CALL(call_sv(cb, G_DISCARD|G_EVAL) 563 , 564 XPUSHs(sv_2mortal(text)); 565 XPUSHs(sv_2mortal(newSViv(success))); 566 , 567 "Perl Error: '%s'" 568 , 569 false 570 , 571 true 572 , 573 ); 551 574 } 552 575 -
perlglue.xs
re89ec48 r1ced34f 67 67 OUTPUT: 68 68 RETVAL 69 69 70 int 71 getnumlines() 72 CODE: 73 RETVAL = owl_global_get_lines(&g); 74 OUTPUT: 75 RETVAL 76 70 77 time_t 71 78 getidletime() … … 88 95 OUTPUT: 89 96 RETVAL 90 91 void92 zephyr_zwrite(cmd,msg)93 const char *cmd94 const char *msg95 PREINIT:96 int i;97 CODE:98 i = owl_zwrite_create_and_send_from_line(cmd, msg);99 97 100 98 const utf8 * … … 257 255 } 258 256 } 257 258 bool 259 message_matches_filter(message, filter_name, quiet = false) 260 SV *message 261 const char *filter_name 262 bool quiet 263 PREINIT: 264 owl_message *m; 265 const owl_filter *f; 266 CODE: 267 { 268 if (!SvROK(message) || SvTYPE(SvRV(message)) != SVt_PVHV) { 269 croak("Usage: BarnOwl::message_matches_filter($message, $filter_name[, $quiet])"); 270 } 271 272 m = owl_perlconfig_hashref2message(message); 273 f = owl_global_get_filter(&g, filter_name); 274 if (!f && !quiet) { 275 owl_function_error("%s filter is not defined", filter_name); 276 } 277 RETVAL = f && owl_filter_message_match(f, m); 278 } 279 OUTPUT: 280 RETVAL 281 CLEANUP: 282 owl_message_delete(m); 259 283 260 284 const utf8 * … … 404 428 } 405 429 406 void 407 new_variable_string(name, ival, summ, desc) 408 const char * name 409 const char * ival 410 const char * summ 411 const char * desc 412 CODE: 413 owl_variable_dict_newvar_string(owl_global_get_vardict(&g), 414 name, 415 summ, 416 desc, 417 ival); 418 419 void 420 new_variable_int(name, ival, summ, desc) 421 const char * name 422 int ival 423 const char * summ 424 const char * desc 425 CODE: 426 owl_variable_dict_newvar_int(owl_global_get_vardict(&g), 427 name, 428 summ, 429 desc, 430 ival); 431 432 void 433 new_variable_bool(name, ival, summ, desc) 434 const char * name 435 int ival 436 const char * summ 437 const char * desc 438 CODE: 439 owl_variable_dict_newvar_bool(owl_global_get_vardict(&g), 440 name, 441 summ, 442 desc, 443 ival); 430 431 MODULE = BarnOwl PACKAGE = BarnOwl::Internal 432 433 void 434 new_variable(name, summary, description, validsettings, takes_on_off, get_tostring_fn, set_fromstring_fn, data) 435 const char *name 436 const char *summary 437 const char *description 438 const char *validsettings 439 int takes_on_off 440 SV *get_tostring_fn 441 SV *set_fromstring_fn 442 SV *data 443 CODE: 444 { 445 /* data is somewhat redundant given we can create closures, but oh 446 * well. Might be convenient sometimes. */ 447 if(!SV_IS_CODEREF(get_tostring_fn)) { 448 croak("To-string function must be a coderef!"); 449 } 450 if(!SV_IS_CODEREF(set_fromstring_fn)) { 451 croak("From-string function must be a coderef!"); 452 } 453 454 owl_variable_dict_newvar_other(owl_global_get_vardict(&g), 455 name, summary, description, validsettings, takes_on_off, 456 perl_closure_new(get_tostring_fn, data, false), 457 perl_closure_new(set_fromstring_fn, data, false)); 458 } 444 459 445 460 void … … 468 483 } 469 484 485 int 486 zephyr_zwrite(cmd,msg) 487 const char *cmd 488 const char *msg 489 CODE: 490 RETVAL = owl_zwrite_create_and_send_from_line(cmd, msg); 491 OUTPUT: 492 RETVAL 493 470 494 MODULE = BarnOwl PACKAGE = BarnOwl::Editwin 471 495 -
runtests.sh
rf6ab6ee r5db8835 1 1 #!/bin/sh 2 exec env HARNESS_PERL=./tester prove --failures t/2 exec env HARNESS_PERL=./tester prove --failures "${srcdir:=$(dirname "$0")}/t/" -
sepbar.c
r6eb3ed9 ra38becd 67 67 } 68 68 69 if (owl_ global_is_zaway(&g) || owl_global_is_aaway(&g)) {69 if (owl_function_is_away()) { 70 70 getyx(sepwin, y, x); 71 71 wmove(sepwin, y, x+2); 72 72 wattron(sepwin, A_BOLD); 73 73 wattroff(sepwin, A_REVERSE); 74 if (owl_global_is_zaway(&g) && owl_global_is_aaway(&g)) { 75 waddstr(sepwin, " AWAY "); 76 } else if (owl_global_is_zaway(&g)) { 77 waddstr(sepwin, " Z-AWAY "); 78 } else if (owl_global_is_aaway(&g)) { 79 waddstr(sepwin, " A-AWAY "); 80 } 74 waddstr(sepwin, " AWAY "); 81 75 wattron(sepwin, A_REVERSE); 82 76 wattroff(sepwin, A_BOLD); -
style.c
r14be3a5 r92ffd89 23 23 { 24 24 SV *sv = NULL; 25 OWL_PERL_CALL _METHOD(s->perlobj,26 "description",27 ;,28 "Error in style_get_description: %s",29 0,30 31 32 if (sv) {25 OWL_PERL_CALL(call_method("description", G_SCALAR|G_EVAL), 26 XPUSHs(s->perlobj);, 27 "Error in style_get_description: %s", 28 0, 29 false, 30 sv = SvREFCNT_inc(POPs); 31 ); 32 if (sv) { 33 33 return SvPV_nolen(sv_2mortal(sv)); 34 34 } else { … … 50 50 51 51 /* Call the perl object */ 52 OWL_PERL_CALL_METHOD(s->perlobj, 53 "format_message", 54 XPUSHs(sv_2mortal(owl_perlconfig_message2hashref(m)));, 55 "Error in format_message: %s", 56 0, 57 sv = SvREFCNT_inc(POPs); 58 ); 52 OWL_PERL_CALL(call_method("format_message", G_SCALAR|G_EVAL), 53 XPUSHs(s->perlobj); 54 XPUSHs(sv_2mortal(owl_perlconfig_message2hashref(m)));, 55 "Error in format_message: %s", 56 0, 57 false, 58 sv = SvREFCNT_inc(POPs); 59 ); 59 60 60 if (sv) {61 if (sv) { 61 62 body = SvPV_nolen(sv); 62 63 } else { -
t/00-core-tests.t
r95414bf r5db8835 1 1 #!/usr/bin/env perl 2 use File::Basename; 3 system(dirname($0) . "/../tester", "--builtin"); 2 system("./tester", "--builtin"); -
tester.c
r97cdbaf5 r6a8b519 133 133 { 134 134 int numfailed=0; 135 char * s, *path, *home;135 char *path, *home; 136 136 137 137 printf("# BEGIN testing owl_util\n"); … … 229 229 230 230 231 s = owl_util_baseclass("barnowl"); 232 FAIL_UNLESS("baseclass barnowl", !strcmp("barnowl", s)); 233 g_free(s); 234 s = owl_util_baseclass("unbarnowl"); 235 FAIL_UNLESS("baseclass unbarnowl", !strcmp("barnowl", s)); 236 g_free(s); 237 s = owl_util_baseclass("unununbarnowl.d.d"); 238 FAIL_UNLESS("baseclass unununbarnowl.d.d", !strcmp("barnowl", s)); 239 g_free(s); 240 s = owl_util_baseclass("ununun.d.d"); 241 FAIL_UNLESS("baseclass ununun.d.d", !strcmp("", s)); 242 g_free(s); 243 s = owl_util_baseclass("d.d.d.d"); 244 FAIL_UNLESS("baseclass d.d.d.d", !strcmp("d", s)); 245 g_free(s); 246 s = owl_util_baseclass("n.d.d.d"); 247 FAIL_UNLESS("baseclass n.d.d.d", !strcmp("n", s)); 248 g_free(s); 249 s = owl_util_baseclass("ununun."); 250 FAIL_UNLESS("baseclass ununun.", !strcmp(".", s)); 251 g_free(s); 252 s = owl_util_baseclass("unununu"); 253 FAIL_UNLESS("baseclass unununu", !strcmp("u", s)); 254 g_free(s); 255 256 257 s = owl_util_makepath("foo/bar"); 258 FAIL_UNLESS("makepath foo/bar", !strcmp("foo/bar", s)); 259 g_free(s); 260 s = owl_util_makepath("//foo///bar"); 261 FAIL_UNLESS("makepath //foo///bar", !strcmp("/foo/bar", s)); 262 g_free(s); 263 s = owl_util_makepath("foo/~//bar/"); 264 FAIL_UNLESS("makepath foo/~//bar/", !strcmp("foo/~/bar/", s)); 265 g_free(s); 266 s = owl_util_makepath("~thisuserhadreallybetternotexist/foobar/"); 267 FAIL_UNLESS("makepath ~thisuserhadreallybetternotexist/foobar/", 268 !strcmp("~thisuserhadreallybetternotexist/foobar/", s)); 269 g_free(s); 231 CHECK_STR_AND_FREE("baseclass barnowl", 232 "barnowl", owl_util_baseclass("barnowl")); 233 CHECK_STR_AND_FREE("baseclass unbarnowl", 234 "barnowl", owl_util_baseclass("unbarnowl")); 235 CHECK_STR_AND_FREE("baseclass unununbarnowl.d.d", 236 "barnowl", owl_util_baseclass("unununbarnowl.d.d")); 237 CHECK_STR_AND_FREE("baseclass ununun.d.d", 238 "", owl_util_baseclass("ununun.d.d")); 239 CHECK_STR_AND_FREE("baseclass d.d.d.d", 240 "d", owl_util_baseclass("d.d.d.d")); 241 CHECK_STR_AND_FREE("baseclass n.d.d.d", 242 "n", owl_util_baseclass("n.d.d.d")); 243 CHECK_STR_AND_FREE("baseclass ununun.", 244 ".", owl_util_baseclass("ununun.")); 245 CHECK_STR_AND_FREE("baseclass unununu", 246 "u", owl_util_baseclass("unununu")); 247 248 249 CHECK_STR_AND_FREE("makepath foo/bar", 250 "foo/bar", owl_util_makepath("foo/bar")); 251 CHECK_STR_AND_FREE("makepath //foo///bar", 252 "/foo/bar", owl_util_makepath("//foo///bar")); 253 CHECK_STR_AND_FREE("makepath foo/~//bar/", 254 "foo/~/bar/", owl_util_makepath("foo/~//bar/")); 255 CHECK_STR_AND_FREE("makepath ~thisuserhadreallybetternotexist/foobar/", 256 "~thisuserhadreallybetternotexist/foobar/", 257 owl_util_makepath("~thisuserhadreallybetternotexist/foobar/")); 270 258 271 259 home = g_strdup(owl_global_get_homedir(&g)); 272 s = owl_util_makepath("~"); 273 FAIL_UNLESS("makepath ~", !strcmp(home, s)); 274 g_free(s); 260 CHECK_STR_AND_FREE("makepath ~", 261 home, owl_util_makepath("~")); 275 262 276 263 path = g_build_filename(home, "foo/bar/baz", NULL); 277 s = owl_util_makepath("~///foo/bar//baz"); 278 FAIL_UNLESS("makepath ~///foo/bar//baz", !strcmp(path, s)); 279 g_free(s); 264 CHECK_STR_AND_FREE("makepath ~///foo/bar//baz", 265 path, owl_util_makepath("~///foo/bar//baz")); 280 266 g_free(path); 281 267 g_free(home); … … 288 274 } 289 275 290 s = owl_util_makepath("~root"); 291 FAIL_UNLESS("makepath ~root", !strcmp(home, s)); 292 g_free(s); 276 CHECK_STR_AND_FREE("makepath ~root", 277 home, owl_util_makepath("~root")); 293 278 294 279 path = g_build_filename(home, "foo/bar/baz", NULL); 295 s = owl_util_makepath("~root///foo/bar//baz"); 296 FAIL_UNLESS("makepath ~root///foo/bar//baz", !strcmp(path, s)); 297 g_free(s); 280 CHECK_STR_AND_FREE("makepath ~root///foo/bar//baz", 281 path, owl_util_makepath("~root///foo/bar//baz")); 298 282 g_free(path); 299 283 g_free(home); … … 353 337 int numfailed=0; 354 338 char *value; 355 const void *v;356 339 357 340 printf("# BEGIN testing owl_variable\n"); 358 FAIL_UNLESS("setup", 0==owl_variable_dict_setup(&vd));341 owl_variable_dict_setup(&vd); 359 342 360 343 FAIL_UNLESS("get bool var", NULL != (var = owl_variable_get_var(&vd, "rxping"))); … … 393 376 FAIL_UNLESS("get int 7", 9 == owl_variable_get_int(var)); 394 377 395 owl_variable_dict_newvar_string(&vd, "stringvar", "", "", "testval"); 378 FAIL_UNLESS("get enum var", NULL != (var = owl_variable_get_var(&vd, "scrollmode"))); 379 FAIL_UNLESS("get enum", OWL_SCROLLMODE_NORMAL == owl_variable_get_int(var)); 380 FAIL_UNLESS("get enum as string", 381 !strcmp((value = owl_variable_get_tostring(var)), "normal")); 382 g_free(value); 383 FAIL_UNLESS("set enum 1", 0 == owl_variable_set_int(var, OWL_SCROLLMODE_TOP)); 384 FAIL_UNLESS("get enum 1", OWL_SCROLLMODE_TOP == owl_variable_get_int(var)); 385 FAIL_UNLESS("set enum 2a", -1 == owl_variable_set_int(var, -1)); 386 FAIL_UNLESS("set enum 2b", -1 == owl_variable_set_int(var, OWL_SCROLLMODE_PAGEDCENTER + 1)); 387 FAIL_UNLESS("get enum 2", OWL_SCROLLMODE_TOP == owl_variable_get_int(var)); 388 FAIL_UNLESS("set enum 3", 0 == owl_variable_set_fromstring(var, "center", 0)); 389 FAIL_UNLESS("get enum 4", OWL_SCROLLMODE_CENTER == owl_variable_get_int(var)); 390 FAIL_UNLESS("set enum 5", -1 == owl_variable_set_fromstring(var, "bogus", 0)); 391 FAIL_UNLESS("set enum 6", -1 == owl_variable_set_fromstring(var, "", 0)); 392 FAIL_UNLESS("get enum 7", OWL_SCROLLMODE_CENTER == owl_variable_get_int(var)); 393 394 owl_variable_dict_newvar_string(&vd, "stringvar", "testval", "", ""); 396 395 FAIL_UNLESS("get new string var", NULL != (var = owl_variable_get_var(&vd, "stringvar"))); 397 FAIL_UNLESS("get new string var", NULL != (v = owl_variable_get(var)));398 396 FAIL_UNLESS("get new string val", !strcmp("testval", owl_variable_get_string(var))); 399 397 owl_variable_set_string(var, "new val"); 400 398 FAIL_UNLESS("update string val", !strcmp("new val", owl_variable_get_string(var))); 401 399 402 owl_variable_dict_newvar_int(&vd, "intvar", "", "", 47);400 owl_variable_dict_newvar_int(&vd, "intvar", 47, "", ""); 403 401 FAIL_UNLESS("get new int var", NULL != (var = owl_variable_get_var(&vd, "intvar"))); 404 FAIL_UNLESS("get new int var", NULL != (v = owl_variable_get(var)));405 402 FAIL_UNLESS("get new int val", 47 == owl_variable_get_int(var)); 406 403 owl_variable_set_int(var, 17); 407 404 FAIL_UNLESS("update int val", 17 == owl_variable_get_int(var)); 408 405 409 owl_variable_dict_newvar_bool(&vd, "boolvar", "", "", 1);406 owl_variable_dict_newvar_bool(&vd, "boolvar", true, "", ""); 410 407 FAIL_UNLESS("get new bool var", NULL != (var = owl_variable_get_var(&vd, "boolvar"))); 411 FAIL_UNLESS("get new bool var", NULL != (v = owl_variable_get(var)));412 408 FAIL_UNLESS("get new bool val", owl_variable_get_bool(var)); 413 409 owl_variable_set_bool_off(var); 414 410 FAIL_UNLESS("update bool val", !owl_variable_get_bool(var)); 415 411 416 owl_variable_dict_newvar_string(&vd, "nullstringvar", "", "", NULL);412 owl_variable_dict_newvar_string(&vd, "nullstringvar", NULL, "", ""); 417 413 FAIL_UNLESS("get new string (NULL) var", NULL != (var = owl_variable_get_var(&vd, "nullstringvar"))); 418 414 FAIL_UNLESS("get string (NULL)", NULL == (value = owl_variable_get_tostring(var))); … … 421 417 FAIL_UNLESS("get string (NULL) 2", NULL == (value = owl_variable_get_tostring(var))); 422 418 g_free(value); 419 420 owl_variable_dict_newvar_enum(&vd, "enumvar", 0, "", "", "a,b,c,d"); 421 FAIL_UNLESS("get new enum var", NULL != (var = owl_variable_get_var(&vd, "enumvar"))); 422 FAIL_UNLESS("get new enum val", 0 == owl_variable_get_int(var)); 423 owl_variable_set_fromstring(var, "c", 0); 424 FAIL_UNLESS("update enum val", 2 == owl_variable_get_int(var)); 423 425 424 426 owl_variable_dict_cleanup(&vd); -
variable.c
rd126a19 r9d4dfdc 1 1 #include "owl.h" 2 2 #include <stdio.h> 3 4 #define OWLVAR_BOOL(name,default,summary,description) \ 5 { g_strdup(name), OWL_VARIABLE_BOOL, NULL, default, "on,off", g_strdup(summary), g_strdup(description), NULL, \ 6 NULL, NULL, NULL, NULL, NULL, NULL } 7 8 #define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \ 9 { g_strdup(name), OWL_VARIABLE_BOOL, NULL, default, "on,off", g_strdup(summary), g_strdup(description), NULL, \ 10 validate, set, NULL, get, NULL, NULL } 11 12 #define OWLVAR_INT(name,default,summary,description) \ 13 { g_strdup(name), OWL_VARIABLE_INT, NULL, default, "<int>", g_strdup(summary), g_strdup(description), NULL, \ 14 NULL, NULL, NULL, NULL, NULL, NULL } 3 #include "gmarshal_funcs.h" 4 5 /* TODO(davidben): When we can require 2.30 and up, remove this. */ 6 #ifndef G_VALUE_INIT 7 #define G_VALUE_INIT { 0, { { 0 } } } 8 #endif 9 10 typedef const char *(*get_string_t)(const owl_variable *); 11 typedef int (*get_int_t)(const owl_variable *); 12 typedef bool (*get_bool_t)(const owl_variable *); 13 14 typedef int (*set_string_t)(owl_variable *, const char *); 15 typedef int (*set_int_t)(owl_variable *, int); 16 typedef int (*set_bool_t)(owl_variable *, bool); 17 18 typedef int (*validate_string_t)(const owl_variable *, const char *); 19 typedef int (*validate_int_t)(const owl_variable *, int); 20 typedef int (*validate_bool_t)(const owl_variable *, bool); 21 22 static void owl_variable_dict_newvar_bool_full(owl_vardict *vd, 23 const char *name, 24 bool default_val, 25 const char *summary, 26 const char *description, 27 validate_bool_t validate_fn, 28 set_bool_t set_fn, 29 get_bool_t get_fn); 30 31 static void owl_variable_dict_newvar_string_full(owl_vardict *vd, 32 const char *name, 33 const char *default_val, 34 const char *summary, 35 const char *description, 36 const char *validsettings, 37 validate_string_t validate_fn, 38 set_string_t set_fn, 39 get_string_t get_fn); 40 41 static void owl_variable_dict_newvar_int_full(owl_vardict *vd, 42 const char *name, 43 int default_val, 44 const char *summary, 45 const char *description, 46 const char *validsettings, 47 validate_int_t validate_fn, 48 set_int_t set_fn, 49 get_int_t get_fn); 50 51 static void owl_variable_dict_newvar_enum_full(owl_vardict *vd, 52 const char *name, 53 int default_val, 54 const char *summary, 55 const char *description, 56 const char *validsettings, 57 validate_int_t validate_fn, 58 set_int_t set_fn, 59 get_int_t get_fn); 60 61 #define OWLVAR_BOOL(name, default, summary, description) \ 62 owl_variable_dict_newvar_bool(vd, name, default, summary, description) 63 64 #define OWLVAR_BOOL_FULL(name, default, summary, description, validate, set, get) \ 65 owl_variable_dict_newvar_bool_full(vd, name, default, summary, description, \ 66 validate, set, get) 67 68 #define OWLVAR_INT(name, default, summary, description) \ 69 owl_variable_dict_newvar_int(vd, name, default, summary, description) 15 70 16 71 #define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \ 17 { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \ 18 validate, set, NULL, get, NULL, NULL } 19 20 #define OWLVAR_PATH(name,default,summary,description) \ 21 { g_strdup(name), OWL_VARIABLE_STRING, g_strdup(default), 0, "<path>", g_strdup(summary), g_strdup(description), NULL, \ 22 NULL, NULL, NULL, NULL, NULL, NULL } 23 24 #define OWLVAR_STRING(name,default,summary,description) \ 25 { g_strdup(name), OWL_VARIABLE_STRING, g_strdup(default), 0, "<string>", g_strdup(summary), g_strdup(description), NULL, \ 26 NULL, NULL, NULL, NULL, NULL, NULL } 27 28 #define OWLVAR_STRING_FULL(name,default,validset,summary,description,validate,set,get) \ 29 { g_strdup(name), OWL_VARIABLE_STRING, g_strdup(default), 0, validset, g_strdup(summary), g_strdup(description), NULL, \ 30 validate, set, NULL, get, NULL, NULL } 72 owl_variable_dict_newvar_int_full(vd, name, default, summary, description, \ 73 validset, validate, set, get) 74 75 #define OWLVAR_PATH(name, default, summary, description) \ 76 owl_variable_dict_newvar_path(vd, name, default, summary, description) 77 78 #define OWLVAR_STRING(name, default, summary, description) \ 79 owl_variable_dict_newvar_string(vd, name, default, summary, description) 80 81 #define OWLVAR_STRING_FULL(name, default, validset, summary, description, validate, set, get) \ 82 owl_variable_dict_newvar_string_full(vd, name, default, summary, description, \ 83 validset, validate, set, get) 31 84 32 85 /* enums are really integers, but where validset is a comma-separated 33 86 * list of strings which can be specified. The tokens, starting at 0, 34 87 * correspond to the values that may be specified. */ 35 #define OWLVAR_ENUM(name,default,summary,description,validset) \ 36 { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \ 37 owl_variable_enum_validate, \ 38 NULL, owl_variable_enum_set_fromstring, \ 39 NULL, owl_variable_enum_get_tostring, \ 40 NULL } 88 #define OWLVAR_ENUM(name, default, summary, description, validset) \ 89 owl_variable_dict_newvar_enum(vd, name, default, summary, description, validset) 41 90 42 91 #define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \ 43 { g_strdup(name), OWL_VARIABLE_INT, NULL, default, validset, g_strdup(summary), g_strdup(description), NULL, \ 44 validate, \ 45 set, owl_variable_enum_set_fromstring, \ 46 get, owl_variable_enum_get_tostring, \ 47 NULL } 48 49 int owl_variable_add_defaults(owl_vardict *vd) 50 { 51 owl_variable variables_to_init[] = { 52 92 owl_variable_dict_newvar_enum_full(vd, name, default, summary, description, \ 93 validset, validate, set, get) 94 95 void owl_variable_add_defaults(owl_vardict *vd) 96 { 53 97 OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off", 54 98 "ring the terminal bell when personal messages are received", 55 99 "Can be set to 'on', 'off', or the name of a filter which\n" 56 "messages need to match in order to ring the bell") ,100 "messages need to match in order to ring the bell"); 57 101 58 102 OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1, 59 "enable / disable the terminal bell", "" ) ,103 "enable / disable the terminal bell", "" ); 60 104 61 105 OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG, … … 63 107 "If set to 'on', debugging messages are logged to the\n" 64 108 "file specified by the debugfile variable.\n", 65 NULL, owl_variable_debug_set, NULL) ,109 NULL, owl_variable_debug_set, NULL); 66 110 67 111 OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1, 68 "send a login message when BarnOwl starts", "" ) ,112 "send a login message when BarnOwl starts", "" ); 69 113 70 114 OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1, 71 "send a logout message when BarnOwl exits", "" ) ,115 "send a logout message when BarnOwl exits", "" ); 72 116 73 117 OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0, 74 "display received pings", "" ) ,118 "display received pings", "" ); 75 119 76 120 OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1, 77 "send pings", "" ) ,121 "send pings", "" ); 78 122 79 123 OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0, 80 "disable printing information in the separator bar", "" ) ,124 "disable printing information in the separator bar", "" ); 81 125 82 126 OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1, 83 "strip kerberos instance for reply", "") ,127 "strip kerberos instance for reply", ""); 84 128 85 129 OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1, 86 "strip leading and trailing newlines", "") ,130 "strip leading and trailing newlines", ""); 87 131 88 132 OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1, 89 "display outgoing messages", "" ) ,133 "display outgoing messages", "" ); 90 134 91 135 OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1, 92 "load logins from .anyone on startup", "" ) ,136 "load logins from .anyone on startup", "" ); 93 137 94 138 OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0, … … 97 141 "logged in the directory specified\n" 98 142 "by the 'logpath' variable. The filename in that\n" 99 "directory is derived from the sender of the message.\n" ) ,143 "directory is derived from the sender of the message.\n" ); 100 144 101 145 OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0, … … 105 149 "by the 'classlogpath' variable.\n" 106 150 "The filename in that directory is derived from\n" 107 "the name of the class to which the message was sent.\n" ) ,151 "the name of the class to which the message was sent.\n" ); 108 152 109 153 OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH, … … 114 158 "is selected both incoming and outgoing messages are\n" 115 159 "logged.", 116 "both,in,out") ,160 "both,in,out"); 117 161 118 162 OWLVAR_BOOL_FULL( "colorztext" /* %OwlVarStub */, 1, 119 163 "allow @color() in zephyrs to change color", 120 NULL, NULL, owl_variable_colorztext_set, NULL) ,164 NULL, NULL, owl_variable_colorztext_set, NULL); 121 165 122 166 OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1, … … 124 168 "If turned off, dashes, pipes and pluses will be used\n" 125 169 "to draw lines on the screen. Useful when the terminal\n" 126 "is causing problems" ) ,170 "is causing problems" ); 127 171 128 172 OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1, 129 173 "Do automatic zcrypt processing", 130 "" ) ,174 "" ); 131 175 132 176 OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0, … … 136 180 "but sent no login message, or a user is not present that sent no\n" 137 181 "logout message, a pseudo login or logout message will be created\n", 138 NULL, owl_variable_pseudologins_set, NULL) ,182 NULL, owl_variable_pseudologins_set, NULL); 139 183 140 184 OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0, … … 142 186 "When this is enabled, BarnOwl will print login and logout notifications\n" 143 187 "for AIM, zephyr, or other protocols. If disabled BarnOwl will not print\n" 144 "login or logout notifications.\n") ,188 "login or logout notifications.\n"); 145 189 146 190 OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "", … … 151 195 "variables like logging, classlogging, loglogins, loggingdirection,\n" 152 196 "etc. If you want this variable to control all logging, make sure\n" 153 "all other logging variables are in their default state.\n") ,197 "all other logging variables are in their default state.\n"); 154 198 155 199 OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0, … … 157 201 "When this is enabled, BarnOwl will log login and logout notifications\n" 158 202 "for AIM, zephyr, or other protocols. If disabled BarnOwl will not print\n" 159 "login or logout notifications.\n") ,203 "login or logout notifications.\n"); 160 204 161 205 OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1, … … 169 213 "in the editmulti keymap.\n", 170 214 "off,middle,on", 171 NULL, owl_variable_disable_ctrl_d_set, NULL) ,215 NULL, owl_variable_disable_ctrl_d_set, NULL); 172 216 173 217 OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people", 174 218 "path for logging personal zephyrs", 175 219 "Specifies a directory which must exist.\n" 176 "Files will be created in the directory for each sender.\n") ,220 "Files will be created in the directory for each sender.\n"); 177 221 178 222 OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class", 179 223 "path for logging class zephyrs", 180 224 "Specifies a directory which must exist.\n" 181 "Files will be created in the directory for each class.\n") ,225 "Files will be created in the directory for each class.\n"); 182 226 183 227 OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE, 184 228 "path for logging debug messages when debugging is enabled", 185 229 "This file will be logged to if 'debug' is set to 'on'.\n" 186 "BarnOwl will append a dot and the current process's pid to the filename.") ,230 "BarnOwl will append a dot and the current process's pid to the filename."); 187 231 188 232 OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL, … … 192 236 "See the documentation for 'zsig' for more information about\n" 193 237 "how the outgoing zsig is chosen." 194 ) ,238 ); 195 239 196 240 OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL, … … 198 242 "The named program will be run when BarnOwl receives new\n" 199 243 "messages. It will not be run again until the first\n" 200 "instance exits") ,244 "instance exits"); 201 245 202 246 OWLVAR_STRING( "zsender" /* %OwlVarStub */, "", … … 205 249 "zephyrs. If this is unset, it will use your Kerberos\n" 206 250 "principal. Note that customizing the sender name will\n" 207 "cause your zephyrs to be sent unauthenticated.") ,251 "cause your zephyrs to be sent unauthenticated."); 208 252 209 253 OWLVAR_STRING( "zsigfunc" /* %OwlVarStub */, "BarnOwl::default_zephyr_signature()", … … 212 256 "explicit zsig. The default setting implements the policy\n" 213 257 "described in the documentation for the 'zsig' variable.\n" 214 "See also BarnOwl::random_zephyr_signature().\n") ,258 "See also BarnOwl::random_zephyr_signature().\n"); 215 259 216 260 OWLVAR_STRING( "zsig" /* %OwlVarStub */, "", … … 219 263 "unset, 'zsigproc' will be run to generate a zsig. If that is\n" 220 264 "also unset, the 'zwrite-signature' zephyr variable will be\n" 221 "used instead.\n") ,265 "used instead.\n"); 222 266 223 267 OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "", … … 225 269 "The sepbar is the bar separating the top and bottom\n" 226 270 "of the BarnOwl screen. Any string specified here will\n" 227 "be displayed on the right of the sepbar\n") ,271 "be displayed on the right of the sepbar\n"); 228 272 229 273 OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0, 230 "turn zaway on or off", "" ) ,274 "turn zaway on or off", "" ); 231 275 232 276 OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */, 233 277 OWL_DEFAULT_ZAWAYMSG, 234 "zaway msg for responding to zephyrs when away", "" ) ,278 "zaway msg for responding to zephyrs when away", "" ); 235 279 236 280 OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */, 237 281 OWL_DEFAULT_ZAWAYMSG, 238 "default zaway message", "" ) ,282 "default zaway message", "" ); 239 283 240 284 OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0, 241 285 "Set AIM away status", 242 286 "", 243 NULL, owl_variable_aaway_set, NULL) ,287 NULL, owl_variable_aaway_set, NULL); 244 288 245 289 OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */, 246 290 OWL_DEFAULT_AAWAYMSG, 247 "AIM away msg for responding when away", "" ) ,291 "AIM away msg for responding when away", "" ); 248 292 249 293 OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */, 250 294 OWL_DEFAULT_AAWAYMSG, 251 "default AIM away message", "" ) ,295 "default AIM away message", "" ); 252 296 253 297 OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all", 254 298 "home view to switch to after 'X' and 'V'", 255 "SEE ALSO: view, filter\n" ) ,299 "SEE ALSO: view, filter\n" ); 256 300 257 301 OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none", 258 302 "filter on which to trigger alert actions", 259 "" ) ,303 "" ); 260 304 261 305 OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop", 262 306 "BarnOwl command to execute for alert actions", 263 "" ) ,307 "" ); 264 308 265 309 OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "<string>", "tty name for zephyr location", "", 266 NULL, owl_variable_tty_set, NULL) ,310 NULL, owl_variable_tty_set, NULL); 267 311 268 312 OWLVAR_STRING( "default_style" /* %OwlVarStub */, "default", … … 275 319 " perl - legacy perl interface\n" 276 320 "\nSEE ALSO: style, show styles, view -s <style>\n" 277 ) ,321 ); 278 322 279 323 … … 282 326 "This specifies the maximum number of columns for M-q to fill text\n" 283 327 "to. If set to 0, M-q will wrap to the width of the window, and\n" 284 "values less than 0 disable M-q entirely.\n") ,328 "values less than 0 disable M-q entirely.\n"); 285 329 286 330 OWLVAR_INT( "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 70, … … 291 335 "\n" 292 336 "As a courtesy to recipients, it is recommended that outgoing\n" 293 "Zephyr messages be no wider than 70 columns.\n") ,337 "Zephyr messages be no wider than 70 columns.\n"); 294 338 295 339 OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15, … … 298 342 "AIM login before allowing the receipt of AIM login notifications.\n" 299 343 "By default this is set to 15. If you would like to view login\n" 300 "notifications of buddies as soon as you login, set it to 0 instead.") ,344 "notifications of buddies as soon as you login, set it to 0 instead."); 301 345 302 346 … … 311 355 owl_variable_typewinsize_set, 312 356 NULL /* use default for get */ 313 ) ,357 ); 314 358 315 359 OWLVAR_INT( "typewindelta" /* %OwlVarStub */, 0, … … 321 365 "typewinsize to 1.\n\n" 322 366 "This works a lot better with a non-default scrollmode;\n" 323 "try :set scrollmode pagedcenter.\n") ,367 "try :set scrollmode pagedcenter.\n"); 324 368 325 369 OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL, … … 350 394 " the screen will be paged up or down and\n" 351 395 " the cursor will be near the center.\n", 352 "normal,top,neartop,center,paged,pagedcenter" ) ,396 "normal,top,neartop,center,paged,pagedcenter" ); 353 397 354 398 OWLVAR_BOOL( "narrow-related" /* %OwlVarStub:narrow_related */, 1, 355 399 "Make smartnarrow use broader filters", 356 "Causes smartfil er to narrow to messages \"related\" to \n"400 "Causes smartfilter to narrow to messages \"related\" to \n" 357 401 "the current message, as well as ones to the same place.\n\n" 358 402 "for Zephyr, this controls whether to narrow to e.g. class-help or\n" 359 403 "class-help.d alone, or to related-class-help, which includes\n" 360 "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" ) ,404 "help, unhelp, help.d, etc.\n\nDefault is true (include unclasses, etc.).\n" ); 361 405 362 406 OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0, … … 365 409 "continue to follow the last message if this is set.\n" 366 410 "Note that this is currently risky as you might accidentally\n" 367 "delete a message right as it came in.\n" ) ,411 "delete a message right as it came in.\n" ); 368 412 369 413 OWLVAR_STRING_FULL( "default_exposure" /* %OwlVarStub */, "", … … 374 418 "~/.zephyr.vars.\n" 375 419 "See the description of exposure for the values this can be.", 376 NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get ) ,420 NULL, owl_variable_default_exposure_set, owl_variable_default_exposure_get ); 377 421 378 422 OWLVAR_STRING_FULL( "exposure" /* %OwlVarStub */, "", … … 430 474 " personal subscriptions will be entered for the\n" 431 475 " user.\n", 432 NULL, owl_variable_exposure_set, NULL /* use default for get */ ), 433 434 /* This MUST be last... */ 435 { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL, 436 NULL, NULL, NULL, NULL, NULL, NULL } 437 438 }; 439 440 int ret = owl_variable_dict_add_from_list(vd, variables_to_init); 441 owl_variable *var; 442 for (var = variables_to_init; var->name != NULL; var++) 443 owl_variable_cleanup(var); 444 return ret; 476 NULL, owl_variable_exposure_set, NULL /* use default for get */ ); 445 477 } 446 478 … … 452 484 /* commonly useful */ 453 485 454 int owl_variable_int_validate_gt0(const owl_variable *v, const void *newval) 455 { 456 if (newval == NULL) return(0); 457 else if (*(const int*)newval < 1) return(0); 458 else return (1); 459 } 460 461 int owl_variable_int_validate_positive(const owl_variable *v, const void *newval) 462 { 463 if (newval == NULL) return(0); 464 else if (*(const int*)newval < 0) return(0); 465 else return (1); 486 int owl_variable_int_validate_gt0(const owl_variable *v, int newval) 487 { 488 return !(newval < 1); 489 } 490 491 int owl_variable_int_validate_positive(const owl_variable *v, int newval) 492 { 493 return !(newval < 0); 466 494 } 467 495 468 496 /* typewinsize */ 469 int owl_variable_typewinsize_set(owl_variable *v, const void *newval)497 int owl_variable_typewinsize_set(owl_variable *v, int newval) 470 498 { 471 499 int rv; … … 476 504 477 505 /* debug (cache value in g->debug) */ 478 int owl_variable_debug_set(owl_variable *v, const void *newval) 479 { 480 if (newval && (*(const int*)newval == 1 || *(const int*)newval == 0)) { 481 g.debug = *(const int*)newval; 506 int owl_variable_debug_set(owl_variable *v, bool newval) 507 { 508 g.debug = newval; 509 return owl_variable_bool_set_default(v, newval); 510 } 511 512 /* When 'aaway' is changed, need to notify the AIM server */ 513 int owl_variable_aaway_set(owl_variable *v, bool newval) 514 { 515 if (newval) { 516 owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g)); 517 } else { 518 owl_aim_set_awaymsg(""); 482 519 } 483 520 return owl_variable_bool_set_default(v, newval); 484 521 } 485 522 486 /* When 'aaway' is changed, need to notify the AIM server */ 487 int owl_variable_aaway_set(owl_variable *v, const void *newval) 488 { 489 if (newval) { 490 if (*(const int*)newval == 1) { 491 owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g)); 492 } else if (*(const int*)newval == 0) { 493 owl_aim_set_awaymsg(""); 494 } 495 } 496 return owl_variable_bool_set_default(v, newval); 497 } 498 499 int owl_variable_colorztext_set(owl_variable *v, const void *newval) 523 int owl_variable_colorztext_set(owl_variable *v, bool newval) 500 524 { 501 525 int ret = owl_variable_bool_set_default(v, newval); … … 510 534 } 511 535 512 int owl_variable_pseudologins_set(owl_variable *v, const void *newval)536 int owl_variable_pseudologins_set(owl_variable *v, bool newval) 513 537 { 514 538 static guint timer = 0; 515 539 if (newval) { 516 if (*(const int*)newval == 1) { 517 owl_function_zephyr_buddy_check(0); 518 if (timer == 0) { 519 timer = g_timeout_add_seconds(180, owl_zephyr_buddycheck_timer, NULL); 520 } 521 } else { 522 if (timer != 0) { 523 g_source_remove(timer); 524 timer = 0; 525 } 540 owl_function_zephyr_buddy_check(0); 541 if (timer == 0) { 542 timer = g_timeout_add_seconds(180, owl_zephyr_buddycheck_timer, NULL); 543 } 544 } else { 545 if (timer != 0) { 546 g_source_remove(timer); 547 timer = 0; 526 548 } 527 549 } … … 531 553 /* note that changing the value of this will clobber 532 554 * any user setting of this */ 533 int owl_variable_disable_ctrl_d_set(owl_variable *v, const void *newval)534 { 535 if ( newval &&!owl_context_is_startup(owl_global_get_context(&g))) {536 if ( *(const int*)newval == 2) {555 int owl_variable_disable_ctrl_d_set(owl_variable *v, int newval) 556 { 557 if (!owl_context_is_startup(owl_global_get_context(&g))) { 558 if (newval == 2) { 537 559 owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char"); 538 } else if ( *(const int*)newval == 1) {560 } else if (newval == 1) { 539 561 owl_function_command_norv("bindkey editmulti C-d command edit:done-or-delete"); 540 562 } else { … … 542 564 } 543 565 } 544 return owl_variable_int_set_default(v, newval); 545 } 546 547 int owl_variable_tty_set(owl_variable *v, const void*newval)566 return owl_variable_int_set_default(v, newval); 567 } 568 569 int owl_variable_tty_set(owl_variable *v, const char *newval) 548 570 { 549 571 owl_zephyr_set_locationinfo(g_get_host_name(), newval); 550 return (owl_variable_string_set_default(v, newval));551 } 552 553 int owl_variable_default_exposure_set(owl_variable *v, const void*newval)572 return owl_variable_string_set_default(v, newval); 573 } 574 575 int owl_variable_default_exposure_set(owl_variable *v, const char *newval) 554 576 { 555 577 return owl_zephyr_set_default_exposure(newval); 556 578 } 557 579 558 const void*owl_variable_default_exposure_get(const owl_variable *v)580 const char *owl_variable_default_exposure_get(const owl_variable *v) 559 581 { 560 582 return owl_zephyr_get_default_exposure(); 561 583 } 562 584 563 int owl_variable_exposure_set(owl_variable *v, const void*newval)585 int owl_variable_exposure_set(owl_variable *v, const char *newval) 564 586 { 565 587 int ret = owl_zephyr_set_exposure(newval); … … 573 595 /**************************************************************************/ 574 596 575 intowl_variable_dict_setup(owl_vardict *vd) {597 void owl_variable_dict_setup(owl_vardict *vd) { 576 598 owl_dict_create(vd); 577 return owl_variable_add_defaults(vd); 578 } 579 580 int owl_variable_dict_add_from_list(owl_vardict *vd, owl_variable *variables_to_init) 581 { 582 owl_variable *var, *cur; 583 for (var = variables_to_init; var->name != NULL; var++) { 584 cur = g_new(owl_variable, 1); 585 *cur = *var; 586 /* strdup all the strings so we can delete them consistently. */ 587 cur->name = g_strdup(var->name); 588 cur->summary = g_strdup(var->summary); 589 cur->description = g_strdup(var->description); 590 switch (cur->type) { 591 case OWL_VARIABLE_OTHER: 592 cur->set_fn(cur, cur->pval_default); 593 break; 594 case OWL_VARIABLE_STRING: 595 if (!cur->validate_fn) 596 cur->validate_fn = owl_variable_string_validate_default; 597 if (!cur->set_fn) 598 cur->set_fn = owl_variable_string_set_default; 599 if (!cur->set_fromstring_fn) 600 cur->set_fromstring_fn = owl_variable_string_set_fromstring_default; 601 if (!cur->get_fn) 602 cur->get_fn = owl_variable_get_default; 603 if (!cur->get_tostring_fn) 604 cur->get_tostring_fn = owl_variable_string_get_tostring_default; 605 if (!cur->delete_fn) 606 cur->delete_fn = owl_variable_delete_default; 607 cur->pval_default = g_strdup(var->pval_default); 608 cur->set_fn(cur, cur->pval_default); 609 break; 610 case OWL_VARIABLE_BOOL: 611 if (!cur->validate_fn) 612 cur->validate_fn = owl_variable_bool_validate_default; 613 if (!cur->set_fn) 614 cur->set_fn = owl_variable_bool_set_default; 615 if (!cur->set_fromstring_fn) 616 cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default; 617 if (!cur->get_fn) 618 cur->get_fn = owl_variable_get_default; 619 if (!cur->get_tostring_fn) 620 cur->get_tostring_fn = owl_variable_bool_get_tostring_default; 621 if (!cur->delete_fn) 622 cur->delete_fn = owl_variable_delete_default; 623 cur->val = g_new(int, 1); 624 cur->set_fn(cur, &cur->ival_default); 625 break; 626 case OWL_VARIABLE_INT: 627 if (!cur->validate_fn) 628 cur->validate_fn = owl_variable_int_validate_default; 629 if (!cur->set_fn) 630 cur->set_fn = owl_variable_int_set_default; 631 if (!cur->set_fromstring_fn) 632 cur->set_fromstring_fn = owl_variable_int_set_fromstring_default; 633 if (!cur->get_fn) 634 cur->get_fn = owl_variable_get_default; 635 if (!cur->get_tostring_fn) 636 cur->get_tostring_fn = owl_variable_int_get_tostring_default; 637 if (!cur->delete_fn) 638 cur->delete_fn = owl_variable_delete_default; 639 cur->val = g_new(int, 1); 640 cur->set_fn(cur, &cur->ival_default); 641 break; 642 default: 643 fprintf(stderr, "owl_variable_setup: invalid variable type\n"); 644 return(-2); 645 } 646 owl_dict_insert_element(vd, cur->name, cur, NULL); 647 } 648 return 0; 599 owl_variable_add_defaults(vd); 600 } 601 602 CALLER_OWN GClosure *owl_variable_make_closure(owl_variable *v, 603 GCallback fn, 604 GClosureMarshal marshal) { 605 GClosure *closure = g_cclosure_new_swap(fn, v, NULL); 606 g_closure_set_marshal(closure,marshal); 607 g_closure_ref(closure); 608 g_closure_sink(closure); 609 return closure; 649 610 } 650 611 651 612 void owl_variable_dict_add_variable(owl_vardict * vardict, 652 613 owl_variable * var) { 614 char *oldvalue = NULL; 615 owl_variable *oldvar = owl_variable_get_var(vardict, var->name); 616 /* Save the old value as a string. */ 617 if (oldvar) { 618 oldvalue = owl_variable_get_tostring(oldvar); 619 } 653 620 owl_dict_insert_element(vardict, var->name, var, (void (*)(void *))owl_variable_delete); 654 } 655 656 CALLER_OWN owl_variable *owl_variable_newvar(const char *name, const char *summary, const char *description) 657 { 658 owl_variable * var = g_new0(owl_variable, 1); 621 /* Restore the old value. */ 622 if (oldvalue) { 623 owl_variable_set_fromstring(var, oldvalue, 0); 624 g_free(oldvalue); 625 } 626 } 627 628 static owl_variable *owl_variable_newvar(int type, const char *name, const char *summary, const char *description, const char *validsettings) { 629 owl_variable *var = g_new0(owl_variable, 1); 630 var->type = type; 659 631 var->name = g_strdup(name); 660 632 var->summary = g_strdup(summary); 661 633 var->description = g_strdup(description); 634 var->validsettings = g_strdup(validsettings); 662 635 return var; 663 636 } 664 637 665 void owl_variable_update(owl_variable *var, const char *summary, const char *desc) { 666 g_free(var->summary); 667 var->summary = g_strdup(summary); 668 g_free(var->description); 669 var->description = g_strdup(desc); 670 } 671 672 void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *summ, const char *desc, const char *initval) 673 { 674 owl_variable *old = owl_variable_get_var(vd, name); 675 if (old && owl_variable_get_type(old) == OWL_VARIABLE_STRING) { 676 owl_variable_update(old, summ, desc); 677 g_free(old->pval_default); 678 old->pval_default = g_strdup(initval); 679 } else { 680 owl_variable * var = owl_variable_newvar(name, summ, desc); 681 var->type = OWL_VARIABLE_STRING; 682 var->validsettings = "<string>"; 683 var->pval_default = g_strdup(initval); 684 var->set_fn = owl_variable_string_set_default; 685 var->set_fromstring_fn = owl_variable_string_set_fromstring_default; 686 var->get_fn = owl_variable_get_default; 687 var->get_tostring_fn = owl_variable_string_get_tostring_default; 688 var->delete_fn = owl_variable_delete_default; 689 var->set_fn(var, initval); 690 owl_variable_dict_add_variable(vd, var); 691 } 692 } 693 694 void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval) 695 { 696 owl_variable *old = owl_variable_get_var(vd, name); 697 if (old && owl_variable_get_type(old) == OWL_VARIABLE_INT) { 698 owl_variable_update(old, summ, desc); 699 old->ival_default = initval; 700 } else { 701 owl_variable * var = owl_variable_newvar(name, summ, desc); 702 var->type = OWL_VARIABLE_INT; 703 var->validsettings = "<int>"; 704 var->ival_default = initval; 705 var->validate_fn = owl_variable_int_validate_default; 706 var->set_fn = owl_variable_int_set_default; 707 var->set_fromstring_fn = owl_variable_int_set_fromstring_default; 708 var->get_fn = owl_variable_get_default; 709 var->get_tostring_fn = owl_variable_int_get_tostring_default; 710 var->delete_fn = owl_variable_delete_default; 711 var->val = g_new(int, 1); 712 var->set_fn(var, &initval); 713 owl_variable_dict_add_variable(vd, var); 714 } 715 } 716 717 void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, const char *summ, const char *desc, int initval) 718 { 719 owl_variable *old = owl_variable_get_var(vd, name); 720 if (old && owl_variable_get_type(old) == OWL_VARIABLE_BOOL) { 721 owl_variable_update(old, summ, desc); 722 old->ival_default = initval; 723 } else { 724 owl_variable * var = owl_variable_newvar(name, summ, desc); 725 var->type = OWL_VARIABLE_BOOL; 726 var->validsettings = "on,off"; 727 var->ival_default = initval; 728 var->validate_fn = owl_variable_bool_validate_default; 729 var->set_fn = owl_variable_bool_set_default; 730 var->set_fromstring_fn = owl_variable_bool_set_fromstring_default; 731 var->get_fn = owl_variable_get_default; 732 var->get_tostring_fn = owl_variable_bool_get_tostring_default; 733 var->delete_fn = owl_variable_delete_default; 734 var->val = g_new(int, 1); 735 var->set_fn(var, &initval); 736 owl_variable_dict_add_variable(vd, var); 737 } 638 static void owl_variable_dict_newvar_int_full(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validsettings, validate_int_t validate_fn, set_int_t set_fn, get_int_t get_fn) 639 { 640 owl_variable *var = owl_variable_newvar(OWL_VARIABLE_INT, name, summary, 641 description, validsettings); 642 var->takes_on_off = false; 643 var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_int_get_default); 644 var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_int_set_default); 645 var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_int_validate_default); 646 647 var->get_tostring_fn = owl_variable_make_closure( 648 var, G_CALLBACK(owl_variable_int_get_tostring_default), 649 g_cclosure_user_marshal_STRING__VOID); 650 var->set_fromstring_fn = owl_variable_make_closure( 651 var, G_CALLBACK(owl_variable_int_set_fromstring_default), 652 g_cclosure_user_marshal_INT__STRING); 653 654 g_value_init(&var->val, G_TYPE_INT); 655 owl_variable_set_int(var, default_val); 656 657 var->default_str = owl_variable_get_tostring(var); 658 owl_variable_dict_add_variable(vd, var); 659 } 660 661 void owl_variable_dict_newvar_int(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description) { 662 owl_variable_dict_newvar_int_full(vd, name, default_val, summary, description, 663 "<int>", NULL, NULL, NULL); 664 } 665 666 static void owl_variable_dict_newvar_bool_full(owl_vardict *vd, const char *name, bool default_val, const char *summary, const char *description, validate_bool_t validate_fn, set_bool_t set_fn, get_bool_t get_fn) 667 { 668 owl_variable *var = owl_variable_newvar(OWL_VARIABLE_BOOL, name, summary, 669 description, "on,off"); 670 var->takes_on_off = true; 671 var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_bool_get_default); 672 var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_bool_set_default); 673 var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_bool_validate_default); 674 675 var->get_tostring_fn = owl_variable_make_closure( 676 var, G_CALLBACK(owl_variable_bool_get_tostring_default), 677 g_cclosure_user_marshal_STRING__VOID); 678 var->set_fromstring_fn = owl_variable_make_closure( 679 var, G_CALLBACK(owl_variable_bool_set_fromstring_default), 680 g_cclosure_user_marshal_INT__STRING); 681 682 g_value_init(&var->val, G_TYPE_BOOLEAN); 683 owl_variable_set_bool(var, default_val); 684 685 var->default_str = owl_variable_get_tostring(var); 686 owl_variable_dict_add_variable(vd, var); 687 } 688 689 void owl_variable_dict_newvar_bool(owl_vardict *vd, const char *name, bool default_val, const char *summary, const char *description) { 690 owl_variable_dict_newvar_bool_full(vd, name, default_val, summary, description, 691 NULL, NULL, NULL); 692 } 693 694 static void owl_variable_dict_newvar_string_full(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description, const char *validsettings, validate_string_t validate_fn, set_string_t set_fn, get_string_t get_fn) 695 { 696 owl_variable *var = owl_variable_newvar(OWL_VARIABLE_STRING, name, summary, 697 description, validsettings); 698 var->takes_on_off = false; 699 var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_string_get_default); 700 var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_string_set_default); 701 var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_string_validate_default); 702 703 var->get_tostring_fn = owl_variable_make_closure( 704 var, G_CALLBACK(owl_variable_string_get_tostring_default), 705 g_cclosure_user_marshal_STRING__VOID); 706 var->set_fromstring_fn = owl_variable_make_closure( 707 var, G_CALLBACK(owl_variable_string_set_fromstring_default), 708 g_cclosure_user_marshal_INT__STRING); 709 710 g_value_init(&var->val, G_TYPE_STRING); 711 owl_variable_set_string(var, default_val); 712 713 var->default_str = owl_variable_get_tostring(var); 714 owl_variable_dict_add_variable(vd, var); 715 } 716 717 void owl_variable_dict_newvar_string(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description) { 718 owl_variable_dict_newvar_string_full(vd, name, default_val, summary, description, 719 "<string>", NULL, NULL, NULL); 720 } 721 722 void owl_variable_dict_newvar_path(owl_vardict *vd, const char *name, const char *default_val, const char *summary, const char *description) { 723 owl_variable_dict_newvar_string_full(vd, name, default_val, summary, description, 724 "<path>", NULL, NULL, NULL); 725 } 726 727 static void owl_variable_dict_newvar_enum_full(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validsettings, validate_int_t validate_fn, set_int_t set_fn, get_int_t get_fn) 728 { 729 owl_variable *var = owl_variable_newvar(OWL_VARIABLE_INT, name, summary, 730 description, validsettings); 731 var->takes_on_off = false; 732 var->get_fn = G_CALLBACK(get_fn ? get_fn : owl_variable_int_get_default); 733 var->set_fn = G_CALLBACK(set_fn ? set_fn : owl_variable_int_set_default); 734 var->validate_fn = G_CALLBACK(validate_fn ? validate_fn : owl_variable_enum_validate); 735 736 var->get_tostring_fn = owl_variable_make_closure( 737 var, G_CALLBACK(owl_variable_enum_get_tostring), 738 g_cclosure_user_marshal_STRING__VOID); 739 var->set_fromstring_fn = owl_variable_make_closure( 740 var, G_CALLBACK(owl_variable_enum_set_fromstring), 741 g_cclosure_user_marshal_INT__STRING); 742 743 g_value_init(&var->val, G_TYPE_INT); 744 owl_variable_set_int(var, default_val); 745 746 var->default_str = owl_variable_get_tostring(var); 747 owl_variable_dict_add_variable(vd, var); 748 } 749 750 void owl_variable_dict_newvar_enum(owl_vardict *vd, const char *name, int default_val, const char *summary, const char *description, const char *validset) { 751 owl_variable_dict_newvar_enum_full(vd, name, default_val, summary, description, 752 validset, NULL, NULL, NULL); 753 } 754 755 void owl_variable_dict_newvar_other(owl_vardict *vd, const char *name, const char *summary, const char *description, const char *validsettings, bool takes_on_off, GClosure *get_tostring_fn, GClosure *set_fromstring_fn) 756 { 757 owl_variable *var = owl_variable_newvar(OWL_VARIABLE_OTHER, name, summary, 758 description, validsettings); 759 var->takes_on_off = takes_on_off; 760 761 var->get_tostring_fn = g_closure_ref(get_tostring_fn); 762 g_closure_sink(get_tostring_fn); 763 764 var->set_fromstring_fn = g_closure_ref(set_fromstring_fn); 765 g_closure_sink(set_fromstring_fn); 766 767 var->default_str = owl_variable_get_tostring(var); 768 769 /* Note: this'll overwrite any existing variable of that name, even a C one, 770 but it's consistent with previous behavior and commands. */ 771 owl_variable_dict_add_variable(vd, var); 738 772 } 739 773 … … 747 781 } 748 782 749 void owl_variable_cleanup(owl_variable *v) 750 { 751 if (v->delete_fn) v->delete_fn(v); 783 void owl_variable_delete(owl_variable *v) 784 { 752 785 g_free(v->name); 753 786 g_free(v->summary); 754 787 g_free(v->description); 755 if (v->type == OWL_VARIABLE_STRING)756 g_free(v->pval_default);757 } 758 759 void owl_variable_delete(owl_variable *v) 760 { 761 owl_variable_cleanup(v); 788 g_free(v->default_str); 789 g_free(v->validsettings); 790 if (v->type != OWL_VARIABLE_OTHER) 791 g_value_unset(&(v->val)); 792 g_closure_unref(v->get_tostring_fn); 793 g_closure_unref(v->set_fromstring_fn); 794 762 795 g_free(v); 763 796 } … … 785 818 return v->type; 786 819 } 787 788 /* functions for getting and setting variable values */789 820 790 821 /* returns 0 on success, prints a status msg if msg is true */ 791 822 int owl_variable_set_fromstring(owl_variable *v, const char *value, int msg) { 792 823 char *tostring; 793 if (!v->set_fromstring_fn) { 794 if (msg) owl_function_error("Variable %s is read-only", owl_variable_get_name(v)); 795 return -1; 796 } 797 if (0 != v->set_fromstring_fn(v, value)) { 824 GValue values[] = {G_VALUE_INIT, G_VALUE_INIT}; 825 GValue return_box = G_VALUE_INIT; 826 int set_successfully; 827 828 g_value_init(&values[0], G_TYPE_POINTER); 829 g_value_set_pointer(&values[0], NULL); 830 g_value_init(&values[1], G_TYPE_STRING); 831 g_value_set_static_string(&values[1], value); 832 g_value_init(&return_box, G_TYPE_INT); 833 g_closure_invoke(v->set_fromstring_fn, &return_box, 2, values, NULL); 834 835 set_successfully = g_value_get_int(&return_box); 836 if (0 != set_successfully) { 798 837 if (msg) owl_function_error("Unable to set %s (must be %s)", owl_variable_get_name(v), 799 838 owl_variable_get_validsettings(v)); 800 return -1; 839 } else if (msg) { 840 tostring = owl_variable_get_tostring(v); 841 if (tostring) { 842 owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring); 843 } else { 844 owl_function_makemsg("%s = <null>", owl_variable_get_name(v)); 845 } 846 g_free(tostring); 801 847 } 802 if (msg) { 803 tostring = v->get_tostring_fn(v, v->get_fn(v)); 804 if (tostring) 805 owl_function_makemsg("%s = '%s'", owl_variable_get_name(v), tostring); 806 else 807 owl_function_makemsg("%s = <null>", owl_variable_get_name(v)); 808 g_free(tostring); 809 } 810 return 0; 848 849 g_value_unset(&return_box); 850 g_value_unset(&values[1]); 851 g_value_unset(&values[0]); 852 return set_successfully; 811 853 } 812 854 813 855 int owl_variable_set_string(owl_variable *v, const char *newval) 814 856 { 815 if (v->type != OWL_VARIABLE_STRING) return -1; 816 return v->set_fn(v, newval); 817 } 818 857 g_return_val_if_fail(v->type == OWL_VARIABLE_STRING, -1); 858 859 set_string_t cb = (set_string_t) v->set_fn; 860 return cb(v, newval); 861 } 862 819 863 int owl_variable_set_int(owl_variable *v, int newval) 820 864 { 821 if (v->type != OWL_VARIABLE_INT && v->type != OWL_VARIABLE_BOOL) return -1; 822 return v->set_fn(v, &newval); 823 } 824 865 g_return_val_if_fail(v->type == OWL_VARIABLE_INT, -1); 866 867 set_int_t cb = (set_int_t) v->set_fn; 868 return cb(v, newval); 869 } 870 871 int owl_variable_set_bool(owl_variable *v, bool newval) { 872 g_return_val_if_fail(v->type == OWL_VARIABLE_BOOL, -1); 873 874 set_bool_t cb = (set_bool_t) v->set_fn; 875 return cb(v, newval); 876 } 877 825 878 int owl_variable_set_bool_on(owl_variable *v) 826 879 { 827 880 if (v->type != OWL_VARIABLE_BOOL) return -1; 828 return owl_variable_set_ int(v, true);881 return owl_variable_set_bool(v, true); 829 882 } 830 883 … … 832 885 { 833 886 if (v->type != OWL_VARIABLE_BOOL) return -1; 834 return owl_variable_set_ int(v, false);887 return owl_variable_set_bool(v, false); 835 888 } 836 889 837 890 CALLER_OWN char *owl_variable_get_tostring(const owl_variable *v) 838 891 { 839 return v->get_tostring_fn(v, v->get_fn(v)); 840 } 841 842 CALLER_OWN char *owl_variable_get_default_tostring(const owl_variable *v) 843 { 844 if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) { 845 return v->get_tostring_fn(v, &(v->ival_default)); 846 } else { 847 return v->get_tostring_fn(v, v->pval_default); 848 } 892 GValue instance = G_VALUE_INIT; 893 GValue tostring_box = G_VALUE_INIT; 894 char *ret = NULL; 895 896 g_value_init(&instance, G_TYPE_POINTER); 897 g_value_set_pointer(&instance, NULL); 898 g_value_init(&tostring_box, G_TYPE_STRING); 899 g_closure_invoke(v->get_tostring_fn, &tostring_box, 1, &instance, NULL); 900 901 ret = g_value_dup_string(&tostring_box); 902 903 g_value_unset(&tostring_box); 904 g_value_unset(&instance); 905 return ret; 906 } 907 908 const char *owl_variable_get_default_tostring(const owl_variable *v) 909 { 910 return v->default_str; 849 911 } 850 912 … … 854 916 } 855 917 856 /* returns a reference */857 const void *owl_variable_get(const owl_variable *v)858 {859 return v->get_fn(v);860 }861 862 918 const char *owl_variable_get_string(const owl_variable *v) 863 919 { 864 if (owl_variable_get_type(v) != OWL_VARIABLE_STRING) { 865 owl_function_error("Variable '%s' is not a string.", owl_variable_get_name(v)); 866 return NULL; 867 } 868 return owl_variable_get(v); 869 } 870 871 /* returns a reference */ 872 const void *owl_variable_get_other(const owl_variable *v) 873 { 874 if (owl_variable_get_type(v) != OWL_VARIABLE_OTHER) { 875 owl_function_error("Variable '%s' is not type other.", owl_variable_get_name(v)); 876 return NULL; 877 } 878 return owl_variable_get(v); 920 g_return_val_if_fail(v->type == OWL_VARIABLE_STRING, NULL); 921 922 get_string_t cb = (get_string_t) v->get_fn; 923 return cb(v); 879 924 } 880 925 881 926 int owl_variable_get_int(const owl_variable *v) 882 927 { 883 if (owl_variable_get_type(v) != OWL_VARIABLE_INT) { 884 owl_function_error("Variable '%s' is an int.", owl_variable_get_name(v)); 885 return -1; 886 } 887 const int *pi = owl_variable_get(v); 888 if (!pi) return -1; 889 return *pi; 890 } 891 892 int owl_variable_get_bool(const owl_variable *v) 893 { 894 if (owl_variable_get_type(v) != OWL_VARIABLE_BOOL) { 895 owl_function_error("Variable '%s' is a boolean.", owl_variable_get_name(v)); 896 return -1; 897 } 898 const int *pi = owl_variable_get(v); 899 if (!pi) return -1; 900 return *pi; 928 g_return_val_if_fail(v->type == OWL_VARIABLE_INT, 0); 929 930 get_int_t cb = (get_int_t) v->get_fn; 931 return cb(v); 932 } 933 934 bool owl_variable_get_bool(const owl_variable *v) 935 { 936 g_return_val_if_fail(v->type == OWL_VARIABLE_BOOL, FALSE); 937 938 get_bool_t cb = (get_bool_t) v->get_fn; 939 return cb(v); 901 940 } 902 941 903 942 void owl_variable_describe(const owl_variable *v, owl_fmtext *fm) 904 943 { 905 c har *tostring= owl_variable_get_default_tostring(v);944 const char *default_str = owl_variable_get_default_tostring(v); 906 945 char *default_buf; 907 946 908 if ( tostring)909 default_buf = g_strdup_printf("'%s'", tostring);947 if (default_str) 948 default_buf = g_strdup_printf("'%s'", default_str); 910 949 else 911 950 default_buf = g_strdup("<null>"); … … 914 953 owl_variable_get_summary(v), default_buf); 915 954 g_free(default_buf); 916 g_free(tostring);917 955 } 918 956 919 957 void owl_variable_get_help(const owl_variable *v, owl_fmtext *fm) { 920 958 char *tostring; 959 const char *default_str; 921 960 922 961 owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n"); … … 933 972 owl_fmtext_append_normal(fm, "\n\n"); 934 973 935 936 tostring = owl_variable_get_default_tostring(v); 974 default_str = owl_variable_get_default_tostring(v); 937 975 owl_fmtext_append_normal(fm, "Default: "); 938 owl_fmtext_append_normal(fm, ( tostring ? tostring: "<null>"));976 owl_fmtext_append_normal(fm, (default_str ? default_str : "<null>")); 939 977 owl_fmtext_append_normal(fm, "\n\n"); 940 978 … … 948 986 owl_fmtext_append_normal(fm, "\n\n"); 949 987 } 950 g_free(tostring);951 988 } 952 989 … … 960 997 /* default common functions */ 961 998 962 const void *owl_variable_get_default(const owl_variable *v) { 963 return v->val; 964 } 965 966 void owl_variable_delete_default(owl_variable *v) 967 { 968 g_free(v->val); 999 const char *owl_variable_string_get_default(const owl_variable *v) { 1000 return g_value_get_string(&(v->val)); 1001 } 1002 1003 int owl_variable_int_get_default(const owl_variable *v) { 1004 return g_value_get_int(&(v->val)); 1005 } 1006 1007 bool owl_variable_bool_get_default(const owl_variable *v) { 1008 return g_value_get_boolean(&(v->val)); 969 1009 } 970 1010 971 1011 /* default functions for booleans */ 972 1012 973 int owl_variable_bool_validate_default(const owl_variable *v, const void *newval) { 974 if (newval == NULL) return(0); 975 else if (*(const int*)newval==1 || *(const int*)newval==0) return(1); 976 else return (0); 977 } 978 979 int owl_variable_bool_set_default(owl_variable *v, const void *newval) { 980 if (v->validate_fn) { 981 if (!v->validate_fn(v, newval)) return(-1); 1013 int owl_variable_bool_validate_default(const owl_variable *v, bool newval) { 1014 return (newval == 1) || (newval == 0); 1015 } 1016 1017 int owl_variable_bool_set_default(owl_variable *v, bool newval) { 1018 if (!((validate_bool_t)v->validate_fn)(v, newval)) 1019 return -1; 1020 1021 g_value_set_boolean(&(v->val), newval); 1022 return(0); 1023 } 1024 1025 int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) { 1026 bool i; 1027 if (!strcmp(newval, "on")) { 1028 i = true; 1029 } else if (!strcmp(newval, "off")) { 1030 i = false; 1031 } else { 1032 return(-1); 982 1033 } 983 *(int*)v->val = *(const int*)newval; 984 return(0); 985 } 986 987 int owl_variable_bool_set_fromstring_default(owl_variable *v, const char *newval) { 988 int i; 989 if (!strcmp(newval, "on")) i=1; 990 else if (!strcmp(newval, "off")) i=0; 991 else return(-1); 992 return (v->set_fn(v, &i)); 993 } 994 995 CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, const void *val) 996 { 997 if (val == NULL) { 998 return NULL; 999 } else if (*(const int*)val == 0) { 1034 1035 return owl_variable_set_bool(v, i); 1036 } 1037 1038 CALLER_OWN char *owl_variable_bool_get_tostring_default(const owl_variable *v, void *dummy) 1039 { 1040 bool val = owl_variable_get_bool(v); 1041 if (val == 0) { 1000 1042 return g_strdup("off"); 1001 } else if ( *(const int*)val == 1) {1043 } else if (val == 1) { 1002 1044 return g_strdup("on"); 1003 1045 } else { … … 1008 1050 /* default functions for integers */ 1009 1051 1010 int owl_variable_int_validate_default(const owl_variable *v, const void *newval) {1011 if (newval == NULL) return(0); 1012 elsereturn (1);1013 } 1014 1015 int owl_variable_int_set_default(owl_variable *v, const void *newval) {1016 if ( v->validate_fn) {1017 if (!v->validate_fn(v, newval)) return(-1);1018 } 1019 *(int*)v->val = *(const int*)newval;1052 int owl_variable_int_validate_default(const owl_variable *v, int newval) 1053 { 1054 return (1); 1055 } 1056 1057 int owl_variable_int_set_default(owl_variable *v, int newval) { 1058 if (!((validate_int_t)v->validate_fn)(v, newval)) 1059 return -1; 1060 1061 g_value_set_int(&(v->val), newval); 1020 1062 return(0); 1021 1063 } 1022 1064 1023 int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval ) {1065 int owl_variable_int_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) { 1024 1066 int i; 1025 1067 char *ep; 1026 1068 i = strtol(newval, &ep, 10); 1027 1069 if (*ep || ep==newval) return(-1); 1028 return (v->set_fn(v, &i)); 1029 } 1030 1031 CALLER_OWN char *owl_variable_int_get_tostring_default(const owl_variable *v, const void *val) 1032 { 1033 if (val == NULL) { 1034 return NULL; 1035 } else { 1036 return g_strdup_printf("%d", *(const int*)val); 1037 } 1070 return owl_variable_set_int(v, i); 1071 } 1072 1073 CALLER_OWN char *owl_variable_int_get_tostring_default(const owl_variable *v, void *dummy) 1074 { 1075 return g_strdup_printf("%d", owl_variable_get_int(v)); 1038 1076 } 1039 1077 1040 1078 /* default functions for enums (a variant of integers) */ 1041 1079 1042 int owl_variable_enum_validate(const owl_variable *v, const void *newval) {1080 int owl_variable_enum_validate(const owl_variable *v, int newval) { 1043 1081 char **enums; 1044 1082 int nenums, val; 1045 if (newval == NULL) return(0);1046 1083 enums = g_strsplit_set(v->validsettings, ",", 0); 1047 1084 nenums = g_strv_length(enums); 1048 1085 g_strfreev(enums); 1049 val = *(const int*)newval;1086 val = newval; 1050 1087 if (val < 0 || val >= nenums) { 1051 1088 return(0); … … 1054 1091 } 1055 1092 1056 int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval ) {1093 int owl_variable_enum_set_fromstring(owl_variable *v, const char *newval, void *dummy) { 1057 1094 char **enums; 1058 1095 int i, val=-1; … … 1066 1103 g_strfreev(enums); 1067 1104 if (val == -1) return(-1); 1068 return (v->set_fn(v, &val));1069 } 1070 1071 CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, const void *val)1105 return owl_variable_set_int(v, val); 1106 } 1107 1108 CALLER_OWN char *owl_variable_enum_get_tostring(const owl_variable *v, void *dummy) 1072 1109 { 1073 1110 char **enums; … … 1075 1112 char *tostring; 1076 1113 1077 if (val == NULL) {1078 return NULL;1079 }1080 1114 enums = g_strsplit_set(v->validsettings, ",", 0); 1081 1115 nenums = g_strv_length(enums); 1082 i = *(const int*)val;1116 i = owl_variable_get_int(v); 1083 1117 if (i<0 || i>=nenums) { 1084 1118 g_strfreev(enums); … … 1092 1126 /* default functions for stringeans */ 1093 1127 1094 int owl_variable_string_validate_default(const struct _owl_variable *v, const void*newval) {1128 int owl_variable_string_validate_default(const owl_variable *v, const char *newval) { 1095 1129 if (newval == NULL) return(0); 1096 1130 else return (1); 1097 1131 } 1098 1132 1099 int owl_variable_string_set_default(owl_variable *v, const void *newval) { 1100 if (v->validate_fn) { 1101 if (!v->validate_fn(v, newval)) return(-1); 1102 } 1103 g_free(v->val); 1104 v->val = g_strdup(newval); 1133 int owl_variable_string_set_default(owl_variable *v, const char *newval) { 1134 if (!((validate_string_t)v->validate_fn)(v, newval)) 1135 return -1; 1136 1137 g_value_set_string(&(v->val), newval); 1105 1138 return(0); 1106 1139 } 1107 1140 1108 int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval) { 1109 return (v->set_fn(v, newval)); 1110 } 1111 1112 CALLER_OWN char *owl_variable_string_get_tostring_default(const owl_variable *v, const void *val) 1113 { 1114 return g_strdup((const char*)val); 1115 } 1116 1141 int owl_variable_string_set_fromstring_default(owl_variable *v, const char *newval, void *dummy) 1142 { 1143 return owl_variable_set_string(v, newval); 1144 } 1145 1146 CALLER_OWN char *owl_variable_string_get_tostring_default(const owl_variable *v, void *dummy) 1147 { 1148 return g_strdup(owl_variable_get_string(v)); 1149 } 1150 -
window.c
reba02ec r3442788 397 397 } 398 398 399 static owl_window *_get_cursor(void) 400 { 399 static owl_window *_get_cursor(bool *is_default) 400 { 401 *is_default = false; 401 402 if (cursor_owner && owl_window_is_realized(cursor_owner)) 402 403 return cursor_owner; 404 *is_default = true; 403 405 if (default_cursor && owl_window_is_realized(default_cursor)) 404 406 return default_cursor; … … 486 488 owl_window *cursor; 487 489 owl_window *screen = owl_window_get_screen(); 490 bool default_cursor; 488 491 489 492 if (!screen->dirty_subtree) … … 491 494 _owl_window_redraw_subtree(screen); 492 495 update_panels(); 493 cursor = _get_cursor( );496 cursor = _get_cursor(&default_cursor); 494 497 if (cursor && cursor->win) { 498 /* If supported, hide the default cursor. */ 499 curs_set(default_cursor ? 0 : 1); 495 500 /* untouch it to avoid drawing; window should be clean now, but we must 496 501 * clean up in case there was junk left over on a subwin (cleaning up after -
zcrypt.c
r97cdbaf5 r8f335a8 16 16 #include <sys/wait.h> 17 17 #include <ctype.h> 18 19 #include "config.h" 18 #include <limits.h> 19 #include <getopt.h> 20 21 #include <config.h> 20 22 21 23 #ifdef HAVE_KERBEROS_IV … … 26 28 27 29 #include "filterproc.h" 30 31 #ifndef OWL_VERSION_STRING 32 #ifdef GIT_VERSION 33 #define stringify(x) __stringify(x) 34 #define __stringify(x) #x 35 #define OWL_VERSION_STRING stringify(GIT_VERSION) 36 #else 37 #define OWL_VERSION_STRING PACKAGE_VERSION 38 #endif 39 #endif /* !OWL_VERSION_STRING */ 28 40 29 41 /* Annotate functions in which the caller owns the return value and is … … 106 118 } 107 119 120 void usage(FILE *file, const char *progname) 121 { 122 fprintf(file, "Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", progname); 123 fprintf(file, " [-advqtluon] [-s signature] [-f arg] [-m message]\n"); 124 fprintf(file, " One or more of class, instance, and keyfile must be specified.\n"); 125 } 126 108 127 int main(int argc, char *argv[]) 109 128 { … … 116 135 int mode = M_NONE; 117 136 118 charc;137 int c; 119 138 120 139 int messageflag = FALSE; … … 122 141 zoptions.flags = 0; 123 142 124 while ((c = getopt(argc, argv, "ZDERSF:c:i:advqtluons:f:m")) != (char)EOF) 143 enum { 144 OPT_VERSION = CHAR_MAX + 1, 145 OPT_HELP, 146 }; 147 static const struct option options[] = { 148 {"version", no_argument, NULL, OPT_VERSION}, 149 {"help", no_argument, NULL, OPT_HELP}, 150 {NULL, 0, NULL, 0} 151 }; 152 153 while ((c = getopt_long(argc, argv, "ZDERSF:c:i:advqtluons:f:m", options, NULL)) != -1) 125 154 { 126 155 switch(c) 127 156 { 157 case OPT_VERSION: 158 /* Version */ 159 printf("This is zcrypt version %s\n", OWL_VERSION_STRING); 160 exit(0); 161 case OPT_HELP: 162 /* Help */ 163 usage(stdout, argv[0]); 164 exit(0); 128 165 case 'Z': 129 166 /* Zephyr encrypt */ … … 257 294 if (error || !cryptspec) 258 295 { 259 fprintf(stderr, "Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", argv[0]); 260 fprintf(stderr, " [-advqtluon] [-s signature] [-f arg] [-m message]\n"); 261 fprintf(stderr, " One or more of class, instance, and keyfile must be specified.\n"); 296 usage(stderr, argv[0]); 262 297 exit(1); 263 298 } … … 766 801 "gpg", 767 802 "--symmetric", 803 "--no-options", 804 "--no-default-keyring", 805 "--keyring", "/dev/null", 806 "--secret-keyring", "/dev/null", 768 807 "--batch", 769 808 "--quiet", … … 846 885 "gpg", 847 886 "--decrypt", 887 "--no-options", 888 "--no-default-keyring", 889 "--keyring", "/dev/null", 890 "--secret-keyring", "/dev/null", 848 891 "--batch", 849 892 "--no-use-agent", … … 858 901 859 902 err = call_filter(argv, in, &out, &status); 903 free(in); 860 904 if(err || status) { 861 905 g_free(out); -
zephyr.c
ra03a409 r80d7b44 29 29 #define HM_SVC_FALLBACK htons((unsigned short) 2104) 30 30 31 static char *owl_zephyr_dotfile(const char *name, const char *input)31 static CALLER_OWN char *owl_zephyr_dotfile(const char *name, const char *input) 32 32 { 33 33 if (input != NULL) … … 291 291 struct stat statbuff; 292 292 293 subs = g_new(ZSubscription_t, subSize);294 293 subsfile = owl_zephyr_dotfile(".zephyr.subs", filename); 295 294 … … 307 306 if (!file) 308 307 return -1; 308 309 subs = g_new(ZSubscription_t, subSize); 309 310 while (owl_getline(&buffer, file)) { 310 311 if (buffer[0] == '#' || buffer[0] == '\n') … … 454 455 } 455 456 456 voidunsuball(void)457 bool unsuball(void) 457 458 { 458 459 #if HAVE_LIBZEPHYR … … 464 465 owl_function_error("Zephyr: Cancelling subscriptions: %s", 465 466 error_message(ret)); 466 #endif 467 return (ret == ZERR_NONE); 468 #endif 469 return true; 467 470 } 468 471 … … 716 719 notice.z_kind=ACKED; 717 720 notice.z_port=0; 721 #ifdef ZCHARSET_UTF_8 722 notice.z_charset = ZCHARSET_UTF_8; 723 #endif 718 724 notice.z_class=zstr(class); 719 725 notice.z_class_inst=zstr(instance); … … 725 731 if (!owl_zwrite_recip_is_personal(recipient) && *owl_global_get_zsender(&g)) 726 732 notice.z_sender = zsender = long_zuser(owl_global_get_zsender(&g)); 727 notice.z_default_format=zstr( "Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\nFrom: @bold{$1 <$sender>}\n\n$2");733 notice.z_default_format=zstr(ZEPHYR_DEFAULT_FORMAT); 728 734 if (opcode) notice.z_opcode=zstr(opcode); 729 735 … … 738 744 /* free then check the return */ 739 745 g_free(notice.z_message); 740 ZFreeNotice(¬ice);741 746 g_free(zsender); 742 747 if (ret != ZERR_NONE) { … … 1020 1025 } 1021 1026 1027 g_free(subsfile); 1022 1028 g_free(line); 1023 1029 #endif
Note: See TracChangeset
for help on using the changeset viewer.