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