/* * release_client_state * * input - pointer to client to release * output - NONE * side effects - */ static void release_client_state(struct Client* client_p) { if (client_p->user != NULL) { free_user(client_p->user, client_p); /* try this here */ } if (client_p->serv) { if (client_p->serv->user != NULL) free_user(client_p->serv->user, client_p); MyFree((char*) client_p->serv); } }
/* * Taken the code from ExitOneClient() for this and placed it here. * - avalon */ void remove_client_from_list(struct Client *cptr) { assert(cli_verify(cptr)); assert(con_verify(cli_connect(cptr))); assert(!cli_prev(cptr) || cli_verify(cli_prev(cptr))); assert(!cli_next(cptr) || cli_verify(cli_next(cptr))); assert(!IsMe(cptr)); /* Only remove from the list if it actually IS in the list. * cli_next(cptr) cannot be NULL here if cptr is in the list, * only &me is at the end, and we never try to remove &me -GW */ if(cli_next(cptr)) { if (cli_prev(cptr)) cli_next(cli_prev(cptr)) = cli_next(cptr); else { GlobalClientList = cli_next(cptr); cli_prev(GlobalClientList) = 0; } cli_prev(cli_next(cptr)) = cli_prev(cptr); } cli_next(cptr) = cli_prev(cptr) = 0; if (IsUser(cptr) && cli_user(cptr)) { add_history(cptr, 0); off_history(cptr); } if (cli_user(cptr)) { free_user(cli_user(cptr)); cli_user(cptr) = 0; } if (cli_serv(cptr)) { if (cli_serv(cptr)->user) { free_user(cli_serv(cptr)->user); cli_serv(cptr)->user = 0; } if (cli_serv(cptr)->client_list) MyFree(cli_serv(cptr)->client_list); MyFree(cli_serv(cptr)->last_error_msg); MyFree(cli_serv(cptr)); #ifdef DEBUGMODE --servs.inuse; #endif } free_client(cptr); }
int userlist_remove (struct session *sess, char *name) { struct User *user; int pos; user = userlist_find (sess, name); if (!user) return FALSE; if (user->voice) sess->voices--; if (user->op) sess->ops--; if (user->hop) sess->hops--; sess->total--; fe_userlist_numbers (sess); fe_userlist_remove (sess, user); if (user == sess->me) sess->me = NULL; tree_remove (sess->usertree, user, &pos); tree_remove (sess->usertree_alpha, user, &pos); free_user (user, NULL); return TRUE; }
static void free_args(struct isl_arg *arg, void *opt) { int i; for (i = 0; arg[i].type != isl_arg_end; ++i) { switch (arg[i].type) { case isl_arg_child: free_child(&arg[i], opt); break; case isl_arg_arg: case isl_arg_str: free(*(char **)(((char *)opt) + arg[i].offset)); break; case isl_arg_str_list: free_str_list(&arg[i], opt); break; case isl_arg_user: free_user(&arg[i], opt); break; case isl_arg_alias: case isl_arg_bool: case isl_arg_choice: case isl_arg_flags: case isl_arg_int: case isl_arg_long: case isl_arg_ulong: case isl_arg_version: case isl_arg_footer: case isl_arg_end: break; } } }
/** Remove \a cptr from lists that it is a member of. * Specifically, this delinks \a cptr from #GlobalClientList, updates * the whowas history list, frees its Client::cli_user and * Client::cli_serv fields, and finally calls free_client() on it. * @param[in] cptr Client to remove from lists and free. */ void remove_client_from_list(struct Client *cptr) { assert(cli_verify(cptr)); assert(con_verify(cli_connect(cptr))); assert(!cli_prev(cptr) || cli_verify(cli_prev(cptr))); assert(!cli_next(cptr) || cli_verify(cli_next(cptr))); assert(!IsMe(cptr)); /* Only try remove cptr from the list if it IS in the list. * cli_next(cptr) cannot be NULL here, as &me is always the end * the list, and we never remove &me. -GW */ if(cli_next(cptr)) { if (cli_prev(cptr)) cli_next(cli_prev(cptr)) = cli_next(cptr); else { GlobalClientList = cli_next(cptr); cli_prev(GlobalClientList) = 0; } cli_prev(cli_next(cptr)) = cli_prev(cptr); } cli_next(cptr) = cli_prev(cptr) = 0; if (IsUser(cptr) && cli_user(cptr)) { add_history(cptr, 0); off_history(cptr); } if (cli_user(cptr)) { free_user(cli_user(cptr)); cli_user(cptr) = 0; } if (cli_serv(cptr)) { if (cli_serv(cptr)->user) { free_user(cli_serv(cptr)->user); cli_serv(cptr)->user = 0; } if (cli_serv(cptr)->client_list) MyFree(cli_serv(cptr)->client_list); MyFree(cli_serv(cptr)->last_error_msg); MyFree(cli_serv(cptr)); --servs.inuse; --servs.alloc; } free_client(cptr); }
/* * taken the code from ExitOneClient() for this and placed it here. * - avalon * remove client **AND** _related structures_ from lists, * *free* them too. -krys */ void remove_client_from_list(aClient *cptr) { checklist(); /* is there another way, at this point? */ /* servers directly connected have hopcount=1, but so do their * users, hence the check for IsServer --B. */ if (cptr->hopcount == 0 || (cptr->hopcount == 1 && IsServer(cptr))) istat.is_localc--; else istat.is_remc--; if (cptr->prev) cptr->prev->next = cptr->next; else { client = cptr->next; client->prev = NULL; } if (cptr->next) cptr->next->prev = cptr->prev; if (cptr->user) { istat.is_users--; /* decrement reference counter, and eventually free it */ cptr->user->bcptr = NULL; (void)free_user(cptr->user); } if (cptr->serv) { cptr->serv->bcptr = NULL; free_server(cptr->serv); } if (cptr->service) /* ** has to be removed from the list of aService structures, ** no reference counter for services, thus this part of the ** code can safely be included in free_service() */ free_service(cptr); #ifdef DEBUGMODE if (cptr->fd == -2) cloc.inuse--; else crem.inuse--; #endif (void)free_client(cptr); numclients--; return; }
void free_server(aServer *serv) { aClient *cptr = serv->bcptr; /* decrement reference counter, and eventually free it */ if (--serv->refcnt <= 0) { if (serv->refcnt == -211001) { /* Loop detected, break it. * XXX: Remove loop detection before 2.11.0 - jv */ sendto_flag(SCH_DEBUG, "* %#x free_server loop %s *", serv, serv->namebuf); return; } /* Decrease (and possibly free) refcnt of the user struct * of who connected this server. */ if (serv->user) { int cnt = serv->refcnt; serv->refcnt = -211000; /* Loop detection */ free_user(serv->user); serv->user = NULL; serv->refcnt = cnt; } if (serv->refcnt < 0 || serv->prevs || serv->nexts || serv->bcptr || serv->user) { char buf[512]; sprintf(buf, "%d %p %p %p %p (%s)", serv->refcnt, (void *)serv->prevs, (void *)serv->nexts, (void *)serv->user, (void *)serv->bcptr, (serv->bcptr) ? serv->bcptr->name : "none"); #ifdef DEBUGMODE dumpcore("%#x server %s %s", cptr, cptr ? cptr->name : "<noname>", buf); servs.inuse--; #else sendto_flag(SCH_ERROR, "* %#x server %s %s *", cptr, cptr ? cptr->name : "<noname>", buf); #endif } MyFree(serv); } }
void quit_command(int index){ int connfd = p.clientfd[index]; user* u; if((u = user_table[connfd])){ send_command_to_daemon("REMOVEUSER",u->nick_name); if(u->located_channel) part_command(connfd,u->located_channel->name,0); free_user(u); user_table[connfd] = NULL; } close(connfd); FD_CLR(connfd, &p.read_set); p.clientfd[index] = -1; }
void userdel(char* argv) { char* firstSpace = strchr(argv, ' '); struct User* user; if (firstSpace == NULL) { printf("Usage: userdel LOGIN\n"); } else if ((user = get_user_by_name(firstSpace + 1)) == NULL) { printf("userdel: user '%s' does not exists.\n", firstSpace + 1) ; } else { delete_group_member(user->gid[0], user->id); delete_user(firstSpace + 1); free_user(user); printf("Successfully deleted user account.\n"); } }
void userlist_remove_user (struct session *sess, struct User *user) { int pos; if (user->voice) sess->voices--; if (user->op) sess->ops--; if (user->hop) sess->hops--; sess->total--; fe_userlist_numbers (sess); fe_userlist_remove (sess, user); if (user == sess->me) sess->me = NULL; tree_remove (sess->usertree, user, &pos); free_user (user, NULL); }
/** Free the users array. */ void free_users(gboolean reset) { #ifdef DEBUG printf("free_users\n"); #endif gint i; if(users == NULL) { if(reset) users = g_array_new(FALSE, FALSE, sizeof(User)); return; } for(i=0; i<users->len; i++) free_user(&usr(i)); free_g_array(&users); if(reset) users = g_array_new(FALSE, FALSE, sizeof(User)); }
int main(int argc, char **argv) { // time the program struct timeval sysTimeStart, sysTimeEnd; gettimeofday(&sysTimeStart, NULL); mkdir("bplus", 0777); int i; // open file count information file_count_t *fc = read_file_count(); // keep track of roots bplus_roots_t bpr; // users { printf("\n"); printf("Making user B+ tree with %d users\n", fc->users); // time this section struct timeval startSysTimeSub, endSysTimeSub; gettimeofday(&startSysTimeSub, NULL); // create root int_node_t root; root.next = -1; root.previous = -1; root.tableType = TABLE_TYPE_USER; root.nodeType = NODE_TYPE_LEAF; root.count = 0; root.firstFile = -1; write_node(0, &root); int rootFileNum = 0; for (i = 0; i < fc->users; i++) { user_t *user = read_user(i); rootFileNum = insert_node(rootFileNum, TABLE_TYPE_USER, user->stateId, i); free_user(user); } bpr.user = rootFileNum; // end timing this section gettimeofday(&endSysTimeSub, NULL); float totalTime = (endSysTimeSub.tv_sec - startSysTimeSub.tv_sec) + (endSysTimeSub.tv_usec - startSysTimeSub.tv_usec) / 1000000.0f; printf("B+ tree creation time: %f seconds\n", totalTime); } // cities { printf("\n"); printf("Making city B+ tree with %d cities\n", fc->cities); // time this section struct timeval startSysTimeSub, endSysTimeSub; gettimeofday(&startSysTimeSub, NULL); // create root int_node_t root; root.next = -1; root.previous = -1; root.tableType = TABLE_TYPE_CITY; root.nodeType = NODE_TYPE_LEAF; root.count = 0; root.firstFile = -1; write_node(0, &root); int rootFileNum = 0; for (i = 0; i < fc->cities; i++) { city_t *city = read_city(i); rootFileNum = insert_node(rootFileNum, TABLE_TYPE_CITY, city->stateId, i); free_city(city); } bpr.city = rootFileNum; // end timing this section gettimeofday(&endSysTimeSub, NULL); float totalTime = (endSysTimeSub.tv_sec - startSysTimeSub.tv_sec) + (endSysTimeSub.tv_usec - startSysTimeSub.tv_usec) / 1000000.0f; printf("B+ tree creation time: %f seconds\n", totalTime); } //states { printf("\n"); printf("Making state B+ tree with %d states\n", fc->states); // time this section struct timeval startSysTimeSub, endSysTimeSub; gettimeofday(&startSysTimeSub, NULL); // create root int_node_t root; root.next = -1; root.previous = -1; root.tableType = TABLE_TYPE_STATE; root.nodeType = NODE_TYPE_LEAF; root.count = 0; root.firstFile = -1; write_node(0, &root); int rootFileNum = 0; for (i = 0; i < fc->states; i++) { state_t *state = read_state(i); rootFileNum = insert_node(rootFileNum, TABLE_TYPE_STATE, (int) hash_state(state), i); free_state(state); } bpr.state = rootFileNum; // end timing this section gettimeofday(&endSysTimeSub, NULL); float totalTime = (endSysTimeSub.tv_sec - startSysTimeSub.tv_sec) + (endSysTimeSub.tv_usec - startSysTimeSub.tv_usec) / 1000000.0f; printf("B+ tree creation time: %f seconds\n", totalTime); } // messages { printf("\n"); printf("Making message B+ tree with %d messages\n", fc->messages); // time this section struct timeval startSysTimeSub, endSysTimeSub; gettimeofday(&startSysTimeSub, NULL); // create root int_node_t root; root.next = -1; root.previous = -1; root.tableType = TABLE_TYPE_MESSAGE; root.nodeType = NODE_TYPE_LEAF; root.count = 0; root.firstFile = -1; write_node(0, &root); int rootFileNum = 0; for (i = 0; i < fc->messages; i++) { message_t *message = read_message(i); rootFileNum = insert_node(rootFileNum, TABLE_TYPE_MESSAGE, message->timestampId, i); free_message(message); } bpr.message = rootFileNum; // end timing this section gettimeofday(&endSysTimeSub, NULL); float totalTime = (endSysTimeSub.tv_sec - startSysTimeSub.tv_sec) + (endSysTimeSub.tv_usec - startSysTimeSub.tv_usec) / 1000000.0f; printf("B+ tree creation time: %f seconds\n", totalTime); } // timestamps { printf("\n"); printf("Making timestamp B+ tree with %d timestamps\n", fc->timestamps); // time this section struct timeval startSysTimeSub, endSysTimeSub; gettimeofday(&startSysTimeSub, NULL); // create root int_node_t root; root.next = -1; root.previous = -1; root.tableType = TABLE_TYPE_TIMESTAMP; root.nodeType = NODE_TYPE_LEAF; root.count = 0; root.firstFile = -1; write_node(0, &root); int rootFileNum = 0; for (i = 0; i < fc->timestamps; i++) { timestamp_t *timestamp = read_timestamp(i); rootFileNum = insert_node(rootFileNum, TABLE_TYPE_TIMESTAMP, (int) hash_timestamp(timestamp), i); free_timestamp(timestamp); } bpr.timestamp = rootFileNum; // end timing this section gettimeofday(&endSysTimeSub, NULL); float totalTime = (endSysTimeSub.tv_sec - startSysTimeSub.tv_sec) + (endSysTimeSub.tv_usec - startSysTimeSub.tv_usec) / 1000000.0f; printf("B+ tree creation time: %f seconds\n", totalTime); } // datestamps { printf("\n"); printf("Making datestamp B+ tree with %d datestamps\n", fc->datestamps); // time this section struct timeval startSysTimeSub, endSysTimeSub; gettimeofday(&startSysTimeSub, NULL); // create root int_node_t root; root.next = -1; root.previous = -1; root.tableType = TABLE_TYPE_DATESTAMP; root.nodeType = NODE_TYPE_LEAF; root.count = 0; root.firstFile = -1; write_node(0, &root); int rootFileNum = 0; for (i = 0; i < fc->datestamps; i++) { datestamp_t *datestamp = read_datestamp(i); rootFileNum = insert_node(rootFileNum, TABLE_TYPE_DATESTAMP, (int) hash_datestamp(datestamp), i); free_datestamp(datestamp); } bpr.datestamp = rootFileNum; // end timing this section gettimeofday(&endSysTimeSub, NULL); float totalTime = (endSysTimeSub.tv_sec - startSysTimeSub.tv_sec) + (endSysTimeSub.tv_usec - startSysTimeSub.tv_usec) / 1000000.0f; printf("B+ tree creation time: %f seconds\n", totalTime); } free_file_count(fc); printf("\n"); print_bplus_roots(&bpr); write_bplus_roots(&bpr); // end timing the program gettimeofday(&sysTimeEnd, NULL); float totalTime = (sysTimeEnd.tv_sec - sysTimeStart.tv_sec) + (sysTimeEnd.tv_usec - sysTimeStart.tv_usec) / 1000000.0f; printf("Process time %f seconds\n", totalTime); return 0; }
/* ** add_history ** Add the currently defined name of the client to history. ** usually called before changing to a new name (nick). ** Client must be a fully registered user (specifically, ** the user structure must have been allocated). ** if nodelay is NULL, then the nickname will be subject to NickDelay */ void add_history(aClient *cptr, aClient *nodelay) { Reg aName *np; Reg Link *uwas; cptr->user->refcnt++; np = &was[ww_index]; if ((np->ww_online && (np->ww_online != &me)) && !(np->ww_user && np->ww_user->uwas)) #ifdef DEBUGMODE dumpcore("whowas[%d] %#x %#x %#x", ww_index, np->ww_online, np->ww_user, np->ww_user->uwas); #else sendto_flag(SCH_ERROR, "whowas[%d] %#x %#x %#x", ww_index, np->ww_online, np->ww_user, np->ww_user->uwas); #endif /* ** The entry to be overwritten in was[] is still online. ** its uwas has to be updated */ if (np->ww_online && (np->ww_online != &me)) { Reg Link **old_uwas; old_uwas = &(np->ww_user->uwas); /* (*old_uwas) should NEVER happen to be NULL. -krys */ while ((*old_uwas)->value.i != ww_index) old_uwas = &((*old_uwas)->next); uwas = *old_uwas; *old_uwas = uwas->next; free_link(uwas); free_user(np->ww_user); istat.is_wwuwas--; } else if (np->ww_user) { /* ** Testing refcnt here is quite ugly, and unexact. ** Nonetheless, the result is almost correct, and another ** ugly thing in free_server() shoud make it exact. ** The problem is that 1 anUser structure might be ** referenced several times from whowas[] but is only counted ** once. One knows when to add, not when to substract - krys */ if (np->ww_user->refcnt == 1) { istat.is_wwusers--; if (np->ww_user->away) { istat.is_wwaways--; istat.is_wwawaysmem -=strlen(np->ww_user->away) + 1; } } free_user(np->ww_user); } if (np->ww_logout != 0) { int elapsed = timeofday - np->ww_logout; /* some stats */ ircstp->is_wwcnt++; ircstp->is_wwt += elapsed; if (elapsed < ircstp->is_wwmt) ircstp->is_wwmt = elapsed; if (elapsed > ircstp->is_wwMt) ircstp->is_wwMt = elapsed; if (np->ww_online == NULL) { if (locked[lk_index].logout) { elapsed = timeofday - locked[lk_index].logout; /* some stats first */ ircstp->is_lkcnt++; ircstp->is_lkt += elapsed; if (elapsed < ircstp->is_lkmt) ircstp->is_lkmt = elapsed; if (elapsed > ircstp->is_lkMt) ircstp->is_lkMt = elapsed; } /* ** This nickname has to be locked, thus copy it to the ** lock[] array. */ strcpy(locked[lk_index].nick, np->ww_nick); locked[lk_index++].logout = np->ww_logout; if ((lk_index == lk_size) && (lk_size != ww_size)) { grow_locked(); } if (lk_index >= lk_size) lk_index = 0; } } if (nodelay == cptr) /* &me is NOT a valid value, see off_history() */ { /* ** The client is online, np->ww_online is going to point to ** it. The client user struct has to point to this entry ** as well for faster off_history() ** this uwas, and the ww_online form a pair. */ uwas = make_link(); istat.is_wwuwas++; /* ** because of reallocs, one can not store a pointer inside ** the array. store the index instead. */ uwas->value.i = ww_index; uwas->flags = timeofday; uwas->next = cptr->user->uwas; cptr->user->uwas = uwas; } np->ww_logout = timeofday; np->ww_user = cptr->user; np->ww_online = (nodelay != NULL) ? nodelay : NULL; strncpyzt(np->ww_nick, cptr->name, NICKLEN+1); strncpyzt(np->ww_info, cptr->info, REALLEN+1); ww_index++; if ((ww_index == ww_size) && (numclients > ww_size)) grow_whowas(); if (ww_index >= ww_size) ww_index = 0; return; }
int main(int argc, char **argv) { // time the program struct timeval sysTimeStart, sysTimeEnd; gettimeofday(&sysTimeStart, NULL); // counters, etc. int first, mid, last, i, nebraskaUserCount = 0, nebraskaStateId; char nebraskaStr[] = "Nebraska"; // get file counts file_count_t *fc = read_file_count(); int userCount = fc->users; int stateCount = fc->states; free_file_count(fc); // binary search states to get Nebraska's ID first = 0; last = stateCount - 1; nebraskaStateId = -1; while (first <= last && nebraskaStateId == -1) { mid = (first + last) / 2; state_t *state = read_state(mid); if (strcmp(state->name, nebraskaStr) == 0) { nebraskaStateId = state->stateId; } else if (strcmp(state->name, nebraskaStr) < 0) { first = mid + 1; } else { last = mid - 1; } free_state(state); } // note, if we didn't find Nebraska, nebraskaStateId = -1 first = 0; last = userCount - 1; while(first <= last) { mid = (first + last) / 2; user_t *user = read_user(mid); if (user->stateId == nebraskaStateId) { nebraskaUserCount++; last = first - 1; } else if(user->stateId < nebraskaStateId) { first = mid + 1; } else { last = mid - 1; } free_user(user); } for(i = mid + 1; i < userCount; i++) { user_t *user = read_user(i); if (user->stateId == nebraskaStateId) { nebraskaUserCount++; } else { i = userCount; } free_user(user); } for(i = mid - 1; i >= 0; i--) { user_t *user = read_user(i); if (user->stateId == nebraskaStateId) { nebraskaUserCount++; } else { i = -1; } free_user(user); } printf("Found %d users from %s (state id %d)\n", nebraskaUserCount, nebraskaStr, nebraskaStateId); // end timing the program gettimeofday(&sysTimeEnd, NULL); float totalTime = (sysTimeEnd.tv_sec - sysTimeStart.tv_sec) + (sysTimeEnd.tv_usec - sysTimeStart.tv_usec) / 1000000.0f; printf("Process time %f seconds\n", totalTime); return 0; }
user * load_user(int crontab_fd, struct passwd *pw, const char *name) { char envstr[MAX_ENVSTR]; FILE *file; user *u; entry *e; int status, save_errno; char **envp, **tenvp; if (!(file = fdopen(crontab_fd, "r"))) { perror("fdopen on crontab_fd in load_user"); return (NULL); } Debug(DPARS, ("load_user()\n")) /* file is open. build user entry, then read the crontab file. */ if ((u = (user *) malloc(sizeof(user))) == NULL) return (NULL); if ((u->name = strdup(name)) == NULL) { save_errno = errno; free(u); errno = save_errno; return (NULL); } u->crontab = NULL; /* init environment. this will be copied/augmented for each entry. */ if ((envp = env_init()) == NULL) { save_errno = errno; free(u->name); free(u); errno = save_errno; return (NULL); } /* load the crontab */ while ((status = load_env(envstr, file)) >= OK) { switch (status) { case ERR: free_user(u); u = NULL; goto done; case FALSE: e = load_entry(file, NULL, pw, envp); if (e) { e->next = u->crontab; u->crontab = e; } break; case TRUE: if ((tenvp = env_set(envp, envstr)) == NULL) { save_errno = errno; free_user(u); u = NULL; errno = save_errno; goto done; } envp = tenvp; break; } } done: env_free(envp); fclose(file); Debug(DPARS, ("...load_user() done\n")) return (u); }
void User_Data_Tools::savedata(std::string filename,bool allatonce) { #ifdef userlist_use_simple struct user_list * m_users; m_users = user_list_head; #endif struct user_data * u_data; void *t_module_data[MAX_MODULES]; int i; FILE *myfile; ng_slogdebug_spam(log_str,"saving ...."); #ifndef userlist_use_simple bool was_reset = false; if (allatonce && save_in_progress) { ng_slogerror(log_str,"save was in progress but no progress save was requested -> cleanup"); save_in_progress = false; fclose(save_file); was_reset = true; } if (!save_in_progress) { ng_slogdebug_spam(log_str,"enter new save"); if (!filename.length()) { ng_slogerror(log_str,0,"can not save - got emtpy filename"); return; } if (!allatonce) { ng_slogdebug_spam(log_str,"save junk steps %d",savejunk); } if (!was_reset) { string rename_file = filename; rename_file.append(".old"); if (rename(filename.c_str(), rename_file.c_str())) { ng_slogerror(log_str,0,"rename accounting data from %s to %s",filename.c_str(),rename_file.c_str()); } } ng_slogext(log_str,2000,"saving users to %s",filename.c_str()); myfile = fopen(filename.c_str(), "w+"); if (!myfile) { ng_slogerror(log_str,0,"can not save users to %s",filename.c_str()); return; } fwrite(ACC_DATA_VERSION_MAGIC,strlen(ACC_DATA_VERSION_MAGIC),1,myfile); save_index = 0; save_file = myfile; save_index_data = get_list_idx(); } else { if (!save_index) { save_index_data.clear(); save_in_progress = false; fclose(save_file); ng_slogerror(log_str,0,"resume old saving .... save_index is zero"); return; } myfile = save_file; ng_slogdebug_spam(log_str,"resume old saving ....at %d",save_index); } save_in_progress = true; #endif #ifdef userlist_use_simple while (m_users != NULL) { u_data = m_users->data; #else ip_storage_hash::iterator it; it = user_index.begin(); int counter = 0; if (save_index) { for (; it != user_index.end(); it++) { if (save_index > counter) { counter++; } else { ng_slogdebug_spam(log_str,"skipped users on save resume - position %d",counter); break; } } } for (; it != user_index.end(); it++) { u_data = (*it).second; #endif counter++; //backup module data addr //memcpy(&u_data->module_data,t_module_data, MAX_MODULES * sizeof(void *)); for(i=0; i<MAX_MODULES; i++) t_module_data[i] = u_data->module_data[i]; memset(&u_data->module_data,0,MAX_MODULES * sizeof(void *)); fwrite(u_data,sizeof(struct user_data),1, myfile); //restore module data addr //memcpy(t_module_data, u_data->module_data, MAX_MODULES * sizeof(void *)); for(i=0; i<MAX_MODULES; i++) u_data->module_data[i] = t_module_data[i]; #ifdef userlist_use_simple m_users = m_users->next; #else if (!allatonce) { //did we save savejunk items and are more then 10% of savejunk away from the end ? lets have a break if ((counter-save_index >= savejunk) && (user_index.size() >= counter + round(savejunk*0.1) ) ) { ng_slogdebug_spam(log_str,"break save loop - on counter %d",counter); //save_index = counter; //done later now break; } } #endif } #ifndef userlist_use_simple if (!allatonce && (counter-save_index > savejunk)) ng_slogdebug_spam(log_str,"extented junk size - saved %d users this run",counter-save_index); #endif if (it == user_index.end()) { ng_slogdebug_spam(log_str,"saved %d users",counter); #ifndef userlist_use_simple save_in_progress = false; save_index = 0; save_index_data.clear(); save_file = NULL; #endif fwrite(ACC_DATA_VERSION_MAGIC,strlen(ACC_DATA_VERSION_MAGIC),1,myfile); fclose(myfile); } else { #ifndef userlist_use_simple save_index = counter; ng_slogdebug_spam(log_str,"pause saving on %d",save_index); #endif } } void User_Data_Tools::list_clear() { ng_slogdebug_spam(log_str,"clearing user list"); #ifdef userlist_use_simple user_list *p, *q; p = user_list_head; while ( p != NULL ) { q = p->next; free_user((struct user_data*)p->data); free(p); p = q; } user_list_head = NULL; #else ip_storage_hash::iterator it; for (it=user_index.begin(); it != user_index.end(); it++) { free_user((*it).second); //TODO does STD lib really free it ?! //delete (*it).first; } user_index.clear(); #endif ng_slogdebug_spam(log_str,"cleared user list"); }
void load_database(cron_db *old_db) { struct stat spool_stat, syscron_stat, crond_stat; cron_db new_db; user *u, *nu; time_t new_mtime; Debug(DLOAD, ("[%ld] load_database()\n", (long)getpid())); /* before we start loading any data, do a stat on SPOOL_DIR * so that if anything changes as of this moment (i.e., before we've * cached any of the database), we'll see the changes next time. */ if (stat(SPOOL_DIR, &spool_stat) < OK) { log_it("CRON", getpid(), "STAT FAILED", SPOOL_DIR); (void) exit(ERROR_EXIT); } /* track system crontab directory */ if (stat(CROND_DIR, &crond_stat) < OK) crond_stat.st_mtime = 0; /* track system crontab file */ if (stat(SYSCRONTAB, &syscron_stat) < OK) syscron_stat.st_mtime = 0; /* if spooldir's mtime has not changed, we don't need to fiddle with * the database. * * Note that old_db->mtime is initialized to 0 in main(), and * so is guaranteed to be different than the stat() mtime the first * time this function is called. */ new_mtime = TMAX(crond_stat.st_mtime, TMAX(spool_stat.st_mtime, syscron_stat.st_mtime)); if (old_db->mtime == new_mtime) { Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", (long)getpid())); return; } /* something's different. make a new database, moving unchanged * elements from the old database, reloading elements that have * actually changed. Whatever is left in the old database when * we're done is chaff -- crontabs that disappeared. */ new_db.mtime = new_mtime; new_db.head = new_db.tail = NULL; if (syscron_stat.st_mtime) process_crontab("root", NULL, SYSCRONTAB, &syscron_stat, &new_db, old_db); if (crond_stat.st_mtime) process_dir(CROND_DIR, &crond_stat, 1, &new_db, old_db); process_dir(SPOOL_DIR, &spool_stat, 0, &new_db, old_db); /* if we don't do this, then when our children eventually call * getpwnam() in do_command.c's child_process to verify MAILTO=, * they will screw us up (and v-v). */ endpwent(); /* whatever's left in the old database is now junk. */ Debug(DLOAD, ("unlinking old database:\n")); for (u = old_db->head; u != NULL; u = nu) { Debug(DLOAD, ("\t%s\n", u->name)); nu = u->next; unlink_user(old_db, u); free_user(u); } /* overwrite the database control block with the new one. */ *old_db = new_db; Debug(DLOAD, ("load_database is done\n")); }
static void process_crontab(const char *uname, const char *fname, const char *tabname, struct stat *statbuf, cron_db *new_db, cron_db *old_db) { struct passwd *pw = NULL; int crontab_fd = OK - 1; mode_t eqmode = 0400, badmode = 0; user *u; if (fname == NULL) { /* * SYSCRONTAB: * set fname to something for logging purposes. * Allow it to become readable by group and others, but * not writable. */ fname = "*system*"; eqmode = 0; badmode = 022; } else if ((pw = getpwnam(uname)) == NULL) { /* file doesn't have a user in passwd file. */ log_it(fname, getpid(), "ORPHAN", "no passwd entry"); goto next_crontab; } if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < OK) { /* crontab not accessible? */ log_it(fname, getpid(), "CAN'T OPEN", tabname); goto next_crontab; } if (fstat(crontab_fd, statbuf) < OK) { log_it(fname, getpid(), "FSTAT FAILED", tabname); goto next_crontab; } if (!S_ISREG(statbuf->st_mode)) { log_it(fname, getpid(), "NOT REGULAR", tabname); goto next_crontab; } if ((eqmode && (statbuf->st_mode & 07577) != eqmode) || (badmode && (statbuf->st_mode & badmode) != 0)) { log_it(fname, getpid(), "BAD FILE MODE", tabname); goto next_crontab; } if (statbuf->st_uid != ROOT_UID && (pw == NULL || statbuf->st_uid != pw->pw_uid || strcmp(uname, pw->pw_name) != 0)) { log_it(fname, getpid(), "WRONG FILE OWNER", tabname); goto next_crontab; } if (statbuf->st_nlink != 1) { log_it(fname, getpid(), "BAD LINK COUNT", tabname); goto next_crontab; } Debug(DLOAD, ("\t%s:", fname)); u = find_user(old_db, fname); if (u != NULL) { /* if crontab has not changed since we last read it * in, then we can just use our existing entry. */ if (u->mtime == statbuf->st_mtime) { Debug(DLOAD, (" [no change, using old data]")); unlink_user(old_db, u); link_user(new_db, u); goto next_crontab; } /* before we fall through to the code that will reload * the user, let's deallocate and unlink the user in * the old database. This is more a point of memory * efficiency than anything else, since all leftover * users will be deleted from the old database when * we finish with the crontab... */ Debug(DLOAD, (" [delete old data]")); unlink_user(old_db, u); free_user(u); log_it(fname, getpid(), "RELOAD", tabname); } u = load_user(crontab_fd, pw, fname); if (u != NULL) { u->mtime = statbuf->st_mtime; link_user(new_db, u); } next_crontab: if (crontab_fd >= OK) { Debug(DLOAD, (" [done]\n")); (void)close(crontab_fd); } }
/* * m_webirc * parv[0] = sender prefix * parv[1] = password that authenticates the WEBIRC command from this client * parv[2] = username or client requesting spoof (cgiirc defaults to cgiirc) * parv[3] = hostname of user * parv[4] = IP address of user */ int m_webirc(aClient *cptr, aClient *sptr, int parc, char *parv[]) { char oldusername[USERLEN + 1]; struct userBan *ban; int i; if (parc < 5 || *parv[1] == '\0' || *parv[2] == '\0' || *parv[3] == '\0' || *parv[4] == '\0') { sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "WEBIRC"); return 0; } if (!MyConnect(sptr) || !IsUnknown(cptr) || cptr->receiveM != 1) { sendto_one(sptr, err_str(ERR_ALREADYREGISTRED), me.name, parv[0]); return 0; } strncpyzt(oldusername, cptr->username, USERLEN + 1); make_user(cptr); if (!(cptr->flags & FLAGS_GOTID)) strcpy(cptr->username, "webirc"); i = attach_Iline(cptr, cptr->hostp, cptr->sockhost); if (i == 0) { aAllow *pwaconf = sptr->user->allow; if (BadPtr(pwaconf->passwd) || strncmp(pwaconf->passwd, "webirc.", strlen("webirc.")) != 0) { sendto_one(sptr, "NOTICE * :Not a CGI:IRC auth block"); i = -1; } else if (!StrEq(parv[1], pwaconf->passwd + strlen("webirc."))) { sendto_one(sptr, "NOTICE * :CGI:IRC password incorrect"); i = -1; } else if (pwaconf->flags & CONF_FLAGS_NOTHROTTLE) throttle_remove(cptr->sockhost); } clear_conflinks(cptr); free_user(cptr->user, cptr); cptr->user = NULL; cptr->flags &= ~FLAGS_DOID; strncpyzt(cptr->username, oldusername, USERLEN + 1); if (i != 0) return 0; if (inet_pton(AF_INET, parv[4], &cptr->ip.ip4)) cptr->ip_family = AF_INET; else if (inet_pton(AF_INET6, parv[4], &cptr->ip.ip6)) cptr->ip_family = AF_INET6; else { sendto_one(sptr, "NOTICE * :Invalid IP"); return 0; } if (cptr->flags & FLAGS_GOTID) { cptr->webirc_username = MyMalloc(strlen(cptr->username) + 1); strcpy(cptr->webirc_username, cptr->username); } else { cptr->webirc_username = MyMalloc(strlen(parv[2]) + 1); strcpy(cptr->webirc_username, parv[2]); } cptr->webirc_ip = MyMalloc(strlen(cptr->sockhost) + 1); strcpy(cptr->webirc_ip, cptr->sockhost); get_sockhost(cptr, parv[3]); cptr->hostp = NULL; /* * Acknowledge that WEBIRC was accepted, and flush the client's send queue * to make debugging easier. */ sendto_one(sptr, ":%s NOTICE AUTH :*** CGI:IRC host/IP set to %s %s", me.name, cptr->sockhost, parv[4]); dump_connections(cptr->fd); /* if they are throttled, drop them silently. */ if (throttle_check(parv[4], cptr->fd, NOW) == 0) { cptr->flags |= FLAGS_DEADSOCKET; ircstp->is_ref++; ircstp->is_throt++; return exit_client(cptr, sptr, &me, "Client throttled"); } ban = check_userbanned(cptr, UBAN_IP|UBAN_CIDR4|UBAN_WILDUSER, 0); if(ban) { int loc = (ban->flags & UBAN_LOCAL) ? 1 : 0; ircstp->is_ref++; ircstp->is_ref_2++; return exit_banned_client(cptr, loc, loc ? 'K' : 'A', ban->reason, 0); } return 0; }