static void config_free_node(node *n) { node *m; attribute *a, *b; if (n == NULL) { return; } n->parent = NULL; n->next = NULL; while (n != NULL) { m = n; if (n->children != NULL) { n = n->children; m->children = NULL; } else { if (n->next != NULL) { n = n->next; } else { n = n->parent; } if (m->name == NULL) { free(m->data); } else { irc_free(m->name); } a = m->attrs; while (a != NULL) { irc_free(a->name); irc_free(a->value); b = a->next; irc_free(a); a = b; } irc_free(m); } } }
/* immed=1 makes this function pretty much equal to irc_free(), except that this one will "log". In case the connection is already broken and we shouldn't try to write to it. */ void irc_abort(irc_t *irc, int immed, char *format, ...) { char *reason = NULL; if (format != NULL) { va_list params; va_start(params, format); reason = g_strdup_vprintf(format, params); va_end(params); } if (reason) { irc_write(irc, "ERROR :Closing link: %s", reason); } ipc_to_master_str("OPERMSG :Client exiting: %s@%s [%s]\r\n", irc->user->nick ? irc->user->nick : "(NONE)", irc->user->host, reason ? : ""); g_free(reason); irc_flush(irc); if (immed) { irc_free(irc); } else { b_event_remove(irc->ping_source_id); irc->ping_source_id = b_timeout_add(1, (b_event_handler) irc_free, irc); } }
node *config_get_node(node *root, char *name) { node *n; char *x, *y, *z = NULL; if (name == NULL) { return root; } x = irc_strdup(name); n = root; for (y = strtok_r(x, "/", &z); y != NULL && n != NULL; y = strtok_r(NULL, "/", &z)) { n = n->children; while (n != NULL) { if (n->name != NULL && !strcmp(y, n->name)) { break; } n = n->next; } } while (y != NULL && n != NULL); irc_free(x); return n; }
storage_status_t storage_rename (const char *onick, const char *nnick, const char *password) { storage_status_t status; GList *gl = global.storage; storage_t *primary_storage = gl->data; irc_t *irc; /* First, try to rename in the current write backend, assuming onick * is stored there */ status = primary_storage->rename(onick, nnick, password); if (status != STORAGE_NO_SUCH_USER) return status; /* Try to load from a migration backend and save to the current backend. * Explicitly remove the account from the migration backend as otherwise * it'd still be usable under the old name */ irc = g_new0(irc_t, 1); status = storage_load(onick, password, irc); if (status != STORAGE_OK) { irc_free(irc); return status; } g_free(irc->nick); irc->nick = g_strdup(nnick); status = storage_save(irc, FALSE); if (status != STORAGE_OK) { irc_free(irc); return status; } irc_free(irc); storage_remove(onick, password); return STORAGE_OK; }
void handle_client(int client_fd, char *ip, short port) { irc_data_t irc_channels; char buf[MAX_CLIENT_SEND_BUFF_SZ]; int retn = 0; irc_init(&irc_channels); if (0 != get_ip_from_hostname(ip, buf, sizeof(buf))) { perror("get ip from host error\n"); goto err; } printf("connect to irc server: %s[%s] %d\n", ip, buf, port); irc_channels.socket_fd = create_client_socket(buf, port); if (0 > irc_channels.socket_fd) { goto err; } if (0 != pthread_create(&irc_channels.thread_recv, NULL , thread_recv_msg_from_server, &irc_channels)) { perror("create recv thread error!"); goto err; } if (0 != pthread_create(&irc_channels.thread_send, NULL , thread_send_msg_to_server, &irc_channels)) { perror("create send thread error!"); goto err; } for(;;) { retn = recv(client_fd, buf, sizeof(buf) - 1, 0); if (retn > 0) { buf[retn - 1] = '\0'; fprintf(stdout, "[local-client]: recv: %s\n",buf); handle_msg_remove_illegal_ch(buf, retn); handle_msg_from_client(&irc_channels, buf, retn - 1); } else if (0 == retn) { fprintf(stdout, "client offline"); break; } else { fprintf(stderr, "client error"); break; } } err: close(client_fd); irc_free(&irc_channels); }
void _socket_free(sock *sock) { if (sock->laddr != NULL) { address_free(sock->laddr); } if (sock->raddr != NULL) { address_free(sock->raddr); } #ifdef HAVE_SSL if (sock->sslstate != SSL_OFF) { SSL_free(sock->ssl); } #endif irc_free(sock); }
static void ipc_child_cmd_takeover( irc_t *irc, char **cmd ) { if( strcmp( cmd[1], "NO" ) == 0 ) { /* Master->New connection */ /* No takeover, finish the login. */ } else if( strcmp( cmd[1], "INIT" ) == 0 ) { /* Master->New connection */ if( !set_getbool( &irc->b->set, "allow_takeover" ) ) { ipc_child_cmd_takeover_no( irc ); return; } /* Offer to take over the old session, unless for some reason we're already logging into IM connections. */ if( irc->login_source_id != -1 ) query_add( irc, NULL, "You're already connected to this server. " "Would you like to take over this session?", ipc_child_cmd_takeover_yes, ipc_child_cmd_takeover_no, NULL, irc ); /* This one's going to connect to accounts, avoid that. */ b_event_remove( irc->login_source_id ); irc->login_source_id = -1; } else if( strcmp( cmd[1], "AUTH" ) == 0 ) { /* Master->Old connection */ if( irc->password && cmd[2] && cmd[3] && ipc_child_recv_fd != -1 && strcmp( irc->user->nick, cmd[2] ) == 0 && strcmp( irc->password, cmd[3] ) == 0 && set_getbool( &irc->b->set, "allow_takeover" ) ) { irc_switch_fd( irc, ipc_child_recv_fd ); irc_sync( irc ); irc_rootmsg( irc, "You've successfully taken over your old session" ); ipc_child_recv_fd = -1; ipc_to_master_str( "TAKEOVER DONE\r\n" ); } else { ipc_to_master_str( "TAKEOVER FAIL\r\n" ); } } else if( strcmp( cmd[1], "DONE" ) == 0 ) { /* Master->New connection (now taken over by old process) */ irc_free( irc ); } else if( strcmp( cmd[1], "FAIL" ) == 0 ) { /* Master->New connection */ irc_rootmsg( irc, "Could not take over old session" ); } }
int main(int argc, char **argv) { int ret, opt, conn, plugins_loaded = 0, banner_displayed = 0; unsigned long now, lastconn = time(NULL); FILE *urandom; runlevel = RL_OFFLINE; while ((opt = getopt(argc, argv, "c:dj:u:vh")) != -1) { switch(opt) { case 'c': settings.config = optarg; break; case 'd': settings.daemonize = 1; break; case 'j': settings.chroot = optarg; break; case 'u': settings.chuser = optarg; break; case 'v': print_version(); break; case 'h': default: print_usage(argv[0]); break; } } srand(time(NULL)); urandom = fopen("/dev/urandom", "r"); srrand(time(NULL) ^ getpid(), urandom); if (config_parse(settings.config)) { fprintf(stderr, "Unable to load configuration file '%s'.\n", settings.config); return -1; } if (checkconfig()) return -1; if (settings.daemonize) { ret = fork(); switch(ret) { case -1: fprintf(stderr, "Unable to fork to background\n"); return -1; default: return 0; } } if (secure_it(settings.chroot, settings.chuser)) { fprintf(stderr, "Failed to chroot/setuid\n"); return -1; } #ifdef TLS if (gnutls_global_init() == GNUTLS_E_SUCCESS) atexit(gnutls_global_deinit); else fprintf(stderr, "Unable to initialize TLS library\n"); #endif if (dns_init() == -1) warn("Unable to initialize dns resolver\n"); for(runlevel = RL_RUNNING; runlevel;) { if (irc_init() == -1) { warn("Unable to init irc data structure"); return -1; } if(!plugins_loaded) { plugins_load(); plugins_loaded = 1; } if(!banner_displayed) { banner_displayed = banner("Welcome to " PACKAGE_STRING #ifdef SVN_REV "." SVN_REV #endif ); } while ((runlevel == RL_RUNNING) && (irc_conn() == -1)) { warn("Unable to establish irc connection\n"); sleep(RECONNECT_DELAY); } lastconn = time(NULL); while(runlevel == RL_RUNNING) io_loop(100); irc_free(); if((runlevel != RL_RUNNING) && plugins_loaded) { plugins_unload(); plugins_loaded = 0; } if(runlevel == RL_RELOAD) { printc("Reloading config file '%s'...\n", settings.config); if(config_parse(settings.config)) { warn("Error reloading config file.\n"); runlevel = RL_OFFLINE; } else if(checkconfig()) { runlevel = RL_OFFLINE; } runlevel = RL_RUNNING; } conn = 0; now = time(NULL); if(runlevel != RL_OFFLINE) { runlevel = RL_RUNNING; if (now < lastconn + RECONNECT_DELAY) sleep(lastconn + RECONNECT_DELAY - now); } } if(urandom) fclose(urandom); return 0; }