Net::XMPP version 1.0-2
Well, here is what I use. Its a modified version of the sendxmpp command
#!/usr/bin/perl -w
#-*-mode:perl-*-
#Time-stamp: <2004-12-01 14:52:47 (djcb)> # script to send message using xmpp (aka jabber), # somewhat resembling mail(1) # author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
# copyright (c) 2004, Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
#
# released under the terms of the GNU General Public License v2 use Net::XMPP;
use Mail::Internet;
use Getopt::Long;
use strict; # subroutines decls
sub xmpp_login($$$$$$);
sub xmpp_send_message($$$$$);
sub xmpp_send_chatroom_message($$$$$);
sub xmpp_logout($);
sub xmpp_presence_callback($$);
sub xmpp_check_result;
sub parse_cmdline();
sub error_exit;
sub debug_print;
sub read_config_file($);
sub push_hash($$);
sub main (); my # MakeMaker
$VERSION = ''0.0.5'';
my $RESOURCE = ''sendxmpp'';
my $VERBOSE = 0;
my $DEBUG = 0;
my %STATUS;
# start!
&main; #
# main: main routine
#
sub main () { my $cmdline = parse_cmdline();
$DEBUG = 1 if ($$cmdline{''debug''});
$VERBOSE = 1 if ($$cmdline{''verbose''}); my $config = read_config_file ($$cmdline{''file''})
unless ($$cmdline{''jserver''} && $$cmdline{''username''} && $$cmdline{''password''} && $$cmdline{''online''});
# login to xmpp
my $cnx = xmpp_login ($$cmdline{''jserver''} || $$config{''jserver''},
$$cmdline{''username''} || $$config{''username''},
$$cmdline{''password''} || $$config{''password''},
$$cmdline{''resource''},
$$cmdline{''tls''},
$$cmdline{''debug''})
or error_exit("cannot login: $!");
unless ($$cmdline{''chatroom''}) {
xmpp_send_message ($cnx,
$$cmdline{''recipient''},
$$cmdline{''subject''},
$$cmdline{''online''},
$$cmdline{''message''});
} else {
xmpp_send_chatroom_message ($cnx,
$$cmdline{''resource''},
$$cmdline{''subject''},
$$cmdline{''recipient''},
$$cmdline{''message''});
} xmpp_logout($cnx);
exit(0);
} sub mail_parse_msg {
# Read and parse email
my $mail = Mail::Internet->new(*STDIN);
my $msg = $mail->body();
my @m = @{$msg}[0..5];
# Extract header info
my $header = $mail->head()->header_hashref();
chomp $header->{$_}[0] foreach keys(%{$header});
# Create message body
my $body = "Incoming Email: \n";
$body .= "From: $header->{From}[0]\n";
$body .= "To: ".join(", ",@{$header->{To}})."\n";
if($header->{CC}) {
$body .= "Cc: ".join(", ",@{$header->{CC}})."\n";
}
$body .= "Subject: $header->{Subject}[0]\n";
$body .= "Date: $header->{Date}[0]\n";
$body .= "\n";
$body .= join(" ",@m);
print("Message: $body");
return $body;
} #
# read_config_file: read the configuration file
# input: filename
# output: hash with ''user'', ''jserver'' and ''password'' keys
#
sub read_config_file ($) {
# check permissions
my $cfg_file = shift;
error_exit ("cannot read $cfg_file: $!") unless (-r $cfg_file); my $owner = (stat($cfg_file))[4];
error_exit ("you must own $cfg_file")
unless ($owner == $>); my $mode = (stat($cfg_file))[2] & 07777;
error_exit ("$cfg_file must have mode 0600")
unless ($mode == 0600);
open (CFG,"<$cfg_file")
or error_exit("cannot open $cfg_file for reading: $!"); my %config;
my $line = 0;
while (<CFG>) { ++$line; next if (/^\s*$/); # ignore empty lines
next if (/^\s*\#.*/); # ignore comment lines s/\#.*$//; # ignore comments in lines if (/([-\.\w]+)@([-\.\w]+)\s+(\S+)\s*$/) {
%config = (''username''=>$1,
''jserver''=>$2, ''password''=>$3); } else {
close(CFG);
error_exit ("syntax error in line $line of $cfg_file");
}
} close(CFG);
error_exit ("no correct config found in $cfg_file") unless (scalar(%config)); if ($DEBUG || $VERBOSE) {
while (my ($key,$val) = each %config) {
debug_print ("config: ''$key'' => ''$val''");
}
} return \%config; } #
# parse_cmdline: parse commandline options
# output: hash with commandline options
#
sub parse_cmdline () {
usage() unless (scalar(@ARGV));
my ($subject,$file,$resource,$jserver,$username,$password,
$message,$chatroom,$online,$debug,$tls,$help,$verbose);
my $res = GetOptions (''subject|s=s'' => \$subject,
''file|f=s'' => \$file,
''resource|r=s'' => \$resource,
''jserver|j=s'' => \$jserver,
''username|u=s'' => \$username,
''password|p=s'' => \$password,
''chatroom|c'' => \$chatroom,
''online|o'' => \$online,
''tls|t'' => \$tls,
''help|usage|h'' => \$help,
''debug|d'' => \$debug,
''verbose|v'' => \$verbose);
usage () if ($help); my $rcpt = $ARGV[0]
or error_exit("no recipient specified"); ## read message from STDIN
my $txt = mail_parse_msg();
my %dict = (''subject'' => ($subject or ''''),
''message'' => ($txt or ''''),
''resource'' => ($resource or $RESOURCE),
''jserver'' => ($jserver or ''''),
''username'' => ($username or ''''),
''password'' => ($password or ''''),
''chatroom'' => ($chatroom or 0),
''online'' => ($online or 0),
''tls'' => ($tls or 0),
''debug'' => ($debug or 0),
''verbose'' => ($verbose or 0),
''file'' => ($file or ($ENV{''HOME''}.''/.sendxmpprc'')),
''recipient'' => $rcpt); if ($DEBUG || $VERBOSE) {
while (my ($key,$val) = each %dict) {
debug_print ("cmdline: ''$key'' => ''$val''");
}
} return \%dict; } #
# xmpp_login: login to the xmmp (jabber) server
# input: hostname,username,password,resource,tls,debug
# output: an XMPP connection object
#
sub xmpp_login ($$$$$$) { my ($host,$user,$pw,$res,$tls,$debug) = @_;
my $cnx = new Net::XMPP::Client(debuglevel=>($debug?2:0));
#$STATUS = new Net::XMPP::Roster(connection=>$cnx);
$cnx->SetPresenceCallBacks(available=>\&xmpp_presence_callback);
error_exit ("could not create XMPP client object: $!")
unless ($cnx); my @res = $cnx->Connect(hostname=>$host,tls=>$tls);
xmpp_check_result("Connect",\@res,$cnx); @res = $cnx->AuthIQAuth(''hostname''=>$host,
''username''=>$user,
''password''=>$pw,
''resource''=>$res);
xmpp_check_result(''AuthSend'',\@res,$cnx);
@res = $cnx->PresenceSend(type=>''available'');
xmpp_check_result("PresenceSend",\@res,$cnx); return $cnx; } #
# xmmp_send_message: send a message to some xmmp user
# input: connection,recipient,subject,online,msg
#
sub xmpp_send_message ($$$$$) {
my ($cnx,$rcpt,$subject,$online,$msg) = @_; if($online) {
debug_print("checking if $rcpt is online");
$cnx->Process(1);
if($STATUS{$rcpt}) {
debug_print("$rcpt is online");
} else {
debug_print("$rcpt is not online");
return;
}
}
# for some reason, MessageSend does not return anything
$cnx->MessageSend(''to''=>$rcpt,
''subject''=>$subject,
''body''=>$msg);
xmpp_check_result(''MessageSend'',0,$cnx);
}
#
# xmpp_send_chatroom_message: send a message to a chatroom
# input: connection,resource,subject,recipient,message
#
sub xmpp_send_chatroom_message ($$$$$) { my ($cnx,$resource,$subject,$rcpt,$msg) = @_;
# set the presence
my $pres = new Net::XMPP::Presence;
my $res = $pres->SetTo("$rcpt/$resource"); $cnx->Send($pres); # create/send the message
my $groupmsg = new Net::XMPP::Message;
$groupmsg->SetMessage(to=>$rcpt, body=>$msg,
subject=>$subject,
type=>''groupchat''); $res = $cnx->Send($groupmsg);
xmpp_check_result (''Send'',$res,$cnx); # leave the group
$pres->SetPresence (Type=>''unavailable'',To=>$rcpt);
} #
# xmmp_logout: log out from the xmpp server
# input: connection
#
sub xmpp_logout($) {
# HACK
# messages may not be received if we log out too quickly...
sleep 1; my $cnx = shift;
$cnx->Disconnect();
xmpp_check_result (''Disconnect'',0); # well, nothing to check, really
} #
# xmpp_check_result: check the return value from some xmpp function execution
# input: text, result, [connection] #
sub xmpp_check_result { my ($txt,$res,$cnx)=@_;
error_exit ("Error ''$txt'': result undefined")
unless (defined $res); # res may be 0
if ($res == 0) {
debug_print "$txt";
# result can be true or ''ok'' } elsif ((@$res == 1 && $$res[0]) || $$res[0] eq ''ok'') {
debug_print "$txt: " . $$res[0];
# otherwise, there is some error
} else {
my $errmsg = $cnx->GetErrorCode() || ''?'';
error_exit ("Error ''$txt'': " . join ('': '',@$res) . "[$errmsg]", $cnx);
}
} sub xmpp_presence_callback ($$) {
my $sid = shift;
my $presence = shift;
my $jid = $presence->GetFrom("jid")->GetJID("base");
my $status = $presence->GetStatus();
if($status eq "") { $status = "online";}
debug_print("got status from $jid: $status");
$STATUS{$jid} = $status;
} #
# debug_print: print the data if defined and DEBUG || VERBOSE is TRUE
# input: [array of strings]
#
sub debug_print {
print STDERR "sendxmpp: " . (join '' '',@_) . "\n"
if (@_ && ($DEBUG ||$VERBOSE));
} #
# error_exit: print error message and exit the program
# logs out if there is a connection # input: error, [connection]
#
sub error_exit {
my ($err,$cnx) = @_;
print STDERR "$err\n"; xmpp_logout ($cnx) if ($cnx); exit 1;
} #
# usage: print short usage message and exit
#
sub usage () {
print "sendxmpp version $VERSION, (c) 2004 Dirk-Jan C. Binnema\n" .
"usage: sendxmpp [options] <recipient>\n" .
"or refer to the the sendxmpp manpage\n";
exit 0;
}
You run it like this:
cat mailmsg | sendxmpp.pl -u username -p password -j servername -o recipient-JID@someserver
This is on Debian 4.0 using the packages from the default repositories.