#include "irc.h" unsigned int IRCC_connect(IRCC_client *irc, const char *ip, const unsigned int port){ struct hostent *ghbn = gethostbyname(ip); if (!ghbn) return IRCC_ERROR; //Only ipv4 struct sockaddr_in client_str; memset(&client_str, 0, sizeof(client_str)); client_str.sin_family = AF_INET; client_str.sin_port = htons(port); client_str.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)ghbn->h_addr)); irc->socket = socket(AF_INET, SOCK_STREAM, 0); if (irc->socket < 0) return IRCC_ERROR; int status = connect(irc->socket, (struct sockaddr *)&client_str, sizeof(client_str)); if (status == -1) return IRCC_ERROR; return IRCC_SUCCESS; } unsigned int IRCC_register(IRCC_client *irc, const char *nickname){ size_t size = strlen("NICK %s\r\nUSER %s 0 localhost :%s \r\n") + (strlen(nickname) * 3); char *tmp = (char *)malloc(size); if (tmp == NULL){ fprintf(stderr, "malloc returned NULL (IRCC_register)\n"); exit(1); } sleep(2); snprintf(tmp, size, "NICK %s\r\nUSER %s 0 localhost :%s\r\n", nickname, nickname, nickname); send(irc->socket, tmp, strlen(tmp), 0); free(tmp); return IRCC_SUCCESS; } void IRCC_parse(char *tmp, IRCC_client *irc){ irc->raw[strcspn(irc->raw, "\r\n")] = '\0'; if (tmp != NULL){ //Message if (strstr(tmp, ":") != NULL) irc->msg = strstr(tmp, ":"); //Channel if (strstr(tmp, " ") != NULL){ irc->channel = strstr(tmp, " ") + 1; irc->channel[strcspn(irc->channel, ":") - 1] = '\0'; } //Nickname irc->raw[strcspn(irc->raw, "!")] = '\0'; irc->nick = irc->raw + 1; } } unsigned int IRCC_recv(IRCC_client *irc){ memset(irc->raw, '\0', irc->size); irc->channel = NULL; irc->msg = NULL; irc->nick = NULL; int msg_size = recv(irc->socket, irc->raw, irc->size, 0); if (msg_size == 0 || msg_size == -1) return IRCC_DISCONNECTED; else if (!strncmp(irc->raw, "PING", 4)){ *(strchr(irc->raw, 'I')) = 'O'; send(irc->socket, irc->raw, strlen(irc->raw), 0); return IRCC_PING; } else { //puts(irc->raw); //Check end of motd if (strstr(irc->raw, "PRIVMSG ") == NULL && strstr(irc->raw, "MOTD")) return IRCC_CONNECTED; //Other else if (strstr(irc->raw, "PRIVMSG ")){ IRCC_parse(strstr(irc->raw, "PRIVMSG "), irc); return IRCC_PRIVMSG; } else if (strstr(irc->raw, "NICK ")){ IRCC_parse(strstr(irc->raw, "NICK "), 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; } else if (strstr(irc->raw, "PART ") || strstr(irc->raw, "QUIT ")){ IRCC_parse(strstr(irc->raw, "PART "), irc); IRCC_parse(strstr(irc->raw, "QUIT "), irc); return IRCC_PART; } } return IRCC_SUCCESS; } void IRCC_send(IRCC_client *irc, char *msg, char *channel){ size_t size = strlen("PRIVMSG :\r\n") + strlen(channel) + strlen(msg); char *tmp = (char *)malloc(size + 1); if (tmp == NULL){ fprintf(stderr, "malloc returned NULL (IRCC_send)\n"); exit(1); } snprintf(tmp, size, "PRIVMSG %s :%s\r\n", channel, msg); send(irc->socket, tmp, strlen(tmp), 0); memset(tmp, 0, size); free(tmp); } unsigned int IRCC_init(IRCC_client *irc, size_t size){ if (size <= 250){ fprintf(stderr, "Low buffer size (IRCC_init) (Min 250/512)\n"); return IRCC_ERROR; } irc->raw = (char *)malloc(size + 1); if (irc->raw == NULL){ fprintf(stderr, "malloc returned NULL (IRCC_init)\n"); exit(1); } irc->msg = irc->nick = irc->channel = NULL; irc->size = size; return IRCC_SUCCESS; } void IRCC_close(IRCC_client *irc){ close(irc->socket); free(irc->raw); irc->raw = irc->msg = irc->nick = irc->channel = NULL; irc->size = 0; }