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