void net_connect() { int err; // Connect struct addrinfo hints; struct addrinfo *srv; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; if ((err = getaddrinfo(config->host, config->port, &hints, &srv)) != 0) die("getaddrinfo", gai_strerror(err)); if ((socket_fd = socket(srv->ai_family, srv->ai_socktype, 0)) < 0) die("socket", gai_strerror(socket_fd)); if ((err = connect(socket_fd, srv->ai_addr, srv->ai_addrlen)) != 0) die("connect", gai_strerror(err)); freeaddrinfo(srv); // Join printf("connecting...\n"); char buffer[strlen("USER host realmname :\nNICK \n") + strlen(config->user) + strlen(config->nick) + strlen(config->nick) + 1]; // + 1 for terminating null byte sprintf(buffer, "USER %s host realmname :%s\nNICK %s\n", config->user, config->nick, config->nick); irc_send_str(buffer); join_channels(); }
static void process_response(void *context, char *id, char *resp){ const char joined_prefix[8] = "joined "; if(strstr(resp, joined_prefix)){ char arg[256]; memcpy(arg, resp + 7, strlen(resp) -6); //printf("response awrg: %s\n", arg); join_channels(context, id, arg); } }
int main(int argc, char **argv) { int socketfd, n; char in[BUF+1], out[BUF+1], c[512]; char *pos, *action; if(argc != 5) { printf("Usage: %s <address> <port> <nick> <owner>\n", argv[0]); exit(1); } else if(atoi(argv[2]) < 1 || atoi(argv[2]) > 50000) { printf("Invalid port specified.\n"); exit(1); } else if(irc_connect(argv[1], atoi(argv[2]), &socketfd) == 0) { printf("Failed to connect to %s.\n", argv[1]); exit(1); } nick = argv[3]; owner = argv[4]; if(strlen(nick)>48) { printf("Error: irc bot nickname too long\n"); exit(1); } if(strlen(owner)>48) { printf("Error: bot owner nickname too long\n"); exit(1); } /* write to buffer */ sprintf(c, "NICK %s\r\n", nick); irc_send(socketfd, c); sprintf(c, "USER %s %s %s :%s\r\n", nick, nick, nick, nick); irc_send(socketfd, c); /* do the service jobs */ if(join_channels(socketfd, "./owners.log") == 2) { return 1; } while(1) { in[0] = 0; n = irc_read(socketfd, in); if (n > 0) { char *str = process_string(in, n); if(strncmp(str, "0", 1)!=0) { irc_send(socketfd, str); } if(strncmp(str, "QUIT", 4)==0) { break; } } // if(n > 0) } // while(1) return 0; }
int m_server(user_t *cptr, int parc, char **parv) { if (me.servers == 1 && me.servtype == SERV_HYBRD) { intro_nicks(ALL); join_channels(OS); } if (parc > 3) add_linked_server((parv[0] ? parv[0] : me.servname), parv[1], strnull(parv[3])); return 1; }
void intro_nicks(u_short nicknum) { short i = nicknum; if (i == ALL) i--; switch (me.servtype) { case SERV_IRCNN: for (; i >= 0; i--) { toserv(":%s NICK %s 1 %lu %s %s %s :%s\r\n", me.servname, me.sclients[i].nick, time(NULL), me.sclients[i].username, me.servname, me.servname, me.sclients[i].realname); toserv(":%s MODE %s :+ko\r\n", me.sclients[i].nick, me.sclients[i].nick); me.opers++; add_user(me.sclients[i].nick, me.sclients[i].username, me.servname, me.sclients[i].realname, me.servname, NOKILL); /* XXX - lame services will kill operserv2 if not identified */ if (i == OS) toserv(":%s PRIVMSG NickServ :identify abcd123\r\n", me.sclients[i].nick); if (nicknum != ALL) break; } break; case SERV_HYBRD: for (; i >= 0; i--) { /* NICK wiz6 1 1021703400 +iw jason rr.wiz.cx h6.wiz.cx :monkey mushroom */ toserv(":%s NICK %s 1 %lu +omw %s %s %s :%s\r\n", me.servname, me.sclients[i].nick, time(NULL), me.sclients[i].username, me.servname, me.servname, me.sclients[i].realname); add_user(me.sclients[i].nick, me.sclients[i].username, me.servname, me.sclients[i].realname, me.servname, NOKILL); me.htmtime = time(NULL); if (me.eob == 1) join_channels(i); if (nicknum != ALL) break; } break; } }
int main(int argc, char **argv) { tic(); char *conf_file = NULL; socket_fd = -1; for (int i=1; i<argc; i++) { if (!strcmp(argv[i], "-c")) { if (argc <= i) { print_usage(); } conf_file = argv[++i]; } else if (!strcmp(argv[i], "-fd")) { if (argc <= i) { print_usage(); } socket_fd = atoi(argv[++i]); } else { printf(" >> unknown option: %s\n", argv[i]); } } if (!conf_file) conf_file = "cbot.conf"; load_config(conf_file); // Set rand seed srand(time(NULL)); // Set up cURL curl_global_init(CURL_GLOBAL_ALL); // Set up db connection for logging if (config->enabled_modules & MODULE_LOG) { log_init(); } // Parse markov corpus if (config->enabled_modules & MODULE_MARKOV) { markov_init(config->markovcorpus); } irc_init(); if (socket_fd == -1) { printf(" - Connecting to %s:%s with nick %s, joining channels...\n", config->host, config->port, config->nick); net_connect(); } else { // In-place upgrade yo printf(" >> Already connected, upgraded in-place!\n"); join_channels(); } struct recv_data *irc = malloc(sizeof(struct recv_data)); patterns = malloc(sizeof(*patterns)); compile_patterns(patterns); // Select param fd_set socket_set; FD_ZERO(&socket_set); FD_SET(STDIN_FILENO, &socket_set); FD_SET(socket_fd, &socket_set); int recv_size; char buffer[BUFFER_SIZE]; char input[BUFFER_SIZE]; memset(buffer, 0, BUFFER_SIZE); size_t buffer_length = 0; while (1) { int ret = select(socket_fd+1, &socket_set, 0, 0, 0); if (ret == -1) { printf(" >> Disconnected, reconnecting...\n"); close(socket_fd); net_connect(); } if (FD_ISSET(STDIN_FILENO, &socket_set)) { if (fgets(input, BUFFER_SIZE, stdin) == NULL) { printf(" >> Error while reading from stdin!\n"); continue; } if (strcmp(input, "quit\n") == 0) { printf(" >> Bye!\n"); break; } else if (strcmp(input, "reload\n") == 0) { terminate(); free(irc); free_patterns(patterns); free(patterns); // Set up arguments char * arguments[6]; arguments[0] = argv[0]; arguments[1] = "-c"; arguments[2] = conf_file; arguments[3] = "-fd"; char fdstring[snprintf(NULL, 0, "%d", socket_fd)]; sprintf(fdstring, "%d", socket_fd); arguments[4] = fdstring; arguments[5] = NULL; printf(" >> Upgrading...\n"); execvp(argv[0], arguments); printf(" !!! Execvp failing, giving up...\n"); exit(-1); } else if (strncmp(input, "say ", 4) == 0) { int offsets[30]; int offsetcount = pcre_exec(patterns->command_say, 0, input, strlen(input), 0, 0, offsets, 30); if (offsetcount > 0) { char channel[BUFFER_SIZE]; char message[BUFFER_SIZE]; pcre_copy_substring(input, offsets, offsetcount, 1, channel, BUFFER_SIZE); pcre_copy_substring(input, offsets, offsetcount, 2, message, BUFFER_SIZE); char sendbuf[strlen("PRIVMSG : ") + strlen(channel) + strlen(message)]; sprintf(sendbuf, "PRIVMSG %s :%s\n", channel, message); irc_send_str(sendbuf); } } else if (strncmp(input, "kick ", 5) == 0) { int offsets[30]; int offsetcount = pcre_exec(patterns->command_kick, 0, input, strlen(input), 0, 0, offsets, 30); if (offsetcount > 0) { char channel[BUFFER_SIZE]; char user[BUFFER_SIZE]; pcre_copy_substring(input, offsets, offsetcount, 1, channel, BUFFER_SIZE); pcre_copy_substring(input, offsets, offsetcount, 2, user, BUFFER_SIZE); char sendbuf[strlen("KICK :Gene police! You! Out of the pool, now!\n") + strlen(channel) + strlen(user)]; sprintf(sendbuf, "KICK %s %s :Gene police! You! Out of the pool, now!\n", channel, user); irc_send_str(sendbuf); } } else { printf(" >> Unrecognized command. Try 'quit'\n"); } FD_SET(socket_fd, &socket_set); } else { if (buffer_length >= BUFFER_SIZE - 1) { printf(" >> what the f**k, IRCd, a line longer than 4k? dropping some buffer\n"); memset(buffer, 0, BUFFER_SIZE); buffer_length = 0; continue; } recv_size = recv(socket_fd, buffer + buffer_length, BUFFER_SIZE - buffer_length - 1, 0); buffer_length += recv_size; buffer[buffer_length] = '\0'; if (recv_size == 0) { printf(" >> recv_size is 0, assuming closed remote socket, reconnecting\n"); close(socket_fd); printf("closed\n"); net_connect(); printf("reconnected\n"); } char *newlinepos = 0; char *bufbegin = buffer; while ((newlinepos = strchr(bufbegin, '\n'))) { *newlinepos = 0; printf(" ~ %s\n", bufbegin); // Only handle privmsg if (irc_parse_input(bufbegin, irc, patterns)) { irc_handle_input(irc, patterns); } bufbegin = newlinepos + 1; } size_t bytes_removed = bufbegin - buffer; memmove(buffer, bufbegin, buffer_length - bytes_removed); buffer_length -= bytes_removed; memset(buffer + buffer_length, 0, BUFFER_SIZE - buffer_length); FD_SET(STDIN_FILENO, &socket_set); } } printf(" >> Socket closed, quitting...\n"); close(socket_fd); free(irc); free_patterns(patterns); free(patterns); terminate(); return 0; }
void io_loop(void) { int r, i, errv, errlen = sizeof(errv); struct timeval tv = { 1, 0 }; struct sockaddr_in sin; size_t ssin = sizeof(sin); char buffer[BUFSIZE]; sock_t *sock, *tmp; memset(buffer, 0, BUFSIZE); loop: /* wiz is leet */ FD_ZERO(&me.readfds); FD_ZERO(&me.writefds); for (sock = main_sock; sock;) { if (sock->flags & SOCK_DEL) { tmp = sock->next; del_sock(sock); sock = tmp; continue; } if (sock->flags & (SOCK_LISTEN|SOCK_CONN)) FD_SET(sock->socket, &me.readfds); else FD_SET(sock->socket, &me.writefds); sock = sock->next; } while ((r = select(FD_SETSIZE, &me.readfds, &me.writefds, NULL, &tv)) == -1) if (errno != EINTR) { log("FATAL! select() == -1: %s", ERR); exit(1); } do_events(time(NULL)); for (sock = main_sock; r > 0 && sock;) { if (FD_ISSET(sock->socket, &me.readfds) && r--) { if (sock->flags & SOCK_LISTEN) { memset(&sin, 0, sizeof(sin)); if ((i = accept(sock->socket, (struct sockaddr *)&sin, &ssin)) == -1) goto nextsock; log("NET: connection from %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); tmp = add_sock_to_list(); if ((tmp->socket = nonblock_sock(i)) == -1) { del_sock(tmp); goto nextsock; } else if (!(tmp->fd = fdopen(tmp->socket, "r"))) { log("fdopen(%d) failed: %s", tmp->socket, strerror(errno)); del_sock(tmp); goto nextsock; } tmp->conn = time(NULL); tmp->addr = sin.sin_addr; tmp->port = ntohs(sin.sin_port); tmp->buffer = leetcalloc(BUFSIZE, 1); tmp->flags |= (SOCK_CONN|sock->flags); tmp->flags &= ~SOCK_LISTEN; greet_dcc(tmp); goto nextsock; } if (!fgets(sock->buffer, BUFSIZE, sock->fd)) { errv = 0; if (getsockopt(sock->socket, SOL_SOCKET, SO_ERROR, &errv, &errlen) < 0) { log("NET: getsockopt(SO_ERROR) failed: %s", ERR); goto delsock; } goto readerr; } sock->last = time(NULL); for(i = 0; i < BUFSIZE; i++) if (sock->buffer[i] == '\r' || sock->buffer[i] == '\n') sock->buffer[i] = 0; if (sock->flags & SOCK_HUB) parse(sock->buffer); else if (sock->flags & (SOCK_DCC|SOCK_TELNET)) parse_dcc(sock, sock->buffer); memset(sock->buffer, 0, BUFSIZE); } else if (FD_ISSET(sock->socket, &me.writefds) && r--) { errv = 0; if (getsockopt(sock->socket, SOL_SOCKET, SO_ERROR, &errv, &errlen) < 0) { log("NET: getsockopt(SO_ERROR) failed: %s", ERR); goto delsock; } if (errv > 0) { if (sock->flags & SOCK_HUB) { log("HUB: error connecting to %s: %s", sock->name, strerror(errv)); alldcc("HUB: error connecting to %s: %s", sock->name, strerror(errv)); #if 0 } else if (sock->flags & SOCK_DCC && find_client(sock->name)) reply(OS, sock->name, "Error DCC connecting: %s", strerror(errv)); #else } #endif goto delsock; } if (sock->flags & SOCK_HUB) { log("HUB: connected to %s", sock->name); alldcc("HUB: connected to %s", sock->name); del_event_func(&try_next_hub); sock->conn = time(NULL); me.conn = 1; switch (me.servtype) { case SERV_IRCNN: toserv("PASS :%s\r\n", servpass); toserv("SERVER %s 1 %lu %lu J09 :%s\r\n", me.servname, time(NULL), time(NULL), me.servdesc); add_linked_server(me.servname, me.servname, me.servdesc); intro_nicks(ALL); join_channels(OS); break; case SERV_HYBRD: toserv("CAPAB :QS EX IE EOB UNKLN KLN HOPS HUB TBURST\r\n"); toserv("PASS %s :TS\r\n", servpass); toserv("SERVER %s 0 :%s\r\n", me.servname, me.servdesc); toserv("SVINFO 5 5 0 :%lu\r\n", time(NULL)); add_linked_server(me.servname, me.servname, me.servdesc); break; } } else if (sock->flags & SOCK_DCC) { log("DCC: %s connected from %s:%d", sock->name, inet_ntoa(sock->addr), sock->port); me.dcc++; } sock->flags |= SOCK_CONN; } nextsock: { sock = sock->next; continue; } readerr: { log("NET: read error from %s: %s", (sock->name ? sock->name : inet_ntoa(sock->addr)), strerror(errv)); } delsock: { sock->flags |= SOCK_DEL; goto nextsock; } }