Vous n'êtes pas identifié(e).

Top posteurs

Statistiques

Partenaires

  • eXolia Hosting
  • Eggdrop.fr

#1 08/11/2011 23:26:31

TiSmA
Administrateur
Lieu : Saint Martin (87)
Inscription : 18/08/2004
Messages : 43
Site Web

[C] Construire un bot IRC

Bonsoir,

Voici un petit snippet qui a pour but de vous montrez le système de connexion d'un bot IRC en language C :

Nom du fichier : main.c
Modification code : adresse-du-serveur / port-du-serveur

Code: C
/***************************************
*       IRCBOT
*           Nic0
****************************************/
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
 
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
 
#define PORT port-du-serveur
#define HOST "adresse-du-serveur"
 
#define ERROR fprintf (stderr, \
        "%s:%d Error (%d) : %s\n", \
        __FILE__, __LINE__, \
        errno, strerror(errno))
 
int initSocket (int *sock, struct sockaddr_in *sockname, struct hostent *host_address);
int initSocketConnect (int *sock);
int socketAction (int *sock, char *buffer);
int pong (int *sock, char *buffer);
 
int main (void)
{  
    struct sockaddr_in sockname;
    struct hostent *host_address;
    int sock = 0;
 
    if ((initSocket (&sock, &sockname, host_address)) == 1)
        return EXIT_FAILURE;
 
    if (initSocketConnect (&sock) == 1)
    {
        close (sock);
        return EXIT_FAILURE;
    }
 
    while(1)
    {
        char buffer [2048] = {0};
        if ((recv(sock, buffer, sizeof(buffer) - 1, 0)) == -1)
        {
            ERROR;
            close (sock);
            return EXIT_FAILURE;
        }
        printf("%s", buffer);
 
        if ((socketAction (&sock, buffer)) == 1)
            ERROR;
    }
 
 
    return EXIT_SUCCESS;
}
/*  Fonction permettant de créer la socket et de la connecter au serveur IRC.
 */
int initSocket (int *sock, struct sockaddr_in *sockname, struct hostent *host_address)
{
/*  Obtention de l'adresse de la machine distante à partir de l'host.
 */
    if ((host_address = gethostbyname (HOST)) == NULL)
    {
        ERROR;
        return 1;
    }
 
/*  Création d'une socket.
 */
    if ((*sock = socket (PF_INET, SOCK_STREAM, 0)) == -1)
    {
        ERROR;
        return 1;
    }
 
/*  Connexion de la socket au server distant
 */
    sockname->sin_family = host_address ->h_addrtype;
    sockname->sin_port = htons (PORT);
    memcpy ((char *) &(sockname->sin_addr.s_addr), host_address->h_addr, host_address->h_length);
 
    if ((connect (*sock, (struct sockaddr *) sockname, sizeof (struct sockaddr_in))) == -1)
    {
        ERROR;
        return 1;
    }
    return 0;
}
 
/*  Fonction permettant d'envoyer les paramètres de bases pour rejoindre un salon, avec
 *  le choix du pseudo et identifiant
 */
int initSocketConnect (int *sock)
{
 
    char *nick = "NICK IRCBot\r\n";
    char *user = "USER IRCBot \"localhost\" \"irc_server\" :IRCBot\r\n";
    char *join = "JOIN #IRCBot,#linux\r\n";
 
    if ((send(*sock, nick, strlen(nick), 0)) == -1)
    {
        ERROR;
        return 1;
    }
 
    if ((send(*sock, user, strlen(user), 0)) == -1)
    {
        ERROR;
        return 1;
    }
 
    if ((send(*sock, join, strlen(join), 0)) == -1)
    {
        ERROR;
        return 1;
    }
    return 0;
}
/*  Fonction envoyant la réponse au ping
 */
int pong (int *sock, char *buffer)
{
    buffer[1] = 'O';
    if ((send(*sock, buffer, strlen(buffer), 0)) == -1)
    {
        ERROR;
        return 1;
    }
    return 0;
}
/*  Fonction traitant le buffer pour savoir quel action on doit lui associer.
 *  Ici, seul la réponse au Ping est traiter, et le cas de fermeture de la socket
 *  par le serveur distant.
 *  Pour rajouter des fonctionnalité au bot,
 *  c'est ici qu'il est le plus simple de le faire.
 */
int socketAction (int *sock, char *buffer)
{
    if (strstr(buffer, "PING :") != NULL && buffer[0] == 'P')
    {
        if ((pong(sock, buffer)) ==1)
        {
            close(*sock);
            return 1;
        }
    }
 
    if (strstr(buffer, "ERROR :Closing Link:") != NULL && buffer[0] == 'E')
    {
        close (*sock);
        return 1;
    }
    return 0;
}

Compilation du fichier :

gcc main.c -o bot

Démarrage du bot :

./bot

Vous pouvez retrouver une version améliorée du snippet avec fichier de configuration directement sur le site de l'auteur : http://www.nicosphere.net/socket-en-lan … tion-1744/

Une version plus complète est également fournie en archive : http://src.nicosphere.net/cbot.tar.bz2


Inutile d'avoir un Tigre dans son ordi, s'il y'a un âne derrière l'écran...  big_smile

Hors ligne

#2 08/11/2011 23:47:35

hardtek
Nouveau IRCzien
Lieu : 127.0.0.1
Inscription : 18/06/2011
Messages : 12

Re : [C] Construire un bot IRC

ça fonctionne... Parcontre quand ont quitte Putty le bot se déconnecte ?

[EDIT :] "Voici un petit snippet qui a pour but de vous montrez le système de connexion d'un bot IRC "

OK! Donc à la base ce code sert à montrer le systéme de connection aprés faut le moduler...

Dernière modification par hardtek (09/11/2011 00:25:17)


ton meilleur ami est ton pire ennemi

Hors ligne

#3 08/11/2011 23:57:28

TiSmA
Administrateur
Lieu : Saint Martin (87)
Inscription : 18/08/2004
Messages : 43
Site Web

Re : [C] Construire un bot IRC

Bonjour,

La gestion du processus n'est pas prise en compte dans cette version. Tu peux utiliser SCREEN pour démarrer ton robot ou directement avec & :

Démarrage

screen -dmS ircbot /chemin/de/ton/fichier/bot

Arret

screen -dr ircbot -X quit
./bot & >/dev/null 2>&1

@+


Inutile d'avoir un Tigre dans son ordi, s'il y'a un âne derrière l'écran...  big_smile

Hors ligne

#4 09/11/2011 01:23:26

Harakiri
Administrateur
Lieu : Paris
Inscription : 02/07/2011
Messages : 260

Re : [C] Construire un bot IRC

Salut,

Le problème avec la mise en background du processus (avec l'utilisation du &), c'est que si affichage il y a, lorsque le terminal (ou PuTTy) sera fermé, le programme plantera, faute d'endroit où faire l'affichage. Il est donc préférable de rediriger les flux de sorties vers /dev/null ( >/dev/null 2>&1 ) ou vers un fichier de log.
Mais si on veut un debug sur la sortie standard sans faire toutes ces redirections bizarres (:D), mieux vaut utiliser screen (ou tmux), à mon avis.

P.S: Dommage que cet exemple de bot ne gère pas les statuts des file descriptor (select ou epoll par exemple), parce que là j'imagine que même threadé, il doit prendre pas mal de CPU ce bot à lire en boucle comme ca !


EOF

Hors ligne

#5 09/11/2011 09:49:11

TiSmA
Administrateur
Lieu : Saint Martin (87)
Inscription : 18/08/2004
Messages : 43
Site Web

Re : [C] Construire un bot IRC

Lut,

Les deux autres versions disponible à la fin de la discussion ont été nettement améliorées avec l'ajout d'un fichier de configuration, la gestion des logs de la socket dans un fichier ainsi que l'optimisation du code.

/dev/null corrigé smile

@+


Inutile d'avoir un Tigre dans son ordi, s'il y'a un âne derrière l'écran...  big_smile

Hors ligne

#6 09/11/2011 20:25:24

Nic0
IRCzien en herbe
Inscription : 09/11/2011
Messages : 83
Site Web

Re : [C] Construire un bot IRC

Salut,

Ça fait drôle de voir ressurgir un vieux code comme ça, surtout par TiSmA.

Pour répondre aux remarques, ce code suit effectivement une implémentation naïve, mais je pense que c'est un bon choix d'exemple, ceux intéressé par ce genre de topic cherche généralement un point de départ facile à reprendre en main, et c'est un peu à quoi répond ce snippet. Il me semble que la deuxième version gérait l'IO du réseau par un thread, mais je n'ose à peine regarder, risquant de me faire peur tongue
De mémoire, la charge CPU n'est pas très importante, malgré la boucle, car elle est justement régulé par l'IO, mais ce n'est effectivement pas l'idéal.

HS: Bon retour à ircz, ça fait drôle, bonne continuation.


Linux and programming blog

Hors ligne

Pied de page des forums

475356 visites ( 183 aujourd'hui ) 5 visiteurs en ligne
Copyright © 2004 - 2013 IRCz