|
|
1.1 ! root 1: /* useredit.cpp */ ! 2: ! 3: /* Synchronet online sysop user editor */ ! 4: ! 5: /* $Id: useredit.cpp,v 1.35 2006/05/03 00:26:52 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: /*******************************************************************/ ! 39: /* The function useredit(), and functions that are closely related */ ! 40: /*******************************************************************/ ! 41: ! 42: #include "sbbs.h" ! 43: ! 44: #define SEARCH_TXT 0 ! 45: #define SEARCH_ARS 1 ! 46: ! 47: /****************************************************************************/ ! 48: /* Edits user data. Can only edit users with a Main Security Level less */ ! 49: /* than or equal to the current user's Main Security Level */ ! 50: /* Called from functions waitforcall, main_sec, xfer_sec and inkey */ ! 51: /****************************************************************************/ ! 52: void sbbs_t::useredit(int usernumber) ! 53: { ! 54: char str[256],tmp2[256],tmp3[256],c,stype=SEARCH_TXT; ! 55: char tmp[512]; ! 56: char search[256]={""},artxt[128]={""}; ! 57: uchar *ar=NULL; ! 58: uint i,j,k; ! 59: float f; ! 60: long l; ! 61: user_t user; ! 62: struct tm tm; ! 63: ! 64: if(online==ON_REMOTE && console&(CON_R_ECHO|CON_R_INPUT) && !chksyspass()) ! 65: return; ! 66: #if 0 /* no local logins in v3 */ ! 67: if(online==ON_LOCAL) { ! 68: if(!(cfg.sys_misc&SM_L_SYSOP)) ! 69: return; ! 70: if(cfg.node_misc&NM_SYSPW && !chksyspass()) ! 71: return; } ! 72: #endif ! 73: if(usernumber) ! 74: user.number=usernumber; ! 75: else ! 76: user.number=useron.number; ! 77: action=NODE_SYSP; ! 78: if(sys_status&SS_INUEDIT) ! 79: return; ! 80: sys_status|=SS_INUEDIT; ! 81: while(online) { ! 82: CLS; ! 83: attr(LIGHTGRAY); ! 84: getuserdat(&cfg,&user); ! 85: if(!user.number) { ! 86: user.number=1; ! 87: getuserdat(&cfg,&user); ! 88: if(!user.number) { ! 89: bputs(text[NoUserData]); ! 90: getkey(0); ! 91: sys_status&=~SS_INUEDIT; ! 92: return; } } ! 93: unixtodstr(&cfg,time(NULL),str); ! 94: unixtodstr(&cfg,user.laston,tmp); ! 95: if(strcmp(str,tmp) && user.ltoday) { ! 96: user.ltoday=user.ttoday=user.ptoday=user.etoday=user.textra=0; ! 97: user.freecdt=cfg.level_freecdtperday[user.level]; ! 98: putuserdat(&cfg,&user); } /* Leave alone */ ! 99: if(user.misc&DELETED) ! 100: bputs(text[Deleted]); ! 101: else if(user.misc&INACTIVE) ! 102: bputs(text[Inactive]); ! 103: bprintf(text[UeditAliasPassword] ! 104: ,user.alias, (user.level>useron.level && console&CON_R_ECHO) ! 105: || !(cfg.sys_misc&SM_ECHO_PW) ? "XXXXXXXX" : user.pass ! 106: , unixtodstr(&cfg,user.pwmod,tmp)); ! 107: bprintf(text[UeditRealNamePhone] ! 108: ,user.level>useron.level && console&CON_R_ECHO ! 109: ? "XXXXXXXX" : user.name ! 110: ,user.level>useron.level && console&CON_R_ECHO ! 111: ? "XXX-XXX-XXXX" : user.phone); ! 112: bprintf(text[UeditAddressBirthday] ! 113: ,user.address,getage(&cfg,user.birth),user.sex,user.birth); ! 114: bprintf(text[UeditLocationZipcode],user.location,user.zipcode); ! 115: bprintf(text[UeditNoteHandle],user.note,user.handle); ! 116: bprintf(text[UeditComputerModem],user.comp,user.modem); ! 117: if(user.netmail[0]) ! 118: bprintf(text[UserNetMail],user.netmail); ! 119: ! 120: sprintf(str,"%suser/%4.4u.msg", cfg.data_dir,user.number); ! 121: i=fexist(str); ! 122: if(user.comment[0] || i) ! 123: bprintf(text[UeditCommentLine],i ? '+' : ' ' ! 124: ,user.comment); ! 125: else ! 126: CRLF; ! 127: if(localtime_r(&user.laston,&tm)==NULL) ! 128: return; ! 129: bprintf(text[UserDates] ! 130: ,unixtodstr(&cfg,user.firston,str),unixtodstr(&cfg,user.expire,tmp) ! 131: ,unixtodstr(&cfg,user.laston,tmp2),tm.tm_hour, tm.tm_min); ! 132: ! 133: bprintf(text[UserTimes] ! 134: ,user.timeon,user.ttoday,cfg.level_timeperday[user.level] ! 135: ,user.tlast,cfg.level_timepercall[user.level],user.textra); ! 136: if(user.posts) ! 137: f=(float)user.logons/user.posts; ! 138: else ! 139: f=0; ! 140: bprintf(text[UserLogons] ! 141: ,user.logons,user.ltoday,cfg.level_callsperday[user.level],user.posts ! 142: ,f ? (uint)(100/f) : user.posts>user.logons ? 100 : 0 ! 143: ,user.ptoday); ! 144: bprintf(text[UserEmails] ! 145: ,user.emails,user.fbacks,getmail(&cfg,user.number,0),user.etoday); ! 146: ! 147: bprintf(text[UserUploads],ultoac(user.ulb,tmp),user.uls); ! 148: if(user.leech) ! 149: sprintf(str,text[UserLeech],user.leech); ! 150: else ! 151: str[0]=0; ! 152: bprintf(text[UserDownloads],ultoac(user.dlb,tmp),user.dls,str); ! 153: bprintf(text[UserCredits],ultoac(user.cdt,tmp) ! 154: ,ultoac(user.freecdt,tmp2),ultoac(cfg.level_freecdtperday[user.level],str)); ! 155: bprintf(text[UserMinutes],ultoac(user.min,tmp)); ! 156: bprintf(text[UeditSecLevel],user.level); ! 157: bprintf(text[UeditFlags],ltoaf(user.flags1,tmp),ltoaf(user.flags3,tmp2) ! 158: ,ltoaf(user.flags2,tmp3),ltoaf(user.flags4,str)); ! 159: bprintf(text[UeditExempts],ltoaf(user.exempt,tmp),ltoaf(user.rest,tmp2)); ! 160: l=lastuser(&cfg); ! 161: ASYNC; ! 162: if(lncntr>=rows-2) ! 163: lncntr=0; ! 164: bprintf(text[UeditPrompt],user.number,l); ! 165: if(user.level>useron.level && console&CON_R_INPUT) ! 166: strcpy(str,"QG[]?/{},"); ! 167: else ! 168: strcpy(str,"ABCDEFGHIJKLMNOPQRSTUVWXYZ+[]?/{}~*$#"); ! 169: l=getkeys(str,l); ! 170: if(l&0x80000000L) { ! 171: user.number=(ushort)(l&~0x80000000L); ! 172: continue; } ! 173: switch(l) { ! 174: case 'A': ! 175: bputs(text[EnterYourAlias]); ! 176: getstr(user.alias,LEN_ALIAS,K_LINE|K_EDIT|K_AUTODEL); ! 177: putuserrec(&cfg,user.number,U_ALIAS,LEN_ALIAS,user.alias); ! 178: if(!(user.misc&DELETED)) ! 179: putusername(&cfg,user.number,user.alias); ! 180: bputs(text[EnterYourHandle]); ! 181: getstr(user.handle,LEN_HANDLE,K_LINE|K_EDIT|K_AUTODEL); ! 182: putuserrec(&cfg,user.number,U_HANDLE,LEN_HANDLE,user.handle); ! 183: break; ! 184: case 'B': ! 185: bprintf(text[EnterYourBirthday] ! 186: ,cfg.sys_misc&SM_EURODATE ? "DD/MM/YY" : "MM/DD/YY"); ! 187: gettmplt(user.birth,"nn/nn/nn",K_LINE|K_EDIT|K_AUTODEL); ! 188: putuserrec(&cfg,user.number,U_BIRTH,LEN_BIRTH,user.birth); ! 189: break; ! 190: case 'C': ! 191: bputs(text[EnterYourComputer]); ! 192: getstr(user.comp,LEN_COMP,K_LINE|K_EDIT|K_AUTODEL); ! 193: putuserrec(&cfg,user.number,U_COMP,LEN_COMP,user.comp); ! 194: break; ! 195: case 'D': ! 196: if(user.misc&DELETED) { ! 197: if(!noyes(text[UeditRestoreQ])) { ! 198: putuserrec(&cfg,user.number,U_MISC,8 ! 199: ,ultoa(user.misc&~DELETED,str,16)); ! 200: putusername(&cfg,user.number,user.alias); } ! 201: break; } ! 202: if(user.misc&INACTIVE) { ! 203: if(!noyes(text[UeditActivateQ])) ! 204: putuserrec(&cfg,user.number,U_MISC,8 ! 205: ,ultoa(user.misc&~INACTIVE,str,16)); ! 206: break; } ! 207: if(!noyes(text[UeditDeleteQ])) { ! 208: getsmsg(user.number); ! 209: if(getmail(&cfg,user.number,0)) { ! 210: if(yesno(text[UeditReadUserMailWQ])) ! 211: readmail(user.number,MAIL_YOUR); } ! 212: if(getmail(&cfg,user.number,1)) { ! 213: if(yesno(text[UeditReadUserMailSQ])) ! 214: readmail(user.number,MAIL_SENT); } ! 215: putuserrec(&cfg,user.number,U_MISC,8 ! 216: ,ultoa(user.misc|DELETED,str,16)); ! 217: putusername(&cfg,user.number,nulstr); ! 218: break; } ! 219: if(!noyes(text[UeditDeactivateUserQ])) { ! 220: if(getmail(&cfg,user.number,0)) { ! 221: if(yesno(text[UeditReadUserMailWQ])) ! 222: readmail(user.number,MAIL_YOUR); } ! 223: if(getmail(&cfg,user.number,1)) { ! 224: if(yesno(text[UeditReadUserMailSQ])) ! 225: readmail(user.number,MAIL_SENT); } ! 226: putuserrec(&cfg,user.number,U_MISC,8 ! 227: ,ultoa(user.misc|INACTIVE,str,16)); ! 228: break; } ! 229: break; ! 230: case 'E': ! 231: if(!yesno(text[ChangeExemptionQ])) ! 232: break; ! 233: while(online) { ! 234: bprintf(text[FlagEditing],ltoaf(user.exempt,tmp)); ! 235: c=(char)getkeys("ABCDEFGHIJKLMNOPQRSTUVWXYZ?\r",0); ! 236: if(sys_status&SS_ABORT) ! 237: break; ! 238: if(c==CR) break; ! 239: if(c=='?') { ! 240: menu("exempt"); ! 241: continue; } ! 242: if(user.level>useron.level ! 243: && !(useron.exempt&FLAG(c)) && console&CON_R_INPUT) ! 244: continue; ! 245: user.exempt^=FLAG(c); ! 246: putuserrec(&cfg,user.number,U_EXEMPT,8,ultoa(user.exempt,tmp,16)); } ! 247: break; ! 248: case 'F': ! 249: i=1; ! 250: while(online) { ! 251: bprintf("\r\nFlag Set #%d\r\n",i); ! 252: switch(i) { ! 253: case 1: ! 254: bprintf(text[FlagEditing],ltoaf(user.flags1,tmp)); ! 255: break; ! 256: case 2: ! 257: bprintf(text[FlagEditing],ltoaf(user.flags2,tmp)); ! 258: break; ! 259: case 3: ! 260: bprintf(text[FlagEditing],ltoaf(user.flags3,tmp)); ! 261: break; ! 262: case 4: ! 263: bprintf(text[FlagEditing],ltoaf(user.flags4,tmp)); ! 264: break; } ! 265: c=(char)getkeys("ABCDEFGHIJKLMNOPQRSTUVWXYZ?1234\r",0); ! 266: if(sys_status&SS_ABORT) ! 267: break; ! 268: if(c==CR) break; ! 269: if(c=='?') { ! 270: sprintf(str,"flags%d",i); ! 271: menu(str); ! 272: continue; } ! 273: if(isdigit(c)) { ! 274: i=c&0xf; ! 275: continue; } ! 276: if(user.level>useron.level && console&CON_R_INPUT) ! 277: switch(i) { ! 278: case 1: ! 279: if(!(useron.flags1&FLAG(c))) ! 280: continue; ! 281: break; ! 282: case 2: ! 283: if(!(useron.flags2&FLAG(c))) ! 284: continue; ! 285: break; ! 286: case 3: ! 287: if(!(useron.flags3&FLAG(c))) ! 288: continue; ! 289: break; ! 290: case 4: ! 291: if(!(useron.flags4&FLAG(c))) ! 292: continue; ! 293: break; } ! 294: switch(i) { ! 295: case 1: ! 296: user.flags1^=FLAG(c); ! 297: putuserrec(&cfg,user.number,U_FLAGS1,8 ! 298: ,ultoa(user.flags1,tmp,16)); ! 299: break; ! 300: case 2: ! 301: user.flags2^=FLAG(c); ! 302: putuserrec(&cfg,user.number,U_FLAGS2,8 ! 303: ,ultoa(user.flags2,tmp,16)); ! 304: break; ! 305: case 3: ! 306: user.flags3^=FLAG(c); ! 307: putuserrec(&cfg,user.number,U_FLAGS3,8 ! 308: ,ultoa(user.flags3,tmp,16)); ! 309: break; ! 310: case 4: ! 311: user.flags4^=FLAG(c); ! 312: putuserrec(&cfg,user.number,U_FLAGS4,8 ! 313: ,ultoa(user.flags4,tmp,16)); ! 314: break; } } ! 315: break; ! 316: case 'G': ! 317: bputs(text[GoToUser]); ! 318: if(getstr(str,LEN_ALIAS,K_UPPER|K_LINE)) { ! 319: if(isdigit(str[0])) { ! 320: i=atoi(str); ! 321: if(i>lastuser(&cfg)) ! 322: break; ! 323: if(i) user.number=i; } ! 324: else { ! 325: i=finduser(str); ! 326: if(i) user.number=i; } } ! 327: break; ! 328: case 'H': /* edit user's information file */ ! 329: attr(LIGHTGRAY); ! 330: sprintf(str,"%suser/%4.4u.msg", cfg.data_dir,user.number); ! 331: editfile(str); ! 332: break; ! 333: case 'I': ! 334: maindflts(&user); ! 335: break; ! 336: case 'J': /* Edit Minutes */ ! 337: bputs(text[UeditMinutes]); ! 338: ultoa(user.min,str,10); ! 339: if(getstr(str,10,K_NUMBER|K_LINE)) ! 340: putuserrec(&cfg,user.number,U_MIN,10,str); ! 341: break; ! 342: case 'K': /* date changes */ ! 343: bputs(text[UeditLastOn]); ! 344: unixtodstr(&cfg,user.laston,str); ! 345: gettmplt(str,"nn/nn/nn",K_LINE|K_EDIT); ! 346: if(sys_status&SS_ABORT) ! 347: break; ! 348: user.laston=dstrtounix(&cfg,str); ! 349: putuserrec(&cfg,user.number,U_LASTON,8,ultoa(user.laston,tmp,16)); ! 350: bputs(text[UeditFirstOn]); ! 351: unixtodstr(&cfg,user.firston,str); ! 352: gettmplt(str,"nn/nn/nn",K_LINE|K_EDIT); ! 353: if(sys_status&SS_ABORT) ! 354: break; ! 355: user.firston=dstrtounix(&cfg,str); ! 356: putuserrec(&cfg,user.number,U_FIRSTON,8,ultoa(user.firston,tmp,16)); ! 357: bputs(text[UeditExpire]); ! 358: unixtodstr(&cfg,user.expire,str); ! 359: gettmplt(str,"nn/nn/nn",K_LINE|K_EDIT); ! 360: if(sys_status&SS_ABORT) ! 361: break; ! 362: user.expire=dstrtounix(&cfg,str); ! 363: putuserrec(&cfg,user.number,U_EXPIRE,8,ultoa(user.expire,tmp,16)); ! 364: bputs(text[UeditPwModDate]); ! 365: unixtodstr(&cfg,user.pwmod,str); ! 366: gettmplt(str,"nn/nn/nn",K_LINE|K_EDIT); ! 367: if(sys_status&SS_ABORT) ! 368: break; ! 369: user.pwmod=dstrtounix(&cfg,str); ! 370: putuserrec(&cfg,user.number,U_PWMOD,8,ultoa(user.pwmod,tmp,16)); ! 371: break; ! 372: case 'L': ! 373: bputs(text[EnterYourAddress]); ! 374: getstr(user.address,LEN_ADDRESS,K_LINE|K_EDIT|K_AUTODEL); ! 375: if(sys_status&SS_ABORT) ! 376: break; ! 377: putuserrec(&cfg,user.number,U_ADDRESS,LEN_ADDRESS,user.address); ! 378: bputs(text[EnterYourCityState]); ! 379: getstr(user.location,LEN_LOCATION,K_LINE|K_EDIT|K_AUTODEL); ! 380: if(sys_status&SS_ABORT) ! 381: break; ! 382: putuserrec(&cfg,user.number,U_LOCATION,LEN_LOCATION,user.location); ! 383: bputs(text[EnterYourZipCode]); ! 384: getstr(user.zipcode,LEN_ZIPCODE,K_LINE|K_EDIT|K_AUTODEL|K_UPPER); ! 385: if(sys_status&SS_ABORT) ! 386: break; ! 387: putuserrec(&cfg,user.number,U_ZIPCODE,LEN_ZIPCODE,user.zipcode); ! 388: break; ! 389: case 'M': ! 390: bputs(text[UeditML]); ! 391: ultoa(user.level,str,10); ! 392: if(getstr(str,2,K_NUMBER|K_LINE)) ! 393: if(!(atoi(str)>useron.level && console&CON_R_INPUT)) ! 394: putuserrec(&cfg,user.number,U_LEVEL,2,str); ! 395: break; ! 396: case 'N': ! 397: bputs(text[UeditNote]); ! 398: getstr(user.note,LEN_NOTE,K_LINE|K_EDIT|K_AUTODEL); ! 399: putuserrec(&cfg,user.number,U_NOTE,LEN_NOTE,user.note); ! 400: break; ! 401: case 'O': ! 402: bputs(text[UeditComment]); ! 403: getstr(user.comment,60,K_LINE|K_EDIT|K_AUTODEL); ! 404: putuserrec(&cfg,user.number,U_COMMENT,60,user.comment); ! 405: break; ! 406: case 'P': ! 407: bputs(text[EnterYourPhoneNumber]); ! 408: getstr(user.phone,LEN_PHONE,K_UPPER|K_LINE|K_EDIT|K_AUTODEL); ! 409: putuserrec(&cfg,user.number,U_PHONE,LEN_PHONE,user.phone); ! 410: break; ! 411: case 'Q': ! 412: CLS; ! 413: sys_status&=~SS_INUEDIT; ! 414: FREE_AR(ar); /* assertion here */ ! 415: return; ! 416: case 'R': ! 417: bputs(text[EnterYourRealName]); ! 418: getstr(user.name,LEN_NAME,K_LINE|K_EDIT|K_AUTODEL); ! 419: putuserrec(&cfg,user.number,U_NAME,LEN_NAME,user.name); ! 420: break; ! 421: case 'S': ! 422: bputs(text[EnterYourSex]); ! 423: if(getstr(str,1,K_UPPER|K_LINE)) ! 424: putuserrec(&cfg,user.number,U_SEX,1,str); ! 425: break; ! 426: case 'T': /* Text Search */ ! 427: bputs(text[SearchStringPrompt]); ! 428: if(getstr(search,30,K_UPPER|K_LINE)) ! 429: stype=SEARCH_TXT; ! 430: break; ! 431: case 'U': ! 432: bputs(text[UeditUlBytes]); ! 433: ultoa(user.ulb,str,10); ! 434: if(getstr(str,10,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL)) ! 435: putuserrec(&cfg,user.number,U_ULB,10,str); ! 436: if(sys_status&SS_ABORT) ! 437: break; ! 438: bputs(text[UeditUploads]); ! 439: sprintf(str,"%u",user.uls); ! 440: if(getstr(str,5,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL)) ! 441: putuserrec(&cfg,user.number,U_ULS,5,str); ! 442: if(sys_status&SS_ABORT) ! 443: break; ! 444: bputs(text[UeditDlBytes]); ! 445: ultoa(user.dlb,str,10); ! 446: if(getstr(str,10,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL)) ! 447: putuserrec(&cfg,user.number,U_DLB,10,str); ! 448: if(sys_status&SS_ABORT) ! 449: break; ! 450: bputs(text[UeditDownloads]); ! 451: sprintf(str,"%u",user.dls); ! 452: if(getstr(str,5,K_NUMBER|K_LINE|K_EDIT|K_AUTODEL)) ! 453: putuserrec(&cfg,user.number,U_DLS,5,str); ! 454: break; ! 455: case 'V': ! 456: CLS; ! 457: attr(LIGHTGRAY); ! 458: for(i=0;i<10;i++) { ! 459: bprintf(text[QuickValidateFmt] ! 460: ,i,cfg.val_level[i],ltoaf(cfg.val_flags1[i],str) ! 461: ,ltoaf(cfg.val_exempt[i],tmp) ! 462: ,ltoaf(cfg.val_rest[i],tmp3)); } ! 463: ASYNC; ! 464: bputs(text[QuickValidatePrompt]); ! 465: c=getkey(0); ! 466: if(!isdigit(c)) ! 467: break; ! 468: i=c&0xf; ! 469: user.level=cfg.val_level[i]; ! 470: user.flags1=cfg.val_flags1[i]; ! 471: user.flags2=cfg.val_flags2[i]; ! 472: user.flags3=cfg.val_flags3[i]; ! 473: user.flags4=cfg.val_flags4[i]; ! 474: user.exempt=cfg.val_exempt[i]; ! 475: user.rest=cfg.val_rest[i]; ! 476: user.cdt+=cfg.val_cdt[i]; ! 477: now=time(NULL); ! 478: if(cfg.val_expire[i]) { ! 479: if(user.expire<now) ! 480: user.expire=now+((long)cfg.val_expire[i]*24L*60L*60L); ! 481: else ! 482: user.expire+=((long)cfg.val_expire[i]*24L*60L*60L); } ! 483: putuserdat(&cfg,&user); ! 484: break; ! 485: case 'W': ! 486: bputs(text[UeditPassword]); ! 487: getstr(user.pass,LEN_PASS,K_UPPER|K_LINE|K_EDIT|K_AUTODEL); ! 488: putuserrec(&cfg,user.number,U_PASS,LEN_PASS,user.pass); ! 489: break; ! 490: case 'X': ! 491: attr(LIGHTGRAY); ! 492: sprintf(str,"%suser/%4.4u.msg", cfg.data_dir,user.number); ! 493: printfile(str,0); ! 494: pause(); ! 495: break; ! 496: case 'Y': ! 497: if(!noyes(text[UeditCopyUserQ])) { ! 498: bputs(text[UeditCopyUserToSlot]); ! 499: i=getnum(lastuser(&cfg)); ! 500: if((int)i>0) { ! 501: user.number=i; ! 502: putusername(&cfg,user.number,user.alias); ! 503: putuserdat(&cfg,&user); } } ! 504: break; ! 505: case 'Z': ! 506: if(!yesno(text[ChangeRestrictsQ])) ! 507: break; ! 508: while(online) { ! 509: bprintf(text[FlagEditing],ltoaf(user.rest,tmp)); ! 510: c=(char)getkeys("ABCDEFGHIJKLMNOPQRSTUVWXYZ?\r",0); ! 511: if(sys_status&SS_ABORT) ! 512: break; ! 513: if(c==CR) break; ! 514: if(c=='?') { ! 515: menu("restrict"); ! 516: continue; } ! 517: user.rest^=FLAG(c); ! 518: putuserrec(&cfg,user.number,U_REST,8,ultoa(user.rest,tmp,16)); } ! 519: break; ! 520: case '?': ! 521: CLS; ! 522: menu("uedit"); /* Sysop Uedit Edit Menu */ ! 523: pause(); ! 524: break; ! 525: case '~': ! 526: bputs(text[UeditLeech]); ! 527: if(getstr(str,2,K_NUMBER|K_LINE)) ! 528: putuserrec(&cfg,user.number,U_LEECH,2,ultoa(atoi(str),tmp,16)); ! 529: break; ! 530: case '+': ! 531: bputs(text[ModifyCredits]); ! 532: getstr(str,10,K_UPPER|K_LINE); ! 533: l=atol(str); ! 534: if(strstr(str,"M")) ! 535: l*=0x100000L; ! 536: else if(strstr(str,"K")) ! 537: l*=1024; ! 538: else if(strstr(str,"$")) ! 539: l*=cfg.cdt_per_dollar; ! 540: if(l<0L && l*-1 > (long)user.cdt) ! 541: user.cdt=0L; ! 542: else ! 543: user.cdt+=l; ! 544: putuserrec(&cfg,user.number,U_CDT,10,ultoa(user.cdt,tmp,10)); ! 545: break; ! 546: case '*': ! 547: bputs(text[ModifyMinutes]); ! 548: getstr(str,10,K_UPPER|K_LINE); ! 549: l=atol(str); ! 550: if(strstr(str,"H")) ! 551: l*=60L; ! 552: if(l<0L && l*-1 > (long)user.min) ! 553: user.min=0L; ! 554: else ! 555: user.min+=l; ! 556: putuserrec(&cfg,user.number,U_MIN,10,ultoa(user.min,tmp,10)); ! 557: break; ! 558: case '#': /* read new user questionaire */ ! 559: sprintf(str,"%suser/%4.4u.dat", cfg.data_dir,user.number); ! 560: if(!cfg.new_sof[0] || !fexist(str)) ! 561: break; ! 562: read_sif_dat(cfg.new_sof,str); ! 563: if(!noyes(text[DeleteQuestionaireQ])) ! 564: remove(str); ! 565: break; ! 566: case '$': ! 567: bputs(text[UeditCredits]); ! 568: ultoa(user.cdt,str,10); ! 569: if(getstr(str,10,K_NUMBER|K_LINE)) ! 570: putuserrec(&cfg,user.number,U_CDT,10,str); ! 571: break; ! 572: case '/': ! 573: bputs(text[SearchStringPrompt]); ! 574: if(getstr(artxt,40,K_UPPER|K_LINE)) ! 575: stype=SEARCH_ARS; ! 576: FREE_AR(ar); ! 577: ar=arstr(NULL,artxt,&cfg); ! 578: break; ! 579: case '{': ! 580: if(stype==SEARCH_TXT) ! 581: user.number=searchdn(search,user.number); ! 582: else { ! 583: if(!ar) ! 584: break; ! 585: k=user.number; ! 586: for(i=k-1;i;i--) { ! 587: user.number=i; ! 588: getuserdat(&cfg,&user); ! 589: if(chk_ar(ar,&user)) { ! 590: outchar(BEL); ! 591: break; } } ! 592: if(!i) ! 593: user.number=k; } ! 594: break; ! 595: case '}': ! 596: if(stype==SEARCH_TXT) ! 597: user.number=searchup(search,user.number); ! 598: else { ! 599: if(!ar) ! 600: break; ! 601: j=lastuser(&cfg); ! 602: k=user.number; ! 603: for(i=k+1;i<=j;i++) { ! 604: user.number=i; ! 605: getuserdat(&cfg,&user); ! 606: if(chk_ar(ar,&user)) { ! 607: outchar(BEL); ! 608: break; } } ! 609: if(i>j) ! 610: user.number=k; } ! 611: break; ! 612: case ']': ! 613: if(user.number==lastuser(&cfg)) ! 614: user.number=1; ! 615: else user.number++; ! 616: break; ! 617: case '[': ! 618: if(user.number==1) ! 619: user.number=lastuser(&cfg); ! 620: else user.number--; ! 621: break; ! 622: } /* switch */ ! 623: } /* while */ ! 624: sys_status&=~SS_INUEDIT; ! 625: FREE_AR(ar); ! 626: } ! 627: ! 628: /****************************************************************************/ ! 629: /* Seaches forward through the USER.DAT file for the ocurrance of 'search' */ ! 630: /* starting at the offset for usernum+1 and returning the usernumber of the */ ! 631: /* record where the string was found or the original usernumber if the */ ! 632: /* string wasn't found */ ! 633: /* Called from the function useredit */ ! 634: /****************************************************************************/ ! 635: int sbbs_t::searchup(char *search,int usernum) ! 636: { ! 637: char userdat[U_LEN+1]; ! 638: int file,count; ! 639: uint i=usernum+1; ! 640: long flen; ! 641: ! 642: if(!search[0]) ! 643: return(usernum); ! 644: sprintf(userdat,"%suser/user.dat", cfg.data_dir); ! 645: if((file=nopen(userdat,O_RDONLY|O_DENYNONE))==-1) ! 646: return(usernum); ! 647: ! 648: flen=filelength(file); ! 649: lseek(file,(long)((long)usernum*U_LEN),0); ! 650: ! 651: while((i*U_LEN)<=(ulong)flen) { ! 652: count=0; ! 653: while(count<LOOP_NODEDAB ! 654: && lock(file,(long)((long)(i-1)*U_LEN),U_LEN)==-1) { ! 655: if(count) ! 656: mswait(100); ! 657: count++; ! 658: } ! 659: ! 660: if(count>=LOOP_NODEDAB) { ! 661: close(file); ! 662: errormsg(WHERE,ERR_LOCK,"user.dat",i); ! 663: return(usernum); ! 664: } ! 665: ! 666: if(read(file,userdat,U_LEN)!=U_LEN) { ! 667: unlock(file,(long)((long)(i-1)*U_LEN),U_LEN); ! 668: close(file); ! 669: errormsg(WHERE,ERR_READ,"user.dat",U_LEN); ! 670: return(usernum); ! 671: } ! 672: ! 673: unlock(file,(long)((long)(i-1)*U_LEN),U_LEN); ! 674: userdat[U_LEN]=0; ! 675: strupr(userdat); ! 676: if(strstr(userdat,search)) { ! 677: outchar(BEL); ! 678: close(file); ! 679: return(i); ! 680: } ! 681: i++; ! 682: } ! 683: close(file); ! 684: return(usernum); ! 685: } ! 686: ! 687: /****************************************************************************/ ! 688: /* Seaches backward through the USER.DAT file for the ocurrance of 'search' */ ! 689: /* starting at the offset for usernum-1 and returning the usernumber of the */ ! 690: /* record where the string was found or the original usernumber if the */ ! 691: /* string wasn't found */ ! 692: /* Called from the function useredit */ ! 693: /****************************************************************************/ ! 694: int sbbs_t::searchdn(char *search,int usernum) ! 695: { ! 696: char userdat[U_LEN+1]; ! 697: int file,count; ! 698: uint i=usernum-1; ! 699: ! 700: if(!search[0]) ! 701: return(usernum); ! 702: sprintf(userdat,"%suser/user.dat", cfg.data_dir); ! 703: if((file=nopen(userdat,O_RDONLY|O_DENYNONE))==-1) ! 704: return(usernum); ! 705: while(i) { ! 706: lseek(file,(long)((long)(i-1)*U_LEN),0); ! 707: count=0; ! 708: while(count<LOOP_NODEDAB ! 709: && lock(file,(long)((long)(i-1)*U_LEN),U_LEN)==-1) { ! 710: if(count) ! 711: mswait(100); ! 712: count++; ! 713: } ! 714: ! 715: if(count>=LOOP_NODEDAB) { ! 716: close(file); ! 717: errormsg(WHERE,ERR_LOCK,"user.dat",i); ! 718: return(usernum); ! 719: } ! 720: ! 721: if(read(file,userdat,U_LEN)==-1) { ! 722: unlock(file,(long)((long)(i-1)*U_LEN),U_LEN); ! 723: close(file); ! 724: errormsg(WHERE,ERR_READ,"USER.DAT",U_LEN); ! 725: return(usernum); ! 726: } ! 727: unlock(file,(long)((long)(i-1)*U_LEN),U_LEN); ! 728: userdat[U_LEN]=0; ! 729: strupr(userdat); ! 730: if(strstr(userdat,search)) { ! 731: outchar(BEL); ! 732: close(file); ! 733: return(i); ! 734: } ! 735: i--; ! 736: } ! 737: close(file); ! 738: return(usernum); ! 739: } ! 740: ! 741: /****************************************************************************/ ! 742: /* This function view/edits the users main default settings. */ ! 743: /****************************************************************************/ ! 744: void sbbs_t::maindflts(user_t* user) ! 745: { ! 746: char str[256],ch; ! 747: char tmp[512]; ! 748: int i; ! 749: ! 750: action=NODE_DFLT; ! 751: while(online) { ! 752: CLS; ! 753: getuserdat(&cfg,user); ! 754: if(user->rows) ! 755: rows=user->rows; ! 756: bprintf(text[UserDefaultsHdr],user->alias,user->number); ! 757: sprintf(str,"%s%s%s%s%s" ! 758: ,user->misc&AUTOTERM ? "Auto Detect ":nulstr ! 759: ,user->misc&ANSI ? "ANSI ":"TTY " ! 760: ,user->misc&COLOR ? "(Color) ":"(Mono) " ! 761: ,user->misc&WIP ? "WIP" : user->misc&RIP ? "RIP " ! 762: : user->misc&HTML ? "HTML " : nulstr ! 763: ,user->misc&NO_EXASCII ? "ASCII Only":nulstr); ! 764: bprintf(text[UserDefaultsTerminal],str); ! 765: if(cfg.total_xedits) ! 766: bprintf(text[UserDefaultsXeditor] ! 767: ,user->xedit ? cfg.xedit[user->xedit-1]->name : "None"); ! 768: if(user->rows) ! 769: ultoa(user->rows,tmp,10); ! 770: else ! 771: sprintf(tmp,"Auto Detect (%ld)",rows); ! 772: bprintf(text[UserDefaultsRows],tmp); ! 773: if(cfg.total_shells>1) ! 774: bprintf(text[UserDefaultsCommandSet] ! 775: ,cfg.shell[user->shell]->name); ! 776: bprintf(text[UserDefaultsArcType] ! 777: ,user->tmpext); ! 778: bprintf(text[UserDefaultsMenuMode] ! 779: ,user->misc&EXPERT ? text[On] : text[Off]); ! 780: bprintf(text[UserDefaultsPause] ! 781: ,user->misc&UPAUSE ? text[On] : text[Off]); ! 782: bprintf(text[UserDefaultsHotKey] ! 783: ,user->misc&COLDKEYS ? text[Off] : text[On]); ! 784: bprintf(text[UserDefaultsCursor] ! 785: ,user->misc&SPIN ? text[On] : user->misc&NOPAUSESPIN ? text[Off] : "Pause Prompt Only"); ! 786: bprintf(text[UserDefaultsCLS] ! 787: ,user->misc&CLRSCRN ? text[On] : text[Off]); ! 788: bprintf(text[UserDefaultsAskNScan] ! 789: ,user->misc&ASK_NSCAN ? text[On] : text[Off]); ! 790: bprintf(text[UserDefaultsAskSScan] ! 791: ,user->misc&ASK_SSCAN ? text[On] : text[Off]); ! 792: bprintf(text[UserDefaultsANFS] ! 793: ,user->misc&ANFSCAN ? text[On] : text[Off]); ! 794: bprintf(text[UserDefaultsRemember] ! 795: ,user->misc&CURSUB ? text[On] : text[Off]); ! 796: bprintf(text[UserDefaultsBatFlag] ! 797: ,user->misc&BATCHFLAG ? text[On] : text[Off]); ! 798: if(cfg.sys_misc&SM_FWDTONET) ! 799: bprintf(text[UserDefaultsNetMail] ! 800: ,user->misc&NETMAIL ? text[On] : text[Off]); ! 801: if(startup->options&BBS_OPT_AUTO_LOGON && user->exempt&FLAG('V')) ! 802: bprintf(text[UserDefaultsAutoLogon] ! 803: ,user->misc&AUTOLOGON ? text[On] : text[Off]); ! 804: if(useron.exempt&FLAG('Q') || user->misc&QUIET) ! 805: bprintf(text[UserDefaultsQuiet] ! 806: ,user->misc&QUIET ? text[On] : text[Off]); ! 807: if(user->prot!=' ') ! 808: sprintf(str,"%c",user->prot); ! 809: else ! 810: strcpy(str,"None"); ! 811: bprintf(text[UserDefaultsProtocol],str ! 812: ,user->misc&AUTOHANG ? "(Hang-up After Xfer)":nulstr); ! 813: if(cfg.sys_misc&SM_PWEDIT && !(user->rest&FLAG('G'))) ! 814: bputs(text[UserDefaultsPassword]); ! 815: ! 816: ASYNC; ! 817: bputs(text[UserDefaultsWhich]); ! 818: strcpy(str,"HTBALPRSYFNCQXZ\r"); ! 819: if(cfg.sys_misc&SM_PWEDIT && !(user->rest&FLAG('G'))) ! 820: strcat(str,"W"); ! 821: if(useron.exempt&FLAG('Q') || user->misc&QUIET) ! 822: strcat(str,"D"); ! 823: if(cfg.total_xedits) ! 824: strcat(str,"E"); ! 825: if(cfg.sys_misc&SM_FWDTONET) ! 826: strcat(str,"M"); ! 827: if(startup->options&BBS_OPT_AUTO_LOGON && user->exempt&FLAG('V')) ! 828: strcat(str,"I"); ! 829: if(cfg.total_shells>1) ! 830: strcat(str,"K"); ! 831: ! 832: ch=(char)getkeys(str,0); ! 833: switch(ch) { ! 834: case 'T': ! 835: if(yesno(text[AutoTerminalQ])) { ! 836: user->misc|=AUTOTERM; ! 837: user->misc&=~(ANSI|RIP|WIP|HTML); ! 838: user->misc|=autoterm; } ! 839: else ! 840: user->misc&=~AUTOTERM; ! 841: if(!(user->misc&AUTOTERM)) { ! 842: if(yesno(text[AnsiTerminalQ])) ! 843: user->misc|=ANSI; ! 844: else ! 845: user->misc&=~(ANSI|COLOR); } ! 846: if(user->misc&ANSI) { ! 847: if(yesno(text[ColorTerminalQ])) ! 848: user->misc|=COLOR; ! 849: else ! 850: user->misc&=~COLOR; } ! 851: if(!yesno(text[ExAsciiTerminalQ])) ! 852: user->misc|=NO_EXASCII; ! 853: else ! 854: user->misc&=~NO_EXASCII; ! 855: if(!(user->misc&AUTOTERM)) { ! 856: if(!noyes(text[RipTerminalQ])) ! 857: user->misc|=RIP; ! 858: else ! 859: user->misc&=~RIP; } ! 860: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 861: break; ! 862: case 'B': ! 863: user->misc^=BATCHFLAG; ! 864: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 865: break; ! 866: case 'E': ! 867: if(noyes("Use an external editor")) { ! 868: putuserrec(&cfg,user->number,U_XEDIT,8,nulstr); ! 869: break; } ! 870: if(user->xedit) ! 871: user->xedit--; ! 872: for(i=0;i<cfg.total_xedits;i++) ! 873: uselect(1,i,"External Editor",cfg.xedit[i]->name, cfg.xedit[i]->ar); ! 874: if((i=uselect(0,user->xedit,0,0,0))>=0) ! 875: putuserrec(&cfg,user->number,U_XEDIT,8,cfg.xedit[i]->code); ! 876: break; ! 877: case 'K': /* Command shell */ ! 878: for(i=0;i<cfg.total_shells;i++) ! 879: uselect(1,i,"Command Shell",cfg.shell[i]->name,cfg.shell[i]->ar); ! 880: if((i=uselect(0,user->shell,0,0,0))>=0) ! 881: putuserrec(&cfg,user->number,U_SHELL,8,cfg.shell[i]->code); ! 882: break; ! 883: case 'A': ! 884: for(i=0;i<cfg.total_fcomps;i++) ! 885: uselect(1,i,"Archive Type",cfg.fcomp[i]->ext,cfg.fcomp[i]->ar); ! 886: if((i=uselect(0,0,0,0,0))>=0) ! 887: putuserrec(&cfg,user->number,U_TMPEXT,3,cfg.fcomp[i]->ext); ! 888: break; ! 889: case 'L': ! 890: bputs(text[HowManyRows]); ! 891: if((ch=(char)getnum(99))!=-1) { ! 892: putuserrec(&cfg,user->number,U_ROWS,2,ultoa(ch,tmp,10)); ! 893: if(user==&useron) { ! 894: useron.rows=ch; ! 895: ansi_getlines(); ! 896: } ! 897: } ! 898: break; ! 899: case 'P': ! 900: user->misc^=UPAUSE; ! 901: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 902: break; ! 903: case 'H': ! 904: user->misc^=COLDKEYS; ! 905: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 906: break; ! 907: case 'S': ! 908: user->misc^=SPIN; ! 909: if(!(user->misc&SPIN)) { ! 910: if(!yesno("Spinning cursor on pause prompts")) ! 911: user->misc|=NOPAUSESPIN; ! 912: else ! 913: user->misc&=~NOPAUSESPIN; ! 914: } ! 915: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 916: break; ! 917: case 'F': ! 918: user->misc^=ANFSCAN; ! 919: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 920: break; ! 921: case 'X': ! 922: user->misc^=EXPERT; ! 923: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 924: break; ! 925: case 'R': /* Remember current sub/dir */ ! 926: user->misc^=CURSUB; ! 927: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 928: break; ! 929: case 'Y': /* Prompt for scanning message to you */ ! 930: user->misc^=ASK_SSCAN; ! 931: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 932: break; ! 933: case 'N': /* Prompt for new message/files scanning */ ! 934: user->misc^=ASK_NSCAN; ! 935: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 936: break; ! 937: case 'M': /* NetMail address */ ! 938: if(noyes(text[ForwardMailQ])) ! 939: user->misc&=~NETMAIL; ! 940: else { ! 941: user->misc|=NETMAIL; ! 942: bputs(text[EnterNetMailAddress]); ! 943: if(!getstr(user->netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE)) ! 944: break; ! 945: putuserrec(&cfg,user->number,U_NETMAIL,LEN_NETMAIL,user->netmail); } ! 946: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 947: break; ! 948: case 'C': ! 949: user->misc^=CLRSCRN; ! 950: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 951: break; ! 952: case 'D': ! 953: user->misc^=QUIET; ! 954: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 955: break; ! 956: case 'I': ! 957: user->misc^=AUTOLOGON; ! 958: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 959: break; ! 960: case 'W': ! 961: if(!noyes(text[NewPasswordQ])) { ! 962: bputs(text[CurrentPassword]); ! 963: console|=CON_R_ECHOX; ! 964: ch=getstr(str,LEN_PASS,K_UPPER); ! 965: console&=~(CON_R_ECHOX|CON_L_ECHOX); ! 966: if(strcmp(str,user->pass)) { ! 967: bputs(text[WrongPassword]); ! 968: pause(); ! 969: break; } ! 970: bputs(text[NewPassword]); ! 971: if(!getstr(str,LEN_PASS,K_UPPER|K_LINE)) ! 972: break; ! 973: truncsp(str); ! 974: if(!chkpass(str,user,false)) { ! 975: CRLF; ! 976: pause(); ! 977: break; } ! 978: bputs(text[VerifyPassword]); ! 979: console|=CON_R_ECHOX; ! 980: getstr(tmp,LEN_PASS*2,K_UPPER); ! 981: console&=~(CON_R_ECHOX|CON_L_ECHOX); ! 982: if(strcmp(str,tmp)) { ! 983: bputs(text[WrongPassword]); ! 984: pause(); ! 985: break; } ! 986: if(!online) ! 987: break; ! 988: putuserrec(&cfg,user->number,U_PASS,LEN_PASS,str); ! 989: now=time(NULL); ! 990: putuserrec(&cfg,user->number,U_PWMOD,8,ultoa(now,tmp,16)); ! 991: bputs(text[PasswordChanged]); ! 992: sprintf(str,"%s changed password",useron.alias); ! 993: logline(nulstr,str); ! 994: } ! 995: sprintf(str,"%suser/%04u.sig",cfg.data_dir,user->number); ! 996: if(fexist(str) && yesno("View signature")) ! 997: printfile(str,P_NOATCODES); ! 998: if(!noyes("Create/Edit signature")) ! 999: editfile(str); ! 1000: else if(fexist(str) && !noyes("Delete signature")) ! 1001: remove(str); ! 1002: break; ! 1003: case 'Z': ! 1004: xfer_prot_menu(XFER_DOWNLOAD); ! 1005: SYNC; ! 1006: mnemonics(text[ProtocolOrQuit]); ! 1007: strcpy(str,"Q"); ! 1008: for(i=0;i<cfg.total_prots;i++) ! 1009: if(cfg.prot[i]->dlcmd[0] && chk_ar(cfg.prot[i]->ar,&useron)) { ! 1010: sprintf(tmp,"%c",cfg.prot[i]->mnemonic); ! 1011: strcat(str,tmp); } ! 1012: ch=(char)getkeys(str,0); ! 1013: if(ch=='Q' || sys_status&SS_ABORT) { ! 1014: ch=' '; ! 1015: putuserrec(&cfg,user->number,U_PROT,1,&ch); } ! 1016: else ! 1017: putuserrec(&cfg,user->number,U_PROT,1,&ch); ! 1018: if(yesno(text[HangUpAfterXferQ])) ! 1019: user->misc|=AUTOHANG; ! 1020: else ! 1021: user->misc&=~AUTOHANG; ! 1022: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16)); ! 1023: break; ! 1024: default: ! 1025: return; } } ! 1026: } ! 1027: ! 1028: void sbbs_t::purgeuser(int usernumber) ! 1029: { ! 1030: char str[128]; ! 1031: user_t user; ! 1032: ! 1033: user.number=usernumber; ! 1034: getuserdat(&cfg,&user); ! 1035: sprintf(str,"Purged %s #%u",user.alias,usernumber); ! 1036: logentry("!*",str); ! 1037: delallmail(usernumber); ! 1038: putusername(&cfg,usernumber,nulstr); ! 1039: putuserrec(&cfg,usernumber,U_MISC,8,ultoa(user.misc|DELETED,str,16)); ! 1040: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.