Sophie

Sophie

distrib > Mandriva > 7.2 > i586 > media > updates > by-pkgid > e5919242b1173b67c3c6d55b4eb6e5d5 > files > 651

kdenetwork-2.0.1-1mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML
><HEAD
><TITLE
>Programming Your Sirc Client</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.57"><LINK
REL="HOME"
TITLE="The KSirc Handbook"
HREF="index.html"><LINK
REL="PREVIOUS"
TITLE="Keys"
HREF="keys.html"><LINK
REL="NEXT"
TITLE="Hooks"
HREF="hooks.html"><META
HTTP-EQUIV="Content-Style-Type"
CONTENT="text/css"><LINK
REL="stylesheet"
HREF="common/kde-common.css"
TYPE="text/css"><META
HTTP-EQUIV="Content-Type"
CONTENT="text/html; charset=iso-8859-1"><META
HTTP-EQUIV="Content-Language"
CONTENT="en"><LINK
REL="stylesheet"
HREF="common/kde-localised.css"
TYPE="text/css"
TITLE="KDE-English"><LINK
REL="stylesheet"
HREF="common/kde-default.css"
TYPE="text/css"
TITLE="KDE-Default"></HEAD
><BODY
CLASS="CHAPTER"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#AA0000"
VLINK="#AA0055"
ALINK="#AA0000"
STYLE="font-family: sans-serif;"
><DIV
CLASS="logoheader"
><A
HREF="http://www.kde.org/"
><IMG
SRC="common/logotp3.png"
BORDER="0"
ALT="The K Desktop Environment"
HEIGHT="62"
WIDTH="229"></A
></DIV
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>The KSirc Handbook</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="keys.html"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="hooks.html"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="CHAPTER"
><H1
><A
NAME="PROGRAMMINGYOURSIRCCLIENT"
>Chapter 5. Programming Your Sirc Client</A
></H1
><P
>Warning: to understand this you need to know perl (the programming
language; read the perl man pages for more info), and have read the
README thoroughly.</P
><P
>For a real usable example of a sirc script, look at the file <TT
CLASS="LITERAL"
>n0thing.pl</TT
>;
if you wonder how you could do something in sirc script, try
understanding the functions defined in there.</P
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="COMMANDS"
>5.1. Commands</A
></H1
><P
>From <TT
CLASS="LITERAL"
>/loaded</TT
> scripts and <TT
CLASS="LITERAL"
>.sircrc.pl</TT
>, you can define new commands
and give their implementation in perl.</P
><P
>These scripts are actually files of perl code, and they get loaded
right into sirc's context.</P
><P
>To define a new command, all you need to do is define a sub with the
name <TT
CLASS="LITERAL"
>cmd_yourcommandname</TT
> which does whatever you want it to do, and call
<TT
CLASS="LITERAL"
>&#38;addcmd("yourcommandname");</TT
></P
><P
>You can also define some help for the command, by calling
<TT
CLASS="LITERAL"
>&#38;addhelp("yourcommandname", "First line of help\nSecond line of help...")</TT
>;</P
><P
>Your sub gets all of its arguments in the global variable <TT
CLASS="LITERAL"
>$args</TT
>
(unparsed), its own name in <TT
CLASS="LITERAL"
>$cmd</TT
>, and the whole command line in <TT
CLASS="LITERAL"
>$line</TT
>.</P
><P
>It can also use a number of routines from the sirc client:</P
><P
><DIV
CLASS="VARIABLELIST"
><DL
><DT
>&#38;load("file");</DT
><DD
><P
>loads a sirc script, searching in @loadpath.
the ".pl" extension is optional.</P
></DD
><DT
>&#38;dosplat;</DT
><DD
><P
>turns a * into the current channel name, if it's
the first word of <TT
CLASS="LITERAL"
>$args</TT
></P
></DD
><DT
>&#38;getarg;</DT
><DD
><P
>to get the first word of <TT
CLASS="LITERAL"
>$args</TT
> in $newarg and
the rest in <TT
CLASS="LITERAL"
>$args</TT
></P
></DD
><DT
>&#38;yetonearg;</DT
><DD
><P
>same thing, removing a trailing : in <TT
CLASS="LITERAL"
>$args</TT
> if
there's one</P
></DD
><DT
>&#38;eq("txt1", "txt2");</DT
><DD
><P
>tests case-insensitive equality</P
></DD
><DT
>&#38;sl("text");</DT
><DD
><P
>to send a line of text to the server (the
trailing <TT
CLASS="LITERAL"
>"\n"</TT
> gets added automatically)</P
></DD
><DT
>&#38;tell("txt");</DT
><DD
><P
>sends text to the screen, adding a <TT
CLASS="LITERAL"
>"\n"</TT
>, and
only if not in silent mode</P
></DD
><DT
>&#38;print("txt");</DT
><DD
><P
>sends text to the screen, adding a <TT
CLASS="LITERAL"
>"\n"</TT
>, regardless
of silent mode</P
></DD
><DT
>&#38;getuserline("str", "prompt");</DT
><DD
><P
>prints "str" on the screen, puts "prompt" as a
temporary prompt if using ssfe, and prompts the
users for a line, returning it in <TT
CLASS="LITERAL"
>$_</TT
></P
></DD
><DT
>&#38;getuserpass("str", "prompt");</DT
><DD
><P
>same for prompting passwords; ssfe will not echo
the password</P
></DD
><DT
>&#38;dostatus;</DT
><DD
><P
>redisplays the status line</P
></DD
><DT
>&#38;msg("nck", "msg");</DT
><DD
><P
>sends a message, printing it.  the destination
can be a nick, a channel, or a =nick (DCC CHAT)</P
></DD
><DT
>&#38;notice("nck", "msg");</DT
><DD
><P
>sends a notice, printing it.  the destination can be a channel or a nick</P
></DD
><DT
>&#38;say("msg");</DT
><DD
><P
>says something on the current channel, printing it</P
></DD
><DT
>&#38;describe("nck", "msg");</DT
><DD
><P
>sends a <TT
CLASS="LITERAL"
>/describe</TT
>, printing it</P
></DD
><DT
>&#38;me("msg");</DT
><DD
><P
>does an action on the current channel, printing it</P
></DD
><DT
>&#38;connect($fh, "host", port);</DT
><DD
><P
>opens a tcp connection with the given host and
port.  the first argument <TT
CLASS="LITERAL"
>($fh)</TT
> must be a
variable and <TT
CLASS="LITERAL"
>&#38;connect</TT
> sets it to the value of
the file handle associated with the connection.
<TT
CLASS="LITERAL"
>&#38;tell's</TT
> a message and returns 0 if there's an
error, otherwise returns 1.</P
></DD
><DT
>&#38;listen($fh, port);</DT
><DD
><P
>opens listening socket bound to the given port;
lets the system pick a port if the specified
port is 0 (or the second argument is not passed
at all).  the first argument must be a variable
and <TT
CLASS="LITERAL"
>&#38;listen</TT
> sets it to the value of the file
handle associated with the listening socket.
&#38;tell's a message and returns 0 if there's an
error, otherwise returns the port on which the
socket listens.</P
></DD
><DT
>&#38;accept($nfh, $ofh);</DT
><DD
><P
>accepts a connection on the file handle <TT
CLASS="LITERAL"
>$ofh</TT
>
(which must refer to a listening socket), and
returns it in <TT
CLASS="LITERAL"
>$nfh</TT
>;  <TT
CLASS="LITERAL"
>$nfh</TT
> must be a variable
and will be changed by <TT
CLASS="LITERAL"
>&#38;accept</TT
>.  <TT
CLASS="LITERAL"
>$ofh</TT
> is
automatically closed by <TT
CLASS="LITERAL"
>&#38;accept</TT
>.  returns a
boolean value, but does not print an error
message in any case.</P
></DD
><DT
>&#38;resolve("address");</DT
><DD
><P
>resolves a hostname into a packed in_addr (i.e
a 4-byte string representing the IP address).
the argument can be a hostname, an IP address
written in dotted quad notation, or a (large)
number representing the address, "read" as a
32-bit number in network order.  if the
resolution fails, returns a false result ("" or
0 or undef).</P
><P
>to get a dotted quad from what <TT
CLASS="LITERAL"
>&#38;resolve</TT
> returns,
use <TT
CLASS="LITERAL"
>join(".", unpack("C4", &#38;resolve("whatever")))</TT
></P
></DD
><DT
>&#38;newfh;</DT
><DD
><P
>returns a fresh name for use as a filehandle</P
></DD
><DT
>&#38;doset("variable", "value");</DT
><DD
><P
>sets a value to a SET variable; the value is
validated, and this has no effect if the value
is incorrect or the variable does not exist.
this is the only way scripts should ever change
the values of SET variables, except possibly
those that they define themselves.</P
></DD
><DT
>&#38;docommand("command");</DT
><DD
><P
>interprets a command line as if it were typed at
the keyboard.  a *single* leading "/" will
disable alias/function expansion on the
command.</P
><P
>*warning* this calls the command dispatcher
recursively from itself, which is pretty bad.
there is a test against loops (a limit on
recursion, set to 20), but it's mostly up to
*you* to make sure your scripts work.
perl being a language with strong and powerful
control structures (unlike ircII...), recursion
at this level should be avoided whenever
possible.</P
></DD
></DL
></DIV
></P
><P
>You have access to the a number of global variables;  note that some have
been removed because they have been turned into SET variables, to be
read in %set and written to with &#38;doset.</P
><P
>Unless otherwise specified, these variables should be treated as
read-only by scripts.
<DIV
CLASS="VARIABLELIST"
><DL
><DT
>$version</DT
><DD
><P
>sirc's version - should always be a number, and
never be modified by a user function</P
></DD
><DT
>$add_ons</DT
><DD
><P
>additional modules loaded; scripts can add a
"+scriptname" to it</P
></DD
><DT
>$restrict</DT
><DD
><P
>set to true if sirc is running in restricted
(secure) mode, which disallows access to the
shell and to the filesystem</P
></DD
><DT
>$maxrecursion</DT
><DD
><P
>number of times &#38;docommand may be called recursively
before giving a "max recursion exceeded" error (you
can change this one, but it is not guaranteed to
work on future versions where this might become a
SET variable)</P
></DD
><DT
>$nick</DT
><DD
><P
>your current nick</P
></DD
><DT
>$server</DT
><DD
><P
>your current server</P
></DD
><DT
>@channels</DT
><DD
><P
>list of channels you're on</P
></DD
><DT
>$talkchannel</DT
><DD
><P
>your current channel (or '' if none)</P
></DD
><DT
>%mode</DT
><DD
><P
>associative array with the modes of the different
channels we're on.  the channel names are all in
lower case, and the mode is a string of letters
without +'s or -'s, and without 'k' or 'l' either
since those are treated separately.  the value
for channels without any mode is '', while the
value for channels we're not on is undef.</P
></DD
><DT
>%chankey</DT
><DD
><P
>keys to channels, undef if none or we're not on
the channel.  channel names are in lower case.</P
></DD
><DT
>%limit</DT
><DD
><P
>limits to channels, undef if none or we're not
on the channel.  channel names in lower case.</P
></DD
><DT
>%haveops</DT
><DD
><P
>associative array of booleans, true if we have ops
on the channel.  channel names are...  you know how</P
></DD
><DT
>$umode</DT
><DD
><P
>user mode, string of letters without +'s or -'s</P
></DD
><DT
>$query</DT
><DD
><P
>whoever you're querying, or '' if no-one</P
></DD
><DT
>%aliases</DT
><DD
><P
>associative array of defined substitution aliases;
the alias name is in CAPS</P
></DD
><DT
>%set</DT
><DD
><P
>associative array of SET variable values; the
variable name is in CAPS too</P
></DD
><DT
>%notify</DT
><DD
><P
>associative array of the notify list; the value
for a given nick is 0 for "absent", or the time
of the most recent notification for this nick</P
></DD
><DT
>$bindaddr</DT
><DD
><P
>this is the IP address of the machine to which
outgoing connections are bound, as far as sirc
can tell.  it changes when the "localhost" SET
variable changes, and is set to the IP of the
proxy machine when sirc is running with socks
support loaded.  <TT
CLASS="LITERAL"
>$bindaddr</TT
> is a 4-byte string
representing a packed <TT
CLASS="LITERAL"
>in_addr;</TT
> you can get an
integer out of it (as used by DCC CHAT/SEND)
with <TT
CLASS="LITERAL"
>unpack("N", $binaddr);</TT
> and a dotted quad
with <TT
CLASS="LITERAL"
>join(".", unpack("C4", $bindaddr));</TT
></P
></DD
></DL
></DIV
></P
><P
>Unless otherwise specified, commands and hooks should never modify the
parameters that are passed to them (i.e. do somethign like
<TT
CLASS="LITERAL"
>$_[1]="some value"</TT
>.  If they wish to modify local copies of them, they
should start with <TT
CLASS="LITERAL"
>local(...)=@_;</TT
></P
><P
>Also, if your script is going to use global variables, please make sure
they're not likely to clash with sirc's own (same goes for file
descriptor names, and procedures).  A good convention would be to give
all these variables and procedures a name that starts with the script
name, or with a few letters from it.  For example, in <TT
CLASS="LITERAL"
>n0thing.pl</TT
> all the
script's global variables and internal procedures have names that start
with "n_".</P
><P
>Example, which could be put into a file and <TT
CLASS="LITERAL"
>/load'ed</TT
> directly, of
a command that will yeek on a channel if you specify one, and at a
nick if you do too:</P
><P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="SCREEN"
> sub cmd_yeek {
   &#38;dosplat;		# if the 1st arg is *, replace it with $talkchannel
   &#38;getarg;		# get 1st arg in $newarg
   local($channel)=($talkchannel);	# by default we talk to $talkchannel
   if ($newarg =&#732; /^[\#\&#38;]/) {		# if the 1st arg starts with # or &#38;
     $channel=$newarg;			# talk there instead
     &#38;getarg;				# and get an extra arg
   }
   if ($newarg) {	# look at whether we specified who we're yeeking at
     &#38;describe($channel, "look at $newarg and *yeeeks*");
   } else {		# or not
     &#38;describe($channel, "*yeeks* at the crowd");
   }
 }
 
 # \cb is the way to specify ^B in perl
 &#38;addcmd("yeek");
 &#38;addhelp("yeek", "Usage: \cbYEEK\cb [&#60;channel&#62;] [&#60;nick&#62;]
 Yeeks at the given nickname or at the whole channel.
 Examples: /yeek someone
           /yeek * someone
  	  /yeek #channel
  	  /yeek #channel someone");</PRE
></TD
></TR
></TABLE
></P
></DIV
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="keys.html"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="hooks.html"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Keys</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Hooks</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>