|
|
1.1 root 1: /* logon.cpp */
2:
3: /* Synchronet user logon routines */
4:
1.1.1.2 ! root 5: /* $Id: logon.cpp,v 1.38 2004/10/21 08:43:33 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: * *
1.1.1.2 ! root 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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: #include "sbbs.h"
39: #include "cmdshell.h"
40:
1.1.1.2 ! root 41: extern "C" void client_on(SOCKET sock, client_t* client, BOOL update);
1.1 root 42:
43: /****************************************************************************/
44: /* Called once upon each user logging on the board */
45: /* Returns 1 if user passed logon, 0 if user failed. */
46: /****************************************************************************/
47: bool sbbs_t::logon()
48: {
49: char str[256],c;
50: char tmp[512];
51: int file;
52: uint i,j,mailw;
1.1.1.2 ! root 53: long kmode;
1.1 root 54: ulong totallogons;
55: node_t node;
56: struct tm tm;
57:
58: now=time(NULL);
1.1.1.2 ! root 59: if(localtime_r(&now,&tm)==NULL)
1.1 root 60: return(false);
61:
62: if(!useron.number)
63: return(false);
64:
65: client.user=useron.alias;
1.1.1.2 ! root 66: client_on(client_socket,&client,TRUE /* update */);
! 67:
! 68: #ifdef JAVASCRIPT
! 69: js_create_user_objects();
! 70: #endif
1.1 root 71:
72: if(useron.rest&FLAG('Q'))
73: qwklogon=1;
1.1.1.2 ! root 74: if(SYSOP && !(cfg.sys_misc&SM_R_SYSOP))
1.1 root 75: return(false);
76: if(cur_rate<cfg.node_minbps && !(useron.exempt&FLAG('M'))) {
77: bprintf(text[MinimumModemSpeed],cfg.node_minbps);
78: sprintf(str,"%stooslow.msg",cfg.text_dir);
79: if(fexist(str))
80: printfile(str,0);
1.1.1.2 ! root 81: sprintf(str,"(%04u) %-25s Modem speed: %lu<%u"
1.1 root 82: ,useron.number,useron.alias,cur_rate,cfg.node_minbps);
83: logline("+!",str);
1.1.1.2 ! root 84: return(false);
! 85: }
1.1 root 86:
87: if(useron.rest&FLAG('G')) { /* Guest account */
88: useron.misc=(cfg.new_misc&(~ASK_NSCAN));
89: useron.rows=0;
1.1.1.2 ! root 90: useron.misc&=~(ANSI|RIP|WIP|NO_EXASCII|COLOR|HTML);
1.1 root 91: useron.misc|=autoterm;
92: if(!(useron.misc&ANSI) && yesno(text[AnsiTerminalQ]))
93: useron.misc|=ANSI;
1.1.1.2 ! root 94: if(useron.misc&(RIP|WIP|HTML)
1.1 root 95: || (useron.misc&ANSI && yesno(text[ColorTerminalQ])))
96: useron.misc|=COLOR;
97: if(!yesno(text[ExAsciiTerminalQ]))
98: useron.misc|=NO_EXASCII;
99: for(i=0;i<cfg.total_xedits;i++)
100: if(!stricmp(cfg.xedit[i]->code,cfg.new_xedit)
101: && chk_ar(cfg.xedit[i]->ar,&useron))
102: break;
103: if(i<cfg.total_xedits)
104: useron.xedit=i+1;
105: else
106: useron.xedit=0;
107: useron.prot=cfg.new_prot;
1.1.1.2 ! root 108: useron.shell=cfg.new_shell;
! 109: }
1.1 root 110:
111: if(cfg.node_dollars_per_call) {
112: adjustuserrec(&cfg,useron.number,U_CDT,10
113: ,cfg.cdt_per_dollar*cfg.node_dollars_per_call);
114: bprintf(text[CreditedAccount]
115: ,cfg.cdt_per_dollar*cfg.node_dollars_per_call);
1.1.1.2 ! root 116: sprintf(str,"%s #%u was billed $%d T: %lu seconds"
1.1 root 117: ,useron.alias,useron.number
1.1.1.2 ! root 118: ,cfg.node_dollars_per_call,(ulong)(now-answertime));
1.1 root 119: logline("$+",str);
120: hangup();
1.1.1.2 ! root 121: return(false);
! 122: }
1.1 root 123:
124: if(!chk_ar(cfg.node_ar,&useron)) {
125: bputs(text[NoNodeAccess]);
126: sprintf(str,"(%04u) %-25s Insufficient node access"
127: ,useron.number,useron.alias);
128: logline("+!",str);
1.1.1.2 ! root 129: return(false);
! 130: }
1.1 root 131:
132: getnodedat(cfg.node_num,&thisnode,1);
133: if(thisnode.misc&NODE_LOCK) {
134: putnodedat(cfg.node_num,&thisnode); /* must unlock! */
135: if(!SYSOP && !(useron.exempt&FLAG('N'))) {
136: bputs(text[NodeLocked]);
137: sprintf(str,"(%04u) %-25s Locked node logon attempt"
138: ,useron.number,useron.alias);
139: logline("+!",str);
1.1.1.2 ! root 140: return(false);
! 141: }
1.1 root 142: if(yesno(text[RemoveNodeLockQ])) {
143: getnodedat(cfg.node_num,&thisnode,1);
144: logline("S-","Removed Node Lock");
1.1.1.2 ! root 145: thisnode.misc&=~NODE_LOCK;
! 146: }
1.1 root 147: else
1.1.1.2 ! root 148: getnodedat(cfg.node_num,&thisnode,1);
! 149: }
! 150:
! 151: if(useron.exempt&FLAG('H'))
! 152: console|=CON_NO_INACT;
1.1 root 153:
154: if((useron.exempt&FLAG('Q') && useron.misc&QUIET))
155: thisnode.status=NODE_QUIET;
156: else
157: thisnode.status=NODE_INUSE;
158: action=thisnode.action=NODE_LOGN;
159: thisnode.connection=0xffff;
160: thisnode.misc&=~(NODE_ANON|NODE_INTR|NODE_MSGW|NODE_POFF|NODE_AOFF);
161: if(useron.chat&CHAT_NOACT)
162: thisnode.misc|=NODE_AOFF;
163: if(useron.chat&CHAT_NOPAGE)
164: thisnode.misc|=NODE_POFF;
165: thisnode.useron=useron.number;
166: putnodedat(cfg.node_num,&thisnode);
167:
168: getusrsubs();
169: getusrdirs();
170:
171: if(useron.misc&CURSUB && !(useron.rest&FLAG('G'))) {
172: for(i=0;i<usrgrps;i++) {
173: for(j=0;j<usrsubs[i];j++) {
174: if(!strcmp(cfg.sub[usrsub[i][j]]->code,useron.cursub))
1.1.1.2 ! root 175: break;
! 176: }
1.1 root 177: if(j<usrsubs[i]) {
178: curgrp=i;
179: cursub[i]=j;
1.1.1.2 ! root 180: break;
! 181: }
! 182: }
1.1 root 183: for(i=0;i<usrlibs;i++) {
184: for(j=0;j<usrdirs[i];j++)
185: if(!strcmp(cfg.dir[usrdir[i][j]]->code,useron.curdir))
186: break;
187: if(j<usrdirs[i]) {
188: curlib=i;
189: curdir[i]=j;
1.1.1.2 ! root 190: break;
! 191: }
! 192: }
! 193: }
1.1 root 194:
195:
196: if(useron.misc&AUTOTERM) {
1.1.1.2 ! root 197: useron.misc&=~(ANSI|RIP|WIP|HTML);
! 198: useron.misc|=autoterm;
! 199: }
1.1 root 200:
201: if(!chk_ar(cfg.shell[useron.shell]->ar,&useron)) {
202: useron.shell=cfg.new_shell;
203: if(!chk_ar(cfg.shell[useron.shell]->ar,&useron)) {
204: for(i=0;i<cfg.total_shells;i++)
205: if(chk_ar(cfg.shell[i]->ar,&useron))
206: break;
207: if(i==cfg.total_shells)
1.1.1.2 ! root 208: useron.shell=0;
! 209: }
! 210: }
1.1 root 211:
212: logon_ml=useron.level;
213: logontime=time(NULL);
214: starttime=logontime;
1.1.1.2 ! root 215: useron.logontime=logontime;
1.1 root 216: last_ns_time=ns_time=useron.ns_time;
217: // ns_time-=(useron.tlast*60); /* file newscan time == last logon time */
218: delfiles(cfg.temp_dir,ALLFILES);
219: sprintf(str,"%smsgs/n%3.3u.msg",cfg.data_dir,cfg.node_num);
220: remove(str); /* remove any pending node messages */
221: sprintf(str,"%smsgs/n%3.3u.ixb",cfg.data_dir,cfg.node_num);
222: remove(str); /* remove any pending node message indices */
223:
1.1.1.2 ! root 224: if(!SYSOP && online==ON_REMOTE && !qwklogon) {
1.1 root 225: rioctl(IOCM|ABORT); /* users can't abort anything */
1.1.1.2 ! root 226: rioctl(IOCS|ABORT);
! 227: }
1.1 root 228:
229: CLS;
230: if(useron.rows)
231: rows=useron.rows;
232: else if(online==ON_LOCAL)
233: rows=cfg.node_scrnlen-1;
234: unixtodstr(&cfg,logontime,str);
235: if(!strncmp(str,useron.birth,5) && !(useron.rest&FLAG('Q'))) {
236: bputs(text[HappyBirthday]);
237: pause();
238: CLS;
1.1.1.2 ! root 239: user_event(EVENT_BIRTHDAY);
! 240: }
1.1 root 241: unixtodstr(&cfg,useron.laston,tmp);
242: if(strcmp(str,tmp)) { /* str still equals logon time */
243: useron.ltoday=1;
244: useron.ttoday=useron.etoday=useron.ptoday=useron.textra=0;
1.1.1.2 ! root 245: useron.freecdt=cfg.level_freecdtperday[useron.level];
! 246: }
1.1 root 247: else
248: useron.ltoday++;
249:
250: gettimeleft();
251: sprintf(str,"%sfile/%04u.dwn",cfg.data_dir,useron.number);
252: batch_add_list(str);
253: if(!qwklogon) { /* QWK Nodes don't go through this */
254:
255: if(cfg.sys_pwdays
256: && (ulong)logontime>(useron.pwmod+((ulong)cfg.sys_pwdays*24UL*60UL*60UL))) {
257: bprintf(text[TimeToChangePw],cfg.sys_pwdays);
258:
259: c=0;
260: while(c<LEN_PASS) { /* Create random password */
261: str[c]=sbbs_random(43)+'0';
262: if(isalnum(str[c]))
1.1.1.2 ! root 263: c++;
! 264: }
1.1 root 265: str[c]=0;
266: bprintf(text[YourPasswordIs],str);
267:
268: if(cfg.sys_misc&SM_PWEDIT && yesno(text[NewPasswordQ]))
269: while(online) {
270: bputs(text[NewPassword]);
271: getstr(str,LEN_PASS,K_UPPER|K_LINE);
272: truncsp(str);
273: if(chkpass(str,&useron,true))
274: break;
1.1.1.2 ! root 275: CRLF;
! 276: }
1.1 root 277:
278: while(online) {
279: if(cfg.sys_misc&SM_PWEDIT) {
280: CRLF;
1.1.1.2 ! root 281: bputs(text[VerifyPassword]);
! 282: }
1.1 root 283: else
284: bputs(text[NewUserPasswordVerify]);
285: console|=CON_R_ECHOX;
286: if(!(cfg.sys_misc&SM_ECHO_PW))
287: console|=CON_L_ECHOX;
1.1.1.2 ! root 288: getstr(tmp,LEN_PASS*2,K_UPPER);
1.1 root 289: console&=~(CON_R_ECHOX|CON_L_ECHOX);
290: if(strcmp(str,tmp)) {
291: bputs(text[Wrong]);
1.1.1.2 ! root 292: continue;
! 293: }
! 294: break;
! 295: }
1.1 root 296: strcpy(useron.pass,str);
297: useron.pwmod=time(NULL);
298: putuserrec(&cfg,useron.number,U_PWMOD,8,ultoa(useron.pwmod,str,16));
299: bputs(text[PasswordChanged]);
1.1.1.2 ! root 300: pause();
! 301: }
1.1 root 302: if(useron.ltoday>cfg.level_callsperday[useron.level]
303: && !(useron.exempt&FLAG('L'))) {
304: bputs(text[NoMoreLogons]);
305: sprintf(str,"(%04u) %-25s Out of logons"
306: ,useron.number,useron.alias);
307: logline("+!",str);
308: hangup();
1.1.1.2 ! root 309: return(false);
! 310: }
1.1 root 311: if(useron.rest&FLAG('L') && useron.ltoday>1) {
312: bputs(text[R_Logons]);
313: sprintf(str,"(%04u) %-25s Out of logons"
314: ,useron.number,useron.alias);
315: logline("+!",str);
316: hangup();
1.1.1.2 ! root 317: return(false);
! 318: }
! 319: kmode=(cfg.uq&UQ_NOEXASC);
! 320: if(!(cfg.uq&UQ_NOUPRLWR))
! 321: kmode|=K_UPRLWR;
! 322:
1.1 root 323: if(!(useron.rest&FLAG('G'))) {
324: if(!useron.name[0] && ((cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME)
325: || cfg.uq&UQ_COMPANY))
326: while(online) {
327: if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME)
328: bputs(text[EnterYourRealName]);
329: else
330: bputs(text[EnterYourCompany]);
1.1.1.2 ! root 331: getstr(useron.name,LEN_NAME,kmode);
1.1 root 332: if(cfg.uq&UQ_ALIASES && cfg.uq&UQ_REALNAME) {
333: if(trashcan(useron.name,"name") || !useron.name[0]
1.1.1.2 ! root 334: || !strchr(useron.name,' ')
1.1 root 335: || strchr(useron.name,0xff)
336: || (cfg.uq&UQ_DUPREAL
337: && userdatdupe(useron.number,U_NAME,LEN_NAME
338: ,useron.name,0)))
339: bputs(text[YouCantUseThatName]);
340: else
1.1.1.2 ! root 341: break;
! 342: }
1.1 root 343: else
1.1.1.2 ! root 344: break;
! 345: }
1.1 root 346: if(cfg.uq&UQ_HANDLE && !useron.handle[0]) {
347: sprintf(useron.handle,"%.*s",LEN_HANDLE,useron.alias);
348: while(online) {
349: bputs(text[EnterYourHandle]);
350: if(!getstr(useron.handle,LEN_HANDLE
351: ,K_LINE|K_EDIT|K_AUTODEL|(cfg.uq&UQ_NOEXASC))
352: || strchr(useron.handle,0xff)
353: || (cfg.uq&UQ_DUPHAND
354: && userdatdupe(useron.number,U_HANDLE,LEN_HANDLE
355: ,useron.handle,0))
356: || trashcan(useron.handle,"name"))
357: bputs(text[YouCantUseThatName]);
358: else
1.1.1.2 ! root 359: break;
! 360: }
! 361: }
1.1 root 362: if(cfg.uq&UQ_LOCATION && !useron.location[0])
363: while(online) {
364: bputs(text[EnterYourCityState]);
1.1.1.2 ! root 365: if(getstr(useron.location,LEN_LOCATION,kmode))
! 366: break;
! 367: }
1.1 root 368: if(cfg.uq&UQ_ADDRESS && !useron.address[0])
369: while(online) {
370: bputs(text[EnterYourAddress]);
1.1.1.2 ! root 371: if(getstr(useron.address,LEN_ADDRESS,kmode))
! 372: break;
! 373: }
1.1 root 374: if(cfg.uq&UQ_ADDRESS && !useron.zipcode[0])
375: while(online) {
376: bputs(text[EnterYourZipCode]);
377: if(getstr(useron.zipcode,LEN_ZIPCODE,K_UPPER|(cfg.uq&UQ_NOEXASC)))
1.1.1.2 ! root 378: break;
! 379: }
1.1 root 380: if(cfg.uq&UQ_PHONE && !useron.phone[0]) {
381: i=yesno(text[CallingFromNorthAmericaQ]);
382: while(online) {
383: bputs(text[EnterYourPhoneNumber]);
384: if(i) {
385: if(gettmplt(useron.phone,cfg.sys_phonefmt
386: ,K_LINE|(cfg.uq&UQ_NOEXASC))<strlen(cfg.sys_phonefmt))
1.1.1.2 ! root 387: continue;
! 388: } else {
1.1 root 389: if(getstr(useron.phone,LEN_PHONE
390: ,K_UPPER|(cfg.uq&UQ_NOEXASC))<5)
1.1.1.2 ! root 391: continue;
! 392: }
1.1 root 393: if(!trashcan(useron.phone,"phone"))
1.1.1.2 ! root 394: break;
! 395: }
! 396: }
1.1 root 397: if(!(sys_status&SS_RLOGIN)
1.1.1.2 ! root 398: && !(cfg.uq&UQ_NONETMAIL) && !useron.netmail[0]) {
1.1 root 399: while(online) {
400: bputs(text[EnterNetMailAddress]);
1.1.1.2 ! root 401: if(getstr(useron.netmail,LEN_NETMAIL,K_EDIT|K_AUTODEL|K_LINE)
! 402: && !trashcan(useron.netmail,"email"))
1.1 root 403: break;
404: }
1.1.1.2 ! root 405: if(useron.netmail[0] && cfg.sys_misc&SM_FWDTONET && !noyes(text[ForwardMailQ]))
1.1 root 406: useron.misc|=NETMAIL;
407: else
408: useron.misc&=~NETMAIL;
409: }
410: if(cfg.new_sif[0]) {
411: sprintf(str,"%suser/%4.4u.dat",cfg.data_dir,useron.number);
412: if(flength(str)<1L)
1.1.1.2 ! root 413: create_sif_dat(cfg.new_sif,str);
! 414: }
1.1 root 415: }
416: }
417: if(!online) {
418: sprintf(str,"(%04u) %-25s Unsuccessful logon"
419: ,useron.number,useron.alias);
420: logline("+!",str);
1.1.1.2 ! root 421: return(false);
! 422: }
1.1 root 423: strcpy(useron.modem,connection);
424: useron.logons++;
425: putuserdat(&cfg,&useron);
426: getmsgptrs();
427: sys_status|=SS_USERON; /* moved from further down */
428:
429: if(useron.rest&FLAG('Q')) {
430: sprintf(str,"(%04u) %-25s QWK Network Connection"
431: ,useron.number,useron.alias);
432: logline("++",str);
1.1.1.2 ! root 433: return(true);
! 434: }
1.1 root 435:
436: /********************/
437: /* SUCCESSFUL LOGON */
438: /********************/
439: totallogons=logonstats();
440: sprintf(str,"(%04u) %-25s Logon %lu - %u"
441: ,useron.number,useron.alias,totallogons,useron.ltoday);
442: logline("++",str);
443:
444: if(!qwklogon && cfg.logon_mod[0])
445: exec_bin(cfg.logon_mod,&main_csi);
446:
447: if(thisnode.status!=NODE_QUIET && (!REALSYSOP || cfg.sys_misc&SM_SYSSTAT)) {
448: sprintf(str,"%slogon.lst",cfg.data_dir);
449: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
450: errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_CREAT|O_APPEND);
1.1.1.2 ! root 451: return(false);
! 452: }
! 453: getuserrec(&cfg,useron.number,U_NOTE,LEN_NOTE,useron.note);
! 454: getuserrec(&cfg,useron.number,U_LOCATION,LEN_LOCATION,useron.location);
1.1 root 455: sprintf(str,text[LastFewCallersFmt],cfg.node_num
456: ,totallogons,useron.alias
457: ,cfg.sys_misc&SM_LISTLOC ? useron.location : useron.note
458: ,tm.tm_hour,tm.tm_min
459: ,connection,useron.ltoday);
460: write(file,str,strlen(str));
1.1.1.2 ! root 461: close(file);
! 462: }
1.1 root 463:
464: if(cfg.sys_logon[0]) /* execute system logon event */
1.1.1.2 ! root 465: external(cmdstr(cfg.sys_logon,nulstr,nulstr,NULL),EX_OUTR|EX_OUTL); /* EX_SH */
1.1 root 466:
467: if(qwklogon)
468: return(true);
469:
470: sys_status|=SS_PAUSEON; /* always force pause on during this section */
471: mailw=getmail(&cfg,useron.number,0);
1.1.1.2 ! root 472:
! 473: if(!(cfg.sys_misc&SM_NOSYSINFO)) {
! 474: bprintf(text[SiSysName],cfg.sys_name);
! 475: //bprintf(text[SiNodeNumberName],cfg.node_num,cfg.node_name);
! 476: bprintf(text[LiUserNumberName],useron.number,useron.alias);
! 477: bprintf(text[LiLogonsToday],useron.ltoday
! 478: ,cfg.level_callsperday[useron.level]);
! 479: bprintf(text[LiTimeonToday],useron.ttoday
! 480: ,cfg.level_timeperday[useron.level]+useron.min);
! 481: bprintf(text[LiMailWaiting],mailw);
! 482: strcpy(str,text[LiSysopIs]);
! 483: if(startup->options&BBS_OPT_SYSOP_AVAILABLE
! 484: || (cfg.sys_chat_ar[0] && chk_ar(cfg.sys_chat_ar,&useron)))
! 485: strcat(str,text[LiSysopAvailable]);
! 486: else
! 487: strcat(str,text[LiSysopNotAvailable]);
! 488: bprintf("%s\r\n\r\n",str);
! 489: }
! 490:
1.1 root 491: if(sys_status&SS_EVENT)
1.1.1.2 ! root 492: bprintf(text[ReducedTime],timestr(&event_time));
1.1 root 493: getnodedat(cfg.node_num,&thisnode,1);
494: thisnode.misc&=~(NODE_AOFF|NODE_POFF);
495: if(useron.chat&CHAT_NOACT)
496: thisnode.misc|=NODE_AOFF;
497: if(useron.chat&CHAT_NOPAGE)
498: thisnode.misc|=NODE_POFF;
499: putnodedat(cfg.node_num,&thisnode);
1.1.1.2 ! root 500:
1.1 root 501: getsmsg(useron.number); /* Moved from further down */
502: SYNC;
503: c=0;
504: for(i=1;i<=cfg.sys_nodes;i++)
505: if(i!=cfg.node_num) {
506: getnodedat(i,&node,0);
1.1.1.2 ! root 507: if(!(cfg.sys_misc&SM_NONODELIST)
! 508: && (node.status==NODE_INUSE
! 509: || ((node.status==NODE_QUIET || node.errors) && SYSOP))) {
1.1 root 510: if(!c)
511: bputs(text[NodeLstHdr]);
512: printnodedat(i,&node);
1.1.1.2 ! root 513: c=1;
! 514: }
1.1 root 515: if(node.status==NODE_INUSE && i!=cfg.node_num && node.useron==useron.number
516: && !SYSOP && !(useron.exempt&FLAG('G'))) {
517: strcpy(tmp,"On two nodes at the same time");
518: sprintf(str,"(%04u) %-25s %s"
519: ,useron.number,useron.alias,tmp);
520: logline("+!",str);
521: errorlog(tmp);
522: bputs(text[UserOnTwoNodes]);
523: hangup();
1.1.1.2 ! root 524: return(false);
! 525: }
1.1 root 526: if(thisnode.status!=NODE_QUIET
527: && (node.status==NODE_INUSE || node.status==NODE_QUIET)
528: && !(node.misc&NODE_AOFF) && node.useron!=useron.number) {
529: sprintf(str,text[NodeLoggedOnAtNbps]
530: ,cfg.node_num
531: ,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias
532: ,connection);
1.1.1.2 ! root 533: putnmsg(&cfg,i,str);
! 534: }
! 535: }
1.1 root 536:
537: if(cfg.sys_exp_warn && useron.expire && useron.expire>now /* Warn user of coming */
538: && (useron.expire-now)/(1440L*60L)<=cfg.sys_exp_warn) /* expiration */
539: bprintf(text[AccountWillExpireInNDays],(useron.expire-now)/(1440L*60L));
540:
541: if(criterrs && SYSOP)
542: bprintf(text[CriticalErrors],criterrs);
1.1.1.2 ! root 543: if((i=getuserxfers(0,useron.number,0))!=0)
! 544: bprintf(text[UserXferForYou],i,i>1 ? "s" : nulstr);
! 545: if((i=getuserxfers(useron.number,0,0))!=0)
! 546: bprintf(text[UnreceivedUserXfer],i,i>1 ? "s" : nulstr);
1.1 root 547: SYNC;
548: sys_status&=~SS_PAUSEON; /* Turn off the pause override flag */
549: if(online==ON_REMOTE)
550: rioctl(IOSM|ABORT); /* Turn abort ability on */
551: if(mailw) {
552: if(yesno(text[ReadYourMailNowQ]))
1.1.1.2 ! root 553: readmail(useron.number,MAIL_YOUR);
! 554: }
! 555: if(usrgrps && useron.misc&ASK_NSCAN && yesno(text[NScanAllGrpsQ]))
1.1 root 556: scanallsubs(SCAN_NEW);
1.1.1.2 ! root 557: if(usrgrps && useron.misc&ASK_SSCAN && yesno(text[SScanAllGrpsQ]))
1.1 root 558: scanallsubs(SCAN_TOYOU);
559: return(true);
560: }
561:
562: /****************************************************************************/
563: /* Checks the system dsts.dab to see if it is a new day, if it is, all the */
564: /* nodes' and the system's csts.dab are added to, and the dsts.dab's daily */
565: /* stats are cleared. Also increments the logon values in dsts.dab if */
566: /* applicable. */
567: /****************************************************************************/
568: ulong sbbs_t::logonstats()
569: {
570: char str[256];
571: int dsts,csts;
572: uint i;
1.1.1.2 ! root 573: time_t update_t=0;
1.1 root 574: stats_t stats;
575: node_t node;
1.1.1.2 ! root 576: struct tm tm, update_tm;
1.1 root 577:
1.1.1.2 ! root 578: memset(&stats,0,sizeof(stats));
1.1 root 579: sprintf(str,"%sdsts.dab",cfg.ctrl_dir);
580: if((dsts=nopen(str,O_RDWR))==-1) {
581: errormsg(WHERE,ERR_OPEN,str,O_RDWR);
1.1.1.2 ! root 582: return(0L);
! 583: }
1.1 root 584: read(dsts,&update_t,4); /* Last updated */
585: read(dsts,&stats.logons,4); /* Total number of logons on system */
586: close(dsts);
587: if(update_t>now+(24L*60L*60L)) /* More than a day in the future? */
588: errormsg(WHERE,ERR_CHK,"Daily stats time stamp",update_t);
1.1.1.2 ! root 589: if(localtime_r(&update_t,&update_tm)==NULL)
1.1 root 590: return(0);
1.1.1.2 ! root 591: if(localtime_r(&now,&tm)==NULL)
1.1 root 592: return(0);
1.1.1.2 ! root 593: if((tm.tm_mday>update_tm.tm_mday && tm.tm_mon==update_tm.tm_mon)
! 594: || tm.tm_mon>update_tm.tm_mon || tm.tm_year>update_tm.tm_year) {
1.1 root 595:
596: sprintf(str,"New Day - Prev: %s ",timestr(&update_t));
597: logentry("!=",str);
598:
599: sys_status|=SS_DAILY; /* New Day !!! */
600: sprintf(str,"%slogon.lst",cfg.data_dir); /* Truncate logon list */
601: if((dsts=nopen(str,O_TRUNC|O_CREAT|O_WRONLY))==-1) {
602: errormsg(WHERE,ERR_OPEN,str,O_TRUNC|O_CREAT|O_WRONLY);
1.1.1.2 ! root 603: return(0L);
! 604: }
1.1 root 605: close(dsts);
606: for(i=0;i<=cfg.sys_nodes;i++) {
607: if(i) { /* updating a node */
608: getnodedat(i,&node,1);
609: node.misc|=NODE_EVENT;
1.1.1.2 ! root 610: putnodedat(i,&node);
! 611: }
1.1 root 612: sprintf(str,"%sdsts.dab",i ? cfg.node_path[i-1] : cfg.ctrl_dir);
613: if((dsts=nopen(str,O_RDWR))==-1) /* node doesn't have stats yet */
614: continue;
615: sprintf(str,"%scsts.dab",i ? cfg.node_path[i-1] : cfg.ctrl_dir);
616: if((csts=nopen(str,O_WRONLY|O_APPEND|O_CREAT))==-1) {
617: close(dsts);
618: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_APPEND|O_CREAT);
1.1.1.2 ! root 619: continue;
! 620: }
1.1 root 621: lseek(dsts,8L,SEEK_SET); /* Skip time and logons */
622: write(csts,&now,4);
623: read(dsts,&stats.ltoday,4);
624: write(csts,&stats.ltoday,4);
625: lseek(dsts,4L,SEEK_CUR); /* Skip total time on */
626: read(dsts,&stats.ttoday,4);
627: write(csts,&stats.ttoday,4);
628: read(dsts,&stats.uls,4);
629: write(csts,&stats.uls,4);
630: read(dsts,&stats.ulb,4);
631: write(csts,&stats.ulb,4);
632: read(dsts,&stats.dls,4);
633: write(csts,&stats.dls,4);
634: read(dsts,&stats.dlb,4);
635: write(csts,&stats.dlb,4);
636: read(dsts,&stats.ptoday,4);
637: write(csts,&stats.ptoday,4);
638: read(dsts,&stats.etoday,4);
639: write(csts,&stats.etoday,4);
640: read(dsts,&stats.ftoday,4);
641: write(csts,&stats.ftoday,4);
642: close(csts);
643: lseek(dsts,0L,SEEK_SET); /* Go back to beginning */
644: write(dsts,&now,4); /* Update time stamp */
645: lseek(dsts,4L,SEEK_CUR); /* Skip total logons */
646: stats.ltoday=0;
647: write(dsts,&stats.ltoday,4); /* Logons today to 0 */
648: lseek(dsts,4L,SEEK_CUR); /* Skip total time on */
649: stats.ttoday=0; /* Set all other today variables to 0 */
650: write(dsts,&stats.ttoday,4); /* Time on today to 0 */
651: write(dsts,&stats.ttoday,4); /* Uploads today to 0 */
652: write(dsts,&stats.ttoday,4); /* U/L Bytes today */
653: write(dsts,&stats.ttoday,4); /* Download today */
654: write(dsts,&stats.ttoday,4); /* Download bytes */
655: write(dsts,&stats.ttoday,4); /* Posts today */
656: write(dsts,&stats.ttoday,4); /* Emails today */
657: write(dsts,&stats.ttoday,4); /* Feedback today */
658: write(dsts,&stats.ttoday,2); /* New users Today */
1.1.1.2 ! root 659: close(dsts);
! 660: }
! 661: }
1.1 root 662:
663: if(thisnode.status==NODE_QUIET) /* Quiet users aren't counted */
664: return(0);
665:
666: if(REALSYSOP && !(cfg.sys_misc&SM_SYSSTAT))
667: return(0);
668:
669: for(i=0;i<2;i++) {
670: sprintf(str,"%sdsts.dab",i ? cfg.ctrl_dir : cfg.node_dir);
671: if((dsts=nopen(str,O_RDWR))==-1) {
672: errormsg(WHERE,ERR_OPEN,str,O_RDWR);
1.1.1.2 ! root 673: return(0L);
! 674: }
1.1 root 675: lseek(dsts,4L,SEEK_SET); /* Skip time stamp */
676: read(dsts,&stats.logons,4);
677: read(dsts,&stats.ltoday,4);
678: stats.logons++;
679: stats.ltoday++;
680: lseek(dsts,4L,SEEK_SET); /* Rewind back and overwrite */
681: write(dsts,&stats.logons,4);
682: write(dsts,&stats.ltoday,4);
1.1.1.2 ! root 683: close(dsts);
! 684: }
1.1 root 685: return(stats.logons);
686: }
687:
688:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.