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