/** internal functions implementation starts here **/ int ev_irc_connect(void* dummy1, void* dummy2) { int cr; stdlog(L_INFO, "Connecting to IRC server %s:%i", RemoteServer, RemotePort); cr = irc_FullConnect(RemoteServer, RemotePort, ServerPass, 0); if(cr < 0) { errlog("Could not connect to IRC server: %s", irc_GetLastMsg()); exit(1); } stdlog(L_INFO, "Netjoin complete, %.1d Kbs received", irc_InByteCount()/1024); /* not sure if this fork should be on the irc module for now lets leave it like this to make sure we only fork after the connection is fully established */ if( nofork == 0 ) { fork_process(); write_pidfile(); } irc_LoopWhileConnected(); errlog("Disconnected:%s\n", irc_GetLastMsg()); /* stdlog(L_INFO, "PTlink IRC Services Terminated"); */ return 0; }
/** load code **/ int mod_load(void) { if(Interval) { stdlog(L_INFO, "Running expire routines..."); ev_expire(NULL, NULL); stdlog(L_INFO,"Expire interval set to %d minute(s)", Interval / 60); irc_AddEvent(ET_LOOP, ev_expire); /* set the expire routines */ } else stdlog(L_WARN, "Data expiration is disabled"); return 0; }
void fork_process(void) { int pid; if((pid = fork()) < 0) { errlog("Couldn't fork: %s\n", strerror(errno)); exit(0); } else if (pid > 0) /* this is the parent process */ { stdlog(L_INFO, "Running in the background with pid=%d", pid); exit(0); } setsid(); }
/* module load code */ int mod_load(void) { int r; ns_log = log_handle("nickserv"); r = sql_check_inst_upgrade(mod_info.name, DB_VERSION, NULL); if(r < 0) return -4; else if(r == 1) /* table was installed */ create_core_groups(); else { if(Root) stdlog(L_WARN, "Root is defined, please add a nick to the Root group and disable the setting"); } nsu = nickserv_suser(); suser_add_cmd(nsu, "GROUP", ns_group, NS_GROUP_SUMMARY, NS_GROUP_HELP); /* Add event actions */ mod_add_event_action(e_nick_identify, (ActionHandler) ev_ns_group_nick_identify); mod_add_event_action(e_nick_recognize, (ActionHandler) ev_ns_group_nick_identify); mod_add_event_action(e_expire, (ActionHandler) ev_ns_group_expire); /* Add subcommands help */ suser_add_help(nsu, "GROUP ADD", NS_GROUP_ADD_HELP); suser_add_help(nsu, "GROUP CREATE", NS_GROUP_CREATE_HELP); suser_add_help(nsu, "GROUP DROP", NS_GROUP_DROP_HELP); suser_add_help(nsu, "GROUP DEL", NS_GROUP_DEL_HELP); suser_add_help(nsu, "GROUP INFO", NS_GROUP_INFO_HELP); suser_add_help(nsu, "GROUP LIST", NS_GROUP_LIST_HELP); suser_add_help(nsu, "GROUP SET", NS_GROUP_SET_HELP); suser_add_help(nsu, "GROUP SHOW", NS_GROUP_SHOW_HELP); return 0; }
/* * dbconf_get_or_build * For each item of the dbitems array * If the value exists on the db * update its description * set the value pointer if found * else * try to add item, returns -1 if fails * returns: * -1 , error adding item * >=0 number of items added to the db */ int dbconf_get_or_build(char *module, dbConfItem* dbitems) { int new_item = 0; dbConfItem* item = dbitems; while(item && item->name) { if(sql_singlequery("SELECT value FROM dbconf WHERE module=%s AND name=%s" " ORDER BY module, name", sql_str(module), sql_str(item->name)) > 0) { /* read the value */ if(!strcmp(item->type, "str") || !strcmp(item->type, "word")) { FREE(*(char **)item->vptr); *(char **)item->vptr = sql_field(0) ? strdup(sql_field(0)) : NULL; } else if(!strcmp(item->type,"int") && sql_field_i(0)) *(int*) item->vptr = sql_field_i(0); else if(!strcmp(item->type,"time") && sql_field(0)) { if(ftime_str(sql_field(0)) == -1) { errlog("Invalid time value on %s.%s", module, item->name); return -1; } *(int*) item->vptr = ftime_str(sql_field(0)); } else if(!strcmp(item->type,"switch") && sql_field(0)) *(int*) item->vptr = (!strcasecmp(sql_field(0),"on")); /* update type and description */ sql_execute("UPDATE dbconf SET stype=%s, ddesc=%s" " WHERE module=%s AND name=%s", sql_str(item->type), sql_str(item->desc), sql_str(module), sql_str(item->name)); } else { sqlb_init("dbconf"); sqlb_add_str("module", module); sqlb_add_str("name", item->name); sqlb_add_str("stype", item->type); sqlb_add_str("ddesc", item->desc); sqlb_add_str("optional", item->optional); sqlb_add_str("configured", "n"); sqlb_add_str("value", item->def); if(sql_execute(sqlb_insert()) < 0) { errlog("Error adding dbconf item %s!", item->name); return -1; } if(!strcmp(item->type, "str") || !strcmp(item->type, "word")) { FREE(*(char **)item->vptr); *(char **)item->vptr = item->def ? strdup(item->def): NULL; } else if(!strcmp(item->type, "int") && item->def) *(int*) item->vptr = atoi(item->def); else if(!strcmp(item->type, "switch")) *(int*) item->vptr = (!strcasecmp(item->def,"on")); else if(!strcmp(item->type,"time") && item->def) { if(ftime_str(item->def) == -1) { errlog("Invalid default time value on %s.%s", module, item->name); return -1; } *(int*) item->vptr = ftime_str(item->def); } ++new_item; } item++; } if(new_item) stdlog(L_INFO, "Installed %d new configuration item(s)", new_item); return new_item; }
/** * スレッド処理 * * @return なし */ static void * client_thread(void *arg) { /* スレッドデータ */ thread_data *dt = (thread_data *)arg; int retval = 0; /* 戻り値 */ size_t length = 0; /* 長さ */ ssize_t slen = 0; /* 送信するバイト数 */ struct header hd; /* ヘッダ */ /* コネクト */ dt->sock = connect_sock(); if (dt->sock < 0) { outstd("Connect error"); pthread_exit((void *)EX_CONNECT_ERR); } pthread_cleanup_push(thread_cleanup, &dt); length = strlen((char *)dt->expr) + 1; /* データ設定 */ slen = set_client_data(&dt->sdata, dt->expr, length); if (slen < 0) /* メモリ確保できない */ pthread_exit((void *)EX_ALLOC_ERR); pthread_cleanup_push(thread_memfree, &dt->sdata); /* データ送信 */ retval = send_data(dt->sock, dt->sdata, (size_t *)&slen); /* ヘッダ受信 */ length = sizeof(struct header); (void)memset(&hd, 0, length); retval = recv_data(dt->sock, &hd, &length); if (retval < 0) /* エラー */ pthread_exit((void *)EX_RECV_ERR); dbglog("recv_data: hd=%p, length=%zu", &hd, length); length = (size_t)ntohl((uint32_t)hd.length); /* データ長を保持 */ /* データ受信 */ dt->answer = (uchar *)recv_data_new(dt->sock, &length); if (!dt->answer) /* メモリ確保できない */ pthread_exit((void *)EX_ALLOC_ERR); pthread_cleanup_push(thread_memfree, &dt->answer); if (!length) /* 受信エラー */ pthread_exit((void *)EX_RECV_ERR); dbglog("answer=%p, length=%zu", dt->answer, length); stdlog("%s", dt->answer); retval = strcmp((char *)dt->expected, (char *)dt->answer); stdlog("strcmp=%d", retval); assert(0 == retval); retval = shutdown(dt->sock, SHUT_RDWR); if (retval < 0) { outstd("shutdown: sock=%d", dt->sock); pthread_exit((void *)EXIT_FAILURE); } pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_cleanup_pop(1); pthread_exit((void *)EX_SUCCESS); return (void *)EX_SUCCESS; }
/** * スレッド生成 * * @return なし */ static void create_threads(void) { int retval = 0; /* 戻り値 */ thread_data *dt = NULL; /* 送信データ構造体 */ pthread_t tid[threads]; /* スレッドID */ void *thread_ret = NULL; /* スレッド戻り値 */ char tmp[48]; /* 一時バッファ */ char expr[threads][BUF_SIZE]; /* 式 */ char answer[threads][BUF_SIZE]; /* 答え */ /* データ作成 */ int i; for (i = 0; i < threads; i++) { (void)memset(tmp, 0, sizeof(tmp)); (void)memset(expr[i], 0, sizeof(expr[i])); (void)snprintf(tmp, sizeof(tmp), "%d", i); (void)strncpy(expr[i], "1+", sizeof(expr[i]) - 1); (void)strncat(expr[i], tmp, sizeof(expr[i]) - strlen(expr[i]) - 1); (void)memset(answer[i], 0, sizeof(answer[i])); (void)snprintf(answer[i], sizeof(answer[i]), "%d", (1 + i)); } (void)memset(tid, 0, sizeof(tid)); int j; for (j = 0; j < threads; j++) { dt = (thread_data *)malloc(sizeof(thread_data)); if (!dt) { outstd("malloc: size=%zu", sizeof(thread_data)); break; } (void)memset(dt, 0, sizeof(thread_data)); (void)memcpy(dt->expr, expr[j], sizeof(dt->expr)); (void)memcpy(dt->expected, answer[j], sizeof(dt->expected)); retval = pthread_create(&tid[j], NULL, client_thread, dt); if (retval) { outstd("pthread_create=%lu, j=%d", (ulong)tid[j], j); memfree((void **)&dt, NULL); break; } stdlog("pthread_create: tid=%lu", (ulong)tid[j]); } int k; for (k = 0; k < threads; k++) { if (tid[k]) { dbglog("tid=%lu", (ulong)tid[k]); retval = pthread_join(tid[k], &thread_ret); if (retval) { outstd("pthread_join=%lu, k=%jd", (ulong)tid[k], k); continue; } if (thread_ret) outstd("thread error=%ld", (long)thread_ret); stdlog("pthread_join=%ld: tid=%lu", (long)thread_ret, (ulong)tid[k]); assert(0 == thread_ret); } } (void)fprintf(stderr, "threads: %d\n", j); }
static void sighup_handler(int sig) { stdlog(L_CRIT, "Received SIGHUP, rehashing"); modules_rehash(); }
/* * sigterm_handler - exit the server */ static void sigterm_handler(int sig) { stdlog(L_CRIT, "Service killed By SIGTERM"); exit(-1); }
int main(int argc, char* argv[]) { setup_corefile(); /* we wan't core files for debug */ setup_signals(); srandom(time(NULL)); /* random seed */ /* check if we are just doing a configuration change */ if((argc > 1) && (strcasecmp(argv[1], "conf")==0)) return cmd_conf(argc-2, &argv[2]); parse_command_line(argc, argv); /* parse command line options */ printf("Starting %s, CopyRight PTlink IRC Software 1999-2005\n", svs_version); printf("Setting ircsvs log file to "LOGPATH "/ircsvs.log\n"); /* rotate the logsize if required */ check_logsize(); if(init_log(LOGPATH "/ircsvs.log") == 0) { fprintf(stderr,"ERROR: Could not create log file\n"); return 3; } slog(L_INFO, "Starting %s", svs_version); #if 0 if(TimeZone) { #ifdef HAVE_SETENV setenv("TZ",TimeZone,1); tzset(); #else fprintf(stderr, "TimeZone defined but setenv() is not supported on this OS!"); #endif } #endif /* Let's init the irc functions first, we may use them on modules */ e_expire = mod_register_event("e_expire"); e_complete = mod_register_event("e_complete"); if(load_modules_file("ircsvs") < 0) { fprintf(stderr,"ERROR: Error loading modules\n"); return -3; } stdlog(L_INFO, "All modules succesfully loaded"); /* check it here to avoid "Server already exists" uppon connection */ if( nofork == 0 ) check_pidfile(); #if 0 #warning need to move ExpireInterval to the module if(ExpireInterval) { stdlog(L_INFO, "Running expire routines..."); ev_expire(NULL, NULL); stdlog(L_INFO,"Expire interval set to %d minute(s)", ExpireInterval / 60); irc_AddEvent(ET_LOOP, ev_expire); /* set the expire routines */ } else stdlog(L_WARN, "Data expiration is disabled"); #endif stdlog(L_INFO, "Services startup completed."); mod_do_event(e_complete, NULL, NULL); return 0; }