Net-Jabber-2.0/0002755000175000017500000000000010112242737014421 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/lib/0002755000175000017500000000000010112242736015166 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/lib/Net/0002755000175000017500000000000010112242736015714 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/lib/Net/Jabber.pm0000644000175000017500000001355010110275751017442 0ustar reatmonreatmon00000000000000############################################################################### # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################### package Net::Jabber; =head1 NAME Net::Jabber - Jabber Perl Library =head1 SYNOPSIS Net::Jabber provides a Perl user with access to the Jabber Instant Messaging protocol. For more information about Jabber visit: http://www.jabber.org =head1 DESCRIPTION Net::Jabber is a convenient tool to use for any perl script that would like to utilize the Jabber Instant Messaging protocol. While not a client in and of itself, it provides all of the necessary back-end functions to make a CGI client or command-line perl client feasible and easy to use. Net::Jabber is a wrapper around the rest of the official Net::Jabber::xxxxxx packages. There is are example scripts in the example directory that provide you with examples of very simple Jabber programs. NOTE: The parser that XML::Stream::Parser provides, as are most Perl parsers, is synchronous. If you are in the middle of parsing a packet and call a user defined callback, the Parser is blocked until your callback finishes. This means you cannot be operating on a packet, send out another packet and wait for a response to that packet. It will never get to you. Threading might solve this, but as of the writing of this, threading in Perl is not quite up to par yet. This issue will be revisted in the future. =head1 EXAMPLES For a client: use Net::Jabber; my $client = new Net::Jabber::Client(); For a component: use Net::Jabber; my $component = new Net::Jabber::Component(); =head1 METHODS The Net::Jabber module does not define any methods that you will call directly in your code. Instead you will instantiate objects that call functions from this module to do work. The three main objects that you will work with are the Message, Presence, and IQ modules. Each one corresponds to the Jabber equivilant and allows you get and set all parts of those packets. =head1 PACKAGES For more information on each of these packages, please see the man page for each one. =head2 Net::Jabber::Client This package contains the code needed to communicate with a Jabber server: login, wait for messages, send messages, and logout. It uses XML::Stream to read the stream from the server and based on what kind of tag it encounters it calls a function to handle the tag. =head2 Net::Jabber::Component This package contains the code needed to write a server component. A component is a program tha handles the communication between a jabber server and some outside program or communications pacakge (IRC, talk, email, etc...) With this module you can write a full component in just a few lines of Perl. It uses XML::Stream to communicate with its host server and based on what kind of tag it encounters it calls a function to handle the tag. =head2 Net::Jabber::Protocol A collection of high-level functions that Client and Component use to make their lives easier through inheritance. =head2 Net::Jabber::JID The Jabber IDs consist of three parts: user id, server, and resource. This module gives you access to those components without having to parse the string yourself. =head2 Net::Jabber::Message Everything needed to create and read a received from the server. =head2 Net::Jabber::Presence Everything needed to create and read a received from the server. =head2 Net::Jabber::IQ IQ is a wrapper around a number of modules that provide support for the various Info/Query namespaces that Jabber recognizes. =head2 Net::Jabber::Stanza This module represents a namespaced stanza that is used to extend a , , and . Ultimately each namespace is documented in a JEP of some kind. http://jabber.org/jeps/ The man page for Net::Jabber::Stanza contains a listing of all supported namespaces, and the methods that are supported by the objects that represent those namespaces. =head2 Net::Jabber::Namespaces Jabber allows for any stanza to be extended by any bit of XML. This module contains all of the internals for defining the Jabber based extensions defined by the JEPs. The documentation for this module explains more about how to add your own custom namespace and have it be supported. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.005; use strict; use Carp; use POSIX; use Net::XMPP 1.0; use base qw( Net::XMPP ); use vars qw( $VERSION ); $VERSION = "2.0"; use Net::Jabber::Debug; use Net::Jabber::JID; use Net::Jabber::Namespaces; use Net::Jabber::Stanza; use Net::Jabber::Message; use Net::Jabber::IQ; use Net::Jabber::Presence; use Net::Jabber::Protocol; use Net::Jabber::Client; use Net::Jabber::Component; sub GetTimeStamp { return &Net::XMPP::GetTimeStamp(@_); } sub printData { return &Net::XMPP::printData(@_); } sub sprintData { return &Net::XMPP::sprintData(@_); } 1; Net-Jabber-2.0/lib/Net/Jabber/0002755000175000017500000000000010112242737017102 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/lib/Net/Jabber/Protocol.pm0000644000175000017500000031225310110304740021234 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Protocol; =head1 NAME Net::Jabber::Protocol - Jabber Protocol Library =head1 SYNOPSIS Net::Jabber::Protocol is a module that provides a developer easy access to the Jabber Instant Messaging protocol. It provides high level functions to the Net::Jabber Client, Component, and Server objects. These functions are automatically indluded in those modules through AUTOLOAD and delegates. =head1 DESCRIPTION Protocol.pm seeks to provide enough high level APIs and automation of the low level APIs that writing a Jabber Client/Transport in Perl is trivial. For those that wish to work with the low level you can do that too, but those functions are covered in the documentation for each module. Net::Jabber::Protocol provides functions to login, send and receive messages, set personal information, create a new user account, manage the roster, and disconnect. You can use all or none of the functions, there is no requirement. For more information on how the details for how Net::Jabber is written please see the help for Net::Jabber itself. For more information on writing a Client see Net::Jabber::Client. For more information on writing a Transport see Net::Jabber::Transport. =head2 Modes Several of the functions take a mode argument that let you specify how the function should behave: block - send the packet with an ID, and then block until an answer comes back. You can optionally specify a timeout so that you do not block forever. nonblock - send the packet with an ID, but then return that id and control to the master program. Net::Jabber is still tracking this packet, so you must use the CheckID function to tell when it comes in. (This might not be very useful...) passthru - send the packet with an ID, but do NOT register it with Net::Jabber, then return the ID. This is useful when combined with the XPath function because you can register a one shot function tied to the id you get back. =head2 Basic Functions use Net::Jabber qw( Client ); $Con = new Net::Jabber::Client(); # From $status = $Con->Connect(hostname=>"jabber.org"); # Net::Jabber::Client or use Net::Jabber qw( Component ); $Con = new Net::Jabber::Component(); # $status = $Con->Connect(hostname=>"jabber.org", # From secret=>"bob"); # Net::Jabber::Component # # For callback setup, see Net::XMPP::Protocol # $Con->Info(name=>"Jarl", version=>"v0.6000"); =head2 ID Functions $id = $Con->SendWithID($sendObj); $id = $Con->SendWithID("XML"); $receiveObj = $Con->SendAndReceiveWithID($sendObj); $receiveObj = $Con->SendAndReceiveWithID($sendObj, 10); $receiveObj = $Con->SendAndReceiveWithID("XML"); $receiveObj = $Con->SendAndReceiveWithID("XML", 5); $yesno = $Con->ReceivedID($id); $receiveObj = $Con->GetID($id); $receiveObj = $Con->WaitForID($id); $receiveObj = $Con->WaitForID($id, 20); =head2 IQ Functions =head2 Agents Functions %agents = $Con->AgentsGet(); %agents = $Con->AgentsGet(to=>"transport.jabber.org"); =head2 Browse Functions %hash = $Con->BrowseRequest(jid=>"jabber.org"); %hash = $Con->BrowseRequest(jid=>"jabber.org", timeout=>10); $id = $Con->BrowseRequest(jid=>"jabber.org", mode=>"nonblock"); $id = $Con->BrowseRequest(jid=>"jabber.org", mode=>"passthru"); =head2 Browse DB Functions $Con->BrowseDBDelete("jabber.org"); $Con->BrowseDBDelete(Net::Jabber::JID); $presence = $Con->BrowseDBQuery(jid=>"bob\@jabber.org"); $presence = $Con->BrowseDBQuery(jid=>Net::Jabber::JID); $presence = $Con->BrowseDBQuery(jid=>"users.jabber.org", timeout=>10); $presence = $Con->BrowseDBQuery(jid=>"conference.jabber.org", refresh=>1); =head2 Bystreams Functions %hash = $Con->ByteStreamsProxyRequest(jid=>"proxy.server"); %hash = $Con->ByteStreamsProxyRequest(jid=>"proxy.server", timeout=>10); $id = $Con->ByteStreamsProxyRequest(jid=>"proxy.server", mode=>"nonblock"); $id = $Con->ByteStreamsProxyRequest(jid=>"proxy.server", mode=>"passthru"); %hash = $Con->ByteStreamsProxyParse($query); $status = $Con->ByteStreamsProxyActivate(sid=>"stream_id", jid=>"proxy.server"); $status = $Con->ByteStreamsProxyActivate(sid=>"stream_id", jid=>"proxy.server", timeout=>10); $id = $Con->ByteStreamsProxyActivate(sid=>"stream_id", jid=>"proxy.server", mode=>"nonblock"); $id = $Con->ByteStreamsProxyActivate(sid=>"stream_id", jid=>"proxy.server", mode=>"passthru"); $jid = $Con->ByteStreamsOffer(sid=>"stream_id", streamhosts=>[{jid=>"jid", host=>"host", port=>"port", zeroconf=>"zero", }, ... ], jid=>"bob\@jabber.org"); $jid = $Con->ByteStreamsOffer(sid=>"stream_id", streamhosts=>[{},{},...], jid=>"bob\@jabber.org", timeout=>10); $id = $Con->ByteStreamsOffer(sid=>"stream_id", streamhosts=>[{},{},...], jid=>"bob\@jabber.org", mode=>"nonblock"); $id = $Con->ByteStreamsOffer(sid=>"stream_id", streamhosts=>[{},{},...], jid=>"bob\@jabber.org", mode=>"passthru"); =head2 Disco Functions %hash = $Con->DiscoInfoRequest(jid=>"jabber.org"); %hash = $Con->DiscoInfoRequest(jid=>"jabber.org", node=>"node..."); %hash = $Con->DiscoInfoRequest(jid=>"jabber.org", node=>"node...", timeout=>10); $id = $Con->DiscoInfoRequest(jid=>"jabber.org", mode=>"nonblock"); $id = $Con->DiscoInfoRequest(jid=>"jabber.org", node=>"node...", mode=>"nonblock"); $id = $Con->DiscoInfoRequest(jid=>"jabber.org", mode=>"passthru"); $id = $Con->DiscoInfoRequest(jid=>"jabber.org", node=>"node...", mode=>"passthru"); %hash = $Con->DiscoInfoParse($query); %hash = $Con->DiscoItemsRequest(jid=>"jabber.org"); %hash = $Con->DiscoItemsRequest(jid=>"jabber.org", timeout=>10); $id = $Con->DiscoItemsRequest(jid=>"jabber.org", mode=>"nonblock"); $id = $Con->DiscoItemsRequest(jid=>"jabber.org", mode=>"passthru"); %hash = $Con->DiscoItemsParse($query); =head2 Feature Negotiation Functions %hash = $Con->FeatureNegRequest(jid=>"jabber.org", features=>{ feat1=>["opt1","opt2",...], feat2=>["optA","optB",...] } ); %hash = $Con->FeatureNegRequest(jid=>"jabber.org", features=>{ ... }, timeout=>10); $id = $Con->FeatureNegRequest(jid=>"jabber.org", features=>{ ... }, mode=>"nonblock"); $id = $Con->FeatureNegRequest(jid=>"jabber.org", features=>{ ... }, mode=>"passthru"); my $query = $self->FeatureNegQuery(\{ ... }); $iq->AddQuery($query); %hash = $Con->FeatureNegParse($query); =head2 File Transfer Functions $method = $Con->FileTransferOffer(jid=>"bob\@jabber.org", sid=>"stream_id", filename=>"/path/to/file", methods=>["http://jabber.org/protocol/si/profile/bytestreams", "jabber:iq:oob", ... ] ); $method = $Con->FileTransferOffer(jid=>"bob\@jabber.org", sid=>"stream_id", filename=>"/path/to/file", methods=>\@methods, timeout=>"10"); $id = $Con->FileTransferOffer(jid=>"bob\@jabber.org", sid=>"stream_id", filename=>"/path/to/file", methods=>\@methods, mode=>"nonblock"); $id = $Con->FileTransferOffer(jid=>"bob\@jabber.org", sid=>"stream_id", filename=>"/path/to/file", methods=>\@methods, mode=>"passthru"); =head2 Last Functions $Con->LastQuery(); $Con->LastQuery(to=>"bob@jabber.org"); %result = $Con->LastQuery(mode=>"block"); %result = $Con->LastQuery(to=>"bob@jabber.org", mode=>"block"); %result = $Con->LastQuery(to=>"bob@jabber.org", mode=>"block", timeout=>10); %result = $Con->LastQuery(mode=>"block", timeout=>10); $Con->LastSend(to=>"bob@jabber.org"); $seconds = $Con->LastActivity(); =head2 Multi-User Chat Functions $Con->MUCJoin(room=>"jabber", server=>"conference.jabber.org", nick=>"nick"); $Con->MUCJoin(room=>"jabber", server=>"conference.jabber.org", nick=>"nick", password=>"secret"); =head2 Register Functions @result = $Con->RegisterSendData("users.jabber.org", first=>"Bob", last=>"Smith", nick=>"bob", email=>"foo@bar.net"); =head2 RPC Functions $query = $Con->RPCEncode(type=>"methodCall", methodName=>"methodName", params=>[param,param,...]); $query = $Con->RPCEncode(type=>"methodResponse", params=>[param,param,...]); $query = $Con->RPCEncode(type=>"methodResponse", faultCode=>4, faultString=>"Too many params"); @response = $Con->RPCParse($iq); @response = $Con->RPCCall(to=>"dataHouse.jabber.org", methodname=>"numUsers", params=>[ param,param,... ] ); $Con->RPCResponse(to=>"you\@jabber.org", params=>[ param,param,... ]); $Con->RPCResponse(to=>"you\@jabber.org", faultCode=>"4", faultString=>"Too many parameters" ); $Con->RPCSetCallBacks(myMethodA=>\&methoda, myMethodB=>\&do_somthing, etc... ); =head2 Search Functions %fields = $Con->SearchRequest(); %fields = $Con->SearchRequest(to=>"users.jabber.org"); %fields = $Con->SearchRequest(to=>"users.jabber.org", timeout=>10); $Con->SearchSend(to=>"somewhere", name=>"", first=>"Bob", last=>"", nick=>"bob", email=>"", key=>"some key"); $Con->SearchSendData("users.jabber.org", first=>"Bob", last=>"", nick=>"bob", email=>""); =head2 Time Functions $Con->TimeQuery(); $Con->TimeQuery(to=>"bob@jabber.org"); %result = $Con->TimeQuery(mode=>"block"); %result = $Con->TimeQuery(to=>"bob@jabber.org", mode=>"block"); $Con->TimeSend(to=>"bob@jabber.org"); =head2 Version Functions $Con->VersionQuery(); $Con->VersionQuery(to=>"bob@jabber.org"); %result = $Con->VersionQuery(mode=>"block"); %result = $Con->VersionQuery(to=>"bob@jabber.org", mode=>"block"); $Con->VersionSend(to=>"bob@jabber.org", name=>"Net::Jabber", ver=>"1.0a", os=>"Perl"); =head1 METHODS =head2 Basic Functions Info(name=>string, - Set some information so that Net::Jabber version=>string) can auto-reply to some packets for you to reduce the work you have to do. NOTE: This requires that you use the SetIQCallBacks methodology and not the SetCallBacks for packets. =head2 IQ Functions =head2 Agents Functions ******************************** * * * Deprecated in favor of Disco * * * ******************************** AgentsGet(to=>string, - takes all of the information and AgentsGet() builds a Net::Jabber::IQ::Agents packet. It then sends that packet either to the server, or to the specified transport, with an ID and waits for that ID to return. Then it looks in the resulting packet and builds a hash that contains the values of the agent list. The hash is layed out like this: (NOTE: the jid is the key to distinguish the various agents) $hash{}->{order} = 4 ->{name} = "ICQ Transport" ->{transport} = "ICQ #" ->{description} = "ICQ..blah.." ->{service} = "icq" ->{register} = 1 ->{search} = 1 etc... The order field determines the order that it came from the server in... in case you care. For more info on the valid fields see the Net::Jabber::Query jabber:iq:agent namespace. =head2 Browse Functions ******************************** * * * Deprecated in favor of Disco * * * ******************************** BrowseRequest(jid=>string, - sends a jabber:iq:browse request to mode=>string, the jid passed as an argument. timeout=>int) Returns a hash with the resulting tree if mode is set to "block": $browse{'category'} = "conference" $browse{'children'}->[0] $browse{'children'}->[1] $browse{'children'}->[11] $browse{'jid'} = "conference.jabber.org" $browse{'name'} = "Jabber.org Conferencing Center" $browse{'ns'}->[0] $browse{'ns'}->[1] $browse{'type'} = "public" The ns array is an array of the namespaces that this jid supports. The children array points to hashs of this form, and represent the fact that they can be browsed to. See MODES above for using the mode and timeout. =head2 Browse DB Functions BrowseDBDelete(string|Net::Jabber::JID) - delete thes JID browse data from the DB. BrowseDBQuery(jid=>string | NJ::JID, - returns the browse data timeout=>integer, for the requested JID. If refresh=>0|1) the DB does not contain the data for the JID, then it attempts to fetch the data via BrowseRequest(). The timeout is passed to the BrowseRequest() call, and refresh tells the DB to request the data, even if it already has some. =head2 Bytestreams Functions ByteStreamsProxyRequest(jid=>string, - sends a bytestreams request mode=>string, to the jid passed as an timeout=>int) argument. Returns an array ref with the resulting tree if mode is set to "block". See ByteStreamsProxyParse for the format of the resulting tree. See MODES above for using the mode and timeout. ByteStreamsProxyParse(Net::Jabber::Query) - parses the query and returns an array ref to the resulting tree: $host[0]->{jid} = "bytestreams1.proxy.server"; $host[0]->{host} = "proxy1.server"; $host[0]->{port} = "5006"; $host[1]->{jid} = "bytestreams2.proxy.server"; $host[1]->{host} = "proxy2.server"; $host[1]->{port} = "5007"; ... ByteStreamsProxyActivate(jid=>string, - sends a bytestreams activate sid=>string, to the jid passed as an mode=>string, argument. Returns 1 if the timeout=>int) proxy activated (undef if it did not) if mode is set to "block". sid is the stream id that is being used to talk about this stream. See MODES above for using the mode and timeout. ByteStreamsOffer(jid=>string, - sends a bytestreams offer sid=>string, to the jid passed as an streamhosts=>arrayref argument. Returns the jid mode=>string, of the streamhost that the timeout=>int) user selected if mode is set to "block". streamhosts is the same format as the array ref returned from ByteStreamsProxyParse. See MODES above for using the mode and timeout. =head2 Disco Functions DiscoInfoRequest(jid=>string, - sends a disco#info request to node=>string, the jid passed as an argument, mode=>string, and the node if specified. timeout=>int) Returns a hash with the resulting tree if mode is set to "block". See DiscoInfoParse for the format of the resulting tree. See MODES above for using the mode and timeout. DiscoInfoParse(Net::Jabber::Query) - parses the query and returns a hash ref to the resulting tree: $info{identity}->[0]->{category} = "groupchat"; $info{identity}->[0]->{name} = "Public Chatrooms"; $info{identity}->[0]->{type} = "public"; $info{identity}->[1]->{category} = "groupchat"; $info{identity}->[1]->{name} = "Private Chatrooms"; $info{identity}->[1]->{type} = "private"; $info{feature}->{http://jabber.org/protocol/disco#info} = 1; $info{feature}->{http://jabber.org/protocol/muc#admin} = 1; DiscoItemsRequest(jid=>string, - sends a disco#items request to mode=>string, the jid passed as an argument. timeout=>int) Returns a hash with the resulting tree if mode is set to "block". See DiscoItemsParse for the format of the resulting tree. See MODES above for using the mode and timeout. DiscoItemsParse(Net::Jabber::Query) - parses the query and returns a hash ref to the resulting tree: $items{jid}->{node} = name; $items{"proxy.server"}->{""} = "Bytestream Proxy Server"; $items{"conf.server"}->{"public"} = "Public Chatrooms"; $items{"conf.server"}->{"private"} = "Private Chatrooms"; =head2 Feature Negotiation Functions FeatureNegRequest(jid=>string, - sends a feature negotiation to features=>hash ref, the jid passed as an argument, mode=>string, using the features specified. timeout=>int) Returns a hash with the resulting tree if mode is set to "block". See DiscoInfoQuery for the format of the features hash ref. See DiscoInfoParse for the format of the resulting tree. See MODES above for using the mode and timeout. FeatureNegParse(Net::Jabber::Query) - parses the query and returns a hash ref to the resulting tree: $features->{feat1} = ["opt1","opt2",...]; $features->{feat2} = ["optA","optB",...]; .... If this is a result: $features->{feat1} = "opt2"; $features->{feat2} = "optA"; .... FeatureNeqQuery(hash ref) - takes a hash ref and turns it into a feature negotiation query that you can AddQuery into your packaet. The format of the hash ref is as follows: $features->{feat1} = ["opt1","opt2",...]; $features->{feat2} = ["optA","optB",...]; .... =head2 File Transfer Functions FileTransferOffer(jid=>string, - sends a file transfer stream sid=>string, initiation to the jid passed filename=>string, as an argument. Returns the mode=>string, method (if the users accepts), timeout=>int) undef (if the user declines), if the mode is set to "block". See MODES above for using the mode and timeout. =head2 Last Functions LastQuery(to=>string, - asks the jid specified for its last mode=>string, activity. If the to is blank, then it timeout=>int) queries the server. Returns a hash with LastQuery() the various items set if mode is set to "block": $last{seconds} - Seconds since activity $last{message} - Message for activity See MODES above for using the mode and timeout. LastSend(to=>string, - sends the specified last to the specified jid. hash) the hash is the seconds and message as shown in the Net::Jabber::Query man page. LastActivity() - returns the number of seconds since the last activity by the user. =head2 Multi-User Chat Functions MUCJoin(room=>string, - Sends the appropriate MUC protocol to join server=>string, the specified room with the specified nick. nick=>string, password=>string) =head2 Register Functions RegisterSendData(string|JID, - takes the contents of the hash and hash) builds a jabebr:x:data return packet which it sends in a Net::Jabber::Query jabber:iq:register namespace packet. The first argument is the JID to send the packet to. This function returns an array that looks like this: [ type , message ] If type is "ok" then registration was successful, otherwise message contains a little more detail about the error. =head2 RPC Functions RPCParse(IQ object) - returns an array. The first argument tells the status "ok" or "fault". The second argument is an array if "ok", or a hash if "fault". RPCCall(to=>jid|string, - takes the methodName and params, methodName=>string, builds the RPC calls and sends it params=>array, to the specified address. Returns mode=>string, the above data from RPCParse. timeout=>int) See MODES above for using the mode and timeout. RPCResponse(to=>jid|string, - generates a response back to params=>array, the caller. If any part of faultCode=>int, fault is specified, then it faultString=>string) wins. Note: To ensure that you get the correct type for a param sent back, you can specify the type by prepending the type to the value: "i4:5" or "int:5" "boolean:0" "string:56" "double:5.0" "datetime:20020415T11:11:11" "base64:...." RPCSetCallBacks(method=>function, - sets the callback functions method=>function, for the specified methods. etc...) The method comes from the and is case sensitive. The single arguemnt is a ref to an array that contains the . The function you write should return one of two things: ["ok", [...] ] The [...] is a list of the you want to return. ["fault", {faultCode=>1, faultString=>...} ] If you set the function to undef, then the method is removed from the list. =head2 Search Functions SearchRequest(to=>string, - send an request to the specified mode=>string, server/transport, if not specified it timeout=>int) sends to the current active server. SearchRequest() The function returns a hash that contains the required fields. Here is an example of the hash: $hash{fields} - The raw fields from the iq:register. To be used if there is no x:data in the packet. $hash{instructions} - How to fill out the form. $hash{form} - The new dynamic forms. In $hash{form}, the fields that are present are the required fields the server needs. See MODES above for using the mode and timeout. SearchSend(to=>string|JID, - takes the contents of the hash and hash) passes it to the SetSearch function in the Net::Jabber::Query jabber:iq:search namespace. And then sends the packet. SearchSendData(string|JID, - takes the contents of the hash and hash) builds a jabebr:x:data return packet which it sends in a Net::Jabber::Query jabber:iq:search namespace packet. The first argument is the JID to send the packet to. =head2 Time Functions TimeQuery(to=>string, - asks the jid specified for its localtime. mode=>string, If the to is blank, then it queries the timeout=>int) server. Returns a hash with the various TimeQuery() items set if mode is set to "block": $time{utc} - Time in UTC $time{tz} - Timezone $time{display} - Display string See MODES above for using the mode and timeout. TimeSend(to=>string) - sends the current UTC time to the specified jid. =head2 Version Functions VersionQuery(to=>string, - asks the jid specified for its mode=>string, client version information. If the timeout=>int) to is blank, then it queries the VersionQuery() server. Returns ahash with the various items set if mode is set to "block": $version{name} - Name $version{ver} - Version $version{os} - Operating System/ Platform See MODES above for using the mode and timeout. VersionSend(to=>string, - sends the specified version information name=>string, to the jid specified in the to. ver=>string, os=>string) =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use strict; use Carp; use vars qw($VERSION); $VERSION = "2.0"; ############################################################################## # BuildObject takes a root tag and builds the correct object. NEWOBJECT is # the table that maps tag to package. Override these, or provide new ones. #----------------------------------------------------------------------------- $Net::XMPP::Protocol::NEWOBJECT{'iq'} = "Net::Jabber::IQ"; $Net::XMPP::Protocol::NEWOBJECT{'message'} = "Net::Jabber::Message"; $Net::XMPP::Protocol::NEWOBJECT{'presence'} = "Net::Jabber::Presence"; $Net::XMPP::Protocol::NEWOBJECT{'jid'} = "Net::Jabber::JID"; ############################################################################## ############################################################################### #+----------------------------------------------------------------------------- #| #| Base API #| #+----------------------------------------------------------------------------- ############################################################################### ############################################################################### # # Info - set the base information about this Jabber Client/Component for # use in a default response. # ############################################################################### sub Info { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } foreach my $arg (keys(%args)) { $self->{INFO}->{$arg} = $args{$arg}; } } ############################################################################### # # DefineNamespace - adds the namespace and corresponding functions onto the # of available functions based on namespace. # # Deprecated in favor of AddNamespace # ############################################################################### sub DefineNamespace { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } croak("You must specify xmlns=>'' for the function call to DefineNamespace") if !exists($args{xmlns}); croak("You must specify type=>'' for the function call to DefineNamespace") if !exists($args{type}); croak("You must specify functions=>'' for the function call to DefineNamespace") if !exists($args{functions}); my %xpath; my $tag; if (exists($args{tag})) { $tag = $args{tag}; } else { $tag = "x" if ($args{type} eq "X"); $tag = "query" if ($args{type} eq "Query"); } foreach my $function (@{$args{functions}}) { my %tempHash = %{$function}; my %funcHash; foreach my $func (keys(%tempHash)) { $funcHash{lc($func)} = $tempHash{$func}; } croak("You must specify name=>'' for each function in call to DefineNamespace") if !exists($funcHash{name}); my $name = delete($funcHash{name}); if (!exists($funcHash{set}) && exists($funcHash{get})) { croak("The DefineNamespace arugments have changed, and I cannot determine the\nnew values automatically for name($name). Please read the man page\nfor Net::Jabber::Namespaces. I apologize for this incompatability.\n"); } if (exists($funcHash{type}) || exists($funcHash{path}) || exists($funcHash{child}) || exists($funcHash{calls})) { foreach my $type (keys(%funcHash)) { if ($type eq "child") { $xpath{$name}->{$type}->{ns} = $funcHash{$type}->[1]; my $i = 2; while( $i <= $#{$funcHash{$type}} ) { if ($funcHash{$type}->[$i] eq "__netjabber__:skip_xmlns") { $xpath{$name}->{$type}->{skip_xmlns} = 1; } if ($funcHash{$type}->[$i] eq "__netjabber__:specifyname") { $xpath{$name}->{$type}->{specify_name} = 1; $i++; $xpath{$name}->{$type}->{tag} = $funcHash{$type}->[$i+1]; } $i++; } } else { $xpath{$name}->{$type} = $funcHash{$type}; } } next; } my $type = $funcHash{set}->[0]; my $xpath = $funcHash{set}->[1]; if (exists($funcHash{hash})) { $xpath = "text()" if ($funcHash{hash} eq "data"); $xpath .= "/text()" if ($funcHash{hash} eq "child-data"); $xpath = "\@$xpath" if ($funcHash{hash} eq "att"); $xpath = "$1/\@$2" if ($funcHash{hash} =~ /^att-(\S+)-(.+)$/); } if ($type eq "master") { $xpath{$name}->{type} = $type; next; } if ($type eq "scalar") { $xpath{$name}->{path} = $xpath; next; } if ($type eq "flag") { $xpath{$name}->{type} = 'flag'; $xpath{$name}->{path} = $xpath; next; } if (($funcHash{hash} eq "child-add") && exists($funcHash{add})) { $xpath{$name}->{type} = "node"; $xpath{$name}->{path} = $funcHash{add}->[3]; $xpath{$name}->{child}->{ns} = $funcHash{add}->[1]; $xpath{$name}->{calls} = [ 'Add' ]; next; } } $self->AddNamespace(ns => $args{xmlns}, tag => $tag, xpath => \%xpath ); } ############################################################################### # # AgentsGet - Sends an empty IQ to the server/transport to request that the # list of supported Agents be sent to them. Returns a hash # containing the values for the agents. # ############################################################################### sub AgentsGet { my $self = shift; my $iq = $self->_iq(); $iq->SetIQ(@_); $iq->SetIQ(type=>"get"); my $query = $iq->NewQuery("jabber:iq:agents"); $iq = $self->SendAndReceiveWithID($iq); return unless defined($iq); $query = $iq->GetQuery(); my @agents = $query->GetAgents(); my %agents; my $count = 0; foreach my $agent (@agents) { my $jid = $agent->GetJID(); $agents{$jid}->{name} = $agent->GetName(); $agents{$jid}->{description} = $agent->GetDescription(); $agents{$jid}->{transport} = $agent->GetTransport(); $agents{$jid}->{service} = $agent->GetService(); $agents{$jid}->{register} = $agent->DefinedRegister(); $agents{$jid}->{search} = $agent->DefinedSearch(); $agents{$jid}->{groupchat} = $agent->DefinedGroupChat(); $agents{$jid}->{agents} = $agent->DefinedAgents(); $agents{$jid}->{order} = $count++; } return %agents; } ############################################################################### # # BrowseRequest - requests the browse information from the specified JID. # ############################################################################### sub BrowseRequest { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"get"); my $query = $iq->NewQuery("jabber:iq:browse"); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { my %browse = %{$self->BrowseParse($query)}; return %browse; } else { return; } } ############################################################################### # # BrowseParse - helper function for BrowseRequest to convert the object # tree into a hash for better consumption. # ############################################################################### sub BrowseParse { my $self = shift; my $item = shift; my %browse; if ($item->DefinedCategory()) { $browse{category} = $item->GetCategory(); } else { $browse{category} = $item->GetTag(); } $browse{type} = $item->GetType(); $browse{name} = $item->GetName(); $browse{jid} = $item->GetJID(); $browse{ns} = [ $item->GetNS() ]; foreach my $subitem ($item->GetItems()) { my ($subbrowse) = $self->BrowseParse($subitem); push(@{$browse{children}},$subbrowse); } return \%browse; } ############################################################################### # # BrowseDBDelete - delete the JID from the DB completely. # ############################################################################### sub BrowseDBDelete { my $self = shift; my ($jid) = @_; my $indexJID = $jid; $indexJID = $jid->GetJID() if (ref($jid) eq "Net::Jabber::JID"); return if !exists($self->{BROWSEDB}->{$indexJID}); delete($self->{BROWSEDB}->{$indexJID}); $self->{DEBUG}->Log1("BrowseDBDelete: delete ",$indexJID," from the DB"); } ############################################################################### # # BrowseDBQuery - retrieve the last Net::Jabber::Browse received with # the highest priority. # ############################################################################### sub BrowseDBQuery { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } $args{timeout} = 10 unless exists($args{timeout}); my $indexJID = $args{jid}; $indexJID = $args{jid}->GetJID() if (ref($args{jid}) eq "Net::Jabber::JID"); if ((exists($args{refresh}) && ($args{refresh} eq "1")) || (!exists($self->{BROWSEDB}->{$indexJID}))) { my %browse = $self->BrowseRequest(jid=>$args{jid}, timeout=>$args{timeout}); $self->{BROWSEDB}->{$indexJID} = \%browse; } return %{$self->{BROWSEDB}->{$indexJID}}; } ############################################################################### # # ByteStreamsProxyRequest - This queries a proxy server to get a list of # ############################################################################### sub ByteStreamsProxyRequest { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"get"); my $query = $iq->NewQuery("http://jabber.org/protocol/bytestreams"); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { my @hosts = @{$self->ByteStreamsProxyParse($query)}; return @hosts; } else { return; } } ############################################################################### # # ByteStreamsProxyParse - helper function for ByteStreamProxyRequest to convert # the object tree into a hash for better consumption. # ############################################################################### sub ByteStreamsProxyParse { my $self = shift; my $item = shift; my @hosts; foreach my $host ($item->GetStreamHosts()) { my %host; $host{jid} = $host->GetJID(); $host{host} = $host->GetHost() if $host->DefinedHost(); $host{port} = $host->GetPort() if $host->DefinedPort(); $host{zeroconf} = $host->GetZeroConf() if $host->DefinedZeroConf(); push(@hosts,\%host); } return \@hosts; } ############################################################################### # # ByteStreamsProxyActivate - This tells a proxy to activate the connection # ############################################################################### sub ByteStreamsProxyActivate { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"set"); my $query = $iq->NewQuery("http://jabber.org/protocol/bytestreams"); $query->SetByteStreams(sid=>$args{sid}, activate=>(ref($args{recipient}) eq "Net::Jabber::JID" ? $args{recipient}->GetJID("full") : $args{recipient}) ); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } return 1; } ############################################################################### # # ByteStreamsOffer - This offers a recipient a list of stream hosts to pick # from. # ############################################################################### sub ByteStreamsOffer { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"set"); my $query = $iq->NewQuery("http://jabber.org/protocol/bytestreams"); $query->SetByteStreams(sid=>$args{sid}); foreach my $host (@{$args{streamhosts}}) { $query->AddStreamHost(jid=>$host->{jid}, (exists($host->{host}) ? (host=>$host->{host}) : ()), (exists($host->{port}) ? (port=>$host->{port}) : ()), (exists($host->{zeroconf}) ? (zeroconf=>$host->{zeroconf}) : ()), ); } #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { return $query->GetStreamHostUsedJID(); } else { return; } } ############################################################################### # # DiscoInfoRequest - requests the disco information from the specified JID. # ############################################################################### sub DiscoInfoRequest { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"get"); my $query = $iq->NewQuery("http://jabber.org/protocol/disco#info"); $query->SetDiscoInfo(node=>$args{node}) if exists($args{node}); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } return unless $iq->DefinedQuery(); $query = $iq->GetQuery(); return %{$self->DiscoInfoParse($query)}; } ############################################################################### # # DiscoInfoParse - helper function for DiscoInfoRequest to convert the object # tree into a hash for better consumption. # ############################################################################### sub DiscoInfoParse { my $self = shift; my $item = shift; my %disco; foreach my $ident ($item->GetIdentities()) { my %identity; $identity{category} = $ident->GetCategory(); $identity{name} = $ident->GetName(); $identity{type} = $ident->GetType(); push(@{$disco{identity}},\%identity); } foreach my $feat ($item->GetFeatures()) { $disco{feature}->{$feat->GetVar()} = 1; } return \%disco; } ############################################################################### # # DiscoItemsRequest - requests the disco information from the specified JID. # ############################################################################### sub DiscoItemsRequest { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"get"); my $query = $iq->NewQuery("http://jabber.org/protocol/disco#items"); $query->SetDiscoItems(node=>$args{node}) if exists($args{node}); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { my %disco = %{$self->DiscoItemsParse($query)}; return %disco; } else { return; } } ############################################################################### # # DiscoItemsParse - helper function for DiscoItemsRequest to convert the object # tree into a hash for better consumption. # ############################################################################### sub DiscoItemsParse { my $self = shift; my $item = shift; my %disco; foreach my $item ($item->GetItems()) { $disco{$item->GetJID()}->{$item->GetNode()} = $item->GetName(); } return \%disco; } ############################################################################### # # FeatureNegRequest - requests a feature negotiation from the specified JID. # ############################################################################### sub FeatureNegRequest { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"get"); my $query = $self->FeatureNegQuery($args{features}); $iq->AddQuery($query); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { my %feats = %{$self->FeatureNegParse($query)}; return %feats; } else { return; } } #xxx fneg needs to reutrn a type='submit' on the x:data in a result ############################################################################### # # FeatureNegQuery - given a feature hash, return a query that contains it. # ############################################################################### sub FeatureNegQuery { my $self = shift; my $features = shift; my $tag = "query"; $tag = $Net::Jabber::Query::TAGS{'http://jabber.org/protocol/feature-neg'} if exists($Net::Jabber::Query::TAGS{'http://jabber.org/protocol/feature-neg'}); my $query = new Net::Jabber::Query($tag); $query->SetXMLNS("http://jabber.org/protocol/feature-neg"); my $xdata = $query->NewX("jabber:x:data"); foreach my $feature (keys(%{$features})) { my $field = $xdata->AddField(type=>"list-single", var=>$feature); foreach my $value (@{$features->{$feature}}) { $field->AddOption(value=>$value); } } return $query; } ############################################################################### # # FeatureNegParse - helper function for FeatureNegRequest to convert the object # tree into a hash for better consumption. # ############################################################################### sub FeatureNegParse { my $self = shift; my $item = shift; my %feats; my $xdata = $item->GetX("jabber:x:data"); foreach my $field ($xdata->GetFields()) { my @options; foreach my $option ($field->GetOptions()) { push(@options,$option->GetValue()); } if ($#options == -1) { $feats{$field->GetVar()} = $field->GetValue(); } else { $feats{$field->GetVar()} = \@options; } } return \%feats; } #XXX - need a feature-neg answer function... ############################################################################### # # FileTransferOffer - offer a file transfer JEP-95 # ############################################################################### sub FileTransferOffer { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"set"); my $query = $iq->NewQuery("http://jabber.org/protocol/si"); my $profile = $query->NewQuery("http://jabber.org/protocol/si/profile/file-transfer"); # XXX support hashing via MD5 # XXX support date via JEP-82 my ($filename) = ($args{filename} =~ /\/?([^\/]+)$/); $profile->SetFile(name=>$filename, size=>(-s $args{filename}) ); $profile->SetFile(desc=>$args{desc}) if exists($args{desc}); $query->SetStream(mimetype=>(-B $args{filename} ? "application/octect-stream" : "text/plain" ), id=>$args{sid}, profile=>"http://jabber.org/protocol/si/profile/file-transfer" ); if (!exists($args{skip_methods})) { if ($#{$args{methods}} == -1) { print STDERR "You did not provide any valid methods for file transfer.\n"; return; } my $fneg = $self->FeatureNegQuery({'stream-method'=>$args{methods}}); $query->AddQuery($fneg); } #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { my @fneg = $query->GetQuery("http://jabber.org/protocol/feature-neg"); my @xdata = $fneg[0]->GetX("jabber:x:data"); my @fields = $xdata[0]->GetFields(); return $fields[0]->GetValue(); # XXX need better error handling } else { return; } } ############################################################################### # # TreeTransferOffer - offer a file transfer JEP-95 # ############################################################################### sub TreeTransferOffer { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>$args{jid}, type=>"set"); my $query = $iq->NewQuery("http://jabber.org/protocol/si"); my $profile = $query->NewQuery("http://jabber.org/protocol/si/profile/tree-transfer"); my ($root) = ($args{directory} =~ /\/?([^\/]+)$/); my $rootDir = $profile->AddDirectory(name=>$root); my %tree; $tree{counter} = 0; $self->TreeTransferDescend($args{sidbase}, $args{directory}, $rootDir, \%tree ); $profile->SetTree(numfiles=>$tree{counter}, size=>$tree{size} ); $query->SetStream(id=>$args{sidbase}, profile=>"http://jabber.org/protocol/si/profile/tree-transfer" ); if ($#{$args{methods}} == -1) { print STDERR "You did not provide any valid methods for the tree transfer.\n"; return; } my $fneg = $self->FeatureNegQuery({'stream-method'=>$args{methods}}); $query->AddQuery($fneg); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); $tree{id} = $id; return %tree; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); return; } $query = $iq->GetQuery(); if (defined($query)) { my @fneg = $query->GetQuery("http://jabber.org/protocol/feature-neg"); my @xdata = $fneg[0]->GetX("jabber:x:data"); my @fields = $xdata[0]->GetFields(); return $fields[0]->GetValue(); # XXX need better error handling } else { return; } } ############################################################################### # # TreeTransferDescend - descend a directory structure and build the packet. # ############################################################################### sub TreeTransferDescend { my $self = shift; my $sidbase = shift; my $path = shift; my $parent = shift; my $tree = shift; $tree->{size} += (-s $path); opendir(DIR, $path); foreach my $file ( sort {$a cmp $b} readdir(DIR) ) { next if ($file =~ /^\.\.?$/); if (-d "$path/$file") { my $tempParent = $parent->AddDirectory(name=>$file); $self->TreeTransferDescend($sidbase, "$path/$file", $tempParent, $tree ); } else { $tree->{size} += (-s "$path/$file"); $tree->{tree}->{"$path/$file"}->{order} = $tree->{counter}; $tree->{tree}->{"$path/$file"}->{sid} = $sidbase."-".$tree->{counter}; $tree->{tree}->{"$path/$file"}->{name} = $file; $parent->AddFile(name=>$tree->{tree}->{"$path/$file"}->{name}, sid=>$tree->{tree}->{"$path/$file"}->{sid}); $tree->{counter}++; } } closedir(DIR); } ############################################################################### # # LastQuery - Sends an iq:last query to either the server or the specified # JID. # ############################################################################### sub LastQuery { my $self = shift; my %args; $args{mode} = "passthru"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } $args{waitforid} = 0 unless exists($args{waitforid}); my $waitforid = delete($args{waitforid}); $args{mode} = "block" if $waitforid; my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to})) if exists($args{to}); $iq->SetIQ(type=>'get'); my $last = $iq->NewQuery("jabber:iq:last"); if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); return unless defined($iq); $last = $iq->GetQuery(); return unless defined($last); return $last->GetLast(); } ############################################################################### # # LastSend - sends an iq:last packet to the specified user. # ############################################################################### sub LastSend { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } $args{ignoreactivity} = 0 unless exists($args{ignoreactivity}); my $ignoreActivity = delete($args{ignoreactivity}); my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to}), type=>'result'); my $last = $iq->NewQuery("jabber:iq:last"); $last->SetLast(%args); $self->Send($iq,$ignoreActivity); } ############################################################################### # # LastActivity - returns number of seconds since the last activity. # ############################################################################### sub LastActivity { my $self = shift; return (time - $self->{STREAM}->LastActivity($self->{SESSION}->{id})); } ############################################################################### # # RegisterSendData - This is a self contained function to send a register iq # tag with an id. It uses the jabber:x:data method to # return the data. # ############################################################################### sub RegisterSendData { my $self = shift; my $to = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } #-------------------------------------------------------------------------- # Create a Net::Jabber::IQ object to send to the server #-------------------------------------------------------------------------- my $iq = $self->_iq(); $iq->SetIQ(to=>$to) if (defined($to) && ($to ne "")); $iq->SetIQ(type=>"set"); my $iqRegister = $iq->NewQuery("jabber:iq:register"); my $xForm = $iqRegister->NewX("jabber:x:data"); foreach my $var (keys(%args)) { next if ($args{$var} eq ""); $xForm->AddField(var=>$var, value=>$args{$var} ); } #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- $iq = $self->SendAndReceiveWithID($iq); #-------------------------------------------------------------------------- # From the reply IQ determine if we were successful or not. If yes then # return "". If no then return error string from the reply. #-------------------------------------------------------------------------- return unless defined($iq); return ( $iq->GetErrorCode() , $iq->GetError() ) if ($iq->GetType() eq "error"); return ("ok",""); } ############################################################################### # # RPCSetCallBacks - place to register a callback for RPC calls. This is # used in conjunction with the default IQ callback. # ############################################################################### sub RPCSetCallBacks { my $self = shift; while($#_ >= 0) { my $func = pop(@_); my $method = pop(@_); $self->{DEBUG}->Log2("RPCSetCallBacks: method($method) func($func)"); if (defined($func)) { $self->{RPCCB}{$method} = $func; } else { delete($self->{RPCCB}{$method}); } } } ############################################################################### # # RPCCall - Make an RPC call to the specified JID. # ############################################################################### sub RPCCall { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(type=>"set", to=>delete($args{to})); $iq->AddQuery($self->RPCEncode(type=>"methodCall", %args)); if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); return unless defined($iq); return $self->RPCParse($iq); } ############################################################################### # # RPCResponse - Send back an RPC response, or fault, to the specified JID. # ############################################################################### sub RPCResponse { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $iq = $self->_iq(); $iq->SetIQ(type=>"result", to=>delete($args{to})); $iq->AddQuery($self->RPCEncode(type=>"methodResponse", %args)); $iq = $self->SendAndReceiveWithID($iq); return unless defined($iq); return $self->RPCParse($iq); } ############################################################################### # # RPCEncode - Returns a Net::Jabber::Query with the arguments encoded for the # RPC packet. # ############################################################################### sub RPCEncode { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $query = new Net::Jabber::Stanza("query"); $query->SetXMLNS("jabber:iq:rpc"); my $source; if ($args{type} eq "methodCall") { $source = $query->AddMethodCall(); $source->SetMethodName($args{methodname}); } if ($args{type} eq "methodResponse") { $source = $query->AddMethodResponse(); } if (exists($args{faultcode}) || exists($args{faultstring})) { my $struct = $source->AddFault()->AddValue()->AddStruct(); $struct->AddMember(name=>"faultCode")->AddValue(i4=>$args{faultcode}); $struct->AddMember(name=>"faultString")->AddValue(string=>$args{faultstring}); } elsif (exists($args{params})) { my $params = $source->AddParams(); foreach my $param (@{$args{params}}) { $self->RPCEncode_Value($params->AddParam(),$param); } } return $query; } ############################################################################### # # RPCEncode_Value - Run through the value, and encode it into XML. # ############################################################################### sub RPCEncode_Value { my $self = shift; my $obj = shift; my $value = shift; if (ref($value) eq "ARRAY") { my $array = $obj->AddValue()->AddArray(); foreach my $data (@{$value}) { $self->RPCEncode_Value($array->AddData(),$data); } } elsif (ref($value) eq "HASH") { my $struct = $obj->AddValue()->AddStruct(); foreach my $key (keys(%{$value})) { $self->RPCEncode_Value($struct->AddMember(name=>$key),$value->{$key}); } } else { if ($value =~ /^(int|i4|boolean|string|double|datetime|base64):/i) { my $type = $1; my($val) = ($value =~ /^$type:(.*)$/); $obj->AddValue($type=>$val); } elsif ($value =~ /^[+-]?\d+$/) { $obj->AddValue(i4=>$value); } elsif ($value =~ /^(-?(?:\d+(?:\.\d*)?|\.\d+)|([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)$/) { $obj->AddValue(double=>$value); } else { $obj->AddValue(string=>$value); } } } ############################################################################### # # RPCParse - Returns an array of the params sent in the RPC packet. # ############################################################################### sub RPCParse { my $self = shift; my($iq) = @_; my $query = $iq->GetQuery(); my $source; $source = $query->GetMethodCall() if $query->DefinedMethodCall(); $source = $query->GetMethodResponse() if $query->DefinedMethodResponse(); if (defined($source)) { if (($source->GetTag() eq "methodResponse") && ($source->DefinedFault())) { my %response = $self->RPCParse_Struct($source->GetFault()->GetValue()->GetStruct()); return ("fault",\%response); } if ($source->DefinedParams()) { #------------------------------------------------------------------ # The s part #------------------------------------------------------------------ my @response; foreach my $param ($source->GetParams()->GetParams()) { push(@response,$self->RPCParse_Value($param->GetValue())); } return ("ok",\@response); } } else { print "AAAAHHHH!!!!\n"; } } ############################################################################### # # RPCParse_Value - Takes a and returns the data it represents # ############################################################################### sub RPCParse_Value { my $self = shift; my($value) = @_; if ($value->DefinedStruct()) { my %struct = $self->RPCParse_Struct($value->GetStruct()); return \%struct; } if ($value->DefinedArray()) { my @array = $self->RPCParse_Array($value->GetArray()); return \@array; } return $value->GetI4() if $value->DefinedI4(); return $value->GetInt() if $value->DefinedInt(); return $value->GetBoolean() if $value->DefinedBoolean(); return $value->GetString() if $value->DefinedString(); return $value->GetDouble() if $value->DefinedDouble(); return $value->GetDateTime() if $value->DefinedDateTime(); return $value->GetBase64() if $value->DefinedBase64(); return $value->GetValue(); } ############################################################################### # # RPCParse_Struct - Takes a and returns the hash of values. # ############################################################################### sub RPCParse_Struct { my $self = shift; my($struct) = @_; my %struct; foreach my $member ($struct->GetMembers()) { $struct{$member->GetName()} = $self->RPCParse_Value($member->GetValue()); } return %struct; } ############################################################################### # # RPCParse_Array - Takes a and returns the hash of values. # ############################################################################### sub RPCParse_Array { my $self = shift; my($array) = @_; my @array; foreach my $data ($array->GetDatas()) { push(@array,$self->RPCParse_Value($data->GetValue())); } return @array; } ############################################################################### # # SearchRequest - This is a self contained function to send an iq tag # an id that requests the target address to send back # the required fields. It waits for a reply what the # same id to come back and tell the caller what the # fields are. # ############################################################################### sub SearchRequest { my $self = shift; my %args; $args{mode} = "block"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; #-------------------------------------------------------------------------- # Create a Net::Jabber::IQ object to send to the server #-------------------------------------------------------------------------- my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to})) if exists($args{to}); $iq->SetIQ(type=>"get"); my $query = $iq->NewQuery("jabber:iq:search"); $self->{DEBUG}->Log1("SearchRequest: sent(",$iq->GetXML(),")"); #-------------------------------------------------------------------------- # Send the IQ with the next available ID and wait for a reply with that # id to be received. Then grab the IQ reply. #-------------------------------------------------------------------------- if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); $self->{DEBUG}->Log1("SearchRequest: received(",$iq->GetXML(),")") if defined($iq); #-------------------------------------------------------------------------- # Check if there was an error. #-------------------------------------------------------------------------- return unless defined($iq); if ($iq->GetType() eq "error") { $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError()); $self->{DEBUG}->Log1("SearchRequest: error(",$self->GetErrorCode(),")"); return; } my %search; #-------------------------------------------------------------------------- # From the reply IQ determine what fields are required and send a hash # back with the fields and any values that are already defined (like key) #-------------------------------------------------------------------------- $query = $iq->GetQuery(); $search{fields} = { $query->GetSearch() }; #-------------------------------------------------------------------------- # Get any forms so that we have the option of showing a nive dynamic form # to the user and not just a bunch of fields. #-------------------------------------------------------------------------- &ExtractForms(\%search,$query->GetX("jabber:x:data")); #-------------------------------------------------------------------------- # Get any oobs so that we have the option of sending the user to the http # form and not a dynamic one. #-------------------------------------------------------------------------- &ExtractOobs(\%search,$query->GetX("jabber:x:oob")); return %search; } ############################################################################### # # SearchSend - This is a self contained function to send a search # iq tag with an id. Then wait for a reply what the same # id to come back and tell the caller what the result was. # ############################################################################### sub SearchSend { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } #-------------------------------------------------------------------------- # Create a Net::Jabber::IQ object to send to the server #-------------------------------------------------------------------------- my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to})) if exists($args{to}); $iq->SetIQ(type=>"set"); my $iqSearch = $iq->NewQuery("jabber:iq:search"); $iqSearch->SetSearch(%args); #-------------------------------------------------------------------------- # Send the IQ. #-------------------------------------------------------------------------- $self->Send($iq); } ############################################################################### # # SearchSendData - This is a self contained function to send a search iq tag # with an id. It uses the jabber:x:data method to return the # data. # ############################################################################### sub SearchSendData { my $self = shift; my $to = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } #-------------------------------------------------------------------------- # Create a Net::Jabber::IQ object to send to the server #-------------------------------------------------------------------------- my $iq = $self->_iq(); $iq->SetIQ(to=>$to) if (defined($to) && ($to ne "")); $iq->SetIQ(type=>"set"); my $iqSearch = $iq->NewQuery("jabber:iq:search"); my $xForm = $iqSearch->NewX("jabber:x:data"); foreach my $var (keys(%args)) { next if ($args{$var} eq ""); $xForm->AddField(var=>$var, value=>$args{$var} ); } #-------------------------------------------------------------------------- # Send the IQ. #-------------------------------------------------------------------------- $self->Send($iq); } ############################################################################### # # TimeQuery - Sends an iq:time query to either the server or the specified # JID. # ############################################################################### sub TimeQuery { my $self = shift; my %args; $args{mode} = "passthru"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } $args{waitforid} = 0 unless exists($args{waitforid}); my $waitforid = delete($args{waitforid}); $args{mode} = "block" if $waitforid; my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to})) if exists($args{to}); $iq->SetIQ(type=>'get',%args); my $time = $iq->NewQuery("jabber:iq:time"); if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); return unless defined($iq); my $query = $iq->GetQuery(); return unless defined($query); my %result; $result{utc} = $query->GetUTC(); $result{display} = $query->GetDisplay(); $result{tz} = $query->GetTZ(); return %result; } ############################################################################### # # TimeSend - sends an iq:time packet to the specified user. # ############################################################################### sub TimeSend { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to}), type=>'result'); my $time = $iq->NewQuery("jabber:iq:time"); $time->SetTime(%args); $self->Send($iq); } ############################################################################### # # VersionQuery - Sends an iq:version query to either the server or the # specified JID. # ############################################################################### sub VersionQuery { my $self = shift; my %args; $args{mode} = "passthru"; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } $args{waitforid} = 0 unless exists($args{waitforid}); my $waitforid = delete($args{waitforid}); $args{mode} = "block" if $waitforid; my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef; my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to})) if exists($args{to}); $iq->SetIQ(type=>'get',%args); my $version = $iq->NewQuery("jabber:iq:version"); if ($args{mode} eq "passthru") { my $id = $self->UniqueID(); $iq->SetIQ(id=>$id); $self->Send($iq); return $id; } return $self->SendWithID($iq) if ($args{mode} eq "nonblock"); $iq = $self->SendAndReceiveWithID($iq,$timeout); return unless defined($iq); my $query = $iq->GetQuery(); return unless defined($query); my %result; $result{name} = $query->GetName(); $result{ver} = $query->GetVer(); $result{os} = $query->GetOS(); return %result; } ############################################################################### # # VersionSend - sends an iq:version packet to the specified user. # ############################################################################### sub VersionSend { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $iq = $self->_iq(); $iq->SetIQ(to=>delete($args{to}), type=>'result'); my $version = $iq->NewQuery("jabber:iq:version"); $version->SetVersion(%args); $self->Send($iq); } ############################################################################### # # MUCJoin - join a MUC room # ############################################################################### sub MUCJoin { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $presence = $self->_presence(); $presence->SetTo($args{room}.'@'.$args{server}.'/'.$args{nick}); my $x = $presence->NewChild("http://jabber.org/protocol/muc"); if (exists($args{password}) && ($args{password} ne "")) { $x->SetMUC(password=>$args{password}); } return $presence->GetXML() if exists($args{'__netjabber__:test'}); $self->Send($presence); } ############################################################################### #+----------------------------------------------------------------------------- #| #| Helper Functions #| #+----------------------------------------------------------------------------- ############################################################################### ############################################################################### # # ExtractForms - Helper function to make extracting jabber:x:data for forms # more centrally definable. # ############################################################################### sub ExtractForms { my ($target,@xForms) = @_; my $tempVar = "1"; foreach my $xForm (@xForms) { $target->{instructions} = $xForm->GetInstructions(); my $order = 0; foreach my $field ($xForm->GetFields()) { $target->{form}->[$order]->{type} = $field->GetType() if $field->DefinedType(); $target->{form}->[$order]->{label} = $field->GetLabel() if $field->DefinedLabel(); $target->{form}->[$order]->{desc} = $field->GetDesc() if $field->DefinedDesc(); $target->{form}->[$order]->{var} = $field->GetVar() if $field->DefinedVar(); $target->{form}->[$order]->{var} = "__netjabber__:tempvar:".$tempVar++ if !$field->DefinedVar(); if ($field->DefinedValue()) { if ($field->GetType() eq "list-multi") { $target->{form}->[$order]->{value} = [ $field->GetValue() ]; } else { $target->{form}->[$order]->{value} = ($field->GetValue())[0]; } } my $count = 0; foreach my $option ($field->GetOptions()) { $target->{form}->[$order]->{options}->[$count]->{value} = $option->GetValue(); $target->{form}->[$order]->{options}->[$count]->{label} = $option->GetLabel(); $count++; } $order++; } foreach my $reported ($xForm->GetReported()) { my $order = 0; foreach my $field ($reported->GetFields()) { $target->{reported}->[$order]->{label} = $field->GetLabel(); $target->{reported}->[$order]->{var} = $field->GetVar(); $order++; } } } } ############################################################################### # # ExtractOobs - Helper function to make extracting jabber:x:oob for forms # more centrally definable. # ############################################################################### sub ExtractOobs { my ($target,@xOobs) = @_; foreach my $xOob (@xOobs) { $target->{oob}->{url} = $xOob->GetURL(); $target->{oob}->{desc} = $xOob->GetDesc(); } } ############################################################################### #+----------------------------------------------------------------------------- #| #| Default CallBacks #| #+----------------------------------------------------------------------------- ############################################################################### ############################################################################### # # callbackInit - initialize the default callbacks # ############################################################################### sub callbackInit { my $self = shift; $self->SUPER::callbackInit(); $self->SetIQCallBacks("jabber:iq:last"=> { get=>sub{ $self->callbackGetIQLast(@_) }, result=>sub{ $self->callbackResultIQLast(@_) } }, "jabber:iq:rpc"=> { set=>sub{ $self->callbackSetIQRPC(@_) }, }, "jabber:iq:time"=> { get=>sub{ $self->callbackGetIQTime(@_) }, result=>sub{ $self->callbackResultIQTime(@_) } }, "jabber:iq:version"=> { get=>sub{ $self->callbackGetIQVersion(@_) }, result=>sub{ $self->callbackResultIQVersion(@_) } }, ); } ############################################################################### # # callbackSetIQRPC - callback to handle auto-replying to an iq:rpc by calling # the user registered functions. # ############################################################################### sub callbackSetIQRPC { my $self = shift; my $sid = shift; my $iq = shift; my $query = $iq->GetQuery(); my $reply = $iq->Reply(type=>"result"); my $replyQuery = $reply->GetQuery(); if (!$query->DefinedMethodCall()) { my $methodResponse = $replyQuery->AddMethodResponse(); my $struct = $methodResponse->AddFault()->AddValue()->AddStruct(); $struct->AddMember(name=>"faultCode")->AddValue(int=>400); $struct->AddMember(name=>"faultString")->AddValue(string=>"Missing methodCall."); $self->Send($reply,1); return; } if (!$query->GetMethodCall()->DefinedMethodName()) { my $methodResponse = $replyQuery->AddMethodResponse(); my $struct = $methodResponse->AddFault()->AddValue()->AddStruct(); $struct->AddMember(name=>"faultCode")->AddValue(int=>400); $struct->AddMember(name=>"faultString")->AddValue(string=>"Missing methodName."); $self->Send($reply,1); return; } my $methodName = $query->GetMethodCall()->GetMethodName(); if (!exists($self->{RPCCB}->{$methodName})) { my $methodResponse = $replyQuery->AddMethodResponse(); my $struct = $methodResponse->AddFault()->AddValue()->AddStruct(); $struct->AddMember(name=>"faultCode")->AddValue(int=>404); $struct->AddMember(name=>"faultString")->AddValue(string=>"methodName $methodName not defined."); $self->Send($reply,1); return; } my @params = $self->RPCParse($iq); my @return = &{$self->{RPCCB}->{$methodName}}($iq,$params[1]); if ($return[0] ne "ok") { my $methodResponse = $replyQuery->AddMethodResponse(); my $struct = $methodResponse->AddFault()->AddValue()->AddStruct(); $struct->AddMember(name=>"faultCode")->AddValue(int=>$return[1]->{faultCode}); $struct->AddMember(name=>"faultString")->AddValue(string=>$return[1]->{faultString}); $self->Send($reply,1); return; } $reply->RemoveQuery(); $reply->AddQuery($self->RPCEncode(type=>"methodResponse", params=>$return[1])); $self->Send($reply,1); } ############################################################################### # # callbackGetIQTime - callback to handle auto-replying to an iq:time get. # ############################################################################### sub callbackGetIQTime { my $self = shift; my $sid = shift; my $iq = shift; my $query = $iq->GetQuery(); my $reply = $iq->Reply(type=>"result"); my $replyQuery = $reply->GetQuery(); $replyQuery->SetTime(); $self->Send($reply,1); } ############################################################################### # # callbackResultIQTime - callback to handle formatting iq:time result into # a message. # ############################################################################### sub callbackResultIQTime { my $self = shift; my $sid = shift; my $iq = shift; my $fromJID = $iq->GetFrom("jid"); my $query = $iq->GetQuery(); my $body = "UTC: ".$query->GetUTC()."\n"; $body .= "Time: ".$query->GetDisplay()."\n"; $body .= "Timezone: ".$query->GetTZ()."\n"; my $message = $self->_message(); $message->SetMessage(to=>$iq->GetTo(), from=>$iq->GetFrom(), subject=>"CTCP: Time", body=>$body); $self->CallBack($sid,$message); } ############################################################################### # # callbackGetIQVersion - callback to handle auto-replying to an iq:time # get. # ############################################################################### sub callbackGetIQVersion { my $self = shift; my $sid = shift; my $iq = shift; my $query = $iq->GetQuery(); my $reply = $iq->Reply(type=>"result"); my $replyQuery = $reply->GetQuery(); $replyQuery->SetVersion(name=>$self->{INFO}->{name}, ver=>$self->{INFO}->{version}, os=>""); $self->Send($reply,1); } ############################################################################### # # callbackResultIQVersion - callback to handle formatting iq:time result # into a message. # ############################################################################### sub callbackResultIQVersion { my $self = shift; my $sid = shift; my $iq = shift; my $query = $iq->GetQuery(); my $body = "Program: ".$query->GetName()."\n"; $body .= "Version: ".$query->GetVer()."\n"; $body .= "OS: ".$query->GetOS()."\n"; my $message = $self->_message(); $message->SetMessage(to=>$iq->GetTo(), from=>$iq->GetFrom(), subject=>"CTCP: Version", body=>$body); $self->CallBack($sid,$message); } ############################################################################### # # callbackGetIQLast - callback to handle auto-replying to an iq:last get. # ############################################################################### sub callbackGetIQLast { my $self = shift; my $sid = shift; my $iq = shift; my $query = $iq->GetQuery(); my $reply = $iq->Reply(type=>"result"); my $replyQuery = $reply->GetQuery(); $replyQuery->SetLast(seconds=>$self->LastActivity()); $self->Send($reply,1); } ############################################################################### # # callbackResultIQLast - callback to handle formatting iq:last result into # a message. # ############################################################################### sub callbackResultIQLast { my $self = shift; my $sid = shift; my $iq = shift; my $fromJID = $iq->GetFrom("jid"); my $query = $iq->GetQuery(); my $seconds = $query->GetSeconds(); my $lastTime = &Net::Jabber::GetTimeStamp("local",(time - $seconds),"long"); my $elapsedTime = &Net::Jabber::GetHumanTime($seconds); my $body; if ($fromJID->GetUserID() eq "") { $body = "Start Time: $lastTime\n"; $body .= "Up time: $elapsedTime\n"; $body .= "Message: ".$query->GetMessage()."\n" if ($query->DefinedMessage()); } elsif ($fromJID->GetResource() eq "") { $body = "Logout Time: $lastTime\n"; $body .= "Elapsed time: $elapsedTime\n"; $body .= "Message: ".$query->GetMessage()."\n" if ($query->DefinedMessage()); } else { $body = "Last activity: $lastTime\n"; $body .= "Elapsed time: $elapsedTime\n"; $body .= "Message: ".$query->GetMessage()."\n" if ($query->DefinedMessage()); } my $message = $self->_message(); $message->SetMessage(from=>$iq->GetFrom(), subject=>"Last Activity", body=>$body); $self->CallBack($sid,$message); } 1; Net-Jabber-2.0/lib/Net/Jabber/XDB.pm0000644000175000017500000003355010110275744020063 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::XDB; =head1 NAME Net::Jabber::XDB - Jabber XDB Library =head1 SYNOPSIS Net::Jabber::XDB is a companion to the Net::Jabber module. It provides the user a simple interface to set and retrieve all parts of a Jabber XDB. =head1 DESCRIPTION Net::Jabber::XDB differs from the other Net::Jabber::* modules in that the XMLNS of the data is split out into more submodules under XDB. For specifics on each module please view the documentation for each Net::Jabber::Data::* module. To see the list of avilable namspaces and modules see Net::Jabber::Data. To initialize the XDB with a Jabber you must pass it the XML::Parser Tree array. For example: my $xdb = new Net::Jabber::XDB(@tree); There has been a change from the old way of handling the callbacks. You no longer have to do the above, a Net::Jabber::XDB object is passed to the callback function for the xdb: use Net::Jabber qw(Component); sub xdb { my ($XDB) = @_; . . . } You now have access to all of the retrieval functions available. To create a new xdb to send to the server: use Net::Jabber; $XDB = new Net::Jabber::XDB(); $XDBType = $XDB->NewData( type ); $XDBType->SetXXXXX("yyyyy"); Now you can call the creation functions for the XDB, and for the on the new Data object itself. See below for the functions, and in each data module for those functions. For more information about the array format being passed to the CallBack please read the Net::Jabber::Client documentation. =head1 METHODS =head2 Retrieval functions GetTo() - returns either a string with the Jabber Identifier, GetTo("jid") or a Net::Jabber::JID object for the person who is going to receive the . To get the JID object set the string to "jid", otherwise leave blank for the text string. $to = $XDB->GetTo(); $toJID = $XDB->GetTo("jid"); GetFrom() - returns either a string with the Jabber Identifier, GetFrom("jid") or a Net::Jabber::JID object for the person who sent the . To get the JID object set the string to "jid", otherwise leave blank for the text string. $from = $XDB->GetFrom(); $fromJID = $XDB->GetFrom("jid"); GetType() - returns a string with the type this is. $type = $XDB->GetType(); GetID() - returns an integer with the id of the . $id = $XDB->GetID(); GetAction() - returns a string with the action this is. $action = $XDB->GetAction(); GetMatch() - returns a string with the match this is. $match = $XDB->GetMatch(); GetError() - returns a string with the text description of the error. $error = $XDB->GetError(); GetErrorCode() - returns a string with the code of error. $errorCode = $XDB->GetErrorCode(); GetData() - returns a Net::Jabber::Data object that contains the data in the of the . $dataTag = $XDB->GetData(); GetDataXMLNS() - returns a string with the namespace of the data for this , if one exists. $xmlns = $XDB->GetDataXMLNS(); =head2 Creation functions SetXDB(to=>string|JID, - set multiple fields in the at one from=>string|JID, time. This is a cumulative and over id=>string, writing action. If you set the "to" type=>string, attribute twice, the second setting is action=>string, what is used. If you set the status, and match=>string) then set the priority then both will be in errorcode=>string, the tag. For valid settings read the error=>string) specific Set functions below. $XDB->SetXDB(type=>"get", to=>"bob\@jabber.org", data=>"info"); $XDB->SetXDB(to=>"bob\@jabber.org", errorcode=>403, error=>"Permission Denied"); SetTo(string) - sets the to attribute. You can either pass a string SetTo(JID) or a JID object. They must be a valid Jabber Identifiers or the server will return an error message. (ie. jabber:bob@jabber.org, etc...) $XDB->SetTo("bob\@jabber.org"); SetFrom(string) - sets the from attribute. You can either pass a string SetFrom(JID) or a JID object. They must be a valid Jabber Identifiers or the server will return an error message. (ie. jabber:bob@jabber.org, etc...) $XDB->SetFrom("me\@jabber.org"); SetType(string) - sets the type attribute. Valid settings are: get request information set set information result results of a get error there was an error $XDB->SetType("set"); SetAction(string) - sets the error code of the . $XDB->SetAction("foo"); SetMatch(string) - sets the error code of the . $XDB->SetMatch("foo"); SetErrorCode(string) - sets the error code of the . $XDB->SetErrorCode(403); SetError(string) - sets the error string of the . $XDB->SetError("Permission Denied"); NewData(string) - creates a new Net::Jabber::Data object with the namespace in the string. In order for this function to work with a custom namespace, you must define and register that namespace with the XDB module. For more information please read the documentation for Net::Jabber::Data. $dataObj = $XDB->NewData("jabber:xdb:auth"); $dataObj = $XDB->NewData("jabber:xdb:roster"); Reply(hash) - creates a new XDB object and populates the to/from fields. If you specify a hash the same as with SetXDB then those values will override the Reply values. $xdbReply = $XDB->Reply(); $xdbReply = $XDB->Reply(type=>"result"); =head2 Test functions DefinedTo() - returns 1 if the to attribute is defined in the , 0 otherwise. $test = $XDB->DefinedTo(); DefinedFrom() - returns 1 if the from attribute is defined in the , 0 otherwise. $test = $XDB->DefinedFrom(); DefinedID() - returns 1 if the id attribute is defined in the , 0 otherwise. $test = $XDB->DefinedID(); DefinedType() - returns 1 if the type attribute is defined in the , 0 otherwise. $test = $XDB->DefinedType(); DefinedAction() - returns 1 if the action attribute is defined in the , 0 otherwise. $test = $XDB->DefinedAction(); DefinedMatch() - returns 1 if the match attribute is defined in the , 0 otherwise. $test = $XDB->DefinedMatch(); DefinedError() - returns 1 if is defined in the , 0 otherwise. $test = $XDB->DefinedError(); DefinedErrorCode() - returns 1 if the code attribute is defined in , 0 otherwise. $test = $XDB->DefinedErrorCode(); =head1 AUTHOR By Ryan Eatmon in May of 2001 for http://jabber.org.. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use vars qw($VERSION $AUTOLOAD %FUNCTIONS); $VERSION = "2.0"; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; $self->{VERSION} = $VERSION; bless($self, $proto); $self->{DEBUGHEADER} = "XDB"; $self->{DATA} = {}; $self->{CHILDREN} = {}; $self->{TAG} = "xdb"; if ("@_" ne ("")) { if (ref($_[0]) eq "Net::Jabber::XDB") { return $_[0]; } else { $self->{TREE} = shift; $self->ParseTree(); } } else { $self->{TREE} = new XML::Stream::Node($self->{TAG}); } return $self; } ############################################################################## # # AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm # ############################################################################## sub AUTOLOAD { my $self = shift; &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_); } $FUNCTIONS{Action}->{Get} = "action"; $FUNCTIONS{Action}->{Set} = ["scalar","action"]; $FUNCTIONS{Action}->{Defined} = "action"; $FUNCTIONS{Action}->{Hash} = "att"; $FUNCTIONS{Action}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{Action}->{XPath}->{Path} = '@action'; $FUNCTIONS{Error}->{Get} = "error"; $FUNCTIONS{Error}->{Set} = ["scalar","error"]; $FUNCTIONS{Error}->{Defined} = "error"; $FUNCTIONS{Error}->{Hash} = "child-data"; $FUNCTIONS{Error}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{Error}->{XPath}->{Path} = 'error/text()'; $FUNCTIONS{ErrorCode}->{Get} = "errorcode"; $FUNCTIONS{ErrorCode}->{Set} = ["scalar","errorcode"]; $FUNCTIONS{ErrorCode}->{Defined} = "errorcode"; $FUNCTIONS{ErrorCode}->{Hash} = "att-error-code"; $FUNCTIONS{ErrorCode}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{ErrorCode}->{XPath}->{Path} = 'error/@code'; $FUNCTIONS{From}->{Get} = "from"; $FUNCTIONS{From}->{Set} = ["jid","from"]; $FUNCTIONS{From}->{Defined} = "from"; $FUNCTIONS{From}->{Hash} = "att"; $FUNCTIONS{From}->{XPath}->{Type} = 'jid'; $FUNCTIONS{From}->{XPath}->{Path} = '@from'; $FUNCTIONS{Match}->{Get} = "match"; $FUNCTIONS{Match}->{Set} = ["scalar","match"]; $FUNCTIONS{Match}->{Defined} = "match"; $FUNCTIONS{Match}->{Hash} = "att"; $FUNCTIONS{Match}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{Match}->{XPath}->{Path} = '@match'; $FUNCTIONS{NS}->{Get} = "ns"; $FUNCTIONS{NS}->{Set} = ["scalar","ns"]; $FUNCTIONS{NS}->{Defined} = "ns"; $FUNCTIONS{NS}->{Hash} = "att"; $FUNCTIONS{NS}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{NS}->{XPath}->{Path} = '@ns'; $FUNCTIONS{ID}->{Get} = "id"; $FUNCTIONS{ID}->{Set} = ["scalar","id"]; $FUNCTIONS{ID}->{Defined} = "id"; $FUNCTIONS{ID}->{Hash} = "att"; $FUNCTIONS{ID}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{ID}->{XPath}->{Path} = '@id'; $FUNCTIONS{To}->{Get} = "to"; $FUNCTIONS{To}->{Set} = ["jid","to"]; $FUNCTIONS{To}->{Defined} = "to"; $FUNCTIONS{To}->{Hash} = "att"; $FUNCTIONS{To}->{XPath}->{Type} = 'jid'; $FUNCTIONS{To}->{XPath}->{Path} = '@to'; $FUNCTIONS{Type}->{Get} = "type"; $FUNCTIONS{Type}->{Set} = ["scalar","type"]; $FUNCTIONS{Type}->{Defined} = "type"; $FUNCTIONS{Type}->{Hash} = "att"; $FUNCTIONS{Type}->{XPath}->{Type} = 'scalar'; $FUNCTIONS{Type}->{XPath}->{Path} = '@type'; $FUNCTIONS{Data}->{Get} = "__netjabber__:children:data"; $FUNCTIONS{Data}->{Defined} = "__netjabber__:children:data"; $FUNCTIONS{Data}->{XPath}->{Type} = 'node'; $FUNCTIONS{Data}->{XPath}->{Path} = '*[@xmlns]'; $FUNCTIONS{X}->{Get} = "__netjabber__:children:x"; $FUNCTIONS{X}->{Defined} = "__netjabber__:children:x"; $FUNCTIONS{X}->{XPath}->{Type} = 'node'; $FUNCTIONS{X}->{XPath}->{Path} = '*[@xmlns]'; $FUNCTIONS{XDB}->{Get} = "__netjabber__:master"; $FUNCTIONS{XDB}->{Set} = ["master"]; ############################################################################## # # GetDataXMLNS - returns the xmlns of the tag # ############################################################################## sub GetDataXMLNS { my $self = shift; #XXX fix this return $self->{CHILDREN}->{data}->[0]->GetXMLNS() if exists($self->{CHILDREN}->{data}); } ############################################################################## # # Reply - returns a Net::Jabber::XDB object with the proper fields # already populated for you. # ############################################################################## sub Reply { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } my $reply = new Net::Jabber::XDB(); $reply->SetID($self->GetID()) if ($self->GetID() ne ""); $reply->SetType("result"); if ($self->DefinedData()) { my $selfData = $self->GetData(); $reply->NewData($selfData->GetXMLNS()); } $reply->SetXDB(to=>$self->GetFrom(), from=>$self->GetTo() ); $reply->SetXDB(%args); return $reply; } 1; Net-Jabber-2.0/lib/Net/Jabber/Server.pm0000644000175000017500000003015310110275744020710 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Server; =head1 NAME Net::Jabber::Server - Jabber Server Library =head1 SYNOPSIS Net::Jabber::Server is a module that provides a developer easy access to developing applications that need an embedded Jabber server. =head1 DESCRIPTION Server.pm seeks to provide enough high level APIs and automation of the low level APIs that writing and spawning a Jabber Server in Perl is trivial. For those that wish to work with the low level you can do that too, but those functions are covered in the documentation for each module. Net::Jabber::Server provides functions to run a full Jabber server that accepts incoming connections and delivers packets to external Jabber servers. You can use all or none of the functions, there is no requirement. For more information on how the details for how Net::Jabber is written please see the help for Net::Jabber itself. For a full list of high level functions available please see Net::Jabber::Protocol. =head2 Basic Functions use Net::Jabber qw(Server); $Server = new Net::Jabber::Server(); $Server->Start(); $Server->Start(jabberxml=>"custom_jabber.xml", hostname=>"foobar.net"); %status = $Server->Process(); %status = $Server->Process(5); $Server->Stop(); =head1 METHODS =head2 Basic Functions new(debuglevel=>0|1|2, - creates the Server object. debugfile debugfile=>string, should be set to the path for the debug debugtime=>0|1) log to be written. If set to "stdout" then the debug will go there. debuglevel controls the amount of debug. For more information about the valid setting for debuglevel, debugfile, and debugtime see Net::Jabber::Debug. Start(hostname=>string, - starts the server listening on the proper jaberxml=>string) ports. hostname is a quick way of telling the server the hostname to listen on. jabberxml defines the path to a different jabberd configuration file (default is "./jabber.xml"). Process(integer) - takes the timeout period as an argument. If no timeout is listed then the function blocks until a packet is received. Otherwise it waits that number of seconds and then exits so your program can continue doing useful things. NOTE: This is important for GUIs. You need to leave time to process GUI commands even if you are waiting for packets. The following are the possible return values for each hash entry, and what they mean: 1 - Status ok, data received. 0 - Status ok, no data received. undef - Status not ok, stop processing. IMPORTANT: You need to check the output of every Process. If you get an undef then the connection died and you should behave accordingly. Stop() - stops the server from running and shuts down all sub programs. =head1 AUTHOR By Ryan Eatmon in January of 2001 for http://jabber.org. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use strict; use Carp; use base qw( Net::Jabber::Protocol ); use vars qw( $VERSION ); $VERSION = "2.0"; use Net::Jabber::Data; ($Net::Jabber::Data::VERSION < $VERSION) && die("Net::Jabber::Data $VERSION required--this is only version $Net::Jabber::Data::VERSION"); use Net::Jabber::XDB; ($Net::Jabber::XDB::VERSION < $VERSION) && die("Net::Jabber::XDB $VERSION required--this is only version $Net::Jabber::XDB::VERSION"); #use Net::Jabber::Log; #($Net::Jabber::Log::VERSION < $VERSION) && # die("Net::Jabber::Log $VERSION required--this is only version $Net::Jabber::Log::VERSION"); use Net::Jabber::Dialback; ($Net::Jabber::Dialback::VERSION < $VERSION) && die("Net::Jabber::Dialback $VERSION required--this is only version $Net::Jabber::Dialback::VERSION"); use Net::Jabber::Key; ($Net::Jabber::Key::VERSION < $VERSION) && die("Net::Jabber::Key $VERSION required--this is only version $Net::Jabber::Key::VERSION"); sub new { srand( time() ^ ($$ + ($$ << 15))); my $proto = shift; my $self = { }; my %args; while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); } bless($self, $proto); $self->{KEY} = new Net::Jabber::Key(); $self->{DEBUG} = new Net::Jabber::Debug(level=>exists($args{debuglevel}) ? $args{debuglevel} : -1, file=>exists($args{debugfile}) ? $args{debugfile} : "stdout", time=>exists($args{debugtime}) ? $args{debugtime} : 0, setdefault=>1, header=>"NJ::Server" ); $self->{SERVER} = { hostname => "localhost", port => 5269, servername => ""}; $self->{STREAM} = new XML::Stream(style=>"node", debugfh=>$self->{DEBUG}->GetHandle(), debuglevel=>$self->{DEBUG}->GetLevel(), debugtime=>$self->{DEBUG}->GetTime()); $self->{STREAM}->SetCallBacks(node=>sub{ $self->CallBack(@_) }, sid=>sub{ return $self->{KEY}->Generate()}); $self->{VERSION} = $VERSION; return $self; } ############################################################################## # # Start - starts the server running # ############################################################################## sub Start { my $self = shift; my %args; while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); } $self->{STOP} = 0; $self->SetCallBacks('message'=>sub{ $self->messageHandler(@_); }, 'presence'=>sub{ $self->presenceHandler(@_); }, 'iq'=>sub{ $self->iqHandler(@_); }, 'db:result'=>sub{ $self->dbresultHandler(@_); }, 'db:verify'=>sub{ $self->dbverifyHandler(@_); }, ); my $hostname = $self->{SERVER}->{hostname}; $hostname = $args{hostname} if exists($args{hostname}); my $status = $self->{STREAM}->Listen(hostname=>$hostname, port=>$self->{SERVER}->{port}, namespace=>"jabber:server"); while($self->{STOP} == 0) { while(($self->{STOP} == 0) && defined($self->{STREAM}->Process())) { } } } ############################################################################### # # Process - If a timeout value is specified then the function will wait # that long before returning. This is useful for apps that # need to handle other processing while still waiting for # packets. If no timeout is listed then the function waits # until a packet is returned. Either way the function exits # as soon as a packet is returned. # ############################################################################### sub Process { my $self = shift; my ($timeout) = @_; my %status; if (exists($self->{PROCESSERROR}) && ($self->{PROCESSERROR} == 1)) { croak("You should always check the output of the Process call. If it was undef\nthen there was a fatal error that you need to check. There is an error in your\nprogram."); } $self->{DEBUG}->Log1("Process: timeout($timeout)") if defined($timeout); if (!defined($timeout) || ($timeout eq "")) { while(1) { %status = $self->{STREAM}->Process(); $self->{DEBUG}->Log1("Process: status($status{$self->{SESSION}->{id}})"); last if ($status{$self->{SESSION}->{id}} != 0); select(undef,undef,undef,.25); } $self->{DEBUG}->Log1("Process: return($status{$self->{SESSION}->{id}})"); if ($status{$self->{SESSION}->{id}} == -1) { $self->{PROCESSERROR} = 1; return; } else { return $status{$self->{SESSION}->{id}}; } } else { %status = $self->{STREAM}->Process($timeout); if ($status{$self->{SESSION}->{id}} == -1) { $self->{PROCESSERROR} = 1; return; } else { return $status{$self->{SESSION}->{id}}; } } } ############################################################################## # # Stop - shuts down the server # ############################################################################## sub Stop { my $self = shift; $self->{STOP} = 1; } sub messageHandler { my $self = shift; my $sid = shift; my ($message) = @_; $self->{DEBUG}->Log2("messageHandler: message(",$message->GetXML(),")"); my $reply = $message->Reply(); $self->Send($reply); } sub presenceHandler { my $self = shift; my $sid = shift; my ($presence) = @_; $self->{DEBUG}->Log2("presenceHandler: presence(",$presence->GetXML(),")"); } sub iqHandler { my $self = shift; my $sid = shift; my ($iq) = @_; $self->{DEBUG}->Log2("iqHandler: iq(",$iq->GetXML(),")"); } sub dbresultHandler { my $self = shift; my $sid = shift; my ($dbresult) = @_; $self->{DEBUG}->Log2("dbresultHandler: dbresult(",$dbresult->GetXML(),")"); my $dbverify = new Net::Jabber::Dialback::Verify(); $dbverify->SetVerify(to=>$dbresult->GetFrom(), from=>$dbresult->GetTo(), id=>$self->{STREAM}->GetRoot($sid)->{id}, data=>$dbresult->GetData()); $self->Send($dbverify); } sub dbverifyHandler { my $self = shift; my $sid = shift; my ($dbverify) = @_; $self->{DEBUG}->Log2("dbverifyHandler: dbverify(",$dbverify->GetXML(),")"); } sub Send { my $self = shift; my $object = shift; if (ref($object) eq "") { my ($server) = ($object =~ /to=[\"\']([^\"\']+)[\"\']/); $server =~ s/^\S*\@?(\S+)\/?.*$/$1/; $self->SendXML($server,$object); } else { $self->SendXML($object->GetTo("jid")->GetServer(),$object->GetXML()); } } sub SendXML { my $self = shift; my $server = shift; my $xml = shift; $self->{DEBUG}->Log1("SendXML: server($server) sent($xml)"); my $sid = $self->{STREAM}->Host2SID($server); if (!defined($sid)) { $self->{STREAM}->Connect(hostname=>$server, port=>5269, connectiontype=>"tcpip", namespace=>"jabber:server"); $sid = $self->{STREAM}->Host2SID($server); } $self->{DEBUG}->Log1("SendXML: sid($sid)"); &{$self->{CB}->{send}}($sid,$xml) if exists($self->{CB}->{send}); $self->{STREAM}->Send($sid,$xml); } # # by not send xmlns:db='jabber:server:dialback' to a server, we operate in # legacy mode, and do not have to do dialback. # 1; Net-Jabber-2.0/lib/Net/Jabber/Message.pm0000644000175000017500000000371610110275744021033 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Message; =head1 NAME Net::Jabber::Message - Jabber Message Module =head1 DESCRIPTION Net::Jabber::Message inherits all of its methods from Net::XMPP::Message. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use Net::XMPP::Message; use base qw( Net::XMPP::Message ); use vars qw( $VERSION ); $VERSION = "2.0"; sub GetX { my $self = shift; $self->GetChild(@_); } sub DefinedX { my $self = shift; $self->DefinedChild(@_); } sub NewX { my $self = shift; $self->NewChild(@_); } sub AddX { my $self = shift; $self->AddChild(@_); } sub RemoveX { my $self = shift; $self->RemoveChild(@_); } sub _new_jid { my $self = shift; return new Net::Jabber::JID(@_); } sub _new_packet { my $self = shift; return new Net::Jabber::Stanza(@_); } sub _message { my $self = shift; return new Net::Jabber::Message(@_); } 1; Net-Jabber-2.0/lib/Net/Jabber/Namespaces.pm0000644000175000017500000026420410110275744021527 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Namespaces; =head1 NAME Net::Jabber::Namespaces =head1 SYNOPSIS Net::Jabber::Namespaces is a pure documentation module. It provides no code for execution, just documentation on how the Net::Jabber modules handle namespaces. =head1 DESCRIPTION Net::Jabber::Namespaces is fully documented by Net::XMPP::Namesapces. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use Net::XMPP::Namespaces; $Net::XMPP::Namespaces::SKIPNS{'__netjabber__'} = 1; #----------------------------------------------------------------------------- # jabber:iq:agent #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:agent', tag => 'query', xpath => { Agents => { type => 'flag', path => 'agents', }, Description => { path => 'description/text()' }, JID => { type => 'jid', path => '@jid', }, Name => { path => 'name/text()' }, GroupChat => { type => 'flag', path => 'groupchat', }, Register => { type => 'flag', path => 'register', }, Search => { type => 'flag', path => 'search', }, Service => { path => 'service/text()' }, Transport => { path => 'transport/text()' }, URL => { path => 'url/text()' }, Agent => { type => 'master' }, }, docs => { module => 'Net::Jabber', deprecated => 1, }, ); } #----------------------------------------------------------------------------- # jabber:iq:agents #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:agents', tag => 'query', xpath => { Agent => { type => 'child', path => 'agent', child => { ns => 'jabber:iq:agent', skip_xmlns => 1, }, calls => [ 'Add' ], }, Agents => { type => 'child', path => 'agent', child => { ns => 'jabber:iq:agent' }, }, }, docs => { module => 'Net::Jabber', deprecated => 1, }, ); } #----------------------------------------------------------------------------- # jabber:iq:autoupdate #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:autoupdate', tag => 'query', xpath => { Beta => { type => 'child', path => 'beta', child => { ns => '__netjabber__:iq:autoupdate:release' }, calls => [ 'Add' ], }, Dev => { type => 'child', path => 'dev', child => { ns => '__netjabber__:iq:autoupdate:release' }, calls => [ 'Add' ], }, Release => { type => 'child', path => 'release', child => { ns => '__netjabber__:iq:autoupdate:release' }, calls => [ 'Add' ], }, Releases => { type => 'child', path => '*', child => { ns => '__netjabber__:iq:autoupdate:release' }, }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:autoupdate:release #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:autoupdate:release', xpath => { Desc => { path => 'desc/text()' }, Priority => { path => '@priority' }, URL => { path => 'url/text()' }, Version => { path => 'version/text()' }, Release => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:autoupdate - release objects', }, ); } #----------------------------------------------------------------------------- # jabber:iq:browse #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:browse', tag => 'item', xpath => { Category => { path => '@category' }, Item => { type => 'child', path => '*[name() != "ns"]', child => { ns => '__netjabber__:iq:browse:item', specify_name => 1, tag => 'item', }, calls => [ 'Add' ], }, Items => { type => 'child', path => '*[name() != "ns"]', child => { ns => '__netjabber__:iq:browse:item' }, }, JID => { type => 'jid', path => '@jid', }, Name => { path => '@name' }, NS => { type => 'array', path => 'ns/text()', }, Type => { path => '@type' }, Browse => { type => 'master' } }, docs => { module => 'Net::Jabber', deprecated => 1, }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:browse:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:browse:item', tag => 'item', xpath => { Category => { path => '@category' }, Item => { type => 'child', path => '*[name() != "ns"]', child => { ns => '__netjabber__:iq:browse:item', specify_name => 1, tag => 'item', }, calls => [ 'Add' ], }, Items => { type => 'child', path => '*[name() != "ns"]', child => { ns => '__netjabber__:iq:browse:item' }, }, JID => { type => 'jid', path => '@jid', }, Name => { path => '@name' }, NS => { type => 'array', path => 'ns/text()', }, Type => { path => '@type' }, Browse => { type => 'master' } }, docs => { module => 'Net::Jabber', name => 'jabber:iq:browse - item objects', deprecated => 1, }, ); } #----------------------------------------------------------------------------- # jabber:iq:conference #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:conference', tag => 'query', xpath => { ID => { path => 'id/text()' }, Name => { path => 'name/text()' }, Nick => { path => 'nick/text()' }, Privacy => { type => 'flag', path => 'privacy', }, Secret => { path => 'secret/text()' }, Conference => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:iq:filter #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:filter', tag => 'query', xpath => { Rule => { type => 'child', path => 'rule', child => { ns => '__netjabber__:iq:filter:rule' }, calls => [ 'Add' ], }, Rules => { type => 'child', path => 'rule', child => { ns => '__netjabber__:iq:filter:rule' }, }, }, docs => { module => 'Net::Jabber', deprecated => 1, }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:filter:rule #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:filter:rule', xpath => { Body => { path => 'body/text()' }, Continued => { path => 'continued/text()' }, Drop => { path => 'drop/text()' }, Edit => { path => 'edit/text()' }, Error => { path => 'error/text()' }, From => { path => 'from/text()' }, Offline => { path => 'offline/text()' }, Reply => { path => 'reply/text()' }, Resource => { path => 'resource/text()' }, Show => { path => 'show/text()' }, Size => { path => 'size/text()' }, Subject => { path => 'subject/text()' }, Time => { path => 'time/text()' }, Type => { path => 'type/text()' }, Unavailable => { path => 'unavailable/text()' }, Rule => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:filter - rule objects', deprecated => 1, }, ); } #----------------------------------------------------------------------------- # jabber:iq:gateway #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:gateway', tag => 'query', xpath => { Desc => { path => 'desc/text()' }, JID => { type => 'jid', path => 'jid/text()', }, Prompt => { path => 'prompt/text()' }, Gateway => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:iq:last #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:last', tag => 'query', xpath => { Message => { path => 'text()' }, Seconds => { path => '@seconds' }, Last => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:iq:oob #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:oob', tag => 'query', xpath => { Desc => { path => 'desc/text()' }, URL => { path => 'url/text()' }, Oob => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:iq:pass #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:pass', tag => 'query', xpath => { Client => { path => 'client/text()' }, ClientPort => { path => 'client/@port' }, Close => { type => 'flag', path => 'close', }, Expire => { path => 'expire/text()' }, OneShot => { type => 'flag', path => 'oneshot', }, Proxy => { path => 'proxy/text()' }, ProxyPort => { path => 'proxy/@port' }, Server => { path => 'server/text()' }, ServerPort => { path => 'server/@port' }, Pass => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:iq:rpc #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:rpc', tag => 'query', xpath => { MethodCall => { type => 'child', path => 'methodCall', child => { ns => '__netjabber__:iq:rpc:methodCall' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, MethodResponse => { type => 'child', path => 'methodResponse', child => { ns => '__netjabber__:iq:rpc:methodResponse' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:methodCall #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:rpc:methodCall', xpath => { MethodName => { path => 'methodName/text()' }, Params => { type => 'child', path => 'params', child => { ns => '__netjabber__:iq:rpc:params' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, MethodCall => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - methodCall objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:methodResponse #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:rpc:methodResponse', xpath => { Fault => { type => 'child', path => 'fault', child => { ns => '__netjabber__:iq:rpc:fault' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Params => { type => 'child', path => 'params', child => { ns => '__netjabber__:iq:rpc:params' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - methodResponse objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:fault #----------------------------------------------------------------------------- { &add_ns(ns =>'__netjabber__:iq:rpc:fault', xpath => { Value => { type => 'child', path => 'value', child => { ns => '__netjabber__:iq:rpc:value' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - fault objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:params #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:rpc:params', xpath => { Param => { type => 'child', path => 'param', child => { ns => '__netjabber__:iq:rpc:param' }, calls => [ 'Add' ], }, Params => { type => 'child', path => 'param', child => { ns => '__netjabber__:iq:rpc:param' }, }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - params objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:param #----------------------------------------------------------------------------- { &add_ns(ns =>'__netjabber__:iq:rpc:param', xpath => { Value => { type => 'child', path => 'value', child => { ns => '__netjabber__:iq:rpc:value' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - param objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:value #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:rpc:value', xpath => { Array => { type => 'child', path => 'array', child => { ns => '__netjabber__:iq:rpc:array' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Base64 => { path => 'base64/text()' }, Boolean => { path => 'boolean/text()' }, DateTime => { path => 'dateTime.iso8601/text()' }, Double => { path => 'double/text()' }, I4 => { path => 'i4/text()' }, Int => { path => 'int/text()' }, String => { path => 'string/text()' }, Struct => { type => 'child', path => 'struct', child => { ns => '__netjabber__:iq:rpc:struct' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Value => { path => 'value/text()' }, RPCValue => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - value objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:struct #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:rpc:struct', xpath => { Member => { type => 'child', path => 'member', child => { ns => '__netjabber__:iq:rpc:struct:member' }, calls => [ 'Add' ], }, Members => { type => 'child', path => 'member', child => { ns => '__netjabber__:iq:rpc:struct:member' }, }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - struct objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:struct:member #----------------------------------------------------------------------------- { &add_ns(ns =>'__netjabber__:iq:rpc:struct:member', xpath => { Name => { path => 'name/text()' }, Value => { type => 'child', path => 'value', child => { ns => '__netjabber__:iq:rpc:value' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Member => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - member objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:array #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:rpc:array', xpath => { Data => { type => 'child', path => 'data', child => { ns => '__netjabber__:iq:rpc:array:data' }, calls => [ 'Add' ], }, Datas => { type => 'child', path => 'data', child => { ns => '__netjabber__:iq:rpc:array:data' }, }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - array objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:rpc:array:data #----------------------------------------------------------------------------- { &add_ns(ns =>'__netjabber__:iq:rpc:array:data', xpath => { Value => { type => 'child', path => 'value', child => { ns => '__netjabber__:iq:rpc:value' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:rpc - data objects', }, ); } #----------------------------------------------------------------------------- # jabber:iq:search #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:search', tag => 'query', xpath => { Email => { path => 'email/text()' }, Family => { path => 'family/text()' }, First => { path => 'first/text()' }, Given => { path => 'given/text()' }, Instructions => { path => 'instructions/text()' }, Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:search:item' }, calls => [ 'Add' ], }, Items => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:search:item', }, }, Key => { path => 'key/text()' }, Last => { path => 'last/text()' }, Name => { path => 'name/text()' }, Nick => { path => 'nick/text()' }, Truncated => { type => 'flag', path => 'truncated', }, Search => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:search:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:search:item', xpath => { Email => { path => 'email/text()' }, Family => { path => 'family/text()' }, First => { path => 'first/text()' }, Given => { path => 'given/text()' }, JID => { type => 'jid', path => '@jid', }, Key => { path => 'key/text()' }, Last => { path => 'last/text()' }, Name => { path => 'name/text()' }, Nick => { path => 'nick/text()' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:iq:search - item objects', }, ); } #----------------------------------------------------------------------------- # jabber:iq:time #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:time', tag => 'query', xpath => { Display => { type => ['special','time-display'], path => 'display/text()', }, TZ => { type => ['special','time-tz'], path => 'tz/text()', }, UTC => { type => ['special','time-utc'], path => 'utc/text()', }, Time => { type => [ 'master', 'all' ] } }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:iq:version #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:iq:version', tag => 'query', xpath => { Name => { path => 'name/text()' }, OS => { type => [ 'special', 'version-os' ], path => 'os/text()', }, Ver => { type => [ 'special' ,'version-version' ], path => 'version/text()', }, Version => { type => [ 'master', 'all' ] } }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:autoupdate #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:autoupdate', tag => 'x', xpath => { JID => { type => 'jid', path => '@jid', }, Autoupdate => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:conference #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:conference', tag => 'x', xpath => { JID => { type => 'jid', path => '@jid', }, Conference => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:data #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:data', tag => 'x', xpath => { Field => { type => 'child', path => 'field', child => { ns => '__netjabber__:x:data:field' }, calls => [ 'Add' ], }, Fields => { type => 'child', path => 'field', child => { ns => '__netjabber__:x:data:field', }, }, Form => { path => '@form' }, Instructions => { path => 'instructions/text()' }, Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:x:data:item' }, calls => [ 'Add' ], }, Items => { type => 'child', path => 'item', child => { ns => '__netjabber__:x:data:item', }, }, Reported => { type => 'child', path => 'reported', child => { ns => '__netjabber__:x:data:reported' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Title => { path => 'title/text()' }, Type => { path => '@type' }, Data => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:data:field #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:data:field', xpath => { Desc => { path => 'desc/text()' }, Label => { path => '@label' }, Option => { type => 'child', path => 'option', child => { ns => '__netjabber__:x:data:field:option' }, calls => [ 'Add' ], }, Options => { type => 'child', path => 'option', child => { ns => '__netjabber__:x:data:field:option', }, }, Required => { type => 'flag', path => 'required', }, Type => { path => '@type' }, Value => { type => 'array', path => 'value/text()', }, Var => { path => '@var' }, Field => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:x:data - field objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:data:field:option #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:data:field:option', xpath => { Label => { path => '@label' }, Value => { path => 'value/text()' }, Option => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:x:data - option objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:data:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:data:item', xpath => { Field => { type => 'child', path => 'field', child => { ns => '__netjabber__:x:data:field' }, calls => [ 'Add' ], }, Fields => { type => 'child', path => 'field', child => { ns => '__netjabber__:x:data:field', }, }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:x:data - item objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:data:reported #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:data:reported', xpath => { Field => { type => 'child', path => 'field', child => { ns => '__netjabber__:x:data:field' }, calls => [ 'Add' ], }, Fields => { type => 'child', path => 'field', child => { ns => '__netjabber__:x:data:field', }, }, Reported => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:x:data - reported objects', }, ); } #----------------------------------------------------------------------------- # jabber:x:delay #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:delay', tag => 'x', xpath => { From => { type => 'jid', path => '@from', }, Message => { path => 'text()' }, Stamp => { type => 'timestamp', path => '@stamp', }, Delay => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:encrypted #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:encrypted', tag => 'x', xpath => { Message => { path => 'text()' }, Encrypted => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:event #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:event', tag => 'x', xpath => { Composing => { type => 'flag', path => 'composing', }, Delivered => { type => 'flag', path => 'delivered', }, Displayed => { type => 'flag', path => 'displayed', }, ID => { path => 'id/text()' }, Offline => { type => 'flag', path => 'offline', }, Event => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:expire #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:expire', tag => 'x', xpath => { Seconds => { path => '@seconds' }, Expire => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:oob #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:oob', tag => 'x', xpath => { Desc => { path => 'desc/text()' }, URL => { path => 'url/text()' }, Oob => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # jabber:x:roster #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:roster', tag => 'x', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:x:roster:item' }, calls => [ 'Add' ], }, Items => { type => 'child', path => 'item', child => { ns => '__netjabber__:x:roster:item', }, }, Roster => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:roster:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:roster:item', xpath => { Ask => { path => '@ask' }, Group => { type => 'array', path => 'group/text()', }, JID => { type => 'jid', path => '@jid', }, Name => { path => '@name' }, Subscription => { path => '@subscription' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'jabber:x:roster - item objects', }, ); } #----------------------------------------------------------------------------- # jabber:x:signed #----------------------------------------------------------------------------- { &add_ns(ns => 'jabber:x:signed', tag => 'x', xpath => { Signature => { path => 'text()' }, Signed => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/bytestreams #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/bytestreams', tag => 'query', xpath => { Activate => { path => 'activate/text()' }, SID => { path => '@sid' }, StreamHost => { type => 'child', path => 'streamhost', child => { ns => '__netjabber__:iq:bytestreams:streamhost' }, calls => [ 'Add' ], }, StreamHosts => { type => 'child', path => 'streamhost', child => { ns => '__netjabber__:iq:bytestreams:streamhost', }, }, StreamHostUsedJID => { type => 'jid', path => 'streamhost-used/@jid', }, ByteStreams => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:bytestreams:streamhost #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:bytestreams:streamhost', xpath => { Host => { path => '@host' }, JID => { type => 'jid', path => '@jid', }, Port => { path => '@port' }, ZeroConf => { path => '@zeroconf' }, StreamHost => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/bytestreams - streamhost objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/commands #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/commands', tag => 'command', xpath => { Action => { path => '@action' }, Node => { path => '@node' }, Note => { type => 'child', path => 'note', child => { ns => '__netjabber__:iq:commands:note' }, calls => [ 'Add' ], }, Notes => { type => 'child', path => 'note', child => { ns => '__netjabber__:iq:commands:note', }, }, SessionID => { path => '@sessionid' }, Status => { path => '@status' }, Command => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } # xxx xml:lang #----------------------------------------------------------------------------- # __netjabber__:iq:commands:note #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:commands:note', xpath => { Type => { path => '@type' }, Message => { path => 'text()' }, Note => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/commands - note objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/disco#info #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/disco#info', tag => 'query', xpath => { Feature => { type => 'child', path => 'feature', child => { ns => '__netjabber__:iq:disco:info:feature' }, calls => [ 'Add' ], }, Features => { type => 'child', path => 'feature', child => { ns => '__netjabber__:iq:disco:info:feature' }, }, Identity => { type => 'child', path => 'identity', child => { ns => '__netjabber__:iq:disco:info:identity' }, calls => [ 'Add' ], }, Identities => { type => 'child', path => 'identity', child => { ns => '__netjabber__:iq:disco:info:identity' }, }, Node => { path => '@node' }, DiscoInfo => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:disco:info:feature #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:disco:info:feature', xpath => { Var => { path => '@var' }, Feature => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/disco#info - feature objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:disco:info:identity #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:disco:info:identity', xpath => { Category => { path => '@category' }, Name => { path => '@name' }, Type => { path => '@type' }, Identity => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/disco#info - identity objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/disco#items #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/disco#items', tag => 'query', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:disco:items:item' }, calls => [ 'Add' ], }, Items => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:disco:items:item' }, }, Node => { path => '@node' }, DiscoItems => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:disco:items:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:disco:items:item', xpath => { Action => { path => '@action' }, JID => { type => 'jid', path => '@jid', }, Name => { path => '@name' }, Node => { path => '@node' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/disco#items - item objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/feature-neg #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/feature-neg', tag => 'feature', xpath => { FeatureNeg => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/muc #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/muc', tag => 'x', xpath => { Password => { path => 'password/text()' }, MUC => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/muc#admin #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/muc#admin', tag => 'query', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:muc:admin:item' }, calls => [ 'Add' ], }, Items => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:muc:admin:item' }, }, Admin => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:muc:admin:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:muc:admin:item', xpath => { ActorJID => { type => 'jid', path => 'actor/@jid', }, Affiliation => { path => '@affiliation' }, JID => { type => 'jid', path => '@jid', }, Nick => { path => '@nick' }, Reason => { path => 'reason/text()' }, Role => { path => '@role' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/muc#admin - item objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/muc#user #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/muc#user', tag => 'x', xpath => { Alt => { path => 'alt/text()' }, Invite => { type => 'child', path => 'invite', child => { ns => '__netjabber__:x:muc:invite' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:x:muc:item' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Password => { path => 'password/text()' }, StatusCode => { path => 'status/@code' }, User => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:muc:invite #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:muc:invite', xpath => { From => { type => 'jid', path => '@from', }, Reason => { path => 'reason/text()' }, To => { type => 'jid', path => '@to', }, Invite => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/muc#user - invite objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:x:muc:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:x:muc:item', xpath => { ActorJID => { type => 'jid', path => 'actor/@jid', }, Affiliation => { path => '@affiliation' }, JID => { type => 'jid', path => '@jid', }, Nick => { path => '@nick' }, Reason => { path => 'reason/text()' }, Role => { path => '@role' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/muc#user - item objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/pubsub #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/pubsub', tag => 'pubsub', xpath => { Affiliations => { type => 'child', path => 'affiliations', child => { ns => '__netjabber__:iq:pubsub:affiliations' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Configure => { type => 'child', path => 'configure', child => { ns => '__netjabber__:iq:pubsub:configure' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Create => { type => 'child', path => 'create', child => { ns => '__netjabber__:iq:pubsub:create' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Delete => { type => 'child', path => 'delete', child => { ns => '__netjabber__:iq:pubsub:delete' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Entities => { type => 'child', path => 'entities', child => { ns => '__netjabber__:iq:pubsub:entities' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Entity => { type => 'child', path => 'entity', child => { ns => '__netjabber__:iq:pubsub:entity' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Items => { type => 'child', path => 'items', child => { ns => '__netjabber__:iq:pubsub:items' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:pubsub:item' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Options => { type => 'child', path => 'options', child => { ns => '__netjabber__:iq:pubsub:options' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Publish => { type => 'child', path => 'publish', child => { ns => '__netjabber__:iq:pubsub:publish' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Purge => { type => 'child', path => 'purge', child => { ns => '__netjabber__:iq:pubsub:purge' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Retract => { type => 'child', path => 'retract', child => { ns => '__netjabber__:iq:pubsub:retract' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Subscribe => { type => 'child', path => 'subscribe', child => { ns => '__netjabber__:iq:pubsub:subscribe' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Unsubscribe => { type => 'child', path => 'unsubscribe', child => { ns => '__netjabber__:iq:pubsub:unsubscribe' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, PubSub => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:affiliations #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:affiliations', xpath => { Entity => { type => 'child', path => 'entity', child => { ns => '__netjabber__:iq:pubsub:entity' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Affiliations => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - affiliations objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:configure #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:configure', xpath => { Node => { path => '@node' }, Configure => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - configure objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:create #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:create', xpath => { Node => { path => '@node' }, Create => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - create objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:delete #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:delete', xpath => { Node => { path => '@node' }, Delete => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - delete objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:entities #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:entities', xpath => { Entity => { type => 'child', path => 'entity', child => { ns => '__netjabber__:iq:pubsub:entity' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Entities => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - entities objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:entity #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:entity', xpath => { Affiliation => { path => '@affiliation' }, JID => { type => 'jid', path => '@jid', }, Node => { path => '@node' }, Subscription => { path => '@subscription' }, SubscribeOptions => { type => 'child', path => 'subscribe-options', child => { ns => '__netjabber__:iq:pubsub:subscribe-options' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Entity => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - entity objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:items #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:items', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:pubsub:item' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Node => { path => '@node' }, MaxItems => { path => '@max_items' }, Items => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - items objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:item', xpath => { ID => { path => '@id' }, Payload => { type => 'raw' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - item objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:options #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:options', xpath => { JID => { type => 'jid', path => '@jid', }, Node => { path => '@node' }, Options => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - options objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:publish #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:publish', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:pubsub:item' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Node => { path => '@node' }, Publish => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - publish objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:purge #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:purge', xpath => { Node => { path => '@node' }, Purge => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - purge objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:retract #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:retract', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:pubsub:item' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Node => { path => '@node' }, Retract => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - retract objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:subscribe #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:subscribe', xpath => { JID => { type => 'jid', path => '@jid', }, Node => { path => '@node' }, Subscribe => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - subscribe objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:subscribe-options #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:subscribe-options', xpath => { Required => { type => 'flag', path => 'required', }, SubscribeOptions => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - subscribe-options objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:unsubscribe #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:unsubscribe', xpath => { JID => { type => 'jid', path => '@jid', }, Node => { path => '@node' }, Unsubscribe => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub - unsubscribe objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/pubsub#event #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/pubsub#event', tag => 'event', xpath => { Delete => { type => 'child', path => 'delete', child => { ns => '__netjabber__:iq:pubsub:event:delete' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Items => { type => 'child', path => 'items', child => { ns => '__netjabber__:iq:pubsub:event:items' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Event => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:event:delete #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:event:delete', xpath => { Node => { path => '@node' }, Delete => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub#event - delete objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:event:items #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:event:items', xpath => { Item => { type => 'child', path => 'item', child => { ns => '__netjabber__:iq:pubsub:event:item' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Node => { path => '@node' }, Items => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub#event - items objects', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:event:item #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:event:item', xpath => { ID => { path => '@id' }, Payload => { type => 'raw' }, Item => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub#event - item objects', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/pubsub#owner #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/pubsub#owner', tag => 'pubsub', xpath => { Action => { path => '@action' }, Configure => { type => 'child', path => 'configure', child => { ns => '__netjabber__:iq:pubsub:owner:configure' }, calls => [ 'Get', 'Defined', 'Add', 'Remove' ], }, Owner => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # __netjabber__:iq:pubsub:owner:configure #----------------------------------------------------------------------------- { &add_ns(ns => '__netjabber__:iq:pubsub:owner:configure', xpath => { Node => { path => '@node' }, Configure => { type => 'master' }, }, docs => { module => 'Net::Jabber', name => 'http://jabber.org/protocol/pubsub#owner - configure objects', }, ); } #XXX pubsub#errors #----------------------------------------------------------------------------- # http://jabber.org/protocol/si #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/si', tag => 'si', xpath => { ID => { path => '@id' }, MimeType => { path => '@mime-type' }, Profile => { path => '@profile' }, Stream => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/si/profile/file-transfer #----------------------------------------------------------------------------- { &add_ns(ns => 'http://jabber.org/protocol/si/profile/file-transfer', tag => 'file', xpath => { Date => { path => '@date' }, Desc => { path => 'desc/text()' }, Hash => { path => '@hash' }, Name => { path => '@name' }, Range => { type => 'flag', path => 'range', }, RangeOffset => { path => 'range/@offset' }, RangeLength => { path => 'range/@length' }, Size => { path => '@size' }, File => { type => 'master' }, }, docs => { module => 'Net::Jabber', }, ); } #----------------------------------------------------------------------------- # http://jabber.org/protocol/si/profile/tree-transfer #----------------------------------------------------------------------------- # XXX do later $ns = 'http://jabber.org/protocol/si/profile/tree-transfer'; $TAGS{$ns} = "tree"; $NAMESPACES{$ns}->{Directory}->{XPath}->{Type} = 'child'; $NAMESPACES{$ns}->{Directory}->{XPath}->{Path} = 'directory'; $NAMESPACES{$ns}->{Directory}->{XPath}->{Child} = ['Query','__netjabber__:iq:si:profile:tree:directory']; $NAMESPACES{$ns}->{Directory}->{XPath}->{Calls} = ['Add','Get']; $NAMESPACES{$ns}->{Numfiles}->{XPath}->{Path} = '@numfiles'; $NAMESPACES{$ns}->{Size}->{XPath}->{Path} = '@size'; $NAMESPACES{$ns}->{Tree}->{XPath}->{Type} = 'master'; #----------------------------------------------------------------------------- # __netjabber__:iq:si:profile:tree:directory #----------------------------------------------------------------------------- $ns = '__netjabber__:iq:si:profile:tree:directory'; $NAMESPACES{$ns}->{Directory}->{XPath}->{Type} = 'child'; $NAMESPACES{$ns}->{Directory}->{XPath}->{Path} = 'directory'; $NAMESPACES{$ns}->{Directory}->{XPath}->{Child} = ['Query','__netjabber__:iq:si:profile:tree:directory']; $NAMESPACES{$ns}->{Directory}->{XPath}->{Calls} = ['Add','Get']; $NAMESPACES{$ns}->{File}->{XPath}->{Type} = 'child'; $NAMESPACES{$ns}->{File}->{XPath}->{Path} = 'file'; $NAMESPACES{$ns}->{File}->{XPath}->{Child} = ['Query','__netjabber__:iq:si:profile:tree:file']; $NAMESPACES{$ns}->{File}->{XPath}->{Calls} = ['Add','Get']; $NAMESPACES{$ns}->{Name}->{XPath}->{Path} = '@name'; $NAMESPACES{$ns}->{Dir}->{XPath}->{Type} = 'master'; #----------------------------------------------------------------------------- # __netjabber__:iq:si:profile:tree:file #----------------------------------------------------------------------------- $ns = '__netjabber__:iq:si:profile:tree:file'; $NAMESPACES{$ns}->{Name}->{XPath}->{Path} = '@name'; $NAMESPACES{$ns}->{SID}->{XPath}->{Path} = '@sid'; $NAMESPACES{$ns}->{File}->{XPath}->{Type} = 'master'; sub add_ns { &Net::XMPP::Namespaces::add_ns(@_); } 1; Net-Jabber-2.0/lib/Net/Jabber/Debug.pm0000644000175000017500000000270110110275744020466 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Debug; =head1 NAME Net::Jabber::Debug - Jabber Debug Library =head1 DESCRIPTION Net::Jabber::Debug inherits all of its methods from Net::XMPP::Debug. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use FileHandle; use Carp; use Net::XMPP::Debug; use base qw( Net::XMPP::Debug ); use vars qw( $VERSION ); $VERSION = "2.0"; 1; Net-Jabber-2.0/lib/Net/Jabber/Dialback/0002755000175000017500000000000010112242736020573 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/lib/Net/Jabber/Dialback/Result.pm0000755000175000017500000001550410110275744022420 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Dialback::Result; =head1 NAME Net::Jabber::Dialback::Result - Jabber Dialback Result Module =head1 SYNOPSIS Net::Jabber::Dialback::Result is a companion to the Net::Jabber::Dialback module. It provides the user a simple interface to set and retrieve all parts of a Jabber Dialback Result. =head1 DESCRIPTION To initialize the Result with a Jabber you must pass it the XML::Stream hash. For example: my $dialback = new Net::Jabber::Dialback::Result(%hash); There has been a change from the old way of handling the callbacks. You no longer have to do the above yourself, a NJ::Dialback::Result object is passed to the callback function for the message. Also, the first argument to the callback functions is the session ID from XML::Streams. There are some cases where you might want this information, like if you created a Client that connects to two servers at once, or for writing a mini server. use Net::Jabber qw(Server); sub dialbackResult { my ($sid,$Result) = @_; . . . } You now have access to all of the retrieval functions available. To create a new dialback to send to the server: use Net::Jabber qw(Server); $Result = new Net::Jabber::Dialback::Result(); Now you can call the creation functions below to populate the tag before sending it. For more information about the array format being passed to the CallBack please read the Net::Jabber::Client documentation. =head2 Retrieval functions $to = $Result->GetTo(); $from = $Result->GetFrom(); $type = $Result->GetType(); $data = $Result->GetData(); $str = $Result->GetXML(); @dialback = $Result->GetTree(); =head2 Creation functions $Result->SetResult(from=>"jabber.org", to=>"jabber.com", data=>key); $Result->SetTo("jabber.org"); $Result->SetFrom("jabber.com"); $Result->SetType("valid"); $Result->SetData(key); =head2 Test functions $test = $Result->DefinedTo(); $test = $Result->DefinedFrom(); $test = $Result->DefinedType(); =head1 METHODS =head2 Retrieval functions GetTo() - returns a string with server that the is being sent to. GetFrom() - returns a string with server that the is being sent from. GetType() - returns a string with the type this is. GetData() - returns a string with the cdata of the . GetXML() - returns the XML string that represents the . This is used by the Send() function in Server.pm to send this object as a Jabber Dialback Result. GetTree() - returns an array that contains the tag in XML::Parser::Tree format. =head2 Creation functions SetResult(to=>string, - set multiple fields in the from=>string, at one time. This is a cumulative type=>string, and over writing action. If you set data=>string) the "from" attribute twice, the second setting is what is used. If you set the type, and then set the data then both will be in the tag. For valid settings read the specific Set functions below. SetTo(string) - sets the to attribute. SetFrom(string) - sets the from attribute. SetType(string) - sets the type attribute. Valid settings are: valid invalid SetData(string) - sets the cdata of the . =head2 Test functions DefinedTo() - returns 1 if the to attribute is defined in the , 0 otherwise. DefinedFrom() - returns 1 if the from attribute is defined in the , 0 otherwise. DefinedType() - returns 1 if the type attribute is defined in the , 0 otherwise. =head1 AUTHOR By Ryan Eatmon in May of 2001 for http://jabber.org.. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use vars qw($VERSION $AUTOLOAD %FUNCTIONS); $VERSION = "2.0"; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; $self->{VERSION} = $VERSION; bless($self, $proto); $self->{DEBUGHEADER} = "DB:Result"; $self->{DATA} = {}; $self->{CHILDREN} = {}; $self->{TAG} = "db:result"; if ("@_" ne ("")) { if (ref($_[0]) eq "Net::Jabber::Dialback::Result") { return $_[0]; } else { $self->{TREE} = shift; $self->ParseTree(); } } return $self; } ############################################################################## # # AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm # ############################################################################## sub AUTOLOAD { my $self = shift; &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_); } $FUNCTIONS{From}->{Get} = "from"; $FUNCTIONS{From}->{Set} = ["jid","from"]; $FUNCTIONS{From}->{Defined} = "from"; $FUNCTIONS{From}->{Hash} = "att"; $FUNCTIONS{Data}->{Get} = "data"; $FUNCTIONS{Data}->{Set} = ["scalar","data"]; $FUNCTIONS{Data}->{Defined} = "data"; $FUNCTIONS{Data}->{Hash} = "data"; $FUNCTIONS{To}->{Get} = "to"; $FUNCTIONS{To}->{Set} = ["jid","to"]; $FUNCTIONS{To}->{Defined} = "to"; $FUNCTIONS{To}->{Hash} = "att"; $FUNCTIONS{Type}->{Get} = "type"; $FUNCTIONS{Type}->{Set} = ["scalar","type"]; $FUNCTIONS{Type}->{Defined} = "type"; $FUNCTIONS{Type}->{Hash} = "att"; $FUNCTIONS{Result}->{Get} = "__netjabber__:master"; $FUNCTIONS{Result}->{Set} = ["master"]; 1; Net-Jabber-2.0/lib/Net/Jabber/Dialback/Verify.pm0000644000175000017500000001646210110275744022407 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Dialback::Verify; =head1 NAME Net::Jabber::Dialback::Verify - Jabber Dialback Verify Module =head1 SYNOPSIS Net::Jabber::Dialback::Verify is a companion to the Net::Jabber::Dialback module. It provides the user a simple interface to set and retrieve all parts of a Jabber Dialback Verify. =head1 DESCRIPTION To initialize the Verify with a Jabber you must pass it the XML::Stream hash. For example: my $dialback = new Net::Jabber::Dialback::Verify(%hash); There has been a change from the old way of handling the callbacks. You no longer have to do the above yourself, a NJ::Dialback::Verify object is passed to the callback function for the message. Also, the first argument to the callback functions is the session ID from XML::Streams. There are some cases where you might want this information, like if you created a Client that connects to two servers at once, or for writing a mini server. use Net::Jabber qw(Server); sub dialbackVerify { my ($sid,$Verify) = @_; . . . } You now have access to all of the retrieval functions available. To create a new dialback to send to the server: use Net::Jabber qw(Server); $Verify = new Net::Jabber::Dialback::Verify(); Now you can call the creation functions below to populate the tag before sending it. For more information about the array format being passed to the CallBack please read the Net::Jabber::Client documentation. =head2 Retrieval functions $to = $Verify->GetTo(); $from = $Verify->GetFrom(); $type = $Verify->GetType(); $id = $Verify->GetID(); $data = $Verify->GetData(); $str = $Verify->GetXML(); @dialback = $Verify->GetTree(); =head2 Creation functions $Verify->SetVerify(from=>"jabber.org", to=>"jabber.com", id=>id, data=>key); $Verify->SetTo("jabber.org"); $Verify->SetFrom("jabber.com"); $Verify->SetType("valid"); $Verify->SetID(id); $Verify->SetData(key); =head2 Test functions $test = $Verify->DefinedTo(); $test = $Verify->DefinedFrom(); $test = $Verify->DefinedType(); $test = $Verify->DefinedID(); =head1 METHODS =head2 Retrieval functions GetTo() - returns a string with server that the is being sent to. GetFrom() - returns a string with server that the is being sent from. GetType() - returns a string with the type this is. GetID() - returns a string with the id this is. GetData() - returns a string with the cdata of the . GetXML() - returns the XML string that represents the . This is used by the Send() function in Server.pm to send this object as a Jabber Dialback Verify. GetTree() - returns an array that contains the tag in XML::Parser::Tree format. =head2 Creation functions SetVerify(to=>string, - set multiple fields in the from=>string, at one time. This is a cumulative type=>string, and over writing action. If you set id=>string, the "from" attribute twice, the second data=>string) setting is what is used. If you set the type, and then set the data then both will be in the tag. For valid settings read the specific Set functions below. SetTo(string) - sets the to attribute. SetFrom(string) - sets the from attribute. SetType(string) - sets the type attribute. Valid settings are: valid invalid SetID(string) - sets the id attribute. SetData(string) - sets the cdata of the . =head2 Test functions DefinedTo() - returns 1 if the to attribute is defined in the , 0 otherwise. DefinedFrom() - returns 1 if the from attribute is defined in the , 0 otherwise. DefinedType() - returns 1 if the type attribute is defined in the , 0 otherwise. DefinedID() - returns 1 if the id attribute is defined in the , 0 otherwise. =head1 AUTHOR By Ryan Eatmon in May of 2001 for http://jabber.org.. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use vars qw($VERSION $AUTOLOAD %FUNCTIONS); $VERSION = "2.0"; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; $self->{VERSION} = $VERSION; bless($self, $proto); $self->{DEBUGHEADER} = "DB:Verify"; $self->{DATA} = {}; $self->{CHILDREN} = {}; $self->{TAG} = "db:verify"; if ("@_" ne ("")) { if (ref($_[0]) eq "Net::Jabber::Dialback::Verify") { return $_[0]; } else { $self->{TREE} = shift; $self->ParseTree(); } } return $self; } ############################################################################## # # AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm # ############################################################################## sub AUTOLOAD { my $self = shift; &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_); } $FUNCTIONS{From}->{Get} = "from"; $FUNCTIONS{From}->{Set} = ["jid","from"]; $FUNCTIONS{From}->{Defined} = "from"; $FUNCTIONS{From}->{Hash} = "att"; $FUNCTIONS{Data}->{Get} = "data"; $FUNCTIONS{Data}->{Set} = ["scalar","data"]; $FUNCTIONS{Data}->{Defined} = "data"; $FUNCTIONS{Data}->{Hash} = "data"; $FUNCTIONS{ID}->{Get} = "id"; $FUNCTIONS{ID}->{Set} = ["scalar","id"]; $FUNCTIONS{ID}->{Defined} = "id"; $FUNCTIONS{ID}->{Hash} = "child-data"; $FUNCTIONS{To}->{Get} = "to"; $FUNCTIONS{To}->{Set} = ["jid","to"]; $FUNCTIONS{To}->{Defined} = "to"; $FUNCTIONS{To}->{Hash} = "att"; $FUNCTIONS{Type}->{Get} = "type"; $FUNCTIONS{Type}->{Set} = ["scalar","type"]; $FUNCTIONS{Type}->{Defined} = "type"; $FUNCTIONS{Type}->{Hash} = "att"; $FUNCTIONS{Verify}->{Get} = "__netjabber__:master"; $FUNCTIONS{Verify}->{Set} = ["master"]; 1; Net-Jabber-2.0/lib/Net/Jabber/JID.pm0000644000175000017500000000264210110275744020052 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::JID; =head1 NAME Net::Jabber::JID - Jabber JID Module =head1 DESCRIPTION Net::Jabber::JID inherits all of its methods from Net::XMPP::JID. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use Net::XMPP::JID; use base qw( Net::XMPP::JID ); use vars qw($VERSION); $VERSION = "2.0"; 1; Net-Jabber-2.0/lib/Net/Jabber/Client.pm0000644000175000017500000000465610110275744020671 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Client; =head1 NAME Net::Jabber::Client - Jabber Client Library =head1 SYNOPSIS Net::Jabber::Client is a module that provides a developer easy access to the Jabber Instant Messaging protocol. =head1 DESCRIPTION Client.pm inherits its methods from Net::XMPP::Client, Net::XMPP::Protocol and Net::Jabber::Protocol. The Protocol modules provide enough high level APIs and automation of the low level APIs that writing a Jabber Client in Perl is trivial. For those that wish to work with the low level you can do that too, but those functions are covered in the documentation for each module. Net::Jabber::Client provides functions to connect to a Jabber server, login, send and receive messages, set personal information, create a new user account, manage the roster, and disconnect. You can use all or none of the functions, there is no requirement. For more information on how the details for how Net::Jabber is written please see the help for Net::Jabber itself. For a full list of high level functions available please see: Net::XMPP::Client Net::XMPP::Protocol Net::Jabber::Protocol =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use strict; use Carp; use Net::XMPP::Client; use Net::Jabber::Protocol; use base qw( Net::XMPP::Client Net::Jabber::Protocol ); use vars qw( $VERSION ); $VERSION = "2.0"; 1; Net-Jabber-2.0/lib/Net/Jabber/Stanza.pm0000644000175000017500000026074210110301423020673 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Stanza; =head1 NAME Net::Jabber::Stanza - Jabber Stanza Module =head1 SYNOPSIS Net::Jabber::Stanza is a private package that serves as a basis for all Jabber stanzas generated by Net::Jabber. =head1 DESCRIPTION This module is not meant to be used directly. You should be using either Net::Jabber::IQ, Net::Jabber::Message, Net::Jabber::Presence, or another package that inherits from Net::Jabber::Stanza. That said, this is where all of the namespaced methods are defined. The current supported namespaces are: =cut # NS_BEGIN =pod http://jabber.org/protocol/bytestreams http://jabber.org/protocol/commands http://jabber.org/protocol/disco#info http://jabber.org/protocol/disco#items http://jabber.org/protocol/feature-neg http://jabber.org/protocol/muc http://jabber.org/protocol/muc#admin http://jabber.org/protocol/muc#user http://jabber.org/protocol/pubsub http://jabber.org/protocol/pubsub#event http://jabber.org/protocol/pubsub#owner http://jabber.org/protocol/si http://jabber.org/protocol/si/profile/file-transfer jabber:iq:agent - DEPRECATED jabber:iq:agents - DEPRECATED jabber:iq:autoupdate jabber:iq:browse - DEPRECATED jabber:iq:conference jabber:iq:filter - DEPRECATED jabber:iq:gateway jabber:iq:last jabber:iq:oob jabber:iq:pass jabber:iq:rpc jabber:iq:search jabber:iq:time jabber:iq:version jabber:x:autoupdate jabber:x:conference jabber:x:data jabber:x:delay jabber:x:encrypted jabber:x:event jabber:x:expire jabber:x:oob jabber:x:roster jabber:x:signed =cut # NS_END =pod For more information on what these namespaces are for, visit http://www.jabber.org and browse the Jabber Programmers Guide. The following tables can be read as follows: ny:private:ns Name Type Get Set Remove Defined Add ========================== ======= === === ====== ======= === Foo scalar X X X X Bar child X Bars child X Test master X X Withing the my:private:ns namespace, there exists the functions: GetFoo(), SetFoo(), RemoveFoo(), DefinedFoo() AddBar() GetBars(), DefinedBars() GetTest(), SetMaster() Hopefully it should be obvious how this all works. If not feel free to contact me and I'll work on adding more documentation. =cut # DOC_BEGIN =head1 http://jabber.org/protocol/bytestreams Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Activate scalar X X X X SID scalar X X X X StreamHostUsedJID jid X X X X StreamHost child X StreamHosts child X X X ByteStreams master X X =head1 http://jabber.org/protocol/bytestreams - streamhost objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Host scalar X X X X JID jid X X X X Port scalar X X X X ZeroConf scalar X X X X StreamHost master X X =head1 http://jabber.org/protocol/commands Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Action scalar X X X X Node scalar X X X X SessionID scalar X X X X Status scalar X X X X Note child X Notes child X X X Command master X X =head1 http://jabber.org/protocol/commands - note objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Message scalar X X X X Type scalar X X X X Note master X X =head1 http://jabber.org/protocol/disco#info Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Feature child X Features child X X X Identities child X X X Identity child X DiscoInfo master X X =head1 http://jabber.org/protocol/disco#info - feature objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Var scalar X X X X Feature master X X =head1 http://jabber.org/protocol/disco#info - identity objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Category scalar X X X X Name scalar X X X X Type scalar X X X X Identity master X X =head1 http://jabber.org/protocol/disco#items Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X Items child X X X DiscoItems master X X =head1 http://jabber.org/protocol/disco#items - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Action scalar X X X X JID jid X X X X Name scalar X X X X Node scalar X X X X Item master X X =head1 http://jabber.org/protocol/feature-neg Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === FeatureNeg master X X =head1 http://jabber.org/protocol/muc Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Password scalar X X X X MUC master X X =head1 http://jabber.org/protocol/muc#admin Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Item child X Items child X X X Admin master X X =head1 http://jabber.org/protocol/muc#admin - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ActorJID jid X X X X Affiliation scalar X X X X JID jid X X X X Nick scalar X X X X Reason scalar X X X X Role scalar X X X X Item master X X =head1 http://jabber.org/protocol/muc#user Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Alt scalar X X X X Password scalar X X X X StatusCode scalar X X X X Invite child X X X X Item child X X X X User master X X =head1 http://jabber.org/protocol/muc#user - invite objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === From jid X X X X Reason scalar X X X X To jid X X X X Invite master X X =head1 http://jabber.org/protocol/muc#user - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ActorJID jid X X X X Affiliation scalar X X X X JID jid X X X X Nick scalar X X X X Reason scalar X X X X Role scalar X X X X Item master X X =head1 http://jabber.org/protocol/pubsub Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Affiliations child X X X X Configure child X X X X Create child X X X X Delete child X X X X Entities child X X X X Entity child X X X X Item child X X X X Items child X X X X Options child X X X X Publish child X X X X Purge child X X X X Retract child X X X X Subscribe child X X X X Unsubscribe child X X X X PubSub master X X =head1 http://jabber.org/protocol/pubsub - affiliations objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Entity child X X X X Affiliations master X X =head1 http://jabber.org/protocol/pubsub - configure objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Configure master X X =head1 http://jabber.org/protocol/pubsub - create objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Create master X X =head1 http://jabber.org/protocol/pubsub - delete objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Delete master X X =head1 http://jabber.org/protocol/pubsub - entities objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Entity child X X X X Entities master X X =head1 http://jabber.org/protocol/pubsub - entity objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Affiliation scalar X X X X JID jid X X X X Node scalar X X X X Subscription scalar X X X X SubscribeOptions child X X X X Entity master X X =head1 http://jabber.org/protocol/pubsub - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X Payload raw X X X X Item master X X =head1 http://jabber.org/protocol/pubsub - items objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === MaxItems scalar X X X X Node scalar X X X X Item child X X X X Items master X X =head1 http://jabber.org/protocol/pubsub - options objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Node scalar X X X X Options master X X =head1 http://jabber.org/protocol/pubsub - publish objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X X X X Publish master X X =head1 http://jabber.org/protocol/pubsub - purge objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Purge master X X =head1 http://jabber.org/protocol/pubsub - retract objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X X X X Retract master X X =head1 http://jabber.org/protocol/pubsub - subscribe objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Node scalar X X X X Subscribe master X X =head1 http://jabber.org/protocol/pubsub - subscribe-options objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Required flag X X X X SubscribeOptions master X X =head1 http://jabber.org/protocol/pubsub - unsubscribe objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Node scalar X X X X Unsubscribe master X X =head1 http://jabber.org/protocol/pubsub#event Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Delete child X X X X Items child X X X X Event master X X =head1 http://jabber.org/protocol/pubsub#event - delete objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Delete master X X =head1 http://jabber.org/protocol/pubsub#event - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X Payload raw X X X X Item master X X =head1 http://jabber.org/protocol/pubsub#event - items objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X X X X Items master X X =head1 http://jabber.org/protocol/pubsub#owner Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Action scalar X X X X Configure child X X X X Owner master X X =head1 http://jabber.org/protocol/pubsub#owner - configure objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Configure master X X =head1 http://jabber.org/protocol/si Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X MimeType scalar X X X X Profile scalar X X X X Stream master X X =head1 http://jabber.org/protocol/si/profile/file-transfer Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Date scalar X X X X Desc scalar X X X X Hash scalar X X X X Name scalar X X X X Range flag X X X X RangeLength scalar X X X X RangeOffset scalar X X X X Size scalar X X X X File master X X =head1 jabber:iq:agent - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Agents flag X X X X Description scalar X X X X GroupChat flag X X X X JID jid X X X X Name scalar X X X X Register flag X X X X Search flag X X X X Service scalar X X X X Transport scalar X X X X URL scalar X X X X Agent master X X =head1 jabber:iq:agents - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Agent child X Agents child X X X =head1 jabber:iq:autoupdate Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Beta child X Dev child X Release child X Releases child X X X =head1 jabber:iq:autoupdate - release objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X Priority scalar X X X X URL scalar X X X X Version scalar X X X X Release master X X =head1 jabber:iq:browse - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Category scalar X X X X JID jid X X X X NS array X X X X Name scalar X X X X Type scalar X X X X Item child X Items child X X X Browse master X X =head1 jabber:iq:browse - item objects - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Category scalar X X X X JID jid X X X X NS array X X X X Name scalar X X X X Type scalar X X X X Item child X Items child X X X Browse master X X =head1 jabber:iq:conference Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X Name scalar X X X X Nick scalar X X X X Privacy flag X X X X Secret scalar X X X X Conference master X X =head1 jabber:iq:filter - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Rule child X Rules child X X X =head1 jabber:iq:filter - rule objects - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Body scalar X X X X Continued scalar X X X X Drop scalar X X X X Edit scalar X X X X Error scalar X X X X From scalar X X X X Offline scalar X X X X Reply scalar X X X X Resource scalar X X X X Show scalar X X X X Size scalar X X X X Subject scalar X X X X Time scalar X X X X Type scalar X X X X Unavailable scalar X X X X Rule master X X =head1 jabber:iq:gateway Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X JID jid X X X X Prompt scalar X X X X Gateway master X X =head1 jabber:iq:last Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Message scalar X X X X Seconds scalar X X X X Last master X X =head1 jabber:iq:oob Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X URL scalar X X X X Oob master X X =head1 jabber:iq:pass Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Client scalar X X X X ClientPort scalar X X X X Close flag X X X X Expire scalar X X X X OneShot flag X X X X Proxy scalar X X X X ProxyPort scalar X X X X Server scalar X X X X ServerPort scalar X X X X Pass master X X =head1 jabber:iq:rpc Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === MethodCall child X X X X MethodResponse child X X X X =head1 jabber:iq:rpc - array objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Data child X Datas child X X X =head1 jabber:iq:rpc - data objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Value child X X X X =head1 jabber:iq:rpc - fault objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Value child X X X X =head1 jabber:iq:rpc - member objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Name scalar X X X X Value child X X X X Member master X X =head1 jabber:iq:rpc - methodCall objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === MethodName scalar X X X X Params child X X X X MethodCall master X X =head1 jabber:iq:rpc - methodResponse objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Fault child X X X X Params child X X X X =head1 jabber:iq:rpc - param objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Value child X X X X =head1 jabber:iq:rpc - params objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Param child X Params child X X X =head1 jabber:iq:rpc - struct objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Member child X Members child X X X =head1 jabber:iq:rpc - value objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Base64 scalar X X X X Boolean scalar X X X X DateTime scalar X X X X Double scalar X X X X I4 scalar X X X X Int scalar X X X X String scalar X X X X Value scalar X X X X Array child X X X X Struct child X X X X RPCValue master X X =head1 jabber:iq:search Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Email scalar X X X X Family scalar X X X X First scalar X X X X Given scalar X X X X Instructions scalar X X X X Key scalar X X X X Last scalar X X X X Name scalar X X X X Nick scalar X X X X Truncated flag X X X X Item child X Items child X X X Search master X X =head1 jabber:iq:search - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Email scalar X X X X Family scalar X X X X First scalar X X X X Given scalar X X X X JID jid X X X X Key scalar X X X X Last scalar X X X X Name scalar X X X X Nick scalar X X X X Item master X X =head1 jabber:iq:time Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Display special X X X X TZ special X X X X UTC special X X X X Time master X X =head1 jabber:iq:version Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Name scalar X X X X OS special X X X X Ver special X X X X Version master X X =head1 jabber:x:autoupdate Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Autoupdate master X X =head1 jabber:x:conference Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Conference master X X =head1 jabber:x:data Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Form scalar X X X X Instructions scalar X X X X Title scalar X X X X Type scalar X X X X Field child X Fields child X X X Item child X Items child X X X Reported child X X X X Data master X X =head1 jabber:x:data - field objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X Label scalar X X X X Required flag X X X X Type scalar X X X X Value array X X X X Var scalar X X X X Option child X Options child X X X Field master X X =head1 jabber:x:data - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Field child X Fields child X X X Item master X X =head1 jabber:x:data - option objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Label scalar X X X X Value scalar X X X X Option master X X =head1 jabber:x:data - reported objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Field child X Fields child X X X Reported master X X =head1 jabber:x:delay Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === From jid X X X X Message scalar X X X X Stamp timestamp X X X X Delay master X X =head1 jabber:x:encrypted Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Message scalar X X X X Encrypted master X X =head1 jabber:x:event Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Composing flag X X X X Delivered flag X X X X Displayed flag X X X X ID scalar X X X X Offline flag X X X X Event master X X =head1 jabber:x:expire Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Seconds scalar X X X X Expire master X X =head1 jabber:x:oob Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X URL scalar X X X X Oob master X X =head1 jabber:x:roster Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Item child X Items child X X X Roster master X X =head1 jabber:x:roster - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Ask scalar X X X X Group array X X X X JID jid X X X X Name scalar X X X X Subscription scalar X X X X Item master X X =head1 jabber:x:signed Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Signature scalar X X X X Signed master X X # DOC_BEGIN =head1 http://jabber.org/protocol/bytestreams Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Activate scalar X X X X SID scalar X X X X StreamHostUsedJID jid X X X X StreamHost child X StreamHosts child X X X ByteStreams master X X =head1 http://jabber.org/protocol/bytestreams - streamhost objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Host scalar X X X X JID jid X X X X Port scalar X X X X ZeroConf scalar X X X X StreamHost master X X =head1 http://jabber.org/protocol/commands Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Action scalar X X X X Node scalar X X X X SessionID scalar X X X X Status scalar X X X X Note child X Notes child X X X Command master X X =head1 http://jabber.org/protocol/commands - note objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Message scalar X X X X Type scalar X X X X Note master X X =head1 http://jabber.org/protocol/disco#info Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Feature child X Features child X X X Identities child X X X Identity child X DiscoInfo master X X =head1 http://jabber.org/protocol/disco#info - feature objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Var scalar X X X X Feature master X X =head1 http://jabber.org/protocol/disco#info - identity objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Category scalar X X X X Name scalar X X X X Type scalar X X X X Identity master X X =head1 http://jabber.org/protocol/disco#items Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X Items child X X X DiscoItems master X X =head1 http://jabber.org/protocol/disco#items - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Action scalar X X X X JID jid X X X X Name scalar X X X X Node scalar X X X X Item master X X =head1 http://jabber.org/protocol/feature-neg Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === FeatureNeg master X X =head1 http://jabber.org/protocol/muc Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Password scalar X X X X MUC master X X =head1 http://jabber.org/protocol/muc#admin Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Item child X Items child X X X Admin master X X =head1 http://jabber.org/protocol/muc#admin - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ActorJID jid X X X X Affiliation scalar X X X X JID jid X X X X Nick scalar X X X X Reason scalar X X X X Role scalar X X X X Item master X X =head1 http://jabber.org/protocol/muc#user Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Alt scalar X X X X Password scalar X X X X StatusCode scalar X X X X Invite child X X X X Item child X X X X User master X X =head1 http://jabber.org/protocol/muc#user - invite objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === From jid X X X X Reason scalar X X X X To jid X X X X Invite master X X =head1 http://jabber.org/protocol/muc#user - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ActorJID jid X X X X Affiliation scalar X X X X JID jid X X X X Nick scalar X X X X Reason scalar X X X X Role scalar X X X X Item master X X =head1 http://jabber.org/protocol/pubsub Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Affiliations child X X X X Configure child X X X X Create child X X X X Delete child X X X X Entities child X X X X Entity child X X X X Item child X X X X Items child X X X X Options child X X X X Publish child X X X X Purge child X X X X Retract child X X X X Subscribe child X X X X Unsubscribe child X X X X PubSub master X X =head1 http://jabber.org/protocol/pubsub - affiliations objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Entity child X X X X Affiliations master X X =head1 http://jabber.org/protocol/pubsub - configure objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Configure master X X =head1 http://jabber.org/protocol/pubsub - create objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Create master X X =head1 http://jabber.org/protocol/pubsub - delete objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Delete master X X =head1 http://jabber.org/protocol/pubsub - entities objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Entity child X X X X Entities master X X =head1 http://jabber.org/protocol/pubsub - entity objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Affiliation scalar X X X X JID jid X X X X Node scalar X X X X Subscription scalar X X X X SubscribeOptions child X X X X Entity master X X =head1 http://jabber.org/protocol/pubsub - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X Payload raw X X X X Item master X X =head1 http://jabber.org/protocol/pubsub - items objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === MaxItems scalar X X X X Node scalar X X X X Item child X X X X Items master X X =head1 http://jabber.org/protocol/pubsub - options objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Node scalar X X X X Options master X X =head1 http://jabber.org/protocol/pubsub - publish objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X X X X Publish master X X =head1 http://jabber.org/protocol/pubsub - purge objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Purge master X X =head1 http://jabber.org/protocol/pubsub - retract objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X X X X Retract master X X =head1 http://jabber.org/protocol/pubsub - subscribe objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Node scalar X X X X Subscribe master X X =head1 http://jabber.org/protocol/pubsub - subscribe-options objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Required flag X X X X SubscribeOptions master X X =head1 http://jabber.org/protocol/pubsub - unsubscribe objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Node scalar X X X X Unsubscribe master X X =head1 http://jabber.org/protocol/pubsub#event Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Delete child X X X X Items child X X X X Event master X X =head1 http://jabber.org/protocol/pubsub#event - delete objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Delete master X X =head1 http://jabber.org/protocol/pubsub#event - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X Payload raw X X X X Item master X X =head1 http://jabber.org/protocol/pubsub#event - items objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Item child X X X X Items master X X =head1 http://jabber.org/protocol/pubsub#owner Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Action scalar X X X X Configure child X X X X Owner master X X =head1 http://jabber.org/protocol/pubsub#owner - configure objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Node scalar X X X X Configure master X X =head1 http://jabber.org/protocol/si Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X MimeType scalar X X X X Profile scalar X X X X Stream master X X =head1 http://jabber.org/protocol/si/profile/file-transfer Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Date scalar X X X X Desc scalar X X X X Hash scalar X X X X Name scalar X X X X Range flag X X X X RangeLength scalar X X X X RangeOffset scalar X X X X Size scalar X X X X File master X X =head1 jabber:iq:agent - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Agents flag X X X X Description scalar X X X X GroupChat flag X X X X JID jid X X X X Name scalar X X X X Register flag X X X X Search flag X X X X Service scalar X X X X Transport scalar X X X X URL scalar X X X X Agent master X X =head1 jabber:iq:agents - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Agent child X Agents child X X X =head1 jabber:iq:autoupdate Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Beta child X Dev child X Release child X Releases child X X X =head1 jabber:iq:autoupdate - release objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X Priority scalar X X X X URL scalar X X X X Version scalar X X X X Release master X X =head1 jabber:iq:browse - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Category scalar X X X X JID jid X X X X NS array X X X X Name scalar X X X X Type scalar X X X X Item child X Items child X X X Browse master X X =head1 jabber:iq:browse - item objects - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Category scalar X X X X JID jid X X X X NS array X X X X Name scalar X X X X Type scalar X X X X Item child X Items child X X X Browse master X X =head1 jabber:iq:conference Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === ID scalar X X X X Name scalar X X X X Nick scalar X X X X Privacy flag X X X X Secret scalar X X X X Conference master X X =head1 jabber:iq:filter - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Rule child X Rules child X X X =head1 jabber:iq:filter - rule objects - DEPRECATED Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Body scalar X X X X Continued scalar X X X X Drop scalar X X X X Edit scalar X X X X Error scalar X X X X From scalar X X X X Offline scalar X X X X Reply scalar X X X X Resource scalar X X X X Show scalar X X X X Size scalar X X X X Subject scalar X X X X Time scalar X X X X Type scalar X X X X Unavailable scalar X X X X Rule master X X =head1 jabber:iq:gateway Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X JID jid X X X X Prompt scalar X X X X Gateway master X X =head1 jabber:iq:last Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Message scalar X X X X Seconds scalar X X X X Last master X X =head1 jabber:iq:oob Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X URL scalar X X X X Oob master X X =head1 jabber:iq:pass Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Client scalar X X X X ClientPort scalar X X X X Close flag X X X X Expire scalar X X X X OneShot flag X X X X Proxy scalar X X X X ProxyPort scalar X X X X Server scalar X X X X ServerPort scalar X X X X Pass master X X =head1 jabber:iq:rpc Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === MethodCall child X X X X MethodResponse child X X X X =head1 jabber:iq:rpc - array objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Data child X Datas child X X X =head1 jabber:iq:rpc - data objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Value child X X X X =head1 jabber:iq:rpc - fault objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Value child X X X X =head1 jabber:iq:rpc - member objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Name scalar X X X X Value child X X X X Member master X X =head1 jabber:iq:rpc - methodCall objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === MethodName scalar X X X X Params child X X X X MethodCall master X X =head1 jabber:iq:rpc - methodResponse objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Fault child X X X X Params child X X X X =head1 jabber:iq:rpc - param objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Value child X X X X =head1 jabber:iq:rpc - params objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Param child X Params child X X X =head1 jabber:iq:rpc - struct objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Member child X Members child X X X =head1 jabber:iq:rpc - value objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Base64 scalar X X X X Boolean scalar X X X X DateTime scalar X X X X Double scalar X X X X I4 scalar X X X X Int scalar X X X X String scalar X X X X Value scalar X X X X Array child X X X X Struct child X X X X RPCValue master X X =head1 jabber:iq:search Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Email scalar X X X X Family scalar X X X X First scalar X X X X Given scalar X X X X Instructions scalar X X X X Key scalar X X X X Last scalar X X X X Name scalar X X X X Nick scalar X X X X Truncated flag X X X X Item child X Items child X X X Search master X X =head1 jabber:iq:search - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Email scalar X X X X Family scalar X X X X First scalar X X X X Given scalar X X X X JID jid X X X X Key scalar X X X X Last scalar X X X X Name scalar X X X X Nick scalar X X X X Item master X X =head1 jabber:iq:time Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Display special X X X X TZ special X X X X UTC special X X X X Time master X X =head1 jabber:iq:version Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Name scalar X X X X OS special X X X X Ver special X X X X Version master X X =head1 jabber:x:autoupdate Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Autoupdate master X X =head1 jabber:x:conference Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === JID jid X X X X Conference master X X =head1 jabber:x:data Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Form scalar X X X X Instructions scalar X X X X Title scalar X X X X Type scalar X X X X Field child X Fields child X X X Item child X Items child X X X Reported child X X X X Data master X X =head1 jabber:x:data - field objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X Label scalar X X X X Required flag X X X X Type scalar X X X X Value array X X X X Var scalar X X X X Option child X Options child X X X Field master X X =head1 jabber:x:data - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Field child X Fields child X X X Item master X X =head1 jabber:x:data - option objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Label scalar X X X X Value scalar X X X X Option master X X =head1 jabber:x:data - reported objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Field child X Fields child X X X Reported master X X =head1 jabber:x:delay Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === From jid X X X X Message scalar X X X X Stamp timestamp X X X X Delay master X X =head1 jabber:x:encrypted Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Message scalar X X X X Encrypted master X X =head1 jabber:x:event Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Composing flag X X X X Delivered flag X X X X Displayed flag X X X X ID scalar X X X X Offline flag X X X X Event master X X =head1 jabber:x:expire Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Seconds scalar X X X X Expire master X X =head1 jabber:x:oob Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Desc scalar X X X X URL scalar X X X X Oob master X X =head1 jabber:x:roster Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Item child X Items child X X X Roster master X X =head1 jabber:x:roster - item objects Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Ask scalar X X X X Group array X X X X JID jid X X X X Name scalar X X X X Subscription scalar X X X X Item master X X =head1 jabber:x:signed Name Type Get Set Remove Defined Add ========================== ========= === === ====== ======= === Signature scalar X X X X Signed master X X =cut # DOC_END =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use strict; use Carp; use Net::XMPP::Stanza; use Net::Jabber::Namespaces; use base qw( Net::XMPP::Stanza ); use vars qw( $TIMEZONE ); if (eval "require Time::Timezone") { $TIMEZONE = 1; Time::Timezone->import(qw(tz_local_offset tz_name)); } else { $TIMEZONE = 0; } sub _init { my $self = shift; my $result = $self->SUPER::_init(@_); if (defined($result)) { $result->_CustomSet_init(); return $result; } $self->_CustomSet_init(); return; } sub GetX { my $self = shift; $self->GetChild(@_); } sub DefinedX { my $self = shift; $self->DefinedChild(@_); } sub NewX { my $self = shift; $self->NewChild(@_); } sub AddX { my $self = shift; $self->AddChild(@_); } sub RemoveX { my $self = shift; $self->RemoveChild(@_); } sub GetQuery { my $self = shift; $self->GetChild(@_); } sub DefinedQuery { my $self = shift; $self->DefinedChild(@_); } sub NewQuery { my $self = shift; $self->NewChild(@_); } sub AddQuery { my $self = shift; $self->AddChild(@_); } sub RemoveQuery { my $self = shift; $self->RemoveChild(@_); } sub _new_jid { my $self = shift; return new Net::Jabber::JID(@_); } sub _new_packet { my $self = shift; return new Net::Jabber::Stanza(@_); } sub _CustomSet_init { my $self = shift; $self->{CUSTOMSET}->{"time-display"} = \&_CustomSet_timedisplay; $self->{CUSTOMSET}->{"time-tz"} = \&_CustomSet_timetz; $self->{CUSTOMSET}->{"time-utc"} = \&_CustomSet_timeutc; $self->{CUSTOMSET}->{"version-os"} = \&_CustomSet_versionos; $self->{CUSTOMSET}->{"version-version"} = \&_CustomSet_versionversion; } sub _CustomSet_timedisplay { my $self = shift; my $value = shift; return $value if defined($value); $self->{DATA}->{__netjabbertime__} = time unless exists($self->{DATA}->{__netjabbertime__}); return &Net::XMPP::GetTimeStamp("local",$self->{DATA}->{__netjabbertime__}); } sub _CustomSet_timetz { my $self = shift; my $value = shift; if (!defined($value) && ($TIMEZONE == 1)) { return uc(&tz_name(&tz_local_offset())) } return $value; } sub _CustomSet_timeutc { my $self = shift; my $value = shift; return $value if defined($value); $self->{DATA}->{__netjabbertime__} = time unless exists($self->{DATA}->{__netjabbertime__}); return &Net::XMPP::GetTimeStamp("utc",$self->{DATA}->{__netjabbertime__},"stamp"); } sub _CustomSet_versionos { my $self = shift; my $value = shift; return (&POSIX::uname())[0]; } sub _CustomSet_versionversion { my $self = shift; my $value = shift; if (defined($value)) { $value .= " - [ Net::Jabber v$Net::Jabber::VERSION ]"; } else { $value = "Net::Jabber v$Net::Jabber::VERSION"; } return $value; } sub GetResults { my $self = shift; my %results; foreach my $item ($self->GetItems()) { my %result; my @xData = $item->GetX("jabber:x:data"); if ($#xData == -1) { %result = $item->GetItem(); } else { foreach my $field ($xData[0]->GetFields()) { $result{$field->GetVar()} = $field->GetValue(); } } $results{$item->GetJID()} = \%result; } return %results; } 1; Net-Jabber-2.0/lib/Net/Jabber/Key.pm0000644000175000017500000001176010110275744020175 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Key; =head1 NAME Net::Jabber::Key - Jabber Key Library =head1 SYNOPSIS Net::Jabber::Key is a module that provides a developer easy access to generating, caching, and comparing keys. =head1 DESCRIPTION Key.pm is a helper module for the Net::Jabber::Transport. When the Transport talks to a Client it sends a key and expects to get that key back from the Client. This module provides an API to generate, cache, and then compare the key send from the Client. =head2 Basic Functions $Key = new Net::Jabber::Key(); $key = $Key->Generate(); $key = $Key->Create("bob\@jabber.org"); $test = $Key->Compare("bob\@jabber.org","some key"); =head1 METHODS =head2 Basic Functions new(debug=>string, - creates the Key object. debug should debugfh=>FileHandle, be set to the path for the debug debuglevel=>integer) log to be written. If set to "stdout" then the debug will go there. Also, you can specify a filehandle that already exists and use that. debuglevel controls the amount of debug. 0 is none, 1 is normal, 2 is all. Generate() - returns a key in Digest SHA1 form based on the current time and the PID. Create(cacheString) - generates a key and caches it with the key of cacheString. Create returns the key. Compare(cacheString, - compares the key stored in the cache under keyString) cacheString with the keyString. Returns 1 if they match, and 0 otherwise. =head1 AUTHOR By Ryan Eatmon in May of 2000 for http://jabber.org. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use FileHandle; use vars qw($VERSION); $VERSION = "2.0"; sub new { srand( time() ^ ($$ + ($$ << 15))); my $proto = shift; my $self = { }; $self->{DEBUG} = new Net::Jabber::Debug(usedefault=>1, header=>"NJ::Key"); $self->{VERSION} = $VERSION; $self->{CACHE} = {}; if (eval "require Digest::SHA1") { $self->{DIGEST} = 1; Digest::SHA1->import(qw(sha1 sha1_hex sha1_base64)); } else { print "ERROR: You cannot use Key.pm unless you have Digest::SHA1 installed.\n"; exit(0); } bless($self, $proto); return $self; } ########################################################################### # # Generate - returns a random string based on the PID and time and a # random number. Then it creates an SHA1 Digest of that # string and returns it. # ########################################################################### sub Generate { my $self = shift; my $string = $$.time.rand(1000000); $string = Digest::SHA1::sha1_hex($string); $self->{DEBUG}->Log1("Generate: key($string)"); return $string; } ############################################################################## # # Create - Creates a key and caches the id for comparison later. # ############################################################################## sub Create { my $self = shift; my ($cacheString) = @_; $self->{DEBUG}->Log1("Create: cacheString($cacheString)"); my $key = $self->Generate(); $self->{DEBUG}->Log1("Create: key($key)"); $self->{CACHE}->{$cacheString} = $key; return $key; } ############################################################################## # # Compare - Compares the key with the key in the cache. # ############################################################################## sub Compare { my $self = shift; my ($cacheString,$key) = @_; $self->{DEBUG}->Log1("Compare: cacheString($cacheString) key($key)"); my $cacheKey = delete($self->{CACHE}->{$cacheString}); $self->{DEBUG}->Log1("Compare: cacheKey($cacheKey)"); return ($key eq $cacheKey); } 1; Net-Jabber-2.0/lib/Net/Jabber/Component.pm0000644000175000017500000002366210110275744021413 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Component; =head1 NAME Net::Jabber::Component - Jabber Component Library =head1 SYNOPSIS Net::Jabber::Component is a module that provides a developer easy access to developing server components in the Jabber Instant Messaging protocol. =head1 DESCRIPTION Component.pm seeks to provide enough high level APIs and automation of the low level APIs that writing a Jabber Component in Perl is trivial. For those that wish to work with the low level you can do that too, but those functions are covered in the documentation for each module. Net::Jabber::Component provides functions to connect to a Jabber server, login, send and receive messages, operate as a server side component, and disconnect. You can use all or none of the functions, there is no requirement. For more information on how the details for how Net::Jabber is written please see the help for Net::Jabber itself. For a full list of high level functions available please see Net::Jabber::Protocol and Net::XMPP::Protocol. =head2 Basic Functions use Net::Jabber; $Con = new Net::Jabber::Component(); $Con->Execute(hostname=>"jabber.org", componentname=>"service.jabber.org", secret=>"XXXX" ); # # For the list of available functions see Net::XMPP::Protocol. # $Con->Disconnect(); =head1 METHODS =head2 Basic Functions new(debuglevel=>0|1|2, - creates the Component object. debugfile debugfile=>string, should be set to the path for the debug debugtime=>0|1) log to be written. If set to "stdout" then the debug will go there. debuglevel controls the amount of debug. For more information about the valid setting for debuglevel, debugfile, and debugtime see Net::Jabber::Debug. AuthSend(secret=>string) - Perform the handshake and authenticate with the server. Connect(hostname=>string, - opens a connection to the server port=>integer, based on the value of componentname=>string, connectiontype. The only valid connectiontype=>string) setting is: accept - TCP/IP remote connection In the future this might be used again by offering new features. If accept then it connects to the server listed in the hostname value, on the port listed. The defaults for the two are localhost and 5269. Note: A change from previous versions is that Component now shares its core with Client. To that end, the secret should no longer be used. Call AuthSend after connecting. Better yet, use Execute. Connected() - returns 1 if the Component is connected to the server, and 0 if not. Disconnect() - closes the connection to the server. Execute(hostname=>string, - Generic inner loop to handle port=>int, connecting to the server, calling secret=>string, Process, and reconnecting if the componentname=>string, connection is lost. There are four connectiontype=>string, callbacks available that are called connectattempts=>int, at various places in the loop. connectsleep=>int) onconnect - when the component connects to the server. onauth - when the component has completed its handshake with the server this will be called. onprocess - this is the most inner loop and so gets called the most. Be very very careful what you put here since it can *DRASTICALLY* affect performance. ondisconnect - when connection is lost. onexit - when the function gives up trying to connect and exits. The arguments are passed straight on to the Connect function, except for connectattempts and connectsleep. connectattempts is the number of time that the Component should try to connect before giving up. -1 means try forever. The default is -1. connectsleep is the number of seconds to sleep between each connection attempt. Process(integer) - takes the timeout period as an argument. If no timeout is listed then the function blocks until a packet is received. Otherwise it waits that number of seconds and then exits so your program can continue doing useful things. NOTE: This is important for GUIs. You need to leave time to process GUI commands even if you are waiting for packets. The following are the possible return values, and what they mean: 1 - Status ok, data received. 0 - Status ok, no data received. undef - Status not ok, stop processing. IMPORTANT: You need to check the output of every Process. If you get an undef then the connection died and you should behave accordingly. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut use strict; use Carp; use Net::XMPP::Connection; use Net::Jabber::Protocol; use base qw( Net::XMPP::Connection Net::Jabber::Protocol ); use vars qw( $VERSION ); $VERSION = "2.0"; use Net::Jabber::XDB; sub new { srand( time() ^ ($$ + ($$ << 15))); my $proto = shift; my $self = { }; bless($self, $proto); $self->init(@_); $self->{SERVER}->{port} = 5269; $self->{SERVER}->{namespace} = "jabber:component:accept"; $self->{SERVER}->{allow_register} = 0; return $self; } sub AuthSend { my $self = shift; $self->_auth(@_); } sub _auth { my $self = shift; my (%args) = @_; $self->{STREAM}->SetCallBacks(node=>undef); $self->Send("".Digest::SHA1::sha1_hex($self->{SESSION}->{id}.$args{secret}).""); my $handshake = $self->Process(); if (!defined($handshake) || ($#{$handshake} == -1) || (ref($handshake->[0]) ne "XML::Stream::Node") || ($handshake->[0]->get_tag() ne "handshake")) { $self->SetErrorCode("Bad handshake."); return ("fail","Bad handshake."); } shift(@{$handshake}); foreach my $node (@{$handshake}) { $self->CallBack($self->{SESSION}->{id},$node); } $self->{STREAM}->SetCallBacks(node=>sub{ $self->CallBack(@_) }); return ("ok",""); } sub _connection_args { my $self = shift; my (%args) = @_; my %connect; $connect{componentname} = $args{componentname}; $connect{hostname} = $args{hostname}; $connect{port} = $args{port} if exists($args{port}); $connect{connectiontype} = $args{connectiontype} if exists($args{connectiontype}); $connect{timeout} = $args{connecttimeout} if exists($args{connecttimeout}); $connect{tls} = $args{tls} if exists($args{tls}); return %connect; } 1; Net-Jabber-2.0/lib/Net/Jabber/Presence.pm0000644000175000017500000000372710110275744021215 0ustar reatmonreatmon00000000000000############################################################################# # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::Presence; =head1 NAME Net::Jabber::Presence - Jabber Presence Module =head1 DESCRIPTION Net::Jabber::Presence inherits all of its methods from Net::XMPP::Presence. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use Net::XMPP::Presence; use base qw( Net::XMPP::Presence ); use vars qw( $VERSION ); $VERSION = "2.0"; sub GetX { my $self = shift; $self->GetChild(@_); } sub DefinedX { my $self = shift; $self->DefinedChild(@_); } sub NewX { my $self = shift; $self->NewChild(@_); } sub AddX { my $self = shift; $self->AddChild(@_); } sub RemoveX { my $self = shift; $self->RemoveChild(@_); } sub _new_jid { my $self = shift; return new Net::Jabber::JID(@_); } sub _new_packet { my $self = shift; return new Net::Jabber::Stanza(@_); } sub _presence { my $self = shift; return new Net::Jabber::Presence(@_); } 1; Net-Jabber-2.0/lib/Net/Jabber/Dialback.pm0000644000175000017500000000667610110275744021151 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Dialback; =head1 NAME Net::Jabber::Dialback - Jabber Dialback Module =head1 SYNOPSIS Net::Jabber::Dialback is a companion to the Net::Jabber::Server module. It provides the user a simple interface to set and retrieve all parts of a Jabber Server Dialback. =head1 DESCRIPTION To initialize the Dialback with a Jabber you must pass it the XML::Stream hash. For example: my $dialback = new Net::Jabber::Dialback(%hash); You now have access to all of the retrieval functions available. To create a new message to send to the server: use Net::Jabber qw(Server); $DB = new Net::Jabber::Dialback("verify"); $DB = new Net::Jabber::Dialback("result"); Please see the specific documentation for Net::Jabber::Dialback::Result and Net::Jabber::Dialback::Verify. For more information about the array format being passed to the CallBack please read the Net::Jabber::Client documentation. =head1 AUTHOR By Ryan Eatmon in May of 2001 for http://jabber.org.. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use vars qw($VERSION $AUTOLOAD %FUNCTIONS); $VERSION = "2.0"; use Net::Jabber::Dialback::Result; ($Net::Jabber::Dialback::Result::VERSION < $VERSION) && die("Net::Jabber::Dialback::Result $VERSION required--this is only version $Net::Jabber::Dialback::Result::VERSION"); use Net::Jabber::Dialback::Verify; ($Net::Jabber::Dialback::Verify::VERSION < $VERSION) && die("Net::Jabber::Dialback::Verify $VERSION required--this is only version $Net::Jabber::Dialback::Verify::VERSION"); sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; bless($self, $proto); if ("@_" ne ("")) { if (ref($_[0]) =~ /Net::Jabber::Dialback/) { return $_[0]; } else { my ($temp) = @_; return new Net::Jabber::Dialback::Result() if ($temp eq "result"); return new Net::Jabber::Dialback::Verify() if ($temp eq "verify"); my @temp = @{$temp}; return new Net::Jabber::Dialback::Result(@temp) if ($temp[0] eq "db:result"); return new Net::Jabber::Dialback::Verify(@temp) if ($temp[0] eq "db:verify"); } } else { carp "You must specify either \"result\" or \"verify\" as an argument"; } } 1; Net-Jabber-2.0/lib/Net/Jabber/Data.pm0000644000175000017500000003307410110275744020320 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Data; =head1 NAME Net::Jabber::Data - Jabber Data Library =head1 SYNOPSIS Net::Jabber::Data is a companion to the Net::Jabber::XDB module. It provides the user a simple interface to set and retrieve all parts of a Jabber XDB Data. =head1 DESCRIPTION Net::Jabber::Data differs from the other modules in that its behavior and available functions are based off of the XML namespace that is set in it. The current list of supported namespaces is: jabber:iq:auth jabber:iq:auth:0k jabber:iq:register jabber:iq:roster For more information on what these namespaces are for, visit http://www.jabber.org and browse the Jabber Programmers Guide. Each of these namespaces provide Net::Jabber::Data with the functions to access the data. By using the AUTOLOAD function the functions for each namespace is used when that namespace is active. To access a Data object you must create an XDB object and use the access functions there to get to the Data. To initialize the XDB with a Jabber you must pass it the XML::Stream hash from the Net::Jabber::Client module. my $xdb = new Net::Jabber::XDB(%hash); There has been a change from the old way of handling the callbacks. You no longer have to do the above yourself, a Net::Jabber::XDB object is passed to the callback function for the message. Also, the first argument to the callback functions is the session ID from XML::Streams. There are some cases where you might want this information, like if you created a Client that connects to two servers at once, or for writing a mini server. use Net::Jabber qw(Client); sub xdbCB { my ($sid,$XDB) = @_; my $data = $XDB->GetData(); . . . } You now have access to all of the retrieval functions available for that namespace. To create a new xdb to send to the server: use Net::Jabber; my $xdb = new Net::Jabber::XDB(); $data = $xdb->NewData("jabber:iq:auth"); Now you can call the creation functions for the Data as defined in the proper namespaces. See below for the general functions, and in each data module for those functions. For more information about the array format being passed to the CallBack please read the Net::Jabber::Client documentation. =head1 METHODS =head2 Retrieval functions GetXMLNS() - returns a string with the namespace of the data that the contains. $xmlns = $XDB->GetXMLNS(); GetData() - since the behavior of this module depends on the namespace, a Data object may contain Data objects. This helps to leverage code reuse by making children behave in the same manner. More than likely this function will never be called. @data = GetData() =head2 Creation functions SetXMLNS(string) - sets the xmlns of the to the string. $data->SetXMLNS("jabber:xdb:roster"); In an effort to make maintaining this document easier, I am not going to go into full detail on each of these functions. Rather I will present the functions in a list with a type in the first column to show what they return, or take as arugments. Here is the list of types I will use: string - just a string array - array of strings flag - this means that the specified child exists in the XML and acts like a flag. get will return 0 or 1. JID - either a string or Net::Jabber::JID object. objects - creates new objects, or returns an array of objects. special - this is a special case kind of function. Usually just by calling Set() with no arguments it will default the value to a special value, like OS or time. Sometimes it will modify the value you set, like in jabber:xdb:version SetVersion() the function adds on the Net::Jabber version to the string just for advertisement purposes. =) master - this desribes a function that behaves like the SetMessage() function in Net::Jabber::Message. It takes a hash and sets all of the values defined, and the Set returns a hash with the values that are defined in the object. =head1 jabber:iq: Type Get Set Defined ======= ================ ================ ================== =head1 jabber:iq: Type Get Set Defined ======= ================ ================ ================== =head1 jabber:iq: Type Get Set Defined ======= ================ ================ ================== =head1 jabber:iq: Type Get Set Defined ======= ================ ================ ================== =head1 jabber:iq: Type Get Set Defined ======= ================ ================ ================== =head1 CUSTOM NAMESPACES Part of the flexability of this module is that you can define your own namespace. For more information on this topic, please read the Net::Jabber::Namespaces man page. =head1 AUTHOR By Ryan Eatmon in May of 2001 for http://jabber.org.. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use vars qw($VERSION $AUTOLOAD %FUNCTIONS %NAMESPACES); $VERSION = "2.0"; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; $self->{VERSION} = $VERSION; bless($self, $proto); $self->{DEBUGHEADER} = "Data"; $self->{DATA} = {}; $self->{CHILDREN} = {}; $self->{TAG} = "data"; if ("@_" ne ("")) { if (ref($_[0]) eq "Net::Jabber::Data") { return $_[0]; } else { $self->{TREE} = shift; $self->{TAG} = $self->{TREE}->get_tag(); $self->ParseXMLNS(); $self->ParseTree(); } } return $self; } ############################################################################## # # AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm # ############################################################################## sub AUTOLOAD { my $self = shift; &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_); } $FUNCTIONS{XMLNS}->{Get} = "xmlns"; $FUNCTIONS{XMLNS}->{Set} = ["scalar","xmlns"]; $FUNCTIONS{XMLNS}->{Defined} = "xmlns"; $FUNCTIONS{XMLNS}->{Hash} = "att"; $FUNCTIONS{Data}->{Get} = "__netjabber__:children:data"; $FUNCTIONS{Data}->{Defined} = "__netjabber__:children:data"; #----------------------------------------------------------------------------- # jabber:iq:auth #----------------------------------------------------------------------------- $NAMESPACES{"jabber:iq:auth"}->{Password}->{Get} = "password"; $NAMESPACES{"jabber:iq:auth"}->{Password}->{Set} = ["scalar","password"]; $NAMESPACES{"jabber:iq:auth"}->{Password}->{Defined} = "password"; $NAMESPACES{"jabber:iq:auth"}->{Password}->{Hash} = "data"; $NAMESPACES{"jabber:iq:auth"}->{Auth}->{Get} = "__netjabber__:master"; $NAMESPACES{"jabber:iq:auth"}->{Auth}->{Set} = ["master"]; $NAMESPACES{"jabber:iq:auth"}->{"__netjabber__"}->{Tag} = "password"; #----------------------------------------------------------------------------- # jabber:iq:auth:0k #----------------------------------------------------------------------------- $NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Get} = "hash"; $NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Set} = ["scalar","hash"]; $NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Defined} = "hash"; $NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Hash} = "child-data"; $NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Get} = "sequence"; $NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Set} = ["scalar","sequence"]; $NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Defined} = "sequence"; $NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Hash} = "child-data"; $NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Get} = "token"; $NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Set} = ["scalar","token"]; $NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Defined} = "token"; $NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Hash} = "child-data"; $NAMESPACES{"jabber:iq:auth:0k"}->{ZeroK}->{Get} = "__netjabber__:master"; $NAMESPACES{"jabber:iq:auth:0k"}->{ZeroK}->{Set} = ["master"]; $NAMESPACES{"jabber:iq:auth:0k"}->{"__netjabber__"}->{Tag} = "zerok"; #----------------------------------------------------------------------------- # jabber:iq:last #----------------------------------------------------------------------------- $NAMESPACES{"jabber:iq:last"}->{Message}->{Get} = "message"; $NAMESPACES{"jabber:iq:last"}->{Message}->{Set} = ["scalar","message"]; $NAMESPACES{"jabber:iq:last"}->{Message}->{Defined} = "message"; $NAMESPACES{"jabber:iq:last"}->{Message}->{Hash} = "data"; $NAMESPACES{"jabber:iq:last"}->{Seconds}->{Get} = "last"; $NAMESPACES{"jabber:iq:last"}->{Seconds}->{Set} = ["scalar","last"]; $NAMESPACES{"jabber:iq:last"}->{Seconds}->{Defined} = "last"; $NAMESPACES{"jabber:iq:last"}->{Seconds}->{Hash} = "att"; $NAMESPACES{"jabber:iq:last"}->{Last}->{Get} = "__netjabber__:master"; $NAMESPACES{"jabber:iq:last"}->{Last}->{Set} = ["master"]; $NAMESPACES{"jabber:iq:last"}->{"__netjabber__"}->{Tag} = "query"; #----------------------------------------------------------------------------- # jabber:iq:roster #----------------------------------------------------------------------------- $NAMESPACES{"jabber:iq:roster"}->{Item}->{Get} = ""; $NAMESPACES{"jabber:iq:roster"}->{Item}->{Set} = ["add","Data","__netjabber__:iq:roster:item"]; $NAMESPACES{"jabber:iq:roster"}->{Item}->{Defined} = "__netjabber__:children:data"; $NAMESPACES{"jabber:iq:roster"}->{Item}->{Hash} = "child-add"; $NAMESPACES{"jabber:iq:roster"}->{Item}->{Add} = ["Data","__netjabber__:iq:roster:item","Item","item"]; $NAMESPACES{"jabber:iq:roster"}->{Items}->{Get} = ["__netjabber__:children:data","__netjabber__:iq:roster:item"]; $NAMESPACES{"jabber:iq:roster"}->{"__netjabber__"}->{Tag} = "query"; #----------------------------------------------------------------------------- # __netjabber__:iq:roster:item #----------------------------------------------------------------------------- $NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Get} = "ask"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Set} = ["scalar","ask"]; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Defined} = "ask"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Hash} = "att"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Get} = "group"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Set} = ["array","group"]; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Defined} = "group"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Hash} = "child-data"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Get} = "jid"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Set} = ["jid","jid"]; $NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Defined} = "jid"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Hash} = "att"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Get} = "name"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Set} = ["scalar","name"]; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Defined} = "name"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Hash} = "att"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Get} = "subscription"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Set} = ["scalar","subscription"]; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Defined} = "subscription"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Hash} = "att"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Item}->{Get} = "__netjabber__:master"; $NAMESPACES{"__netjabber__:iq:roster:item"}->{Item}->{Set} = ["master"]; #----------------------------------------------------------------------------- # jabber:x:offline #----------------------------------------------------------------------------- $NAMESPACES{"jabber:x:offline"}->{Data}->{Get} = "data"; $NAMESPACES{"jabber:x:offline"}->{Data}->{Set} = ["scalar","data"]; $NAMESPACES{"jabber:x:offline"}->{Data}->{Defined} = "data"; $NAMESPACES{"jabber:x:offline"}->{Data}->{Hash} = "data"; $NAMESPACES{"jabber:x:offline"}->{Offline}->{Get} = "__netjabber__:master"; $NAMESPACES{"jabber:x:offline"}->{Offline}->{Set} = ["master"]; $NAMESPACES{"jabber:x:offline"}->{"__netjabber__"}->{Tag} = "foo"; 1; Net-Jabber-2.0/lib/Net/Jabber/Log.pm0000644000175000017500000002170610110275744020167 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Jabber # Copyright (C) 1998-1999 The Jabber Team http://jabber.org/ # ############################################################################## package Net::Jabber::Log; =head1 NAME Net::Jabber::Log - Jabber Log Module =head1 SYNOPSIS Net::Jabber::Log is a companion to the Net::Jabber module. It provides the user a simple interface to set and retrieve all parts of a Jabber Log. =head1 DESCRIPTION To initialize the Log with a Jabber you must pass it the XML::Parser Tree array. For example: my $log = new Net::Jabber::Log(@tree); There has been a change from the old way of handling the callbacks. You no longer have to do the above, a Net::Jabber::Log object is passed to the callback function for the log: use Net::Jabber; sub log { my ($Log) = @_; . . . } You now have access to all of the retrieval functions available. To create a new log to send to the server: use Net::Jabber; $Log = new Net::Jabber::Log(); Now you can call the creation functions below to populate the tag before sending it. For more information about the array format being passed to the CallBack please read the Net::Jabber::Client documentation. =head2 Retrieval functions $from = $Log->GetFrom(); $fromJID = $Log->GetFrom("jid"); $type = $Log->GetType(); $data = $Log->GetData(); $str = $Log->GetXML(); @log = $Log->GetTree(); =head2 Creation functions $Log->SetLog(type=>"error", from=>"users.jabber.org", data=>"The moon is full... I can't run anymore."); $Log->SetFrom("foo.jabber.org"); $Log->SetType("warn"); $Log->SetData("I can't find a config file. Using defaults."); =head2 Test functions $test = $Log->DefinedFrom(); $test = $Log->DefinedType(); =head1 METHODS =head2 Retrieval functions GetFrom() - returns either a string with the Jabber Identifier, GetFrom("jid") or a Net::Jabber::JID object for the person who sent the . To get the JID object set the string to "jid", otherwise leave blank for the text string. GetType() - returns a string with the type this is. GetData() - returns a string with the cdata of the . GetXML() - returns the XML string that represents the . This is used by the Send() function in Client.pm to send this object as a Jabber Log. GetTree() - returns an array that contains the tag in XML::Parser Tree format. =head2 Creation functions SetLog(from=>string|JID, - set multiple fields in the type=>string, at one time. This is a cumulative data=>string) and over writing action. If you set the "from" attribute twice, the second setting is what is used. If you set the type, and then set the data then both will be in the tag. For valid settings read the specific Set functions below. SetFrom(string) - sets the from attribute. You can either pass a string SetFrom(JID) or a JID object. They must be valid Jabber Identifiers or the server will return an error log. (ie. jabber:bob@jabber.org/Silent Bob, etc...) SetType(string) - sets the type attribute. Valid settings are: notice general logging warn warning alert critical error (can still run but not correctly) error fatal error (cannot run anymore) SetData(string) - sets the cdata of the . =head2 Test functions DefinedFrom() - returns 1 if the from attribute is defined in the , 0 otherwise. DefinedType() - returns 1 if the type attribute is defined in the , 0 otherwise. =head1 AUTHOR By Ryan Eatmon in May of 2000 for http://jabber.org.. =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use vars qw($VERSION $AUTOLOAD %FUNCTIONS); $VERSION = "2.0"; sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = { }; $self->{VERSION} = $VERSION; $self->{TIMESTAMP} = &Net::Jabber::GetTimeStamp("local"); bless($self, $proto); $self->{DEBUG} = new Net::Jabber::Debug(usedefault=>1, header=>"NJ::Log"); if ("@_" ne ("")) { if (ref($_[0]) eq "Net::Jabber::Log") { return $_[0]; } else { my @temp = @_; $self->{LOG} = \@temp; } } else { $self->{LOG} = [ "log" , [{}]]; } return $self; } ############################################################################## # # AUTOLOAD - This function calls the delegate with the appropriate function # name and argument list. # ############################################################################## sub AUTOLOAD { my $self = shift; return if ($AUTOLOAD =~ /::DESTROY$/); $AUTOLOAD =~ s/^.*:://; my ($type,$value) = ($AUTOLOAD =~ /^(Get|Set|Defined)(.*)$/); $type = "" unless defined($type); my $treeName = "LOG"; return "log" if ($AUTOLOAD eq "GetTag"); return &XML::Stream::BuildXML(@{$self->{$treeName}}) if ($AUTOLOAD eq "GetXML"); return @{$self->{$treeName}} if ($AUTOLOAD eq "GetTree"); return &Net::Jabber::Get($self,$self,$value,$treeName,$FUNCTIONS{get}->{$value},@_) if ($type eq "Get"); return &Net::Jabber::Set($self,$self,$value,$treeName,$FUNCTIONS{set}->{$value},@_) if ($type eq "Set"); return &Net::Jabber::Defined($self,$self,$value,$treeName,$FUNCTIONS{defined}->{$value},@_) if ($type eq "Defined"); return &Net::Jabber::debug($self,$treeName) if ($AUTOLOAD eq "debug"); &Net::Jabber::MissingFunction($self,$AUTOLOAD); } $FUNCTIONS{get}->{From} = ["value","","from"]; $FUNCTIONS{get}->{Type} = ["value","","type"]; $FUNCTIONS{get}->{Data} = ["value","",""]; $FUNCTIONS{set}->{Type} = ["single","","","type","*"]; $FUNCTIONS{set}->{Data} = ["single","","*","",""]; $FUNCTIONS{defined}->{From} = ["existence","","from"]; $FUNCTIONS{defined}->{Type} = ["existence","","type"]; ############################################################################## # # GetXML - returns the XML string that represents the data in the XML::Parser # Tree. # ############################################################################## sub GetXML { my $self = shift; $self->MergeX(); return &XML::Stream::BuildXML(@{$self->{LOG}}); } ############################################################################## # # GetTree - returns the XML::Parser Tree that is stored in the guts of # the object. # ############################################################################## sub GetTree { my $self = shift; $self->MergeX(); return %{$self->{LOG}}; } ############################################################################## # # SetLog - takes a hash of all of the things you can set on a # and sets each one. # ############################################################################## sub SetLog { my $self = shift; my %log; while($#_ >= 0) { $log{ lc pop(@_) } = pop(@_); } $self->SetFrom($log{from}) if exists($log{from}); $self->SetType($log{type}) if exists($log{type}); $self->SetData($log{data}) if exists($log{data}); } ############################################################################## # # SetFrom - sets the from attribute in the # ############################################################################## sub SetFrom { my $self = shift; my ($from) = @_; if (ref($from) eq "Net::Jabber::JID") { $from = $from->GetJID("full"); } return unless ($from ne ""); &XML::Stream::SetXMLData("single",$self->{LOG},"","",{from=>$from}); } 1; Net-Jabber-2.0/lib/Net/Jabber/IQ.pm0000644000175000017500000000443110110275744017753 0ustar reatmonreatmon00000000000000############################################################################## # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/ # ############################################################################## package Net::Jabber::IQ; =head1 NAME Net::Jabber::IQ - Jabber Info/Query Library =head1 DESCRIPTION Net::Jabber::IQ inherits all of its methods from Net::XMPP::IQ. =head1 AUTHOR Ryan Eatmon =head1 COPYRIGHT This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut require 5.003; use strict; use Carp; use Net::XMPP::IQ; use base qw( Net::XMPP::IQ ); use vars qw( $VERSION ); $VERSION = "2.0"; sub GetQuery { my $self = shift; $self->GetChild(@_); } sub DefinedQuery { my $self = shift; $self->DefinedChild(@_); } sub NewQuery { my $self = shift; $self->RemoveFirstChild(); $self->NewFirstChild(@_); } sub AddQuery { my $self = shift; $self->AddChild(@_); } sub RemoveQuery { my $self = shift; $self->RemoveFirstChild(@_); } sub GetX { my $self = shift; $self->GetChild(@_); } sub DefinedX { my $self = shift; $self->DefinedChild(@_); } sub NewX { my $self = shift; $self->NewChild(@_); } sub AddX { my $self = shift; $self->AddChild(@_); } sub RemoveX { my $self = shift; $self->RemoveChild(@_); } sub _new_jid { my $self = shift; return new Net::Jabber::JID(@_); } sub _new_packet { my $self = shift; return new Net::Jabber::Stanza(@_); } sub _iq { my $self = shift; return new Net::Jabber::IQ(@_); } 1; Net-Jabber-2.0/t/0002755000175000017500000000000010112242737014664 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/t/query_oob.t0000644000175000017500000000170010110275744017053 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>25; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:oob"); testScalar($query,"Desc","desc"); testScalar($query,"URL","url"); is( $query->GetXML(), "descurl", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:oob"); $query2->SetOob(desc=>"desc", url=>"url" ); testPostScalar($query2,"Desc","desc"); testPostScalar($query2,"URL","url"); is( $query2->GetXML(), "descurl", "GetXML()" ); Net-Jabber-2.0/t/query_si_filetrans.t0000644000175000017500000001041710110275744020763 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>100; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("si"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/si"); testScalar($query,"Profile","http://jabber.org/protocol/si/profile/file-transfer"); my $prof = $query->NewChild("http://jabber.org/protocol/si/profile/file-transfer"); testScalar($prof,"Date","date"); testScalar($prof,"Desc","desc"); testScalar($prof,"Hash","hash"); testScalar($prof,"Name","name"); testScalar($prof,"RangeLength","length"); testScalar($prof,"RangeOffset","offest"); testScalar($prof,"Size","size"); is( $query->GetXML(), "desc", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("si"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/si"); testScalar($query2,"Profile","http://jabber.org/protocol/si/profile/file-transfer"); my $prof2 = $query2->NewChild("http://jabber.org/protocol/si/profile/file-transfer"); testScalar($prof2,"Date","date"); testScalar($prof2,"Hash","hash"); testScalar($prof2,"Name","name"); testFlag($prof2,"Range"); testScalar($prof2,"Size","size"); is( $query2->GetXML(), "", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("si"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/si"); $query3->SetStream(profile=>"http://jabber.org/protocol/si/profile/file-transfer"); testPostScalar($query3,"Profile","http://jabber.org/protocol/si/profile/file-transfer"); my $prof3 = $query3->NewChild("http://jabber.org/protocol/si/profile/file-transfer"); $prof3->SetFile(date=>"date", desc=>"desc", hash=>"hash", name=>"name", rangelength=>"length", rangeoffset=>"offset", size=>"size" ); testPostScalar($prof3,"Date","date"); testPostScalar($prof3,"Desc","desc"); testPostScalar($prof3,"Hash","hash"); testPostScalar($prof3,"Name","name"); testPostScalar($prof3,"RangeLength","length"); testPostScalar($prof3,"RangeOffset","offset"); testPostScalar($prof3,"Size","size"); is( $query3->GetXML(), "desc", "GetXML()" ); my $query4 = new Net::Jabber::Stanza("si"); ok( defined($query4), "new()" ); isa_ok( $query4, "Net::Jabber::Stanza" ); isa_ok( $query4, "Net::XMPP::Stanza" ); testScalar($query4,"XMLNS","http://jabber.org/protocol/si"); $query4->SetStream(profile=>"http://jabber.org/protocol/si/profile/file-transfer"); testPostScalar($query4,"Profile","http://jabber.org/protocol/si/profile/file-transfer"); my $prof4 = $query4->NewChild("http://jabber.org/protocol/si/profile/file-transfer"); $prof4->SetFile(date=>"date", hash=>"hash", name=>"name", range=>1, size=>"size" ); testPostScalar($prof4,"Date","date"); testPostScalar($prof4,"Hash","hash"); testPostScalar($prof4,"Name","name"); testPostFlag($prof4,"Range"); testPostScalar($prof4,"Size","size"); is( $query4->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/query_gateway.t0000644000175000017500000000235210110275744017741 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>42; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:gateway"); testJID($query,"JID","user1","server1","resource1"); testScalar($query,"Desc","desc"); testScalar($query,"Prompt","prompt"); is( $query->GetXML(), "user1\@server1/resource1descprompt", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:gateway"); $query2->SetGateway(jid=>"user2\@server2/resource2", desc=>"desc", prompt=>"prompt" ); testPostJID($query2,"JID","user2","server2","resource2"); testPostScalar($query2,"Desc","desc"); testPostScalar($query2,"Prompt","prompt"); is( $query2->GetXML(), "descuser2\@server2/resource2prompt", "GetXML()" ); Net-Jabber-2.0/t/query_search.t0000644000175000017500000001205210110275744017543 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>140; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:search"); testScalar($query,"Email","email"); testScalar($query,"Family","family"); testScalar($query,"First","first"); testScalar($query,"Given","given"); testScalar($query,"Instructions","instructions"); testScalar($query,"Key","key"); testScalar($query,"Last","last"); testScalar($query,"Name","name"); testScalar($query,"Nick","nick"); testFlag($query,"Truncated"); is( $query->GetXML(), "emailfamilyfirstgiveninstructionskeylastnamenick", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:search"); $query2->SetSearch(email=>"email", family=>"family", first=>"first", given=>"given", instructions=>"instructions", key=>"key", last=>"last", name=>"name", nick=>"nick", truncated=>1, ); testPostScalar($query2,"Email","email"); testPostScalar($query2,"Family","family"); testPostScalar($query2,"First","first"); testPostScalar($query2,"Given","given"); testPostScalar($query2,"Instructions","instructions"); testPostScalar($query2,"Key","key"); testPostScalar($query2,"Last","last"); testPostScalar($query2,"Name","name"); testPostScalar($query2,"Nick","nick"); testPostFlag($query2,"Truncated"); is( $query2->GetXML(), "emailfamilyfirstgiveninstructionskeylastnamenick", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("query"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","jabber:iq:search"); my $item1 = $query3->AddItem(); ok( defined($item1), "new()" ); isa_ok( $item1, "Net::Jabber::Stanza" ); isa_ok( $item1, "Net::XMPP::Stanza" ); testScalar($item1,"Email","email"); testScalar($item1,"Family","family"); testScalar($item1,"First","first"); testScalar($item1,"Given","given"); testJID($item1,"JID","user1","server1","resource1"); testScalar($item1,"Key","key"); testScalar($item1,"Last","last"); testScalar($item1,"Name","name"); testScalar($item1,"Nick","nick"); is( $query3->GetXML(), "emailfamilyfirstgivenkeylastnamenick", "GetXML()" ); my $item2 = $query3->AddItem(email=>"email", family=>"family", first=>"first", given=>"given", jid=>"user2\@server2/resource2", key=>"key", last=>"last", name=>"name", nick=>"nick", ); ok( defined($item2), "new()" ); isa_ok( $item2, "Net::Jabber::Stanza" ); isa_ok( $item2, "Net::XMPP::Stanza" ); testPostScalar($item2,"Email","email"); testPostScalar($item2,"Family","family"); testPostScalar($item2,"First","first"); testPostScalar($item2,"Given","given"); testPostJID($item2,"JID","user2","server2","resource2"); testPostScalar($item2,"Key","key"); testPostScalar($item2,"Last","last"); testPostScalar($item2,"Name","name"); testPostScalar($item2,"Nick","nick"); is( $query3->GetXML(), "emailfamilyfirstgivenkeylastnamenickemailfamilyfirstgivenkeylastnamenick", "GetXML()" ); my @items = $query3->GetItems(); is( $#items, 1, "are there two items?" ); is( $items[0]->GetXML(), "emailfamilyfirstgivenkeylastnamenick", "GetXML()" ); is( $items[1]->GetXML(), "emailfamilyfirstgivenkeylastnamenick", "GetXML()" ); Net-Jabber-2.0/t/query_conference.t0000644000175000017500000000257110110275744020412 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>41; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:conference"); testScalar($query,"ID","id"); testScalar($query,"Name","name"); testScalar($query,"Nick","nick"); testFlag($query,"Privacy"); testScalar($query,"Secret","secret"); is( $query->GetXML(), "idnamenicksecret", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:conference"); $query2->SetConference(id=>"id", name=>"name", nick=>"nick", privacy=>1, secret=>"secret"); testPostScalar($query2,"ID","id"); testPostScalar($query2,"Name","name"); testPostScalar($query2,"Nick","nick"); testPostFlag($query2,"Privacy"); testPostScalar($query2,"Secret","secret"); is( $query2->GetXML(), "idnamenicksecret", "GetXML()" ); Net-Jabber-2.0/t/query_agents.t0000644000175000017500000000304110110275744017555 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>20; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:agents"); my $agent = $query->AddAgent(); ok( defined($agent), "AddAgent()"); isa_ok($agent, "Net::Jabber::Stanza"); isa_ok($agent, "Net::XMPP::Stanza"); is( $agent->GetXMLNS(), "jabber:iq:agent", "xmlns = 'jabber:iq:agent'"); $agent->SetAgent(jid=>"user1\@server1/resource1", name=>"name1"); is( $query->GetXML(), "name1", "GetXML()" ); my $agent2 = $query->AddAgent(jid=>"user2\@server2/resource2", name=>"name2"); ok( defined($agent2), "AddAgent()"); isa_ok($agent2, "Net::Jabber::Stanza"); isa_ok($agent2, "Net::XMPP::Stanza"); is( $agent2->GetXMLNS(), "jabber:iq:agent", "xmlns = 'jabber:iq:agent'"); is( $query->GetXML(), "name1name2", "GetXML()" ); my @agents = $query->GetAgents(); is( $#agents, 1, "two agents?"); is( $agents[0]->GetXML(), "name1", "agent GetXML()" ); is( $agents[1]->GetXML(), "name2", "agent GetXML()" ); Net-Jabber-2.0/t/query_rpc.t0000644000175000017500000002054010110275744017063 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>217; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:rpc"); my $methodCall = $query->AddMethodCall(); ok( defined($methodCall), "new()" ); isa_ok( $methodCall, "Net::Jabber::Stanza" ); isa_ok( $methodCall, "Net::XMPP::Stanza" ); ok( $query->DefinedMethodCall(), "DefinedMethodCall()" ); testScalar($methodCall, "MethodName", "method_name"); my $params = $methodCall->AddParams(); ok( defined($params), "new()" ); isa_ok( $params, "Net::Jabber::Stanza" ); isa_ok( $params, "Net::XMPP::Stanza" ); my $param1 = $params->AddParam(); ok( defined($param1), "new()" ); isa_ok( $param1, "Net::Jabber::Stanza" ); isa_ok( $param1, "Net::XMPP::Stanza" ); my $value1_1 = $param1->AddValue(); ok( defined($value1_1), "new()" ); isa_ok( $value1_1, "Net::Jabber::Stanza" ); isa_ok( $value1_1, "Net::XMPP::Stanza" ); testScalar($value1_1, "Base64", "value"); testScalar($value1_1, "Boolean", "value"); testScalar($value1_1, "DateTime", "value"); testScalar($value1_1, "Double", "value"); testScalar($value1_1, "I4", "value"); testScalar($value1_1, "Int", "value"); testScalar($value1_1, "String", "value"); testScalar($value1_1, "Value", "value"); my $struct1 = $value1_1->AddStruct(); my $member1 = $struct1->AddMember(); ok( defined($member1), "new()" ); isa_ok( $member1, "Net::Jabber::Stanza" ); isa_ok( $member1, "Net::XMPP::Stanza" ); testScalar($member1, "Name", "name"); my $member1_value1 = $member1->AddValue(); ok( defined($member1_value1), "new()" ); isa_ok( $member1_value1, "Net::Jabber::Stanza" ); isa_ok( $member1_value1, "Net::XMPP::Stanza" ); testScalar($member1_value1, "Base64", "base64"); testScalar($member1_value1, "Boolean", "boolean"); testScalar($member1_value1, "DateTime", "datetime"); testScalar($member1_value1, "Double", "double"); testScalar($member1_value1, "I4", "i4"); testScalar($member1_value1, "Int", "int"); testScalar($member1_value1, "String", "string"); testScalar($member1_value1, "Value", "value"); my $array1 = $value1_1->AddArray(); my $data1 = $array1->AddData(); ok( defined($data1), "new()" ); isa_ok( $data1, "Net::Jabber::Stanza" ); isa_ok( $data1, "Net::XMPP::Stanza" ); my $data1_value1 = $data1->AddValue(); ok( defined($data1_value1), "new()" ); isa_ok( $data1_value1, "Net::Jabber::Stanza" ); isa_ok( $data1_value1, "Net::XMPP::Stanza" ); testScalar($data1_value1, "Base64", "base64"); testScalar($data1_value1, "Boolean", "boolean"); testScalar($data1_value1, "DateTime", "datetime"); testScalar($data1_value1, "Double", "double"); testScalar($data1_value1, "I4", "i4"); testScalar($data1_value1, "Int", "int"); testScalar($data1_value1, "String", "string"); testScalar($data1_value1, "Value", "value"); is( $query->GetXML(), "method_namevaluevaluevaluevaluevaluevaluevaluevaluenamebase64booleandatetimedoublei4intstringvaluebase64booleandatetimedoublei4intstringvalue", "GetXML()" ); my $methodResponse = $query->AddMethodResponse(); ok( defined($methodResponse), "new()" ); isa_ok( $methodResponse, "Net::Jabber::Stanza" ); isa_ok( $methodResponse, "Net::XMPP::Stanza" ); my $params2 = $methodResponse->AddParams(); ok( defined($params2), "new()" ); isa_ok( $params2, "Net::Jabber::Stanza" ); isa_ok( $params2, "Net::XMPP::Stanza" ); my $param2 = $params2->AddParam(); ok( defined($param2), "new()" ); isa_ok( $param2, "Net::Jabber::Stanza" ); isa_ok( $param2, "Net::XMPP::Stanza" ); my $value2_1 = $param2->AddValue(); ok( defined($value2_1), "new()" ); isa_ok( $value2_1, "Net::Jabber::Stanza" ); isa_ok( $value2_1, "Net::XMPP::Stanza" ); testScalar($value2_1, "Base64", "value"); testScalar($value2_1, "Boolean", "value"); testScalar($value2_1, "DateTime", "value"); testScalar($value2_1, "Double", "value"); testScalar($value2_1, "I4", "value"); testScalar($value2_1, "Int", "value"); testScalar($value2_1, "String", "value"); testScalar($value2_1, "Value", "value"); my $struct2 = $value2_1->AddStruct(); my $member2 = $struct2->AddMember(); ok( defined($member2), "new()" ); isa_ok( $member2, "Net::Jabber::Stanza" ); isa_ok( $member2, "Net::XMPP::Stanza" ); testScalar($member2, "Name", "name"); my $member2_value1 = $member2->AddValue(); ok( defined($member2_value1), "new()" ); isa_ok( $member2_value1, "Net::Jabber::Stanza" ); isa_ok( $member2_value1, "Net::XMPP::Stanza" ); testScalar($member2_value1, "Base64", "base64"); testScalar($member2_value1, "Boolean", "boolean"); testScalar($member2_value1, "DateTime", "datetime"); testScalar($member2_value1, "Double", "double"); testScalar($member2_value1, "I4", "i4"); testScalar($member2_value1, "Int", "int"); testScalar($member2_value1, "String", "string"); testScalar($member2_value1, "Value", "value"); my $array2 = $value2_1->AddArray(); my $data2 = $array2->AddData(); ok( defined($data2), "new()" ); isa_ok( $data2, "Net::Jabber::Stanza" ); isa_ok( $data2, "Net::XMPP::Stanza" ); my $data2_value1 = $data2->AddValue(); ok( defined($data2_value1), "new()" ); isa_ok( $data2_value1, "Net::Jabber::Stanza" ); isa_ok( $data2_value1, "Net::XMPP::Stanza" ); testScalar($data2_value1, "Base64", "base64"); testScalar($data2_value1, "Boolean", "boolean"); testScalar($data2_value1, "DateTime", "datetime"); testScalar($data2_value1, "Double", "double"); testScalar($data2_value1, "I4", "i4"); testScalar($data2_value1, "Int", "int"); testScalar($data2_value1, "String", "string"); testScalar($data2_value1, "Value", "value"); my $fault1 = $methodResponse->AddFault(); ok( defined($fault1), "new()" ); isa_ok( $fault1, "Net::Jabber::Stanza" ); isa_ok( $fault1, "Net::XMPP::Stanza" ); my $faultStruct = $fault1->AddValue()->AddStruct(); ok( defined($faultStruct), "new()" ); isa_ok( $faultStruct, "Net::Jabber::Stanza" ); isa_ok( $faultStruct, "Net::XMPP::Stanza" ); $faultStruct->AddMember(name=>"faultCode")->AddValue(i4=>404); $faultStruct->AddMember(name=>"faultString")->AddValue(string=>"not found"); is( $query->GetXML(), "method_namevaluevaluevaluevaluevaluevaluevaluevaluenamebase64booleandatetimedoublei4intstringvaluebase64booleandatetimedoublei4intstringvaluevaluevaluevaluevaluevaluevaluevaluevaluenamebase64booleandatetimedoublei4intstringvaluebase64booleandatetimedoublei4intstringvaluefaultCode404faultStringnot found", "GetXML()" ); Net-Jabber-2.0/t/lib/0002755000175000017500000000000010112242736015431 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/t/lib/Test/0002755000175000017500000000000010112242737016351 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/t/lib/Test/Simple.pm0000644000175000017500000001456510110275744020153 0ustar reatmonreatmon00000000000000package Test::Simple; use 5.004; use strict 'vars'; use vars qw($VERSION); $VERSION = '0.47'; use Test::Builder; my $Test = Test::Builder->new; sub import { my $self = shift; my $caller = caller; *{$caller.'::ok'} = \&ok; $Test->exported_to($caller); $Test->plan(@_); } =head1 NAME Test::Simple - Basic utilities for writing tests. =head1 SYNOPSIS use Test::Simple tests => 1; ok( $foo eq $bar, 'foo is bar' ); =head1 DESCRIPTION ** If you are unfamiliar with testing B first! ** This is an extremely simple, extremely basic module for writing tests suitable for CPAN modules and other pursuits. If you wish to do more complicated testing, use the Test::More module (a drop-in replacement for this one). The basic unit of Perl testing is the ok. For each thing you want to test your program will print out an "ok" or "not ok" to indicate pass or fail. You do this with the ok() function (see below). The only other constraint is you must pre-declare how many tests you plan to run. This is in case something goes horribly wrong during the test and your test program aborts, or skips a test or whatever. You do this like so: use Test::Simple tests => 23; You must have a plan. =over 4 =item B ok( $foo eq $bar, $name ); ok( $foo eq $bar ); ok() is given an expression (in this case C<$foo eq $bar>). If it's true, the test passed. If it's false, it didn't. That's about it. ok() prints out either "ok" or "not ok" along with a test number (it keeps track of that for you). # This produces "ok 1 - Hell not yet frozen over" (or not ok) ok( get_temperature($hell) > 0, 'Hell not yet frozen over' ); If you provide a $name, that will be printed along with the "ok/not ok" to make it easier to find your test when if fails (just search for the name). It also makes it easier for the next guy to understand what your test is for. It's highly recommended you use test names. All tests are run in scalar context. So this: ok( @stuff, 'I have some stuff' ); will do what you mean (fail if stuff is empty) =cut sub ok ($;$) { $Test->ok(@_); } =back Test::Simple will start by printing number of tests run in the form "1..M" (so "1..5" means you're going to run 5 tests). This strange format lets Test::Harness know how many tests you plan on running in case something goes horribly wrong. If all your tests passed, Test::Simple will exit with zero (which is normal). If anything failed it will exit with how many failed. If you run less (or more) tests than you planned, the missing (or extras) will be considered failures. If no tests were ever run Test::Simple will throw a warning and exit with 255. If the test died, even after having successfully completed all its tests, it will still be considered a failure and will exit with 255. So the exit codes are... 0 all tests successful 255 test died any other number how many failed (including missing or extras) If you fail more than 254 tests, it will be reported as 254. This module is by no means trying to be a complete testing system. It's just to get you started. Once you're off the ground its recommended you look at L. =head1 EXAMPLE Here's an example of a simple .t file for the fictional Film module. use Test::Simple tests => 5; use Film; # What you're testing. my $btaste = Film->new({ Title => 'Bad Taste', Director => 'Peter Jackson', Rating => 'R', NumExplodingSheep => 1 }); ok( defined($btaste) and ref $btaste eq 'Film', 'new() works' ); ok( $btaste->Title eq 'Bad Taste', 'Title() get' ); ok( $btaste->Director eq 'Peter Jackson', 'Director() get' ); ok( $btaste->Rating eq 'R', 'Rating() get' ); ok( $btaste->NumExplodingSheep == 1, 'NumExplodingSheep() get' ); It will produce output like this: 1..5 ok 1 - new() works ok 2 - Title() get ok 3 - Director() get not ok 4 - Rating() get # Failed test (t/film.t at line 14) ok 5 - NumExplodingSheep() get # Looks like you failed 1 tests of 5 Indicating the Film::Rating() method is broken. =head1 CAVEATS Test::Simple will only report a maximum of 254 failures in its exit code. If this is a problem, you probably have a huge test script. Split it into multiple files. (Otherwise blame the Unix folks for using an unsigned short integer as the exit status). Because VMS's exit codes are much, much different than the rest of the universe, and perl does horrible mangling to them that gets in my way, it works like this on VMS. 0 SS$_NORMAL all tests successful 4 SS$_ABORT something went wrong Unfortunately, I can't differentiate any further. =head1 NOTES Test::Simple is B tested all the way back to perl 5.004. Test::Simple is thread-safe in perl 5.8.0 and up. =head1 HISTORY This module was conceived while talking with Tony Bowden in his kitchen one night about the problems I was having writing some really complicated feature into the new Testing module. He observed that the main problem is not dealing with these edge cases but that people hate to write tests B. What was needed was a dead simple module that took all the hard work out of testing and was really, really easy to learn. Paul Johnson simultaneously had this idea (unfortunately, he wasn't in Tony's kitchen). This is it. =head1 SEE ALSO =over 4 =item L More testing functions! Once you outgrow Test::Simple, look at Test::More. Test::Simple is 100% forward compatible with Test::More (i.e. you can just use Test::More instead of Test::Simple in your programs and things will still work). =item L The original Perl testing module. =item L Elaborate unit testing. =item L, L Embed tests in your code! =item L Interprets the output of your test program. =back =head1 AUTHORS Idea by Tony Bowden and Paul Johnson, code by Michael G Schwern Eschwern@pobox.comE, wardrobe by Calvin Klein. =head1 COPYRIGHT Copyright 2001 by Michael G Schwern Eschwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F =cut 1; Net-Jabber-2.0/t/lib/Test/Builder.pm0000644000175000017500000007377310110275744020316 0ustar reatmonreatmon00000000000000package Test::Builder; use 5.004; # $^C was only introduced in 5.005-ish. We do this to prevent # use of uninitialized value warnings in older perls. $^C ||= 0; use strict; use vars qw($VERSION $CLASS); $VERSION = '0.17'; $CLASS = __PACKAGE__; my $IsVMS = $^O eq 'VMS'; # Make Test::Builder thread-safe for ithreads. BEGIN { use Config; if( $] >= 5.008 && $Config{useithreads} ) { require threads; require threads::shared; threads::shared->import; } else { *share = sub { 0 }; *lock = sub { 0 }; } } use vars qw($Level); my($Test_Died) = 0; my($Have_Plan) = 0; my $Original_Pid = $$; my $Curr_Test = 0; share($Curr_Test); my @Test_Results = (); share(@Test_Results); my @Test_Details = (); share(@Test_Details); =head1 NAME Test::Builder - Backend for building test libraries =head1 SYNOPSIS package My::Test::Module; use Test::Builder; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(ok); my $Test = Test::Builder->new; $Test->output('my_logfile'); sub import { my($self) = shift; my $pack = caller; $Test->exported_to($pack); $Test->plan(@_); $self->export_to_level(1, $self, 'ok'); } sub ok { my($test, $name) = @_; $Test->ok($test, $name); } =head1 DESCRIPTION Test::Simple and Test::More have proven to be popular testing modules, but they're not always flexible enough. Test::Builder provides the a building block upon which to write your own test libraries I. =head2 Construction =over 4 =item B my $Test = Test::Builder->new; Returns a Test::Builder object representing the current state of the test. Since you only run one test per program, there is B Test::Builder object. No matter how many times you call new(), you're getting the same object. (This is called a singleton). =cut my $Test; sub new { my($class) = shift; $Test ||= bless ['Move along, nothing to see here'], $class; return $Test; } =back =head2 Setting up tests These methods are for setting up tests and declaring how many there are. You usually only want to call one of these methods. =over 4 =item B my $pack = $Test->exported_to; $Test->exported_to($pack); Tells Test::Builder what package you exported your functions to. This is important for getting TODO tests right. =cut my $Exported_To; sub exported_to { my($self, $pack) = @_; if( defined $pack ) { $Exported_To = $pack; } return $Exported_To; } =item B $Test->plan('no_plan'); $Test->plan( skip_all => $reason ); $Test->plan( tests => $num_tests ); A convenient way to set up your tests. Call this and Test::Builder will print the appropriate headers and take the appropriate actions. If you call plan(), don't call any of the other methods below. =cut sub plan { my($self, $cmd, $arg) = @_; return unless $cmd; if( $Have_Plan ) { die sprintf "You tried to plan twice! Second plan at %s line %d\n", ($self->caller)[1,2]; } if( $cmd eq 'no_plan' ) { $self->no_plan; } elsif( $cmd eq 'skip_all' ) { return $self->skip_all($arg); } elsif( $cmd eq 'tests' ) { if( $arg ) { return $self->expected_tests($arg); } elsif( !defined $arg ) { die "Got an undefined number of tests. Looks like you tried to ". "say how many tests you plan to run but made a mistake.\n"; } elsif( !$arg ) { die "You said to run 0 tests! You've got to run something.\n"; } } else { require Carp; my @args = grep { defined } ($cmd, $arg); Carp::croak("plan() doesn't understand @args"); } return 1; } =item B my $max = $Test->expected_tests; $Test->expected_tests($max); Gets/sets the # of tests we expect this test to run and prints out the appropriate headers. =cut my $Expected_Tests = 0; sub expected_tests { my($self, $max) = @_; if( defined $max ) { $Expected_Tests = $max; $Have_Plan = 1; $self->_print("1..$max\n") unless $self->no_header; } return $Expected_Tests; } =item B $Test->no_plan; Declares that this test will run an indeterminate # of tests. =cut my($No_Plan) = 0; sub no_plan { $No_Plan = 1; $Have_Plan = 1; } =item B $plan = $Test->has_plan Find out whether a plan has been defined. $plan is either C (no plan has been set), C (indeterminate # of tests) or an integer (the number of expected tests). =cut sub has_plan { return($Expected_Tests) if $Expected_Tests; return('no_plan') if $No_Plan; return(undef); }; =item B $Test->skip_all; $Test->skip_all($reason); Skips all the tests, using the given $reason. Exits immediately with 0. =cut my $Skip_All = 0; sub skip_all { my($self, $reason) = @_; my $out = "1..0"; $out .= " # Skip $reason" if $reason; $out .= "\n"; $Skip_All = 1; $self->_print($out) unless $self->no_header; exit(0); } =back =head2 Running tests These actually run the tests, analogous to the functions in Test::More. $name is always optional. =over 4 =item B $Test->ok($test, $name); Your basic test. Pass if $test is true, fail if $test is false. Just like Test::Simple's ok(). =cut sub ok { my($self, $test, $name) = @_; # $test might contain an object which we don't want to accidentally # store, so we turn it into a boolean. $test = $test ? 1 : 0; unless( $Have_Plan ) { require Carp; Carp::croak("You tried to run a test without a plan! Gotta have a plan."); } lock $Curr_Test; $Curr_Test++; $self->diag(<caller; my $todo = $self->todo($pack); my $out; my $result = {}; share($result); unless( $test ) { $out .= "not "; @$result{ 'ok', 'actual_ok' } = ( ( $todo ? 1 : 0 ), 0 ); } else { @$result{ 'ok', 'actual_ok' } = ( 1, $test ); } $out .= "ok"; $out .= " $Curr_Test" if $self->use_numbers; if( defined $name ) { $name =~ s|#|\\#|g; # # in a name can confuse Test::Harness. $out .= " - $name"; $result->{name} = $name; } else { $result->{name} = ''; } if( $todo ) { my $what_todo = $todo; $out .= " # TODO $what_todo"; $result->{reason} = $what_todo; $result->{type} = 'todo'; } else { $result->{reason} = ''; $result->{type} = ''; } $Test_Results[$Curr_Test-1] = $result; $out .= "\n"; $self->_print($out); unless( $test ) { my $msg = $todo ? "Failed (TODO)" : "Failed"; $self->diag(" $msg test ($file at line $line)\n"); } return $test ? 1 : 0; } =item B $Test->is_eq($got, $expected, $name); Like Test::More's is(). Checks if $got eq $expected. This is the string version. =item B $Test->is_num($got, $expected, $name); Like Test::More's is(). Checks if $got == $expected. This is the numeric version. =cut sub is_eq { my($self, $got, $expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $expect ) { # undef only matches undef and nothing else my $test = !defined $got && !defined $expect; $self->ok($test, $name); $self->_is_diag($got, 'eq', $expect) unless $test; return $test; } return $self->cmp_ok($got, 'eq', $expect, $name); } sub is_num { my($self, $got, $expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $expect ) { # undef only matches undef and nothing else my $test = !defined $got && !defined $expect; $self->ok($test, $name); $self->_is_diag($got, '==', $expect) unless $test; return $test; } return $self->cmp_ok($got, '==', $expect, $name); } sub _is_diag { my($self, $got, $type, $expect) = @_; foreach my $val (\$got, \$expect) { if( defined $$val ) { if( $type eq 'eq' ) { # quote and force string context $$val = "'$$val'" } else { # force numeric context $$val = $$val+0; } } else { $$val = 'undef'; } } return $self->diag(sprintf < $Test->isnt_eq($got, $dont_expect, $name); Like Test::More's isnt(). Checks if $got ne $dont_expect. This is the string version. =item B $Test->is_num($got, $dont_expect, $name); Like Test::More's isnt(). Checks if $got ne $dont_expect. This is the numeric version. =cut sub isnt_eq { my($self, $got, $dont_expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $dont_expect ) { # undef only matches undef and nothing else my $test = defined $got || defined $dont_expect; $self->ok($test, $name); $self->_cmp_diag('ne', $got, $dont_expect) unless $test; return $test; } return $self->cmp_ok($got, 'ne', $dont_expect, $name); } sub isnt_num { my($self, $got, $dont_expect, $name) = @_; local $Level = $Level + 1; if( !defined $got || !defined $dont_expect ) { # undef only matches undef and nothing else my $test = defined $got || defined $dont_expect; $self->ok($test, $name); $self->_cmp_diag('!=', $got, $dont_expect) unless $test; return $test; } return $self->cmp_ok($got, '!=', $dont_expect, $name); } =item B $Test->like($this, qr/$regex/, $name); $Test->like($this, '/$regex/', $name); Like Test::More's like(). Checks if $this matches the given $regex. You'll want to avoid qr// if you want your tests to work before 5.005. =item B $Test->unlike($this, qr/$regex/, $name); $Test->unlike($this, '/$regex/', $name); Like Test::More's unlike(). Checks if $this B the given $regex. =cut sub like { my($self, $this, $regex, $name) = @_; local $Level = $Level + 1; $self->_regex_ok($this, $regex, '=~', $name); } sub unlike { my($self, $this, $regex, $name) = @_; local $Level = $Level + 1; $self->_regex_ok($this, $regex, '!~', $name); } =item B $Test->maybe_regex(qr/$regex/); $Test->maybe_regex('/$regex/'); Convenience method for building testing functions that take regular expressions as arguments, but need to work before perl 5.005. Takes a quoted regular expression produced by qr//, or a string representing a regular expression. Returns a Perl value which may be used instead of the corresponding regular expression, or undef if it's argument is not recognised. For example, a version of like(), sans the useful diagnostic messages, could be written as: sub laconic_like { my ($self, $this, $regex, $name) = @_; my $usable_regex = $self->maybe_regex($regex); die "expecting regex, found '$regex'\n" unless $usable_regex; $self->ok($this =~ m/$usable_regex/, $name); } =cut sub maybe_regex { my ($self, $regex) = @_; my $usable_regex = undef; if( ref $regex eq 'Regexp' ) { $usable_regex = $regex; } # Check if it looks like '/foo/' elsif( my($re, $opts) = $regex =~ m{^ /(.*)/ (\w*) $ }sx ) { $usable_regex = length $opts ? "(?$opts)$re" : $re; }; return($usable_regex) }; sub _regex_ok { my($self, $this, $regex, $cmp, $name) = @_; local $Level = $Level + 1; my $ok = 0; my $usable_regex = $self->maybe_regex($regex); unless (defined $usable_regex) { $ok = $self->ok( 0, $name ); $self->diag(" '$regex' doesn't look much like a regex to me."); return $ok; } { local $^W = 0; my $test = $this =~ /$usable_regex/ ? 1 : 0; $test = !$test if $cmp eq '!~'; $ok = $self->ok( $test, $name ); } unless( $ok ) { $this = defined $this ? "'$this'" : 'undef'; my $match = $cmp eq '=~' ? "doesn't match" : "matches"; $self->diag(sprintf < $Test->cmp_ok($this, $type, $that, $name); Works just like Test::More's cmp_ok(). $Test->cmp_ok($big_num, '!=', $other_big_num); =cut sub cmp_ok { my($self, $got, $type, $expect, $name) = @_; my $test; { local $^W = 0; local($@,$!); # don't interfere with $@ # eval() sometimes resets $! $test = eval "\$got $type \$expect"; } local $Level = $Level + 1; my $ok = $self->ok($test, $name); unless( $ok ) { if( $type =~ /^(eq|==)$/ ) { $self->_is_diag($got, $type, $expect); } else { $self->_cmp_diag($got, $type, $expect); } } return $ok; } sub _cmp_diag { my($self, $got, $type, $expect) = @_; $got = defined $got ? "'$got'" : 'undef'; $expect = defined $expect ? "'$expect'" : 'undef'; return $self->diag(sprintf < $Test->BAILOUT($reason); Indicates to the Test::Harness that things are going so badly all testing should terminate. This includes running any additional test scripts. It will exit with 255. =cut sub BAILOUT { my($self, $reason) = @_; $self->_print("Bail out! $reason"); exit 255; } =item B $Test->skip; $Test->skip($why); Skips the current test, reporting $why. =cut sub skip { my($self, $why) = @_; $why ||= ''; unless( $Have_Plan ) { require Carp; Carp::croak("You tried to run tests without a plan! Gotta have a plan."); } lock($Curr_Test); $Curr_Test++; my %result; share(%result); %result = ( 'ok' => 1, actual_ok => 1, name => '', type => 'skip', reason => $why, ); $Test_Results[$Curr_Test-1] = \%result; my $out = "ok"; $out .= " $Curr_Test" if $self->use_numbers; $out .= " # skip $why\n"; $Test->_print($out); return 1; } =item B $Test->todo_skip; $Test->todo_skip($why); Like skip(), only it will declare the test as failing and TODO. Similar to print "not ok $tnum # TODO $why\n"; =cut sub todo_skip { my($self, $why) = @_; $why ||= ''; unless( $Have_Plan ) { require Carp; Carp::croak("You tried to run tests without a plan! Gotta have a plan."); } lock($Curr_Test); $Curr_Test++; my %result; share(%result); %result = ( 'ok' => 1, actual_ok => 0, name => '', type => 'todo_skip', reason => $why, ); $Test_Results[$Curr_Test-1] = \%result; my $out = "not ok"; $out .= " $Curr_Test" if $self->use_numbers; $out .= " # TODO & SKIP $why\n"; $Test->_print($out); return 1; } =begin _unimplemented =item B $Test->skip_rest; $Test->skip_rest($reason); Like skip(), only it skips all the rest of the tests you plan to run and terminates the test. If you're running under no_plan, it skips once and terminates the test. =end _unimplemented =back =head2 Test style =over 4 =item B $Test->level($how_high); How far up the call stack should $Test look when reporting where the test failed. Defaults to 1. Setting $Test::Builder::Level overrides. This is typically useful localized: { local $Test::Builder::Level = 2; $Test->ok($test); } =cut sub level { my($self, $level) = @_; if( defined $level ) { $Level = $level; } return $Level; } $CLASS->level(1); =item B $Test->use_numbers($on_or_off); Whether or not the test should output numbers. That is, this if true: ok 1 ok 2 ok 3 or this if false ok ok ok Most useful when you can't depend on the test output order, such as when threads or forking is involved. Test::Harness will accept either, but avoid mixing the two styles. Defaults to on. =cut my $Use_Nums = 1; sub use_numbers { my($self, $use_nums) = @_; if( defined $use_nums ) { $Use_Nums = $use_nums; } return $Use_Nums; } =item B $Test->no_header($no_header); If set to true, no "1..N" header will be printed. =item B $Test->no_ending($no_ending); Normally, Test::Builder does some extra diagnostics when the test ends. It also changes the exit code as described in Test::Simple. If this is true, none of that will be done. =cut my($No_Header, $No_Ending) = (0,0); sub no_header { my($self, $no_header) = @_; if( defined $no_header ) { $No_Header = $no_header; } return $No_Header; } sub no_ending { my($self, $no_ending) = @_; if( defined $no_ending ) { $No_Ending = $no_ending; } return $No_Ending; } =back =head2 Output Controlling where the test output goes. It's ok for your test to change where STDOUT and STDERR point to, Test::Builder's default output settings will not be affected. =over 4 =item B $Test->diag(@msgs); Prints out the given $message. Normally, it uses the failure_output() handle, but if this is for a TODO test, the todo_output() handle is used. Output will be indented and marked with a # so as not to interfere with test output. A newline will be put on the end if there isn't one already. We encourage using this rather than calling print directly. Returns false. Why? Because diag() is often used in conjunction with a failing test (C) it "passes through" the failure. return ok(...) || diag(...); =for blame transfer Mark Fowler =cut sub diag { my($self, @msgs) = @_; return unless @msgs; # Prevent printing headers when compiling (i.e. -c) return if $^C; # Escape each line with a #. foreach (@msgs) { $_ = 'undef' unless defined; s/^/# /gms; } push @msgs, "\n" unless $msgs[-1] =~ /\n\Z/; local $Level = $Level + 1; my $fh = $self->todo ? $self->todo_output : $self->failure_output; local($\, $", $,) = (undef, ' ', ''); print $fh @msgs; return 0; } =begin _private =item B<_print> $Test->_print(@msgs); Prints to the output() filehandle. =end _private =cut sub _print { my($self, @msgs) = @_; # Prevent printing headers when only compiling. Mostly for when # tests are deparsed with B::Deparse return if $^C; local($\, $", $,) = (undef, ' ', ''); my $fh = $self->output; # Escape each line after the first with a # so we don't # confuse Test::Harness. foreach (@msgs) { s/\n(.)/\n# $1/sg; } push @msgs, "\n" unless $msgs[-1] =~ /\n\Z/; print $fh @msgs; } =item B $Test->output($fh); $Test->output($file); Where normal "ok/not ok" test output should go. Defaults to STDOUT. =item B $Test->failure_output($fh); $Test->failure_output($file); Where diagnostic output on test failures and diag() should go. Defaults to STDERR. =item B $Test->todo_output($fh); $Test->todo_output($file); Where diagnostics about todo test failures and diag() should go. Defaults to STDOUT. =cut my($Out_FH, $Fail_FH, $Todo_FH); sub output { my($self, $fh) = @_; if( defined $fh ) { $Out_FH = _new_fh($fh); } return $Out_FH; } sub failure_output { my($self, $fh) = @_; if( defined $fh ) { $Fail_FH = _new_fh($fh); } return $Fail_FH; } sub todo_output { my($self, $fh) = @_; if( defined $fh ) { $Todo_FH = _new_fh($fh); } return $Todo_FH; } sub _new_fh { my($file_or_fh) = shift; my $fh; unless( UNIVERSAL::isa($file_or_fh, 'GLOB') ) { $fh = do { local *FH }; open $fh, ">$file_or_fh" or die "Can't open test output log $file_or_fh: $!"; } else { $fh = $file_or_fh; } return $fh; } unless( $^C ) { # We dup STDOUT and STDERR so people can change them in their # test suites while still getting normal test output. open(TESTOUT, ">&STDOUT") or die "Can't dup STDOUT: $!"; open(TESTERR, ">&STDERR") or die "Can't dup STDERR: $!"; # Set everything to unbuffered else plain prints to STDOUT will # come out in the wrong order from our own prints. _autoflush(\*TESTOUT); _autoflush(\*STDOUT); _autoflush(\*TESTERR); _autoflush(\*STDERR); $CLASS->output(\*TESTOUT); $CLASS->failure_output(\*TESTERR); $CLASS->todo_output(\*TESTOUT); } sub _autoflush { my($fh) = shift; my $old_fh = select $fh; $| = 1; select $old_fh; } =back =head2 Test Status and Info =over 4 =item B my $curr_test = $Test->current_test; $Test->current_test($num); Gets/sets the current test # we're on. You usually shouldn't have to set this. =cut sub current_test { my($self, $num) = @_; lock($Curr_Test); if( defined $num ) { unless( $Have_Plan ) { require Carp; Carp::croak("Can't change the current test number without a plan!"); } $Curr_Test = $num; if( $num > @Test_Results ) { my $start = @Test_Results ? $#Test_Results + 1 : 0; for ($start..$num-1) { my %result; share(%result); %result = ( ok => 1, actual_ok => undef, reason => 'incrementing test number', type => 'unknown', name => undef ); $Test_Results[$_] = \%result; } } } return $Curr_Test; } =item B my @tests = $Test->summary; A simple summary of the tests so far. True for pass, false for fail. This is a logical pass/fail, so todos are passes. Of course, test #1 is $tests[0], etc... =cut sub summary { my($self) = shift; return map { $_->{'ok'} } @Test_Results; } =item B
my @tests = $Test->details; Like summary(), but with a lot more detail. $tests[$test_num - 1] = { 'ok' => is the test considered a pass? actual_ok => did it literally say 'ok'? name => name of the test (if any) type => type of test (if any, see below). reason => reason for the above (if any) }; 'ok' is true if Test::Harness will consider the test to be a pass. 'actual_ok' is a reflection of whether or not the test literally printed 'ok' or 'not ok'. This is for examining the result of 'todo' tests. 'name' is the name of the test. 'type' indicates if it was a special test. Normal tests have a type of ''. Type can be one of the following: skip see skip() todo see todo() todo_skip see todo_skip() unknown see below Sometimes the Test::Builder test counter is incremented without it printing any test output, for example, when current_test() is changed. In these cases, Test::Builder doesn't know the result of the test, so it's type is 'unkown'. These details for these tests are filled in. They are considered ok, but the name and actual_ok is left undef. For example "not ok 23 - hole count # TODO insufficient donuts" would result in this structure: $tests[22] = # 23 - 1, since arrays start from 0. { ok => 1, # logically, the test passed since it's todo actual_ok => 0, # in absolute terms, it failed name => 'hole count', type => 'todo', reason => 'insufficient donuts' }; =cut sub details { return @Test_Results; } =item B my $todo_reason = $Test->todo; my $todo_reason = $Test->todo($pack); todo() looks for a $TODO variable in your tests. If set, all tests will be considered 'todo' (see Test::More and Test::Harness for details). Returns the reason (ie. the value of $TODO) if running as todo tests, false otherwise. todo() is pretty part about finding the right package to look for $TODO in. It uses the exported_to() package to find it. If that's not set, it's pretty good at guessing the right package to look at. Sometimes there is some confusion about where todo() should be looking for the $TODO variable. If you want to be sure, tell it explicitly what $pack to use. =cut sub todo { my($self, $pack) = @_; $pack = $pack || $self->exported_to || $self->caller(1); no strict 'refs'; return defined ${$pack.'::TODO'} ? ${$pack.'::TODO'} : 0; } =item B my $package = $Test->caller; my($pack, $file, $line) = $Test->caller; my($pack, $file, $line) = $Test->caller($height); Like the normal caller(), except it reports according to your level(). =cut sub caller { my($self, $height) = @_; $height ||= 0; my @caller = CORE::caller($self->level + $height + 1); return wantarray ? @caller : $caller[0]; } =back =cut =begin _private =over 4 =item B<_sanity_check> _sanity_check(); Runs a bunch of end of test sanity checks to make sure reality came through ok. If anything is wrong it will die with a fairly friendly error message. =cut #'# sub _sanity_check { _whoa($Curr_Test < 0, 'Says here you ran a negative number of tests!'); _whoa(!$Have_Plan and $Curr_Test, 'Somehow your tests ran without a plan!'); _whoa($Curr_Test != @Test_Results, 'Somehow you got a different number of results than tests ran!'); } =item B<_whoa> _whoa($check, $description); A sanity check, similar to assert(). If the $check is true, something has gone horribly wrong. It will die with the given $description and a note to contact the author. =cut sub _whoa { my($check, $desc) = @_; if( $check ) { die < _my_exit($exit_num); Perl seems to have some trouble with exiting inside an END block. 5.005_03 and 5.6.1 both seem to do odd things. Instead, this function edits $? directly. It should ONLY be called from inside an END block. It doesn't actually exit, that's your job. =cut sub _my_exit { $? = $_[0]; return 1; } =back =end _private =cut $SIG{__DIE__} = sub { # We don't want to muck with death in an eval, but $^S isn't # totally reliable. 5.005_03 and 5.6.1 both do the wrong thing # with it. Instead, we use caller. This also means it runs under # 5.004! my $in_eval = 0; for( my $stack = 1; my $sub = (CORE::caller($stack))[3]; $stack++ ) { $in_eval = 1 if $sub =~ /^\(eval\)/; } $Test_Died = 1 unless $in_eval; }; sub _ending { my $self = shift; _sanity_check(); # Don't bother with an ending if this is a forked copy. Only the parent # should do the ending. do{ _my_exit($?) && return } if $Original_Pid != $$; # Bailout if plan() was never called. This is so # "require Test::Simple" doesn't puke. do{ _my_exit(0) && return } if !$Have_Plan && !$Test_Died; # Figure out if we passed or failed and print helpful messages. if( @Test_Results ) { # The plan? We have no plan. if( $No_Plan ) { $self->_print("1..$Curr_Test\n") unless $self->no_header; $Expected_Tests = $Curr_Test; } # 5.8.0 threads bug. Shared arrays will not be auto-extended # by a slice. Worse, we have to fill in every entry else # we'll get an "Invalid value for shared scalar" error for my $idx ($#Test_Results..$Expected_Tests-1) { my %empty_result = (); share(%empty_result); $Test_Results[$idx] = \%empty_result unless defined $Test_Results[$idx]; } my $num_failed = grep !$_->{'ok'}, @Test_Results[0..$Expected_Tests-1]; $num_failed += abs($Expected_Tests - @Test_Results); if( $Curr_Test < $Expected_Tests ) { $self->diag(<<"FAIL"); Looks like you planned $Expected_Tests tests but only ran $Curr_Test. FAIL } elsif( $Curr_Test > $Expected_Tests ) { my $num_extra = $Curr_Test - $Expected_Tests; $self->diag(<<"FAIL"); Looks like you planned $Expected_Tests tests but ran $num_extra extra. FAIL } elsif ( $num_failed ) { $self->diag(<<"FAIL"); Looks like you failed $num_failed tests of $Expected_Tests. FAIL } if( $Test_Died ) { $self->diag(<<"FAIL"); Looks like your test died just after $Curr_Test. FAIL _my_exit( 255 ) && return; } _my_exit( $num_failed <= 254 ? $num_failed : 254 ) && return; } elsif ( $Skip_All ) { _my_exit( 0 ) && return; } elsif ( $Test_Died ) { $self->diag(<<'FAIL'); Looks like your test died before it could output anything. FAIL } else { $self->diag("No tests run!\n"); _my_exit( 255 ) && return; } } END { $Test->_ending if defined $Test and !$Test->no_ending; } =head1 THREADS In perl 5.8.0 and later, Test::Builder is thread-safe. The test number is shared amongst all threads. This means if one thread sets the test number using current_test() they will all be effected. =head1 EXAMPLES CPAN can provide the best examples. Test::Simple, Test::More, Test::Exception and Test::Differences all use Test::Builder. =head1 SEE ALSO Test::Simple, Test::More, Test::Harness =head1 AUTHORS Original code by chromatic, maintained by Michael G Schwern Eschwern@pobox.comE =head1 COPYRIGHT Copyright 2002 by chromatic Echromatic@wgz.orgE, Michael G Schwern Eschwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F =cut 1; Net-Jabber-2.0/t/lib/Test/More.pm0000644000175000017500000007467610110275744017635 0ustar reatmonreatmon00000000000000package Test::More; use 5.004; use strict; use Test::Builder; # Can't use Carp because it might cause use_ok() to accidentally succeed # even though the module being used forgot to use Carp. Yes, this # actually happened. sub _carp { my($file, $line) = (caller(1))[1,2]; warn @_, " at $file line $line\n"; } require Exporter; use vars qw($VERSION @ISA @EXPORT %EXPORT_TAGS $TODO); $VERSION = '0.47'; @ISA = qw(Exporter); @EXPORT = qw(ok use_ok require_ok is isnt like unlike is_deeply cmp_ok skip todo todo_skip pass fail eq_array eq_hash eq_set $TODO plan can_ok isa_ok diag ); my $Test = Test::Builder->new; # 5.004's Exporter doesn't have export_to_level. sub _export_to_level { my $pkg = shift; my $level = shift; (undef) = shift; # redundant arg my $callpkg = caller($level); $pkg->export($callpkg, @_); } =head1 NAME Test::More - yet another framework for writing test scripts =head1 SYNOPSIS use Test::More tests => $Num_Tests; # or use Test::More qw(no_plan); # or use Test::More skip_all => $reason; BEGIN { use_ok( 'Some::Module' ); } require_ok( 'Some::Module' ); # Various ways to say "ok" ok($this eq $that, $test_name); is ($this, $that, $test_name); isnt($this, $that, $test_name); # Rather than print STDERR "# here's what went wrong\n" diag("here's what went wrong"); like ($this, qr/that/, $test_name); unlike($this, qr/that/, $test_name); cmp_ok($this, '==', $that, $test_name); is_deeply($complex_structure1, $complex_structure2, $test_name); SKIP: { skip $why, $how_many unless $have_some_feature; ok( foo(), $test_name ); is( foo(42), 23, $test_name ); }; TODO: { local $TODO = $why; ok( foo(), $test_name ); is( foo(42), 23, $test_name ); }; can_ok($module, @methods); isa_ok($object, $class); pass($test_name); fail($test_name); # Utility comparison functions. eq_array(\@this, \@that); eq_hash(\%this, \%that); eq_set(\@this, \@that); # UNIMPLEMENTED!!! my @status = Test::More::status; # UNIMPLEMENTED!!! BAIL_OUT($why); =head1 DESCRIPTION B If you're just getting started writing tests, have a look at Test::Simple first. This is a drop in replacement for Test::Simple which you can switch to once you get the hang of basic testing. The purpose of this module is to provide a wide range of testing utilities. Various ways to say "ok" with better diagnostics, facilities to skip tests, test future features and compare complicated data structures. While you can do almost anything with a simple C function, it doesn't provide good diagnostic output. =head2 I love it when a plan comes together Before anything else, you need a testing plan. This basically declares how many tests your script is going to run to protect against premature failure. The preferred way to do this is to declare a plan when you C. use Test::More tests => $Num_Tests; There are rare cases when you will not know beforehand how many tests your script is going to run. In this case, you can declare that you have no plan. (Try to avoid using this as it weakens your test.) use Test::More qw(no_plan); In some cases, you'll want to completely skip an entire testing script. use Test::More skip_all => $skip_reason; Your script will declare a skip with the reason why you skipped and exit immediately with a zero (success). See L for details. If you want to control what functions Test::More will export, you have to use the 'import' option. For example, to import everything but 'fail', you'd do: use Test::More tests => 23, import => ['!fail']; Alternatively, you can use the plan() function. Useful for when you have to calculate the number of tests. use Test::More; plan tests => keys %Stuff * 3; or for deciding between running the tests at all: use Test::More; if( $^O eq 'MacOS' ) { plan skip_all => 'Test irrelevant on MacOS'; } else { plan tests => 42; } =cut sub plan { my(@plan) = @_; my $caller = caller; $Test->exported_to($caller); my @imports = (); foreach my $idx (0..$#plan) { if( $plan[$idx] eq 'import' ) { my($tag, $imports) = splice @plan, $idx, 2; @imports = @$imports; last; } } $Test->plan(@plan); __PACKAGE__->_export_to_level(1, __PACKAGE__, @imports); } sub import { my($class) = shift; goto &plan; } =head2 Test names By convention, each test is assigned a number in order. This is largely done automatically for you. However, it's often very useful to assign a name to each test. Which would you rather see: ok 4 not ok 5 ok 6 or ok 4 - basic multi-variable not ok 5 - simple exponential ok 6 - force == mass * acceleration The later gives you some idea of what failed. It also makes it easier to find the test in your script, simply search for "simple exponential". All test functions take a name argument. It's optional, but highly suggested that you use it. =head2 I'm ok, you're not ok. The basic purpose of this module is to print out either "ok #" or "not ok #" depending on if a given test succeeded or failed. Everything else is just gravy. All of the following print "ok" or "not ok" depending on if the test succeeded or failed. They all also return true or false, respectively. =over 4 =item B ok($this eq $that, $test_name); This simply evaluates any expression (C<$this eq $that> is just a simple example) and uses that to determine if the test succeeded or failed. A true expression passes, a false one fails. Very simple. For example: ok( $exp{9} == 81, 'simple exponential' ); ok( Film->can('db_Main'), 'set_db()' ); ok( $p->tests == 4, 'saw tests' ); ok( !grep !defined $_, @items, 'items populated' ); (Mnemonic: "This is ok.") $test_name is a very short description of the test that will be printed out. It makes it very easy to find a test in your script when it fails and gives others an idea of your intentions. $test_name is optional, but we B strongly encourage its use. Should an ok() fail, it will produce some diagnostics: not ok 18 - sufficient mucus # Failed test 18 (foo.t at line 42) This is actually Test::Simple's ok() routine. =cut sub ok ($;$) { my($test, $name) = @_; $Test->ok($test, $name); } =item B =item B is ( $this, $that, $test_name ); isnt( $this, $that, $test_name ); Similar to ok(), is() and isnt() compare their two arguments with C and C respectively and use the result of that to determine if the test succeeded or failed. So these: # Is the ultimate answer 42? is( ultimate_answer(), 42, "Meaning of Life" ); # $foo isn't empty isnt( $foo, '', "Got some foo" ); are similar to these: ok( ultimate_answer() eq 42, "Meaning of Life" ); ok( $foo ne '', "Got some foo" ); (Mnemonic: "This is that." "This isn't that.") So why use these? They produce better diagnostics on failure. ok() cannot know what you are testing for (beyond the name), but is() and isnt() know what the test was and why it failed. For example this test: my $foo = 'waffle'; my $bar = 'yarblokos'; is( $foo, $bar, 'Is foo the same as bar?' ); Will produce something like this: not ok 17 - Is foo the same as bar? # Failed test (foo.t at line 139) # got: 'waffle' # expected: 'yarblokos' So you can figure out what went wrong without rerunning the test. You are encouraged to use is() and isnt() over ok() where possible, however do not be tempted to use them to find out if something is true or false! # XXX BAD! $pope->isa('Catholic') eq 1 is( $pope->isa('Catholic'), 1, 'Is the Pope Catholic?' ); This does not check if C<$pope->isa('Catholic')> is true, it checks if it returns 1. Very different. Similar caveats exist for false and 0. In these cases, use ok(). ok( $pope->isa('Catholic') ), 'Is the Pope Catholic?' ); For those grammatical pedants out there, there's an C function which is an alias of isnt(). =cut sub is ($$;$) { $Test->is_eq(@_); } sub isnt ($$;$) { $Test->isnt_eq(@_); } *isn't = \&isnt; =item B like( $this, qr/that/, $test_name ); Similar to ok(), like() matches $this against the regex C. So this: like($this, qr/that/, 'this is like that'); is similar to: ok( $this =~ /that/, 'this is like that'); (Mnemonic "This is like that".) The second argument is a regular expression. It may be given as a regex reference (i.e. C) or (for better compatibility with older perls) as a string that looks like a regex (alternative delimiters are currently not supported): like( $this, '/that/', 'this is like that' ); Regex options may be placed on the end (C<'/that/i'>). Its advantages over ok() are similar to that of is() and isnt(). Better diagnostics on failure. =cut sub like ($$;$) { $Test->like(@_); } =item B unlike( $this, qr/that/, $test_name ); Works exactly as like(), only it checks if $this B match the given pattern. =cut sub unlike { $Test->unlike(@_); } =item B cmp_ok( $this, $op, $that, $test_name ); Halfway between ok() and is() lies cmp_ok(). This allows you to compare two arguments using any binary perl operator. # ok( $this eq $that ); cmp_ok( $this, 'eq', $that, 'this eq that' ); # ok( $this == $that ); cmp_ok( $this, '==', $that, 'this == that' ); # ok( $this && $that ); cmp_ok( $this, '&&', $that, 'this || that' ); ...etc... Its advantage over ok() is when the test fails you'll know what $this and $that were: not ok 1 # Failed test (foo.t at line 12) # '23' # && # undef It's also useful in those cases where you are comparing numbers and is()'s use of C will interfere: cmp_ok( $big_hairy_number, '==', $another_big_hairy_number ); =cut sub cmp_ok($$$;$) { $Test->cmp_ok(@_); } =item B can_ok($module, @methods); can_ok($object, @methods); Checks to make sure the $module or $object can do these @methods (works with functions, too). can_ok('Foo', qw(this that whatever)); is almost exactly like saying: ok( Foo->can('this') && Foo->can('that') && Foo->can('whatever') ); only without all the typing and with a better interface. Handy for quickly testing an interface. No matter how many @methods you check, a single can_ok() call counts as one test. If you desire otherwise, use: foreach my $meth (@methods) { can_ok('Foo', $meth); } =cut sub can_ok ($@) { my($proto, @methods) = @_; my $class = ref $proto || $proto; unless( @methods ) { my $ok = $Test->ok( 0, "$class->can(...)" ); $Test->diag(' can_ok() called with no methods'); return $ok; } my @nok = (); foreach my $method (@methods) { local($!, $@); # don't interfere with caller's $@ # eval sometimes resets $! eval { $proto->can($method) } || push @nok, $method; } my $name; $name = @methods == 1 ? "$class->can('$methods[0]')" : "$class->can(...)"; my $ok = $Test->ok( !@nok, $name ); $Test->diag(map " $class->can('$_') failed\n", @nok); return $ok; } =item B isa_ok($object, $class, $object_name); isa_ok($ref, $type, $ref_name); Checks to see if the given $object->isa($class). Also checks to make sure the object was defined in the first place. Handy for this sort of thing: my $obj = Some::Module->new; isa_ok( $obj, 'Some::Module' ); where you'd otherwise have to write my $obj = Some::Module->new; ok( defined $obj && $obj->isa('Some::Module') ); to safeguard against your test script blowing up. It works on references, too: isa_ok( $array_ref, 'ARRAY' ); The diagnostics of this test normally just refer to 'the object'. If you'd like them to be more specific, you can supply an $object_name (for example 'Test customer'). =cut sub isa_ok ($$;$) { my($object, $class, $obj_name) = @_; my $diag; $obj_name = 'The object' unless defined $obj_name; my $name = "$obj_name isa $class"; if( !defined $object ) { $diag = "$obj_name isn't defined"; } elsif( !ref $object ) { $diag = "$obj_name isn't a reference"; } else { # We can't use UNIVERSAL::isa because we want to honor isa() overrides local($@, $!); # eval sometimes resets $! my $rslt = eval { $object->isa($class) }; if( $@ ) { if( $@ =~ /^Can't call method "isa" on unblessed reference/ ) { if( !UNIVERSAL::isa($object, $class) ) { my $ref = ref $object; $diag = "$obj_name isn't a '$class' it's a '$ref'"; } } else { die <isa on your object and got some weird error. This should never happen. Please contact the author immediately. Here's the error. $@ WHOA } } elsif( !$rslt ) { my $ref = ref $object; $diag = "$obj_name isn't a '$class' it's a '$ref'"; } } my $ok; if( $diag ) { $ok = $Test->ok( 0, $name ); $Test->diag(" $diag\n"); } else { $ok = $Test->ok( 1, $name ); } return $ok; } =item B =item B pass($test_name); fail($test_name); Sometimes you just want to say that the tests have passed. Usually the case is you've got some complicated condition that is difficult to wedge into an ok(). In this case, you can simply use pass() (to declare the test ok) or fail (for not ok). They are synonyms for ok(1) and ok(0). Use these very, very, very sparingly. =cut sub pass (;$) { $Test->ok(1, @_); } sub fail (;$) { $Test->ok(0, @_); } =back =head2 Diagnostics If you pick the right test function, you'll usually get a good idea of what went wrong when it failed. But sometimes it doesn't work out that way. So here we have ways for you to write your own diagnostic messages which are safer than just C. =over 4 =item B diag(@diagnostic_message); Prints a diagnostic message which is guaranteed not to interfere with test output. Handy for this sort of thing: ok( grep(/foo/, @users), "There's a foo user" ) or diag("Since there's no foo, check that /etc/bar is set up right"); which would produce: not ok 42 - There's a foo user # Failed test (foo.t at line 52) # Since there's no foo, check that /etc/bar is set up right. You might remember C with the mnemonic C. B The exact formatting of the diagnostic output is still changing, but it is guaranteed that whatever you throw at it it won't interfere with the test. =cut sub diag { $Test->diag(@_); } =back =head2 Module tests You usually want to test if the module you're testing loads ok, rather than just vomiting if its load fails. For such purposes we have C and C. =over 4 =item B BEGIN { use_ok($module); } BEGIN { use_ok($module, @imports); } These simply use the given $module and test to make sure the load happened ok. It's recommended that you run use_ok() inside a BEGIN block so its functions are exported at compile-time and prototypes are properly honored. If @imports are given, they are passed through to the use. So this: BEGIN { use_ok('Some::Module', qw(foo bar)) } is like doing this: use Some::Module qw(foo bar); don't try to do this: BEGIN { use_ok('Some::Module'); ...some code that depends on the use... ...happening at compile time... } instead, you want: BEGIN { use_ok('Some::Module') } BEGIN { ...some code that depends on the use... } =cut sub use_ok ($;@) { my($module, @imports) = @_; @imports = () unless @imports; my $pack = caller; local($@,$!); # eval sometimes interferes with $! eval <import(\@imports); USE my $ok = $Test->ok( !$@, "use $module;" ); unless( $ok ) { chomp $@; $Test->diag(< require_ok($module); Like use_ok(), except it requires the $module. =cut sub require_ok ($) { my($module) = shift; my $pack = caller; local($!, $@); # eval sometimes interferes with $! eval <ok( !$@, "require $module;" ); unless( $ok ) { chomp $@; $Test->diag(<. The way Test::More handles this is with a named block. Basically, a block of tests which can be skipped over or made todo. It's best if I just show you... =over 4 =item B SKIP: { skip $why, $how_many if $condition; ...normal testing code goes here... } This declares a block of tests that might be skipped, $how_many tests there are, $why and under what $condition to skip them. An example is the easiest way to illustrate: SKIP: { eval { require HTML::Lint }; skip "HTML::Lint not installed", 2 if $@; my $lint = new HTML::Lint; isa_ok( $lint, "HTML::Lint" ); $lint->parse( $html ); is( $lint->errors, 0, "No errors found in HTML" ); } If the user does not have HTML::Lint installed, the whole block of code I. Test::More will output special ok's which Test::Harness interprets as skipped, but passing, tests. It's important that $how_many accurately reflects the number of tests in the SKIP block so the # of tests run will match up with your plan. It's perfectly safe to nest SKIP blocks. Each SKIP block must have the label C, or Test::More can't work its magic. You don't skip tests which are failing because there's a bug in your program, or for which you don't yet have code written. For that you use TODO. Read on. =cut #'# sub skip { my($why, $how_many) = @_; unless( defined $how_many ) { # $how_many can only be avoided when no_plan is in use. _carp "skip() needs to know \$how_many tests are in the block" unless $Test::Builder::No_Plan; $how_many = 1; } for( 1..$how_many ) { $Test->skip($why); } local $^W = 0; last SKIP; } =item B TODO: { local $TODO = $why if $condition; ...normal testing code goes here... } Declares a block of tests you expect to fail and $why. Perhaps it's because you haven't fixed a bug or haven't finished a new feature: TODO: { local $TODO = "URI::Geller not finished"; my $card = "Eight of clubs"; is( URI::Geller->your_card, $card, 'Is THIS your card?' ); my $spoon; URI::Geller->bend_spoon; is( $spoon, 'bent', "Spoon bending, that's original" ); } With a todo block, the tests inside are expected to fail. Test::More will run the tests normally, but print out special flags indicating they are "todo". Test::Harness will interpret failures as being ok. Should anything succeed, it will report it as an unexpected success. You then know the thing you had todo is done and can remove the TODO flag. The nice part about todo tests, as opposed to simply commenting out a block of tests, is it's like having a programmatic todo list. You know how much work is left to be done, you're aware of what bugs there are, and you'll know immediately when they're fixed. Once a todo test starts succeeding, simply move it outside the block. When the block is empty, delete it. =item B TODO: { todo_skip $why, $how_many if $condition; ...normal testing code... } With todo tests, it's best to have the tests actually run. That way you'll know when they start passing. Sometimes this isn't possible. Often a failing test will cause the whole program to die or hang, even inside an C with and using C. In these extreme cases you have no choice but to skip over the broken tests entirely. The syntax and behavior is similar to a C except the tests will be marked as failing but todo. Test::Harness will interpret them as passing. =cut sub todo_skip { my($why, $how_many) = @_; unless( defined $how_many ) { # $how_many can only be avoided when no_plan is in use. _carp "todo_skip() needs to know \$how_many tests are in the block" unless $Test::Builder::No_Plan; $how_many = 1; } for( 1..$how_many ) { $Test->todo_skip($why); } local $^W = 0; last TODO; } =item When do I use SKIP vs. TODO? B, use SKIP. This includes optional modules that aren't installed, running under an OS that doesn't have some feature (like fork() or symlinks), or maybe you need an Internet connection and one isn't available. B, use TODO. This is for any code you haven't written yet, or bugs you have yet to fix, but want to put tests in your testing script (always a good idea). =back =head2 Comparison functions Not everything is a simple eq check or regex. There are times you need to see if two arrays are equivalent, for instance. For these instances, Test::More provides a handful of useful functions. B These are NOT well-tested on circular references. Nor am I quite sure what will happen with filehandles. =over 4 =item B is_deeply( $this, $that, $test_name ); Similar to is(), except that if $this and $that are hash or array references, it does a deep comparison walking each data structure to see if they are equivalent. If the two structures are different, it will display the place where they start differing. Barrie Slaymaker's Test::Differences module provides more in-depth functionality along these lines, and it plays well with Test::More. B Display of scalar refs is not quite 100% =cut use vars qw(@Data_Stack); my $DNE = bless [], 'Does::Not::Exist'; sub is_deeply { my($this, $that, $name) = @_; my $ok; if( !ref $this || !ref $that ) { $ok = $Test->is_eq($this, $that, $name); } else { local @Data_Stack = (); if( _deep_check($this, $that) ) { $ok = $Test->ok(1, $name); } else { $ok = $Test->ok(0, $name); $ok = $Test->diag(_format_stack(@Data_Stack)); } } return $ok; } sub _format_stack { my(@Stack) = @_; my $var = '$FOO'; my $did_arrow = 0; foreach my $entry (@Stack) { my $type = $entry->{type} || ''; my $idx = $entry->{'idx'}; if( $type eq 'HASH' ) { $var .= "->" unless $did_arrow++; $var .= "{$idx}"; } elsif( $type eq 'ARRAY' ) { $var .= "->" unless $did_arrow++; $var .= "[$idx]"; } elsif( $type eq 'REF' ) { $var = "\${$var}"; } } my @vals = @{$Stack[-1]{vals}}[0,1]; my @vars = (); ($vars[0] = $var) =~ s/\$FOO/ \$got/; ($vars[1] = $var) =~ s/\$FOO/\$expected/; my $out = "Structures begin differing at:\n"; foreach my $idx (0..$#vals) { my $val = $vals[$idx]; $vals[$idx] = !defined $val ? 'undef' : $val eq $DNE ? "Does not exist" : "'$val'"; } $out .= "$vars[0] = $vals[0]\n"; $out .= "$vars[1] = $vals[1]\n"; $out =~ s/^/ /msg; return $out; } =item B eq_array(\@this, \@that); Checks if two arrays are equivalent. This is a deep check, so multi-level structures are handled correctly. =cut #'# sub eq_array { my($a1, $a2) = @_; return 1 if $a1 eq $a2; my $ok = 1; my $max = $#$a1 > $#$a2 ? $#$a1 : $#$a2; for (0..$max) { my $e1 = $_ > $#$a1 ? $DNE : $a1->[$_]; my $e2 = $_ > $#$a2 ? $DNE : $a2->[$_]; push @Data_Stack, { type => 'ARRAY', idx => $_, vals => [$e1, $e2] }; $ok = _deep_check($e1,$e2); pop @Data_Stack if $ok; last unless $ok; } return $ok; } sub _deep_check { my($e1, $e2) = @_; my $ok = 0; my $eq; { # Quiet uninitialized value warnings when comparing undefs. local $^W = 0; if( $e1 eq $e2 ) { $ok = 1; } else { if( UNIVERSAL::isa($e1, 'ARRAY') and UNIVERSAL::isa($e2, 'ARRAY') ) { $ok = eq_array($e1, $e2); } elsif( UNIVERSAL::isa($e1, 'HASH') and UNIVERSAL::isa($e2, 'HASH') ) { $ok = eq_hash($e1, $e2); } elsif( UNIVERSAL::isa($e1, 'REF') and UNIVERSAL::isa($e2, 'REF') ) { push @Data_Stack, { type => 'REF', vals => [$e1, $e2] }; $ok = _deep_check($$e1, $$e2); pop @Data_Stack if $ok; } elsif( UNIVERSAL::isa($e1, 'SCALAR') and UNIVERSAL::isa($e2, 'SCALAR') ) { push @Data_Stack, { type => 'REF', vals => [$e1, $e2] }; $ok = _deep_check($$e1, $$e2); } else { push @Data_Stack, { vals => [$e1, $e2] }; $ok = 0; } } } return $ok; } =item B eq_hash(\%this, \%that); Determines if the two hashes contain the same keys and values. This is a deep check. =cut sub eq_hash { my($a1, $a2) = @_; return 1 if $a1 eq $a2; my $ok = 1; my $bigger = keys %$a1 > keys %$a2 ? $a1 : $a2; foreach my $k (keys %$bigger) { my $e1 = exists $a1->{$k} ? $a1->{$k} : $DNE; my $e2 = exists $a2->{$k} ? $a2->{$k} : $DNE; push @Data_Stack, { type => 'HASH', idx => $k, vals => [$e1, $e2] }; $ok = _deep_check($e1, $e2); pop @Data_Stack if $ok; last unless $ok; } return $ok; } =item B eq_set(\@this, \@that); Similar to eq_array(), except the order of the elements is B important. This is a deep check, but the irrelevancy of order only applies to the top level. B By historical accident, this is not a true set comparision. While the order of elements does not matter, duplicate elements do. =cut # We must make sure that references are treated neutrally. It really # doesn't matter how we sort them, as long as both arrays are sorted # with the same algorithm. sub _bogus_sort { local $^W = 0; ref $a ? 0 : $a cmp $b } sub eq_set { my($a1, $a2) = @_; return 0 unless @$a1 == @$a2; # There's faster ways to do this, but this is easiest. return eq_array( [sort _bogus_sort @$a1], [sort _bogus_sort @$a2] ); } =back =head2 Extending and Embedding Test::More Sometimes the Test::More interface isn't quite enough. Fortunately, Test::More is built on top of Test::Builder which provides a single, unified backend for any test library to use. This means two test libraries which both use Test::Builder B. If you simply want to do a little tweaking of how the tests behave, you can access the underlying Test::Builder object like so: =over 4 =item B my $test_builder = Test::More->builder; Returns the Test::Builder object underlying Test::More for you to play with. =cut sub builder { return Test::Builder->new; } =back =head1 NOTES Test::More is B tested all the way back to perl 5.004. Test::More is thread-safe for perl 5.8.0 and up. =head1 BUGS and CAVEATS =over 4 =item Making your own ok() If you are trying to extend Test::More, don't. Use Test::Builder instead. =item The eq_* family has some caveats. =item Test::Harness upgrades no_plan and todo depend on new Test::Harness features and fixes. If you're going to distribute tests that use no_plan or todo your end-users will have to upgrade Test::Harness to the latest one on CPAN. If you avoid no_plan and TODO tests, the stock Test::Harness will work fine. If you simply depend on Test::More, it's own dependencies will cause a Test::Harness upgrade. =back =head1 HISTORY This is a case of convergent evolution with Joshua Pritikin's Test module. I was largely unaware of its existence when I'd first written my own ok() routines. This module exists because I can't figure out how to easily wedge test names into Test's interface (along with a few other problems). The goal here is to have a testing utility that's simple to learn, quick to use and difficult to trip yourself up with while still providing more flexibility than the existing Test.pm. As such, the names of the most common routines are kept tiny, special cases and magic side-effects are kept to a minimum. WYSIWYG. =head1 SEE ALSO L if all this confuses you and you just want to write some tests. You can upgrade to Test::More later (it's forward compatible). L for more ways to test complex data structures. And it plays well with Test::More. L is the old testing module. Its main benefit is that it has been distributed with Perl since 5.004_05. L for details on how your test results are interpreted by Perl. L describes a very featureful unit testing interface. L shows the idea of embedded testing. L is another approach to embedded testing. =head1 AUTHORS Michael G Schwern Eschwern@pobox.comE with much inspiration from Joshua Pritikin's Test module and lots of help from Barrie Slaymaker, Tony Bowden, chromatic and the perl-qa gang. =head1 COPYRIGHT Copyright 2001 by Michael G Schwern Eschwern@pobox.comE. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See F =cut 1; Net-Jabber-2.0/t/query_filter.t0000644000175000017500000001077110110275744017571 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>93; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:filter"); my $rule1 = $query->AddRule(); ok( defined($rule1), "new()" ); isa_ok( $rule1, "Net::Jabber::Stanza" ); isa_ok( $rule1, "Net::XMPP::Stanza" ); testScalar($rule1,"Body","body1"); testScalar($rule1,"Continued","continued1"); testScalar($rule1,"Drop","drop1"); testScalar($rule1,"Edit","edit1"); testScalar($rule1,"Error","error1"); testScalar($rule1,"From","from1"); testScalar($rule1,"Offline","offline1"); testScalar($rule1,"Reply","reply1"); testScalar($rule1,"Resource","resource1"); testScalar($rule1,"Show","show1"); testScalar($rule1,"Size","size1"); testScalar($rule1,"Subject","subject1"); testScalar($rule1,"Time","time1"); testScalar($rule1,"Type","type1"); testScalar($rule1,"Unavailable","unavailable1"); is( $query->GetXML(), "body1continued1drop1edit1error1from1offline1reply1resource1show1size1subject1type1unavailable1", "GetXML()" ); my $rule2 = $query->AddRule(body=>"body2", continued=>"continued2", drop=>"drop2", edit=>"edit2", error=>"error2", from=>"from2", offline=>"offline2", reply=>"reply2", resource=>"resource2", show=>"show2", size=>"size2", subject=>"subject2", time=>"time2", type=>"type2", unavailable=>"unavailable2", ); ok( defined($rule2), "new()" ); isa_ok( $rule2, "Net::Jabber::Stanza" ); isa_ok( $rule2, "Net::XMPP::Stanza" ); testPostScalar($rule2,"Body","body2"); testPostScalar($rule2,"Continued","continued2"); testPostScalar($rule2,"Drop","drop2"); testPostScalar($rule2,"Edit","edit2"); testPostScalar($rule2,"Error","error2"); testPostScalar($rule2,"From","from2"); testPostScalar($rule2,"Offline","offline2"); testPostScalar($rule2,"Reply","reply2"); testPostScalar($rule2,"Resource","resource2"); testPostScalar($rule2,"Show","show2"); testPostScalar($rule2,"Size","size2"); testPostScalar($rule2,"Subject","subject2"); testPostScalar($rule2,"Time","time2"); testPostScalar($rule2,"Type","type2"); testPostScalar($rule2,"Unavailable","unavailable2"); is( $query->GetXML(), "body1continued1drop1edit1error1from1offline1reply1resource1show1size1subject1type1unavailable1body2continued2drop2edit2error2from2offline2reply2resource2show2size2subject2type2unavailable2", "GetXML()" ); my @rules = $query->GetRules(); is( $#rules, 1, "are there two rules?" ); is( $rules[0]->GetXML(), "body1continued1drop1edit1error1from1offline1reply1resource1show1size1subject1type1unavailable1", "GetXML()" ); is( $rules[1]->GetXML(), "body2continued2drop2edit2error2from2offline2reply2resource2show2size2subject2type2unavailable2", "GetXML()" ); Net-Jabber-2.0/t/protocol_muc.t0000644000175000017500000000106310110275744017556 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>4; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $client = new Net::Jabber::Client(); ok( defined($client), "new()" ); isa_ok( $client, "Net::Jabber::Client" ); my $presence_xml = $client->MUCJoin(room=>"test1", server=>"test2", nick=>"test3", '__netjabber__:test'=>1); is( $presence_xml, "", "GetXML()"); Net-Jabber-2.0/t/query_disco_info.t0000644000175000017500000000670010110275744020415 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>67; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/disco#info"); testScalar($query,"Node","node"); is( $query->GetXML(), "", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/disco#info"); $query2->SetDiscoInfo(node=>'node'); testPostScalar($query2,"Node","node"); is( $query2->GetXML(), "", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("query"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/disco#info"); testScalar($query3,"Node","node"); my $item = $query3->AddIdentity(); isa_ok( $item, "Net::Jabber::Stanza" ); isa_ok( $item, "Net::XMPP::Stanza" ); testScalar($item,"Category","category1"); testScalar($item,"Name","name1"); testScalar($item,"Type","type1"); is( $query3->GetXML(), "", "GetXML()" ); my $feature = $query3->AddFeature(); isa_ok( $feature, "Net::Jabber::Stanza" ); isa_ok( $feature, "Net::XMPP::Stanza" ); testScalar($feature,"Var","var1"); is( $query3->GetXML(), "", "GetXML()" ); my $item2 = $query3->AddIdentity(category=>"category2", name=>"name2", type=>"type2" ); isa_ok( $item2, "Net::Jabber::Stanza" ); isa_ok( $item2, "Net::XMPP::Stanza" ); testPostScalar($item2,"Category","category2"); testPostScalar($item2,"Name","name2"); testPostScalar($item2,"Type","type2"); is( $query3->GetXML(), "", "GetXML()" ); my $feature2 = $query3->AddFeature(var=>"var2"); isa_ok( $feature2, "Net::Jabber::Stanza" ); isa_ok( $feature2, "Net::XMPP::Stanza" ); testPostScalar($feature2,"Var","var2"); is( $query3->GetXML(), "", "GetXML()" ); my @idents = $query3->GetIdentities(); is($#idents,1,"two identities"); is( $idents[0]->GetXML(), "","item 1 - GetXML()"); is( $idents[1]->GetXML(), "","item 2 - GetXML()"); my @feats = $query3->GetFeatures(); is($#feats,1,"two features"); is( $feats[0]->GetXML(), "","item 1 - GetXML()"); is( $feats[1]->GetXML(), "","item 2 - GetXML()"); Net-Jabber-2.0/t/mytestlib.pl0000644000175000017500000000621410110275744017240 0ustar reatmonreatmon00000000000000 sub testDefined { my ($obj, $tag) = @_; my $ltag = lc($tag); my $defined; eval "\$defined = \$obj->Defined$tag();"; is( $defined, 1, "$ltag defined" ); } sub testNotDefined { my ($obj, $tag) = @_; my $ltag = lc($tag); my $defined; eval "\$defined = \$obj->Defined$tag();"; is( $defined, '', "$ltag not defined" ); } sub testDefinedField { my ($hash, $tag) = @_; my $ltag = lc($tag); ok( exists($hash->{$ltag}), "$ltag defined" ); } sub testScalar { my ($obj, $tag, $value) = @_; my $ltag = lc($tag); testNotDefined(@_); testSetScalar(@_); } sub testSetScalar { my ($obj, $tag, $value) = @_; my $ltag = lc($tag); eval "\$obj->Set$tag(\$value);"; testPostScalar(@_); } sub testPostScalar { my ($obj, $tag, $value) = @_; my $ltag = lc($tag); testDefined(@_); my $get; eval "\$get = \$obj->Get$tag();"; is( $get, $value, "$ltag eq '$value'" ); } sub testFieldScalar { my ($hash, $tag, $value) = @_; my $ltag = lc($tag); testDefinedField(@_); is( $hash->{$ltag}, $value , "$ltag eq '$value'"); } sub testFlag { my ($obj, $tag) = @_; my $ltag = lc($tag); testNotDefined($obj,$tag,''); my $get; eval "\$get = \$obj->Get$tag();"; is( $get, '', "$ltag is not set" ); testSetFlag(@_); } sub testSetFlag { my ($obj, $tag) = @_; my $ltag = lc($tag); eval "\$obj->Set$tag();"; testPostFlag(@_); } sub testPostFlag { my ($obj, $tag) = @_; my $ltag = lc($tag); testDefined(@_); my $get; eval "\$get = \$obj->Get$tag();"; is( $get, 1, "$ltag is set" ); } sub testFieldFlag { my ($hash, $tag) = @_; my $ltag = lc($tag); testDefinedField(@_); is( $hash->{$ltag}, 1 , "$ltag is set"); } sub testJID { my ($obj, $tag, $user, $server, $resource) = @_; my $ltag = lc($tag); testNotDefined(@_); testSetJID(@_); } sub testSetJID { my ($obj, $tag, $user, $server, $resource) = @_; my $ltag = lc($tag); my $value = $user.'@'.$server.'/'.$resource; eval "\$obj->Set$tag(\$value);"; testPostJID(@_); } sub testPostJID { my ($obj, $tag, $user, $server, $resource) = @_; my $ltag = lc($tag); my $value = $user.'@'.$server.'/'.$resource; testDefined(@_); my $get; eval "\$get = \$obj->Get$tag();"; is( $get, $value, "$ltag eq '$value'" ); my $jid; eval "\$jid = \$obj->Get$tag(\"jid\");"; ok( defined($jid), "jid object defined"); isa_ok( $jid, 'Net::Jabber::JID'); isa_ok( $jid, 'Net::XMPP::JID'); is( $jid->GetUserID(), $user , "user eq '$user'"); is( $jid->GetServer(), $server , "server eq '$server'"); is( $jid->GetResource(), $resource , "resource eq '$resource'"); } sub testFieldJID { my ($hash, $tag, $user, $server, $resource) = @_; my $ltag = lc($tag); testDefined(@_); my $jid = $hash->{$ltag}; isa_ok( $jid, 'Net::Jabber::JID'); isa_ok( $jid, 'Net::XMPP::JID'); is( $jid->GetUserID(), $user , "user eq '$user'"); is( $jid->GetServer(), $server , "server eq '$server'"); is( $jid->GetResource(), $resource , "resource eq '$resource'"); } 1; Net-Jabber-2.0/t/query_last.t0000644000175000017500000000211710110275744017242 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>28; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:last"); testSetScalar($query,"Message","message"); testScalar($query,"Seconds",2000); is( $query->GetXML(), "message", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:last"); $query2->SetLast(message=>"message", seconds=>1000 ); testPostScalar($query2,"Message","message"); testPostScalar($query2,"Seconds",1000); is( $query2->GetXML(), "message", "GetXML()" ); my %fields = $query2->GetLast(); testFieldScalar(\%fields,"Message","message"); testFieldScalar(\%fields,"Seconds",1000); Net-Jabber-2.0/t/protocol_definenamespace.t0000644000175000017500000002500010110275744022076 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>70; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $client = new Net::Jabber::Client(); ok( defined($client), "new()" ); isa_ok( $client, "Net::Jabber::Client" ); $client->DefineNamespace(xmlns=>"foo:bar:1", type=>"X", functions=>[{name=>"Data", get=>"data", set=>["scalar","data"], defined=>"data", hash=>"data" }, {name=>"Attrib", get=>"attrib", set=>["scalar","attrib"], defined=>"attrib", hash=>"att" }, {name=>"ChildFlag", get=>"childflag", set=>["flag","childflag"], defined=>"childflag", hash=>"child-flag", }, { name=>"ChildData", get=>"childdata", set=>["scalar","childdata"], defined=>"childdata", hash=>"child-data", }, { name=>"AttTagAtt", get=>"atttagatt", set=>["scalar","atttagatt"], defined=>"atttagatt", hash=>"att-tag-att", }, {name=>"FooBar", get=>"__netjabber__:master", set=>["master"] } ] ); my $message = new Net::Jabber::Message(); ok( defined($message), "new()"); isa_ok( $message, "Net::Jabber::Message" ); my $x = $message->NewChild("foo:bar:1"); ok( defined($x), "NewChild()"); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testSetScalar($x,"Data","data"); testScalar($x,"Attrib","attrib"); testFlag($x,"ChildFlag"); testScalar($x,"ChildData","data"); testScalar($x,"AttTagAtt","attrib"); is( $message->GetXML(), "datadata", "GetXML()" ); eval { $client->DefineNamespace(xmlns=>"foo:bar:2", type=>"X", functions=>[{name=>"Data", get=>"data", set=>["scalar","data"], defined=>"data", hash=>"data" }, {name=>"Attrib", get=>"attrib", set=>["scalar","attrib"], defined=>"attrib", hash=>"att" }, {name=>"ChildFlag", get=>"childflag", set=>["flag","childflag"], defined=>"childflag", hash=>"child-flag", }, { name=>"ChildData", get=>"childdata", set=>["scalar","childdata"], defined=>"childdata", hash=>"child-data", }, { name=>"ChildAdd", get=>"childadd", set=>["add","X","__netjabber__:foo:bar"], add=>["X","__netjabber__:foo:bar","FooBar","childadd"], defined=>"childdata", hash=>"child-add", }, { name=>"AttTagAtt", get=>"atttagatt", set=>["scalar","atttagatt"], defined=>"atttagatt", hash=>"att-tag-att", }, { name=>"ChildAdds", get=>["__netjabber__:children:x","__netjabber__:foo:bar"] }, {name=>"FooBar", get=>"__netjabber__:master", set=>["master"] } ] ); }; ok( $@ ne "", "croak test" ); $client->DefineNamespace(xmlns=>"foo:bar:3", type=>"X", functions=>[{name=>"Data", path=>"text()", }, {name=>"Attrib", path=>"\@attrib", }, {name=>"ChildFlag", type=>"flag", path=>"childflag", }, { name=>"ChildData", path=>"childdata/text()", }, { name=>"AttTagAtt", path=>"tag/\@att", }, {name=>"FooBar", type=>"master", } ] ); my $message2 = new Net::Jabber::Message(); ok( defined($message2), "new()"); isa_ok( $message2, "Net::Jabber::Message" ); my $x2 = $message2->NewChild("foo:bar:3"); ok( defined($x2), "NewChild()"); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testSetScalar($x2,"Data","data"); testScalar($x2,"Attrib","attrib"); testFlag($x2,"ChildFlag"); testScalar($x2,"ChildData","data"); testScalar($x2,"AttTagAtt","attrib"); is( $message2->GetXML(), "datadata", "GetXML()" ); $client->DefineNamespace(xmlns=>"foo:bar:4", type=>"X", functions=>[{name=>"Data", path=>"text()", }, {name=>"Attrib", path=>"\@attrib", }, {name=>"ChildFlag", type=>"flag", path=>"childflag", }, { name=>"ChildData", path=>"childdata/text()", }, { name=>"AttTagAtt", path=>"tag/\@att", }, { name=>"ChildAdd", path=>"childadd", type=>"node", child=>["X","__netjabber__:foo:bar:4"], calls=>["Add"] }, { name=>"ChildAdds", type=>"children", path=>"childadd", child=>["X","__netjabber__:foo:bar:4"], }, {name=>"FooBar", type=>"master", } ] ); $client->DefineNamespace(xmlns=>"__netjabber__:foo:bar:4", type=>"X", functions=>[{name=>"Data", path=>"text()", }, {name=>"AddedChild", type=>"master", } ] ); my $message3 = new Net::Jabber::Message(); ok( defined($message3), "new()"); isa_ok( $message3, "Net::Jabber::Message" ); my $x3 = $message3->NewChild("foo:bar:4"); ok( defined($x3), "NewChild()"); isa_ok( $x3, "Net::Jabber::Stanza" ); isa_ok( $x3, "Net::XMPP::Stanza" ); testSetScalar($x3,"Data","data"); testScalar($x3,"Attrib","attrib"); testFlag($x3,"ChildFlag"); testScalar($x3,"ChildData","data"); testScalar($x3,"AttTagAtt","attrib"); my $childadd1 = $x3->AddChildAdd(); testSetScalar($childadd1,"Data","data1"); my $childadd2 = $x3->AddChildAdd(data=>"data2"); my @children = $x3->GetChildAdds(); is( $#children, 1, "are there two kids?" ); is( $message3->GetXML(), "datadatadata1data2", "GetXML()" ); Net-Jabber-2.0/t/jid.t0000644000175000017500000000172310110275744015622 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>15; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $jid = new Net::Jabber::JID('host.com/xxx@yyy.com/zzz'); ok( defined($jid), "new()" ); isa_ok( $jid, "Net::Jabber::JID" ); is( $jid->GetUserID(), '', "GetUserID()" ); is( $jid->GetServer(), 'host.com', "GetServer()" ); is( $jid->GetResource(), 'xxx@yyy.com/zzz', "GetResource()" ); is( $jid->GetJID("full"), 'host.com/xxx@yyy.com/zzz', "GetJID(\"full\")" ); is( $jid->GetJID("base"), 'host.com', "GetJID(\"base\")" ); my $jid2 = new Net::Jabber::JID('user@host.com/xxx@yyy.com/zzz'); ok( defined($jid2), "new()" ); isa_ok( $jid2, "Net::Jabber::JID" ); is( $jid2->GetUserID(), 'user', "GetUserID()" ); is( $jid2->GetServer(), 'host.com', "GetServer()" ); is( $jid2->GetResource(), 'xxx@yyy.com/zzz', "GetResource()" ); is( $jid2->GetJID("full"), 'user@host.com/xxx@yyy.com/zzz', "GetJID(\"full\")" ); is( $jid2->GetJID("base"), 'user@host.com', "GetJID(\"base\")" ); Net-Jabber-2.0/t/x_muc.t0000644000175000017500000000152510110275745016170 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>20; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","http://jabber.org/protocol/muc"); testScalar($x, "Password", "password"); is( $x->GetXML(), "password", "GetXML()"); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","http://jabber.org/protocol/muc"); $x2->SetMUC(password=>"password"); testPostScalar($x2, "Password", "password"); is( $x2->GetXML(), "password", "GetXML()"); Net-Jabber-2.0/t/x_roster.t0000644000175000017500000000442110110275745016720 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>66; BEGIN{ use_ok( "Net::Jabber" ); } my $debug = new Net::XMPP::Debug(setdefault=>1, level=>-1, file=>"stdout", header=>"test", ); require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:roster"); my $item1 = $x->AddItem(); ok( defined($x), "AddItem()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($item1, "Group", "group"); testJID($item1, "JID", "user1", "server1", "resource1"); testScalar($item1, "Name", "name"); is( $x->GetXML(), "group", "GetXML()" ); my $item2 = $x->AddItem(group=>["group1","group2"], jid=>"user2\@server2/resource2", name=>"user2"); ok( $item2->DefinedGroup(), "group defined"); my @groups = $item2->GetGroup(); is_deeply(\@groups, ["group1","group2"], "groups match"); testPostJID($item2, "JID", "user2", "server2", "resource2"); testPostScalar($item2, "Name", "user2"); is( $x->GetXML(), "groupgroup1group2", "GetXML()" ); my @items = $x->GetItems(); is( $#items, 1, "two items"); testPostScalar($items[0], "Group", "group"); testPostJID($items[0], "JID", "user1", "server1", "resource1"); testPostScalar($items[0], "Name", "name"); is( $items[0]->GetXML(), "group", "GetXML()"); my @groups2 = $items[1]->GetGroup(); is_deeply(\@groups2, ["group1","group2"], "groups match"); testPostJID($items[1], "JID", "user2", "server2", "resource2"); testPostScalar($items[1], "Name", "user2"); is( $items[1]->GetXML(), "group1group2", "GetXML()"); $x->RemoveItems(); is( $x->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/query_time.t0000644000175000017500000000326110110275744017236 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>39; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:time"); testScalar($query,"Display","display"); testScalar($query,"TZ","tz"); testScalar($query,"UTC","utc"); is( $query->GetXML(), "displaytzutc", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:time"); $query2->SetTime(display=>"display", tz=>"tz", utc=>"utc" ); testPostScalar($query2,"Display","display"); testPostScalar($query2,"TZ","tz"); testPostScalar($query2,"UTC","utc"); is( $query2->GetXML(), "displaytzutc", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("query"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","jabber:iq:time"); $query3->SetTime(); like( $query3->GetUTC(), qr/^\d\d\d\d\d\d\d\dT\d\d:\d\d:\d\d$/, "look like a utc?" ); like( $query3->GetDisplay(), qr/^\w\w\w \w\w\w \d\d, \d\d\d\d \d\d:\d\d:\d\d$/, "look like a display?" ); SKIP: { eval("use Time::Timezone 99.062401;"); skip "Time::Timezone not installed", 1 if $@; like( $query3->GetTZ(), qr/^\S+$/, "look like a timezone?" ); } Net-Jabber-2.0/t/query_pubsub_event.t0000644000175000017500000000637210110275745021010 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>48; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $line = "-"x40; #------------------------------------------------------------------------------ # Delete #------------------------------------------------------------------------------ my $query1 = new Net::Jabber::Stanza("pubsub"); ok( defined($query1), "new() - delete $line" ); isa_ok( $query1, "Net::Jabber::Stanza" ); isa_ok( $query1, "Net::XMPP::Stanza" ); testScalar($query1,"XMLNS","http://jabber.org/protocol/pubsub#event"); is( $query1->GetXML(), "", "GetXML()" ); my $delete1 = $query1->AddDelete(); testScalar($delete1,"Node","node1"); is( $query1->GetXML(), "", "GetXML()" ); my $delete2 = $query1->AddDelete(node=>'node2'); testPostScalar($delete2,"Node","node2"); is( $query1->GetXML(), "", "GetXML()" ); my @deletes = $query1->GetDelete(); is( $#deletes, 1, "two deletes"); is( $deletes[0]->GetXML(), "", "delete[0]"); is( $deletes[1]->GetXML(), "", "delete[1]"); #------------------------------------------------------------------------------ # Items #------------------------------------------------------------------------------ my $query7 = new Net::Jabber::Stanza("pubsub"); ok( defined($query7), "new() - items $line" ); isa_ok( $query7, "Net::Jabber::Stanza" ); isa_ok( $query7, "Net::XMPP::Stanza" ); testScalar($query7,"XMLNS","http://jabber.org/protocol/pubsub#event"); is( $query7->GetXML(), "", "GetXML()" ); my $items1 = $query7->AddItems(); testScalar($items1,"Node","node1"); is( $query7->GetXML(), "", "GetXML()" ); my $item1 = $items1->AddItem(); testScalar($item1,"ID","id1"); testScalar($item1,"Payload",""); is( $query7->GetXML(), "", "GetXML()" ); my $item2 = $items1->AddItem(id=>"id2", payload=>""); testPostScalar($item2,"ID","id2"); testPostScalar($item2,"Payload",""); is( $query7->GetXML(), "", "GetXML()" ); $query7->AddItems(); is( $query7->GetXML(), "", "GetXML()" ); my @items = $query7->GetItems(); is( $#items, 1, "two items"); is( $items[0]->GetXML(), "","items[0]"); is( $items[1]->GetXML(), "","items[1]"); my @item = $items[0]->GetItem(); is( $#item, 1, "two item"); is( $item[0]->GetXML(), "","item[0]"); is( $item[1]->GetXML(), "","item[1]"); Net-Jabber-2.0/t/query_agent.t0000644000175000017500000000503110110275744017373 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>91; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:agent"); testFlag($query,"Agents"); testScalar($query,"Description","this is something"); testJID($query,"JID","user","server","resource"); testFlag($query,"GroupChat"); testScalar($query,"Name","name"); testFlag($query,"Register"); testFlag($query,"Search"); testScalar($query,"Service","service"); testScalar($query,"Transport","transport"); testScalar($query,"URL","url"); is( $query->GetXML(), "this is somethingnameservicetransporturl", "GetXML()"); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:agent"); testNotDefined($query2,"Agents"); testNotDefined($query2,"Description"); testNotDefined($query2,"JID"); testNotDefined($query2,"Name"); testNotDefined($query2,"GroupChat"); testNotDefined($query2,"Register"); testNotDefined($query2,"Search"); testNotDefined($query2,"Service"); testNotDefined($query2,"Transport"); testNotDefined($query2,"URL"); $query2->SetAgent(agents=>1, description=>"this is something", jid=>"user\@server/resource", name=>"name", groupchat=>1, register=>1, search=>1, service=>"service", transport=>"transport", url=>"url"); testPostFlag($query2,"Agents"); testPostScalar($query2,"Description","this is something"); testPostJID($query2,"JID","user","server","resource"); testPostScalar($query2,"Name","name"); testPostFlag($query2,"GroupChat"); testPostFlag($query2,"Register"); testPostFlag($query2,"Search"); testPostScalar($query2,"Service","service"); testPostScalar($query2,"Transport","transport"); testPostScalar($query2,"URL","url"); is( $query2->GetXML(), "this is somethingnameservicetransporturl", "GetXML()"); Net-Jabber-2.0/t/query_muc_admin.t0000644000175000017500000000505710110275744020241 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>72; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS",'http://jabber.org/protocol/muc#admin'); my $item1 = $query->AddItem(); ok( defined($item1), "new()" ); isa_ok( $item1, "Net::Jabber::Stanza" ); isa_ok( $item1, "Net::XMPP::Stanza" ); testJID($item1,"ActorJID","user1", "server1", "resource1"); testScalar($item1,"Affiliation","affiliation"); testJID($item1,"JID","user2", "server2", "resource2"); testScalar($item1,"Nick","nick"); testScalar($item1,"Reason","reason"); testScalar($item1,"Role","role"); is( $query->GetXML(), "reason", "GetXML()"); my $item2 = $query->AddItem(actorjid=>'user3@server3/resource3', affiliation=>"affiliation", jid=>'user4@server4/resource4', nick=>"nick", reason=>"reason", role=>"role"); ok( defined($item2), "new()" ); isa_ok( $item2, "Net::Jabber::Stanza" ); isa_ok( $item2, "Net::XMPP::Stanza" ); testPostJID($item2,"ActorJID","user3", "server3", "resource3"); testPostScalar($item2,"Affiliation","affiliation"); testPostJID($item2,"JID","user4", "server4", "resource4"); testPostScalar($item2,"Nick","nick"); testPostScalar($item2,"Reason","reason"); testPostScalar($item2,"Role","role"); is( $query->GetXML(), "reasonreason", "GetXML()"); my @items = $query->GetItems(); is( $#items, 1, "are there two items?" ); is( $items[0]->GetXML(), "reason", "GetXML()" ); is( $items[1]->GetXML(), "reason", "GetXML()" ); Net-Jabber-2.0/t/query_browse.t0000644000175000017500000001310110110275744017573 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>167; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("item"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:browse"); testScalar($query,"Category","category"); testJID($query,"JID","user1","server1","resource1"); testScalar($query,"Name","name"); testScalar($query,"Type","type"); testScalar($query,"NS","ns"); is( $query->GetXML(), "ns", "GetXML()" ); my $item1 = $query->AddItem(); ok( defined($item1), "new()" ); isa_ok( $item1, "Net::Jabber::Stanza" ); isa_ok( $item1, "Net::XMPP::Stanza" ); testScalar($item1,"Category","category"); testJID($item1,"JID","user2","server2","resource2"); testScalar($item1,"Name","name"); testScalar($item1,"Type","type"); testScalar($item1,"NS","ns"); is( $item1->GetXML(), "ns", "GetXML()" ); my $item2 = $query->AddItem(category=>"category", jid=>"user3\@server3/resource3", name=>"name", type=>"type", ns=>["ns1","ns2"] ); ok( defined($item2), "new()" ); isa_ok( $item2, "Net::Jabber::Stanza" ); isa_ok( $item2, "Net::XMPP::Stanza" ); testPostScalar($item2,"Category","category"); testPostJID($item2,"JID","user3","server3","resource3"); testPostScalar($item2,"Name","name"); testPostScalar($item2,"Type","type"); is( $item2->GetXML(), "ns1ns2", "GetXML()" ); is( $query->GetXML(), "nsnsns1ns2", "GetXML()" ); my @items = $query->GetItems(); is( $#items, 1, "are there two items?" ); is( $items[0]->GetXML(), "ns", "GetXML()" ); is( $items[1]->GetXML(), "ns1ns2", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("item"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:browse"); $query2->SetBrowse(category=>"category", jid=>"user2\@server2/resource2", name=>"name", type=>"type", ns=>["ns1","ns2"] ); testPostScalar($query2,"Category","category"); testPostJID($query2,"JID","user2","server2","resource2"); testPostScalar($query2,"Name","name"); testPostScalar($query2,"Type","type"); my @ns = $query2->GetNS(); is( $#ns, 1, "are there two ns?" ); is( $ns[0], "ns1", "ns[0] == 'ns1'" ); is( $ns[1], "ns2", "ns[1] == 'ns2'" ); is( $query2->GetXML(), "ns1ns2", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("service"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","jabber:iq:browse"); testJID($query3,"JID","user3","server3","resource3"); testScalar($query3,"Name","name"); testScalar($query3,"Type","type"); testScalar($query3,"NS","ns"); is( $query3->GetXML(), "ns", "GetXML()" ); my $item3 = $query3->AddItem("service"); ok( defined($item3), "new()" ); isa_ok( $item3, "Net::Jabber::Stanza" ); isa_ok( $item3, "Net::XMPP::Stanza" ); testJID($item3,"JID","user4","server4","resource4"); testScalar($item3,"Name","name"); testScalar($item3,"Type","type"); testScalar($item3,"NS","ns"); is( $item3->GetXML(), "ns", "GetXML()" ); my $item4 = $query3->AddItem("conference", jid=>"user5\@server5/resource5", name=>"name", type=>"type" ); ok( defined($item4), "new()" ); isa_ok( $item4, "Net::Jabber::Stanza" ); isa_ok( $item4, "Net::XMPP::Stanza" ); testPostJID($item4,"JID","user5","server5","resource5"); testPostScalar($item4,"Name","name"); testPostScalar($item4,"Type","type"); is( $item4->GetXML(), "", "GetXML()" ); is( $query3->GetXML(), "nsns", "GetXML()" ); @items = $query3->GetItems(); is( $#items, 1, "are there two items?" ); is( $items[0]->GetXML(), "ns", "GetXML()" ); is( $items[1]->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/rawxml.t0000644000175000017500000000414010110275744016362 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>59; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $message = new Net::Jabber::Message(); ok( defined($message), "new()"); isa_ok( $message, "Net::Jabber::Message"); testScalar($message, "Body", "body"); testJID($message, "From", "user1", "server1", "resource1"); testScalar($message, "Subject", "subject"); testJID($message, "To", "user2", "server2", "resource2"); $message->InsertRawXML("bar"); $message->InsertRawXML("foo"); is( $message->GetXML(), "bodysubjectbarfoo", "GetXML()" ); $message->ClearRawXML(); is( $message->GetXML(), "bodysubject", "GetXML()" ); $message->InsertRawXML("foo"); is( $message->GetXML(), "bodysubjectfoo", "GetXML()" ); my $iq = new Net::Jabber::IQ(); ok( defined($iq), "new()"); isa_ok( $iq, "Net::Jabber::IQ"); testJID($iq, "From", "user1", "server1", "resource1"); testJID($iq, "To", "user2", "server2", "resource2"); my $query = $iq->NewChild("jabber:iq:auth"); ok( defined($query), "AddQuery()"); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testPostScalar( $query, "XMLNS", "jabber:iq:auth"); is( $iq->GetXML(), "", "GetXML()"); $iq->InsertRawXML(""); is( $iq->GetXML(), "", "GetXML()"); $query->InsertRawXML(""); is( $query->GetXML(), "", "GetXML()"); is( $iq->GetXML(), "", "GetXML()"); Net-Jabber-2.0/t/x_data.t0000644000175000017500000001603410110275744016315 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>155; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x, "XMLNS", "jabber:x:data"); testScalar($x, "Instructions", "do this"); testScalar($x, "Title", "title"); testScalar($x, "Type", "type"); my $field = $x->AddField(); ok( defined($field), "AddField()" ); isa_ok( $field, "Net::Jabber::Stanza" ); isa_ok( $field, "Net::XMPP::Stanza" ); testScalar($field, "Desc", "desc"); testScalar($field, "Label", "label"); testFlag($field, "Required"); testScalar($field, "Type", "type"); testScalar($field, "Value", "value"); testScalar($field, "Var", "var"); $field->SetValue("value2"); my @values = $field->GetValue(); is( $values[0], "value", "check value 1" ); is( $values[1], "value2", "check value 2" ); my $option = $field->AddOption(); ok( defined($option), "AddOption()" ); isa_ok( $option, "Net::Jabber::Stanza" ); isa_ok( $option, "Net::XMPP::Stanza" ); testScalar($option, "Label", "label"); testScalar($option, "Value", "value"); my $field2 = $x->AddField(); ok( defined($field2), "AddField()" ); isa_ok( $field2, "Net::Jabber::Stanza" ); isa_ok( $field2, "Net::XMPP::Stanza" ); my $option2 = $field2->AddOption(); ok( defined($option2), "AddOption()" ); isa_ok( $option2, "Net::Jabber::Stanza" ); isa_ok( $option2, "Net::XMPP::Stanza" ); my @testFields = $x->GetFields(); is( $#testFields, 1, "Only two fields..."); my $testField = $testFields[0]; testPostScalar($testField, "Desc", "desc"); testPostScalar($testField, "Label", "label"); is( $testField->DefinedRequired(), 1, "required defined" ); ok( $testField->GetRequired(), "required" ); testPostScalar($testField, "Type", "type"); testPostScalar($testField, "Var", "var"); my @testOptions = $testField->GetOptions(); is( $#testOptions, 0, "Only two options..."); my $testOption = $testOptions[0]; testPostScalar($testOption, "Label", "label"); testPostScalar($testOption, "Value", "value"); is( $x->GetXML(), "do thistitledescvaluevalue2", "GetXML()" ); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2, "XMLNS", "jabber:x:data"); $x2->SetData(instructions=>"do this", title=>"title", type=>"type"); testPostScalar($x2, "Instructions", "do this"); testPostScalar($x2, "Title", "title"); testPostScalar($x2, "Type", "type"); my $field3 = $x2->AddField(); ok( defined($field3), "AddField()" ); isa_ok( $field3, "Net::Jabber::Stanza" ); isa_ok( $field3, "Net::XMPP::Stanza" ); testNotDefined($field3, "Desc"); testNotDefined($field3, "Label"); testNotDefined($field3, "Required"); testNotDefined($field3, "Type"); testNotDefined($field3, "Value"); testNotDefined($field3, "Var"); $field3->SetField(desc=>"desc", label=>"label", required=>1, type=>"type", value=>"value", var=>"var"); testPostScalar($field3, "Desc", "desc"); testPostScalar($field3, "Label", "label"); testPostFlag($field3, "Required"); testPostScalar($field3, "Type", "type"); testPostScalar($field3, "Value", "value"); testPostScalar($field3, "Var", "var"); my $option3 = $field3->AddOption(); ok( defined($option3), "AddOption()" ); isa_ok( $option3, "Net::Jabber::Stanza" ); isa_ok( $option3, "Net::XMPP::Stanza" ); testNotDefined($option3, "Label"); testNotDefined($option3, "Value"); $option3->SetOption(label=>"label", value=>"value"); testPostScalar($option3, "Label", "label"); testPostScalar($option3, "Value", "value"); is( $x2->GetXML(), "do thistitledescvalue", "GetXML()" ); my $x3 = new Net::Jabber::Stanza("x"); ok( defined($x3), "new()" ); isa_ok( $x3, "Net::Jabber::Stanza" ); isa_ok( $x3, "Net::XMPP::Stanza" ); testScalar($x3, "XMLNS", "jabber:x:data"); my $reported = $x3->AddReported(); ok( defined($reported), "new()" ); isa_ok( $reported, "Net::Jabber::Stanza" ); isa_ok( $reported, "Net::XMPP::Stanza" ); ok( defined($x3), "new()" ); isa_ok( $x3, "Net::Jabber::Stanza" ); isa_ok( $x3, "Net::XMPP::Stanza" ); $reported->AddField(var=>"var1", label=>"Var1"); $reported->AddField(var=>"var2", label=>"Var2"); is( $x3->GetXML(), "", "GetXML()"); my $x4 = new Net::Jabber::Stanza("x"); ok( defined($x4), "new()" ); isa_ok( $x4, "Net::Jabber::Stanza" ); isa_ok( $x4, "Net::XMPP::Stanza" ); testScalar($x4, "XMLNS", "jabber:x:data"); my $item = $x4->AddItem(); ok( defined($item), "new()" ); isa_ok( $item, "Net::Jabber::Stanza" ); isa_ok( $item, "Net::XMPP::Stanza" ); ok( defined($x4), "new()" ); isa_ok( $x4, "Net::Jabber::Stanza" ); isa_ok( $x4, "Net::XMPP::Stanza" ); $item->AddField(var=>"var1", label=>"Var1"); $item->AddField(var=>"var2", label=>"Var2"); is( $x4->GetXML(), "", "GetXML()"); my $item2 = $x4->AddItem(); ok( defined($item2), "new()" ); isa_ok( $item2, "Net::Jabber::Stanza" ); isa_ok( $item2, "Net::XMPP::Stanza" ); ok( defined($x4), "new()" ); isa_ok( $x4, "Net::Jabber::Stanza" ); isa_ok( $x4, "Net::XMPP::Stanza" ); $item2->AddField(var=>"var3", label=>"Var3", value=>"value3"); $item2->AddField(var=>"var4", label=>"Var4", value=>"value4"); is( $x4->GetXML(), "value3value4", "GetXML()"); my @items = $x4->GetItems(); is( $#items, 1, "are there two items?"); is( $items[0]->GetXML(), "", "GetXML()"); is( $items[1]->GetXML(), "value3value4", "GetXML()"); my @fields = $items[1]->GetFields(); is( $#fields, 1, "are there two fields?"); is( $fields[0]->GetXML(), "value3", "GetXML()"); is( $fields[1]->GetXML(), "value4", "GetXML()"); $fields[1]->RemoveValue(); is( $fields[1]->GetXML(), "", "GetXML()"); Net-Jabber-2.0/t/query_pass.t0000644000175000017500000000362310110275744017250 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>62; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:pass"); testScalar($query,"Client","client"); testScalar($query,"ClientPort",1234); testFlag($query,"Close"); testScalar($query,"Expire",10); testFlag($query,"OneShot"); testScalar($query,"Proxy","proxy"); testScalar($query,"ProxyPort",2345); testScalar($query,"Server","server"); testScalar($query,"ServerPort",3456); is( $query->GetXML(), "client10proxyserver", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:pass"); $query2->SetPass(client=>"client", clientport=>4321, close=>1, expire=>21, oneshot=>1, proxy=>"proxy", proxyport=>5432, server=>"server", serverport=>6543 ); testPostScalar($query2,"Client","client"); testPostScalar($query2,"ClientPort",4321); testPostFlag($query2,"Close"); testPostScalar($query2,"Expire",21); testPostFlag($query2,"OneShot"); testPostScalar($query2,"Proxy","proxy"); testPostScalar($query2,"ProxyPort",5432); testPostScalar($query2,"Server","server"); testPostScalar($query2,"ServerPort",6543); is( $query2->GetXML(), "client21proxyserver", "GetXML()" ); Net-Jabber-2.0/t/message.t0000644000175000017500000001335610110275744016505 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>126; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $debug = new Net::XMPP::Debug(setdefault=>1, level=>-1, file=>"stdout", header=>"test", ); #------------------------------------------------------------------------------ # message #------------------------------------------------------------------------------ my $message = new Net::Jabber::Message(); ok( defined($message), "new()"); isa_ok( $message, "Net::Jabber::Message"); isa_ok( $message, "Net::XMPP::Message"); testScalar($message, "Body", "body"); testScalar($message, "Error", "error"); testScalar($message, "ErrorCode", "401"); testJID($message, "From", "user1", "server1", "resource1"); testScalar($message, "ID", "id"); testScalar($message, "Subject", "subject"); testScalar($message, "Thread", "thread"); testJID($message, "To", "user2", "server2", "resource2"); testScalar($message, "Type", "Type"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my $xoob = $message->NewChild("jabber:x:oob"); ok( defined( $xoob ), "NewChild - jabber:x:oob" ); isa_ok( $xoob, "Net::XMPP::Stanza" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x = $message->GetChild(); is( $x[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my $xroster = $message->NewChild("jabber:x:roster"); ok( defined( $xroster ), "NewChild - jabber:x:roster" ); isa_ok( $xroster, "Net::XMPP::Stanza" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x2 = $message->GetChild(); is( $x2[0], $xoob, "Is the first x the oob?"); is( $x2[1], $xroster, "Is the second x the roster?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x3 = $message->GetChild("jabber:x:oob"); is( $#x3, 0, "filter on xmlns - only one x... right?"); is( $x3[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x4 = $message->GetChild("jabber:x:roster"); is( $#x4, 0, "filter on xmlns - only one x... right?"); is( $x4[0], $xroster, "Is the first x the roster?"); ok( $message->DefinedChild(), "DefinedX - yes"); ok( $message->DefinedChild("jabber:x:roster"), "DefinedX - jabber:x:roster - yes"); ok( $message->DefinedChild("jabber:x:oob"), "DefinedX - jabber:x:oob - yes"); ok( !$message->DefinedChild("foo:bar"), "DefinedX - foo:bar - no"); #------------------------------------------------------------------------------ # message #------------------------------------------------------------------------------ my $message2 = new Net::Jabber::Message(); ok( defined($message2), "new()"); isa_ok( $message2, "Net::Jabber::Message"); isa_ok( $message2, "Net::XMPP::Message"); #------------------------------------------------------------------------------ # defined #------------------------------------------------------------------------------ is( $message2->DefinedBody(), '', "body not defined" ); is( $message2->DefinedError(), '', "error not defined" ); is( $message2->DefinedErrorCode(), '', "errorcode not defined" ); is( $message2->DefinedFrom(), '', "from not defined" ); is( $message2->DefinedID(), '', "id not defined" ); is( $message2->DefinedSubject(), '', "subject not defined" ); is( $message2->DefinedThread(), '', "thread not defined" ); is( $message2->DefinedTo(), '', "to not defined" ); is( $message2->DefinedType(), '', "type not defined" ); #------------------------------------------------------------------------------ # set it #------------------------------------------------------------------------------ $message2->SetMessage(body=>"body", error=>"error", errorcode=>"401", from=>"user1\@server1/resource1", id=>"id", subject=>"subject", thread=>"thread", to=>"user2\@server2/resource2", type=>"type"); testPostScalar($message2, "Body", "body"); testPostScalar($message2, "Error", "error"); testPostScalar($message2, "ErrorCode", "401"); testPostJID($message2, "From", "user1", "server1", "resource1"); testPostScalar($message2, "ID", "id"); testPostScalar($message2, "Subject", "subject"); testPostScalar($message2, "Thread", "thread"); testPostJID($message2, "To", "user2", "server2", "resource2"); testPostScalar($message2, "Type", "type"); #------------------------------------------------------------------------------ # Reply #------------------------------------------------------------------------------ my $reply2 = $message2->Reply(); ok( defined($reply2), "new()"); isa_ok( $reply2, "Net::Jabber::Message"); isa_ok( $reply2, "Net::XMPP::Message"); testPostJID($reply2, "From", "user2", "server2", "resource2"); testPostScalar($reply2, "ID", "id"); testPostScalar($reply2, "Thread", "thread"); testPostJID($reply2, "To", "user1", "server1", "resource1"); testPostScalar($reply2, "Type", "type"); is( $reply2->GetXML(), "thread", "GetXML()"); Net-Jabber-2.0/t/x_signed.t0000644000175000017500000000137310110275745016656 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>19; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:signed"); testSetScalar($x,"Signature","signature"); is( $x->GetXML(), "signature", "GetXML()" ); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:signed"); $x2->SetSigned(signature=>"signature"); testPostScalar($x2, "Signature","signature"); is( $x2->GetXML(), "signature", "GetXML()" ); Net-Jabber-2.0/t/oldadd.t0000644000175000017500000001231610110275744016303 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>88; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $debug = new Net::XMPP::Debug(setdefault=>1, level=>-1, file=>"stdout", header=>"test", ); #------------------------------------------------------------------------------ # iq #------------------------------------------------------------------------------ my $iq = new Net::Jabber::IQ(); ok( defined($iq), "new()"); isa_ok( $iq, "Net::Jabber::IQ"); isa_ok( $iq, "Net::XMPP::IQ"); testScalar($iq, "Error", "error"); testScalar($iq, "ErrorCode", "401"); testJID($iq, "From", "user1", "server1", "resource1"); testScalar($iq, "ID", "id"); testJID($iq, "To", "user2", "server2", "resource2"); testScalar($iq, "Type", "Type"); is( $iq->DefinedQuery("jabber:x:oob"), "", "not DefinedChild - jabber:x:oob" ); is( $iq->DefinedQuery("jabber:iq:roster"), "", "not DefinedChild - jabber:iq:roster" ); #------------------------------------------------------------------------------ # query - roster #------------------------------------------------------------------------------ my $xroster = $iq->NewQuery("jabber:iq:roster"); ok( defined( $xroster ), "NewChild - jabber:iq:roster" ); isa_ok( $xroster, "Net::XMPP::Stanza" ); #------------------------------------------------------------------------------ # x - oob #------------------------------------------------------------------------------ my $xoob = $iq->NewX("jabber:x:oob"); ok( defined( $xoob ), "NewChild - jabber:x:oob" ); isa_ok( $xoob, "Net::XMPP::Stanza" ); #------------------------------------------------------------------------------ # DefinedChild... #------------------------------------------------------------------------------ is( $iq->DefinedQuery(), 1, "DefinedChild" ); is( $iq->DefinedQuery("jabber:iq:roster"), 1, "DefinedChild - jabber:iq:roster" ); is( $iq->DefinedX("jabber:x:oob"), 1, "DefinedChild - jabber:x:oob" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x2 = $iq->GetQuery(); is( $x2[0], $xroster, "Is the first the roster?"); is( $x2[1], $xoob, "Is the second the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x3 = $iq->GetX("jabber:x:oob"); is( $#x3, 0, "filter on xmlns - only one x... right?"); is( $x3[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x4 = $iq->GetQuery("jabber:iq:roster"); is( $#x4, 0, "filter on xmlns - only one x... right?"); is( $x4[0], $xroster, "Is the first x the roster?"); is( $iq->DefinedX("jabber:x:testns"), "", "not DefinedX - jabber:x:testns" ); #------------------------------------------------------------------------------ # iq #------------------------------------------------------------------------------ my $iq2 = new Net::Jabber::IQ(); ok( defined($iq2), "new()"); isa_ok( $iq2, "Net::Jabber::IQ"); #------------------------------------------------------------------------------ # defined #------------------------------------------------------------------------------ is( $iq2->DefinedError(), '', "error not defined" ); is( $iq2->DefinedErrorCode(), '', "errorcode not defined" ); is( $iq2->DefinedFrom(), '', "from not defined" ); is( $iq2->DefinedID(), '', "id not defined" ); is( $iq2->DefinedTo(), '', "to not defined" ); is( $iq2->DefinedType(), '', "type not defined" ); #------------------------------------------------------------------------------ # set it #------------------------------------------------------------------------------ $iq2->SetIQ(error=>"error", errorcode=>"401", from=>"user1\@server1/resource1", id=>"id", to=>"user2\@server2/resource2", type=>"type"); testPostScalar($iq, "Error", "error"); testPostScalar($iq, "ErrorCode", "401"); testPostJID($iq, "From", "user1", "server1", "resource1"); testPostScalar($iq, "ID", "id"); testPostJID($iq, "To", "user2", "server2", "resource2"); testPostScalar($iq, "Type", "Type"); my $iq3 = new Net::Jabber::IQ(); ok( defined($iq3), "new()"); isa_ok( $iq3, "Net::Jabber::IQ"); $iq3->SetIQ(error=>"error", errorcode=>"401", from=>"user1\@server1/resource1", id=>"id", to=>"user2\@server2/resource2", type=>"type"); my $query = $iq3->NewQuery("jabber:iq:auth"); ok( defined($query), "new()"); isa_ok( $query, "Net::XMPP::Stanza"); $query->SetAuth(username=>"user", password=>"pass"); is( $iq3->GetXML(), "errorpassuser", "GetXML()"); my $reply = $iq3->Reply(); is( $reply->GetXML(), "", "GetXML()"); Net-Jabber-2.0/t/query_featureneg.t0000644000175000017500000000230210110275744020420 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>22; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("feature"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/feature-neg"); is( $query->GetXML(), "", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("feature"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/feature-neg"); $query2->SetFeatureNeg(); is( $query2->GetXML(), "", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("feature"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/feature-neg"); my $xdata = $query3->NewChild("jabber:x:data"); is( $query3->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/query_pubsub_owner.t0000644000175000017500000000277310110275745021022 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>22; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $line = "-"x40; #------------------------------------------------------------------------------ # Delete #------------------------------------------------------------------------------ my $query1 = new Net::Jabber::Stanza("pubsub"); ok( defined($query1), "new() - delete $line" ); isa_ok( $query1, "Net::Jabber::Stanza" ); isa_ok( $query1, "Net::XMPP::Stanza" ); testScalar($query1,"XMLNS","http://jabber.org/protocol/pubsub#owner"); is( $query1->GetXML(), "", "GetXML()" ); testScalar($query1,"Action","action1"); is( $query1->GetXML(), "", "GetXML()" ); my $delete1 = $query1->AddConfigure(); testScalar($delete1,"Node","node1"); is( $query1->GetXML(), "", "GetXML()" ); my $delete2 = $query1->AddConfigure(node=>'node2'); testPostScalar($delete2,"Node","node2"); is( $query1->GetXML(), "", "GetXML()" ); my @configure = $query1->GetConfigure(); is( $#configure, 1, "two configure"); is( $configure[0]->GetXML(), "", "configure[0]"); is( $configure[1]->GetXML(), "", "configure[1]"); Net-Jabber-2.0/t/query_autoupdate.t0000644000175000017500000000772010110275744020457 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>97; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:autoupdate"); my $dev = $query->AddDev(); ok( defined($dev), "new()" ); isa_ok( $dev, "Net::Jabber::Stanza" ); isa_ok( $dev, "Net::XMPP::Stanza" ); testScalar($dev,"Desc","desc"); testScalar($dev,"Priority","priority"); testScalar($dev,"URL","url"); testScalar($dev,"Version","version"); my $beta = $query->AddBeta(); ok( defined($beta), "new()" ); isa_ok( $beta, "Net::Jabber::Stanza" ); isa_ok( $beta, "Net::XMPP::Stanza" ); testScalar($beta,"Desc","desc"); testScalar($beta,"Priority","priority"); testScalar($beta,"URL","url"); testScalar($beta,"Version","version"); my $release = $query->AddRelease(); ok( defined($release), "new()" ); isa_ok( $release, "Net::Jabber::Stanza" ); isa_ok( $release, "Net::XMPP::Stanza" ); testScalar($release,"Desc","desc"); testScalar($release,"Priority","priority"); testScalar($release,"URL","url"); testScalar($release,"Version","version"); is( $query->GetXML(), "descurlversiondescurlversiondescurlversion", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:autoupdate"); my $dev2 = $query2->AddDev(desc=>"desc", priority=>"priority", url=>"url", version=>"version"); ok( defined($dev2), "new()" ); isa_ok( $dev2, "Net::Jabber::Stanza" ); isa_ok( $dev2, "Net::XMPP::Stanza" ); testPostScalar($dev2,"Desc","desc"); testPostScalar($dev2,"Priority","priority"); testPostScalar($dev2,"URL","url"); testPostScalar($dev2,"Version","version"); my $beta2 = $query2->AddBeta(desc=>"desc", priority=>"priority", url=>"url", version=>"version"); ok( defined($beta2), "new()" ); isa_ok( $beta2, "Net::Jabber::Stanza" ); isa_ok( $beta2, "Net::XMPP::Stanza" ); testPostScalar($beta2,"Desc","desc"); testPostScalar($beta2,"Priority","priority"); testPostScalar($beta2,"URL","url"); testPostScalar($beta2,"Version","version"); my $release2 = $query2->AddRelease(desc=>"desc", priority=>"priority", url=>"url", version=>"version"); ok( defined($release2), "new()" ); isa_ok( $release2, "Net::Jabber::Stanza" ); isa_ok( $release2, "Net::XMPP::Stanza" ); testPostScalar($release2,"Desc","desc"); testPostScalar($release2,"Priority","priority"); testPostScalar($release2,"URL","url"); testPostScalar($release2,"Version","version"); is( $query2->GetXML(), "descurlversiondescurlversiondescurlversion", "GetXML()" ); my @releases = $query2->GetReleases(); is( $#releases, 2, "are there three releases?" ); is( $releases[0]->GetXML(), "descurlversion", "GetXML()" ); is( $releases[1]->GetXML(), "descurlversion", "GetXML()" ); is( $releases[2]->GetXML(), "descurlversion", "GetXML()" ); Net-Jabber-2.0/t/x_autoupdate.t0000644000175000017500000000150410110275744017553 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>32; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:autoupdate"); testJID($x, "JID", "user", "server", "resource"); is( $x->GetXML(), "", "GetXML()" ); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:autoupdate"); $x2->SetAutoupdate(jid=>"user\@server/resource"); testPostJID($x2, "JID", "user", "server", "resource"); is( $x2->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/x_expire.t0000644000175000017500000000136410110275744016700 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>20; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:expire"); testScalar($x,"Seconds","seconds"); is( $x->GetXML(), "", "GetXML()"); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:expire"); $x2->SetExpire(seconds=>"seconds"); testPostScalar($x2,"Seconds","seconds"); is( $x2->GetXML(), "", "GetXML()"); Net-Jabber-2.0/t/1_load.t0000644000175000017500000000011610110275744016206 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>1; BEGIN{ use_ok( "Net::Jabber" ); } Net-Jabber-2.0/t/x_encrypted.t0000644000175000017500000000136610110275744017403 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>19; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:encrypted"); testSetScalar($x,"Message","message"); is( $x->GetXML(), "message", "GetXML()"); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:encrypted"); $x2->SetEncrypted(message=>"message"); testPostScalar($x2,"Message","message"); is( $x2->GetXML(), "message", "GetXML()"); Net-Jabber-2.0/t/presence.t0000644000175000017500000001256110110275744016662 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>117; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $debug = new Net::XMPP::Debug(setdefault=>1, level=>-1, file=>"stdout", header=>"test", ); #------------------------------------------------------------------------------ # presence #------------------------------------------------------------------------------ my $presence = new Net::Jabber::Presence(); ok( defined($presence), "new()"); isa_ok( $presence, "Net::Jabber::Presence"); isa_ok( $presence, "Net::XMPP::Presence"); testScalar($presence, "Error", "error"); testScalar($presence, "ErrorCode", "401"); testJID($presence, "From", "user1", "server1", "resource1"); testScalar($presence, "ID", "id"); testScalar($presence, "Priority", "priority"); testScalar($presence, "Show", "show"); testScalar($presence, "Status", "status"); testJID($presence, "To", "user2", "server2", "resource2"); testScalar($presence, "Type", "Type"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my $xoob = $presence->NewChild("jabber:x:oob"); ok( defined( $xoob ), "NewChild - jabber:x:oob" ); isa_ok( $xoob, "Net::XMPP::Stanza" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x = $presence->GetChild(); is( $x[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my $xroster = $presence->NewChild("jabber:x:roster"); ok( defined( $xoob ), "NewChild - jabber:x:roster" ); isa_ok( $xoob, "Net::XMPP::Stanza" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x2 = $presence->GetChild(); is( $x2[0], $xoob, "Is the first x the oob?"); is( $x2[1], $xroster, "Is the second x the roster?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x3 = $presence->GetChild("jabber:x:oob"); is( $#x3, 0, "filter on xmlns - only one x... right?"); is( $x3[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x4 = $presence->GetChild("jabber:x:roster"); is( $#x4, 0, "filter on xmlns - only one x... right?"); is( $x4[0], $xroster, "Is the first x the roster?"); #------------------------------------------------------------------------------ # presence #------------------------------------------------------------------------------ my $presence2 = new Net::Jabber::Presence(); ok( defined($presence2), "new()"); isa_ok( $presence2, "Net::Jabber::Presence"); #------------------------------------------------------------------------------ # defined #------------------------------------------------------------------------------ is( $presence2->DefinedError(), '', "error not defined" ); is( $presence2->DefinedErrorCode(), '', "errorcode not defined" ); is( $presence2->DefinedFrom(), '', "from not defined" ); is( $presence2->DefinedID(), '', "id not defined" ); is( $presence2->DefinedPriority(), '', "priority not defined" ); is( $presence2->DefinedShow(), '', "show not defined" ); is( $presence2->DefinedStatus(), '', "status not defined" ); is( $presence2->DefinedTo(), '', "to not defined" ); is( $presence2->DefinedType(), '', "type not defined" ); #------------------------------------------------------------------------------ # set it #------------------------------------------------------------------------------ $presence2->SetPresence(error=>"error", errorcode=>"401", from=>"user1\@server1/resource1", id=>"id", priority=>"priority", show=>"show", status=>"status", to=>"user2\@server2/resource2", type=>"type"); testPostScalar($presence2, "Error", "error"); testPostScalar($presence2, "ErrorCode", "401"); testPostJID($presence2, "From", "user1", "server1", "resource1"); testPostScalar($presence2, "ID", "id"); testPostScalar($presence2, "Priority", "priority"); testPostScalar($presence2, "Show", "show"); testPostScalar($presence2, "Status", "status"); testPostJID($presence2, "To", "user2", "server2", "resource2"); testPostScalar($presence2, "Type", "type"); #------------------------------------------------------------------------------ # Reply #------------------------------------------------------------------------------ my $reply2 = $presence2->Reply(); ok( defined($reply2), "new()"); isa_ok( $reply2, "Net::Jabber::Presence"); isa_ok( $reply2, "Net::XMPP::Presence"); testPostJID($reply2, "From", "user2", "server2", "resource2"); testPostScalar($reply2, "ID", "id"); testPostJID($reply2, "To", "user1", "server1", "resource1"); is( $reply2->GetXML(), "", "GetXML()"); Net-Jabber-2.0/t/query_pubsub.t0000644000175000017500000007240010110275744017601 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>455; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $line = "-"x40; #------------------------------------------------------------------------------ # Affiliations #------------------------------------------------------------------------------ my $query1 = new Net::Jabber::Stanza("pubsub"); ok( defined($query1), "new() - affiliations $line" ); isa_ok( $query1, "Net::Jabber::Stanza" ); isa_ok( $query1, "Net::XMPP::Stanza" ); testScalar($query1,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query1->GetXML(), "", "GetXML()" ); my $affiliations = $query1->AddAffiliations(); my $aff_entity1 = $affiliations->AddEntity(); testScalar($aff_entity1,"Affiliation","affiliation1"); testJID($aff_entity1,"JID","user1","server1","resource1"); testScalar($aff_entity1,"Node","node1"); testScalar($aff_entity1,"Subscription","subscription1"); my $aff_entity1_subopt = $aff_entity1->AddSubscribeOptions(); testFlag($aff_entity1_subopt,"Required"); is( $query1->GetXML(), "", "GetXML()" ); my $aff_entity2 = $affiliations->AddEntity(affiliation=>'affiliation2', jid=>'user2@server2/resource2', node=>'node2', subscription=>'subscription2' ); my $aff_entity2_subopt = $aff_entity2->AddSubscribeOptions(required=>1); testPostScalar($aff_entity2,"Affiliation","affiliation2"); testPostJID($aff_entity2,"JID","user2","server2","resource2"); testPostScalar($aff_entity2,"Node","node2"); testPostScalar($aff_entity2,"Subscription","subscription2"); testPostFlag($aff_entity2_subopt,"Required"); is( $query1->GetXML(), "", "GetXML()" ); $query1->AddAffiliations(); is( $query1->GetXML(), "", "GetXML()" ); my @affiliations = $query1->GetAffiliations(); is( $#affiliations, 1, "two affiliations"); is( $affiliations[0]->GetXML(), "","affiliations[0]"); is( $affiliations[1]->GetXML(), "","affiliations[1]"); my @aff_entities = $affiliations[0]->GetEntity(); is( $#aff_entities, 1, "two entities"); is( $aff_entities[0]->GetXML(), "","aff_entities[0]"); ok( $aff_entities[0]->GetSubscribeOptions()->GetRequired(), "aff_entities[0] - subopts required"); is( $aff_entities[1]->GetXML(), "","aff_entities[1]"); ok( $aff_entities[1]->GetSubscribeOptions()->GetRequired(), "aff_entities[1] - subopts required"); $query1->RemoveAffiliations(); is( $query1->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Configure #------------------------------------------------------------------------------ my $query2 = new Net::Jabber::Stanza("pubsub"); ok( defined($query2), "new() - configure $line" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query2->GetXML(), "", "GetXML()" ); my $configure1 = $query2->AddConfigure(); testScalar($configure1,"Node","node1"); is( $query2->GetXML(), "", "GetXML()" ); my $configure2 = $query2->AddConfigure(node=>'node2'); testPostScalar($configure2,"Node","node2"); is( $query2->GetXML(), "", "GetXML()" ); my @configures = $query2->GetConfigure(); is( $#configures, 1, "two configures"); is( $configures[0]->GetXML(), "", "configure[0]"); is( $configures[1]->GetXML(), "", "configure[1]"); $query2->RemoveConfigure(); is( $query2->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Create #------------------------------------------------------------------------------ my $query3 = new Net::Jabber::Stanza("pubsub"); ok( defined($query3), "new() - create $line" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query3->GetXML(), "", "GetXML()" ); my $create1 = $query3->AddCreate(); is( $query3->GetXML(), "", "GetXML()" ); testScalar($create1,"Node","node1"); is( $query3->GetXML(), "", "GetXML()" ); my $create2 = $query3->AddCreate(node=>'node2'); testPostScalar($create2,"Node","node2"); is( $query3->GetXML(), "", "GetXML()" ); my @creates = $query3->GetCreate(); is( $#creates, 1, "two creates"); is( $creates[0]->GetXML(), "", "create[0]"); is( $creates[1]->GetXML(), "", "create[1]"); $query3->RemoveCreate(); is( $query3->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Delete #------------------------------------------------------------------------------ my $query4 = new Net::Jabber::Stanza("pubsub"); ok( defined($query4), "new() - delete $line" ); isa_ok( $query4, "Net::Jabber::Stanza" ); isa_ok( $query4, "Net::XMPP::Stanza" ); testScalar($query4,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query4->GetXML(), "", "GetXML()" ); my $delete1 = $query4->AddDelete(); testScalar($delete1,"Node","node1"); is( $query4->GetXML(), "", "GetXML()" ); my $delete2 = $query4->AddDelete(node=>'node2'); testPostScalar($delete2,"Node","node2"); is( $query4->GetXML(), "", "GetXML()" ); my @deletes = $query4->GetDelete(); is( $#deletes, 1, "two deletes"); is( $deletes[0]->GetXML(), "", "delete[0]"); is( $deletes[1]->GetXML(), "", "delete[1]"); $query4->RemoveDelete(); is( $query4->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Entities #------------------------------------------------------------------------------ my $query5 = new Net::Jabber::Stanza("pubsub"); ok( defined($query5), "new() - entities $line" ); isa_ok( $query5, "Net::Jabber::Stanza" ); isa_ok( $query5, "Net::XMPP::Stanza" ); testScalar($query5,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query5->GetXML(), "", "GetXML()" ); my $entities1 = $query5->AddEntities(); is( $query5->GetXML(), "", "GetXML()" ); my $ents_entity1 = $entities1->AddEntity(); testScalar($ents_entity1,"Affiliation","affiliation1"); testJID($ents_entity1,"JID","user1","server1","resource1"); testScalar($ents_entity1,"Node","node1"); testScalar($ents_entity1,"Subscription","subscription1"); is( $query5->GetXML(), "", "GetXML()" ); my $ents_entity2 = $entities1->AddEntity(affiliation=>"affiliation2", jid=>'user2@server2/resource2', node=>"node2", subscription=>"subscription2"); testPostScalar($ents_entity2,"Affiliation","affiliation2"); testPostJID($ents_entity2,"JID","user2","server2","resource2"); testPostScalar($ents_entity2,"Node","node2"); testPostScalar($ents_entity2,"Subscription","subscription2"); is( $query5->GetXML(), "", "GetXML()" ); $query5->AddEntities(); is( $query5->GetXML(), "", "GetXML()" ); my @ents_entities = $query5->GetEntities(); is( $#ents_entities, 1, "two entities"); is( $ents_entities[0]->GetXML(), "","ents_entities[0]"); is( $ents_entities[1]->GetXML(), "","ents_entities[1]"); my @ents_entity = $ents_entities[0]->GetEntity(); is( $#ents_entity, 1, "two entities"); is( $ents_entity[0]->GetXML(), "","ents_entities[0]"); is( $ents_entity[1]->GetXML(), "","ents_entities[1]"); $query5->RemoveEntities(); is( $query5->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Entity #------------------------------------------------------------------------------ my $query6 = new Net::Jabber::Stanza("pubsub"); ok( defined($query6), "new() - entity $line" ); isa_ok( $query6, "Net::Jabber::Stanza" ); isa_ok( $query6, "Net::XMPP::Stanza" ); testScalar($query6,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query6->GetXML(), "", "GetXML()" ); my $entity1 = $query6->AddEntity(); testScalar($entity1,"Affiliation","affiliation1"); testJID($entity1,"JID","user1","server1","resource1"); testScalar($entity1,"Node","node1"); testScalar($entity1,"Subscription","subscription1"); is( $query6->GetXML(), "", "GetXML()" ); my $subopts1 = $entity1->AddSubscribeOptions(); testFlag($subopts1,"Required"); is( $query6->GetXML(), "", "GetXML()" ); my $entity2 = $query6->AddEntity(affiliation=>"affiliation2", jid=>'user2@server2/resource2', node=>"node2", subscription=>"subscription2"); testPostScalar($entity2,"Affiliation","affiliation2"); testPostJID($entity2,"JID","user2","server2","resource2"); testPostScalar($entity2,"Node","node2"); testPostScalar($entity2,"Subscription","subscription2"); is( $query6->GetXML(), "", "GetXML()" ); my $subopts2 = $entity2->AddSubscribeOptions(required=>1); testPostFlag($subopts2,"Required"); is( $query6->GetXML(), "", "GetXML()" ); my @entities = $query6->GetEntity(); is( $#entities, 1, "two entities"); is( $entities[0]->GetXML(), "","entities[0]"); ok( $entities[0]->GetSubscribeOptions()->GetRequired(), "entities[0] - subopts required"); is( $entities[1]->GetXML(), "","entities[1]"); ok( $entities[1]->GetSubscribeOptions()->GetRequired(), "entities[1] - subopts required"); $query6->RemoveEntity(); is( $query6->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Items #------------------------------------------------------------------------------ my $query7 = new Net::Jabber::Stanza("pubsub"); ok( defined($query7), "new() - items $line" ); isa_ok( $query7, "Net::Jabber::Stanza" ); isa_ok( $query7, "Net::XMPP::Stanza" ); testScalar($query7,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query7->GetXML(), "", "GetXML()" ); my $items1 = $query7->AddItems(); testScalar($items1,"Node","node1"); testScalar($items1,"MaxItems","max1"); is( $query7->GetXML(), "", "GetXML()" ); my $its_item1 = $items1->AddItem(); testScalar($its_item1,"ID","id1"); testScalar($its_item1,"Payload","bar"); is( $query7->GetXML(), "bar", "GetXML()" ); my $its_item2 = $items1->AddItem(id=>"id2", payload=>"boobob"); testPostScalar($its_item2,"ID","id2"); testPostScalar($its_item2,"Payload","boobob"); is( $query7->GetXML(), "barboobob", "GetXML()" ); $query7->AddItems(); is( $query7->GetXML(), "barboobob", "GetXML()" ); my @its_items = $query7->GetItems(); is( $#its_items, 1, "two items"); is( $its_items[0]->GetXML(), "barboobob","its_items[0]"); is( $its_items[1]->GetXML(), "","its_items[1]"); my @its_item = $its_items[0]->GetItem(); is( $#its_item, 1, "two item"); is( $its_item[0]->GetXML(), "bar","its_item[0]"); is( $its_item[1]->GetXML(), "boobob","its_item[1]"); $query7->RemoveItems(); is( $query7->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Item #------------------------------------------------------------------------------ my $query8 = new Net::Jabber::Stanza("pubsub"); ok( defined($query8), "new() - item $line" ); isa_ok( $query8, "Net::Jabber::Stanza" ); isa_ok( $query8, "Net::XMPP::Stanza" ); testScalar($query8,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query8->GetXML(), "", "GetXML()" ); my $item1 = $query8->AddItem(); testScalar($item1,"ID","id1"); testScalar($item1,"Payload",""); is( $query8->GetXML(), "", "GetXML()" ); my $item2 = $query8->AddItem(id=>"id2", payload=>""); testPostScalar($item2,"ID","id2"); testPostScalar($item2,"Payload",""); is( $query8->GetXML(), "", "GetXML()" ); my @item = $query8->GetItem(); is( $#item, 1, "two item"); is( $item[0]->GetXML(), "","item[0]"); is( $item[1]->GetXML(), "","item[1]"); $query8->RemoveItem(); is( $query8->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Options #------------------------------------------------------------------------------ my $query9 = new Net::Jabber::Stanza("pubsub"); ok( defined($query9), "new() - options $line" ); isa_ok( $query9, "Net::Jabber::Stanza" ); isa_ok( $query9, "Net::XMPP::Stanza" ); testScalar($query9,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query9->GetXML(), "", "GetXML()" ); my $options1 = $query9->AddOptions(); testJID($options1,"JID","user1","server1","resource1"); testScalar($options1,"Node","node1"); is( $query9->GetXML(), "", "GetXML()" ); my $options2 = $query9->AddOptions(jid=>'user2@server2/resource2', node=>"node2" ); testPostJID($options2,"JID","user2","server2","resource2"); testPostScalar($options2,"Node","node2"); is( $query9->GetXML(), "", "GetXML()" ); my @options = $query9->GetOptions(); is( $#options, 1, "two options"); is( $options[0]->GetXML(), "","options[0]"); is( $options[1]->GetXML(), "","options[1]"); $query9->RemoveOptions(); is( $query9->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Publish #------------------------------------------------------------------------------ my $query10 = new Net::Jabber::Stanza("pubsub"); ok( defined($query10), "new() - publish $line" ); isa_ok( $query10, "Net::Jabber::Stanza" ); isa_ok( $query10, "Net::XMPP::Stanza" ); testScalar($query10,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query10->GetXML(), "", "GetXML()" ); my $publish1 = $query10->AddPublish(); testScalar($publish1,"Node","node1"); is( $query10->GetXML(), "", "GetXML()" ); my $pub_item1 = $publish1->AddItem(); testScalar($pub_item1,"ID","id1"); testScalar($pub_item1,"Payload","bar"); is( $query10->GetXML(), "bar", "GetXML()" ); my $pub_item2 = $publish1->AddItem(id=>"id2", payload=>"boobob"); testPostScalar($pub_item2,"ID","id2"); testPostScalar($pub_item2,"Payload","boobob"); is( $query10->GetXML(), "barboobob", "GetXML()" ); $query10->AddPublish(); is( $query10->GetXML(), "barboobob", "GetXML()" ); my @publish = $query10->GetPublish(); is( $#publish, 1, "two publish"); is( $publish[0]->GetXML(), "barboobob","publish[0]"); is( $publish[1]->GetXML(), "","publish[1]"); my @pub_item = $publish[0]->GetItem(); is( $#pub_item, 1, "two item"); is( $pub_item[0]->GetXML(), "bar","pub_item[0]"); is( $pub_item[1]->GetXML(), "boobob","pub_item[1]"); $query10->RemovePublish(); is( $query10->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Purge #------------------------------------------------------------------------------ my $query11 = new Net::Jabber::Stanza("pubsub"); ok( defined($query11), "new() - purge $line" ); isa_ok( $query11, "Net::Jabber::Stanza" ); isa_ok( $query11, "Net::XMPP::Stanza" ); testScalar($query11,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query11->GetXML(), "", "GetXML()" ); my $purge1 = $query11->AddPurge(); testScalar($purge1,"Node","node1"); is( $query11->GetXML(), "", "GetXML()" ); my $purge2 = $query11->AddPurge(node=>'node2'); testPostScalar($purge2,"Node","node2"); is( $query11->GetXML(), "", "GetXML()" ); my @purge = $query11->GetPurge(); is( $#purge, 1, "two purge"); is( $purge[0]->GetXML(), "","purge[0]"); is( $purge[1]->GetXML(), "","purge[1]"); $query11->RemovePurge(); is( $query11->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Retract #------------------------------------------------------------------------------ my $query12 = new Net::Jabber::Stanza("pubsub"); ok( defined($query12), "new() - retract $line" ); isa_ok( $query12, "Net::Jabber::Stanza" ); isa_ok( $query12, "Net::XMPP::Stanza" ); testScalar($query12,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query12->GetXML(), "", "GetXML()" ); my $retract1 = $query12->AddRetract(); testScalar($retract1,"Node","node1"); is( $query12->GetXML(), "", "GetXML()" ); my $ret_item1 = $retract1->AddItem(); testScalar($ret_item1,"ID","id1"); is( $query12->GetXML(), "", "GetXML()" ); my $ret_item2 = $retract1->AddItem(id=>"id2"); testPostScalar($ret_item2,"ID","id2"); is( $query12->GetXML(), "", "GetXML()" ); $query12->AddRetract(); is( $query12->GetXML(), "", "GetXML()" ); my @retract = $query12->GetRetract(); is( $#retract, 1, "two retract"); is( $retract[0]->GetXML(), "","retract[0]"); is( $retract[1]->GetXML(), "","retract[1]"); my @ret_item = $retract[0]->GetItem(); is( $#ret_item, 1, "two items"); is( $ret_item[0]->GetXML(), "","ret_item[0]"); is( $ret_item[1]->GetXML(), "","ret_item[1]"); $query12->RemoveRetract(); is( $query12->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Subscribe #------------------------------------------------------------------------------ my $query13 = new Net::Jabber::Stanza("pubsub"); ok( defined($query13), "new() - subscribe $line" ); isa_ok( $query13, "Net::Jabber::Stanza" ); isa_ok( $query13, "Net::XMPP::Stanza" ); testScalar($query13,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query13->GetXML(), "", "GetXML()" ); my $subscribe1 = $query13->AddSubscribe(); testJID($subscribe1,"JID","user1","server1","resource1"); testScalar($subscribe1,"Node","node1"); is( $query13->GetXML(), "", "GetXML()" ); my $subscribe2 = $query13->AddSubscribe(jid=>'user2@server2/resource2', node=>"node2" ); testPostJID($subscribe2,"JID","user2","server2","resource2"); testPostScalar($subscribe2,"Node","node2"); is( $query13->GetXML(), "", "GetXML()" ); my @subscribe = $query13->GetSubscribe(); is( $#subscribe, 1, "two subscribe"); is( $subscribe[0]->GetXML(), "","subscribe[0]"); is( $subscribe[1]->GetXML(), "","subscribe[1]"); $query13->RemoveSubscribe(); is( $query13->GetXML(), "", "GetXML()" ); #------------------------------------------------------------------------------ # Unsubscribe #------------------------------------------------------------------------------ my $query14 = new Net::Jabber::Stanza("pubsub"); ok( defined($query14), "new() - unsubscribe $line" ); isa_ok( $query14, "Net::Jabber::Stanza" ); isa_ok( $query14, "Net::XMPP::Stanza" ); testScalar($query14,"XMLNS","http://jabber.org/protocol/pubsub"); is( $query14->GetXML(), "", "GetXML()" ); my $unsubscribe1 = $query14->AddUnsubscribe(); testJID($unsubscribe1,"JID","user1","server1","resource1"); testScalar($unsubscribe1,"Node","node1"); is( $query14->GetXML(), "", "GetXML()" ); my $unsubscribe2 = $query14->AddUnsubscribe(jid=>'user2@server2/resource2', node=>"node2" ); testPostJID($unsubscribe2,"JID","user2","server2","resource2"); testPostScalar($unsubscribe2,"Node","node2"); is( $query14->GetXML(), "", "GetXML()" ); my @unsubscribe = $query14->GetUnsubscribe(); is( $#unsubscribe, 1, "two unsubscribe"); is( $unsubscribe[0]->GetXML(), "","unsubscribe[0]"); is( $unsubscribe[1]->GetXML(), "","unsubscribe[1]"); $query14->RemoveUnsubscribe(); is( $query14->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/query_bytestreams.t0000644000175000017500000000634610110275744020651 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>89; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/bytestreams"); testScalar($query,"Activate","activate"); testScalar($query,"SID","sid"); testJID($query,"StreamHostUsedJID","user1","server1","resource1"); is( $query->GetXML(), "activate", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/bytestreams"); $query2->SetByteStreams(activate=>'activate', sid=>'sid', streamhostusedjid=>'user2@server2/resource2' ); testPostScalar($query2,"Activate","activate"); testPostScalar($query2,"SID","sid"); testPostJID($query2,"StreamHostUsedJID","user2","server2","resource2"); is( $query2->GetXML(), "activate", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("query"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/bytestreams"); my $host = $query3->AddStreamHost(); isa_ok( $host, "Net::Jabber::Stanza" ); isa_ok( $host, "Net::XMPP::Stanza" ); testScalar($host,"Host","host1"); testJID($host,"JID","user3","server3","resource3"); testScalar($host,"Port","port1"); testScalar($host,"ZeroConf","zeroconf1"); is( $query3->GetXML(), "", "GetXML()" ); my $host2 = $query3->AddStreamHost(host=>"host2", jid=>'user4@server4/resource4', port=>"port2", zeroconf=>"zeroconf2" ); isa_ok( $host2, "Net::Jabber::Stanza" ); isa_ok( $host2, "Net::XMPP::Stanza" ); testPostScalar($host2,"Host","host2"); testPostJID($host2,"JID","user4","server4","resource4"); testPostScalar($host2,"Port","port2"); testPostScalar($host2,"ZeroConf","zeroconf2"); is( $query3->GetXML(), "", "GetXML()" ); my @hosts = $query3->GetStreamHosts(); is($#hosts,1,"two items"); is( $hosts[0]->GetXML(), "","item 1 - GetXML()"); is( $hosts[1]->GetXML(), "","item 2 - GetXML()"); Net-Jabber-2.0/t/query_version.t0000644000175000017500000000356010110275744017767 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>36; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","jabber:iq:version"); testScalar($query,"Name","name"); testScalar($query,"OS",(&POSIX::uname())[0]); $query->SetVer("ver"); testPostScalar($query,"Ver","ver - [ Net::Jabber v$Net::Jabber::VERSION ]"); is( $query->GetXML(), "name".(&POSIX::uname())[0]."ver - [ Net::Jabber v$Net::Jabber::VERSION ]", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","jabber:iq:version"); $query2->SetVersion(name=>"name", os=>"os", ver=>"ver" ); testPostScalar($query2,"Name","name"); testPostScalar($query2,"OS",(&POSIX::uname())[0]); testPostScalar($query2,"Ver","ver - [ Net::Jabber v$Net::Jabber::VERSION ]"); is( $query2->GetXML(), "name".(&POSIX::uname())[0]."ver - [ Net::Jabber v$Net::Jabber::VERSION ]", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("query"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","jabber:iq:version"); $query3->SetVersion(name=>"test-script", ver=>"v1.03" ); is( $query3->GetXML(), "test-script".(&POSIX::uname())[0]."v1.03 - [ Net::Jabber v$Net::Jabber::VERSION ]", "GetXML()" ); Net-Jabber-2.0/t/iq.t0000644000175000017500000001456710110275744015477 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>114; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $debug = new Net::XMPP::Debug(setdefault=>1, level=>-1, file=>"stdout", header=>"test", ); #------------------------------------------------------------------------------ # iq #------------------------------------------------------------------------------ my $iq = new Net::Jabber::IQ(); ok( defined($iq), "new()"); isa_ok( $iq, "Net::Jabber::IQ"); isa_ok( $iq, "Net::XMPP::IQ"); testScalar($iq, "Error", "error"); testScalar($iq, "ErrorCode", "401"); testJID($iq, "From", "user1", "server1", "resource1"); testScalar($iq, "ID", "id"); testJID($iq, "To", "user2", "server2", "resource2"); testScalar($iq, "Type", "Type"); is( $iq->DefinedChild("jabber:x:oob"), "", "not DefinedChild - jabber:x:oob" ); is( $iq->DefinedChild("jabber:x:roster"), "", "not DefinedChild - jabber:x:roster" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my $xoob = $iq->NewChild("jabber:x:oob"); ok( defined( $xoob ), "NewChild - jabber:x:oob" ); isa_ok( $xoob, "Net::XMPP::Stanza" ); is( $iq->DefinedChild(), 1, "DefinedChild" ); is( $iq->DefinedChild("jabber:x:oob"), 1, "DefinedChild - jabber:x:oob" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x = $iq->GetChild(); is( $x[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my $xroster = $iq->NewChild("jabber:x:roster"); ok( defined( $xoob ), "NewChild - jabber:x:roster" ); isa_ok( $xoob, "Net::XMPP::Stanza" ); is( $iq->DefinedChild(), 1, "DefinedChild" ); is( $iq->DefinedChild("jabber:x:oob"), 1, "DefinedChild - jabber:x:oob" ); is( $iq->DefinedChild("jabber:x:roster"), 1, "DefinedChild - jabber:x:roster" ); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x2 = $iq->GetChild(); is( $x2[0], $xoob, "Is the first x the oob?"); is( $x2[1], $xroster, "Is the second x the roster?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x3 = $iq->GetChild("jabber:x:oob"); is( $#x3, 0, "filter on xmlns - only one x... right?"); is( $x3[0], $xoob, "Is the first x the oob?"); #------------------------------------------------------------------------------ # X #------------------------------------------------------------------------------ my @x4 = $iq->GetChild("jabber:x:roster"); is( $#x4, 0, "filter on xmlns - only one x... right?"); is( $x4[0], $xroster, "Is the first x the roster?"); is( $iq->DefinedChild("jabber:x:testns"), "", "not DefinedChild - jabber:x:testns" ); #------------------------------------------------------------------------------ # iq #------------------------------------------------------------------------------ my $iq2 = new Net::Jabber::IQ(); ok( defined($iq2), "new()"); isa_ok( $iq2, "Net::Jabber::IQ"); #------------------------------------------------------------------------------ # defined #------------------------------------------------------------------------------ is( $iq2->DefinedError(), '', "error not defined" ); is( $iq2->DefinedErrorCode(), '', "errorcode not defined" ); is( $iq2->DefinedFrom(), '', "from not defined" ); is( $iq2->DefinedID(), '', "id not defined" ); is( $iq2->DefinedTo(), '', "to not defined" ); is( $iq2->DefinedType(), '', "type not defined" ); #------------------------------------------------------------------------------ # set it #------------------------------------------------------------------------------ $iq2->SetIQ(error=>"error", errorcode=>"401", from=>"user1\@server1/resource1", id=>"id", to=>"user2\@server2/resource2", type=>"type"); testPostScalar($iq, "Error", "error"); testPostScalar($iq, "ErrorCode", "401"); testPostJID($iq, "From", "user1", "server1", "resource1"); testPostScalar($iq, "ID", "id"); testPostJID($iq, "To", "user2", "server2", "resource2"); testPostScalar($iq, "Type", "Type"); my $iq3 = new Net::Jabber::IQ(); ok( defined($iq3), "new()"); isa_ok( $iq3, "Net::Jabber::IQ"); $iq3->SetIQ(error=>"error", errorcode=>"401", from=>"user1\@server1/resource1", id=>"id", to=>"user2\@server2/resource2", type=>"type"); my $query = $iq3->NewChild("jabber:iq:auth"); ok( defined($query), "new()"); isa_ok( $query, "Net::XMPP::Stanza"); $query->SetAuth(username=>"user", password=>"pass"); is( $iq3->GetXML(), "errorpassuser", "GetXML()"); #------------------------------------------------------------------------------ # Reply #------------------------------------------------------------------------------ my $reply3 = $iq3->Reply(); ok( defined($reply3), "new()"); isa_ok( $reply3, "Net::Jabber::IQ"); isa_ok( $reply3, "Net::XMPP::IQ"); testPostJID($reply3, "From", "user2", "server2", "resource2"); testPostScalar($reply3, "ID", "id"); testPostJID($reply3, "To", "user1", "server1", "resource1"); is( $reply3->GetXML(), "", "GetXML()"); my $delay = $reply3->NewChild("jabber:x:delay"); $delay->SetDelay(stamp=>"stamp", message=>"test"); is( $reply3->GetXML(), "test", "GetXML()"); $reply3->NewQuery("jabber:iq:roster"); is( $reply3->GetXML(), "test", "GetXML()"); Net-Jabber-2.0/t/query_commands.t0000644000175000017500000000513510110275744020103 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>59; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("command"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/commands"); testScalar($query,"Action","action"); testScalar($query,"Node","node"); testScalar($query,"SessionID","sessionid"); testScalar($query,"Status","status"); is( $query->GetXML(), "", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("command"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/commands"); $query2->SetCommand(action=>'action', node=>'node', sessionid=>'sessionid', status=>'status' ); testPostScalar($query2,"Action","action"); testPostScalar($query2,"Node","node"); testPostScalar($query2,"SessionID","sessionid"); testPostScalar($query2,"Status","status"); is( $query2->GetXML(), "", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("command"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/commands"); my $note = $query3->AddNote(); isa_ok( $note, "Net::Jabber::Stanza" ); isa_ok( $note, "Net::XMPP::Stanza" ); testScalar($note,"Type","type1"); testSetScalar($note,"Message","message1"); is( $query3->GetXML(), "message1", "GetXML()" ); my $note2 = $query3->AddNote(type=>"type2", message=>"message2" ); isa_ok( $note2, "Net::Jabber::Stanza" ); isa_ok( $note2, "Net::XMPP::Stanza" ); testPostScalar($note2,"Type","type2"); testPostScalar($note2,"Message","message2"); is( $query3->GetXML(), "message1message2", "GetXML()" ); my @notes = $query3->GetNotes(); is($#notes,1,"two items"); is( $notes[0]->GetXML(), "message1","note 1 - GetXML()"); is( $notes[1]->GetXML(), "message2","note 2 - GetXML()"); Net-Jabber-2.0/t/2_client.t0000644000175000017500000000554110110275744016555 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>5; BEGIN{ use_ok( "Net::Jabber" ); } my $Client; my $connected = 0; my $server = "obelisk.net"; my $port = 5222; my $username = "test-netjabber"; my $password = "test"; my $resource = $$.time.qx(hostname); chomp($resource); ############################################################################### # # Make sure you can ever connect to the server. If we cannot then we should # skip the rest of the tests because they will fail. # ############################################################################### SKIP: { my $sock = IO::Socket::INET->new(PeerAddr=>"$server:$port"); skip "Cannot open connection (maybe a firewall?)",4 unless defined($sock); $sock->close(); $Client = new Net::Jabber::Client(); $Client->SetCallBacks(onconnect => \&onConnect, onauth => \&onAuth, message => \&onMessage, ); $Client->Execute(username=>$username, password=>$password, resource=>$resource, hostname=>$server, port=>$port, register=>1, connectsleep=>0, connectattempts=>1, ); #-------------------------------------------------------------------------- # If all went well, we should never get here. #-------------------------------------------------------------------------- ok(0,"Connected") unless $connected; ok(0,"Authenticated"); ok(0,"Subject"); ok(0,"Body"); } ############################################################################### # # onConnect - when we establish an initial connection to the server run the # following # ############################################################################### sub onConnect { $connected = 1; ok(1, "Connected"); } ############################################################################### # # onAuth - when we have successfully authenticated with the server send a # test message to ourselves. # ############################################################################### sub onAuth { $Client->MessageSend(to=>$username."@".$server."/".$resource, subject=>"test", body=>"This is a test."); ok(1, "Authenticated"); } ############################################################################### # # onMessage - when we get a message, check that the contents match what we sent # above. # ############################################################################### sub onMessage { my $sid = shift; my $message = shift; is( $message->GetSubject(), "test", "Subject" ); is( $message->GetBody(), "This is a test.", "Body" ); $Client->Disconnect(); exit(0); } Net-Jabber-2.0/t/parse_x_delay.t0000644000175000017500000000445310110275744017676 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>24; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $message_node = new XML::Stream::Node("message"); ok( defined($message_node), "new()"); isa_ok( $message_node, "XML::Stream::Node" ); $message_node->put_attrib(to=>"jer\@jabber.org", from=>"reatmon\@jabber.org"); my $body_node = $message_node->add_child("body"); $body_node->add_cdata("body"); my $subject_node = $message_node->add_child("subject"); $subject_node->add_cdata("subject"); my $xdelay1 = $message_node->add_child("x"); $xdelay1->put_attrib(xmlns=>"jabber:x:delay", from=>"jabber.org", stamp=>"stamp", ); $xdelay1->add_cdata("Delay1"); my $xdelay2 = $message_node->add_child("x"); $xdelay2->put_attrib(xmlns=>"jabber:x:delay", from=>"jabber.org", stamp=>"stamp", ); $xdelay2->add_cdata("Delay2"); is( $message_node->GetXML(), "bodysubjectDelay1Delay2", "GetXML()" ); my $message = new Net::Jabber::Message($message_node); ok( defined($message), "new()" ); isa_ok( $message, "Net::Jabber::Message" ); isa_ok( $message, "Net::XMPP::Message" ); is( $message->GetTo(), "jer\@jabber.org", "GetTo"); is( $message->GetFrom(), "reatmon\@jabber.org", "GetFrom"); is( $message->GetSubject(), "subject", "GetSubject"); is( $message->GetBody(), "body", "GetBody"); my @xdelays = $message->GetChild("jabber:x:delay"); is( $#xdelays, 1, "two delays"); $xdelay1 = $xdelays[0]; ok( defined($xdelay1), "defined delay" ); isa_ok( $xdelay1, "Net::Jabber::Stanza" ); isa_ok( $xdelay1, "Net::XMPP::Stanza" ); is( $xdelay1->GetFrom(), "jabber.org", "GetFrom"); is( $xdelay1->GetStamp(), "stamp", "GetStamp"); is( $xdelay1->GetMessage(), "Delay1", "GetMessage"); $xdelay2 = $xdelays[1]; ok( defined($xdelay2), "defined delay" ); isa_ok( $xdelay2, "Net::Jabber::Stanza" ); isa_ok( $xdelay2, "Net::XMPP::Stanza" ); is( $xdelay2->GetFrom(), "jabber.org", "GetFrom"); is( $xdelay2->GetStamp(), "stamp", "GetStamp"); is( $xdelay2->GetMessage(), "Delay2", "GetMessage"); Net-Jabber-2.0/t/parse_x_data.t0000644000175000017500000000621410110275744017506 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>28; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $message_node = new XML::Stream::Node("message"); ok( defined($message_node), "new()" ); isa_ok( $message_node, "XML::Stream::Node" ); $message_node->put_attrib(to=>"jer\@jabber.org", from=>"reatmon\@jabber.org"); my $body_node = $message_node->add_child("body"); $body_node->add_cdata("body"); my $subject_node = $message_node->add_child("subject"); $subject_node->add_cdata("subject"); my $xdata = $message_node->add_child("x"); $xdata->put_attrib(xmlns=>"jabber:x:data"); $xdata->add_child("instructions","fill this out"); my $field1 = $xdata->add_child("field"); $field1->put_attrib(type=>"hidden", var=>"formnum"); $field1->add_child("value","value1"); my $field2 = $xdata->add_child("field"); $field2->put_attrib(type=>"list-single", var=>"mylist"); $field2->add_child("value","male"); $field2->add_child("value","test"); $field2->add_child("required"); my $option1 = $field2->add_child("option"); $option1->put_attrib(label=>"Male"); $option1->add_child("value","male"); my $option2 = $field2->add_child("option"); $option2->put_attrib(label=>"Female"); $option2->add_child("value","female"); is( $message_node->GetXML(), "bodysubjectfill this outvalue1maletest", "GetXML()" ); my $message = new Net::Jabber::Message($message_node); ok( defined($message), "new()" ); isa_ok( $message, "Net::Jabber::Message" ); isa_ok( $message, "Net::XMPP::Message" ); is( $message->GetTo(), "jer\@jabber.org", "GetTo"); is( $message->GetFrom(), "reatmon\@jabber.org", "GetFrom"); is( $message->GetSubject(), "subject", "GetSubject"); is( $message->GetBody(), "body", "GetBody"); my @xdatas = $message->GetChild("jabber:x:data"); is( $#xdatas, 0, "one data packet" ); my $xdata1 = $xdatas[0]; ok( defined($xdata1), "defined data" ); isa_ok( $xdata1, "Net::Jabber::Stanza" ); isa_ok( $xdata1, "Net::XMPP::Stanza" ); is( $xdata1->GetInstructions(), "fill this out", "GetInsructions" ); my @fields = $xdata1->GetFields(); is( $#fields, 1, "two fields"); my $listField = $fields[1]; is( $listField->GetVar(), "mylist", "GetVar"); is( $listField->GetType(), "list-single", "GetType"); my @values = $listField->GetValue(); is( $#values, 1, "two values"); is( $values[0], "male", "value == male"); is( $values[1], "test", "value == test"); ok( $listField->GetRequired(), "GetRequired"); my @options = $listField->GetOptions(); is( $#options, 1, "two options"); my $listOption1 = $options[0]; my $listOption2 = $options[1]; is( $listOption1->GetLabel(), "Male", "GetLabel"); is( $listOption1->GetValue(), "male", "Getvalue"); is( $listOption2->GetLabel(), "Female", "GetLabel"); is( $listOption2->GetValue(), "female", "GetValue"); Net-Jabber-2.0/t/protocol_rpc.t0000644000175000017500000000673310110275744017567 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>19; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $client = new Net::Jabber::Client(); ok( defined($client), "new()" ); isa_ok( $client, "Net::Jabber::Client" ); my $query1 = $client->RPCEncode(type=>"methodCall", methodname=>"test_call", params=>["foo",4,{ a=>1, b=>"bar"}]); ok( defined($query1), "new()" ); isa_ok( $query1, "Net::Jabber::Stanza" ); isa_ok( $query1, "Net::XMPP::Stanza" ); is( $query1->GetXML(), "test_callfoo4a1bbar", "GetXML()" ); my $query2 = $client->RPCEncode(type=>"methodResponse", faultcode=>404, faultstring=>"not found", params=>["foo",4]); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); is( $query2->GetXML(), "faultCode404faultStringnot found", "GetXML()" ); my $query3 = $client->RPCEncode(type=>"methodResponse", methodname=>"test_call", params=>["foo",4,{ a=>1, b=>"bar"},["a",1,"foo"]]); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); is( $query3->GetXML(), "foo4a1bbara1foo", "GetXML()" ); my $query4 = $client->RPCEncode(type=>"methodResponse", methodname=>"test_call", params=>["i4:5", "boolean:0", "string:56", "double:5.0", "datetime:20020415T11:11:11", "base64:...." ] ); ok( defined($query4), "new()" ); isa_ok( $query4, "Net::Jabber::Stanza" ); isa_ok( $query4, "Net::XMPP::Stanza" ); is( $query4->GetXML(), "50565.020020415T11:11:11....", "GetXML()" ); Net-Jabber-2.0/t/query_si.t0000644000175000017500000000357410110275744016722 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>44; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("si"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/si"); testScalar($query,"ID","id"); testScalar($query,"MimeType","mimetype"); testScalar($query,"Profile","profile"); is( $query->GetXML(), "", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("si"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/si"); $query2->SetStream(id=>"id", mimetype=>"mimetype", profile=>"profile" ); testPostScalar($query2,"ID","id"); testPostScalar($query2,"MimeType","mimetype"); testPostScalar($query2,"Profile","profile"); is( $query2->GetXML(), "", "GetXML()" ); my $iq = new Net::Jabber::IQ(); ok( defined($iq), "new()" ); isa_ok( $iq, "Net::Jabber::IQ" ); my $query3 = $iq->NewChild("http://jabber.org/protocol/si"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testPostScalar($query3,"XMLNS","http://jabber.org/protocol/si"); $query3->SetStream(id=>"id", mimetype=>"mimetype", profile=>"profile" ); testPostScalar($query3,"ID","id"); testPostScalar($query3,"MimeType","mimetype"); testPostScalar($query3,"Profile","profile"); is( $iq->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/x_oob.t0000644000175000017500000000151310110275745016160 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>25; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:oob"); testScalar($x,"Desc","desc"); testScalar($x,"URL","url"); is( $x->GetXML(), "descurl", "GetXML()" ); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:oob"); $x2->SetOob(desc=>"desc", url=>"url"); testPostScalar($x2,"Desc","desc"); testPostScalar($x2,"URL","url"); is( $x2->GetXML(), "descurl", "GetXML()" ); Net-Jabber-2.0/t/x_conference.t0000644000175000017500000000150510110275744017510 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>32; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:conference"); testJID($x, "JID", "user", "server", "resource"); is( $x->GetXML(), "", "GetXML()" ); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:conference"); $x2->SetConference(jid=>"user\@server/resource"); testPostJID($x2, "JID", "user", "server", "resource"); is( $x2->GetXML(), "", "GetXML()" ); Net-Jabber-2.0/t/x_muc_user.t0000644000175000017500000001032410110275745017223 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>129; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS",'http://jabber.org/protocol/muc#user'); testScalar($x,"Alt","alt"); testScalar($x,"Password","password"); testScalar($x,"StatusCode","code"); is( $x->GetXML(), "altpassword", "GetXML()"); my $invite = $x->AddInvite(); is( $x->GetXML(), "altpassword", "GetXML()"); testJID($invite,"From","user1", "server1", "resource1"); testJID($invite,"To","user2", "server2", "resource2"); testScalar($invite,"Reason","reason"); is( $x->GetXML(), "altpasswordreason", "GetXML()"); my $item = $x->AddItem(); is( $x->GetXML(), "altpasswordreason", "GetXML()"); testJID($item,"ActorJID","user3", "server3", "resource3"); testScalar($item,"Affiliation","affiliation"); testJID($item,"JID","user4", "server4", "resource4"); testScalar($item,"Nick","nick"); testScalar($item,"Reason","reason"); testScalar($item,"Role","role"); is( $x->GetXML(), "altpasswordreasonreason", "GetXML()"); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","http://jabber.org/protocol/muc#user"); $x2->SetUser(alt=>"alt", password=>"password", statuscode=>"code" ); testPostScalar($x2,"Alt","alt"); testPostScalar($x2,"Password","password"); testPostScalar($x2,"StatusCode","code"); is( $x2->GetXML(), "altpassword", "GetXML()"); my $invite2 = $x2->AddInvite(from=>'user5@server5/resource5', reason=>"reason", to=>'user6@server6/resource6'); testPostJID($invite2,"From","user5", "server5", "resource5"); testPostJID($invite2,"To","user6", "server6", "resource6"); testPostScalar($invite2,"Reason","reason"); is( $x2->GetXML(), "altpasswordreason", "GetXML()"); my $item2 = $x2->AddItem(actorjid=>'user7@server7/resource7', affiliation=>"affiliation", jid=>'user8@server8/resource8', nick=>"nick", reason=>"reason", role=>"role"); testPostJID($item2,"ActorJID","user7", "server7", "resource7"); testPostScalar($item2,"Affiliation","affiliation"); testPostJID($item2,"JID","user8", "server8", "resource8"); testPostScalar($item2,"Nick","nick"); testPostScalar($item2,"Reason","reason"); testPostScalar($item2,"Role","role"); is( $x2->GetXML(), "altpasswordreasonreason", "GetXML()"); Net-Jabber-2.0/t/query_disco_items.t0000644000175000017500000000522110110275744020600 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>70; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $query = new Net::Jabber::Stanza("query"); ok( defined($query), "new()" ); isa_ok( $query, "Net::Jabber::Stanza" ); isa_ok( $query, "Net::XMPP::Stanza" ); testScalar($query,"XMLNS","http://jabber.org/protocol/disco#items"); testScalar($query,"Node","node"); is( $query->GetXML(), "", "GetXML()" ); my $query2 = new Net::Jabber::Stanza("query"); ok( defined($query2), "new()" ); isa_ok( $query2, "Net::Jabber::Stanza" ); isa_ok( $query2, "Net::XMPP::Stanza" ); testScalar($query2,"XMLNS","http://jabber.org/protocol/disco#items"); $query2->SetDiscoItems(node=>'node'); testPostScalar($query2,"Node","node"); is( $query2->GetXML(), "", "GetXML()" ); my $query3 = new Net::Jabber::Stanza("query"); ok( defined($query3), "new()" ); isa_ok( $query3, "Net::Jabber::Stanza" ); isa_ok( $query3, "Net::XMPP::Stanza" ); testScalar($query3,"XMLNS","http://jabber.org/protocol/disco#items"); testScalar($query3,"Node","node"); my $item = $query3->AddItem(); isa_ok( $item, "Net::Jabber::Stanza" ); isa_ok( $item, "Net::XMPP::Stanza" ); testScalar($item,"Action","action"); testJID($item,"JID","user1","server1","resource1"); testScalar($item,"Name","name"); testScalar($item,"Node","node"); is( $query3->GetXML(), "", "GetXML()" ); my $item2 = $query3->AddItem(action=>"action", jid=>'user2@server2/resource2', name=>"name", node=>"node" ); isa_ok( $item2, "Net::Jabber::Stanza" ); isa_ok( $item2, "Net::XMPP::Stanza" ); testPostScalar($item2,"Action","action"); testPostJID($item2,"JID","user2","server2","resource2"); testPostScalar($item2,"Name","name"); testPostScalar($item2,"Node","node"); is( $query3->GetXML(), "", "GetXML()" ); my @items = $query3->GetItems(); is($#items,1,"two items"); is( $items[0]->GetXML(), "","item 1 - GetXML()"); is( $items[1]->GetXML(), "","item 2 - GetXML()"); Net-Jabber-2.0/t/x_delay.t0000644000175000017500000000232710110275744016502 0ustar reatmonreatmon00000000000000use lib "t/lib"; use Test::More tests=>43; BEGIN{ use_ok( "Net::Jabber" ); } require "t/mytestlib.pl"; my $x = new Net::Jabber::Stanza("x"); ok( defined($x), "new()" ); isa_ok( $x, "Net::Jabber::Stanza" ); isa_ok( $x, "Net::XMPP::Stanza" ); testScalar($x,"XMLNS","jabber:x:delay"); testJID($x, "From", "user", "server", "resource"); testSetScalar($x, "Message", "message"); testScalar($x, "Stamp", "stamp"); is( $x->GetXML(), "message", "GetXML()" ); $x->SetStamp(); is( $x->DefinedStamp, 1, "stamp defined" ); like( $x->GetStamp, qr/^\d\d\d\d\d\d\d\dT\d\d:\d\d:\d\d$/, "look like a stamp?"); my $x2 = new Net::Jabber::Stanza("x"); ok( defined($x2), "new()" ); isa_ok( $x2, "Net::Jabber::Stanza" ); isa_ok( $x2, "Net::XMPP::Stanza" ); testScalar($x2,"XMLNS","jabber:x:delay"); $x2->SetDelay(from=>"user\@server/resource", message=>"message", stamp=>"stamp"); testPostJID($x2, "From", "user", "server", "resource"); testPostScalar($x2, "Message", "message"); testPostScalar($x2, "Stamp", "stamp"); is( $x2->GetXML(), "message", "GetXML()" ); Net-Jabber-2.0/MANIFEST0000644000175000017500000000314410112242736015551 0ustar reatmonreatmon00000000000000CHANGES README LICENSE.LGPL MANIFEST MANIFEST.SKIP Makefile.PL examples/client.pl examples/client_xpath.pl examples/component_accept.pl examples/component_test.pl examples/rpc_client.pl examples/rpc_server.pl lib/Net/Jabber.pm lib/Net/Jabber/Client.pm lib/Net/Jabber/Component.pm lib/Net/Jabber/Data.pm lib/Net/Jabber/Debug.pm lib/Net/Jabber/Dialback.pm lib/Net/Jabber/Dialback/Result.pm lib/Net/Jabber/Dialback/Verify.pm lib/Net/Jabber/IQ.pm lib/Net/Jabber/JID.pm lib/Net/Jabber/Key.pm lib/Net/Jabber/Log.pm lib/Net/Jabber/Message.pm lib/Net/Jabber/Namespaces.pm lib/Net/Jabber/Presence.pm lib/Net/Jabber/Protocol.pm lib/Net/Jabber/Server.pm lib/Net/Jabber/Stanza.pm lib/Net/Jabber/XDB.pm t/1_load.t t/2_client.t t/iq.t t/jid.t t/lib/Test/Builder.pm t/lib/Test/More.pm t/lib/Test/Simple.pm t/message.t t/mytestlib.pl t/oldadd.t t/parse_x_data.t t/parse_x_delay.t t/presence.t t/protocol_definenamespace.t t/protocol_muc.t t/protocol_rpc.t t/query_agent.t t/query_agents.t t/query_autoupdate.t t/query_browse.t t/query_bytestreams.t t/query_commands.t t/query_conference.t t/query_disco_info.t t/query_disco_items.t t/query_featureneg.t t/query_filter.t t/query_gateway.t t/query_last.t t/query_muc_admin.t t/query_oob.t t/query_pass.t t/query_pubsub.t t/query_pubsub_event.t t/query_pubsub_owner.t t/query_rpc.t t/query_search.t t/query_si.t t/query_si_filetrans.t t/query_time.t t/query_version.t t/rawxml.t t/x_autoupdate.t t/x_conference.t t/x_data.t t/x_delay.t t/x_encrypted.t t/x_expire.t t/x_muc.t t/x_muc_user.t t/x_oob.t t/x_roster.t t/x_signed.t META.yml Module meta-data (added by MakeMaker) Net-Jabber-2.0/examples/0002755000175000017500000000000010112242737016237 5ustar reatmonreatmon00000000000000Net-Jabber-2.0/examples/rpc_server.pl0000755000175000017500000000250610110275743020753 0ustar reatmonreatmon00000000000000#!/bin/sh #-*-Perl-*- exec perl -x $0 "$@" #!perl use Net::Jabber qw(Client); use strict; if ($#ARGV < 3) { print "\nperl client.pl \n\n" ; exit(0); } my $server = $ARGV[0]; my $port = $ARGV[1]; my $username = $ARGV[2]; my $password = $ARGV[3]; $SIG{HUP} = \&Stop; $SIG{KILL} = \&Stop; $SIG{TERM} = \&Stop; $SIG{INT} = \&Stop; my $Connection = new Net::Jabber::Client(); $Connection->RPCSetCallBacks(add=>\&add); my $status = $Connection->Connect("hostname" => $server, "port" => $port); if (!(defined($status))) { print "ERROR: Jabber server is down or connection was not allowed.\n"; print " ($!)\n"; exit(0); } my @result = $Connection->AuthSend("username" => $username, "password" => $password, "resource" => "RPCServer"); if ($result[0] ne "ok") { print "ERROR: Authorization failed: $result[0] - $result[1]\n"; exit(0); } print "Logged in to $server:$port...\n"; while(1) { $Connection->Process(); } sub Stop { print "Exiting...\n"; $Connection->Disconnect(); exit(0); } sub add { my $iq = shift; my $params = shift; print $params->[0]," + ",$params->[1]," = ",$params->[0] + $params->[1],"\n"; return ("ok", [ $params->[0] + $params->[1] ]); } Net-Jabber-2.0/examples/component_accept.pl0000755000175000017500000000200110110275743022110 0ustar reatmonreatmon00000000000000 use Net::Jabber qw(Component); use strict; if ($#ARGV < 2) { print "\nperl component_accept.pl \n\n"; exit(0); } my $server = $ARGV[0]; my $port = $ARGV[1]; my $name = $ARGV[2]; my $secret = $ARGV[3]; $SIG{HUP} = \&Stop; $SIG{KILL} = \&Stop; $SIG{TERM} = \&Stop; $SIG{INT} = \&Stop; my $Component = new Net::Jabber::Component(); $Component->SetCallBacks(onauth=>\&onAuth, message=>\&messageCB); $Component->Execute(hostname=>$server, port=>$port, componentname=>$name, secret=>$secret ); sub onAuth { print "Connected...\n"; } sub Stop { $Component->Disconnect(); print "Exit gracefully...\n"; exit(0); } sub messageCB { my $sid = shift; my $message = shift; print "Recd: ",$message->GetXML(),"\n"; my $reply = $message->Reply(); $reply->SetMessage(body=>uc($message->GetBody())); $Component->Send($reply); print "Sent: ",$reply->GetXML(),"\n"; } Net-Jabber-2.0/examples/client.pl0000644000175000017500000000543210110655222020047 0ustar reatmonreatmon00000000000000 use Net::Jabber; use strict; if ($#ARGV < 4) { print "\nperl client.pl \n\n"; exit(0); } my $server = $ARGV[0]; my $port = $ARGV[1]; my $username = $ARGV[2]; my $password = $ARGV[3]; my $resource = $ARGV[4]; $SIG{HUP} = \&Stop; $SIG{KILL} = \&Stop; $SIG{TERM} = \&Stop; $SIG{INT} = \&Stop; my $Connection = new Net::Jabber::Client(); $Connection->SetCallBacks(message=>\&InMessage, presence=>\&InPresence, iq=>\&InIQ); my $status = $Connection->Connect(hostname=>$server, port=>$port, ); if (!(defined($status))) { print "ERROR: Jabber server is down or connection was not allowed.\n"; print " ($!)\n"; exit(0); } my @result = $Connection->AuthSend(username=>$username, password=>$password, resource=>$resource); if ($result[0] ne "ok") { print "ERROR: Authorization failed: $result[0] - $result[1]\n"; exit(0); } print "Logged in to $server:$port...\n"; $Connection->RosterGet(); print "Getting Roster to tell server to send presence info...\n"; $Connection->PresenceSend(); print "Sending presence to tell world that we are logged in...\n"; while(defined($Connection->Process())) { } print "ERROR: The connection was killed...\n"; exit(0); sub Stop { print "Exiting...\n"; $Connection->Disconnect(); exit(0); } sub InMessage { my $sid = shift; my $message = shift; my $type = $message->GetType(); my $fromJID = $message->GetFrom("jid"); my $from = $fromJID->GetUserID(); my $resource = $fromJID->GetResource(); my $subject = $message->GetSubject(); my $body = $message->GetBody(); print "===\n"; print "Message ($type)\n"; print " From: $from ($resource)\n"; print " Subject: $subject\n"; print " Body: $body\n"; print "===\n"; print $message->GetXML(),"\n"; print "===\n"; } sub InIQ { my $sid = shift; my $iq = shift; my $from = $iq->GetFrom(); my $type = $iq->GetType(); my $query = $iq->GetQuery(); my $xmlns = $query->GetXMLNS(); print "===\n"; print "IQ\n"; print " From $from\n"; print " Type: $type\n"; print " XMLNS: $xmlns"; print "===\n"; print $iq->GetXML(),"\n"; print "===\n"; } sub InPresence { my $sid = shift; my $presence = shift; my $from = $presence->GetFrom(); my $type = $presence->GetType(); my $status = $presence->GetStatus(); print "===\n"; print "Presence\n"; print " From $from\n"; print " Type: $type\n"; print " Status: $status\n"; print "===\n"; print $presence->GetXML(),"\n"; print "===\n"; } Net-Jabber-2.0/examples/rpc_client.pl0000755000175000017500000000262610110275743020726 0ustar reatmonreatmon00000000000000#!/bin/sh #-*-Perl-*- exec perl -x $0 "$@" #!perl use Net::Jabber qw(Client); use strict; if ($#ARGV < 3) { print "\nperl client.pl \n\n" ; exit(0); } my $server = $ARGV[0]; my $port = $ARGV[1]; my $username = $ARGV[2]; my $password = $ARGV[3]; $SIG{HUP} = \&Stop; $SIG{KILL} = \&Stop; $SIG{TERM} = \&Stop; $SIG{INT} = \&Stop; my $Connection = new Net::Jabber::Client(); $Connection->SetCallBacks("message" => \&InMessage, "presence" => \&InPresence, "iq" => \&InIQ); my $status = $Connection->Connect("hostname" => $server, "port" => $port); if (!(defined($status))) { print "ERROR: Jabber server is down or connection was not allowed.\n"; print " ($!)\n"; exit(0); } my @result = $Connection->AuthSend("username" => $username, "password" => $password, "resource" => "RPCClient"); if ($result[0] ne "ok") { print "ERROR: Authorization failed: $result[0] - $result[1]\n"; exit(0); } print "Logged in to $server:$port...\n"; my @response = $Connection->RPCCall(to=>"$username\@$server/RPCServer", methodName=>"add", params=>[5,4]); if ($response[0] eq "ok") { print "5 + 4 = ",$response[1]->[0],"\n"; } sub Stop { print "Exiting...\n"; $Connection->Disconnect(); exit(0); } Net-Jabber-2.0/examples/component_test.pl0000755000175000017500000000232410110275743021640 0ustar reatmonreatmon00000000000000 use Net::Jabber qw(Client); use strict; if ($#ARGV < 5) { print "\nperl client.pl \n"; print " \n\n" ; exit(0); } my $server = $ARGV[0]; my $port = $ARGV[1]; my $username = $ARGV[2]; my $password = $ARGV[3]; my $resource = $ARGV[4]; my $component = $ARGV[5]; my $Client = new Net::Jabber::Client; $Client->SetCallBacks(message=>\&messageCB); my $status = $Client->Connect(hostname=>$server, port=>$port); if (!(defined($status))) { print "ERROR: Jabber server $server is not answering.\n"; print " ($!)\n"; exit(0); } print "Connected...\n"; my @result = $Client->AuthSend(username=>$username, password=>$password, resource=>$resource); if ($result[0] ne "ok") { print "ERROR: $result[0] $result[1]\n"; } print "Logged in...\n"; $Client->MessageSend(to=>$component, body=>"this is a test... a successful test..."); $Client->Process(); $Client->Disconnect(); sub messageCB { my $sid = shift; my $message = shift; print "The body of the message should read:\n"; print " (THIS IS A TEST... A SUCCESSFUL TEST...)\n"; print "\n"; print "Recvd: ",$message->GetBody(),"\n"; } Net-Jabber-2.0/examples/client_xpath.pl0000644000175000017500000000543210110275743021261 0ustar reatmonreatmon00000000000000 use Net::Jabber qw(Client); use strict; if ($#ARGV < 4) { print "\nperl client.pl \n\n"; exit(0); } my $server = $ARGV[0]; my $port = $ARGV[1]; my $username = $ARGV[2]; my $password = $ARGV[3]; my $resource = $ARGV[4]; $SIG{HUP} = \&Stop; $SIG{KILL} = \&Stop; $SIG{TERM} = \&Stop; $SIG{INT} = \&Stop; my $Connection = new Net::Jabber::Client(); $Connection->SetXPathCallBacks('/message'=>\&InMessage, '/presence'=>\&InPresence, '/iq'=>\&InIQ); my $status = $Connection->Connect(hostname=>$server, port=>$port); if (!(defined($status))) { print "ERROR: Jabber server is down or connection was not allowed.\n"; print " ($!)\n"; exit(0); } my @result = $Connection->AuthSend(username=>$username, password=>$password, resource=>$resource); if ($result[0] ne "ok") { print "ERROR: Authorization failed: $result[0] - $result[1]\n"; exit(0); } print "Logged in to $server:$port...\n"; $Connection->RosterGet(); print "Getting Roster to tell server to send presence info...\n"; $Connection->PresenceSend(); print "Sending presence to tell world that we are logged in...\n"; while(defined($Connection->Process())) { } print "ERROR: The connection was killed...\n"; exit(0); sub Stop { print "Exiting...\n"; $Connection->Disconnect(); exit(0); } sub InMessage { my $sid = shift; my $message = shift; my $type = $message->GetType(); my $fromJID = $message->GetFrom("jid"); my $from = $fromJID->GetUserID(); my $resource = $fromJID->GetResource(); my $subject = $message->GetSubject(); my $body = $message->GetBody(); print "===\n"; print "Message ($type)\n"; print " From: $from ($resource)\n"; print " Subject: $subject\n"; print " Body: $body\n"; print "===\n"; print $message->GetXML(),"\n"; print "===\n"; } sub InIQ { my $sid = shift; my $iq = shift; my $from = $iq->GetFrom(); my $type = $iq->GetType(); my $query = $iq->GetQuery(); my $xmlns = $query->GetXMLNS(); print "===\n"; print "IQ\n"; print " From $from\n"; print " Type: $type\n"; print " XMLNS: $xmlns"; print "===\n"; print $iq->GetXML(),"\n"; print "===\n"; } sub InPresence { my $sid = shift; my $presence = shift; my $from = $presence->GetFrom(); my $type = $presence->GetType(); my $status = $presence->GetStatus(); print "===\n"; print "Presence\n"; print " From $from\n"; print " Type: $type\n"; print " Status: $status\n"; print "===\n"; print $presence->GetXML(),"\n"; print "===\n"; } Net-Jabber-2.0/README0000644000175000017500000000205010112223273015266 0ustar reatmonreatmon00000000000000Net::Jabber v2.0 The Jabber Instant Messaging project is an Open Source project seeking to provide a complete cross protocol messaging solution. The problem with current IM solutions is that they are all proprietary and cannot talk to each other. Jabber seeks to get rid of those barriers by allowing a Jabber client to talk with an AOL user, or an IRC chat room, or any number of other programs. For more information about the Jabber project visit http://www.jabber.org. Net::Jabber is a collection of Perl modules that provide a Perl Developer access to the Jabber protocol. Using OOP modules we provide a clean interface to writing anything from a full client to a simple protocol tester. Ryan Eatmon reatmon@jabber.org REQUIREMENTS - Net::XMPP - Provides all of the core logic. INSTALLATION perl Makefile.PL make make install STATUS Initial support for XMPP 1.0 (SASL, TLS, etc...). This release may not be stable. If you run into problems, downgrade to 1.29. Please send any bug reports to reatmon@jabber.org. 2004/08/22 Net-Jabber-2.0/CHANGES0000644000175000017500000004213210110276115015407 0ustar reatmonreatmon000000000000002.0 === - All of the core functionality has moved into Net::XMPP. It provides the connection, messages, iq, and presence. Net::Jabber now just provides the extensions that the JEPs define and that are truly Jabber and not XMPP. 1.30 ==== - Added initial support for XMPP 1.0 via XML::Stream 1.18. - Locked version of XML::Stream to 1.18. - Changed connectiontimeout to just timeout in the Connect function. - Hey, here's a good idea. Instead of copying the function hash out of each namespace why not just use a refrence... duh... This might make things a little faster and use a smidge less memory. Just a little thought. - Fixed a taint problem with an eval and the xmlns read from the socket. - Fixed some -w warnings. - Updated client test to user newer methods and create the test account. - Added password to MUCJoin. - Fixed typo in DefineNamespace. - Added Tree Transfer (JEP-105) 1.29 ==== - Added PubSub (JEP-60) - Added documentation for most of the below. - Added in a basic basic support for SOAP (JEP-72). You can dump in rawxml and get it back out. - Looking into using contants for the namespaces, but they don't work in hashes. =( - Removed jabber:x:sxpm (it was never used). - Added initial (low level) support for Commands (JEP-50). - Added initial (low level) support for FNeg (JEP-20), Disco (JEP-30), Bytestream (JEP-65), SI (JEP-95), and FT-Profile (JEP-96). - Made Client, Component, and Server inherit from Protocol instead of AUTOLOADing. Why didn't I do this in the beginning? - Added function RosterRequest to let the user handle processing the roster in their own callback and not return a hash. - Added function PresenceDBClear that will clear out the presence database. - Added check to see if Process generated an error, and then was called again (bad thing). - Moved Process into Client.pm, Component.pm, and Server.pm. - Locked version of XML::Stream to 1.17. - Fixed typos in the Protocol help. 1.28 ==== - Fixed bug in XPathDefined which caused the main iq callback function to not work. Show stopper bug. - Fixed iq:time test. 1.27 ==== - Update examples/client scripts to include an xpath based example. - Added support for XPath based callbacks. - Updated x:data to match the call for experience. - Requires perl 5.6 in an attempt to get Unicode support. - Added finer callback support for presence and message based on type. - Minor tweak to NOT remove an unknown xmlns packet (duh...) - Fixed bug in JID. - Updated DefineNamespace to handle most old style, and all new style. - Locked version of XML::Stream to 1.16. - Major recore due to XML::Stream::Node and XPath. - Moved from XML::Stream::Hash to XML::Stream::Node. - Fixed XDB Reply error. - Uninitialized value round up. 1.26 ==== - Changed to a more sane version scheme. - Locked version of XML::Stream to 1.15. 1.0025 ====== - Documented the PresenceSend function a little better. - Added GetHumanTime function to convert seconds to a sentence. Useful for various Jabber things (last, time, etc.) - Added the ability to remove a callback. This is to try and speed thigs up by being able to unregister the receive and send callbacks when you don't care about them. - Added jabber:iq:rpc support based on JEP-0009. - Fixed bad function call in VersionQuery. - Added code to handle tracking the user's activity. - Added to the x:data. - Added RemoveXXXX function to match GetXXXX and SetXXXX. - Added timeouts to RegisterRequest(), SearchRequest(), and LastQuery(). - Fixed bug in LastQuery(). - Finished support for jabber:x:data (previously jabber:x:form in the 1.0021 change messages). - Added Execute function to Component to provide a generic inner loop for easier component writing. - Added support for a finer level of callbacks. You can now create callbacks for all types of packets and namespaces. See Net::Jabber::Protocol for more details. - Fixed bugs with the Raw XML functionality. - Added documentation to Net::Jabber for the Raw XML functions. 1.0024 ====== - Fixed a bug where no flag children were being put into the XML string. (ie. for iq:register). Ooops. - Ok... found a really stupid module scoping problem. If Protocol.pm is used before say Dialback.pm, then Protocol cannot call new from Dialback to make a packet. Moved use Protocol; to the last thing in import(). - Callback now checks if you have a callback defined for a packet, or if you were waiting for a packet via SendAndReceiveWithID. Might make some things faster. - Fixed mistake in DefineNamespace where it copied too many things into the hash. 1.0023 ====== - Fixed bugin accept for Components. - Added InsertRawXML and ClearRawXML. - Fixed Reply function in IQ. - Fixed bug in X.pm. - Added jabber:iq:pass support. DRAFT - Added jabber:iq:browse support into Protocol. 1.0022 ====== - XML::Stream supports SSL. Client docs updated to show the switches needed to enable that and HTTP. - Started to work on supporting XDB. But due to lack of documentation, this release DOES NOT 100% support it. Use at your own risk. - Updated docs to reflect changes. - Added Net::Jabber::Namespaces as a way to help document how the redesign works. It's probably incomplete so ask questions and I'll work on it. - Added check to make sure you specify a schema for the use Net::Jabber qw ( xxx ); line. - Fixed bug in Connect where it would not handle the case where it could not connect properly. - Fixed bug in Debug. - Fixed iq:time and iq:version. The redesign broke the automatic behavior they had before. - Tweaked ParseTree for changes in XML::Stream. - Fixed bug in Query.pm where I forgot to copy over a function for jabber:iq:search. - Redesigned modules to try and use less memeory. - Changed over to the new XML::Stream Hash data format. This has helped to reduce memory usage by half (initial results) although it comes at the cost of increased disk usage. - Moved the GetXMLData, SetXMLData, and BuildXML functions into XML::Stream where they belong. Should have done that long ago. 1.0021 ====== - Fixed bug in the Process function caused by the XML::Stream changes. - Added in jabber:x:form. - Added in jabber:x:sxpm. - Removed Transport.pm. - Removed the transport examples and created Component examples. - Changed Component.pm to stop using tcpip and stdinout and use the standard accept and exec. - Changed Debug to handle LogN instead of just 0, 1, and 2. - Added RemoveX to Message and Presence. - Added x:signed and x:encrypted. - In the GetXMLData function in Jabber.pm I forgot to add a test for existence of an attribute in the root tag. 1.0020 ====== - Added support for jabber:x:replypres. - Added an update function to the SetCallBacks function list. - In the SetTo and SetFrom functions, if you try to set it to "" it ignores your request. - Since those are gone, the Reply functions got a lot simpler, so I removed the template argument on most of them. - Removed all references to etherx:to, etherx:from, sto, and sfrom. - Removed anonymous connections from AuthSend since they were taken out of Jabber. - Changed AuthSend to always pick the highest level of security as possible. It now queries the server for all possibilities and picks from the answer. - PresenceDBParse now returns the current presence based on PresenceDBQuery. - Forgot to add a timeout to the Connect functions in Client.pm and Component.pm. - Modified the object creation functions to handle the below so that old code doesn't break. - Changed the way that callbacks are handled. Instead of passing in an XML::Parser::Tree array that the user had to then convert into a Net::Jabber::XXXXXX object. Now the callbacks are passed in the proper Net::Jabber::XXXXXX objects directly. - Modified the GetTimeStamp function in Jabber.pm to support two new types: utcdelaytime and localdelaytim so that you can the tiem value back out to modify before converting to a string. - Added support for ZeroK Authentication. Both in Query/Auth.pm and in AuthSend in Protocol.pm. 1.0019 ====== - Fixed Component.pm to use the new XML::Stream to argument in the Connect function for writing Components to work with the accept model. - Fixed bug in Component.pm where someone on the sever side changed the namespace that you are supposed to connect with and never told me. - Fixed bug in the cases where I would use SendAndReceiveWithID. I was not checking for undef. - Added more debugging in Protocol.pm. 1.0018 ====== - Changed the WaitForID function to be Process() instead of Process(0). - Fixed bug in RosterGet where I might get an undefined value and I wasn't checking for it. - Fixed bug in PresenceDBQuery in Protocol.pm. A hash value was being accessed and causing the Presence DB to become tainted. - Added boiler plate comments for the LGPL. 1.0017 ====== - Deprecating Transport.pm. It will cease to exist in the near future in favor of the Component.pm module and Jabber Server Components. - Fixed support for the new connection profile found in the new Jabber server. (You cannot use this to connect a Transport to a server before 1.1.2). - Fixed bug in JID.pm where changing a JID that did not have a UserID part, but previously had a value in the Server would goof up. - Fixed bug in AuthSend where the type='set' attribute was not being set for the . - Fixed bug where an unkown namespace in an IQ would cause an error. 1.0016 ====== - Converted the rest of the functions to the AUTOLOAD method. - PresenceSend in Protocol.pm now returns the presence object that it sent. - Changed GetJID in JID to not return the @ when the JID dues not have a userid. - Moved Perl requirement to 5.005. - Moved XML::Stream requirement to 1.06 to support the timestamp and a bug fix. - Added timestamp support to Debug.pm. - Added digest control to AuthSend. 1.0015 ====== - Fixed bug with EscapeXML and the XML::Parser. - Converted the Query namespaces to the new AUTOLOAD method. - Fixed bug in the Search.pm file where it would trounce the XML::Parser::Tree. 1.0014 ====== - Fixed bug in the Search namespaces that would cause duplicates to be placed in the query if multiple calls to MergeItems were made. 1.0013 ====== - Removed some leftover print statements that would cause confusing output to STDOUT. 1.0012 ====== - In the Message module Reply function, it only does "re: " for normal messages now. - Added to the iq:register namespace. 1.0011 ====== - Added PresenceDBDelete to allow for deleting JIDs from the the DB. - Fixed a bug where PresenceDBParse would take any presence, regardless of the type. It should only take available and unavailable. 1.0010 ====== - Fixed a bug in the GetXMLData function where it would try to check an attrib but the array entry it was checking did not contain an array. Added a ref() statement in there to fix that. - Fixed another bug with the ErrorCode functions where I forgot to change all of the calls in Protocol to ErrorCode from ErrorType. 1.0009 ====== - Fixed bug in the error tags. 1.0008 ====== - Fixed a bug in the AutoUpdate/Release.pm code. 1.0007 ====== - Added Query/Filter to support the mod_filter in the server. - Added PresenceDB functions to make managing the multiple resource and priority thing much easier for a client/transport. - Initialized some variables to get rid of warnings under perl -w. - Fixed outgoing XML to be UTF-8 encoded. 1.0006 ====== - Added support for in iq:search. 1.0005 ====== - Changed AutoUpdate namespaces to show becoming . - When SeachRequest and RegisterRequest get errors they now return undef to show that there was an error. - Changed versioning scheme to match up Perl and Jabber. 1.005 refers to Jabber version 1.0 and Net::Jabber verison 005. 1.0d ==== - GetQuery and GetX returns undef if there is not valid namespace found. - Fixed bug in namespace handling. Instead of hardcoding looking for and Net::Jabber now searches for any tag that has an xmlns and uses that tag as the query or x. - Added Jabber::X::GC to handle GroupChat X tags. - Added Debug object to make it easier to log debug information. - Fixed bug in JID where GetJID did not return the correct JID if there is an % in the UserID. - Added Key.pm. - Fixed bug in RosterRemove where the JID was not being sent and thus the item not being removed. 1.0c ==== - Fixed bug in Message, Presence, and IQ with the GetJID function changing. 1.0b ==== - Added Query::AutoUpdate. - In Query::Version, a call to SetOS will call POSIX::uname and try to get the OS name from there. (Not sure if this work on Windows and Mac...) - Added GetAgents function to Protocol.pm to query a server/transport and get the list of supported agents. - Fixed bug in Query where the sub lists (items from roster and agents from agents) were not being pulled back into . - Fixed bug in Agent were the GetJID and SetJID were operating on the wrong value. - Fixed bug in Agents where the new agent objects were not being created properly. - Fixed bug in examples/client where it called a function from Query without getting the query from the iq. - Added function Reply to IQ and Presence objects as well. - Added function Reply to Message objects. It takes a string, and based on that string it sets the proper values for to/from/etherx:to/etherx:from, thread, type, and id. 1.0a ==== - Added better example files in examples/. - Wrote Transport.pm, it too uses Protocol.pm through delegates. - Client.pm now uses delegates to pull in the functiosn from Protocol.pm. - Moved high-level functions out of Client.pm into Protocol.pm. - Added support for jabber:iq:agent, jabber:iq:agents, and jabber:x:roster. - Updated example.pl. - If you have Time::Timezone installed in the Query/Time.pm automagically uses the timezone functions to figure out your timezone when you call SetTZ(). - If you have Digest::SHA1 installed then Client.pm automagically uses the SHA-1 digest to encrypt the password for Authorization. - RosterGet returns a complex data structure that contains the roster from the server. - modules now use the AUTOLOAD and delegates same as the modules do. - Bumped version to 1.0a. - Changed method of handling timeouts. - Added code to better handle errors on the Stream. It now actually returns undef, or "", when the server or connection dies. - Added code to test a Connect without crashing. Connect returns undef, or "", if the Connect failed. 0.8.1b ====== - Added IgnoreIDs() and WatchIDs() in Client.pm. - Added support for delegates in the X/pm module. - Added X.pm alpha code to handle reading and setting tags in various top-level tags. - Added PresenceSend to send a presence tag. - Added RegisterSend to send a registration packet. - Fixed SetError and SetErrorType in Message.pm. - Added SetError and SetErrorType to IQ.pm. - Added support for "value" and "tree" on the root tag in the GetXMLData function in Jabber.pm. - Moved Disconnect functionality into XML::Stream. That's really where we should have been sending the closing tag... 0.8.1a ====== - Supports Jabber v0.8.1. - Fixed support for IQ tags. Changed to distributed modules for each namespace. - Created IQ/Auth.pm to give authentication support. - Created IQ/Roster.pm and IQ/Roster/Item.pm to provide Roster support. - Created IQ/Register.pm to give registration support. (Still experimental) - Created Presence.pm to provide support for presence tags. - Changed internal data structure to XML::Parser::Tree. This made integration with XML::Stream a snap. - Created helper functions to access an XML::Parser::Tree easily. - Changed Client.pm to use XML::Stream instead of doing it manually. 0.7.1 ===== - Added support for the new IQ, and Presence tags from Jabber-0.7. - Removed support for Status and Roster since those were removed from Jabber-0.7 in favor of IQ, and Presence. 0.6.2 ===== - Added Set* functions to Message.pm, Status.pm, and Roster.pm. - Moved Simply, BuildXML, and EscapeXML into Jabber.pm to avoid redundant functions. - Redesigned internal data structures to better handle structures and multiple copies of the same tag. - Added better documentation in the perldocs for each. - Changed the perldocs in each file from use Net::Jabber::xxxxx to just use Net::Jabber. - Removed support from Status since it isn't designed to handle it. - Changed the names of the Roster Set* functions. Get()->SetGet(), Add()->SetAdd(), and Delete()->SetDelete(). - Added support to Message.pm to send to multiple people using the SetTo command. 0.6.1 ===== - First version. Net-Jabber-2.0/META.yml0000644000175000017500000000052410112242736015670 0ustar reatmonreatmon00000000000000# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: Net-Jabber version: 2.0 version_from: lib/Net/Jabber.pm installdirs: site requires: Net::XMPP: 1 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.17 Net-Jabber-2.0/LICENSE.LGPL0000644000175000017500000006143710110275743016175 0ustar reatmonreatmon00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! Net-Jabber-2.0/MANIFEST.SKIP0000644000175000017500000000005510110275743016316 0ustar reatmonreatmon00000000000000Makefile$ TODO blib tests .swp$ CVS gen_docs Net-Jabber-2.0/Makefile.PL0000644000175000017500000000053410110275767016402 0ustar reatmonreatmon00000000000000use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Net::Jabber', 'VERSION_FROM' => 'lib/Net/Jabber.pm', 'PREREQ_PM' => { 'Net::XMPP' => 1.0, }, 'dist' => { 'COMPRESS' => 'gzip --best' } );