static void process_args(int *argc, char ***argv, struct settings_s *sett) { char *a0 = (*argv)[0]; const char *optstr = "n:u:f:p:P:T:W:rb:qvh"; for (int ch; (ch = lsi_b_getopt(*argc, *argv, optstr)) != -1;) { switch (ch) { case 'n': irc_set_nick(g_irc, lsi_b_optarg()); break;case 'u': irc_set_uname(g_irc, lsi_b_optarg()); break;case 'f': irc_set_fname(g_irc, lsi_b_optarg()); break;case 'p': irc_set_pass(g_irc, lsi_b_optarg()); break;case 'P': { char host[256]; uint16_t port; int ptype; if (!lsi_ut_parse_pxspec(&ptype, host, sizeof host, &port, lsi_b_optarg())) C("failed to parse proxy '%s'", lsi_b_optarg()); irc_set_px(g_irc, host, port, ptype); } break;case 'T': { char *arg = STRDUP(lsi_b_optarg()); if (!arg) CE("strdup failed"); char *p = strchr(arg, ':'); if (!p) sett->hcto_us = strtoull(arg, NULL, 10) * 1000u; else { *p = '\0'; sett->hcto_us = strtoull(arg, NULL, 10) * 1000u; sett->scto_us = strtoull(p+1, NULL, 10) * 1000u; } D("connect timeout %"PRIu64"ms (s), %"PRIu64"ms (h)", sett->scto_us / 1000u, sett->hcto_us / 1000u); free(arg); } break;case 'W': sett->cfwait_s = (int)strtol(lsi_b_optarg(), NULL, 10); break;case 'b': sett->heartbeat_us = strtoull(lsi_b_optarg(), NULL, 10) * 1000u; break;case 'r': sett->recon = true; break;case 'q': sett->verb--; break;case 'v': sett->verb++; break;case 'h': usage(stdout, a0, EXIT_SUCCESS); break;case '?':default: usage(stderr, a0, EXIT_FAILURE); } } *argc -= lsi_b_optind(); *argv += lsi_b_optind(); return; }
static void init(int *argc, char ***argv, struct settings_s *sett) { if (setvbuf(stdin, NULL, _IOLBF, 0) != 0) WE("setvbuf stdin"); if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) WE("setvbuf stdout"); g_irc = irc_init(); irc_set_track(g_irc, true); irc_set_nick(g_irc, "iwat"); irc_set_uname(g_irc, "iwat"); irc_set_fname(g_irc, "irc netwat"); irc_set_conflags(g_irc, 0); irc_regcb_conread(g_irc, conread, 0); sett->heartbeat_us = DEF_HEARTBEAT_MS * 1000u; sett->cfwait_s = DEF_CONFAILWAIT_S; sett->verb = DEF_VERB; sett->scto_us = DEF_CONTO_SOFT_MS * 1000u; sett->hcto_us = DEF_CONTO_HARD_MS * 1000u; process_args(argc, argv, sett); if (!*argc) C("no server given"); for (int i = 0; i < *argc; i++) { char host[256]; uint16_t port; bool ssl = false; lsi_ut_parse_hostspec(host, sizeof host, &port, &ssl, (*argv)[i]); /* we choke on all other sorts of invalid addrs/hosts later */ struct srvlist_s *node = MALLOC(sizeof *node); if (!node) CE("malloc failed"); node->host = STRDUP(host); node->port = port; node->ssl = ssl; node->next = NULL; if (!g_srvlist) g_srvlist = node; else { struct srvlist_s *n = g_srvlist; while (n->next) n = n->next; n->next = node; } } irc_set_connect_timeout(g_irc, g_sett.scto_us, g_sett.hcto_us); D("initialized"); return; }
int main(int argc, char *argv[]) { int err; int max_descr; fd_set sock_set; struct timeval select_timeout; int running = 1; irc_connection con; unsigned irc_port; char *irc_server; conf = config_from_filename("ircb.conf"); assert(conf); if (argc == 3) { irc_server = argv[1]; irc_port = atoi(argv[2]); } if (argc == 2) { irc_server = argv[1]; irc_port = 6667; } else if (argc == 1) { config_group *g = config_get_group(conf, "irc"); irc_server = Conf("server", "INVALID"); if (!strcmp(irc_server, "INVALID")) { Printerr("No IRC server address given!\n"); return 1; } char *portstr = Conf("port", "6667"); assert(irc_server && portstr); irc_port = atoi(portstr); } else return 1; err = irc_connect(&con, irc_server, irc_port); if (err) { Printerr("Got no connection to IRC server!\n"); return 1; } module_load_module_dir(&con, conf); config_group *g = config_get_group(conf, "bot"); irc_set_nick(&con, Conf("nickname", "cbot")); irc_set_user(&con, Conf("username", "cbot_user"), Conf("hostname", "cbot_host"), Conf("servername", "cbot_server"), Conf("realname", "The CBot!")); max_descr = MAX(STDIN_FILENO, con.sockfd) + 1; while (running) { FD_ZERO(&sock_set); FD_SET(STDIN_FILENO, &sock_set); FD_SET(con.sockfd, &sock_set); select_timeout.tv_sec = 120; select_timeout.tv_usec = 0; err = select(max_descr, &sock_set, NULL, NULL, &select_timeout); if (!err) { /* Handle timeout */ } if (FD_ISSET(con.sockfd, &sock_set)) /* Incoming data from IRC network */ running = !handle_irc_messages(&con); if (FD_ISSET(STDIN_FILENO, &sock_set)) /* Local user input */ running = handle_keyboard_input(&con) != -2; } module_unload_all(&con); irc_close(&con, "bye."); return 0; }