|
|
1.1 root 1: /* logout.cpp */
2:
3: /* Synchronet user logout routines */
4:
1.1.1.2 ! root 5: /* $Id: logout.cpp,v 1.26 2010/03/06 00:13:04 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 2010 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:
41: /****************************************************************************/
42: /* Function that is called after a user hangs up or logs off */
43: /****************************************************************************/
44: void sbbs_t::logout()
45: {
46: char str[256];
47: char tmp[512];
48: int i,j;
49: ushort ttoday;
50: node_t node;
51: struct tm tm;
52:
53: now=time(NULL);
54: if(localtime_r(&now,&tm)==NULL)
55: return;
56:
57: if(!useron.number) { /* Not logged in, so do nothing */
58: if(!online) {
59: sprintf(str,"%s T:%3u sec\r\n"
60: ,hhmmtostr(&cfg,&tm,tmp)
61: ,(uint)(now-answertime));
1.1.1.2 ! root 62: logline("@-",str);
! 63: }
1.1 root 64: return;
65: }
66: strcpy(lastuseron,useron.alias); /* for use with WFC status display */
67:
68: if(useron.rest&FLAG('G')) { /* Reset guest's msg scan cfg */
69: putuserrec(&cfg,useron.number,U_NAME,LEN_NAME,nulstr);
70: batdn_total=0;
71: }
72:
73: batch_create_list();
74:
75: if(sys_status&SS_USERON && thisnode.status!=NODE_QUIET && !(useron.rest&FLAG('Q')))
76: for(i=1;i<=cfg.sys_nodes;i++)
77: if(i!=cfg.node_num) {
78: getnodedat(i,&node,0);
79: if((node.status==NODE_INUSE || node.status==NODE_QUIET)
80: && !(node.misc&NODE_AOFF) && node.useron!=useron.number) {
81: sprintf(str,text[NodeLoggedOff],cfg.node_num
82: ,thisnode.misc&NODE_ANON
83: ? text[UNKNOWN_USER] : useron.alias);
1.1.1.2 ! root 84: putnmsg(&cfg,i,str); }
! 85: }
1.1 root 86:
87: if(!online) { /* NOT re-login */
88:
89: #if 0 /* too soon, handled in node_thread */
90: getnodedat(cfg.node_num,&thisnode,1);
91: thisnode.status=NODE_WFC;
92: thisnode.misc&=~(NODE_INTR|NODE_MSGW|NODE_NMSG
93: |NODE_UDAT|NODE_POFF|NODE_AOFF|NODE_EXT);
94: putnodedat(cfg.node_num,&thisnode);
95: #endif
96:
97: #if 0 /* beep? */
98: if(sys_status&SS_SYSALERT) {
99: mswait(500);
100: offhook();
101: CLS;
102: lputs("\r\n\r\nAlerting Sysop...");
103: while(!lkbrd(1)) {
104: sbbs_beep(1000,200);
105: nosound();
1.1.1.2 ! root 106: mswait(200);
! 107: }
! 108: lkbrd(0);
! 109: }
1.1 root 110: #endif
111: sys_status&=~SS_SYSALERT;
112: if(cfg.sys_logout[0]) /* execute system logout event */
113: external(cmdstr(cfg.sys_logout,nulstr,nulstr,NULL),EX_OUTL|EX_OFFLINE);
114: }
115:
116: if(cfg.logout_mod[0])
117: exec_bin(cfg.logout_mod,&main_csi);
118: backout();
119: sprintf(str,"%smsgs/%4.4u.msg",cfg.data_dir,useron.number);
120: if(!flength(str)) /* remove any 0 byte message files */
121: remove(str);
122:
123: delfiles(cfg.temp_dir,ALLFILES);
124: putmsgptrs();
125: if(!REALSYSOP)
126: logofflist();
127: useron.laston=now;
128:
129: ttoday=useron.ttoday-useron.textra; /* billable time used prev calls */
130: if(ttoday>=cfg.level_timeperday[useron.level])
131: i=0;
132: else
133: i=cfg.level_timeperday[useron.level]-ttoday;
134: if(i>cfg.level_timepercall[useron.level]) /* i=amount of time without min */
135: i=cfg.level_timepercall[useron.level];
136: j=(now-starttime)/60; /* j=billable time online in min */
137: if(i<0) i=0;
138: if(j<0) j=0;
139:
140: if(useron.min && j>i) {
141: j-=i; /* j=time to deduct from min */
142: sprintf(str,"Minute Adjustment: %d",-j);
143: logline(">>",str);
144: if(useron.min>(ulong)j)
145: useron.min-=j;
146: else
147: useron.min=0L;
1.1.1.2 ! root 148: putuserrec(&cfg,useron.number,U_MIN,10,ultoa(useron.min,str,10));
! 149: }
1.1 root 150:
151: if(timeleft>0 && starttime-logontime>0) /* extra time */
152: useron.textra+=(ushort)((starttime-logontime)/60);
153:
154: putuserrec(&cfg,useron.number,U_TEXTRA,5,ultoa(useron.textra,str,10));
155: putuserrec(&cfg,useron.number,U_NS_TIME,8,ultoa(last_ns_time,str,16));
156:
157: logoutuserdat(&cfg, &useron, now, logontime);
158:
159: getusrsubs();
160: getusrdirs();
161: if(usrgrps>0)
162: putuserrec(&cfg,useron.number,U_CURSUB,0,cfg.sub[usrsub[curgrp][cursub[curgrp]]]->code);
163: if(usrlibs>0)
164: putuserrec(&cfg,useron.number,U_CURDIR,0,cfg.dir[usrdir[curlib][curdir[curlib]]]->code);
165: hhmmtostr(&cfg,&tm,str);
166: strcat(str," ");
167: if(sys_status&SS_USERON)
168: sprintf(tmp,"T:%3u R:%3lu P:%3lu E:%3lu F:%3lu "
169: "U:%3luk %lu D:%3luk %lu"
170: ,(uint)(now-logontime)/60,posts_read,logon_posts
171: ,logon_emails,logon_fbacks,logon_ulb/1024UL,logon_uls
172: ,logon_dlb/1024UL,logon_dls);
173: else
174: sprintf(tmp,"T:%3u sec",(uint)(now-answertime));
175: strcat(str,tmp);
176: strcat(str,"\r\n");
177: logline("@-",str);
178: sys_status&=~SS_USERON;
179: answertime=now; // Incase we're relogging on
180: }
181:
182: /****************************************************************************/
183: /* Backout of transactions and statuses for this node */
184: /****************************************************************************/
185: void sbbs_t::backout()
186: {
187: char str[256],code[128],*buf;
188: int i,file;
189: long length,l;
190: file_t f;
191:
192: sprintf(str,"%sbackout.dab",cfg.node_dir);
193: if(flength(str)<1L) {
194: remove(str);
1.1.1.2 ! root 195: return;
! 196: }
1.1 root 197: if((file=nopen(str,O_RDONLY))==-1) {
198: errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
1.1.1.2 ! root 199: return;
! 200: }
! 201: length=(long)filelength(file);
1.1 root 202: if((buf=(char *)malloc(length))==NULL) {
203: close(file);
204: errormsg(WHERE,ERR_ALLOC,str,length);
1.1.1.2 ! root 205: return;
! 206: }
1.1 root 207: if(read(file,buf,length)!=length) {
208: close(file);
209: free(buf);
210: errormsg(WHERE,ERR_READ,str,length);
1.1.1.2 ! root 211: return;
! 212: }
1.1 root 213: close(file);
214: for(l=0;l<length;l+=BO_LEN) {
215: switch(buf[l]) {
216: case BO_OPENFILE: /* file left open */
217: memcpy(code,buf+l+1,8);
218: code[8]=0;
219: for(i=0;i<cfg.total_dirs;i++) /* search by code */
220: if(!stricmp(cfg.dir[i]->code,code))
221: break;
222: if(i<cfg.total_dirs) { /* found internal code */
223: f.dir=i;
224: memcpy(&f.datoffset,buf+l+9,4);
1.1.1.2 ! root 225: closefile(&f);
! 226: }
1.1 root 227: break;
228: default:
1.1.1.2 ! root 229: errormsg(WHERE,ERR_CHK,str,buf[l]); }
! 230: }
1.1 root 231: free(buf);
232: remove(str); /* always remove the backout file */
233: }
234:
235: /****************************************************************************/
236: /* Detailed usage stats for each logon */
237: /****************************************************************************/
238: void sbbs_t::logofflist()
239: {
240: char str[256];
241: int file;
242: struct tm tm, tm_now;
243:
244: if(localtime_r(&now,&tm_now)==NULL)
245: return;
246: if(localtime_r(&logontime,&tm)==NULL)
247: return;
248: sprintf(str,"%slogs/%2.2d%2.2d%2.2d.lol",cfg.logs_dir,tm.tm_mon+1,tm.tm_mday
249: ,TM_YEAR(tm.tm_year));
250: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
251: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
1.1.1.2 ! root 252: return;
! 253: }
1.1 root 254: sprintf(str,"%-*.*s %-2d %-8.8s %2.2d:%2.2d %2.2d:%2.2d %3d%3ld%3ld%3ld%3ld"
255: "%3ld%3ld\r\n",LEN_ALIAS,LEN_ALIAS,useron.alias,cfg.node_num,connection
256: ,tm.tm_hour,tm.tm_min,tm_now.tm_hour,tm_now.tm_min
257: ,(int)(now-logontime)/60,posts_read,logon_posts,logon_emails
258: ,logon_fbacks,logon_uls,logon_dls);
259: write(file,str,strlen(str));
260: close(file);
261: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.