From a31b8a5babec9cb44ff8ba80a2187989b6b81f03 Mon Sep 17 00:00:00 2001 From: 8nlight <8nlight@disroot.org> Date: Wed, 16 Aug 2023 10:53:53 +0300 Subject: [PATCH] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=B2=20=C2=AB?= =?UTF-8?q?C=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- C/irc.c | 16 +++++++-- C/irc.h | 18 ++++++++-- C/main.c | 104 +++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 99 insertions(+), 39 deletions(-) diff --git a/C/irc.c b/C/irc.c index 9831f7f..2f88bc2 100644 --- a/C/irc.c +++ b/C/irc.c @@ -74,7 +74,7 @@ unsigned int IRCC_recv(IRCC_client *irc){ } else { - //puts(irc->raw); + puts(irc->raw); //Check end of motd if (strstr(irc->raw, "PRIVMSG ") == NULL && strstr(irc->raw, "MOTD")) @@ -91,6 +91,16 @@ unsigned int IRCC_recv(IRCC_client *irc){ return IRCC_NICK; } + else if (strstr(irc->raw, "TOPIC ")){ + IRCC_parse(strstr(irc->raw, "TOPIC "), irc); + return IRCC_TOPIC; + } + + else if (strstr(irc->raw, "MODE ")){ + IRCC_parse(strstr(irc->raw, "MODE "), irc); + return IRCC_MODE; + } + else if (strstr(irc->raw, "JOIN ")){ IRCC_parse(strstr(irc->raw, "JOIN "), irc); return IRCC_JOIN; @@ -123,8 +133,8 @@ void IRCC_send(IRCC_client *irc, char *msg, char *channel){ } unsigned int IRCC_init(IRCC_client *irc, size_t size){ - if (size <= 200){ - fprintf(stderr, "Low buffer size (IRCC_init)\n"); + if (size <= 250){ + fprintf(stderr, "Low buffer size (IRCC_init) (Min 250/512)\n"); return IRCC_ERROR; } diff --git a/C/irc.h b/C/irc.h index 969e9f8..5968aab 100644 --- a/C/irc.h +++ b/C/irc.h @@ -1,3 +1,13 @@ +/* + LICENSE: MIT + Simple libary for working with ipv4 irc servers + Dont support: + ssl + ddc + ipv6 + motd parsing +*/ + #ifndef IRC_LINUX #define IRC_LINUX @@ -9,14 +19,18 @@ #include #include #include +#define IRCC_MSG_MAX 512 + enum { - IRCC_CONNECTED = 1, - IRCC_NICK, + IRCC_NICK = 1, IRCC_PRIVMSG, IRCC_JOIN, IRCC_PART, IRCC_PING, + IRCC_TOPIC, + IRCC_MODE, + IRCC_CONNECTED, IRCC_DISCONNECTED, IRCC_ERROR, IRCC_SUCCESS diff --git a/C/main.c b/C/main.c index 2c695e4..ac4cda1 100644 --- a/C/main.c +++ b/C/main.c @@ -1,51 +1,87 @@ #include "irc.h" -#define IF_NULL(client) (client.msg != NULL || client.nick != NULL || client.channel != NULL) +//Config +#define HOST "irc.server.net" +#define PORT 6667 +#define NICK "tester" +char *channels[] = {"#test"}; + +#define CHECK_NULL() (client.nick != NULL && client.channel != NULL && client.msg != NULL) IRCC_client client; -void die(char *msg){ +void die(char *msg) { puts(msg); IRCC_close(&client); exit(1); } -int main(void){ - IRCC_init(&client, 250); - int status = IRCC_connect(&client, "irc.libera.chat", 6667); +void recvinfo(int ignore) { + while (1) { + unsigned int irc_status = IRCC_recv(&client); + if (irc_status == IRCC_DISCONNECTED) { + if (!ignore) + die("Disconnected"); + return; + } + + else if (strstr(client.raw, "No Ident") || irc_status == IRCC_CONNECTED) + return; + + //Print + if (!CHECK_NULL()) + return; + + if (irc_status == IRCC_PRIVMSG) + printf("[%s %s] %s\n", client.channel, client.nick, client.msg); + + else if (irc_status == IRCC_NICK) + printf("[N] %s is know as %s\n", client.nick, client.msg); + + else if (irc_status == IRCC_TOPIC) + printf("[T] %s\n", client.msg); + + else if (irc_status == IRCC_JOIN) + printf("[>] %s\n", client.nick); + + else if (irc_status == IRCC_PART) + printf("[<] %s\n", client.nick); + } +} + +int main(void) { + + //512 - size of raw buffer (max irc) + IRCC_init(&client, IRCC_MSG_MAX); + int status = IRCC_connect(&client, HOST, PORT); if (status == IRCC_ERROR) die("Conn refused"); - IRCC_register(&client, "bot"); + //Socket timeout + struct timeval tv = {5, 5}; + if (setsockopt(client.socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) + die("setsockopt"); + + //Register + recvinfo(1); + IRCC_register(&client, NICK); + + //Recv motd and join in channel + recvinfo(0); sleep(5); - send(client.socket, "JOIN #channel\r\n", strlen("JOIN #channel\r\n"), 0); + for (size_t i = 0; i < sizeof(channels) / sizeof(char *); i++) { + if (channels[i] == NULL) + break; - while (1){ - unsigned int irc_status = IRCC_recv(&client); - if (irc_status == IRCC_DISCONNECTED) - die("Disconnected"); + size_t join_size = strlen("JOIN \r\n") + strlen(channels[i]) + 1; + char *tmp = malloc(join_size); + if (tmp == NULL) + die("malloc retured NULL"); - if (IF_NULL(client)) { - client.msg++; - switch (irc_status) { - case IRCC_PRIVMSG: - printf("%s %s %s\n", client.channel, client.nick, client.msg); - break; - - case IRCC_NICK: - printf("%s is know as %s", client.nick, client.msg); - break; - - case IRCC_JOIN: - printf("< %s\n", client.nick); - break; - - case IRCC_PART: - printf("> %s\n", client.nick); - break; - - default: - break; - } - } + snprintf(tmp, join_size, "JOIN %s\r\n", channels[i]); + send(client.socket, tmp, join_size, 0); + free(tmp); } + + recvinfo(0); } +