int config_set_str(const char *strval, void *config_root, ...) { va_list args; xml_node_t *root = config_root; config_var_t *var; va_start(args, config_root); root = xml_node_vlookup(root, args, 1); va_end(args); if (!gconfig_level) { char *name; int r; name = xml_node_fullname(root); gconfig_level++; r = bind_check(BT_config_str, NULL, name, name, strval); gconfig_level--; free(name); if (r & BIND_RET_BREAK) return(-1); } var = root->client_data; if (var) { if (var->type == CONFIG_STRING && *(char **)var->ptr != strval) str_redup(var->ptr, strval); else if (var->type == CONFIG_INT) *(int *)var->ptr = atoi(strval); } xml_node_set_str(strval, root, NULL); return(0); }
int partymember_set_nick(partymember_t *p, const char *nick) { partymember_common_t *common; partymember_t *mem; char *oldnick; int i; oldnick = p->nick; p->nick = strdup(nick); if (p->handler && p->handler->on_nick) (p->handler->on_nick)(p->client_data, p, oldnick, nick); botnet_set_nick(p, oldnick); p->flags |= PARTY_SELECTED; common = partychan_get_common(p); if (common) { for (i = 0; i < common->len; i++) { mem = common->members[i]; if (mem->flags & PARTY_DELETED) continue; if (mem->handler->on_nick) (mem->handler->on_nick)(mem->client_data, p, oldnick, nick); } partychan_free_common(common); } bind_check(BT_nick, NULL, NULL, p, oldnick, p->nick); if (oldnick) free(oldnick); p->flags &= ~PARTY_SELECTED; return(0); }
int config_set_int(int intval, void *config_root, ...) { va_list args; xml_node_t *root = config_root; config_var_t *var; va_start(args, config_root); root = xml_node_vlookup(root, args, 1); va_end(args); if (!gconfig_level) { char *name; int r; name = xml_node_fullname(root); gconfig_level++; r = bind_check(BT_config_int, NULL, name, name, intval); gconfig_level--; free(name); if (r & BIND_RET_BREAK) return(-1); } var = root->client_data; if (var) { if (var->type == CONFIG_INT) *(int *)var->ptr = intval; } xml_node_set_int(intval, root, NULL); return(0); }
int module_unload(const char *name, int why) { module_list_t *entry; int retval; entry = find_active_module(name); if (!entry) return(-1); if (entry->refcount > 0) return(-2); if (entry->modinfo.close_func) { retval = entry->modinfo.close_func(why); if (retval) return(-3); } if (entry->prev) entry->prev->next = entry->next; else module_list_head = entry->next; if (entry->next) entry->next->prev = entry->prev; entry->next = NULL; if (!deleted_head) { deleted_head = entry; entry->prev = NULL; } else { module_list_t *tail; for (tail = deleted_head; tail->next; tail = tail->next); tail->next = entry; entry->prev = tail; } bind_check(BT_unload, NULL, name, name, why == MODULE_USER ? "request" : why == MODULE_SHUTDOWN ? "shutdown" : "restart"); putlog(LOG_MISC, "*", "Module unloaded: %s", name); garbage_add(module_cleanup, NULL, GARBAGE_ONCE); return 0; }
int module_load(const char *name) { lt_dlhandle hand; module_list_t *entry; egg_start_func_t startfunc; char *startname; /* See if it's already loaded. */ entry = find_active_module(name); if (entry) return(-1); entry = find_deleted_module(name); if (entry) return(-5); hand = lt_dlopenext(name); if (!hand) { const char *err = lt_dlerror(); putlog(LOG_MISC, "*", "Error loading module %s: %s", name, err); return(-2); } startname = egg_mprintf("%s_LTX_start", name); startfunc = (egg_start_func_t)lt_dlsym(hand, startname); free(startname); if (!startfunc) { startfunc = (egg_start_func_t)lt_dlsym(hand, "start"); if (!startfunc) { lt_dlclose(hand); return(-3); } } /* Create an entry for it. */ entry = calloc(1, sizeof(*entry)); entry->prev = NULL; entry->next = module_list_head; entry->refcount = 0; entry->hand = hand; module_list_head = entry; if (startfunc(&entry->modinfo)) { module_list_head = module_list_head->next; free(entry); return(-4); } putlog(LOG_MISC, "*", "Module loaded: %s", name); bind_check(BT_load, NULL, name, name); return(0); }
int partychan_part(partychan_t *chan, partymember_t *p, const char *text) { int i, len; partychan_member_t *mem; if (!chan || !p) return(-1); /* Remove the channel entry from the member. */ if (!(p->flags & PARTY_DELETED)) for (i = 0; i < p->nchannels; i++) { if (p->channels[i] == chan) { memmove(p->channels+i, p->channels+i+1, sizeof(chan) * (p->nchannels-i-1)); p->nchannels--; break; } } /* Mark the member to be deleted. */ for (i = 0; i < chan->nmembers; i++) { if (chan->members[i].flags & PARTY_DELETED) continue; if (chan->members[i].p == p) { chan->members[i].flags |= PARTY_DELETED; garbage_add((garbage_proc_t)partychan_cleanup, chan, GARBAGE_ONCE); break; } } /* If the member is already deleted, then the quit event has been * fired already. */ if (p->flags & PARTY_DELETED) return(0); if (!text) text = ""; len = strlen(text); /* Trigger the partyline channel part bind. */ bind_check(BT_partypart, NULL, NULL, chan->name, chan->cid, p, text, len); if (p->handler && p->handler->on_part) p->handler->on_part(p->client_data, chan, p, text, len); /* Send out the part event to the members. */ for (i = 0; i < chan->nmembers; i++) { mem = chan->members+i; if (mem->flags & PARTY_DELETED || mem->p->flags & PARTY_DELETED) continue; if (mem->p->handler && mem->p->handler->on_part) (mem->p->handler->on_part)(mem->p->client_data, chan, p, text, len); } botnet_member_part(chan, p, text, len); return(0); }
int config_save(const char *handle, const char *fname) { void *root; root = config_get_root(handle); if (root) bind_check(BT_config_save, NULL, handle, handle); if (!fname) fname = "config.xml"; if (xml_save_file(fname, root, XML_INDENT) == 0) return (0); putlog(LOG_MISC, "*", _("Failed to save config '%s': %s"), fname, xml_last_error()); return (-1); }
static int irc_on_read(void *client_data, int idx, char *data, int len) { irc_session_t *session = client_data; irc_msg_t msg; int i; irc_msg_parse(data, &msg); putlog(LOG_MISC, "ircpartylog", "%d, '%s'", msg.nargs, msg.cmd); for (i = 0; i < msg.nargs; i++) { putlog(LOG_MISC, "ircpartylog", "--> '%s'", msg.args[i]); } switch (session->state) { case STATE_PARTYLINE: bind_check(BT_ircparty, NULL, msg.cmd, session->party, idx, msg.cmd, msg.nargs, msg.args); break; case STATE_UNREGISTERED: if (!msg.cmd) break; if (!strcasecmp(msg.cmd, "nick") && msg.nargs == 1) { if (session->nick) egg_iprintf(session->idx, ":%s NICK %s\r\n", session->nick, msg.args[0]); str_redup(&session->nick, msg.args[0]); } else if (!strcasecmp(msg.cmd, "pass") && msg.nargs == 1) { str_redup(&session->pass, msg.args[0]); } else break; if (session->nick && session->pass) { session->user = user_lookup_authed(session->nick, session->pass); if (!session->user) { sockbuf_write(session->idx, ":eggdrop.bot NOTICE AUTH :*** Invalid username/password.\r\n", -1); sockbuf_delete(session->idx); break; } free(session->pass); session->pass = NULL; session->party = partymember_new(-1, session->user, NULL, session->nick, session->ident ? session->ident : "~ircparty", session->host ? session->host : session->ip, &irc_party_handler, session, &irc_pm_owner); session->state = STATE_PARTYLINE; irc_greet(session); socktimer_off(idx); partychan_join_name("*", session->party, 0); } break; } irc_msg_cleanup(&msg); return(0); }
int partymember_delete(partymember_t *p, const botnet_bot_t *lost_bot, const char *text) { int i, len; partymember_common_t *common; partymember_t *mem; if (p->flags & PARTY_DELETED) return(-1); len = strlen(text); if (!lost_bot && p->nchannels) botnet_member_quit(p, text, len); bind_check(BT_quit, NULL, p->nick, p, text); /* Mark it as deleted so it doesn't get reused before it's free. */ p->flags |= PARTY_DELETED; garbage_add(partymember_cleanup, NULL, GARBAGE_ONCE); npartymembers--; common = partychan_get_common(p); if (common) { for (i = 0; i < common->len; i++) { mem = common->members[i]; if (mem->flags & PARTY_DELETED) continue; if (mem->handler->on_quit) (mem->handler->on_quit)(mem->client_data, p, lost_bot, text, len); } partychan_free_common(common); } /* Remove from any stray channels. */ for (i = 0; i < p->nchannels; i++) { partychan_part(p->channels[i], p, text); } p->nchannels = 0; if (p->handler && p->handler->on_quit) { (p->handler->on_quit)(p->client_data, p, lost_bot, text, strlen(text)); } if (p->owner && p->owner->on_delete) p->owner->on_delete(p->owner, p->client_data); p->bot = NULL; return(0); }
partymember_t *partymember_new(int id, user_t *user, botnet_bot_t *bot, const char *nick, const char *ident, const char *host, partyline_event_t *handler, void *client_data, event_owner_t *owner) { partymember_t *mem; if (user && user->flags & USER_BOT) return NULL; mem = calloc(1, sizeof(*mem)); if (id == -1) id = partymember_get_id(bot); mem->id = id; mem->user = user; mem->bot = bot; mem->nick = strdup(nick); mem->ident = strdup(ident); mem->host = strdup(host); mem->net_name = egg_mprintf("%s@%s", b64enc_int(id), bot ? bot->name : botnet_get_name()); mem->full_id_name = egg_mprintf("%d:%s@%s", id, nick, bot ? bot->name : botnet_get_name()); mem->full_name = strchr(mem->full_id_name, ':') + 1; mem->common_name = bot ? mem->full_name : mem->nick; mem->handler = handler; mem->client_data = client_data; mem->owner = owner; mem->next = party_head; if (party_head) party_head->prev = mem; party_head = mem; mem->prev_on_bot = NULL; if (bot) { mem->next_on_bot = bot->partys; if (bot->partys) bot->partys->prev_on_bot = mem; bot->partys = mem; } else { mem->next_on_bot = local_party_head; if (local_party_head) local_party_head->prev_on_bot = mem; local_party_head = mem; } npartymembers++; botnet_announce_login(mem); bind_check(BT_new, NULL, nick, mem); return(mem); }
int partychan_join(partychan_t *chan, partymember_t *p, int linking) { partychan_member_t *mem; int i; if (!chan || !p) return(-1); /* Check to see if he's already on. We put this here just to save some * redundancy in partyline modules. */ for (i = 0; i < chan->nmembers; i++) { if (chan->members[i].flags & PARTY_DELETED) continue; if (chan->members[i].p == p) return(-1); } /* Add the member. */ chan->members = realloc(chan->members, sizeof(*chan->members) * (chan->nmembers+1)); chan->members[chan->nmembers].p = p; chan->members[chan->nmembers].flags = 0; chan->nmembers++; /* Now add the channel to the member's list. */ p->channels = realloc(p->channels, sizeof(chan) * (p->nchannels+1)); p->channels[p->nchannels] = chan; p->nchannels++; /* Trigger the partyline channel join bind. */ bind_check(BT_partyjoin, NULL, NULL, chan->name, chan->cid, p); /* Send out the join event to the members. */ for (i = 0; i < chan->nmembers; i++) { mem = chan->members+i; if (mem->flags & PARTY_DELETED || mem->p->flags & PARTY_DELETED) continue; if (mem->p->handler && mem->p->handler->on_join) (mem->p->handler->on_join)(mem->p->client_data, chan, p, linking); } botnet_member_join(chan, p, linking); return(0); }
static int chan_msg(partychan_t *chan, botnet_entity_t *src, const char *text, int len, int local) { partychan_member_t *mem; int i; if (!chan || chan->flags & PARTY_DELETED) return(-1); if (len < 0) len = strlen(text); /* Trigger the partyline channel pub bind. */ bind_check(BT_partypub, NULL, NULL, chan->name, chan->cid, src, text, len); for (i = 0; i < chan->nmembers; i++) { mem = chan->members+i; if (mem->flags & PARTY_DELETED || mem->p->flags & PARTY_DELETED) continue; if (mem->p->handler && mem->p->handler->on_chanmsg) (mem->p->handler->on_chanmsg)(mem->p->client_data, chan, src, text, len); } if (!local) botnet_chanmsg(chan, src, text, len); return(0); }
/** * @brief main The entrance of zimg. * * @param argc Count of args. * @param argv Arg list. * * @return It returns a int to system. */ int main(int argc, char **argv) { /* Set signal handlers */ sigset_t sigset; sigemptyset(&sigset); struct sigaction siginfo = { .sa_sigaction = &sighandler, .sa_mask = sigset, .sa_flags = SA_RESTART, }; sigaction(SIGINT, &siginfo, NULL); sigaction(SIGTERM, &siginfo, NULL); if (argc < 2) { usage(argc, argv); return -1; } settings_init(); int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-d") == 0) { settings.is_daemon = 1; } else { conf_file = argv[i]; } } if (conf_file == NULL) { usage(argc, argv); return -1; } if (is_file(conf_file) == -1) { fprintf(stderr, "'%s' is not a file or not exists!\n", conf_file); return -1; } if (load_conf(conf_file) == -1) { fprintf(stderr, "'%s' load failed!\n", conf_file); return -1; } if (bind_check(settings.port) == -1) { fprintf(stderr, "Port %d bind failed!\n", settings.port); return -1; } if (settings.is_daemon == 1) { if (daemon(1, 1) < 0) { fprintf(stderr, "Create daemon failed!\n"); return -1; } else { fprintf(stdout, "zimg %s\n", settings.version); fprintf(stdout, "Copyright (c) 2013-2014 zimg.buaa.us\n"); fprintf(stderr, "\n"); } } //init the Path zimg need to use. //start log module... ./log/zimg.log if (mk_dirf(settings.log_name) != 1) { fprintf(stderr, "%s log path create failed!\n", settings.log_name); return -1; } log_init(); if (settings.script_name[0] != '\0') { if (is_file(settings.script_name) == -1) { fprintf(stderr, "%s open failed!\n", settings.script_name); return -1; } settings.script_on = 1; } if (is_dir(settings.img_path) != 1) { if (mk_dirs(settings.img_path) != 1) { LOG_PRINT(LOG_DEBUG, "img_path[%s] Create Failed!", settings.img_path); fprintf(stderr, "%s Create Failed!\n", settings.img_path); return -1; } } LOG_PRINT(LOG_DEBUG, "Paths Init Finished."); if (settings.mode == 2) { LOG_PRINT(LOG_DEBUG, "Begin to Test Memcached Connection..."); memcached_st *beans = memcached_create(NULL); char mserver[32]; snprintf(mserver, 32, "%s:%d", settings.beansdb_ip, settings.beansdb_port); memcached_server_st *servers = memcached_servers_parse(mserver); servers = memcached_servers_parse(mserver); memcached_server_push(beans, servers); memcached_server_list_free(servers); memcached_behavior_set(beans, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 0); memcached_behavior_set(beans, MEMCACHED_BEHAVIOR_NO_BLOCK, 1); memcached_behavior_set(beans, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE, 1); LOG_PRINT(LOG_DEBUG, "beansdb Connection Init Finished."); if (set_cache(beans, "zimg", "1") == -1) { LOG_PRINT(LOG_DEBUG, "Beansdb[%s] Connect Failed!", mserver); fprintf(stderr, "Beansdb[%s] Connect Failed!\n", mserver); memcached_free(beans); return -1; } else { LOG_PRINT(LOG_DEBUG, "beansdb connected to: %s", mserver); } memcached_free(beans); } else if (settings.mode == 3) { redisContext* c = redisConnect(settings.ssdb_ip, settings.ssdb_port); if (c->err) { redisFree(c); LOG_PRINT(LOG_DEBUG, "Connect to ssdb server faile"); fprintf(stderr, "SSDB[%s:%d] Connect Failed!\n", settings.ssdb_ip, settings.ssdb_port); return -1; } else { LOG_PRINT(LOG_DEBUG, "Connect to ssdb server Success"); } } //init magickwand MagickCoreGenesis((char *) NULL, MagickFalse); /* ExceptionInfo *exception=AcquireExceptionInfo(); MagickInfo *jpeg_info = (MagickInfo *)GetMagickInfo("JPEG", exception); if(jpeg_info->thread_support != MagickTrue) LOG_PRINT(LOG_DEBUG, "thread_support != MagickTrue"); jpeg_info->thread_support = MagickTrue; if(jpeg_info->thread_support != MagickTrue) LOG_PRINT(LOG_DEBUG, "thread_support != MagickTrue"); MagickInfo *jpg_info = (MagickInfo *)GetMagickInfo("JPG", exception); jpg_info->thread_support = MagickTrue; */ int result = pthread_key_create(&gLuaStateKey, thread_lua_dtor); if (result != 0) { LOG_PRINT(LOG_ERROR, "Could not allocate TLS key for lua_State."); } //begin to start httpd... LOG_PRINT(LOG_DEBUG, "Begin to Start Httpd Server..."); LOG_PRINT(LOG_INFO, "zimg started"); evbase = event_base_new(); evhtp_t *htp = evhtp_new(evbase, NULL); evhtp_set_cb(htp, "/dump", dump_request_cb, NULL); evhtp_set_cb(htp, "/upload", post_request_cb, NULL); evhtp_set_cb(htp, "/admin", admin_request_cb, NULL); evhtp_set_cb(htp, "/info", info_request_cb, NULL); evhtp_set_cb(htp, "/echo", echo_cb, NULL); evhtp_set_gencb(htp, get_request_cb, NULL); #ifndef EVHTP_DISABLE_EVTHR evhtp_use_threads(htp, init_thread, settings.num_threads, NULL); #endif evhtp_set_max_keepalive_requests(htp, settings.max_keepalives); evhtp_bind_socket(htp, settings.ip, settings.port, settings.backlog); event_base_loop(evbase, 0); evhtp_unbind_socket(htp); //evhtp_free(htp); event_base_free(evbase); free_headers_conf(settings.headers); free_access_conf(settings.up_access); free_access_conf(settings.down_access); free_access_conf(settings.admin_access); free(settings.mp_set); return 0; }