|
|
1.1 root 1: /* useredit.cpp */
2:
3: /* Synchronet online sysop user editor */
4:
1.1.1.2 ! root 5: /* $Id: useredit.cpp,v 1.34 2004/12/01 03:07:32 rswindell Exp $ */
1.1 root 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 2000 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: /****************************************************************************/
1.1.1.2 ! root 52: void sbbs_t::useredit(int usernumber)
1.1 root 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;
1.1.1.2 ! root 59: float f;
1.1 root 60: long l;
61: user_t user;
1.1.1.2 ! root 62: struct tm tm;
1.1 root 63:
1.1.1.2 ! root 64: if(online==ON_REMOTE && console&(CON_R_ECHO|CON_R_INPUT) && !chksyspass())
1.1 root 65: return;
1.1.1.2 ! root 66: #if 0 /* no local logins in v3 */
1.1 root 67: if(online==ON_LOCAL) {
68: if(!(cfg.sys_misc&SM_L_SYSOP))
69: return;
1.1.1.2 ! root 70: if(cfg.node_misc&NM_SYSPW && !chksyspass())
1.1 root 71: return; }
1.1.1.2 ! root 72: #endif
1.1 root 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)
1.1.1.2 ! root 123: bprintf(text[UeditCommentLine],i ? '+' : ' '
1.1 root 124: ,user.comment);
125: else
126: CRLF;
1.1.1.2 ! root 127: if(localtime_r(&user.laston,&tm)==NULL)
1.1 root 128: return;
129: bprintf(text[UserDates]
130: ,unixtodstr(&cfg,user.firston,str),unixtodstr(&cfg,user.expire,tmp)
1.1.1.2 ! root 131: ,unixtodstr(&cfg,user.laston,tmp2),tm.tm_hour, tm.tm_min);
1.1 root 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)
1.1.1.2 ! root 137: f=(float)user.logons/user.posts;
1.1 root 138: else
1.1.1.2 ! root 139: f=0;
1.1 root 140: bprintf(text[UserLogons]
141: ,user.logons,user.ltoday,cfg.level_callsperday[user.level],user.posts
1.1.1.2 ! root 142: ,f ? (uint)(100/f) : user.posts>user.logons ? 100 : 0
1.1 root 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))
1.1.1.2 ! root 179: putusername(&cfg,user.number,user.alias);
1.1 root 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':
1.1.1.2 ! root 185: bprintf(text[EnterYourBirthday]
! 186: ,cfg.sys_misc&SM_EURODATE ? "DD/MM/YY" : "MM/DD/YY");
1.1 root 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));
1.1.1.2 ! root 200: putusername(&cfg,user.number,user.alias); }
1.1 root 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));
1.1.1.2 ! root 217: putusername(&cfg,user.number,nulstr);
1.1 root 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; }
1.1.1.2 ! root 242: if(user.level>useron.level
! 243: && !(useron.exempt&FLAG(c)) && console&CON_R_INPUT)
1.1 root 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=='?') {
1.1.1.2 ! root 270: sprintf(str,"flags%d",i);
1.1 root 271: menu(str);
272: continue; }
273: if(isdigit(c)) {
274: i=c&0xf;
275: continue; }
1.1.1.2 ! root 276: if(user.level>useron.level && console&CON_R_INPUT)
1.1 root 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;
1.1.1.2 ! root 414: FREE_AR(ar); /* assertion here */
1.1 root 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));
1.1.1.2 ! root 500: if((int)i>0) {
1.1 root 501: user.number=i;
1.1.1.2 ! root 502: putusername(&cfg,user.number,user.alias);
1.1 root 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;
1.1.1.2 ! root 576: FREE_AR(ar);
! 577: ar=arstr(NULL,artxt,&cfg);
1.1 root 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--;
1.1.1.2 ! root 621: break;
! 622: } /* switch */
! 623: } /* while */
1.1 root 624: sys_status&=~SS_INUEDIT;
1.1.1.2 ! root 625: FREE_AR(ar);
1.1 root 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) {
1.1.1.2 ! root 655: if(count)
! 656: mswait(100);
! 657: count++;
! 658: }
1.1 root 659:
660: if(count>=LOOP_NODEDAB) {
661: close(file);
662: errormsg(WHERE,ERR_LOCK,"user.dat",i);
1.1.1.2 ! root 663: return(usernum);
! 664: }
1.1 root 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);
1.1.1.2 ! root 670: return(usernum);
! 671: }
1.1 root 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);
1.1.1.2 ! root 679: return(i);
! 680: }
! 681: i++;
! 682: }
1.1 root 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) {
1.1.1.2 ! root 710: if(count)
! 711: mswait(100);
! 712: count++;
! 713: }
1.1 root 714:
715: if(count>=LOOP_NODEDAB) {
716: close(file);
717: errormsg(WHERE,ERR_LOCK,"user.dat",i);
1.1.1.2 ! root 718: return(usernum);
! 719: }
1.1 root 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);
1.1.1.2 ! root 725: return(usernum);
! 726: }
1.1 root 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);
1.1.1.2 ! root 733: return(i);
! 734: }
! 735: i--;
! 736: }
1.1 root 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 "
1.1.1.2 ! root 762: : user->misc&HTML ? "HTML " : nulstr
1.1 root 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
1.1.1.2 ! root 771: sprintf(tmp,"Auto Detect (%ld)",rows);
1.1 root 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]
1.1.1.2 ! root 785: ,user->misc&SPIN ? text[On] : user->misc&NOPAUSESPIN ? text[Off] : "Pause Prompt Only");
1.1 root 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]);
1.1.1.2 ! root 801: if(startup->options&BBS_OPT_AUTO_LOGON && user->exempt&FLAG('V'))
1.1 root 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]);
1.1.1.2 ! root 807: if(user->prot!=' ')
1.1 root 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");
1.1.1.2 ! root 827: if(startup->options&BBS_OPT_AUTO_LOGON && user->exempt&FLAG('V'))
1.1 root 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;
1.1.1.2 ! root 837: user->misc&=~(ANSI|RIP|WIP|HTML);
1.1 root 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]);
1.1.1.2 ! root 891: if((ch=(char)getnum(99))!=-1) {
1.1 root 892: putuserrec(&cfg,user->number,U_ROWS,2,ultoa(ch,tmp,10));
1.1.1.2 ! root 893: if(user==&useron) {
! 894: useron.rows=ch;
! 895: ansi_getlines();
! 896: }
! 897: }
1.1 root 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;
1.1.1.2 ! root 909: if(!(user->misc&SPIN)) {
! 910: if(!yesno("Spinning cursor on pause prompts"))
! 911: user->misc|=NOPAUSESPIN;
! 912: else
! 913: user->misc&=~NOPAUSESPIN;
! 914: }
1.1 root 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':
1.1.1.2 ! root 961: if(!noyes(text[NewPasswordQ])) {
! 962: bputs(text[CurrentPassword]);
! 963: console|=CON_R_ECHOX;
! 964: if(!(cfg.sys_misc&SM_ECHO_PW))
! 965: console|=CON_L_ECHOX;
! 966: ch=getstr(str,LEN_PASS,K_UPPER);
! 967: console&=~(CON_R_ECHOX|CON_L_ECHOX);
! 968: if(strcmp(str,user->pass)) {
! 969: bputs(text[WrongPassword]);
! 970: pause();
! 971: break; }
! 972: bputs(text[NewPassword]);
! 973: if(!getstr(str,LEN_PASS,K_UPPER|K_LINE))
! 974: break;
! 975: truncsp(str);
! 976: if(!chkpass(str,user,false)) {
! 977: CRLF;
! 978: pause();
! 979: break; }
! 980: bputs(text[VerifyPassword]);
! 981: console|=CON_R_ECHOX;
! 982: if(!(cfg.sys_misc&SM_ECHO_PW))
! 983: console|=CON_L_ECHOX;
! 984: getstr(tmp,LEN_PASS*2,K_UPPER);
! 985: console&=~(CON_R_ECHOX|CON_L_ECHOX);
! 986: if(strcmp(str,tmp)) {
! 987: bputs(text[WrongPassword]);
! 988: pause();
! 989: break; }
! 990: if(!online)
! 991: break;
! 992: putuserrec(&cfg,user->number,U_PASS,LEN_PASS,str);
! 993: now=time(NULL);
! 994: putuserrec(&cfg,user->number,U_PWMOD,8,ultoa(now,tmp,16));
! 995: bputs(text[PasswordChanged]);
! 996: sprintf(str,"%s changed password",useron.alias);
! 997: logline(nulstr,str);
! 998: }
! 999: sprintf(str,"%suser/%04u.sig",cfg.data_dir,user->number);
! 1000: if(fexist(str) && yesno("View signature"))
! 1001: printfile(str,P_NOATCODES);
! 1002: if(!noyes("Create/Edit signature"))
! 1003: editfile(str);
! 1004: else if(fexist(str) && !noyes("Delete signature"))
! 1005: remove(str);
1.1 root 1006: break;
1007: case 'Z':
1.1.1.2 ! root 1008: xfer_prot_menu(XFER_DOWNLOAD);
1.1 root 1009: SYNC;
1010: mnemonics(text[ProtocolOrQuit]);
1011: strcpy(str,"Q");
1012: for(i=0;i<cfg.total_prots;i++)
1013: if(cfg.prot[i]->dlcmd[0] && chk_ar(cfg.prot[i]->ar,&useron)) {
1014: sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
1015: strcat(str,tmp); }
1016: ch=(char)getkeys(str,0);
1017: if(ch=='Q' || sys_status&SS_ABORT) {
1.1.1.2 ! root 1018: ch=' ';
1.1 root 1019: putuserrec(&cfg,user->number,U_PROT,1,&ch); }
1020: else
1021: putuserrec(&cfg,user->number,U_PROT,1,&ch);
1022: if(yesno(text[HangUpAfterXferQ]))
1023: user->misc|=AUTOHANG;
1024: else
1025: user->misc&=~AUTOHANG;
1026: putuserrec(&cfg,user->number,U_MISC,8,ultoa(user->misc,str,16));
1027: break;
1028: default:
1029: return; } }
1030: }
1031:
1032: void sbbs_t::purgeuser(int usernumber)
1033: {
1034: char str[128];
1035: user_t user;
1036:
1037: user.number=usernumber;
1038: getuserdat(&cfg,&user);
1039: sprintf(str,"Purged %s #%u",user.alias,usernumber);
1040: logentry("!*",str);
1041: delallmail(usernumber);
1.1.1.2 ! root 1042: putusername(&cfg,usernumber,nulstr);
1.1 root 1043: putuserrec(&cfg,usernumber,U_MISC,8,ultoa(user.misc|DELETED,str,16));
1044: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.