<?xml version="1.0" ?><!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.1-Based Variant V1.0//EN" "dtd/kdex.dtd" [
 <!ENTITY ksirc "<application>ksirc</application>">
 <!ENTITY % addindex "IGNORE">
 <!ENTITY docindex SYSTEM "docindex.docbook"> 
]>
<book lang="fr">

<bookinfo>
<title>Le manuel de KSirc</title>
<authorgroup>
<author>
<firstname>Andrew</firstname>
<surname>Stanley-Jones</surname>
<affiliation>
<address><email>asj@chowtown.cban.com</email></address>
</affiliation>
</author>
</authorgroup>
<date>??/??/????</date>
<releaseinfo>0.09.00</releaseinfo>
<abstract>
<para>Cette documentation décrit KSirc 0.9</para>
</abstract>
<keywordset>
<keyword>KDE</keyword>
<keyword>KMail</keyword>
<keyword>mél</keyword>
<keyword>messagerie électronique</keyword>
</keywordset>
</bookinfo>

<chapter id="installation">
<title>Installation</title>

<mediaobject><imageobject><imagedata fileref="ksirc.png" format="PNG"/></imageobject></mediaobject>

<para><emphasis>Installation des fichiers binaires</emphasis>
<itemizedlist>
<listitem>
<para>SI VOUS N'AVEZ PAS INSTALLE KDE
<screen>	cd /usr/local/
	tar -zxvf &lt;ksirc&gt;
	tar -zxvf kdehelp-netscape.tgz
</screen>
</para>

<para>Vous pouvez ensuite lancer ksirc en tapant "ksirc".
Rappelez-vous qu'il faut avoir installé perl5 sur votre machine.</para>

<para>Si vous voulez une aide en ligne et si vous n'avez pas installé KDE, avec
netscape vous obtenir kdehelp-netscape.tgz depuis ksirc.org/pub/ksirc</para>

</listitem>
<listitem>
<para>Pour ceux qui ont installé KDE</para>

<para><screen>	cd $KDEDIR/..
	tar -zxvf &lt;ksirc&gt;
</screen>
</para>

<para>Vous pouvez ensuite lancer ksirc en tapant "ksirc".</para>

</listitem>
</itemizedlist>
</para>
</chapter>

<chapter id="sectcolors">
<title>Couleurs de ksirc</title>

<para>KSirc suit le modèle des couleurs utilisées par mIrc avec une légère modification,
pour une utilisation personnelle plus performante.</para>

<para><screen>
&lt;fg&gt; == avant-plan
&lt;bg&gt; == arrière-plan
&lsqb;&rsqb; == options
</screen>
</para>

<sect1 id="compatibilit-avec-mirc">
<title>Compatibilité avec mIrc</title>

<para>Format:
<itemizedlist>
<listitem>
<para><emphasis>0x03&lt;fg&gt;&lsqb;,&lt;bg&gt;&rsqb;</emphasis>
définit l'avant-plan et l'arrière-plan</para>
</listitem>
<listitem>
<para><emphasis>0x03</emphasis>
effectue une réinitialisation avec les valeurs par défaut pour CETTE ligne</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="ksirc-natif">
<title>KSirc natif</title>

<para>Format:
<itemizedlist>
<listitem>
<para><emphasis>&tilde;&lt;fg&gt;&lsqb;,&lt;bg&gt;&rsqb;</emphasis>
définit l'avant-plan et l'arrière-plan</para>
</listitem>
<listitem>
<para><emphasis>&tilde;c</emphasis>
réinitialise tp par défaut</para>
</listitem>
<listitem>
<para><emphasis>&tilde;b</emphasis>
définit les polices en gras</para>
</listitem>
<listitem>
<para><emphasis>&tilde;u</emphasis>
définit le soulignement</para>
</listitem>
<listitem>
<para><emphasis>&tilde;i</emphasis>
définit les italiques</para>
</listitem>
<listitem>
<para><emphasis>&tilde;r</emphasis>
définit le soulignement</para>
</listitem>
</itemizedlist>
</para>

<para>Pourquoi ai-je modifié ksirc pour utiliser &tilde; au lieu de 0x03 (&circ;C)?
Eh bien il est difficile d'utiliser 0x03 dans les scripts et toutes les
fonctions en langage C ne semblent pas lui convenir.
L'expression &lt;letter&gt; permet également davantage de commandes sans
écraser les changements ultérieurs.</para>
</sect1>

<sect1 id="liste-des-couleurs">
<title>Liste des Couleurs</title>

<para><orderedlist><listitem>
<para> blanc</para>
</listitem>
<listitem>
<para> noir</para>
</listitem>
<listitem>
<para> bleu marine</para>
</listitem>
<listitem>
<para> vert</para>
</listitem>
<listitem>
<para> rouge</para>
</listitem>
<listitem>
<para> marron</para>
</listitem>
<listitem>
<para> violet</para>
</listitem>
<listitem>
<para> orange</para>
</listitem>
<listitem>
<para> jaune</para>
</listitem>
<listitem>
<para> vert clair</para>
</listitem>
<listitem>
<para> cyan</para>
</listitem>
<listitem>
<para> cyan clair</para>
</listitem>
<listitem>
<para> bleu outremer</para>
</listitem>
<listitem>
<para> rose</para>
</listitem>
<listitem>
<para> gris</para>
</listitem>
<listitem>
<para> gris clair</para>
</listitem>
</orderedlist>
</para>
</sect1>

<sect1 id="envoi-du-gras-soulign-invers-et-couleur">
<title>Envoi du Gras, Souligné, Inversé et Couleur</title>

<para>Vous pouvez utiliser les combinaisons de touches suivantes pour insérer des codes de controle
dans du texte.
<itemizedlist>
<listitem>
<para>Control-B pour le texte en gras</para>
</listitem>
<listitem>
<para>Control-U pour le texte souligné</para>
</listitem>
<listitem>
<para>Control-R pour le texte inversé</para>
</listitem>
<listitem>
<para>Control-K pour le texte coloré</para>
</listitem>
<listitem>
<para>Control-O pour le texte en clair</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="exemples">
<title>Exemples</title>

<para>Pour souligner un seul mot dans une phrase :
<orderedlist><listitem>
<para>Taper Control-U</para>
</listitem>
<listitem>
<para>Taper le mot</para>
</listitem>
<listitem>
<para>Taper Control-U à nouveau</para>
</listitem>
</orderedlist>
</para>

<para>Seul le texte qui est entouré par les codes de début et de fin sera affecté.
Vous pouvez utiliser cette méthode avec tous les autres codes de controle.</para>

<para>Le code de controle Control-K est légèrement différent car il vous autorise
à spécifier un numéro de couleur. Pour colorer un seul mot dans une phrase :</para>

<para><orderedlist><listitem>
<para>Taper Control-K</para>
</listitem>
<listitem>
<para>Taper un nombre entre 0 et 15</para>
</listitem>
<listitem>
<para>Taper le mot</para>
</listitem>
<listitem>
<para>Taper Control-K à nouveau</para>
</listitem>
</orderedlist>
</para>

<para>Si vous voulez également changer la couleur d'arrière-plan d'un mot,
vous devez taper deux nombres séparés par une virgule, au lieu d'un seul nombre.
Le premier nombre représente la couleur du texte, le second la couleur de l'arrière-plan.
Les couleurs sont classées de 0 à 15, l'index est décrit dans la précédente section.</para>

<para>Vous pouvez entourer du texte dans de multiples codes de controle,
vous pourrez donc par exemple avoir un mot en gras, souligné et coloré.</para>
</sect1>
</chapter>

<chapter id="les-filtres">
<title>Les Filtres</title>

<sect1 id="les-rgles-de-filtre-et-comment-les-crer">
<title>Les règles de filtre et comment les créer</title>

<para>Si vous n'arrivez même pas à comprendre, attendez. J'ai l'intention de
construire un "générateur de filtre" pratique où vous n'aurez qu'à cliquer
directement. Cependant, cela demandera un peu de temps.</para>

<para>Le filtre tente de trouver la chaîne de caractères "correspondante" puis
d'utiliser les équivalences "depuis" et "jusqu'à" à la place. Vous pourrez effectuer
les deux opérations, avec uniquement ce sous-programme qui
autorise un meilleur controle des chaînes de caractères sur lesquelles
vous effectuez la substitution. Les correspondances, "depuis" et "jusqu'à" sont toutes des
expressions rationnelles perl. Les règles sont numérotées par ordre
décroissant. La règle du sommet est numérotée en premier lieu, puis la
deuxième à partir du sommet, etc. Toutes les chaînes de caractères sont
numérotées ainsi :</para>

<para>$&lt;namem&gt; est étendue à la variable d'environnement
&lt;name&gt;. Ceci est effectué immédiatement lorsque vous
insérez la règle, et ne sera pas modifié ensuite. Par conséquent, c'est
vraisemblablement un nombre de valeur limitée).</para>

<para>$$&lt;name&gt; est remplacée par la variable $&lt;name&gt; pendant la
correspondance. Il peut s'agir de sous-chaînes de caractères comme $1, $2 dans
la substitution, ou de variables normales disponibles sous sirc (comme
$nick, $channel, etc).</para>

<para>&tilde;&lt;name&gt;&tilde; <emphasis>PREDETERMINEE UNE FOIS POUR TOUTES)</emphasis> à la ligne,
enverra la ligne de texte à la fenêtre appelée &lt;name&gt;. Si la
fenêtre n'existe pas, elle ira à la dernière fenêtre qui avait le focus. Il y
a plusieurs fenêtres spéciales, qui portent toutes un seul préfixe "!" :</para>

<para><variablelist>
<varlistentry>
<term>!par défaut</term>
<listitem>
<para>la fenêtre par défaut. Vous êtes certain de la trouver.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>!toutes</term>
<listitem>
<para>Envoi à chaque fenêtre. Cela pourrait ne pas s'afficher sur toutes les
fenêtres, en fonction de l'analyse du texte. Par exemple, les fenêtres de
canaux s'afficheront/quitteront à moins que le pseudonyme soit sur le canal.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>!suppression</term>
<listitem>
<para>supprime le texte</para>
</listitem>
</varlistentry>
</variablelist>
</para>

<para>Le reste de l'expression est traité comme une expression rationnelle perl normale.
Une bonne compréhension de la page de manuel perlref sera d'une aide
appréciable, mais un minimum de connaissances de base des expressions rationnelles
est obligatoire.</para>
</sect1>

<sect1 id="exemples-">
<title>Exemples :</title>

<para><orderedlist><listitem>
<para>Vous voulez convertir tous les "boren" depuis "boren" jusqu'à "BoreN"</para>

<para><screen>Correspondance : .*
Depuis : boren
Jusqu'à : BoreN

</screen>
</para>

<para>Sans aucun doute, il y a une correspondance, ensuite modifiez "boren"
en "BoreN".</para>

</listitem>
<listitem>
<para>Vous voulez tout faire correspondre avec "boren" et
l'envoyer à la fenêtre appelée "boren"</para>

<para><screen>Correspondance : boren
Depuis : ^
To: &tilde;boren&tilde;
</screen>
</para>

<para>Cherche "boren", s'il le trouve, remplace le début de la chaîne de caractères
(&circ;) par  &tilde;boren&tilde;.</para>

</listitem>
<listitem>
<para>Bien que l'exemple n°2 fonctionne, si la chaîne de caractères contient déjà
<literal>&tilde;somewindow&tilde;</literal>, vous aurez maintenant deux
<literal>&tilde;boren&tilde;&tilde;somewindow&tilde;...</literal>. Donc vous pouvez
faire plutot :</para>

<para><screen>Correspondance : boren
Depuis :  ^(?:&tilde;\S+&tilde;)
Jusqu'à : &tilde;boren&tilde;
</screen>
</para>

<para>D'accord, la ligne "depuis" est un tout petit peu plus compliquée. Elle signifie
qu'il n'y a pas de correspondance ou qu'il y a une copie de <literal>&tilde;\S+&tilde;</literal>,
qui est le premier tilde, une espace ou pas d'espace du tout, et ensuite un autre tilde.
Les puristes feront <literal>(*:&tilde;\S+&tilde;)</literal> qui signifie correspondance
0 ou plusieurs instructions de canal, au cas où les règles précédentes
ne fonctionneraient plus.</para>

</listitem>
<listitem>
<para>Les messages d'arrêt du serveur sont alors longs, laids, ennuyeux, etc.
Un message typique sur réseau de dialogue ressemble à :</para>

<para><screen>*** Notice -- Received KILL message for BOBO!ANDY@line82-basel.datacomm.ch
from NickServ Path: empire.ny.us.dal.net[209.51.168.14]!trapdoor.ca.us.dal
.net[206.86.127.252]!caris.ca.us.dal.net[208.1.222.221]!services.dal.net[2
008.1.222.222]!services.dal.net (NickServ Enforcement)
</screen>
</para>

<para>Lorsque vous êtes <literal>+s</literal>, vous avez des tas de messages, et vous ne voulez pas
en voir partout sur votre écran. Je vais créer 3 règles pour les traiter
morceau par morceau. Vous pourrez le faire avec moins de règles,
mais cela vous montrera la structure de base d'une règle, avec des étapes faciles,
et comment utiliser les multiples règles pour analyser un message.
La première étape consiste à supprimer le Path: (chemin) du message,
et ce sera l'exemple 4.</para>

<para><screen>Correspondance : ^\*\*\*.* KILL message for .* (message d'ARRET pour .*)
Depuis : Path: \S+
Jusqu'à: .
</screen>
</para>

<para>La correspondance cherche le message débutant avec <literal>***</literal>, les * doivent
être mentionnées avec \ puisqu'elles signifient par elles-mêmes 0 ou supérieur
au caractère précédent.
Le <literal>.*</literal> signifie correspondance quelconque jusqu'à ce que vous
trouviez <literal>KILL message for </literal>. Cela nous permet d'éviter de taper
<literal>-- Received...</literal> etc. La fin  <literal>.*</literal> indique une correspondance
quelconque jusqu'à la fin de la ligne. (inutile je pense)</para>

<para>La ligne "Depuis" indique de remplacer l'espace "Path: espace" et tout caractère autre
qu'une espace par "Jusqu'à". "Jusqu'à" est un <literal>"."</literal>,
par conséquent le chemin entier se transforme en un point uniquement.
().</para>

<para>Le message ressemble maintenant à :
<screen>*** Notice -- Received KILL message for BOBO!ANDY@line82-basel.datacomm.ch
from NickServ. (NickServ Enforcement)
</screen>

Vous remarquez le nouveau <literal>"."</literal> après <literal>NickServ</literal>?</para>

</listitem>
<listitem>
<para>D'accord, le message est beaucoup plus net, mais les messages d'arrêt depuis
le serveur de pseudonymes ne sont pas vraiment importants, donc laissons-les
dans la fenêtre <literal>!supprimer</literal>.
<screen>Correspondance : ^\*\*\*.*KILL message .*\(NickServ Enforcement\)
Depuis: ^(?:&tilde;\S+&tilde;)
Jusqu'à :  &tilde;!discard&tilde;
</screen>
</para>

<para>La règle de correspondance recherche le message d'ARRET et s'assure qu'il vient de
NickServ (serveur de pseudonymes). Vous remarquez les <literal>\(</literal> et <literal>\)</literal>,
les deux <literal>()</literal>  utilisés dans les expressions rationnelles, par conséquent
nous devons les mentionner. Ceci est très similaire à l'exemple 3.</para>

</listitem>
<listitem>
<para>Nous avons maintenant éliminé tous les messages d'arrêt du serveur
de pseudonymes, mais le message est encore assez difficile
à lire d'un simple coup d'oeil. Remettons-le donc en ordre comme ceci :</para>

<para><screen>*** [KILL] &lt;KILLER&gt; arrêté &lt;KILLED&gt; (motif)
Correspondance: \*\*\*.*message d'ARRET
Depuis: \*\*\*.*for (.*?) from (.*?)\. \((.*?)\).*
Jusqu'à:  *** [KILL] $$2 killed $$1 ($$3)
</screen>
</para>

<para>D'accord, la correspondance cherche le message d'ARRET <literal>***&lt;something&gt;</literal>.
Nous ne pouvons utiliser <literal>&circ;</literal>  puisque nous venons d'ajouter <literal>&tilde;&lt;fenêtre&gt;&tilde;</literal>.</para>

<para>La ligne "Depuis" devient un peu plus intéressante. L'expression <literal>"for (.*?) "</literal>
cherche le mot pour la suite du texte. <literal>.*?</literal> correspond à zéro ou plusieurs occurences
de n'importe quel caractère, excepté une nouvelle ligne, mais n'est pas absorbant.
Arrêtons lorsque la première condition de terminaison est trouvée, mais non la dernière.
En d'autres termes, il cherche une correspondance quelconque jusqu'à ce qu'il
trouve une espace. La zone entourée de <literal>()</literal> indique de sauvegarder le contenu.
Chaque () sauvegarde les données correspondantes dans <literal>$&num;</literal> où <literal>&num;</literal>
commence à 1 pour la première sous-chaîne de caractères, etc. Dans ce cas,
<literal>$1</literal> obtient l'information-utilisateur/pseudonyme de la personne "tuée".
<literal>$2</literal> est ensuite complétée avec le nom du "tueur". Entre les <literal>()</literal>,
nous avons le motif de l'arrêt. Ici les <literal>(</literal> et <literal>\(</literal> prêtent un peu
à confusion. Rappelez-vous, <literal>\(</literal> correspond au caractère réel <literal>'('</literal>.</para>

</listitem>
<listitem>
<para>Comment colorer votre vie. D'accord, vous voulez ajouter de la couleur à ksirc.
Voyez la section <link linkend="sectcolors">section Couleurs</link> pour
une information sur la couleur, mais il y a une règle de filtre pour
mettre en surbrillance le pseudonyme entre <literal>&lt;NICK&gt;</literal> sur chaque ligne :
<screen>Correspondance: ^(?:&tilde;\S+&tilde;)&lt;\S+&gt;
Depuis: &lt;(\S+)&gt;
Jusqu'à: &lt;&tilde;4$$1&tilde;c&gt;
</screen>
</para>

<para>Prend le pseudonyme et ajoute la couleur n°4 entre les deux <literal>&lt;&gt;
&tilde;c</literal> éclaircit la couleur</para>

</listitem>
</orderedlist>
</para>
</sect1>
</chapter>

<chapter id="touches">
<title>Touches</title>

<para>Voici une liste des raccourcis et des touches de commande sous Ksirc.
<itemizedlist>
<listitem>
<para><emphasis>Alt-F</emphasis>
Menu Fichier</para>
</listitem>
<listitem>
<para><emphasis>Alt-E</emphasis>
Menu Editer</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-N</emphasis>
Nouveau canal/Fenêtre de requête</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-T</emphasis>
Mode Terminal</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-Q</emphasis>
Quitter</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-X</emphasis>
Fenêtre Couper</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-V</emphasis>
Coller</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-Enter</emphasis>
Interlocuteur précédent</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-Shift-Enter</emphasis>
Interlocuteur suivant</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-K</emphasis>
Code de couleur de début</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-U</emphasis>
Soulignement Début/Fin</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-I</emphasis>
Italique Début/Fin</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-B</emphasis>
Gras Début/Fin</para>
</listitem>
<listitem>
<para><emphasis>Ctrl-R</emphasis>
Inversé Début/Fin</para>
</listitem>
<listitem>
<para><emphasis>Tab</emphasis>
Complétement du pseudonyme</para>
</listitem>
</itemizedlist>
</para>
</chapter>

<chapter id="programmation-de-votre-client-sirc">
<title>Programmation de votre Client Sirc</title>

<para>Attention : pour comprendre ceci, vous avez besoin de connaître perl
(le langage de programmation; lisez les pages de manuel pour plus d'informations),
et d'avoir lu soigneusement le README.</para>

<para>Pour un exemple de script sirc vraiment utile, regardez le fichier <literal>n0thing.pl</literal>;
si vous vous demandez comment vous y prendre avec un script sirc, essayez
de comprendre les fonctions qui y sont définies.</para>

<sect1 id="commandes">
<title>Commandes</title>

<para>Depuis les scripts <literal>/loaded/tt&gt;</literal> (chargés) et <literal>.sircrc.pl</literal>, vous
pouvez définir de nouvelles commmandes et donner leur exécution en perl.</para>

<para>Ces scripts sont en fait des fichiers en code perl, et ils sont chargés
de façon correcte dans le contexte de sirc.</para>

<para>Pour définir une nouvelle commande, vous n'avez qu'à définir un sous-programme
avec le nom <literal>cmd&lowbar;yourcommandname</literal> (nomdevotrecommande) qui agit dans tous les cas,
et appeller <literal>&amp;addcmd("yourcommandname");</literal></para>

<para>Vous pouvez également définir une aide pour la commande en appelant
<literal>&amp;addhelp("yourcommandname", "Première ligne d'aide\nSeconde ligne d'aide...")</literal>;</para>

<para>Votre sous-progamme prend tous ses arguments dans la variable globale <literal>$args</literal>
(non analysée), son nom véritable dans <literal>$cmd</literal>, et la ligne entière
de commande dans <literal>$line</literal>.</para>

<para>Il peut aussi utiliser un numéro de routine depuis le client sirc.</para>

<para><variablelist>
<varlistentry>
<term>&amp;load("file");</term>
<listitem>
<para>charge un script sirc, vérifie dans @loadpath.
que l'extension ".pl" est optionelle.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;dosplat;</term>
<listitem>
<para>change une * dans le nom du canal courant, si elle est
le premier mot de <literal>$args</literal></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;getarg;</term>
<listitem>
<para>pour obtenir le premier mot de <literal>$args</literal> dans $newarg et le reste
dans <literal>$args</literal></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;yetonearg;</term>
<listitem>
<para>même chose, supprime une fin de ligne : dans <literal>$args</literal> s'il
y en a une</para>
<para></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;eq("txt1", "txt2");</term>
<listitem>
<para>vérifie une égalité qui ignore la casse</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&amp;sl("text");</term>
<listitem>
<para>pour envoyer une ligne de texte au serveur (la fin
<literal>"\n"</literal> est ajoutée automatiquement)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&amp;tell("txt");</term>
<listitem>
<para>envoie du texte à l'écran, ajoute un <literal>"\n"</literal>, et
uniquement s'il n'est pas en mode silencieux</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&amp;print("txt");</term>
<listitem>
<para>envoie du texte à l'écran, ajoute un <literal>"\n"</literal>, sans tenir compte
du mode silencieux</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&amp;getuserline("str", "prompt");</term>
<listitem>
<para>édite "str" sur l'écran, place "prompt" comme invite
temporaire s'il utilise ssfe, et guide les utilisateurs pour envoyer
une ligne, la renvoie dans <literal>$&lowbar;</literal></para>
</listitem>
</varlistentry>
<varlistentry>
<term>&amp;getuserpass("str", "prompt");</term>
<listitem>
<para>même chose pour les mots de passe d'invite; ssfe ne répétera
pas le mot de passe</para>
<para></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;dostatus;</term>
<listitem>
<para>affiche de nouveau la ligne d'état</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;msg("nck", "msg");</term>
<listitem>
<para>envoie un message, l'édite. La destination peut être un pseudonyme,
un canal, ou un =nick (DCC CHAT)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;notice("nck", "msg");</term>
<listitem>
<para>envoie une remarque, l'édite. La destination peut être un canal ou un pseudonyme</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;say("msg");</term>
<listitem>
<para>signale quelque chose sur le canal courant, l'édite</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;describe("nck", "msg");</term>
<listitem>
<para>envoie un  <literal>/describe</literal>, l'édite</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;me("msg");</term>
<listitem>
<para>effectue une action sur le canal courant, l'édite.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;connect($fh, "host", port);</term>
<listitem>
<para>ouvre une connexion tcp avec l'hote et donne le port.
Le premier argument<literal>($fh)</literal> doit être une variable et
<literal>&amp;connect</literal> la définit à la valeur du gestionnaire de fichiers
associé à la connexion. <literal>&amp;tell's</literal> nous indique un message
et renvoie 0 s'il y a une erreur, sinon 1.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;listen($fh, port);</term>
<listitem>
<para>ouvre un support d'écoute limité au port donné;
laisse le système désigner un port si le port spécifié est 0
(ou si le second argument n'a pas disparu en totalité).
Le premier argument doit être une variable et <literal>&amp;listen</literal>
la définit à la valeur du gestionnaire de fichiers associé au support
d'écoute. &amp; nous signale un message et renvoie 0 s'il y a une erreur,
sinon retourne au port sur lequel le support est en attente.</para>
<para></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;accept($nfh, $ofh);</term>
<listitem>
<para>admet une connexion sur le gestionnaire de fichiers <literal>$ofh</literal>
(qui doit se reporter à un support d'écoute), et le renvoie
dans <literal>$nfh</literal>;  <literal>$nfh</literal> doit être une variable, et
sera modifée par <literal>&amp;accept</literal>.  <literal>$ofh</literal>
automatiquement fermée par <literal>&amp;accept</literal> renvoie
une valeur booléenne, mais n'édite en aucun cas de message d'erreur.</para>
<para></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;resolve("address");</term>
<listitem>
<para>définit un nom d'hote dans un fichier groupé
(c'est-à-dire une chaîne de caractères de 4 bits représentant
l'adresse IP). L'argument peut être un nom d'hote, une adresse IP
écrite en notation à quatre séries de chiffres, ou un (grand)
nombre représentant l'adresse "lue" comme un nombre 32 bits
dans une instruction réseau.  Si la définition échoue, un
résultat faux est renvoyé ("" ou 0 ou indéterminé).</para>
<para>pour obtenir un système à quatre séries de chiffres,
à partir duquel <literal>&amp;resolve</literal> est renvoyé,
utilisez <literal>join(".", unpack("C4", &amp;resolve("whatever")))</literal></para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;newfh;</term>
<listitem>
<para>renvoie un nouveau nom à utiliser comme gestionnaire de fichiers</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;doset("variable", "value");</term>
<listitem>
<para>définit une valeur à une variable SET, la valeur est
validée, et cela n'a pas d'effet si la valeur est incorrecte
ou si la variable n'existe pas. C'est la seule façon
pour que les scripts modifient les valeurs des variables SET,
sauf éventuellement celles qu'ils définissent eux-mêmes.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &amp;docommand("command");</term>
<listitem>
<para>interprète une ligne de commande comme si elle était
tapée au clavier. Un *seul* interligne "/" désactivera l'extension
alias/fonction sur la commande.</para>
<para>*attention* cette routine appelle de façon récurrente
le répartiteur de commandes pour elle-même, ce qui est assez gênant.
C'est une vérification à l'encontre des boucles (récursion limitée
à 20), mais c'est amplement suffisant pour que *vous*
soyez sûr que vos scripts fonctionnent.
Perl étant un langage doté de structures puissantes et performantes
(au contraire de ircII ...), la récursion à ce niveau est
à éviter autant que possible.
descrip&gt;</para>
<para>Vous avez accès à un nombre de variables globales; notez que certaines ont été
supprimées car elles ont été modifiées en variables SET, pour être lues dans &percnt;set et
écrites avec &amp;doset.</para>
<para>A moins qu'autre chose ne soit spécifié, ces variables seront traitées en lecture
seule par les scripts..</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$version</term>
<listitem>
<para>version de sirc's - doit toujours être un nombre, et
ne doit jamais être modifiée par une fonction utilisateur</para>
<para></para>
</listitem>
</varlistentry>
<varlistentry>
<term>$add&lowbar;ons</term>
<listitem>
<para>chargement de modules supplémentaires; des scripts peuvent y ajouter
un *nomdescript"</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$restrict</term>
<listitem>
<para>définie comme vraie si sirc tourne en mode restreint (sécurisé), qui
interdit l'accès à l'interpréteur de commandes et au système de fichiers  		</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$maxrecursion</term>
<listitem>
<para>number of times &amp;docommand : peut être appelée de façon récurrente
avant de donner un message d'erreur "taux maximum de récursion
dépassé" (vous pouvez modifier celle-ci, mais il n'est pas
sûr qu'elle fonctionne sur des versions ultérieures où elle
pourrait devenir une variable SET)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$nick</term>
<listitem>
<para>votre pseudonyme courant</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$server</term>
<listitem>
<para>votre serveur courant</para>
</listitem>
</varlistentry>
<varlistentry>
<term>@channels</term>
<listitem>
<para>liste des canaux sur lesquels vous êtes connecté</para>
</listitem>
</varlistentry>
<varlistentry>
<term>$talkchannel</term>
<listitem>
<para>votre canal courant (ou '' s'il n'y en pas)</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &percnt;mode</term>
<listitem>
<para>tableau réunissant les modes des différents canaux
sur lesquels nous sommes connectés. Les noms de canaux sont
tous dans la case inférieure, et le mode est une chaîne
de caractères sans +' ni -', et sans 'k' ou 'l' puisque ceux-ci
sont traités séparément.
La valeur des canaux sans aucun mode est '', tandis que la valeur
pour les canaux sur lesquels nous ne sommes pas connectés est
indéterminée.			</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&percnt;chankey</term>
<listitem>
<para>touches des canaux, indéfini s'il n'y en a aucun ou si nous ne sommes
pas connectés sur le canal. Les noms de canaux sont dans la case
inférieure.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&percnt;limit</term>
<listitem>
<para>limites des canaux, indéfini s'il n'y en aucun ou si nous ne sommes
pas connectés sur le canal. Les noms de canaux sont dans la case
inférieure.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&percnt;haveops</term>
<listitem>
<para>tableau réunissant les variables booléennes, vrai si nous avons
des opérations sur le canal. Les noms de canaux sont... vous le savez</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  $umode</term>
<listitem>
<para>mode utilisateur, chaîne de caractères sans +' ni -'</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  $query</term>
<listitem>
<para>tout interlocuteur que vous demandez, ou '' s'il n'y a personne</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  &percnt;aliases</term>
<listitem>
<para>tableau réunissant les alias de substitution définis;
le nom d'alias est en capitales		</para>
</listitem>
</varlistentry>
<varlistentry>
<term>&percnt;set</term>
<listitem>
<para>tableau réunissant les valeurs des variables SET; le nom
de variable est également en capitales</para>
</listitem>
</varlistentry>
<varlistentry>
<term> &percnt;notify</term>
<listitem>
<para>tableau réunissant la liste de notification; la valeur
pour un pseudonyme donné est 0 pour un "absent", ou le
moment de la plus récente notification pour ce pseudonyme</para>
</listitem>
</varlistentry>
<varlistentry>
<term>  $bindaddr</term>
<listitem>
<para>c'est l'adresse IP de la machine à laquelle les connexions de sortie sont
limitées, jusqu'à ce que sirc puisse le signaler. Elle change
lorsque la variable SET de "l'hote local" change, et elle
est déterminée à l'adresse IP de la machine proxy lorsque sirc tourne
avec les supports de communication chargés. <literal>$bindaddr</literal> est
une chaîne de caractères de 4 bits représentant un groupe <literal>in&lowbar;addr;</literal>
que vous obtenez en entier (comme il est d'usage dans DCC CHAT/SEND)
avec <literal>unpack("N", $binaddr);</literal>, et un système à quatre séries de
chiffres avec <literal>join(".", unpack("C4", $bindaddr));</literal></para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>A moins qu'autre chose ne soit spécifié, commandes et points d'insertion ne devraient
jamais modifier les paramètres qui leur ont été assignés (c'est-à-dire faire quelque chose
comme <literal>$&lowbar;[1]="some value"</literal>.  S'ils souhaitent en modifier des copies locales, ils
commenceront avec <literal>local(...)=@&lowbar;;</literal></para>
<para>Si votre script utlise des variables globales, veuillez
vous assurer qu'elles ne vont pas s'opposer à celles de sirc (même
problème pour les noms de description de fichiers, et de procédures).
Une bonne convention serait de donner à toutes ces variables et procédures
un nom qui commence par le nom du script, ou avec quelques lettres de celui-ci.
Par exemple, dans <literal>n0thing.pl</literal> toutes les variables globales de script et
les procédures internes ont des noms qui commencent par "n&lowbar;".</para>
<para>Exemple, que pourrait-on introduire directement dans un fichier <literal>/load'ed</literal>,
une commande qui (cible?) un canal si vous en spécifiez un, et un
pseudonyme si vous le mentionnez également :</para>
<para><screen>sub cmd_yeek {
  &amp;dosplat;		# si le premier argument est *, remplacez-le avec $talkchannel
  &amp;getarg;		# place le premier argument dans $newarg
  local($channel)=($talkchannel);	# par défaut, nous communiquons avec le canal $talkchannel
  if ($newarg =&tilde; /^[\#\&amp;]/) {		# si le premier argument commence avec # or &amp;
    $channel=$newarg;			# communiquez plutot ici
    &amp;getarg;				# et placez un argument supplémentaire
  }
  if ($newarg) {	# regardez si nous avons spécifié que nous (ciblons?)
    &amp;describe($channel, "look at $newarg and *yeeeks*"); ("regardez $newarg et (*ciblez*")?)
  } else {		# or not (ou non)
    &amp;describe($channel, "*yeeks* at the crowd"); ((*ciblez*?) le groupe*);
}

# \cb est la manière de spécifier ^B en perl
&amp;addcmd("yeek");
&amp;addhelp("yeek", "Usage: \cbYEEK\cb [&lt;channel&gt;] [&lt;nick&gt;]
Cible sur le pseudonyme ou sur le canal entier
Examples: /yeek someone ((cible?) un interlocuteur)
          /yeek * someone
 	  /yeek #channel  ((cible?) un canal)
 	  /yeek #channel someone"); ((cible?)à un interlocuteur sur le canal)
</screen>
</para>
</sect1>

<sect1 id="points-dinsertion">
<title>Points d'insertion</title>

<para>Depuis les scripts <literal>loaded</literal>, aussi bien que depuis <literal>.sircrc.pl</literal>, vous avez
la possibilité de définir des routines à appeler lorsque des événements particuliers
se produisent. C'est l'équivalent de ircII <literal>/on's</literal>.</para>

<para>Pour déclarer un point d'insertion, vous devez définir une sous-routine appelée
<literal>"hook&lowbar;somename"</literal> qui agit quoi que vous vouliez faire lorsqu'un point d'insertion
de type <literal>"hook&lowbar;type"</literal> est (déclenché), et ensuite appelle
<literal>&amp;addhook("hook&lowbar;type", "somename");</literal></para>

<para>Pour supprimer un point d'insertion, vous appelez <literal>&amp;remhook("hook&lowbar;type", "somename");</literal></para>

<para>Les points d'insertion numériques son également disponibles, pour chaque nombre à 3 caractères;
pour déclarer l'un d'eux, définissez une sous-routine appelée <literal>"hook&lowbar;somename"</literal> qui agit
comme vous le voulez, et appelez <literal>&amp;addhook("xxx", "somename")</literal>, où xxx est
le nombre représentant la réponse numérique. Pour supprimer l'un d'eux,
appelez <literal>&amp;remhook("xxx", "somename");</literal></para>

<para>Les sous-programmes appelés à partir des points d'insertion ont accès aux mêmes
fonctions et variables listées plus haut pour les fonctions, plus quelques-unes plus
spécifiques (partout où c'est applicable) :</para>

<para><screen>$who		est le pseudonyme qui a déclenché le point d'insertion
$user           est le nom d'utilisateur correspondant
$host		est le nom d'hote correspondant
</screen>
</para>

<para>Les points d'insertion peuvent également définir la variable <literal>$silent</literal> s'ils veulent
assurer l'affichage pour l'éventualité (à travers <literal>&amp;print</literal>)
et bloquer les valeurs par défaut. C'est l'équivalent direct de la connexion
<literal>"&circ;"</literal> sur ircII <literal>/on's</literal>, excepté <literal>"raw&lowbar;irc"</literal>.</para>

<para>Les points d'insertion marqués avec une <literal>*</literal> peuvent aussi définir la variable
spéciale <literal>$skip</literal> et la ligne sera ignorée par le client). Ceci est en général
une mauvaise idée, utilisez <literal>$silent</literal> autant que possible.  Seuls les points
d'insertion où ce procédé fournit une fonctionnalité supplémentaire réelle ont cette
possibilité. Pour <literal>"raw&lowbar;irc"</literal>  c'eest l'aquivalent de la connexion
<literal>"&circ;"</literal> sur ircII <literal>/on raw&lowbar;irc</literal>.</para>

<para>Les points d'insertion suivants sont disponibles, et sont appelés avec les arguments
suivants :</para>

<para><screen>action		activée par une action ctcp;
		le 1er argument est le pseudonyme ou le canal auquel il est envoyé
		le 2e argument est le message

commande      *	activée par l'utilisateur tapant une commande (sans tenir compte
                si c'est une /commande ou seulement une ligne de texte)
                le 1er argument est la ligne de l'utilisateur
                ce point d'insertion est spécial (comme "print" et "status"), en ce
                sens qu'il est clairement autorisé à modifier son argument ($_[0]) pour
                modifier toute commande pouvant être interprétée.
		la définition $skip=1 dans le point d'insertion obligera sirc à
                ignorer la commande

chat_disconnect activée lorqu'une discussion en ligne est perdue (mais non lorsque
                l'utilisateur la cloture lui-même avec DCC CLOSE CHAT)
                le 1er argument est le pseudonyme associé à la discussion en ligne

ctcp	     *	activée par tout ctcp, AVANT que le client n'effectue l'analyse
                et éventuellement réponde au ctcp.
		le 1er argument est le nom ou le canal auquel il a été émis
                le 2e argument est la commande ctcp
                les 3e arguments sont les arguments eux-mêmes

ctcp_reply	activée par les réponses ctcp;
                le 1er argument est le pseudonyme ou le canal sur lequel il a été émis
                le 2e argument est la commande ctcp
                les 3e arguments sont les arguments eux-mêmes

dcc_chat	activée par le texte reçu pendant une discussion en ligne dcc
		le 1er argument est le pseudonyme
		le 2e argument est le texte

dcc_disconnect  activée lorsqu'une lecture ou une émission dcc est terminée ou fermée
                (même lorsque l'utilisateur en cloture une avec DCC CLOSE GET/SEND)
                le 1er argument est le pseudonyme associé à la discussion en ligne
                le 2e argument est le nom de fichier
                le 3e argument est le nombre de bytes transférés
                le 4e argument est nombre de secondes nécessaires au transfert

dcc_request	activée par la réception d'une discussion en ligne ou d'une demande
                d'émission; Ceci est le point d'insertion à utiliser si vous voulez
                mettre en oeuvre toute discussion auto-dcc.
                le 1er argument est le type "(DISCUSSION" ou "EMISSION")
                le 2e argument est l'adresse de la machine (un nombre entier 32 bits)
                le 3e argument est le port
                pour une proposition DCC SEND (émission DCC) :
                  le 4e argument est le nom de fichier
                  le 5e argument est la longueur du fichier

disconnect      activée par la perte de la connexion au serveur, ou l'interruption
                avec /déconnexion (mais pas avec le serveur).
                il n'y a pas d'arguments

input	     *	activée chaque fois que le client veut demander à l'utilisateur une
                ligne par &amp;getuserline (c'est-à-dire lorsque vous avez été
                déconnecté, ou que vous avez besoin d'un nouveau pseudonyme,
                ou d'un script appelé &amp;getuserline).
                le 1er argument est l'"invite" longue
                le 2e argument est l'"invite" courte
                si le point d'insertion définit $skip, &amp;getuserline ne demandera
                ensuite rien à l'utilisateur, et le contenu de  $_ will  sera renvoyé

invite		activée par les invites;
                le 1er argument est le canal que vous avez invité

join		activée par les jonctions
                le 1er argument est le canal que joint $who (qui)

kick		activée par les ();
                le 1er argument est le pseudonyme ou la personne qui a été ()
                le 2e argument est le canal d'où ils ont été (virés)
                le 3e argument est le motif

leave		activée par les (partants);
                le 1er argument est le canal que $who abandonne

mode		activée par les changements de modes;
                le 1er argument est le canal ou l'utilisateur auquel s'applique le changement
                le 2e argument est le changement de mode lui-même

msg		activée par les messages;
		le 1er argument est le message

nick		activée par les changements de pseudonymes
                le 1er argument est le nouveau pseudonyme de $who (qui)

notice		activée par les remarques
                le 1er argument est le pseudonyme ou le canal sur lequel il a été émis
                le 2e argument est le message

server_notice	activée par les remarques depuis les serveurs
                le 1er argument est le pseudonyme ou le canal sur lequel il a été émis
                le 2e argument est le message

notify_signon	activée par une ouverture de session
		le 1er argument est le pseudonyme
                $user et $host (utilisateur et hote) ne sont *pas* définis
                de façon significative

notify_signoff	activée par une fermeture de session
                le 1er argument est le pseudonyme
                $user et $host ne sont *pas* définis de façon significative

print	     *	activée par l'édition d'une ligne quelconque à l'écran
                le 1er argument est la ligne à éditer
                ce point d'insertion est spécial (comme "état" et "commande"),
                en ce sens qu'il elle est clairement autorise à modifier
                son argument ($_[0]) pour changer la ligne à éditer
                la définitiion de $skip=1 dans le point d'insertion empêchera la ligne
                d'être réellement éditée

public		activée par les messages non-ctcp à un canal;
                le 1er argument est le canal
                le 2e argument est le message

raw_irc      *	activée par une ligne du serveur
	        $who    est l'initiateur (utilisateur ou serveur)
		$user   est sont nom d'utilisateur ('' s'il vient d'un serveur)
		$host   est son nom d'hote (même commentaire)
                le 1er argument est la commande
                les seconds arguments sont les arguments eux-mêmes

send_action	activée à l'émission  d'un /me ou d'un /de
		($who, $user et $host ne s'appliquent pas ici)
                le 1er argument est le pseudonyme/canal

send_ctcp	activée à l'émission d'un ctcp
                le 1er argument est le pseudonyme ou le canal sur lequel il a été émis
                le second argument est le texte complet ctcp (type et arguments)

send_dcc_chat	activée à l'émission du texte pendant une discussion en ligne dcc
                ($who, $user et $host ne s'appliquent pas ici)
                le 1er argument est le pseudonyme auquel nous émettons un message
                le second argument est le texte

send_text	activée à l'émission d'un /msg ou d'une communication sur un canal
		($who, $user et $host ne s'appliquent pas ici)
                le 1er argument est le pseudonyme/canal
                le second argument est le message

send_notice	activée à l'émission d'une remarque
           	($who, $user et $host ne s'appliquent pas ici)
                le 1er argument est le pseudonyme/canal
                le second argument est la remarque

signoff		activée lorsque quelqu'un ferme une session
                le 1er argument est le commentaire de sortie

status		activée lorsque sirc reconfigure la ligne d'état (comme
                résultat de l'appel à &amp;dostatus, soit de façon interne,
                soit par un script).
		le 1er argument est la ligne d'état proposée
                ce point d'insertion est spécial (comme "édition" et "commande")en ce sens
                qu'il est clairement autorisé à modifier son argument ($_[0]) pour changer
                ce qui devrait figurer sur la ligne d'état

topic		activée lorsque quelqu'un change de sujet
                le 1er argument est le canal
                le second argument est le nouveau sujet

&lt;3-digit nb&gt;  * activée par cette réponse numérique spéciale du serveur
                le 1er argument est tout ce que le serveur a émis après le nombre,et
                non analysé (qui signifie qu'il y a encore un caractère ":"
                devant le dernier argument
</screen>
</para>

<para>Exemple, qu'est ce qui pourrait être placé dans un fichier et
chargé directement, d'un point d'insertion qui joindra un
canal chaque fois que vous serez (viré?) :</para>

<para><screen># auto-rejoin hook (point d'insertion (auto-jonction?))

sub hook_kicked {
  local($kicked, $where_from, $reason)=@_;
  					# local vars with the args (variables locales avec les arguments)
  if (&amp;eq($kicked, $nick)) {		# if *we* got kicked (si *nous* sommes (virés?))
    &amp;sl("JOIN $where_from");		# send a JOIN to the server (envoie une jonction au serveur)
  }
}
&amp;addhook("kick", "kicked");	  	# activate the hook (active le point d'insertion)
</screen>
</para>

<para>Un autre exemple, pour afficher le nom d'utilisateur et le nom d'hote avec
chaque message (opération mieux réalisé avec /set printuh)</para>

<para><screen># userhost-on message (point d'insertion du message)

sub hook_uhmsg {
  &amp;tell("[\cb${who}!${user}\@${host}\cb] $_[0]");  # print everything  (édite tout)
  $silent=1;			# disable the default display (désactive la variable par défaut)
}
&amp;addhook("msg", "uhmsg");	  	# activate the hook  (active le point d'insertion)
</screen>
</para>
</sect1>

<sect1 id="variables-set">
<title>Variables SET</title>

<para>Un script peut accéder à des variables SET;
<itemizedlist>
<listitem>
<para>Pour les lire, vous n'avez besoin que de regarder <literal>$set&lcub;"VARIABLE"&rcub;</literal>,
où le nom des variables est écrit en capitales</para>
</listitem>
<listitem>
<para>Pour les définir, appelez <literal>&amp;doset("variable", "value");</literal> où  le nom
des variables peut être dans les deux cas (un cas ne signifie rien) et la valeur en
est controlée</para>
</listitem>
</itemizedlist>
</para>

<para>Un script peut aussi ajouter ses propres variables SET, fournissant
une valeur par défaut et un point d'insertion pour controler et définir une nouvelle
valeur. Pour ce faire, le script doit :
<itemizedlist>
<listitem>
<para>définir la variable à une valeur par défaut, avec <literal>$set&lcub;"VAR"&rcub;="whatever";</literal>
sirc ne laissera pas l'utilisateur définir une variable <literal>/set</literal> si aucune valeur
pour elle dans <literal>&percnt;set</literal> n'existe.
</para>
</listitem>
<listitem>
<para>définit un sous-programme <literal>set&lowbar;somename</literal>, et appelle
<literal>&amp;addset("var", "somename"); </literal>&amp;addset ("var", "somename");</para>
</listitem>
</itemizedlist>
</para>
<para>
Le nom des variables peut être omis dans les deux cas.
</para>

<para>Les sous-programmes qui servent de point d'insertion pour les variables SET sont appelés
avec la valeur proposée comme premier argument. Ils peuvent (on non) modifierr
la valeur réelle dans <literal>$set&lcub;"VAR"&rcub;</literal> à la valeur donnée à une autre. Par convention,
ils ne seront pas <literal>&amp;tell</literal>, et ignoreront les valeurs des arguments invalides</para>

<para>Ce qui se passe dans <literal>$set&lcub;"VAR"&rcub;</literal> doit être lisible de façon (humaine?); par
exemple, pour les les désactivations, il est suggéré que les valeurs dans
<literal>$set&lcub;"VAR"&rcub;</literal> seront "on","out" ou similaire, et que <literal>&amp;doset</literal>
peut définir une variable (à l'intérieur du script) à 0 ou 1, qui sera la seule réellement
controlée par le script.</para>
</sect1>

<sect1 id="demandes-de-lhte-utilisateur">
<title>Demandes de l'hote utilisateur</title>

<para>Quelquefois, dans une fonction vous avez besoin de savoir le nom complet
de l'utilisateur et de l'hote utilisateur pour chaque peudonyme. Si cela se
produit dans un point d'insertion, et que le point d'insertion est le seul
qui étatit actif, le pseudonyme est alors dans <literal>$who</literal> et les données
de l'hote utilisateur sont déjà dans <literal>$user</literal> et <literal>$host</literal>.</para>

<para>Cependant, vous devez appeler la fonction perl <literal>&amp;userhost</literal> donnant ici
trois arguments : le pseudonyme, ce que vous voulez voir évalué lorsque les données sont
disponibles si le peudinyme n'est pas trouvé sur IRC; si le troisième
argument est omis, sirc éditera le message par défaut
<literal>"*?* somenickname not found on IRC"</literal> (pas de psedonyme trouvé sur IRC).</para>

<para>Au contraire des versions antérieures de sirc, il est possible de faire plus
d'une demande d'hote urilisateur dans un délai court avant d'obtenir
les réponses du serveur.</para>

<para>Exemple : une fonction qui édite le code du pays d'un interlocuteur</para>

<para>p&gt;
<screen># country code (code du pays)

sub printcountry {		# prints $host's country code (édite le code du pays de l'hote)

  if ($host =&tilde; /\.([^.]+)$/) {  # match the last part of the host (correspond à la dernière partie de l'hote)
    local($c)=($1); 		# put it in local var $c  (placé dans une variable locale $c)
    $c="USA" if $c =&tilde; /^edu$/i;	# if it's a .edu, say it's USA (si c'est un .edu, il s'agit des USA)
    $c="USA (probably)" if $c =&tilde; /^com$/i || $c =&tilde; /^org$/i || $c =&tilde; /^net$/i;
				# if it's a .org, .com or .net, it's (si c'est un .org; .com ou .net, il s'agit
				# probably in the USA too             probablement des USA aussi)
    if ($c =&tilde; /^\d+$/) {	# if it's a number (si c'est un nombre)
      &amp;tell("*** out of luck, $who has an IP address :p"); (pas de chance, $who a une adresse IP :p")
				# complain, it's an IP (réclamation si c'est une adresse IP)
    } else {			# otherwise  (autrement)
      &amp;tell("*** $who is in $c");
				# announce the result  (annonce le résultat)
    }
  }
}

sub cmd_country {		# this is the command (voici la commande)

  &amp;getarg;			# get the argument in $newarg (obtient l'argument dans $nearg)
  if ($newarg) {		# if it's there  (s'il y est)
    &amp;userhost($newarg, "&amp;printcountry;");
				# request a userhost with &amp;printcountry as (demande à un hote
                                                                        utlisateur son code de pays)
				# action to take (action à faire)

  } else {			# otherwise (autrement)
    &amp;tell("*** Whose?");	# complain (réclamation)
  }
}

&amp;addcmd("country");		# install the command  (installe la commande)
</screen>
</para>
</sect1>

<sect1 id="timers">
<title>Timers</title>

<para>Il est possible dans sirc de spécifier une action à faire de manière différée,
un certain nombre de secondes plus tard, exactement comme avec la fonction de ircII
La précsion est de l'ordre de la seconde.</para>

<para>Pour ce faire, vous appelez la fonction <literal>&amp;timer</literal> avec le nombre de secondes
à attendre comme premier argument, et la chaîne de caractères à évaluer comme
second argument.</para>

<para>Un troisième argument peut être fourni, il doit être un nombre non-nul,
et sera utilisé comme nombre de référence pour cette minuterie. La définition
d'une minuterie lorsqu'un autre nombre de même référence existe, supprimera
la première minuterie. Si aucun nombre n'est spécifié, la minuterie ne peut
être supprimée.</para>

<para>Pour supprimer une minuterie avec un nombre de référence <literal>$n</literal>, appelez
<literal>&amp;deltimer($n);</literal></para>

<para>Ceci est assez simple, mais vous si avez réellement besoin d'un exemple, en voici un :
pour éditer "hello" dans 10 secondes  vous devez faire <literal>&amp;timer(10, "&amp;
tell('hello')");</literal></para>

<para>Si vous voulez pouvoir l'annuler, vous ferez <literal>&amp;timer(10, "&amp;tell('hello')", 6);</literal>
et ensuite pour l'annuler, vous ferez <literal>&amp; timer12, "('hello')");</literal>.  Il va sans dire que le '6' est arbitraire.
</para>
</sect1>

<sect1 id="ajout-des-gestionnaires-de-fichiers-la-princ">
<title>Ajout des gestionnaires de fichiers à la principale boucle sélectionnée ()</title>

<para>Comme sur la version 2.2, des scripts peuvent ajouter des gestionnaires de
fichiers à la boucle principale, et définir des points d'insertion dessus pour
obtenir un controle lorsque les données sont disponibles.</para>

<para>Il (est assigné( au script d'ouvrir d'abord le gestionnaire de fichiers, qui peut se
référer à une connexion réseau, un tty, un tube, comme dans <literal>open (FH, "program &verbar;")</literal>, etc.</para>

<para>Lors du traitement des supports de communication avec le réseau, il est
fortement recommandé d'utiliser l'API fourni par sirc <literal>&amp;connect, &amp;listen,
&amp;accept, &amp;resolve, &amp;newfh</literal> et <literal>$bindaddr</literal>)
plutot que d'utiliser les fonctions perl brutes. Ceci aura pour effet
de faire travailler ces scripts de façon transparente sur les proxies des
supports de communication, lorsque le module de communication est chargé. Si vous
avez besoin d'une fonctionnalité supplémentaire, bien que (comme le support de
communication UDP, ou admettant des connexions multiples depuis le support d'écoute),
vous puissiez utiliser les fonctions propres de perl.</para>

<para>Pour avoir de nouveau le controle lorsque les données sont disponibles sur un gestionnaire
de fichiers, vous pouvez l'ajouter à la définition de fh sirc <literal>select()s</literal> (from), avec

<literal>&amp;addsel($fh, "somename", flag);</literal> où sel&lowbar;name est le sous-programme
qui prendra le controle à nouveau lorsqu'il y aura un message à lire, et
l'indication 1 si vous voulez que sirc protége votre connexion et la
fractionne en lignes, et 0 si vous ne voulez pas du tout que sirc
touche à vos données..</para>

<para>La convention pour les sous-programmes <literal>sel&lowbar;somename</literal> est différente
dans les deux cas suivants :</para>

<para><itemizedlist>
<listitem>
<para>Pour les gestionnaires de fichiers protégés, il est autorisé un seul
argument contenant une ligne qui a été lue, incluant l'expression  finale
<literal>\n</literal>.  Si la  connexion est fermée ou interrompue, cet argument est
<literal>''</literal> et le gestionnaire de fichiers a déjà été fermé et supprimé de l'
ensemble de fh à <literal>select()</literal>.  Si vous la fermez vous-même,
vous devez utiliser <literal>&amp;remsel</literal> pour indiquer à sirc de la supprimer
de l'ensemble.</para>
</listitem>
<listitem>
<para>Pour les gestionnaires de fichiers non protégés, aucun argument n'est
autorisé; le point d'insertion est appelé lorsque <literal>select()</literal>
indique que la fonction fh est prête pour la lecture, et il est impératif
au point d'insertion de lire à partir de lui (en s'assurant de ne pas bloquer
le point d'insertion, sysread devrait donc être utilisé et non  &lt;&gt;),
et éventuellement le fermer et le supprimer avec <literal>&amp;remsel</literal>.
</para>

<para>Pour supprimer un gestionnaire de fichiers de l'ensemble de fh ()<literal>select()ed</literal>,
appelez <literal>&amp;remsel($fh);</literal>  où <literal>$fh</literal> est le gestionnaire
de fichiers.</para>

<para>Remarquez que sirc n'effectue jamais de controle pour vérifier que le gestionnaire
de fichiers donné est valide. Avoir un <literal>fh</literal> fermé ou invalide
dans le jeu des  <literal>select()able</literal>, ou ne pas réellement lire les donéées
sur un <literal>sel&lowbar;* hook</literal> non protégé, obligera sirc à monopoliser
l'unité centrale (CPU) en ne bloquant pas <literal>select()</literal>.</para>

<para>Pour un exemple d'utilisation intensive de tout ceci, voyez le script
ftp.pl qui met en application un client ftp à l'intérieur  de sirc
(vous pourrez le trouver sur la page internet de sirc à l'adresse
<ulink url="http://www.eleves.ens.fr:8080/home/espel/sirc/sirc.html">http://www.eleves.ens.fr:8080/home/espel/sirc/sirc.html</ulink>).</para>
</listitem>
</itemizedlist>
</para>
</sect1>

<sect1 id="robots">
<title>Robots(?)</title>

<para>Il est possible de créer des robots dans un script sirc, exactement
comme si vous le feriez dans ircII. Ce n'est sûrement pas
une mauvaise idée, puique vous avez à votre disposition
un langage de programmation (perl), débarrassé de toutes les tâches
de programmation réseau ennuyeuses et de l'analyse des problèmes de
réseau.</para>

<para>Toutefois, sirc n'a jamais été considéré comme un client robot,
et je n'ai pas l'intention de le remplir de cloches et de sifflements
pour les supports robots, j'ai donc fourni uniquement un support
minimum pour cela, avec les options -l et  -q.</para>

<para>L'idée est que vous programmez votre robot comme un ensemble de fonctions internes,
de points d'insertion et d'appels à <literal>&amp;addhook</literal> et à <literal>&amp;
docommand</literal>, et ensuite charger sirc de cette façon (évidemment sans ssfe) :</para>

<para><literal>nohup sirc -d -q -l &lt;botfile&gt; -i &lt;bot's ircname&gt; &lt;nick&gt; &lt;server&gt; &gt;/dev/null &amp;</literal></para>

<para>Tour ceci sans <literal>&lt;&gt;'s</literal>, bien sûr.
<literal>&gt;/dev/null</literal> supprime le résultat, puisque de toute façon
vous ne le lirez pas sur l'écran..</para>

<para>Dans le robot, assurez-vous de saisir (avec un point d'insertion numérique) les
lignes qui indiquent <literal>"nick in use"</literal> or <literal>"invalid nick"</literal>, (pseudonyme en cours)
(pseudonyme incorrect) et envoyez les lignes au serveur avec un pseudnyme aléatoire,
et omettez-les, sinon le robot s'arrêtera en tentant de demander un pseudonyme
à l'utilisateur. Vous définirez également un point d'insertion sur  <literal>"disconnect"</literal>,
et lui ferez faire un <literal>&amp;docommand("server 0")</literal> or <literal>"server some.server"</literal>.</para>

<para>Rappelez-vous aussi que le fichier est chargé avant même que
la connexion au serveur soit effectuée, les appels à
<literal>&amp;sl</literal> and most <literal>&amp;docommand's</literal> à ce moment échoueront..</para>

<para>Voici un exemple de robot qui effectue une connexion, joint un canal, refait
une nouvelle connexion s'il est déconnecté, répond à quelques commandes,
effectue ses opérations propres, et enregistre dans un fichier tout ce qu'il
voit sauf l'encombrement général (du réseau); vous devriez charger ce fichier, en supposant
que vous l'ayez sauvegardé dans un fichier appelé "mybot" (mon robot) et que
vous vouliez l'appeler BubbleBot, avec :</para>

<para><literal>nohup sirc -d -q -l mybot -i "bot in sirc" BubbleBot some.server.edu &gt;/dev/null</literal></para>

<para><screen>$botowner="espel\@clipper.ens.fr";	# change it to your address (le modifie à votre adresse)

$logfile=$ENV{'HOME'}."/.botlog";
&amp;docommand("log on");

sub hook_publicstuff {		# don't print the public chatter (so it       (n'édite pas la
                                                                   la discussion publique,( donc il

                       		# doesn't fill the logfile   (ne remplit pas le journal de bord)
}
&amp;addhook("public", "publicstuff");

sub hook_connected {
  &amp;sl("JOIN #BotTub");
}
&amp;addhook("376", "connected");   # join on the "end of MOTD" numeric (jonction à la "fin du
                                                                          MOTD" numérique)
srand;				# init random number generator (nombre générateur d'init aléatoire)

sub hook_badnick {
  local($n);
  $n="B".(int(rand(1000000))+4587454);  # send a garbage nick... (envoie un pseudonyme incorrect...)
  &amp;sl("NICK $n");
  $skip=1;
}
&amp;addhook("432", "badnick");             # if told that ours is taken (s'il est indiqué que le notre est pris)
&amp;addhook("433", "badnick");

sub hook_disc {         # if we got disconnectedj (si nous sommes déconnectés)
  sleep(30);		# wait 30 seconds (so we don't bring the machine (attendez 30 secondes (donc
                                                                 nous ne malmenons pas la machine si
			# down to a crawl if the server is down) le serveur est figé)
  &amp;docommand("server 1"); # reconnect to the same server (réeffectue une connexion au même serveur)
}
&amp;addhook("disconnect", "disc");

sub hook_joined {	# whenever someone joins (au cas où un interlocuteur ())
  local($ch)=($_[0]);
  $ch =&tilde; tr/A-Z/a-z/;	# put channel in lowercase (place le canal dans la case inférieure)
  if (&amp;eq($botowner, "$user\@$host") &amp;&amp; $haveops{$ch}) {
    &amp;sl("MODE $ch +o $who");	# op if that's the owner and we have ops (opération si c'est celle
  }                                                     du propriétaire et que nous avons des opérations)
}
&amp;addhook("join", "joined");

sub hook_message {
  if (&amp;eq($botowner, "$user\@$host")) {  # if it's a msg from the owner
    if ($_[0] =&tilde; /^die$/i) {             # die -&gt; die
      &amp;docommand("quit");
    } elsif ($_[0] =&tilde; /^say /i) {        # say &lt;something&gt; -&gt; say it
      &amp;say($');
    } elsif ($_[0] =&tilde; /^nick /i) {       # nick &lt;nick&gt; -&gt; change nicks
      &amp;sl("NICK $'");
    }
# add more commands here
  }
}
&amp;addhook("msg", "message");
</screen>
</para>
</sect1>
</chapter>
&documentation.index; 
</book>
<!--
Local Variables:
mode: sgml
sgml-omittag: nil
sgml-shorttag: t
sgml-general-insert-case: lower
End:
-->

