From 718f290ba4bc9045ad05dfaaa8018adc13f7b131 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 23 Jun 2025 21:19:00 +0000 Subject: [PATCH] fixed --- C/irc.c | 99 +++++++++++++++++++++++++++++++++++++++----------------- C/irc.h | 40 ++++++++++++++--------- C/main.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 46 deletions(-) create mode 100644 C/main.c diff --git a/C/irc.c b/C/irc.c index 76472ab..271184d 100644 --- a/C/irc.c +++ b/C/irc.c @@ -9,25 +9,27 @@ #include #include "irc.h" -int IRCC_urecv(IRCC_client *irc) { +int IRCC_urecv(IRCC_client *irc, char **buf, const size_t size) { #if defined(ENABLE_SSL) || defined(ENABLE_TLS) if (irc->irc_usingssl) - return SSL_read(irc->irc_ssl, irc->irc_raw, sizeof(irc->irc_raw)); + return SSL_read(irc->irc_ssl, *buf, size); #endif - return recv(irc->irc_socket, irc->irc_raw, sizeof(irc->irc_raw), 0); + return recv(irc->irc_socket, *buf, size, 0); } -int IRCC_usend(IRCC_client *irc, const char *msg, const size_t bytes) { +int IRCC_usend(IRCC_client *irc, const char *msg, const size_t size) { #if defined(ENABLE_SSL) || defined(ENABLE_TLS) if (irc->irc_usingssl) - return SSL_write(irc->irc_ssl, msg, bytes); + return SSL_write(irc->irc_ssl, msg, size); #endif - return send(irc->irc_socket, msg, bytes, 0); + return send(irc->irc_socket, msg, size, 0); } int IRCC_connect(IRCC_client *irc, const char *ip, const int port) { + memset(irc, 0, sizeof(IRCC_client)); + struct hostent *hp = gethostbyname(ip); if (!hp) return IRCC_ERROR; @@ -50,7 +52,7 @@ int IRCC_connect(IRCC_client *irc, const char *ip, const int port) { } int status = connect(irc->irc_socket, (struct sockaddr *)&client_str, sizeof(client_str)); - if (status == -1) { + if (status < 0) { close(irc->irc_socket); return IRCC_ERROR; } @@ -60,8 +62,6 @@ int IRCC_connect(IRCC_client *irc, const char *ip, const int port) { } void IRCC_parse_msg(char *tmp, IRCC_client *irc) { - irc->irc_raw[strcspn(irc->irc_raw, "\r\n")] = '\0'; - if (tmp != NULL) { /* Message */ char *val = strchr(tmp, ':'); @@ -79,7 +79,7 @@ void IRCC_parse_msg(char *tmp, IRCC_client *irc) { val[0] = '\0'; irc->irc_channel = val + 1; } - + /* Nickname */ val = strchr(irc->irc_raw, '!'); if (val != NULL) { @@ -90,19 +90,43 @@ void IRCC_parse_msg(char *tmp, IRCC_client *irc) { } int IRCC_recv(IRCC_client *irc) { - memset(irc->irc_raw, '\0', IRCC_MSG_MAX); + if (irc->irc_raw && irc->irc_alloc) + free(irc->irc_raw); - int msg_size = IRCC_urecv(irc); - if (msg_size <= 0) - return IRCC_DISCONNECTED; + irc->irc_raw = NULL; - char *ptr; - if ((ptr = strstr(irc->irc_raw, "PING :")) != NULL) { - *(strchr(ptr, 'I')) = 'O'; - if (IRCC_usend(irc, ptr, strlen(irc->irc_raw)) < 0) - return IRCC_ERROR; + size_t size = 0; + char *buf = malloc(1); + if (buf == NULL) + return IRCC_ALLOC; + + /* Read message chunk */ + char flag = 0; + while (1) { + size++; + char *bckp = realloc(buf, size + 1); + if (bckp == NULL) { + free(buf); + return IRCC_ALLOC; + } + buf = bckp; + + char *ptr = buf + size - 1; + int msg_size = IRCC_urecv(irc, &ptr, 1); + if (msg_size <= 0) { + free(buf); + return IRCC_DISCONNECTED; + } + + *(ptr + 1) = '\0'; + if (flag) + break; + + if (*ptr == '\r') + flag = 1; } + irc->irc_raw = buf; return IRCC_SUCCESS; } @@ -111,6 +135,15 @@ int IRCC_parse(IRCC_client *irc) { irc->irc_msg = NULL; irc->irc_nick = NULL; + char *ptr; + if ((ptr = strstr(irc->irc_raw, "PING :")) != NULL) { + *(strchr(ptr, 'I')) = 'O'; + if (IRCC_usend(irc, ptr, strlen(irc->irc_raw)) == -1) + return IRCC_ERROR; + + return IRCC_PING; + } + /* Check end of motd */ if (strstr(irc->irc_raw, "PRIVMSG ") == NULL && strstr(irc->irc_raw, "MOTD")) return IRCC_CONNECTED; @@ -150,28 +183,32 @@ int IRCC_parse(IRCC_client *irc) { } int IRCC_register(IRCC_client *irc, const char *nickname) { - size_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "NICK %s\r\n", nickname); - if (IRCC_usend(irc, irc->irc_raw, bytes) < 0) + char buf[512]; + + int bytes = snprintf(buf, sizeof(buf) - 1, "NICK %s\r\n", nickname); + if (IRCC_usend(irc, buf, bytes) < 0) return IRCC_ERROR; - bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "USER %s 0 localhost :%s\r\n", nickname, nickname); - if (IRCC_usend(irc, irc->irc_raw, bytes) < 0) + bytes = snprintf(buf, sizeof(buf) - 1, "USER %s 0 localhost :%s\r\n", nickname, nickname); + if (IRCC_usend(irc, buf, bytes) < 0) return IRCC_ERROR; return IRCC_SUCCESS; } int IRCC_join(IRCC_client *irc, const char *channel, const char *key) { - size_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "JOIN %s %s\r\n", channel, (key) ? key : ""); - if (IRCC_usend(irc, irc->irc_raw, bytes) < 0) + char buf[512]; + ssize_t bytes = snprintf(buf, sizeof(buf) - 1, "JOIN %s %s\r\n", channel, (key) ? key : ""); + if (IRCC_usend(irc, buf, bytes) < 0) return IRCC_ERROR; return IRCC_SUCCESS; } int IRCC_send(IRCC_client *irc, const char *channel, const char *msg) { - size_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "PRIVMSG %s :%s\r\n", channel, msg); - if (IRCC_usend(irc, irc->irc_raw, bytes) < 0) + char buf[512]; + ssize_t bytes = snprintf(buf, sizeof(buf) - 1, "PRIVMSG %s :%s\r\n", channel, msg); + if (IRCC_usend(irc, buf, bytes) < 0) return IRCC_ERROR; return IRCC_SUCCESS; @@ -212,10 +249,12 @@ int IRCC_initssl(IRCC_client *irc) { } void IRCC_close(IRCC_client *irc) { - if (!irc->irc_alloc) - return; + if (irc->irc_alloc) + free(irc->irc_raw); + + if (irc->irc_connected) + close(irc->irc_socket); - close(irc->irc_socket); irc->irc_msg = irc->irc_nick = irc->irc_channel = NULL; #if defined(ENABLE_SSL) || defined(ENABLE_TLS) diff --git a/C/irc.h b/C/irc.h index 174e0d7..04a6096 100644 --- a/C/irc.h +++ b/C/irc.h @@ -10,42 +10,50 @@ #ifndef _IRCC_H #define _IRCC_H -#define IRCC_MSG_MAX 512 #define IRCC_PING_TIMEOUT 600 -#define IRCC_VERSION "2.0.2" +#define IRCC_VERSION "2.1.0b" #if defined(ENABLE_SSL) || defined(ENABLE_TLS) #include #endif enum { - IRCC_NICK = 1, + IRCC_ALLOC = -3, + IRCC_DISCONNECTED, + IRCC_ERROR, + + IRCC_CONNECTED, + IRCC_SUCCESS, + + IRCC_NICK, IRCC_PRIVMSG, IRCC_JOIN, IRCC_QUIT, IRCC_PING, IRCC_TOPIC, - IRCC_MODE, - - IRCC_CONNECTED, - IRCC_DISCONNECTED, - IRCC_ERROR, - IRCC_SUCCESS + IRCC_MODE }; +static const char *IRCC_ERROR_MSGS[] = { + "IRCC_ALLOC", + "IRCC_DISCONNECTED", + "IRCC_ERROR", +}; + +#define IRCC_GET_ERROR(n) (IRCC_ERROR_MSGS[n + 3]) + typedef struct { - /* RW */ + int irc_connected; int irc_socket; - char irc_raw[IRCC_MSG_MAX + 1]; + int irc_alloc; + char *irc_raw; /* RONLY */ char *irc_msg; char *irc_channel; char *irc_nick; - int irc_alloc; - #if defined(ENABLE_SSL) || defined(ENABLE_TLS) /* RONLY */ int irc_usingssl; @@ -60,14 +68,14 @@ typedef struct { int IRCC_connect(IRCC_client *irc, const char *ip, const int port); int IRCC_recv(IRCC_client *irc); int IRCC_parse(IRCC_client *irc); +int IRCC_register(IRCC_client *irc, const char *nickname); int IRCC_join(IRCC_client *irc, const char *channel, const char *key); int IRCC_send(IRCC_client *irc, const char *channel, const char *msg); -int IRCC_register(IRCC_client *irc, const char *nickname); int IRCC_initssl(IRCC_client *irc); void IRCC_close(IRCC_client *irc); /* Raw data operations. Uses tls when possible */ -int IRCC_usend(IRCC_client *irc, const char *msg, const int bytes); -int IRCC_urecv(IRCC_client *irc); +int IRCC_usend(IRCC_client *irc, const char *msg, const size_t size); +int IRCC_urecv(IRCC_client *irc, char **buf, const size_t size); #endif diff --git a/C/main.c b/C/main.c new file mode 100644 index 0000000..aed6668 --- /dev/null +++ b/C/main.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include "irc.h" + +/* Config */ +#define HOST "irc.rizon.net" +#define PORT 6667 +#define NICK "tester134" +char *channels[] = {"#testo"}; + +#define CHECK_NULL() (client.irc_nick != NULL && client.irc_channel != NULL && client.irc_msg != NULL) +IRCC_client client; + +void die(const char *msg) { + perror(msg); + IRCC_close(&client); + exit(1); +} + +void handler(int sig) { + (void)sig; + + IRCC_close(&client); + exit(0); +} + +void recvinfo(void) { + while (1) { + int irc_status = IRCC_recv(&client); + if (irc_status < 0) + die("Disconnected"); + + irc_status = IRCC_parse(&client); + + /* Print */ + if (CHECK_NULL() && irc_status == IRCC_PRIVMSG) + printf("%s %s\n", client.irc_nick, client.irc_msg); + + else if (client.irc_nick != NULL && client.irc_msg != NULL && irc_status == IRCC_NICK) + printf("[N] %s is know as %s\n", client.irc_nick, client.irc_msg); + + else if (CHECK_NULL() && irc_status == IRCC_TOPIC) + printf("[T] %s\n", client.irc_msg); + + else if (client.irc_nick != NULL && irc_status == IRCC_JOIN) + printf("[>] %s\n", client.irc_nick); + + else if (client.irc_nick != NULL && irc_status == IRCC_QUIT) + printf("[<] %s\n", client.irc_nick); + + else + printf("> %s\n", client.irc_raw); + } +} + +int main(void) { + signal(SIGINT, handler); + + int status = IRCC_connect(&client, HOST, PORT); + if (status == IRCC_ERROR) + die("Conn refused"); + + if (IRCC_initssl(&client) == IRCC_ERROR) { + IRCC_close(&client); + die("ssl error"); + } + + /* Register and skip motd */ + IRCC_register(&client, NICK); + + sleep(5); + for (size_t i = 0; i < sizeof(channels) / sizeof(char *); i++) { + if (channels[i] == NULL) + break; + + IRCC_join(&client, channels[i], NULL); + } + + recvinfo(); +}