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