/** delete suggestions from the board **/ void delete_suggestions(UR_OBJECT user) { int cnt; set_crash(); if (word_count<2) { write_user(user,"Pouzitie: dsug all\n"); write_user(user," dsug <#>\n"); write_user(user," dsug to <#>\n"); write_user(user," dsug from <#> to <#>\n"); return; } if (get_wipe_parameters(user)==-1) return; if (!amsys->suggestion_count) { write_user(user,"There are no suggestions to delete.\n"); return; } if (user->wipe_from==-1) { unlink(SUGBOARD); write_user(user,"All suggestions deleted.\n"); write_syslog(SYSLOG,1,"%s wiped all suggestions from the suggestions board\n",user->name); amsys->suggestion_count=0; return; } if (user->wipe_from>amsys->suggestion_count) { vwrite_user(user,"There %s only %d suggestion%s on the board.\n",PLTEXT_IS(amsys->suggestion_count),amsys->suggestion_count,PLTEXT_S(amsys->suggestion_count)); return; } cnt=wipe_messages(SUGBOARD, user->wipe_from,user->wipe_to,0); if (cnt==amsys->suggestion_count) { unlink(SUGBOARD); vwrite_user(user,"There %s only %d suggestion%s on the board, all now deleted.\n",PLTEXT_WAS(cnt),cnt,PLTEXT_S(cnt)); write_syslog(SYSLOG,1,"%s wiped all suggestions from the suggestions board\n",user->name); amsys->suggestion_count=0; return; } amsys->suggestion_count-=cnt; vwrite_user(user,"%d suggestion%s deleted.\n",cnt,PLTEXT_S(cnt)); write_syslog(SYSLOG,1,"%s wiped %d suggestion%s from the suggestions board\n",user->name,cnt,PLTEXT_S(cnt)); }
/* * Show all clones on the system */ void allclones(UR_OBJECT user) { UR_OBJECT u; int cnt; cnt = 0; for (u = user_first; u; u = u->next) { if (u->type != CLONE_TYPE) { continue; } if (!cnt++) { vwrite_user(user, "\n~BB*** Current clones %s ***\n\n", long_date(1)); } vwrite_user(user, "%-15s : %s\n", u->name, u->room->name); } if (!cnt) { write_user(user, "There are no clones on the system.\n"); } else { vwrite_user(user, "\nTotal of ~OL%d~RS clone%s.\n\n", cnt, PLTEXT_S(cnt)); } }
/* Check if a normal user can remove a message */ int check_board_wipe(UR_OBJECT user) { FILE *fp; int valid,cnt,msg_number,yes,pt; char w1[ARR_SIZE],w2[ARR_SIZE],line[ARR_SIZE],line2[ARR_SIZE],fname[FNAME_LEN],id[ARR_SIZE],rmname[ROOM_NAME_LEN+1]; RM_OBJECT rm; set_crash(); if (word_count<2) { write_usage(user,"wipe <message #>"); return 0; } rm=user->room; if (!rm->mesg_cnt) { write_user(user, no_message_prompt); return 0; } msg_number=atoi(word[1]); if (!msg_number) { write_usage(user,"wipe <#>"); return 0; } if (msg_number>rm->mesg_cnt) { vwrite_user(user,"There %s only %d message%s on the board.\n", PLTEXT_IS(rm->mesg_cnt),rm->mesg_cnt,PLTEXT_S(rm->mesg_cnt)); return 0; } if (rm->access==PERSONAL_LOCKED || rm->access==PERSONAL_UNLOCKED) { midcpy(rm->name,rmname,1,strlen(rm->name)-2); rmname[0]=toupper(rmname[0]); sprintf(fname,"%s/%s.B", USERROOMS,rmname); } else sprintf(fname,"%s/%s.B", ROOMFILES, rm->name); if (!(fp=fopen(fname,"r"))) { write_user(user,"There was an error trying to read message board.\n"); write_syslog(ERRLOG,1,"Unable to open message board for %s in check_board_wipe().\n",rm->name); return 0; } valid=1; cnt=1; yes=0; id[0]='\0'; w1[0]='\0'; w2[0]='\0'; fgets(line,ARR_SIZE-1,fp); while(!feof(fp)) { if (*line=='\n') valid=1; sscanf(line,"%s %d",id,&pt); if (valid && !strcmp(id,"PT:")) { line2[0]='\0'; strcpy(line2,remove_first(remove_first(line))); sscanf(line2,"%s %s",w1,w2); if (msg_number==cnt) { /* lower case the name incase of recapping */ strtolower(w2); w2[0]=toupper(w2[0]); if (!strcmp(w2,user->name)) { yes=1; goto SKIP; /* found result, no need to go through rest of file */ } } valid=0; cnt++; if (cnt>msg_number) goto SKIP; /* no point carrying on if checked already */ } fgets(line,ARR_SIZE-1,fp); } SKIP: fclose(fp); if (!yes) { write_user(user,"You did not post that message. Use ~FTbfrom~RS to check the number again.\n"); return 0; } user->wipe_from=msg_number; user->wipe_to=msg_number; return 1; }
/* Allows a user to read a specific message number */ void read_board_specific(UR_OBJECT user, RM_OBJECT rm, int msg_number) { FILE *fp; int valid,cnt,pt; char id[ARR_SIZE],line[ARR_SIZE],fname[FNAME_LEN],*name,rmname[ROOM_NAME_LEN+1]; set_crash(); if (!rm->mesg_cnt) { vwrite_user(user, read_no_messages, rm->name); return; } if (!msg_number) { write_usage(user,"read [<room>] [<message #>]"); return; } if (msg_number>rm->mesg_cnt) { vwrite_user(user,"There %s only %d message%s posted on the %s board.\n",PLTEXT_IS(rm->mesg_cnt),rm->mesg_cnt,PLTEXT_S(rm->mesg_cnt),rm->name); return; } if (rm!=user->room && !has_room_access(user,rm)) { write_user(user,"That room is currently private, you cannot read the board.\n"); return; } if (rm->access==PERSONAL_LOCKED || rm->access==PERSONAL_UNLOCKED) { midcpy(rm->name,rmname,1,strlen(rm->name)-2); rmname[0]=toupper(rmname[0]); sprintf(fname,"%s/%s.B", USERROOMS,rmname); } else sprintf(fname,"%s/%s.B", ROOMFILES, rm->name); if (!(fp=fopen(fname,"r"))) { write_user(user,"There was an error trying to read the message board.\n"); write_syslog(ERRLOG,1,"Unable to open message board for %s in read_board_specific().\n",rm->name); return; } vwrite_user(user, message_board_header, rm->name); valid=1; cnt=1; id[0]='\0'; fgets(line,ARR_SIZE-1,fp); while (!feof(fp)) { if (*line=='\n') valid=1; sscanf(line,"%s %d",id,&pt); if (valid && !strcmp(id,"PT:")) { if (msg_number==cnt) { while(*line!='\n') { write_user(user,line); fgets(line,ARR_SIZE-1,fp); } } valid=0; cnt++; if (cnt>msg_number) goto SKIP; /* no point carrying on if read already */ } fgets(line,ARR_SIZE-1,fp); } SKIP: fclose(fp); vwrite_user(user,"\nMessage number ~FM~OL%d~RS out of ~FM~OL%d~RS.\n\n",msg_number,rm->mesg_cnt); if (user->vis) name=user->recap; else name=invisname; if (rm==user->room) if (user->level<GOD || user->vis) vwrite_room_except(user->room,user,"%s~RS reads the message board.\n",name); }
/*** Remove any expired messages from boards unless force = 2 in which case just do a recount. ***/ void check_messages(UR_OBJECT user, int chforce) { RM_OBJECT rm; FILE *infp=NULL,*outfp=NULL; char id[182],fname[FNAME_LEN],line[82],rmname[ROOM_NAME_LEN+1]; int valid,pt,write_rest; int board_cnt,old_cnt,bad_cnt,tmp; static int done=0; set_crash(); switch (chforce) { case 0: if (amsys->mesg_check_hour==thour && amsys->mesg_check_min==tmin) { if (done) return; } else { done=0; return; } break; case 1: printf("Checking boards...\n"); case 2: if (word_count>=2) { strtolower(word[1]); if (strcmp(word[1],"motds")) { write_usage(user,"recount [motds]"); return; } if (!count_motds(1)) { write_user(user,"Sorry, could not recount the motds at this time.\n"); write_syslog(ERRLOG,1,"Could not recount motds in check_messages().\n"); return; } vwrite_user(user,"There %s %d login motd%s and %d post-login motd%s\n",PLTEXT_WAS(amsys->motd1_cnt),amsys->motd1_cnt,PLTEXT_S(amsys->motd1_cnt),amsys->motd2_cnt,PLTEXT_S(amsys->motd2_cnt)); write_syslog(SYSLOG,1,"%s recounted the MOTDS.\n",user->name); return; } } done=1; board_cnt=0; old_cnt=0; bad_cnt=0; for (rm=room_first; rm!=NULL; rm=rm->next) { tmp=rm->mesg_cnt; rm->mesg_cnt=0; if (rm->access==PERSONAL_LOCKED || rm->access==PERSONAL_UNLOCKED) { midcpy(rm->name,rmname,1,strlen(rm->name)-2); rmname[0]=toupper(rmname[0]); sprintf(fname,"%s/%s.B", USERROOMS,rmname); } else sprintf(fname,"%s/%s.B", ROOMFILES, rm->name); if (!(infp=fopen(fname,"r"))) continue; if (chforce<2) { if (!(outfp=fopen("tempfile","w"))) { if (chforce) write_syslog(ERRLOG, 1, "Lotos: Couldn't open tempfile.\n"); write_syslog(ERRLOG,1,"Couldn't open tempfile in check_messages().\n"); fclose(infp); return; } } board_cnt++; /* We assume that once 1 in date message is encountered all the others will be in date too , hence write_rest once set to 1 is never set to 0 again */ valid=1; write_rest=0; fgets(line,82,infp); /* max of 80+newline+terminator = 82 */ while (!feof(infp)) { if (*line=='\n') valid=1; sscanf(line,"%s %d",id,&pt); if (!write_rest) { if (valid && !strcmp(id,"PT:")) { if (chforce==2) rm->mesg_cnt++; else { /* 86400 = num. of secs in a day */ if ((int)time(0) - pt < amsys->mesg_life*86400) { fputs(line,outfp); rm->mesg_cnt++; write_rest=1; } else old_cnt++; } valid=0; } } else { fputs(line,outfp); if (valid && !strcmp(id,"PT:")) { rm->mesg_cnt++; valid=0; } } fgets(line,82,infp); } fclose(infp); if (chforce<2) { fclose(outfp); unlink(fname); if (!write_rest) unlink("tempfile"); else rename("tempfile",fname); } if (rm->mesg_cnt!=tmp) bad_cnt++; } switch (chforce) { case 0: if (bad_cnt) write_syslog(SYSLOG,1,"CHECK_MESSAGES: %d file%s checked, %d had an incorrect message count, %d message%s deleted.\n", board_cnt,PLTEXT_S(board_cnt),bad_cnt,old_cnt,PLTEXT_S(old_cnt)); else write_syslog(SYSLOG,1,"CHECK_MESSAGES: %d file%s checked, %d message%s deleted.\n",board_cnt,PLTEXT_S(board_cnt),old_cnt,PLTEXT_S(old_cnt)); break; case 1: printf(" %d board file%s checked, %d out of date message%s found.\n",board_cnt,PLTEXT_S(board_cnt),old_cnt,PLTEXT_S(old_cnt)); break; case 2: vwrite_user(user,"%d board file%s checked, %d had an incorrect message count.\n",board_cnt,PLTEXT_S(board_cnt),bad_cnt); write_syslog(SYSLOG,1,"%s forced a recount of the message boards.\n",user->name); } }
/*** Wipe some messages off the board ***/ void wipe_board(UR_OBJECT user) { int cnt; char fname[FNAME_LEN],*name,rmname[ROOM_NAME_LEN+1]; RM_OBJECT rm=user->room; set_crash(); if (word_count<2 && ((user->level>=WIZ && !is_personal_room(rm)) || (is_personal_room(rm) && (is_my_room(user,rm) || user->level>=GOD)))) { write_usage(user,"wipe all"); write_usage(user,"wipe <#>"); write_usage(user,"wipe to <#>"); write_usage(user,"wipe from <#> to <#>"); return; } else if (word_count<2 && ((user->level<WIZ && !is_personal_room(rm)) || (is_personal_room(rm) && !is_my_room(user,rm) && user->level<GOD ) ) ) { write_usage(user,"wipe <#>"); return; } switch (is_personal_room(rm)) { case 0: if (user->level<WIZ && !(check_board_wipe(user))) return; else if (get_wipe_parameters(user)==-1) return; break; case 1: if (!is_my_room(user,rm) && user->level<GOD && !check_board_wipe(user)) return; else if (get_wipe_parameters(user)==-1) return; break; } if (user->vis) name=user->recap; else name=invisname; if (rm->access==PERSONAL_LOCKED || rm->access==PERSONAL_UNLOCKED) { midcpy(rm->name,rmname,1,strlen(rm->name)-2); rmname[0]=toupper(rmname[0]); sprintf(fname,"%s/%s.B", USERROOMS, rmname); } else sprintf(fname,"%s/%s.B", ROOMFILES, rm->name); if (!rm->mesg_cnt) { write_user(user, wipe_empty_board); return; } if (user->wipe_from==-1) { unlink(fname); write_user(user, wipe_user_all_deleted); if (user->level<GOD || user->vis) vwrite_room_except(rm, user, wipe_room_all_deleted, name); write_syslog(SYSLOG,1,"%s wiped all messages from the board in the %s.\n",user->name,rm->name); rm->mesg_cnt=0; return; } if (user->wipe_from>rm->mesg_cnt) { vwrite_user(user,"There %s only %d message%s on the board.\n",PLTEXT_IS(rm->mesg_cnt),rm->mesg_cnt,PLTEXT_S(rm->mesg_cnt)); return; } cnt=wipe_messages(fname,user->wipe_from,user->wipe_to,0); if (cnt==rm->mesg_cnt) { unlink(fname); vwrite_user(user, wipe_too_many, rm->mesg_cnt, grm_num(8, rm->mesg_cnt)); if (user->level<GOD || user->vis) vwrite_room_except(rm,user,"%s maze nastenku.\n",name); write_syslog(SYSLOG,1,"%s wiped all messages from the board in the %s.\n",user->name,rm->name); rm->mesg_cnt=0; return; } rm->mesg_cnt-=cnt; vwrite_user(user, wipe_user_delete_range, cnt, grm_num(8, cnt), grm_num(9, cnt)); if (user->level<GOD || user->vis) vwrite_room_except(rm,user,"%s wipes some messages from the board.\n",name); write_syslog(SYSLOG,1,"%s wiped %d message%s from the board in the %s.\n",user->name,cnt,PLTEXT_S(cnt),rm->name); }
/* * give, take and view money of users currently logged on */ void global_money(UR_OBJECT user) { UR_OBJECT u; const char *name; int cash; if (word_count < 2) { write_user(user, "Usage: money -l/-g/-t [<user> <amount>]\n"); return; } /* list all users online and the amount of cash they have */ if (!strcasecmp(word[1], "-l")) { char text2[ARR_SIZE]; int x, cnt, user_cnt; write_user(user, "\n+----------------------------------------------------------------------------+\n"); write_user(user, "| ~FC~OLUser money listings~RS |\n"); write_user(user, "+----------------------------------------------------------------------------+\n"); x = user_cnt = 0; *text2 = '\0'; for (u = user_first; u; u = u->next) { ++user_cnt; cnt = 13 + teslen(u->recap, 13); if (!x) { /* build up first half of the string */ sprintf(text, "| %-*.*s $%6d ", cnt, cnt, u->recap, u->money); ++x; } else if (x == 1) { /* build up full line and print to user */ sprintf(text2, " %-*.*s $%6d ", cnt, cnt, u->recap, u->money); strcat(text, text2); write_user(user, text); *text = '\0'; *text2 = '\0'; ++x; } else { sprintf(text2, " %-*.*s $%6d |\n", cnt, cnt, u->recap, u->money); strcat(text, text2); write_user(user, text); *text = '\0'; *text2 = '\0'; x = 0; } } /* If you have only printed first half of the string */ if (x == 1) { strcat(text, " |\n"); write_user(user, text); } if (x == 2) { strcat(text, " |\n"); write_user(user, text); } write_user(user, "+----------------------------------------------------------------------------+\n"); sprintf(text, "Total of ~OL%d~RS user%s", user_cnt, PLTEXT_S(user_cnt)); vwrite_user(user, "| %-80s |\n", text); write_user(user, "+----------------------------------------------------------------------------+\n\n"); return; } /* give money to users */ if (!strcasecmp(word[1], "-g")) { if (word_count < 4) { write_user(user, "Usage: money -l/-g/-t [<user> <amount>]\n"); return; } u = get_user_name(user, word[2]); if (!u) { write_user(user, notloggedon); return; } if (u == user && user->level < GOD) { write_user(user, "You cannot give money to yourself.\n"); return; } cash = atoi(word[3]); if (cash < 1) { write_user(user, "You must supply an amount to give.\n"); return; } u->money += cash; name = user->vis || u->level < WIZ ? user->recap : invisname; vwrite_user(user, "You give $%d to %s~RS.\n", cash, u->recap); vwrite_user(u, "%s~RS kindly gives $%d.\n", name, cash); sprintf(text, "%s gives $%d.\n", user->name, cash); add_history(u->name, 1, text); return; } /* take money from users */ if (!strcasecmp(word[1], "-t")) { if (word_count < 4) { write_user(user, "Usage: money -l/-g/-t [<user> <amount>]\n"); return; } u = get_user_name(user, word[2]); if (!u) { write_user(user, notloggedon); return; } if (u == user) { write_user(user, "You cannot take money away from yourself.\n"); return; } cash = atoi(word[3]); if (cash < 1) { write_user(user, "You must supply an amount to take.\n"); return; } if (u->money < cash) { vwrite_user(user, "%s~RS has not got that much money.\n", u->recap); return; } u->money -= cash; name = user->vis || u->level < WIZ ? user->recap : invisname; vwrite_user(user, "You take $%d from %s~RS.\n", cash, u->recap); vwrite_user(u, "%s~RS takes $%d from you.\n", name, cash); sprintf(text, "%s takes $%d.\n", user->name, cash); add_history(u->name, 1, text); return; } write_user(user, "Usage: money -l/-g/-t [<user> <amount>]\n"); }
/* * This command allows you to do a search for any user names that match * a particular pattern */ void grep_users(UR_OBJECT user) { int found, x; char name[USER_NAME_LEN + 1], pat[ARR_SIZE]; UD_OBJECT entry; if (word_count < 2) { write_user(user, "Usage: grepu <pattern>\n"); return; } if (strstr(word[1], "**")) { write_user(user, "You cannot have ** in your pattern.\n"); return; } if (strstr(word[1], "?*")) { write_user(user, "You cannot have ?* in your pattern.\n"); return; } if (strstr(word[1], "*?")) { write_user(user, "You cannot have *? in your pattern.\n"); return; } start_pager(user); write_user(user, "\n+----------------------------------------------------------------------------+\n"); sprintf(text, "| ~FC~OLUser grep for pattern:~RS ~OL%-51s~RS |\n", word[1]); write_user(user, text); write_user(user, "+----------------------------------------------------------------------------+\n"); x = 0; found = 0; *pat = '\0'; strcpy(pat, word[1]); strtolower(pat); for (entry = first_user_entry; entry; entry = entry->next) { strcpy(name, entry->name); *name = tolower(*name); if (pattern_match(name, pat)) { if (!x) { vwrite_user(user, "| %-*s ~FC%-20s~RS ", USER_NAME_LEN, entry->name, user_level[entry->level].name); } else { vwrite_user(user, " %-*s ~FC%-20s~RS |\n", USER_NAME_LEN, entry->name, user_level[entry->level].name); } x = !x; ++found; } } if (x) { write_user(user, " |\n"); } if (!found) { write_user(user, "| |\n"); write_user(user, "| ~OL~FRNo users have that pattern~RS |\n"); write_user(user, "| |\n"); write_user(user, "+----------------------------------------------------------------------------+\n"); stop_pager(user); return; } write_user(user, "+----------------------------------------------------------------------------+\n"); write_user(user, align_string(0, 78, 1, "|", " ~OL%d~RS user%s had the pattern ~OL%s~RS ", found, PLTEXT_S(found), word[1])); write_user(user, "+----------------------------------------------------------------------------+\n\n"); stop_pager(user); }
/* * see list of pictures availiable--file dictated in "go" script */ void preview(UR_OBJECT user) { #if !!0 static const char usage[] = "Usage: preview [<picture>]\n"; #endif sds filename; char line[100]; FILE *fp; DIR *dirp; struct dirent *dp; int cnt, total; if (word_count < 2) { /* open the directory file up */ dirp = opendir(PICTFILES); if (!dirp) { write_user(user, "No list of the picture files is availiable.\n"); return; } *line = '\0'; cnt = total = 0; /* go through directory and list files */ for (dp = readdir(dirp); dp; dp = readdir(dirp)) { if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) { continue; } if (!total++) { write_user(user, "+----------------------------------------------------------------------------+\n"); write_user(user, "| ~OL~FCPictures available to view~RS |\n"); write_user(user, "+----------------------------------------------------------------------------+\n"); } sprintf(text, "%-12.12s ", dp->d_name); strcat(line, text); if (++cnt == 5) { write_user(user, align_string(0, 78, 1, "|", " %s", line)); *line = '\0'; cnt = 0; } } closedir(dirp); if (total) { if (cnt) { write_user(user, align_string(0, 78, 1, "|", " %s", line)); } write_user(user, "+----------------------------------------------------------------------------+\n"); write_user(user, align_string(0, 78, 1, "|", " There are %d picture%s ", total, PLTEXT_S(total))); write_user(user, "+----------------------------------------------------------------------------+\n\n"); } else { write_user(user, "There are no pictures available to be viewed.\n"); } return; } if (strpbrk(word[1], "./")) { write_user(user, "Sorry, there is no picture with that name.\n"); return; } filename = sdscatfmt(sdsempty(), "%s/%s", PICTFILES, word[1]); fp = fopen(filename, "r"); if (!fp) { write_user(user, "Sorry, there is no picture with that name.\n"); return; } fclose(fp); write_user(user, "You ~OL~FGpreview the following picture...\n\n"); switch (more(user, user->socket, filename)) { case 0: break; case 1: user->misc_op = 2; break; } sdsfree(filename); }
/* * read all the user files to check if a user exists */ void recount_users(UR_OBJECT user, char *inpstr) { char filename[80], *s; DIR *dirp; FILE *fp; struct dirent *dp; UD_OBJECT entry, next; UR_OBJECT u; int incorrect, correct, added, removed; if (!user->misc_op) { user->misc_op = 17; write_user(user, "~OL~FRWARNING:~RS This process may take some time if you have a lot of user accounts.\n"); write_user(user, " This should only be done if there are no, or minimal, users currently\n logged on.\n"); write_user(user, "\nDo you wish to continue (y|n)? "); return; } user->misc_op = 0; if (tolower(*inpstr) != 'y') { return; } write_user(user, "\n+----------------------------------------------------------------------------+\n"); incorrect = correct = added = removed = 0; write_user(user, "~OLRecounting all of the users...\n"); /* First process the files to see if there are any to add to the directory listing */ write_user(user, "Processing users to add..."); u = create_user(); if (!u) { write_user(user, "ERROR: Cannot create user object.\n"); write_syslog(SYSLOG | ERRLOG, 1, "ERROR: Cannot create user object in recount_users().\n"); return; } /* open the directory file up */ dirp = opendir(USERFILES); if (!dirp) { write_user(user, "ERROR: Failed to open userfile directory.\n"); write_syslog(SYSLOG | ERRLOG, 1, "ERROR: Directory open failure in recount_users().\n"); return; } /* count up how many files in the directory - this include . and .. */ for (dp = readdir(dirp); dp; dp = readdir(dirp)) { s = strchr(dp->d_name, '.'); if (!s || strcmp(s, ".D")) { continue; } *u->name = '\0'; strncat(u->name, dp->d_name, (size_t) (s - dp->d_name)); for (entry = first_user_entry; entry; entry = next) { next = entry->next; if (!strcmp(u->name, entry->name)) { break; } } if (!entry) { if (load_user_details(u)) { add_user_node(u->name, u->level); write_syslog(SYSLOG, 0, "Added new user node for existing user \"%s\"\n", u->name); ++added; reset_user(u); } /* FIXME: Probably ought to warn about this case */ } else { ++correct; } } closedir(dirp); destruct_user(u); /* * Now process any nodes to remove the directory listing. This may * not be optimal to do one loop to add and then one to remove, but * it is the best way I can think of doing it right now at 4:27am! */ write_user(user, "\nProcessing users to remove..."); for (entry = first_user_entry; entry; entry = next) { next = entry->next; sprintf(filename, "%s/%s.D", USERFILES, entry->name); fp = fopen(filename, "r"); if (!fp) { ++removed; --correct; write_syslog(SYSLOG, 0, "Removed user node for \"%s\" - user file does not exist.\n", entry->name); rem_user_node(entry->name); } else { fclose(fp); } } write_user(user, "\n+----------------------------------------------------------------------------+\n"); vwrite_user(user, "Checked ~OL%d~RS user%s. ~OL%d~RS node%s %s added, and ~OL%d~RS node%s %s removed.\n", added + removed + correct, PLTEXT_S(added + removed + correct), added, PLTEXT_S(added), PLTEXT_WAS(added), removed, PLTEXT_S(removed), PLTEXT_WAS(removed)); if (incorrect) { write_user(user, "See the system log for further details.\n"); } write_user(user, "+----------------------------------------------------------------------------+\n"); }