Da ich keine passende Library gefunden haben, für das was ich vorhatte, habe ich selber eine entworfen. Falls andere auch etwas ähnliches benötigen veröffentliche ich sie hier unter BEER-WARE LICENSE.
Funktionen:
- Mit Server verbinden
- Auf Ping antworten
- Empfangene Zeilen an Callback-Funktion übergeben
- Channel joinen
- Channel verlassen
- Texte/Befehle senden
irclib.h
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <l3akage@martinpoppen.de> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return Martin Poppen
* ----------------------------------------------------------------------------
*/
#ifndef IRCLIB_H
#define IRCLIB_H
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#define DELAY 1
#define RETRIES 3
#define MAXSENDBUFFER 1024
#define MAXRECVBUFFER 1024
// define for some output
#undef DEBUG
void do_send(int socket, char *cmd, ...);
int do_connect(char *host, char *port, char *nick, char *user, char *channel);
int do_recv(int conn, void (*writeData)(char* data));
void do_join(int conn, char* channel);
void do_part(int conn, char* channel);
#endif
irclib.c
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <l3akage@martinpoppen.de> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return Martin Poppen
* ----------------------------------------------------------------------------
*/
#include "irclib.h"
// send some stuff
// format like printf
// needs socket
void do_send(int socket, char *cmd, ...) {
char sbuf[MAXSENDBUFFER];
va_list ap;
va_start(ap, cmd);
vsnprintf(sbuf, MAXSENDBUFFER, cmd, ap);
va_end(ap);
#ifdef DEBUG
printf("SEND: %s\n", sbuf);
#endif
// send it
write(socket, sbuf, strlen(sbuf));
}
// connect to server
// needs:
// host irc.test.de
// port 6667
// nick botibot
// user botibot
// channel #test
int do_connect(char *host, char *port, char *nick, char *user, char *channel) {
int conn;
int retries = RETRIES;
struct addrinfo hints;
struct addrinfo *res;
memset(&hints, 0, sizeof hints);
do {
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if(getaddrinfo(host, port, &hints, &res)) {
sleep(DELAY);
continue;
}
if((conn = socket(res->ai_family, res->ai_socktype, res->ai_protocol))<0) {
sleep(DELAY);
continue;
}
if((connect(conn, res->ai_addr, res->ai_addrlen))<0) {
sleep(DELAY);
continue;
}
break;
} while (retries-->0);
// if connected register with user and nick
if(retries>0) {
do_send(conn, "USER %s 0 0 :%s\r\n", user, user);
do_send(conn, "NICK %s\r\n", nick);
do_join(conn,channel);
return conn;
}else{
return -1;
}
}
// receive data
// answer on pint
// send every line to callback function
int do_recv(int conn, void (*writeData)(char* data)) {
char rbuf[MAXRECVBUFFER];
char *tmpbuf = malloc(sizeof(char));
tmpbuf[0] = '\0';
char line[MAXRECVBUFFER+1];
int answerlen, i;
int linelen;
// reads date until error
while((answerlen = recv(conn, rbuf, MAXRECVBUFFER, 0))) {
linelen = -1;
rbuf[answerlen] = '\0';
#ifdef DEBUG
printf("RECV: %s\n",rbuf);
#endif
tmpbuf = realloc(tmpbuf, strlen(rbuf)+strlen(tmpbuf)+1);
strcat(tmpbuf, rbuf);
for(i=0;i<strlen(tmpbuf); i++) {
linelen++;
line[linelen] = tmpbuf[i];
// line should end with \r\n
if(i>0 && tmpbuf[i-1] == '\r' && tmpbuf[i] == '\n') {
line[linelen-1] = '\0';
// Ping? Pong!
if(!strncmp(rbuf, "PING", 4)) {
rbuf[1] = 'O';
do_send(conn, rbuf);
} else {
writeData(line);
}
linelen = -1;
}
}
line[linelen+1] = '\0';
tmpbuf = realloc(tmpbuf, strlen(line)+1);
// write incomplete lines to buffer
memcpy(tmpbuf, line, strlen(line)+1);
rbuf[0]='\0';
line[0]='\0';
}
return -1;
}
// join channel
void do_join(int conn, char* channel) {
do_send(conn, "JOIN :%s\r\n", channel);
}
// leave channel
void do_part(int conn, char* channel) {
do_send(conn, "PART :%s\r\n", channel);
}
Ein Beispiel – example.c
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <l3akage@martinpoppen.de> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return Martin Poppen
* ----------------------------------------------------------------------------
*/
#include "irclib.h"
#include <stdio.h>
void printData(char *data) {
printf("Line: %s\n",data);
}
int main(void ){
int reconnects = 3;
do{
int connection = do_connect("irc.test.de", "6667", "botibot", "botibot", "#test");
do_recv(connection, printData);
}while(reconnects-->0);
return 0;
}
Fragen, Verbesserungen, Kritik .. sind natürlich gerne gesehen und erwünscht.