|
|
1.1 root 1: /* getnode.cpp */
2:
3: /* Synchronet node information retrieval functions */
4:
5: /* $Id: getnode.cpp,v 1.6 2000/12/11 23:21:11 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 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: #include "sbbs.h"
39: #include "cmdshell.h"
40:
41: /****************************************************************************/
42: /* Reads the data for node number 'number' into the structure 'node' */
43: /* from NODE.DAB */
44: /* if lockit is non-zero, locks this node's record. putnodedat() unlocks it */
45: /****************************************************************************/
46: void sbbs_t::getnodedat(uint number, node_t *node, bool lockit)
47: {
48: char str[256];
49: int count=0;
50:
51: if(!number || number>cfg.sys_nodes) {
52: errormsg(WHERE,ERR_CHK,"node number",number);
53: return; }
54:
55: if(nodefile==-1) {
56: sprintf(str,"%snode.dab",cfg.ctrl_dir);
57: if((nodefile=nopen(str,O_RDWR|O_DENYNONE))==-1) {
58: memset(node,0,sizeof(node_t));
59: errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE);
60: return;
61: }
62: }
63:
64: number--; /* make zero based */
65: while(count<LOOP_NODEDAB) {
66: if(count>10)
67: mswait(100);
68: lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET);
69: if(lockit
70: && lock(nodefile,(long)number*sizeof(node_t),sizeof(node_t))==-1) {
71: count++;
72: continue; }
73: if(read(nodefile,node,sizeof(node_t))==sizeof(node_t))
74: break;
75: count++;
76: }
77: if(!lockit) {
78: close(nodefile);
79: nodefile=-1;
80: }
81:
82: if(count>(LOOP_NODEDAB/2) && count!=LOOP_NODEDAB) {
83: sprintf(str,"NODE.DAB COLLISION - Count: %d",count);
84: logline("!!",str); }
85: if(count==LOOP_NODEDAB) {
86: errormsg(WHERE,ERR_READ,"node.dab",number+1);
87: return;
88: }
89: }
90:
91: /****************************************************************************/
92: /* Synchronizes all the nodes knowledge of the other nodes' actions, mode, */
93: /* status and other flags. */
94: /* Assumes that getnodedat(node_num,&thisnode,0) was called right before it */
95: /* is called. */
96: /****************************************************************************/
97: void sbbs_t::nodesync()
98: {
99: char str[256],today[32];
100: int atr=curatr; /* was lclatr(-1) 01/29/96 */
101:
102: if(nodesync_inside) return;
103: nodesync_inside=1;
104:
105: if(thisnode.action!=action) {
106: getnodedat(cfg.node_num,&thisnode,1);
107: thisnode.action=action;
108: putnodedat(cfg.node_num,&thisnode); }
109:
110: criterrs=thisnode.errors;
111:
112: if(sys_status&SS_USERON) {
113: if(!(sys_status&SS_NEWDAY)) {
114: now=time(NULL);
115: unixtodstr(&cfg,logontime,str);
116: unixtodstr(&cfg,now,today);
117: if(strcmp(str,today)) { /* New day, clear "today" user vars */
118: sys_status|=SS_NEWDAY; // So we don't keep doing this over&over
119: putuserrec(&cfg,useron.number,U_ETODAY,5,"0");
120: putuserrec(&cfg,useron.number,U_PTODAY,5,"0");
121: putuserrec(&cfg,useron.number,U_TTODAY,5,"0");
122: putuserrec(&cfg,useron.number,U_LTODAY,5,"0");
123: putuserrec(&cfg,useron.number,U_TEXTRA,5,"0");
124: putuserrec(&cfg,useron.number,U_FREECDT,10
125: ,ultoa(cfg.level_freecdtperday[useron.level],str,10));
126: getuserdat(&cfg, &useron); } }
127: if(thisnode.misc&NODE_UDAT && !(useron.rest&FLAG('G'))) { /* not guest */
128: getuserdat(&cfg, &useron);
129: getnodedat(cfg.node_num,&thisnode,1);
130: thisnode.misc&=~NODE_UDAT;
131: putnodedat(cfg.node_num,&thisnode); }
132: if(thisnode.misc&NODE_MSGW)
133: getsmsg(useron.number); /* getsmsg clears MSGW flag */
134: if(thisnode.misc&NODE_NMSG)
135: getnmsg(); } /* getnmsg clears NMSG flag */
136:
137: if(cfg.sync_mod[0])
138: exec_bin(cfg.sync_mod,&main_csi);
139:
140: if(thisnode.misc&NODE_INTR) {
141: bputs(text[NodeLocked]);
142: logline(nulstr,"Interrupted");
143: hangup();
144: nodesync_inside=0;
145: return; }
146:
147: if(thisnode.misc&NODE_LCHAT) { // pulled into local chat with sysop
148: SAVELINE;
149: privchat(true);
150: RESTORELINE;
151: }
152:
153: if(sys_status&SS_USERON && memcmp(&nodesync_user,&useron,sizeof(user_t))) {
154: getusrdirs();
155: getusrsubs();
156: memcpy(&nodesync_user,&useron,sizeof(nodesync_user)); }
157:
158: if(sys_status&SS_USERON && online && (timeleft/60)<(5-timeleft_warn)
159: && !SYSOP) {
160: timeleft_warn=5-(timeleft/60);
161: attr(LIGHTGRAY);
162: bprintf(text[OnlyXminutesLeft]
163: ,((ushort)timeleft/60)+1,(timeleft/60) ? "s" : nulstr); }
164:
165: attr(atr); /* replace original attributes */
166: nodesync_inside=0;
167: }
168:
169: /****************************************************************************/
170: /* Prints short messages waiting for this node, if any... */
171: /****************************************************************************/
172: void sbbs_t::getnmsg()
173: {
174: char str[256], HUGE16 *buf;
175: int file;
176: long length;
177:
178: getnodedat(cfg.node_num,&thisnode,1);
179: thisnode.misc&=~NODE_NMSG; /* clear the NMSG flag */
180: putnodedat(cfg.node_num,&thisnode);
181:
182: sprintf(str,"%smsgs/n%3.3u.msg",cfg.data_dir,cfg.node_num);
183: if(flength(str)<1L)
184: return;
185: if((file=nopen(str,O_RDWR))==-1) {
186: /**
187: errormsg(WHERE,ERR_OPEN,str,O_RDWR);
188: **/
189: return; }
190: length=filelength(file);
191: if(!length) {
192: close(file);
193: return; }
194: if((buf=(char *)LMALLOC(length+1))==NULL) {
195: close(file);
196: errormsg(WHERE,ERR_ALLOC,str,length+1);
197: return; }
198: if(lread(file,buf,length)!=length) {
199: close(file);
200: FREE(buf);
201: errormsg(WHERE,ERR_READ,str,length);
202: return; }
203: chsize(file,0L);
204: close(file);
205: buf[length]=0;
206:
207: if(thisnode.action==NODE_MAIN || thisnode.action==NODE_XFER
208: || sys_status&SS_IN_CTRLP) {
209: CRLF; }
210: putmsg(buf,P_NOATCODES);
211: LFREE(buf);
212: }
213:
214: /****************************************************************************/
215: /* 'ext' must be at least 128 bytes! */
216: /****************************************************************************/
217: void sbbs_t::getnodeext(uint number, char *ext)
218: {
219: char str[256];
220: int count=0;
221:
222: if(!number || number>cfg.sys_nodes) {
223: errormsg(WHERE,ERR_CHK,"node number",number);
224: return; }
225:
226: sprintf(str,"%snode.exb",cfg.ctrl_dir);
227: if((node_ext=nopen(str,O_RDONLY|O_DENYNONE))==-1) {
228: memset(ext,0,128);
229: errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_DENYNONE);
230: return;
231: }
232:
233: number--; /* make zero based */
234: while(count<LOOP_NODEDAB) {
235: if(count>10)
236: mswait(100);
237: if(lock(node_ext,(long)number*128L,128)==-1) {
238: count++;
239: continue; }
240: lseek(node_ext,(long)number*128L,SEEK_SET);
241: if(read(node_ext,ext,128)==128)
242: break;
243: count++; }
244: unlock(node_ext,(long)number*128L,128);
245: close(node_ext);
246: node_ext=-1;
247:
248: if(count>(LOOP_NODEDAB/2) && count!=LOOP_NODEDAB) {
249: sprintf(str,"NODE.EXB COLLISION - Count: %d",count);
250: logline("!!",str);
251: }
252: if(count==LOOP_NODEDAB) {
253: errormsg(WHERE,ERR_READ,"node.exb",number+1);
254: return;
255: }
256: }
257:
258:
259: /****************************************************************************/
260: /* Prints short messages waiting for 'usernumber', if any... */
261: /* then deletes them. */
262: /****************************************************************************/
263: void sbbs_t::getsmsg(int usernumber)
264: {
265: char str[256], HUGE16 *buf;
266: int file;
267: long length;
268:
269: sprintf(str,"%smsgs/%4.4u.msg",cfg.data_dir,usernumber);
270: if(flength(str)<1L)
271: return;
272: if((file=nopen(str,O_RDWR))==-1) {
273: errormsg(WHERE,ERR_OPEN,str,O_RDWR);
274: return; }
275: length=filelength(file);
276: if((buf=(char *)LMALLOC(length+1))==NULL) {
277: close(file);
278: errormsg(WHERE,ERR_ALLOC,str,length+1);
279: return; }
280: if(lread(file,buf,length)!=length) {
281: close(file);
282: FREE(buf);
283: errormsg(WHERE,ERR_READ,str,length);
284: return; }
285: chsize(file,0L);
286: close(file);
287: buf[length]=0;
288: getnodedat(cfg.node_num,&thisnode,0);
289: if(thisnode.action==NODE_MAIN || thisnode.action==NODE_XFER
290: || sys_status&SS_IN_CTRLP) {
291: CRLF; }
292: if(thisnode.misc&NODE_MSGW) {
293: getnodedat(cfg.node_num,&thisnode,1);
294: thisnode.misc&=~NODE_MSGW;
295: putnodedat(cfg.node_num,&thisnode); }
296: putmsg(buf,P_NOATCODES);
297: LFREE(buf);
298: }
299:
300: /****************************************************************************/
301: /* This function lists users that are online. */
302: /* If listself is true, it will list the current node. */
303: /* Returns number of active nodes (not including current node). */
304: /****************************************************************************/
305: int sbbs_t::whos_online(bool listself)
306: {
307: int i,j;
308: node_t node;
309:
310: CRLF;
311: bputs(text[NodeLstHdr]);
312: for(j=0,i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) {
313: getnodedat(i,&node,0);
314: if(i==cfg.node_num) {
315: if(listself)
316: printnodedat(i,&node);
317: continue; }
318: if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) {
319: printnodedat(i,&node);
320: if(!lastnodemsg)
321: lastnodemsg=i;
322: j++; } }
323: if(!j)
324: bputs(text[NoOtherActiveNodes]);
325: return(j);
326: }
327:
328: /****************************************************************************/
329: /* Displays the information for node number 'number' contained in 'node' */
330: /****************************************************************************/
331: void sbbs_t::printnodedat(uint number, node_t* node)
332: {
333: uint i;
334: char hour,mer[3];
335: char tmp[512];
336:
337: attr(cfg.color[clr_nodenum]);
338: bprintf("%3d ",number);
339: attr(cfg.color[clr_nodestatus]);
340: switch(node->status) {
341: case NODE_WFC:
342: bputs("Waiting for call");
343: break;
344: case NODE_OFFLINE:
345: bputs("Offline");
346: break;
347: case NODE_NETTING:
348: bputs("Networking");
349: break;
350: case NODE_LOGON:
351: bputs("At logon prompt");
352: break;
353: case NODE_EVENT_WAITING:
354: bputs("Waiting for all nodes to become inactive");
355: break;
356: case NODE_EVENT_LIMBO:
357: bprintf("Waiting for node %d to finish external event",node->aux);
358: break;
359: case NODE_EVENT_RUNNING:
360: bputs("Running external event");
361: break;
362: case NODE_NEWUSER:
363: attr(cfg.color[clr_nodeuser]);
364: bputs("New user");
365: attr(cfg.color[clr_nodestatus]);
366: bputs(" applying for access ");
367: if(!node->connection)
368: bputs("Locally");
369: else if(node->connection==0xffff)
370: bprintf("via telnet");
371: else
372: bprintf("at %ubps",node->connection);
373: break;
374: case NODE_QUIET:
375: if(!SYSOP) {
376: bputs("Waiting for call");
377: break; }
378: case NODE_INUSE:
379: if(node->misc&NODE_EXT) {
380: getnodeext(number,tmp);
381: bputs(tmp);
382: break; }
383: attr(cfg.color[clr_nodeuser]);
384: if(node->misc&NODE_ANON && !SYSOP)
385: bputs("UNKNOWN USER");
386: else
387: bputs(username(&cfg,node->useron,tmp));
388: attr(cfg.color[clr_nodestatus]);
389: bputs(" ");
390: switch(node->action) {
391: case NODE_MAIN:
392: bputs("at main menu");
393: break;
394: case NODE_RMSG:
395: bputs("reading messages");
396: break;
397: case NODE_RMAL:
398: bputs("reading mail");
399: break;
400: case NODE_RSML:
401: bputs("reading sent mail");
402: break;
403: case NODE_RTXT:
404: bputs("reading text files");
405: break;
406: case NODE_PMSG:
407: bputs("posting message");
408: break;
409: case NODE_SMAL:
410: bputs("sending mail");
411: break;
412: case NODE_AMSG:
413: bputs("posting auto-message");
414: break;
415: case NODE_XTRN:
416: if(node->aux<1 || node->aux>cfg.total_xtrns)
417: bputs("at external program menu");
418: else {
419: bputs("running ");
420: i=node->aux-1;
421: if(SYSOP || chk_ar(cfg.xtrn[i]->ar,&useron))
422: bputs(cfg.xtrn[node->aux-1]->name);
423: else
424: bputs("external program"); }
425: break;
426: case NODE_DFLT:
427: bputs("changing defaults");
428: break;
429: case NODE_XFER:
430: bputs("at transfer menu");
431: break;
432: case NODE_RFSD:
433: bprintf("retrieving from device #%d",node->aux);
434: break;
435: case NODE_DLNG:
436: bprintf("downloading");
437: break;
438: case NODE_ULNG:
439: bputs("uploading");
440: break;
441: case NODE_BXFR:
442: bputs("transferring bidirectional");
443: break;
444: case NODE_LFIL:
445: bputs("listing files");
446: break;
447: case NODE_LOGN:
448: bputs("logging on");
449: break;
450: case NODE_LCHT:
451: bprintf("in local chat with %s",cfg.sys_op);
452: break;
453: case NODE_MCHT:
454: if(node->aux) {
455: bprintf("in multinode chat channel %d",node->aux&0xff);
456: if(node->aux&0x1f00) { /* password */
457: outchar('*');
458: if(SYSOP)
459: bprintf(" %s",unpackchatpass(tmp,node)); } }
460: else
461: bputs("in multinode global chat channel");
462: break;
463: case NODE_PAGE:
464: bprintf("paging node %u for private chat",node->aux);
465: break;
466: case NODE_PCHT:
467: if(node->aux)
468: bprintf("in private chat with node %u",node->aux);
469: else
470: bprintf("in local chat with %s",cfg.sys_op);
471: break;
472: case NODE_GCHT:
473: i=node->aux;
474: if(i>=cfg.total_gurus)
475: i=0;
476: bprintf("chatting with %s",cfg.guru[i]->name);
477: break;
478: case NODE_CHAT:
479: bputs("in chat section");
480: break;
481: case NODE_TQWK:
482: bputs("transferring QWK packet");
483: break;
484: case NODE_SYSP:
485: bputs("performing sysop activities");
486: break;
487: default:
488: bputs(ultoa(node->action,tmp,10));
489: break; }
490: if(!node->connection)
491: bputs(" locally");
492: else if(node->connection==0xffff)
493: bprintf(" via telnet");
494: else
495: bprintf(" at %ubps",node->connection);
496: if(node->action==NODE_DLNG) {
497: if(cfg.sys_misc&SM_MILITARY) {
498: hour=node->aux/60;
499: mer[0]=0; }
500: else if((node->aux/60)>=12) {
501: if(node->aux/60==12)
502: hour=12;
503: else
504: hour=(node->aux/60)-12;
505: strcpy(mer,"pm"); }
506: else {
507: if((node->aux/60)==0) /* 12 midnite */
508: hour=12;
509: else hour=node->aux/60;
510: strcpy(mer,"am"); }
511: bprintf(" ETA %02d:%02d %s"
512: ,hour,node->aux%60,mer); }
513: break; }
514: i=NODE_LOCK;
515: if(node->status==NODE_INUSE || SYSOP)
516: i|=NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG;
517: if(node->misc&i) {
518: bputs(" (");
519: if(node->misc&(i&NODE_AOFF))
520: outchar('A');
521: if(node->misc&NODE_LOCK)
522: outchar('L');
523: if(node->misc&(i&(NODE_MSGW|NODE_NMSG)))
524: outchar('M');
525: if(node->misc&(i&NODE_POFF))
526: outchar('P');
527: outchar(')'); }
528: if(SYSOP && ((node->misc
529: &(NODE_ANON|NODE_UDAT|NODE_INTR|NODE_RRUN|NODE_EVENT|NODE_DOWN|NODE_LCHAT))
530: || node->status==NODE_QUIET)) {
531: bputs(" [");
532: if(node->misc&NODE_ANON)
533: outchar('A');
534: if(node->misc&NODE_INTR)
535: outchar('I');
536: if(node->misc&NODE_RRUN)
537: outchar('R');
538: if(node->misc&NODE_UDAT)
539: outchar('U');
540: if(node->status==NODE_QUIET)
541: outchar('Q');
542: if(node->misc&NODE_EVENT)
543: outchar('E');
544: if(node->misc&NODE_DOWN)
545: outchar('D');
546: if(node->misc&NODE_LCHAT)
547: outchar('C');
548: outchar(']'); }
549: if(node->errors && SYSOP) {
550: attr(cfg.color[clr_err]);
551: bprintf(" %d error%c",node->errors, node->errors>1 ? 's' : '\0' ); }
552: attr(LIGHTGRAY);
553: CRLF;
554: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.