|
|
1.1 root 1: /* xtrn_sec.cpp */
2:
3: /* Synchronet external program/door section and drop file routines */
4:
5: /* $Id: xtrn_sec.cpp,v 1.55 2006/09/15 01:01:42 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:
40: /****************************************************************************/
41: /* This is the external programs (doors) section of the bbs */
42: /* Return 1 if no externals available, 0 otherwise. */
43: /****************************************************************************/
44: int sbbs_t::xtrn_sec()
45: {
46: char str[MAX_PATH+1];
47: int xsec;
48: uint i,j,k,*usrxtrn,usrxtrns,*usrxsec,usrxsecs;
49: long l;
50:
51: if(useron.rest&FLAG('X')) {
52: bputs(text[R_ExternalPrograms]);
53: return(1);
54: }
55:
56: if(!cfg.total_xtrns || !cfg.total_xtrnsecs) {
57: bputs(text[NoXtrnPrograms]);
58: return(1);
59: }
60:
61: if((usrxtrn=(uint *)malloc(cfg.total_xtrns*sizeof(int)))==NULL) {
62: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrns);
63: return(1);
64: }
65: if((usrxsec=(uint *)malloc(cfg.total_xtrnsecs*sizeof(int)))==NULL) {
66: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_xtrnsecs);
67: free(usrxtrn);
68: return(1);
69: }
70:
71: while(online) {
72: for(i=0,usrxsecs=0;i<cfg.total_xtrnsecs;i++)
73: if(chk_ar(cfg.xtrnsec[i]->ar,&useron))
74: usrxsec[usrxsecs++]=i;
75: if(!usrxsecs) {
76: bputs(text[NoXtrnPrograms]);
77: free(usrxtrn);
78: free(usrxsec);
79: return(1);
80: }
81: if(usrxsecs>1) {
82: sprintf(str,"%smenu/xtrn_sec.*",cfg.text_dir);
83: if(fexist(str)) {
84: menu("xtrn_sec");
85: xsec=getnum(usrxsecs);
86: if(xsec<=0)
87: break;
88: xsec--;
89: xsec=usrxsec[xsec];
90: }
91: else {
92: for(i=0;i<cfg.total_xtrnsecs;i++)
93: uselect(1,i,"External Program Section"
94: ,cfg.xtrnsec[i]->name,cfg.xtrnsec[i]->ar);
95: xsec=uselect(0,0,0,0,0);
96: }
97: if(xsec==-1)
98: break;
99: }
100: else
101: xsec=0;
102:
103: while(!chk_ar(cfg.xtrnsec[xsec]->ar,&useron))
104: xsec++;
105:
106: if(xsec>=cfg.total_xtrnsecs) {
107: bputs(text[NoXtrnPrograms]);
108: free(usrxtrn);
109: free(usrxsec);
110: return(1);
111: }
112:
113: while(online) {
114: for(i=0,usrxtrns=0;i<cfg.total_xtrns; i++) {
115: if(cfg.xtrn[i]->sec!=xsec)
116: continue;
117: if(cfg.xtrn[i]->event && cfg.xtrn[i]->misc&EVENTONLY)
118: continue;
119: if(!chk_ar(cfg.xtrn[i]->ar,&useron))
120: continue;
121: usrxtrn[usrxtrns++]=i;
122: }
123: if(!usrxtrns) {
124: bputs(text[NoXtrnPrograms]);
125: pause();
126: break;
127: }
128: sprintf(str,"%smenu/xtrn%u.*",cfg.text_dir,xsec+1);
129: if(fexist(str)) {
130: sprintf(str,"xtrn%u",xsec+1);
131: menu(str);
132: }
133: else {
134: bprintf(text[XtrnProgLstHdr],cfg.xtrnsec[xsec]->name);
135: bputs(text[XtrnProgLstTitles]);
136: if(usrxtrns>=10) {
137: bputs(" ");
138: bputs(text[XtrnProgLstTitles]);
139: }
140: CRLF;
141: bputs(text[XtrnProgLstUnderline]);
142: if(usrxtrns>=10) {
143: bputs(" ");
144: bputs(text[XtrnProgLstUnderline]);
145: }
146: CRLF;
147: if(usrxtrns>=10)
148: j=(usrxtrns/2)+(usrxtrns&1);
149: else
150: j=usrxtrns;
151: for(i=0;i<j && !msgabort();i++) {
152: bprintf(text[XtrnProgLstFmt],i+1
153: ,cfg.xtrn[usrxtrn[i]]->name,cfg.xtrn[usrxtrn[i]]->cost);
154: if(usrxtrns>=10) {
155: k=(usrxtrns/2)+i+(usrxtrns&1);
156: if(k<usrxtrns) {
157: bputs(" ");
158: bprintf(text[XtrnProgLstFmt],k+1
159: ,cfg.xtrn[usrxtrn[k]]->name
160: ,cfg.xtrn[usrxtrn[k]]->cost);
161: }
162: }
163: CRLF;
164: }
165: ASYNC;
166: mnemonics(text[WhichXtrnProg]);
167: }
168: getnodedat(cfg.node_num,&thisnode,1);
169: thisnode.aux=0; /* aux is 0, only if at menu */
170: putnodedat(cfg.node_num,&thisnode);
171: action=NODE_XTRN;
172: SYNC;
173: if((l=getnum(usrxtrns))<1)
174: break;
175: l--;
176: sprintf(str,"%smenu/xtrn/%s.*",cfg.text_dir,cfg.xtrn[usrxtrn[l]]->code);
177: if(fexist(str)) {
178: sprintf(str,"xtrn/%s",cfg.xtrn[usrxtrn[l]]->code);
179: menu(str);
180: lncntr=0;
181: }
182: exec_xtrn(usrxtrn[l]);
183:
184: if(cfg.xtrn[usrxtrn[l]]->misc&XTRN_PAUSE)
185: lncntr=2; /* force a pause before CLS */
186: }
187: if(usrxsecs<2)
188: break;
189: }
190: free(usrxtrn);
191: free(usrxsec);
192: return(0);
193: }
194:
195:
196: char *hungupstr="\1n\1h%s\1n hung up on \1h%s\1n %s\r\n";
197:
198: /****************************************************************************/
199: /* Convert C string to pascal string */
200: /****************************************************************************/
201: void str2pas(char *instr, char *outstr)
202: {
203: int i;
204:
205: outstr[0]=(char)strlen(instr);
206: for(i=0;i<outstr[0];i++)
207: outstr[i+1]=instr[i];
208: }
209:
210: /****************************************************************************/
211: /* Convert from unix time (seconds since 1/70) to julian (days since 1900) */
212: /****************************************************************************/
213: int unixtojulian(time_t unix_time)
214: {
215: int days[12]={0,31,59,90,120,151,181,212,243,273,304,334};
216: long j;
217: struct tm tm;
218:
219: if(localtime_r(&unix_time,&tm)==NULL)
220: return(0);
221: j=36525L*(1900+tm.tm_year);
222: if(!(j%100) && (tm.tm_mon+1)<3)
223: j--;
224: j=(j-(1900*36525))/100;
225: j+=tm.tm_mday+days[tm.tm_mon];
226: return(j);
227: }
228:
229: /****************************************************************************/
230: /* Convert julian date into unix format */
231: /****************************************************************************/
232: #ifdef __BORLANDC__
233: #pragma argsused
234: #endif
235: time_t juliantounix(ulong j)
236: {
237: #if 0 /* julian time */
238: int days[2][12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
239: 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
240: long temp;
241: int leap,counter;
242: struct tm tm;
243:
244: if(!j) return(0L);
245:
246: tm.tm_year=((100L*j)/36525L)-1900;
247: temp=(long)date.da_year*36525L;
248: date.da_year+=1900;
249: j-=temp/100L;
250:
251: if (!(temp%100)) {
252: j++;
253: leap=1;
254: }
255: else leap=0;
256:
257: for(date.da_mon=counter=0;counter<12;counter++)
258: if(days[leap][counter]<j)
259: date.da_mon=counter;
260:
261: date.da_day=j-days[leap][date.da_mon];
262: date.da_mon++; /* go from 0 to 1 based */
263:
264: curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0;
265: return(dostounix(&date,&curtime));
266: #else
267: return((time_t)-1);
268: #endif
269: }
270:
271: #ifdef __unix__
272: static void lfexpand(char *str, ulong misc)
273: {
274: char *p;
275: char newstr[1024];
276: size_t len=0;
277:
278: if(misc&XTRN_NATIVE)
279: return;
280:
281: for(p=str;*p && len < sizeof(newstr)-1;p++) {
282: if(*p=='\n')
283: newstr[len++]='\r';
284: newstr[len++]=*p;
285: }
286:
287: newstr[len]=0;
288: strcpy(str,newstr);
289: }
290: #else
291: #define lfexpand(str, misc)
292: #endif
293:
294: /****************************************************************************/
295: /* Creates various types of xtrn (Doors, Chains, etc.) data (drop) files. */
296: /****************************************************************************/
297: void sbbs_t::xtrndat(char *name, char *dropdir, uchar type, ulong tleft
298: ,ulong misc)
299: {
300: char str[1024],tmp2[128],c,*p;
301: char tmp[512];
302: int i,file;
303: ushort w;
304: long l;
305: struct tm tm;
306: struct tm tl;
307: stats_t stats;
308:
309: char node_dir[MAX_PATH+1];
310: char ctrl_dir[MAX_PATH+1];
311: char data_dir[MAX_PATH+1];
312: char exec_dir[MAX_PATH+1];
313: char text_dir[MAX_PATH+1];
314: char temp_dir[MAX_PATH+1];
315:
316: SAFECOPY(node_dir,cfg.node_dir);
317: SAFECOPY(ctrl_dir,cfg.ctrl_dir);
318: SAFECOPY(data_dir,cfg.data_dir);
319: SAFECOPY(exec_dir,cfg.exec_dir);
320: SAFECOPY(text_dir,cfg.text_dir);
321: SAFECOPY(temp_dir,cfg.temp_dir);
322:
323: #ifdef _WIN32
324:
325: if(!(misc&XTRN_NATIVE)) {
326: /* Put Micros~1 shortened paths in drop files when running 16-bit DOS programs */
327: GetShortPathName(cfg.node_dir,node_dir,sizeof(node_dir));
328: GetShortPathName(cfg.ctrl_dir,node_dir,sizeof(ctrl_dir));
329: GetShortPathName(cfg.data_dir,data_dir,sizeof(data_dir));
330: GetShortPathName(cfg.exec_dir,exec_dir,sizeof(exec_dir));
331: GetShortPathName(cfg.text_dir,text_dir,sizeof(text_dir));
332: GetShortPathName(cfg.temp_dir,temp_dir,sizeof(temp_dir));
333: }
334:
335: #endif
336:
337: if(type==XTRN_SBBS) { /* SBBS XTRN.DAT file */
338: strcpy(tmp,"XTRN.DAT");
339: if(misc&XTRN_LWRCASE)
340: strlwr(tmp);
341: sprintf(str,"%s%s",dropdir,tmp);
342: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
343: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
344: return;
345: }
346:
347: sprintf(str,"%s\n%s\n%s\n%s\n"
348: ,name /* User name */
349: ,cfg.sys_name /* System name */
350: ,cfg.sys_op /* Sysop name */
351: ,cfg.sys_guru); /* Guru name */
352: lfexpand(str,misc);
353: write(file,str,strlen(str));
354:
355: sprintf(str,"%s\n%s\n%u\n%u\n%lu\n%s\n%lu\n%lu\n"
356: ,ctrl_dir /* Ctrl dir */
357: ,data_dir /* Data dir */
358: ,cfg.sys_nodes /* Total system nodes */
359: ,cfg.node_num /* Current node */
360: ,tleft /* User Timeleft in seconds */
361: ,term_supports(ANSI) /* User ANSI ? (Yes/Mono/No) */
362: ? term_supports(COLOR)
363: ? "Yes":"Mono":"No"
364: ,rows /* User Screen lines */
365: ,useron.cdt+useron.freecdt); /* User Credits */
366: lfexpand(str,misc);
367: write(file,str,strlen(str));
368:
369: sprintf(str,"%u\n%u\n%s\n%c\n%u\n%s\n"
370: ,useron.level /* User main level */
371: ,useron.level /* User transfer level */
372: ,useron.birth /* User birthday */
373: ,useron.sex /* User sex (M/F) */
374: ,useron.number /* User number */
375: ,useron.phone); /* User phone number */
376: lfexpand(str,misc);
377: write(file,str,strlen(str));
378:
379: sprintf(str,"%u\n%u\n%x\n%lu\n%s\n%s\n"
380: "%s\n%s\n%s\n%s\n%s\n%s\n%lu\n"
381: ,misc&IO_INTS ? 0:cfg.com_port /* Com port or 0 if !FOSSIL */
382: ,cfg.com_irq /* Com IRQ */
383: ,cfg.com_base /* Com base in hex */
384: ,dte_rate /* Com rate */
385: ,"Yes" /* Hardware flow ctrl Y/N */
386: ,"Yes" /* Locked DTE rate Y/N */
387: ,cfg.mdm_init /* Modem initialization string */
388: ,cfg.mdm_spec /* Modem special init string */
389: ,cfg.mdm_term /* Modem terminal mode init str */
390: ,cfg.mdm_dial /* Modem dial string */
391: ,cfg.mdm_offh /* Modem off-hook string */
392: ,cfg.mdm_answ /* Modem answer string */
393: ,0L
394: );
395: lfexpand(str,misc);
396: write(file,str,strlen(str));
397:
398: sprintf(str,"%u\n",cfg.total_xtrns);
399: lfexpand(str,misc);
400: write(file,str,strlen(str)); /* Total external programs */
401:
402: for(i=0;i<cfg.total_xtrns;i++) { /* Each program's name */
403: if(SYSOP || chk_ar(cfg.xtrn[i]->ar,&useron))
404: strcpy(str,cfg.xtrn[i]->name);
405: else
406: str[0]=0; /* Blank if no access */
407: strcat(str,"\n");
408: lfexpand(str,misc);
409: write(file,str,strlen(str));
410: }
411:
412: sprintf(str,"%s\n%s\n"
413: ,ltoaf(useron.flags1,tmp) /* Main flags */
414: ,ltoaf(useron.flags2,tmp2) /* Transfer flags */
415: );
416: lfexpand(str,misc);
417: write(file,str,strlen(str));
418:
419: sprintf(str,"%s\n%s\n%lx\n%s\n%s\n%s\n"
420: ,ltoaf(useron.exempt,tmp) /* Exemptions */
421: ,ltoaf(useron.rest,tmp2) /* Restrictions */
422: ,(long)useron.expire /* Expiration date in unix form */
423: ,useron.address /* Address */
424: ,useron.location /* City/State */
425: ,useron.zipcode /* Zip/Postal code */
426: );
427: lfexpand(str,misc);
428: write(file,str,strlen(str));
429:
430: sprintf(str,"%s\n%s\n%d\n%s\n%lu\n%s\n%s\n%s\n%s\n"
431: "%lx\n%d\n"
432: ,ltoaf(useron.flags3,tmp) /* Flag set #3 */
433: ,ltoaf(useron.flags4,tmp2) /* Flag set #4 */
434: ,0 /* Time-slice type */
435: ,useron.name /* Real name/company */
436: ,cur_rate /* DCE rate */
437: ,exec_dir
438: ,text_dir
439: ,temp_dir
440: ,cfg.sys_id
441: ,cfg.node_misc
442: ,misc&IO_INTS ? INVALID_SOCKET : client_socket_dup
443: );
444: lfexpand(str,misc);
445: write(file,str,strlen(str));
446:
447: close(file);
448: }
449:
450: else if(type==XTRN_WWIV) { /* WWIV CHAIN.TXT File */
451: strcpy(tmp,"CHAIN.TXT");
452: if(misc&XTRN_LWRCASE)
453: strlwr(tmp);
454: sprintf(str,"%s%s",dropdir,tmp);
455: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
456: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
457: return;
458: }
459:
460: if(tleft>0x7fff) /* Reduce time-left for broken 16-bit doors */
461: tleft=0x7fff; /* That interpret this value as a signed short */
462:
463: sprintf(str,"%u\n%s\n%s\n%s\n%u\n%c\n"
464: ,useron.number /* User number */
465: ,name /* User name */
466: ,useron.name /* User real name */
467: ,nulstr /* User call sign */
468: ,getage(&cfg,useron.birth) /* User age */
469: ,useron.sex); /* User sex (M/F) */
470: strupr(str);
471: lfexpand(str,misc);
472: write(file,str,strlen(str));
473:
474: sprintf(str,"%lu\n%s\n%u\n%lu\n%u\n%u\n%u\n%u\n%u\n"
475: ,useron.cdt+useron.freecdt /* Gold */
476: ,unixtodstr(&cfg,useron.laston,tmp) /* User last on date */
477: ,cols /* User screen width */
478: ,rows /* User screen length */
479: ,useron.level /* User SL */
480: ,0 /* Cosysop? */
481: ,SYSOP /* Sysop? (1/0) */
482: ,term_supports(ANSI) /* ANSI ? (1/0) */
483: ,online==ON_REMOTE); /* Remote (1/0) */
484: lfexpand(str,misc);
485: write(file,str,strlen(str));
486:
487: sprintf(str,"%lu\n%s\n%s\n%s\n%lu\n%d\n%s\n%s\n"
488: "%u\n%u\n%lu\n%u\n%lu\n%u\n%s\n"
489: ,tleft /* Time left in seconds */
490: ,node_dir /* Gfiles dir (log dir) */
491: ,data_dir /* Data dir */
492: ,"node.log" /* Name of log file */
493: ,dte_rate /* DTE rate */
494: ,cfg.com_port /* COM port number */
495: ,cfg.sys_name /* System name */
496: ,cfg.sys_op /* Sysop name */
497: ,0 /* Logon time (sec past 12am) */
498: ,0 /* Current time (sec past 12am) */
499: ,useron.ulb/1024UL /* User uploaded kbytes */
500: ,useron.uls /* User uploaded files */
501: ,useron.dlb/1024UL /* User downloaded kbytes */
502: ,useron.dls /* User downloaded files */
503: ,"8N1"); /* Data, parity, stop bits */
504: lfexpand(str,misc);
505: write(file,str,strlen(str));
506:
507: close(file);
508: }
509:
510: else if(type==XTRN_GAP) { /* Gap DOOR.SYS File */
511: strcpy(tmp,"DOOR.SYS");
512: if(misc&XTRN_LWRCASE)
513: strlwr(tmp);
514: sprintf(str,"%s%s",dropdir,tmp);
515: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
516: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
517: return;
518: }
519:
520: if(tleft>0x7fff) /* Reduce time-left for broken 16-bit doors */
521: tleft=0x7fff; /* That interpret this value as a signed short */
522:
523: #if 0
524: if(misc&XTRN_NATIVE) {
525: if(misc&IO_INTS) {
526: strcpy(str,"COM0:STDIO\n");
527: }
528: else {
529: sprintf(str,"COM0:SOCKET%d\n",
530: client_socket_dup
531: );
532: }
533: }
534: else {
535: sprintf(str,"COM%d:\n"
536: ,online==ON_REMOTE ? cfg.com_port:0); /* 01: COM port - 0 if Local */
537: }
538: #else
539: sprintf(str,"COM%d:\n"
540: ,online==ON_REMOTE ? cfg.com_port:0); /* 01: COM port - 0 if Local */
541: #endif
542: lfexpand(str,misc);
543: write(file,str,strlen(str));
544: /* Note about door.sys, line 2 (April-24-2005):
545: It *should* be the DCE rate (any number, including the popular modem
546: DCE rates of 14400, 28800, and 33600). However, according to Deuce,
547: doors created with the DMlib door kit choke with "Error -25: Illegal
548: baud rate" if this isn't a valid FOSSIL baud (DTE) rate, so we're
549: changing this value to the DTE rate until/unless some other doors
550: have an issue with that. <sigh>
551: */
552: sprintf(str,"%lu\n%u\n%u\n%lu\n%c\n%c\n%c\n%c\n"
553: ,dte_rate /* was cur_rate */ /* 02: DCE rate, see note above */
554: ,8 /* 03: Data bits */
555: ,cfg.node_num /* 04: Node number */
556: ,dte_rate /* 05: DTE rate */
557: ,console&CON_L_ECHO ? 'Y':'N' /* 06: Screen display */
558: ,'Y' /* 07: Printer toggle */
559: ,'Y' /* 08: Page bell */
560: ,'Y'); /* 09: Caller alarm */
561: lfexpand(str,misc);
562: write(file,str,strlen(str));
563:
564: sprintf(str,"%s\n%s\n%s\n%s\n%s\n"
565: ,name /* 10: User name */
566: ,useron.location /* 11: User location */
567: ,useron.phone /* 12: User home phone */
568: ,useron.phone /* 13: User work/data phone */
569: ,useron.pass); /* 14: User password */
570: lfexpand(str,misc);
571: write(file,str,strlen(str));
572:
573: sprintf(str,"%u\n%u\n%s\n%lu\n%lu\n%s\n"
574: ,useron.level /* 15: User security level */
575: ,useron.logons /* 16: User total logons */
576: ,unixtodstr(&cfg,useron.laston,tmp) /* 17: User last on date */
577: ,tleft /* 18: User time left in sec */
578: ,tleft/60 /* 19: User time left in min */
579: ,useron.misc&NO_EXASCII /* 20: GR if COLOR ANSI */
580: ? "7E" : (useron.misc&(ANSI|COLOR))==(ANSI|COLOR) ? "GR" : "NG");
581: lfexpand(str,misc);
582: write(file,str,strlen(str));
583:
584: sprintf(str,"%lu\n%c\n%s\n%u\n%s\n%u\n%c\n%u\n%u\n"
585: ,rows /* 21: User screen length */
586: ,useron.misc&EXPERT ? 'Y':'N' /* 22: Expert? (Y/N) */
587: ,ltoaf(useron.flags1,tmp2) /* 23: Registered conferences */
588: ,0 /* 24: Conference came from */
589: ,unixtodstr(&cfg,useron.expire,tmp) /* 25: User expiration date */
590: ,useron.number /* 26: User number */
591: ,'Y' /* 27: Default protocol */
592: ,useron.uls /* 28: User total uploads */
593: ,useron.dls); /* 29: User total downloads */
594: lfexpand(str,misc);
595: write(file,str,strlen(str));
596:
597: sprintf(str,"%u\n%lu\n%s\n%s\n%s\n%s"
598: "\n%s\n%02d:%02d\n%c\n"
599: ,0 /* 30: Kbytes downloaded today */
600: ,(useron.cdt+useron.freecdt)/1024UL /* 31: Max Kbytes to download today */
601: ,useron.birth /* 32: User birthday */
602: ,node_dir /* 33: Path to MAIN directory */
603: ,data_dir /* 34: Path to GEN directory */
604: ,cfg.sys_op /* 35: Sysop name */
605: ,nulstr /* 36: Alias name */
606: ,0 // sys_eventtime/60 /* 37: Event time HH:MM */
607: ,0 // sys_eventtime%60
608: ,'Y'); /* 38: Error correcting connection */
609: lfexpand(str,misc);
610: write(file,str,strlen(str));
611:
612: localtime_r(&ns_time,&tm);
613: sprintf(str,"%c\n%c\n%u\n%lu\n%02d/%02d/%02d\n"
614: ,(useron.misc&(NO_EXASCII|ANSI|COLOR))==ANSI
615: ? 'Y':'N' /* 39: ANSI supported but NG mode */
616: ,'Y' /* 40: Use record locking */
617: ,14 /* 41: BBS default color */
618: ,useron.min /* 42: Time credits in minutes */
619: ,tm.tm_mon+1 /* 43: File new-scan date */
620: ,tm.tm_mday
621: ,TM_YEAR(tm.tm_year));
622: lfexpand(str,misc);
623: write(file,str,strlen(str));
624:
625: localtime_r(&logontime,&tm);
626: localtime_r(&useron.laston,&tl);
627: sprintf(str,"%02d:%02d\n%02d:%02d\n%u\n%u\n%lu\n"
628: "%lu\n%s\n%u\n%u\n"
629: ,tm.tm_hour /* 44: Time of this call */
630: ,tm.tm_min
631: ,tl.tm_hour /* 45: Time of last call */
632: ,tl.tm_min
633: ,999 /* 46: Max daily files available */
634: ,0 /* 47: Files downloaded so far today */
635: ,useron.ulb/1024UL /* 48: Total Kbytes uploaded */
636: ,useron.dlb/1024UL /* 49: Total Kbytes downloaded */
637: ,useron.comment /* 50: User comment */
638: ,0 /* 51: Total doors opened */
639: ,useron.posts); /* 52: User message left */
640: lfexpand(str,misc);
641: write(file,str,strlen(str));
642:
643: close(file);
644: }
645:
646: else if(type==XTRN_RBBS || type==XTRN_RBBS1) {
647: if(type==XTRN_RBBS)
648: sprintf(tmp,"DORINFO%X.DEF",cfg.node_num); /* support 1-F */
649: else
650: sprintf(tmp,"DORINFO1.DEF");
651: if(misc&XTRN_LWRCASE)
652: strlwr(tmp);
653: sprintf(str,"%s%s",dropdir,tmp);
654: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
655: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
656: return;
657: }
658:
659: strcpy(tmp,cfg.sys_op);
660: p=strchr(tmp,' ');
661: if(p)
662: *(p++)=0;
663: else
664: p=nulstr;
665:
666: sprintf(str,"%s\n%s\n%s\nCOM%d\n%lu BAUD,N,8,1\n%u\n"
667: ,cfg.sys_name /* Name of BBS */
668: ,tmp /* Sysop's firstname */
669: ,p /* Sysop's lastname */
670: ,online==ON_REMOTE ? cfg.com_port:0 /* COM port number, 0 if local */
671: ,dte_rate /* DTE rate */
672: ,0); /* Network type */
673: strupr(str);
674: lfexpand(str,misc);
675: write(file,str,strlen(str));
676:
677: strcpy(tmp,name);
678: p=strchr(tmp,' ');
679: if(p)
680: *(p++)=0;
681: else
682: p=nulstr;
683: sprintf(str,"%s\n%s\n%s\n%u\n%u\n%lu\n"
684: ,tmp /* User's firstname */
685: ,p /* User's lastname */
686: ,useron.location /* User's city */
687: ,term_supports(ANSI) /* 1=ANSI 0=ASCII */
688: ,useron.level /* Security level */
689: ,tleft/60); /* Time left in minutes */
690: strupr(str);
691: lfexpand(str,misc);
692: write(file,str,strlen(str));
693:
694: close(file);
695:
696: strcpy(tmp,"EXITINFO.BBS");
697: if(misc&XTRN_LWRCASE)
698: strlwr(tmp);
699: sprintf(str,"%s%s",dropdir,tmp);
700: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
701: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
702: return;
703: }
704: w=(WORD)dte_rate;
705: write(file,&w,sizeof(short)); /* BaudRate */
706: /* SysInfo */
707: getstats(&cfg,0,&stats);
708: write(file,&stats.logons,sizeof(long)); /* CallCount */
709: write(file,nulstr,36); /* LastCallerName */
710: write(file,nulstr,36); /* LastCallerAlias */
711: write(file,nulstr,92); /* ExtraSpace */
712: /* TimeLogInfo */
713: write(file,nulstr,9); /* StartDate */
714: write(file,nulstr,24*sizeof(short)); /* BusyPerHour */
715: write(file,nulstr,7*sizeof(short)); /* BusyPerDay */
716: /* UserInfo */
717: str2pas(name,str); /* Name */
718: write(file,str,36);
719: str2pas(useron.location,str);
720: write(file,str,26); /* City */
721: str2pas(useron.pass,str);
722: write(file,str,16); /* Pwd */
723: str2pas(useron.phone,str);
724: write(file,str,13); /* DataPhone */
725: write(file,str,13); /* HomePhone */
726: localtime_r(&useron.laston,&tm);
727: sprintf(tmp,"%02d:%02d",tm.tm_hour,tm.tm_min);
728: str2pas(tmp,str);
729: write(file,str,6); /* LastTime */
730: unixtodstr(&cfg,useron.laston,tmp);
731: str2pas(tmp,str);
732: write(file,str,9); /* LastDate */
733: c=0;
734: if(useron.misc&DELETED) c|=(1<<0);
735: if(useron.misc&CLRSCRN) c|=(1<<1);
736: if(useron.misc&UPAUSE) c|=(1<<2);
737: if(term_supports(ANSI)) c|=(1<<3);
738: if(useron.sex=='F') c|=(1<<7);
739: write(file,&c,1); /* Attrib */
740: write(file,&useron.flags1,4); /* Flags */
741: w=0;
742: write(file,&w,sizeof(short)); /* Credit */
743: write(file,&w,sizeof(short)); /* Pending */
744: write(file,&useron.posts,sizeof(short));/* TimesPosted */
745: write(file,&w,sizeof(short)); /* HighMsgRead */
746: w=useron.level;
747: write(file,&w,sizeof(short)); /* SecLvl */
748: w=0;
749: write(file,&w,sizeof(short)); /* Times */
750: write(file,&useron.uls,sizeof(short)); /* Ups */
751: write(file,&useron.dls,sizeof(short)); /* Downs */
752: w=(ushort)(useron.ulb/1024UL);
753: write(file,&w,sizeof(short)); /* UpK */
754: w=(ushort)(useron.dlb/1024UL);
755: write(file,&w,sizeof(short)); /* DownK */
756: w=(ushort)(logon_dlb/1024UL);
757: write(file,&w,sizeof(short)); /* TodayK */
758: w=0;
759: write(file,&w,sizeof(short)); /* Elapsed */
760: write(file,&w,sizeof(short)); /* Len */
761: write(file,&w,sizeof(short)); /* CombinedPtr */
762: write(file,&w,sizeof(short)); /* AliasPtr */
763: l=0;
764: write(file,&l,sizeof(long)); /* Birthday (as a long?) */
765: /* EventInfo */
766: c=0;
767: write(file,&c,sizeof(char)); /* Status */
768: write(file,&l /* sys_eventtime */,sizeof(long)); /* RunTime */
769: write(file,&c,sizeof(char)); /* ErrorLevel */
770: c='\xff';
771: write(file,&c,sizeof(char)); /* Days */
772: // c=sys_eventnode==node_num || sys_misc&SM_TIMED_EX ? 1 : 0;
773: c=0;
774: write(file,&c,sizeof(char)); /* Forced */
775: if(!cfg.total_events)
776: l=0;
777: else
778: l=cfg.event[0]->last;
779: write(file,&l,sizeof(long)); /* LastTimeRun */
780: memset(str,0,40);
781: write(file,str,7); /* Spare */
782:
783: c=0;
784: write(file,&c,1); /* NetMailEntered */
785: write(file,&c,1); /* EchoMailEntered */
786:
787: localtime_r(&logontime,&tm);
788: sprintf(tmp,"%02d:%02d",tm.tm_hour,tm.tm_min);
789: str2pas(tmp,str);
790: write(file,str,6); /* LoginTime */
791: unixtodstr(&cfg,logontime,tmp);
792: str2pas(tmp,str);
793: write(file,str,9); /* LoginDate */
794: write(file,&cfg.level_timepercall[useron.level],sizeof(short)); /* TmLimit */
795: write(file,&logontime,sizeof(long)); /* LoginSec */
796: write(file,&useron.cdt,sizeof(long)); /* Credit */
797: write(file,&useron.number,sizeof(short)); /* UserRecNum */
798: write(file,&i,2); /* ReadThru */
799: write(file,&i,2); /* PageTimes */
800: write(file,&i,2); /* DownLimit */
801: c=sys_status&SS_SYSPAGE ? 1:0;
802: write(file,&c,1); /* WantChat */
803: c=0;
804: write(file,&c,1); /* GosubLevel */
805:
806: memset(str,0,255);
807: for(i=1;i<20;i++)
808: write(file,str,9); /* GosubData */
809: write(file,str,9); /* Menu */
810: c=useron.misc&CLRSCRN ? 1:0;
811: write(file,&c,1); /* ScreenClear */
812: c=useron.misc&UPAUSE ? 1:0;
813: write(file,&c,1); /* MorePrompts */
814: c=useron.misc&NO_EXASCII ? 0:1;
815: write(file,&c,1); /* GraphicsMode */
816: c=useron.xedit ? 1:0;
817: write(file,&c,1); /* ExternEdit */
818: i=rows;
819: write(file,&i,2); /* ScreenLength */
820: c=1;
821: write(file,&c,1); /* MNP_Connect */
822: write(file,str,49); /* ChatReason */
823: c=0;
824: write(file,&c,1); /* ExternLogoff */
825: c=(char)term_supports(ANSI);
826: write(file,&c,1); /* ANSI_Capable */
827: close(file);
828: }
829:
830: else if(type==XTRN_WILDCAT) { /* WildCat CALLINFO.BBS File */
831: strcpy(tmp,"CALLINFO.BBS");
832: if(misc&XTRN_LWRCASE)
833: strlwr(tmp);
834: sprintf(str,"%s%s",dropdir,tmp);
835: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
836: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
837: return;
838: }
839:
840: if(online==ON_LOCAL) i=5;
841: else
842: switch(dte_rate) {
843: case 300:
844: i=1;
845: break;
846: case 1200:
847: i=2;
848: break;
849: case 2400:
850: i=0;
851: break;
852: case 9600:
853: i=3;
854: break;
855: case 19200:
856: i=4;
857: break;
858: case 38400:
859: i=6;
860: break;
861: default:
862: i=7;
863: break;
864: }
865: sprintf(str,"%s\n%u\n%s\n%u\n%lu\n%s\n%s\n%u\n"
866: ,name /* User name */
867: ,i /* DTE rate */
868: ,useron.location /* User location */
869: ,useron.level /* Security level */
870: ,tleft/60 /* Time left in min */
871: ,term_supports(ANSI) ? "COLOR":"MONO" /* ANSI ??? */
872: ,useron.pass /* Password */
873: ,useron.number); /* User number */
874: lfexpand(str,misc);
875: write(file,str,strlen(str));
876:
877: localtime_r(&now,&tm);
878: sprintf(str,"%lu\n%02d:%02d\n%02d:%02d %02d/%02d/%02d\n%s\n"
879: ,tleft /* Time left in seconds */
880: ,tm.tm_hour,tm.tm_min /* Current time HH:MM */
881: ,tm.tm_hour,tm.tm_min /* Current time and date HH:MM */
882: ,tm.tm_mon+1,tm.tm_mday /* MM/DD/YY */
883: ,TM_YEAR(tm.tm_year)
884: ,nulstr); /* Conferences with access */
885: lfexpand(str,misc);
886: write(file,str,strlen(str));
887:
888: localtime_r(&useron.laston,&tm);
889: sprintf(str,"%u\n%u\n%u\n%u\n%s\n%s %02u:%02u\n"
890: ,0 /* Daily download total */
891: ,0 /* Max download files */
892: ,0 /* Daily download k total */
893: ,0 /* Max download k total */
894: ,useron.phone /* User phone number */
895: ,unixtodstr(&cfg,useron.laston,tmp) /* Last on date and time */
896: ,tm.tm_hour /* MM/DD/YY HH:MM */
897: ,tm.tm_min);
898: lfexpand(str,misc);
899: write(file,str,strlen(str));
900:
901: localtime_r(&ns_time,&tm);
902: sprintf(str,"%s\n%s\n%02d/%02d/%02d\n%u\n%lu\n%u"
903: "\n%u\n%u\n"
904: ,useron.misc&EXPERT /* Expert or Novice mode */
905: ? "EXPERT":"NOVICE"
906: ,"All" /* Transfer Protocol */
907: ,tm.tm_mon+1,tm.tm_mday /* File new-scan date */
908: ,TM_YEAR(tm.tm_year) /* in MM/DD/YY */
909: ,useron.logons /* Total logons */
910: ,rows /* Screen length */
911: ,0 /* Highest message read */
912: ,useron.uls /* Total files uploaded */
913: ,useron.dls); /* Total files downloaded */
914: lfexpand(str,misc);
915: write(file,str,strlen(str));
916:
917: sprintf(str,"%u\n%s\nCOM%u\n%s\n%lu\n%s\n%s\n"
918: ,8 /* Data bits */
919: ,online==ON_LOCAL?"LOCAL":"REMOTE" /* Online local or remote */
920: ,cfg.com_port /* COMx port */
921: ,useron.birth /* User birthday */
922: ,dte_rate /* DTE rate */
923: ,"FALSE" /* Already connected? */
924: ,"Normal Connection"); /* Normal or ARQ connect */
925: lfexpand(str,misc);
926: write(file,str,strlen(str));
927:
928: localtime_r(&now,&tm);
929: sprintf(str,"%02d/%02d/%02d %02d:%02d\n%u\n%u\n"
930: ,tm.tm_mon+1,tm.tm_mday /* Current date MM/DD/YY */
931: ,TM_YEAR(tm.tm_year)
932: ,tm.tm_hour,tm.tm_min /* Current time HH:MM */
933: ,cfg.node_num /* Node number */
934: ,0); /* Door number */
935: lfexpand(str,misc);
936: write(file,str,strlen(str));
937:
938: close(file);
939: }
940:
941: else if(type==XTRN_PCBOARD) { /* PCBoard Files */
942: strcpy(tmp,"PCBOARD.SYS");
943: if(misc&XTRN_LWRCASE)
944: strlwr(tmp);
945: sprintf(str,"%s%s",dropdir,tmp);
946: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
947: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
948: return;
949: }
950:
951: sprintf(str,"%2d%2d%2d%2d%c%2d%c%c%5u%-5.5s"
952: ,-1 /* Display on/off */
953: ,0 /* Printer on/off */
954: ,sys_status&SS_SYSPAGE ? -1:0 /* Page Bell on/off */
955: ,startup->answer_sound[0] ? -1:0 /* Caller Alarm on/off */
956: ,' ' /* Sysop next flag */
957: ,0 /* Error corrected */
958: ,useron.misc&NO_EXASCII ? '7' /* Graphics mode */
959: : (useron.misc&(COLOR|ANSI))==(COLOR|ANSI) ? 'Y':'N'
960: ,'A' /* Node chat status */
961: ,(uint)dte_rate /* DTE Port Speed */
962: ,connection /* Connection description */
963: );
964: write(file,str,23);
965:
966: write(file,&useron.number,2); /* User record number */
967:
968: strcpy(tmp,name);
969: p=strchr(tmp,' ');
970: if(p) *p=0;
971: sprintf(str,"%-15.15s%-12s"
972: ,tmp /* User's first name */
973: ,useron.pass); /* User's password */
974: write(file,str,27);
975:
976: if(localtime_r(&logontime,&tm)==NULL)
977: i=0;
978: else
979: i=(tm.tm_hour*60)+tm.tm_min;
980: write(file,&i,2); /* Logon time in min since mid */
981:
982: now=time(NULL);
983: i=-(((now-starttime)/60)+useron.ttoday);/* Negative minutes used */
984: write(file,&i,2);
985:
986: sprintf(str,"%02d:%02d",tm.tm_hour,tm.tm_min);
987: write(file,str,5);
988:
989: i=cfg.level_timepercall[useron.level]; /* Time allowed on */
990: write(file,&i,2);
991:
992: i=0; /* Allowed K-bytes for D/L */
993: write(file,&i,2);
994: write(file,&i,1); /* Conference user was in */
995: write(file,&i,2); /* Conferences joined */
996: write(file,&i,2); /* "" */
997: write(file,&i,2); /* "" */
998: write(file,&i,2); /* Conferences scanned */
999: write(file,&i,2); /* "" */
1000: write(file,&i,2); /* Conference add time */
1001: write(file,&i,2); /* Upload/Sysop Chat time min */
1002:
1003: strcpy(str," ");
1004: write(file,str,4); /* Language extension */
1005:
1006: sprintf(str,"%-25.25s",name); /* User's full name */
1007: write(file,str,25);
1008:
1009: i=(tleft/60);
1010: write(file,&i,2); /* Minutes remaining */
1011:
1012: write(file,&cfg.node_num,1); /* Node number */
1013:
1014: sprintf(str,"%02d:%02d%2d%2d" /* Scheduled Event time */
1015: ,0 // sys_eventtime/60
1016: ,0 // sys_eventtime%60
1017: ,0 // sys_timed[0] ? -1:0 /* Event active ? */
1018: ,0 /* Slide event ? */
1019: );
1020: write(file,str,9);
1021:
1022: l=0L;
1023: write(file,&l,4); /* Memorized message number */
1024:
1025: sprintf(str,"%d%c%c%d%s%c%c%d%d%d%c%c"
1026: ,cfg.com_port /* COM Port number */
1027: ,' ' /* Reserved */
1028: ,' ' /* "" */
1029: ,term_supports(ANSI) /* 1=ANSI 0=NO ANSI */
1030: ,"01-01-80" /* last event date */
1031: ,0,0 /* last event minute */
1032: ,0 /* caller exited to dos */
1033: ,sys_status&SS_EVENT ? 1:0 /* event up coming */
1034: ,0 /* stop uploads */
1035: ,0,0 /* conference user was in */
1036: );
1037: write(file,str,19);
1038:
1039: close(file); /* End of PCBOARD.SYS creation */
1040:
1041: strcpy(tmp,"USERS.SYS");
1042: if(misc&XTRN_LWRCASE)
1043: strlwr(tmp);
1044: sprintf(str,"%s%s",dropdir,tmp);
1045: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
1046: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
1047: return;
1048: }
1049:
1050: /* Write goof-ball header */
1051:
1052: i=145;
1053: write(file,&i,2); /* PCBoard version number (i.e. 145) */
1054: l=useron.number;
1055: write(file,&l,4); /* Record number for USER's file */
1056: i=218;
1057: write(file,&i,2); /* Size of "fixed" user record */
1058: i=1;
1059: write(file,&i,2); /* Number of conference areas */
1060: i=7;
1061: write(file,&i,2); /* Number of bit map fields for conferences */
1062: i=5;
1063: write(file,&i,2); /* Size of each bit map field */
1064: memset(str,0,15);
1065: write(file,str,15); /* Name of Third Party Application (if any) */
1066: i=0;
1067: write(file,&i,2); /* Version number for application (if any) */
1068: write(file,&i,2); /* Size of a "fixed length" record (if any) */
1069: write(file,&i,2); /* Size of conference record (if any) */
1070: l=0;
1071: write(file,&l,4); /* Offset of AppRec into USERS.INF (if any) */
1072: i=0;
1073: write(file,&i,1); /* 1, if USERS.SYS file has been updated */
1074:
1075: /* Write fixed record portion */
1076:
1077: write(file,name,26); /* Name */
1078: sprintf(str,"%.24s",useron.location);
1079: write(file,str,25); /* Location */
1080: write(file,useron.pass,13); /* Password */
1081: write(file,useron.phone,14); /* Business or Data Phone */
1082: write(file,useron.phone,14); /* Home or Voice Phone */
1083: i=unixtojulian(useron.laston);
1084: write(file,&i,2); /* Date last on */
1085: localtime_r(&useron.laston,&tm);
1086: sprintf(str,"%02d:%02d",tm.tm_hour,tm.tm_min);
1087: write(file,str,6); /* Last time on */
1088: if(useron.misc&EXPERT)
1089: i=1;
1090: else
1091: i=0;
1092: write(file,&i,1); /* Expert mode */
1093: i='Z';
1094: write(file,&i,1); /* Protocol (A-Z) */
1095: if(useron.misc&CLRSCRN)
1096: i=2;
1097: else
1098: i=0;
1099: write(file,&i,1); /* bit packed flags */
1100: i=0;
1101: write(file,&i,2); /* DOS date for last DIR Scan */
1102: i=useron.level;
1103: write(file,&i,2); /* Security level */
1104: write(file,&useron.logons,2); /* Number of times caller has connected */
1105: c=(char)rows;
1106: write(file,&c,1); /* Page length */
1107: write(file,&useron.uls,2); /* Number of uploads */
1108: write(file,&useron.dls,2); /* Number of downloads */
1109: l=0;
1110: write(file,&l,4); /* Number of download bytes today */
1111: write(file,&useron.note,31); /* Comment #1 */
1112: write(file,&useron.comp,31); /* Comment #2 */
1113: i=(now-starttime)/60;
1114: write(file,&i,2); /* Minutes online (this logon?) */
1115: i=unixtojulian(useron.expire);
1116: write(file,&i,2); /* Expiration date */
1117: i=cfg.expired_level;
1118: write(file,&i,2); /* Expired security level */
1119: i=1;
1120: write(file,&i,2); /* Current conference */
1121: write(file,&useron.dlb,4); /* Bytes downloaded */
1122: write(file,&useron.ulb,4); /* Bytes uploaded */
1123: if(useron.misc&DELETED)
1124: i=1;
1125: else
1126: i=0;
1127: write(file,&i,1); /* Deleted? */
1128: l=useron.number;
1129: write(file,&l,4); /* Record number in USERS.INF file */
1130: l=0;
1131: memset(str,0,9);
1132: write(file,str,9); /* Reserved */
1133: write(file,&l,4); /* Number of messages read */
1134: l=useron.posts+useron.emails+useron.fbacks;
1135: write(file,&l,4); /* Number of messages left */
1136: close(file);
1137:
1138: /* End of USERS.SYS creation */
1139: }
1140:
1141: else if(type==XTRN_SPITFIRE) { /* SpitFire SFDOORS.DAT File */
1142: strcpy(tmp,"SFDOORS.DAT");
1143: if(misc&XTRN_LWRCASE)
1144: strlwr(tmp);
1145: sprintf(str,"%s%s",dropdir,tmp);
1146: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
1147: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
1148: return;
1149: }
1150:
1151: now=time(NULL);
1152: if(localtime_r(&now,&tm)==NULL)
1153: l=0;
1154: else
1155: l=((((long)tm.tm_hour*60L)+(long)tm.tm_min)*60L)
1156: +(long)tm.tm_sec;
1157:
1158: strcpy(tmp,name);
1159: if((p=strchr(tmp,' '))!=NULL)
1160: *p=0;
1161:
1162: sprintf(str,"%u\n%s\n%s\n%s\n%lu\n%u\n%lu\n%lu\n"
1163: ,useron.number /* User number */
1164: ,name /* User name */
1165: ,useron.pass /* Password */
1166: ,tmp /* User's first name */
1167: ,dte_rate /* DTE Rate */
1168: ,cfg.com_port /* COM Port */
1169: ,tleft/60 /* Time left in minutes */
1170: ,l /* Seconds since midnight (now) */
1171: );
1172: lfexpand(str,misc);
1173: write(file,str,strlen(str));
1174:
1175: if(localtime_r(&logontime,&tm)==NULL)
1176: l=0;
1177: else
1178: l=((((long)tm.tm_hour*60L)+(long)tm.tm_min)*60L)
1179: +(long)tm.tm_sec;
1180:
1181: sprintf(str,"%s\n%s\n%u\n%u\n%u\n%u\n%lu\n%lu\n%s\n"
1182: "%s\n%s\n%lu\n%s\n%u\n%u\n%u\n%u\n%u\n%lu\n%u\n"
1183: "%lu\n%lu\n%s\n%s\n"
1184: ,dropdir
1185: ,term_supports(ANSI) ? "TRUE":"FALSE" /* ANSI ? True or False */
1186: ,useron.level /* Security level */
1187: ,useron.uls /* Total uploads */
1188: ,useron.dls /* Total downloads */
1189: ,cfg.level_timepercall[useron.level]/* Minutes allowed this call */
1190: ,l /* Secs since midnight (logon) */
1191: ,(long)(starttime-logontime) /* Extra time in seconds */
1192: ,"FALSE" /* Sysop next? */
1193: ,"FALSE" /* From Front-end? */
1194: ,"FALSE" /* Software Flow Control? */
1195: ,dte_rate /* DTE Rate */
1196: ,"FALSE" /* Error correcting connection? */
1197: ,0 /* Current conference */
1198: ,0 /* Current file dir */
1199: ,cfg.node_num /* Node number */
1200: ,15 /* Downloads allowed per day */
1201: ,0 /* Downloads already this day */
1202: ,100000L /* Download bytes allowed/day */
1203: ,0 /* Downloaded bytes already today */
1204: ,useron.ulb/1024L /* Kbytes uploaded */
1205: ,useron.dlb/1024L /* Kbytes downloaded */
1206: ,useron.phone /* Phone Number */
1207: ,useron.location /* City, State */
1208: );
1209: lfexpand(str,misc);
1210: write(file,str,strlen(str));
1211:
1212: close(file);
1213: }
1214:
1215: else if(type==XTRN_UTI) { /* UTI v2.1 - UTIDOOR.TXT */
1216: strcpy(tmp,"UTIDOOR.TXT");
1217: if(misc&XTRN_LWRCASE)
1218: strlwr(tmp);
1219: sprintf(str,"%s%s",dropdir,tmp);
1220: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
1221: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
1222: return;
1223: }
1224:
1225: strcpy(tmp,name);
1226: strupr(tmp);
1227: sprintf(str,"%s\n%lu\n%u\n%lu\n%lu\n"
1228: ,tmp /* User name */
1229: ,cur_rate /* Actual BPS rate */
1230: ,online==ON_LOCAL ? 0: cfg.com_port /* COM Port */
1231: ,dte_rate /* DTE rate */
1232: ,tleft); /* Time left in sec */
1233: lfexpand(str,misc);
1234: write(file,str,strlen(str));
1235:
1236: close(file);
1237: }
1238:
1239: else if(type==XTRN_SR) { /* Solar Realms DOORFILE.SR */
1240: strcpy(tmp,"DOORFILE.SR");
1241: if(misc&XTRN_LWRCASE)
1242: strlwr(tmp);
1243: sprintf(str,"%s%s",dropdir,tmp);
1244: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
1245: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
1246: return;
1247: }
1248:
1249: sprintf(str,"%s\n%d\n%d\n%lu\n%lu\n%u\n%lu\n"
1250: ,name /* Complete name of user */
1251: ,term_supports(ANSI) /* ANSI ? */
1252: ,term_supports(NO_EXASCII) ? 0:1 /* IBM characters ? */
1253: ,rows /* Page length */
1254: ,dte_rate /* Baud rate */
1255: ,online==ON_LOCAL ? 0:cfg.com_port /* COM port */
1256: ,tleft/60 /* Time left (in minutes) */
1257: );
1258: lfexpand(str,misc);
1259: write(file,str,strlen(str));
1260: close(file);
1261: }
1262:
1263: else if(type==XTRN_TRIBBS) { /* TRIBBS.SYS */
1264: strcpy(tmp,"TRIBBS.SYS");
1265: if(misc&XTRN_LWRCASE)
1266: strlwr(tmp);
1267: sprintf(str,"%s%s",dropdir,tmp);
1268: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
1269: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
1270: return;
1271: }
1272:
1273: sprintf(str,"%u\n%s\n%s\n%u\n%c\n%c\n%lu\n%s\n%s\n%s\n"
1274: ,useron.number /* User's record number */
1275: ,name /* User's name */
1276: ,useron.pass /* User's password */
1277: ,useron.level /* User's level */
1278: ,useron.misc&EXPERT ? 'Y':'N' /* Expert? */
1279: ,term_supports(ANSI) ? 'Y':'N' /* ANSI? */
1280: ,tleft/60 /* Minutes left */
1281: ,useron.phone /* User's phone number */
1282: ,useron.location /* User's city and state */
1283: ,useron.birth /* User's birth date */
1284: );
1285: lfexpand(str,misc);
1286: write(file,str,strlen(str));
1287:
1288: sprintf(str,"%u\n%u\n%lu\n%lu\n%c\n%c\n%s\n%s\n%s\n"
1289: ,cfg.node_num /* Node number */
1290: ,cfg.com_port /* Serial port */
1291: ,online==ON_LOCAL ? 0L:cur_rate /* Baud rate */
1292: ,dte_rate /* Locked rate */
1293: ,'Y'
1294: ,'Y' /* Error correcting connection */
1295: ,cfg.sys_name /* Board's name */
1296: ,cfg.sys_op /* Sysop's name */
1297: ,useron.handle /* User's alias */
1298: );
1299: lfexpand(str,misc);
1300: write(file,str,strlen(str));
1301: close(file);
1302: }
1303:
1304: else if(type==XTRN_DOOR32) { /* DOOR32.SYS */
1305: strcpy(tmp,"DOOR32.SYS");
1306: if(misc&XTRN_LWRCASE)
1307: strlwr(tmp);
1308: sprintf(str,"%s%s",dropdir,tmp);
1309: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT))==-1) {
1310: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC|O_TEXT);
1311: return;
1312: }
1313:
1314: sprintf(str,"%d\n%d\n38400\n%s%c\n%d\n%s\n%s\n%d\n%ld\n"
1315: "%d\n%d\n"
1316: ,misc&IO_INTS ? 0 /* Local */ : 2 /* Telnet */
1317: ,misc&IO_INTS ? INVALID_SOCKET : client_socket_dup
1318: ,VERSION_NOTICE,REVISION
1319: ,useron.number
1320: ,useron.name
1321: ,name
1322: ,useron.level
1323: ,tleft/60
1324: ,term_supports(ANSI)
1325: ,cfg.node_num);
1326: lfexpand(str,misc);
1327: write(file,str,strlen(str));
1328: close(file);
1329: }
1330:
1331: else if(type)
1332: errormsg(WHERE,ERR_CHK,"Drop file type",type);
1333:
1334: }
1335:
1336: /****************************************************************************/
1337: /* Reads in MODUSER.DAT, EXITINFO.BBS, or DOOR.SYS and modify the current */
1338: /* user's values. */
1339: /****************************************************************************/
1340: void sbbs_t::moduserdat(uint xtrnnum)
1341: {
1342: char str[256],path[256],c,startup[128];
1343: char tmp[512];
1344: uint i;
1345: long mod;
1346: int file;
1347: FILE * stream;
1348:
1349: sprintf(startup,"%s/",cfg.xtrn[xtrnnum]->path);
1350: if(cfg.xtrn[xtrnnum]->type==XTRN_RBBS || cfg.xtrn[xtrnnum]->type==XTRN_RBBS1) {
1351: sprintf(path,"%sEXITINFO.BBS"
1352: ,cfg.xtrn[xtrnnum]->misc&STARTUPDIR ? startup : cfg.node_dir);
1353: fexistcase(path);
1354: if((file=nopen(path,O_RDONLY))!=-1) {
1355: lseek(file,361,SEEK_SET);
1356: read(file,&useron.flags1,4); /* Flags */
1357: putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,tmp,16));
1358: lseek(file,373,SEEK_SET);
1359: read(file,&i,2); /* SecLvl */
1360: if(i<SYSOP_LEVEL) {
1361: useron.level=i;
1362: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10));
1363: }
1364: close(file);
1365: remove(path);
1366: }
1367: return;
1368: }
1369: else if(cfg.xtrn[xtrnnum]->type==XTRN_GAP) {
1370: sprintf(path,"%sDOOR.SYS"
1371: ,cfg.xtrn[xtrnnum]->misc&STARTUPDIR ? startup : cfg.node_dir);
1372: fexistcase(path);
1373: if((stream=fopen(path,"rb"))!=NULL) {
1374: for(i=0;i<15;i++) /* skip first 14 lines */
1375: if(!fgets(str,128,stream))
1376: break;
1377: if(i==15 && isdigit(str[0])) {
1378: mod=atoi(str);
1379: if(mod<SYSOP_LEVEL) {
1380: useron.level=(char)mod;
1381: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10));
1382: }
1383: }
1384:
1385: for(;i<23;i++)
1386: if(!fgets(str,128,stream))
1387: break;
1388: if(i==23) { /* set main flags */
1389: useron.flags1=aftol(str);
1390: putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,tmp,16));
1391: }
1392:
1393: for(;i<25;i++)
1394: if(!fgets(str,128,stream))
1395: break;
1396: if(i==25 && isdigit(str[0]) && isdigit(str[1])
1397: && (str[2]=='/' || str[2]=='-') /* xx/xx/xx or xx-xx-xx */
1398: && isdigit(str[3]) && isdigit(str[4])
1399: && (str[5]=='/' || str[5]=='-')
1400: && isdigit(str[6]) && isdigit(str[7])) { /* valid expire date */
1401: useron.expire=dstrtounix(&cfg,str);
1402: putuserrec(&cfg,useron.number,U_EXPIRE,8,ultoa(useron.expire,tmp,16));
1403: }
1404:
1405: for(;i<29;i++) /* line 29, total downloaded files */
1406: if(!fgets(str,128,stream))
1407: break;
1408: if(i==29) {
1409: truncsp(str);
1410: useron.dls=atoi(str);
1411: putuserrec(&cfg,useron.number,U_DLS,5,str);
1412: }
1413:
1414: if(fgets(str,128,stream)) { /* line 30, Kbytes downloaded today */
1415: i++;
1416: truncsp(str);
1417: mod=atol(str)*1024L;
1418: if(mod) {
1419: useron.dlb=adjustuserrec(&cfg,useron.number,U_DLB,10,mod);
1420: subtract_cdt(&cfg,&useron,mod);
1421: }
1422: }
1423:
1424: for(;i<42;i++)
1425: if(!fgets(str,128,stream))
1426: break;
1427: if(i==42 && isdigit(str[0])) { /* Time Credits in Minutes */
1428: useron.min=atol(str);
1429: putuserrec(&cfg,useron.number,U_MIN,10,ultoa(useron.min,tmp,10));
1430: }
1431:
1432: fclose(stream);
1433: }
1434: return;
1435: }
1436:
1437: else if(cfg.xtrn[xtrnnum]->type==XTRN_PCBOARD) {
1438: sprintf(path,"%sUSERS.SYS"
1439: ,cfg.xtrn[xtrnnum]->misc&STARTUPDIR ? startup : cfg.node_dir);
1440: fexistcase(path);
1441: if((file=nopen(path,O_RDONLY))!=-1) {
1442: lseek(file,39,SEEK_SET);
1443: read(file,&c,1);
1444: if(c==1) { /* file has been updated */
1445: lseek(file,105,SEEK_CUR); /* read security level */
1446: read(file,&i,2);
1447: if(i<SYSOP_LEVEL) {
1448: useron.level=i;
1449: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10));
1450: }
1451: lseek(file,75,SEEK_CUR); /* read in expiration date */
1452: read(file,&i,2); /* convert from julian to unix */
1453: useron.expire=juliantounix(i);
1454: putuserrec(&cfg,useron.number,U_EXPIRE,8,ultoa(useron.expire,tmp,16));
1455: }
1456: close(file);
1457: }
1458: return;
1459: }
1460:
1461: sprintf(path,"%sMODUSER.DAT"
1462: ,cfg.xtrn[xtrnnum]->misc&STARTUPDIR ? startup : cfg.node_dir);
1463: fexistcase(path);
1464: if((stream=fopen(path,"rb"))!=NULL) { /* File exists */
1465: if(fgets(str,81,stream) && (mod=atol(str))!=0) {
1466: ultoac(mod>0L ? mod : -mod,tmp); /* put commas in the # */
1467: strcpy(str,"Credit Adjustment: ");
1468: if(mod<0L)
1469: strcat(str,"-"); /* negative, put '-' */
1470: strcat(str,tmp);
1471: if(mod>0L)
1472: strcpy(tmp,"$+");
1473: else
1474: strcpy(tmp,"$-");
1475: logline(tmp,str);
1476: if(mod>0L) /* always add to real cdt */
1477: useron.cdt=adjustuserrec(&cfg,useron.number,U_CDT,10,mod);
1478: else
1479: subtract_cdt(&cfg,&useron,-mod); /* subtract from free cdt first */
1480: }
1481: if(fgets(str,81,stream)) { /* main level */
1482: mod=atoi(str);
1483: if(isdigit(str[0]) && mod<SYSOP_LEVEL) {
1484: useron.level=(uchar)mod;
1485: putuserrec(&cfg,useron.number,U_LEVEL,2,ultoa(useron.level,tmp,10));
1486: }
1487: }
1488: fgets(str,81,stream); /* was transfer level, now ignored */
1489: if(fgets(str,81,stream)) { /* flags #1 */
1490: if(strchr(str,'-')) /* remove flags */
1491: useron.flags1&=~aftol(str);
1492: else /* add flags */
1493: useron.flags1|=aftol(str);
1494: putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,tmp,16));
1495: }
1496:
1497: if(fgets(str,81,stream)) { /* flags #2 */
1498: if(strchr(str,'-')) /* remove flags */
1499: useron.flags2&=~aftol(str);
1500: else /* add flags */
1501: useron.flags2|=aftol(str);
1502: putuserrec(&cfg,useron.number,U_FLAGS2,8,ultoa(useron.flags2,tmp,16));
1503: }
1504:
1505: if(fgets(str,81,stream)) { /* exemptions */
1506: if(strchr(str,'-'))
1507: useron.exempt&=~aftol(str);
1508: else
1509: useron.exempt|=aftol(str);
1510: putuserrec(&cfg,useron.number,U_EXEMPT,8,ultoa(useron.exempt,tmp,16));
1511: }
1512: if(fgets(str,81,stream)) { /* restrictions */
1513: if(strchr(str,'-'))
1514: useron.rest&=~aftol(str);
1515: else
1516: useron.rest|=aftol(str);
1517: putuserrec(&cfg,useron.number,U_REST,8,ultoa(useron.rest,tmp,16));
1518: }
1519: if(fgets(str,81,stream)) { /* Expiration date */
1520: if(isxdigit(str[0]))
1521: putuserrec(&cfg,useron.number,U_EXPIRE,8,str);
1522: }
1523: if(fgets(str,81,stream)) { /* additional minutes */
1524: mod=atol(str);
1525: if(mod) {
1526: sprintf(str,"Minute Adjustment: %s",ultoac(mod,tmp));
1527: logline("*+",str);
1528: useron.min=adjustuserrec(&cfg,useron.number,U_MIN,10,mod);
1529: }
1530: }
1531: if(fgets(str,81,stream)) { /* flags #3 */
1532: if(strchr(str,'-')) /* remove flags */
1533: useron.flags3&=~aftol(str);
1534: else /* add flags */
1535: useron.flags3|=aftol(str);
1536: putuserrec(&cfg,useron.number,U_FLAGS3,8,ultoa(useron.flags3,tmp,16));
1537: }
1538:
1539: if(fgets(str,81,stream)) { /* flags #4 */
1540: if(strchr(str,'-')) /* remove flags */
1541: useron.flags4&=~aftol(str);
1542: else /* add flags */
1543: useron.flags4|=aftol(str);
1544: putuserrec(&cfg,useron.number,U_FLAGS4,8,ultoa(useron.flags4,tmp,16));
1545: }
1546:
1547: if(fgets(str,81,stream)) { /* flags #1 to REMOVE only */
1548: useron.flags1&=~aftol(str);
1549: putuserrec(&cfg,useron.number,U_FLAGS1,8,ultoa(useron.flags1,tmp,16));
1550: }
1551: if(fgets(str,81,stream)) { /* flags #2 to REMOVE only */
1552: useron.flags2&=~aftol(str);
1553: putuserrec(&cfg,useron.number,U_FLAGS2,8,ultoa(useron.flags2,tmp,16));
1554: }
1555: if(fgets(str,81,stream)) { /* flags #3 to REMOVE only */
1556: useron.flags3&=~aftol(str);
1557: putuserrec(&cfg,useron.number,U_FLAGS3,8,ultoa(useron.flags3,tmp,16));
1558: }
1559: if(fgets(str,81,stream)) { /* flags #4 to REMOVE only */
1560: useron.flags4&=~aftol(str);
1561: putuserrec(&cfg,useron.number,U_FLAGS4,8,ultoa(useron.flags4,tmp,16));
1562: }
1563: if(fgets(str,81,stream)) { /* exemptions to remove */
1564: useron.exempt&=~aftol(str);
1565: putuserrec(&cfg,useron.number,U_EXEMPT,8,ultoa(useron.exempt,tmp,16));
1566: }
1567: if(fgets(str,81,stream)) { /* restrictions to remove */
1568: useron.rest&=~aftol(str);
1569: putuserrec(&cfg,useron.number,U_REST,8,ultoa(useron.rest,tmp,16));
1570: }
1571:
1572: fclose(stream);
1573: remove(path);
1574: }
1575: }
1576:
1577:
1578: /****************************************************************************/
1579: /* This function handles configured external program execution. */
1580: /****************************************************************************/
1581: bool sbbs_t::exec_xtrn(uint xtrnnum)
1582: {
1583: char str[256],path[MAX_PATH+1],dropdir[MAX_PATH+1],name[32],c;
1584: int file;
1585: uint i;
1586: long tleft,mode;
1587: node_t node;
1588: time_t start,end;
1589:
1590: if(!chk_ar(cfg.xtrn[xtrnnum]->run_ar,&useron)
1591: || !chk_ar(cfg.xtrnsec[cfg.xtrn[xtrnnum]->sec]->ar,&useron)) {
1592: bputs(text[CantRunThatProgram]);
1593: return(false);
1594: }
1595:
1596: if(cfg.xtrn[xtrnnum]->cost && !(useron.exempt&FLAG('X'))) { /* costs */
1597: if(cfg.xtrn[xtrnnum]->cost>useron.cdt+useron.freecdt) {
1598: bputs(text[NotEnoughCredits]);
1599: pause();
1600: return(false);
1601: }
1602: subtract_cdt(&cfg,&useron,cfg.xtrn[xtrnnum]->cost);
1603: }
1604:
1605: if(!(cfg.xtrn[xtrnnum]->misc&MULTIUSER)) {
1606: for(i=1;i<=cfg.sys_nodes;i++) {
1607: getnodedat(i,&node,0);
1608: c=i;
1609: if((node.status==NODE_INUSE || node.status==NODE_QUIET)
1610: && node.action==NODE_XTRN && node.aux==(xtrnnum+1)) {
1611: if(node.status==NODE_QUIET) {
1612: SAFECOPY(str,cfg.sys_guru);
1613: c=cfg.sys_nodes+1;
1614: }
1615: else if(node.misc&NODE_ANON)
1616: SAFECOPY(str,"UNKNOWN USER");
1617: else
1618: username(&cfg,node.useron,str);
1619: bprintf(text[UserRunningXtrn],str
1620: ,cfg.xtrn[xtrnnum]->name,c);
1621: pause();
1622: break;
1623: }
1624: }
1625: if(i<=cfg.sys_nodes)
1626: return(false);
1627: }
1628:
1629: SAFECOPY(str,cfg.xtrn[xtrnnum]->path);
1630: backslash(str);
1631: SAFECOPY(path,cfg.xtrn[xtrnnum]->misc&STARTUPDIR ? str : cfg.node_dir);
1632: SAFECOPY(dropdir,cfg.xtrn[xtrnnum]->misc&STARTUPDIR ? str : cfg.node_dir);
1633:
1634: switch(cfg.xtrn[xtrnnum]->type) {
1635: case XTRN_WWIV:
1636: SAFECOPY(name,"CHAIN.TXT");
1637: break;
1638: case XTRN_GAP:
1639: SAFECOPY(name,"DOOR.SYS");
1640: break;
1641: case XTRN_RBBS:
1642: sprintf(str,"DORINFO%X.DEF",cfg.node_num);
1643: SAFECOPY(name,str);
1644: break;
1645: case XTRN_RBBS1:
1646: SAFECOPY(name,"DORINFO1.DEF");
1647: break;
1648: case XTRN_WILDCAT:
1649: SAFECOPY(name,"CALLINFO.BBS");
1650: break;
1651: case XTRN_PCBOARD:
1652: SAFECOPY(name,"PCBOARD.SYS");
1653: break;
1654: case XTRN_UTI:
1655: SAFECOPY(name,"UTIDOOR.TXT");
1656: break;
1657: case XTRN_SR:
1658: SAFECOPY(name,"DOORFILE.SR");
1659: break;
1660: case XTRN_TRIBBS:
1661: SAFECOPY(name,"TRIBBS.SYS");
1662: break;
1663: case XTRN_DOOR32:
1664: SAFECOPY(name,"DOOR32.SYS");
1665: break;
1666: default:
1667: SAFECOPY(name,"XTRN.DAT");
1668: break;
1669: }
1670: if(cfg.xtrn[xtrnnum]->misc&XTRN_LWRCASE)
1671: strlwr(name);
1672: strcat(path,name);
1673: getnodedat(cfg.node_num,&thisnode,1);
1674: thisnode.aux=xtrnnum+1;
1675: thisnode.action=NODE_XTRN;
1676: putnodedat(cfg.node_num,&thisnode);
1677: putuserrec(&cfg,useron.number,U_CURXTRN,8,cfg.xtrn[xtrnnum]->code);
1678:
1679: if(cfg.xtrn[xtrnnum]->misc&REALNAME)
1680: SAFECOPY(name,useron.name);
1681: else
1682: SAFECOPY(name,useron.alias);
1683:
1684: gettimeleft();
1685: tleft=timeleft+(cfg.xtrn[xtrnnum]->textra*60);
1686: if(cfg.xtrn[xtrnnum]->maxtime && tleft>(cfg.xtrn[xtrnnum]->maxtime*60))
1687: tleft=(cfg.xtrn[xtrnnum]->maxtime*60);
1688: xtrndat(name,dropdir,cfg.xtrn[xtrnnum]->type,tleft,cfg.xtrn[xtrnnum]->misc);
1689: if(!online)
1690: return(false);
1691: sprintf(str,"%s running external program: %s"
1692: ,useron.alias,cfg.xtrn[xtrnnum]->name);
1693: logline("X-",str);
1694: if(cfg.xtrn[xtrnnum]->cmd[0]!='*' && logfile_fp!=NULL) {
1695: fclose(logfile_fp);
1696: logfile_fp=NULL;
1697: }
1698:
1699: sprintf(str,"%sINTRSBBS.DAT"
1700: ,cfg.xtrn[xtrnnum]->path[0] ? cfg.xtrn[xtrnnum]->path : cfg.node_dir);
1701: if(fexistcase(str))
1702: remove(str);
1703: sprintf(str,"%shangup.now",cfg.node_dir);
1704: if(fexistcase(str))
1705: remove(str);
1706: sprintf(str,"%sfile/%04u.dwn",cfg.data_dir,useron.number);
1707: if(fexistcase(str))
1708: remove(str);
1709:
1710: mode=0;
1711: if(cfg.xtrn[xtrnnum]->misc&XTRN_SH)
1712: mode|=EX_SH;
1713: if(cfg.xtrn[xtrnnum]->misc&IO_INTS)
1714: mode|=(EX_OUTR|EX_INR|EX_OUTL);
1715: mode|=(cfg.xtrn[xtrnnum]->misc&(XTRN_CHKTIME|XTRN_NATIVE|XTRN_NOECHO|WWIVCOLOR));
1716: if(cfg.xtrn[xtrnnum]->misc&MODUSERDAT) { /* Delete MODUSER.DAT */
1717: sprintf(str,"%sMODUSER.DAT",dropdir); /* if for some weird */
1718: remove(str); /* reason it's there */
1719: }
1720:
1721: start=time(NULL);
1722: external(cmdstr(cfg.xtrn[xtrnnum]->cmd,path
1723: ,cfg.xtrn[xtrnnum]->path
1724: ,NULL)
1725: ,mode
1726: ,cfg.xtrn[xtrnnum]->path);
1727: end=time(NULL);
1728: if(cfg.xtrn[xtrnnum]->misc&FREETIME)
1729: starttime+=end-start;
1730: if(cfg.xtrn[xtrnnum]->clean[0]) {
1731: external(cmdstr(cfg.xtrn[xtrnnum]->clean,path,nulstr,NULL)
1732: ,mode&~EX_INR, cfg.xtrn[xtrnnum]->path);
1733: }
1734: /* Re-open the logfile */
1735: if(logfile_fp==NULL) {
1736: sprintf(str,"%snode.log",cfg.node_dir);
1737: if((logfile_fp=fopen(str,"a+b"))==NULL)
1738: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
1739: }
1740:
1741: sprintf(str,"%sfile/%04u.dwn",cfg.data_dir,useron.number);
1742: batch_add_list(str);
1743:
1744: sprintf(str,"%shangup.now",cfg.node_dir);
1745: if(fexistcase(str)) {
1746: lprintf(LOG_NOTICE,"Node %d External program requested hangup (%s signaled)"
1747: ,cfg.node_num, str);
1748: remove(str);
1749: hangup();
1750: }
1751: else if(!online) {
1752: sprintf(str,"%shungup.log",cfg.logs_dir);
1753: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
1754: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
1755: return(false);
1756: }
1757: getnodedat(cfg.node_num,&thisnode,0);
1758: now=time(NULL);
1759: sprintf(str,hungupstr,useron.alias,cfg.xtrn[thisnode.aux-1]->name
1760: ,timestr(&now));
1761: write(file,str,strlen(str));
1762: close(file);
1763: }
1764: if(cfg.xtrn[xtrnnum]->misc&MODUSERDAT) /* Modify user data */
1765: moduserdat(xtrnnum);
1766:
1767: getnodedat(cfg.node_num,&thisnode,1);
1768: thisnode.aux=0;
1769: putnodedat(cfg.node_num,&thisnode);
1770:
1771: return(true);
1772: }
1773:
1774: /****************************************************************************/
1775: /* This function will execute an external program if it is configured to */
1776: /* run during the event specified. */
1777: /****************************************************************************/
1778: bool sbbs_t::user_event(user_event_t event)
1779: {
1780: uint i;
1781: bool success=false;
1782:
1783: for(i=0;i<cfg.total_xtrns;i++) {
1784: if(cfg.xtrn[i]->event!=event)
1785: continue;
1786: if(!chk_ar(cfg.xtrn[i]->ar,&useron)
1787: || !chk_ar(cfg.xtrnsec[cfg.xtrn[i]->sec]->ar,&useron))
1788: continue;
1789: success=exec_xtrn(i);
1790: }
1791:
1792: return(success);
1793: }
1794:
1795:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.