|
|
1.1 root 1: /* SCB */
2:
3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
4:
5: #include "xsdk.h"
6: #include "scb.h"
7:
8: /* RCIOLL.ASM */
9:
10: int rioini(int com,int irq); /* initialize com,irq */
11: int setbaud(int rate); /* set baud rate */
12: int rioctl(int action); /* remote i/o control */
13: int dtr(char onoff); /* set/reset dtr */
14: int outcom(int ch); /* send character */
15: int incom(void); /* receive character */
16: int ivhctl(int intcode); /* local i/o redirection */
17:
18: /************************/
19: /* Remote I/O Constants */
20: /************************/
21:
22: /* i/o mode and state flags */
23: #define CTSCK 0x1000 /* check cts (mode only) */
24: #define RTSCK 0x2000 /* check rts (mode only) */
25: #define TXBOF 0x0800 /* transmit buffer overflow (outcom only) */
26: #define ABORT 0x0400 /* check for ^C (mode), aborting (state) */
27: #define PAUSE 0x0200 /* check for ^S (mode), pausing (state) */
28: #define NOINP 0x0100 /* input buffer empty (incom only) */
29:
30: /* status flags */
31: #define RIODCD 0x80 /* DCD on */
32: #define RI 0x40 /* Ring indicate */
33: #define DSR 0x20 /* Dataset ready */
34: #define CTS 0x10 /* CTS on */
35: #define FERR 0x08 /* Frameing error */
36: #define PERR 0x04 /* Parity error */
37: #define OVRR 0x02 /* Overrun */
38: #define RXLOST 0x01 /* Receive buffer overflow */
39:
40: /* rioctl() arguments */
41: /* returns mode or state flags in high 8 bits, status flags in low 8 bits */
42:
43: /* the following return mode in high 8 bits */
44: #define IOMODE 0 /* no operation */
45: #define IOSM 1 /* i/o set mode flags */
46: #define IOCM 2 /* i/o clear mode flags */
47: /* the following return state in high 8 bits */
48: #define IOSTATE 4 /* no operation */
49: #define IOSS 5 /* i/o set state flags */
50: #define IOCS 6 /* i/o clear state flags */
51: #define IOFB 0x308 /* i/o buffer flush */
52: #define IOFI 0x208 /* input buffer flush */
53: #define IOFO 0x108 /* output buffer flush */
54: #define IOCE 9 /* i/o clear error flags */
55:
56: /* return count (16bit) */
57: #define RXBC 0x0a /* get receive buffer count */
58: #define TXBC 0x0b /* get transmit buffer count */
59: #define TXSYNC 0x0c /* sync transmition (seconds<<8|0x0c) */
60: #define IDLE 0x0d /* suspend communication routines */
61: #define RESUME 0x10d /* return from suspended state */
62: #define RLERC 0x000e /* read line error count and clear */
63: #define CPTON 0x0110 /* set input translation flag for ctrl-p on */
64: #define CPTOFF 0x0010 /* set input translation flag for ctrl-p off */
65: #define GETCPT 0x8010 /* return the status of ctrl-p translation */
66: #define MSR 0x0011 /* read modem status register */
67: #define FIFOCTL 0x0012 /* FIFO UART control */
68: #define TSTYPE 0x0013 /* Time-slice API type */
69: #define GETTST 0x8013 /* Get Time-slice API type */
70:
71:
72: #define I14DB 0x001d /* DigiBoard int 14h driver */
73: #define I14PC 0x011d /* PC int 14h driver */
74: #define I14PS 0x021d /* PS/2 int 14h driver */
75: #define I14FO 0x031d /* FOSSIL int 14h driver */
76:
77:
78: /* ivhctl() arguments */
79: #define INT29R 1 /* copy int 29h output to remote */
80: #define INT29L 2 /* Use _putlc for int 29h */
81: #define INT16 0x10 /* return remote chars to int 16h calls */
82: #define INTCLR 0 /* release int 16h, int 29h */
83:
84: #define LEN_ALIAS 25 /* User alias */
85: #define LEN_NAME 25 /* User name */
86: #define LEN_HANDLE 8 /* User chat handle */
87: #define LEN_NOTE 30 /* User note */
88: #define LEN_COMP 30 /* User computer description */
89: #define LEN_COMMENT 60 /* User comment */
90: #define LEN_NETMAIL 60 /* NetMail forwarding address */
91: #define LEN_PASS 8 /* User password */
92: #define LEN_PHONE 12 /* User phone number */
93: #define LEN_BIRTH 8 /* Birthday in MM/DD/YY format */
94: #define LEN_ADDRESS 30 /* User address */
95: #define LEN_LOCATION 30 /* Location (City, State) */
96: #define LEN_ZIPCODE 10 /* Zip/Postal code */
97: #define LEN_MODEM 8 /* User modem type description */
98: #define LEN_FDESC 58 /* File description */
99: #define LEN_TITLE 70 /* Message title */
100: #define LEN_MAIN_CMD 40 /* Storage in user.dat for custom commands */
101: #define LEN_XFER_CMD 40
102: #define LEN_SCAN_CMD 40
103: #define LEN_MAIL_CMD 40
104: #define LEN_CID 25 /* Caller ID (phone number) */
105: #define LEN_ARSTR 40 /* Max length of Access Requirement string */
106:
107: /****************************************************************************/
108: /* This is a list of offsets into the USER.DAT file for different variables */
109: /* that are stored (for each user) */
110: /****************************************************************************/
111: #define U_ALIAS 0 /* Offset to alias */
112: #define U_NAME (U_ALIAS+LEN_ALIAS) /* Offset to name */
113: #define U_HANDLE (U_NAME+LEN_NAME)
114: #define U_NOTE (U_HANDLE+LEN_HANDLE+2)
115: #define U_COMP (U_NOTE+LEN_NOTE)
116: #define U_COMMENT (U_COMP+LEN_COMP+2)
117:
118: #define U_NETMAIL (U_COMMENT+LEN_COMMENT+2)
119:
120: #define U_ADDRESS (U_NETMAIL+LEN_NETMAIL+2)
121: #define U_LOCATION (U_ADDRESS+LEN_ADDRESS)
122: #define U_ZIPCODE (U_LOCATION+LEN_LOCATION)
123:
124: #define U_PASS (U_ZIPCODE+LEN_ZIPCODE+2)
125: #define U_PHONE (U_PASS+8) /* Offset to phone-number */
126: #define U_BIRTH (U_PHONE+12) /* Offset to users birthday */
127: #define U_MODEM (U_BIRTH+8)
128: #define U_LASTON (U_MODEM+8)
129: #define U_FIRSTON (U_LASTON+8)
130: #define U_EXPIRE (U_FIRSTON+8)
131: #define U_PWMOD (U_EXPIRE+8)
132:
133: #define U_LOGONS (U_PWMOD+8+2)
134: #define U_LTODAY (U_LOGONS+5)
135: #define U_TIMEON (U_LTODAY+5)
136: #define U_TEXTRA (U_TIMEON+5)
137: #define U_TTODAY (U_TEXTRA+5)
138: #define U_TLAST (U_TTODAY+5)
139: #define U_POSTS (U_TLAST+5)
140: #define U_EMAILS (U_POSTS+5)
141: #define U_FBACKS (U_EMAILS+5)
142: #define U_ETODAY (U_FBACKS+5)
143: #define U_PTODAY (U_ETODAY+5)
144:
145: #define U_ULB (U_PTODAY+5+2)
146: #define U_ULS (U_ULB+10)
147: #define U_DLB (U_ULS+5)
148: #define U_DLS (U_DLB+10)
149: #define U_CDT (U_DLS+5)
150: #define U_MIN (U_CDT+10)
151:
152: #define U_LEVEL (U_MIN+10+2) /* Offset to Security Level */
153: #define U_FLAGS1 (U_LEVEL+2) /* Offset to Flags */
154: #define U_TL (U_FLAGS1+8) /* Offset to unused field */
155: #define U_FLAGS2 (U_TL+2) /* Offset to unused field */
156: #define U_EXEMPT (U_FLAGS2+8)
157: #define U_REST (U_EXEMPT+8)
158: #define U_ROWS (U_REST+8+2) /* Number of Rows on user's monitor */
159: #define U_SEX (U_ROWS+2) /* Sex, Del, ANSI, color etc. */
160: #define U_MISC (U_SEX+1) /* Miscellaneous flags in 8byte hex */
161: #define U_XEDIT (U_MISC+8) /* External editor */
162: #define U_LEECH (U_XEDIT+2) /* two hex digits - leech attempt count */
163: #define U_CURGRP (U_LEECH+2) /* Current group */
164: #define U_CURSUB (U_CURGRP+4) /* Current sub-board */
165: #define U_CURLIB (U_CURSUB+4) /* Current library */
166: #define U_CURDIR (U_CURLIB+4) /* Current directory */
167: #define U_CMDSET (U_CURDIR+4) /* User's command set */
168: #define U_MAIN_CMD (U_CMDSET+2+2) /* Custom main command set */
169: #define U_XFER_CMD (U_MAIN_CMD+LEN_MAIN_CMD)
170: #define U_SCAN_CMD (U_XFER_CMD+LEN_XFER_CMD+2)
171: #define U_MAIL_CMD (U_SCAN_CMD+LEN_SCAN_CMD)
172: #define U_FREECDT (U_MAIL_CMD+LEN_MAIL_CMD+2) /* Unused bytes */
173: #define U_FLAGS3 (U_FREECDT+10) /* Unused bytes */
174: #define U_FLAGS4 (U_FLAGS3+8)
175: #define U_UNUSED1 (U_FLAGS4+8)
176: #define U_UNUSED2 (U_UNUSED1+22+2)
177: #define U_LEN (U_UNUSED2+48+2)
178:
179: enum {
180: PHONE_OKAY
181: ,PHONE_INVALID
182: ,PHONE_LD
183: };
184:
185: unsigned _stklen=16000; /* Set stack size in code, not header */
186:
187: uint asmrev,options=0;
188: char canfile[256],result[256]={NULL},tmp[256],
189: addfile[256],phone_number[81]={NULL},flags1[81],flags2[81],flags3[81],
190: flags4[81],exempt[81],restrict[81],expiration[81],credits[81],minutes[81],
191: level[81],bbs_ac[81];
192: char *crlf="\r\n";
193: extern uint riobp;
194: extern int mswtyp;
195: char io_int=0,validated=0; /* i/o interrupts intercepted? yes/no */
196: int sysop=0;
197: int ldstart[7],ldend[7],min_phone_len,max_phone_len,hangup_time;
198:
199: /***********************/
200: /* Function Prototypes */
201: /***********************/
202: int lprintf(char *fmat, ...);
203: void bail();
204: int main();
205: void phone_val();
206: char *get_user_pw();
207: char check_phone(char *insearch);
208: void mdmcmd(char *str);
209: void putcomch(char ch);
210: char getmdmstr(char *str, int sec);
211: void mswait(int);
212: void moduser();
213: void write_info();
214: char long_distance(char *number);
215:
216: /****************************************************************************/
217: /* Performs printf() through local assembly routines */
218: /* Called from everywhere */
219: /****************************************************************************/
220: int lprintf(char *fmat, ...) {
221: char sbuf[256];
222: int chcount;
223:
224: chcount=vsprintf(sbuf,fmat,_va_ptr);
225: lputs(sbuf);
226: return(chcount);
227: }
228:
229: void bail()
230: {
231: char str[256];
232: int i;
233:
234: if(io_int)
235: ivhctl(0);
236: else if(!(options&STAY_CONNECTED)) { /* exiting without re-connecting */
237: dtr(10);
238: sprintf(str,"%sHANGUP.NOW",node_dir);
239: if((i=nopen(str,O_CREAT|O_RDWR))!=-1)
240: close(i); }
241: if(com_port) {
242: for(i=0;i<5;i++)
243: if(!rioctl(TXBC)) /* wait for rest of output */
244: break;
245: else
246: mswait(1000);
247: rioini(0,0); }
248: if(options&ALWAYS_VALIDATE || validated)
249: moduser();
250: write_info();
251: lputc(FF);
252: }
253:
254: int main()
255: {
256: void *v;
257: uchar far *s;
258: char str[128],ch,*p;
259: int i,file;
260: uint base=0xffff;
261: FILE *stream;
262:
263: node_dir[0]=0;
264:
265: p=getenv("SBBSNODE");
266: if(p)
267: strcpy(node_dir,p);
268:
269: if(!node_dir[0]) { /* node directory not specified */
270: printf("\n\7SBBSNODE environment variable must be set.\n");
271: printf("\nExample: SET SBBSNODE=C:\\SBBS\\NODE1\n");
272: getch();
273: return(1); }
274:
275: if(node_dir[strlen(node_dir)-1]!='\\') /* make sure node_dir ends in '\' */
276: strcat(node_dir,"\\");
277:
278: initdata(); /* read XTRN.DAT and more */
279:
280: if((asmrev=*(&riobp-1))!=23) {
281: printf("Wrong rciol.obj\n");
282: exit(1); }
283:
284: lclini(0xd<<8); /* Tab expansion, no CRLF expansion */
285:
286: if(com_port) {
287: lprintf("\r\nInitializing COM port %u: ",com_port);
288: switch(com_base) {
289: case 0xb:
290: lputs("PC BIOS");
291: rioctl(I14PC);
292: break;
293: case 0xffff:
294: case 0xd:
295: lputs("DigiBoard");
296: rioctl(I14DB);
297: break;
298: case 0xe:
299: lputs("PS/2 BIOS");
300: rioctl(I14PS);
301: break;
302: case 0xf:
303: lputs("FOSSIL");
304: rioctl(I14FO);
305: break;
306: case 0:
307: base=com_port;
308: lputs("UART I/O (BIOS), ");
309: if(com_irq)
310: lprintf("IRQ %d",com_irq);
311: else lputs("default IRQ");
312: break;
313: default:
314: base=com_base;
315: lprintf("UART I/O %Xh, ",com_base);
316: if(com_irq)
317: lprintf("IRQ %d",com_irq);
318: else lputs("default IRQ");
319: break; }
320:
321: if(base==0xffff)
322: lprintf(" channel %u",com_irq);
323: i=rioini(base,com_irq);
324: if(i) {
325: lprintf(" - Failed! (%d)\r\n",i);
326: exit(1); }
327: if(mdm_misc&MDM_FLOWCTRL)
328: rioctl(IOSM|CTSCK|RTSCK); /* set rts/cts chk */
329: setbaud((uint)(com_rate&0xffffL));
330: msr=&riobp-1; }
331:
332: rioctl(TSTYPE|mswtyp); /* set time-slice API type */
333:
334: rioctl(CPTON); /* ctrl-p translation */
335:
336: i=INT29L;
337: if(com_port)
338: i|=(INT29R|INT16);
339: ivhctl(i);
340: io_int=1;
341:
342: atexit(bail);
343:
344: phone_val();
345:
346: return(0);
347: }
348:
349: /******************************************************************************
350: Main phone validation loop.
351: ******************************************************************************/
352: void phone_val()
353: {
354: FILE *stream;
355: char user_password[9],str[256],init_attempts=0,callout_attempts=0,*p;
356: int i=0,j,file;
357:
358: if((file=nopen("SCB.CFG",O_RDONLY))==-1) {
359: bprintf("ERROR: Opening configuration file\r\n"); exit(1); }
360: if((stream=fdopen(file,"rb"))==NULL) {
361: bprintf("ERROR: Converting configuration file to a stream\r\n");
362: exit(1); }
363: fgets(str,81,stream); truncsp(str); callout_attempts=atoi(str);
364: fgets(str,81,stream); truncsp(str);
365: if(str[0]=='Y') options|=ALWAYS_VALIDATE;
366: if(str[1]=='Y') options|=MODIFY_USER_NOTE;
367: if(str[2]=='Y') options|=START_WITH_0;
368: if(str[3]=='Y') options|=START_WITH_1;
369: if(str[4]=='Y') options|=STAY_CONNECTED;
370: if(str[5]=='Y') options|=SC_LOCAL_ONLY;
371: if(str[6]=='Y') options|=US_PHONE_FORMAT;
372: if(str[7]=='Y') options|=ALLOWED_ONLY;
373: if(str[8]!='N') options|=SAME_AREA_LD;
374: fgets(canfile,81,stream); truncsp(canfile);
375: fgets(addfile,81,stream); truncsp(addfile);
376: fgets(credits,81,stream); truncsp(credits);
377: fgets(str,81,stream); truncsp(str); sysop=atoi(str);
378: fgets(level,81,stream); truncsp(level);
379: fgets(flags1,81,stream); truncsp(flags1);
380: fgets(flags2,81,stream); truncsp(flags2);
381: fgets(exempt,81,stream); truncsp(exempt);
382: fgets(restrict,81,stream); truncsp(restrict);
383: fgets(expiration,81,stream); truncsp(expiration);
384: fgets(minutes,81,stream); truncsp(minutes);
385: fgets(flags3,81,stream); truncsp(flags3);
386: fgets(flags4,81,stream); truncsp(flags4);
387: for(i=0;i<7;i++) {
388: fgets(str,81,stream); ldstart[i]=atoi(str); /* min since midnight */
389: fgets(str,81,stream); ldend[i]=atoi(str); }
390: fgets(str,81,stream); min_phone_len=atoi(str);
391: fgets(str,81,stream); max_phone_len=atoi(str);
392: fgets(bbs_ac,81,stream); truncsp(bbs_ac);
393: if(fgets(str,81,stream)) {
394: hangup_time=atoi(str);
395: if(hangup_time>90)
396: hangup_time=90; }
397: else
398: hangup_time=30;
399:
400: fgets(str,81,stream); // regnum
401:
402: fclose(stream);
403:
404: cls();
405: strcpy(result,"Hung up");
406: strcpy(user_password,get_user_pw());
407: bprintf("\1c\1hSynchronet Callback v%s "
408: "Developed 1995-1997 Rob Swindell\r\n",VERSION);
409: sprintf(str,"%s..\\EXEC\\",ctrl_dir);
410: printfile("SCB.MSG");
411: if(yesno("\r\nDo you need instructions"))
412: printfile("INSTRUCT.MSG");
413: if(!yesno("\r\nContinue with verification")) {
414: options&=~ALWAYS_VALIDATE;
415: cls(); printfile("REFUSED.MSG"); pause();
416: strcpy(result,"Refused");
417: return; }
418: /***
419: if(!(options&ALLOW_LD) && yesno("Are you calling long distance")) {
420: bprintf("\r\n\1n\1cSorry, \1h%s \1n\1cwill verify \1y\1hLOCAL "
421: "\1n\1ccalls only!\r\n",sys_name);
422: strcpy(result,"Long Dist"); pause();
423: return; }
424: ***/
425:
426: while(1) {
427: while(1) {
428: bprintf("\r\n\r\n\1n\1cEnter your \1h\1yCOMPLETE \1n\1cphone "
429: "number now. If you are calling long distance, enter\r\n\1h\1y"
430: "ALL \1n\1cof the digits necessary to reach your phone number. "
431: "If you are a \1h\1yLOCAL \1n\1ccall from the BBS, \1h\1yDO NOT"
432: "\1n\1c enter unnecessary digits (your area code, for example)."
433: "\r\n:");
434: getstr(phone_number,20,K_LINE|K_NUMBER);
435: if(yesno("\r\nIs this correct")) break; }
436:
437: if(bbs_ac[0]) { /* Strip off area code */
438: if(!strncmp(phone_number,bbs_ac,strlen(bbs_ac)))
439: strcpy(phone_number,phone_number+strlen(bbs_ac));
440: else {
441: sprintf(tmp,"1%s",bbs_ac);
442: if(!strncmp(phone_number,tmp,strlen(tmp)))
443: strcpy(phone_number,phone_number+strlen(tmp)); } }
444:
445: if(options&US_PHONE_FORMAT && /* Add 1 to number */
446: (phone_number[1]=='0' || phone_number[1]=='1') &&
447: strlen(phone_number)>7) {
448: sprintf(tmp,"1%s",phone_number);
449: strcpy(phone_number,tmp); }
450:
451: j=check_phone(phone_number);
452:
453: if(j==PHONE_LD) {
454: strcpy(result,"Long Dist");
455: pause();
456: return; }
457: if(j==PHONE_OKAY)
458: break;
459: options&=~ALWAYS_VALIDATE;
460: strcpy(result,"Invalid #");
461: bprintf("\r\n\1n\1cReturning you to \1h%s.\1n\r\n",sys_name);
462: return; }
463:
464: bprintf("\r\n\r\n\1n\1cDropping Carrier, \1h%s \1n\1cwill call you back "
465: "now.\r\nType \1h\1yATA \1n\1cto answer when your modem rings!\r\n\r\n"
466: ,sys_name);
467: if(!com_port) exit(0);
468: mswait(1000);
469: ivhctl(0); /* put intercepted i/o vectors back */
470: io_int=0;
471:
472: for(init_attempts=0;init_attempts<4;init_attempts++) { /* 4 attempts */
473: dtr(5);
474: if(!init_attempts) mswait(1000);
475: dtr(1);
476: rioctl(IOFB);
477: for(i=0;i<4;i++) {
478: mdmcmd(mdm_init);
479: if(!getmdmstr(str,10))
480: continue;
481: if(!stricmp(str,mdm_init)) { /* Echo on? */
482: getmdmstr(str,10); /* Get OK */
483: mdmcmd("ATE0"); /* Turn echo off */
484: if(!getmdmstr(str,10))
485: continue; }
486: if(!strcmp(str,"OK")) { /* Verbal response? */
487: mdmcmd("ATV0"); /* Turn verbal off */
488: if(!getmdmstr(str,10))
489: continue; }
490: if(!strcmp(str,"0"))
491: break;
492: rioctl(IOFB); /* Send fool-proof init string */
493: mdmcmd("ATE0V0");
494: if(getmdmstr(str,10) && !strcmp(str,"0"))
495: break; }
496: if(i==4)
497: continue;
498: mswait(100);
499: if(mdm_spec[0]) {
500: for(i=0;i<4;i++) {
501: mdmcmd(mdm_spec);
502: if(!getmdmstr(str,10)) continue;
503: if(!strcmp(str,"0")) break; }
504: if(i==4)
505: continue; }
506: break; }
507:
508: if(init_attempts==4) { /* couldn't init */
509: strcpy(result,"No Init");
510: exit(1); }
511:
512: mswait(1000);
513: mdmcmd("ATH");
514: str[0]=0;
515: getmdmstr(str,10);
516: if(strcmp(str,"0")) {
517: strcpy(result,"No Init");
518: exit(1); }
519: if(hangup_time)
520: bprintf("\r\n\1n\1cWaiting \1h%u\1n\1c seconds before dialing..."
521: "\r\n\r\n",hangup_time);
522: mswait(hangup_time*1000); /* Wait xx seconds before dialing */
523:
524: for(i=0;i<callout_attempts;i++) {
525: mswait(5000);
526: rioctl(IOFB);
527: sprintf(str,"%s%s",mdm_dial,phone_number);
528: mdmcmd(str);
529: if(!getmdmstr(str,60)) {
530: mdmcmd(""); /* send CR to abort dial */
531: continue; }
532: if(strcmp(str,"0") && strcmp(str,"2") && strcmp(str,"3")
533: && strcmp(str,"4") && strcmp(str,"6") && strcmp(str,"7")
534: && strcmp(str,"8") && strcmp(str,"9"))
535: break; }
536:
537: if(i==callout_attempts) { /* Couldn't connect */
538: strcpy(result,"No Connect");
539: exit(1); }
540:
541: i=INT29L; /* intercept i/o vectors again */
542: if(com_port)
543: i|=(INT29R|INT16);
544: ivhctl(i);
545: io_int=1;
546:
547: if(rioctl(IOSTATE|DCD)) {
548: mswait(5000); /* wait 5 seconds for MNP to Non-MNP connect */
549: rioctl(IOFB);
550: lncntr=0;
551: i=0; cls();
552: bprintf("\r\n\r\n\1n\1cThis is \1h%s \1n\1ccalling for \1m%s.",
553: sys_name,user_name);
554: while(1) {
555: bprintf("\r\n\r\n\1h\1yEnter your password for verification: ");
556: getstr(str,8,K_UPPER|K_LINE);
557: if(!stricmp(str,user_password)) {
558: validated=1;
559: bprintf("\r\n\r\n\1n\1cYou have now been verified on \1h%s!",
560: sys_name);
561: printfile("VERIFIED.MSG");
562: strcpy(result,"Verified");
563: break; }
564: else {
565: bprintf("\r\n\1r\1hINCORRECT!\1n");
566: if(++i>=4) {
567: bprintf("\r\n\r\n\1r\1hYou have entered an incorrect "
568: "password. Goodbye.\r\n\r\n"); dtr(5);
569: strcpy(result,"Bad Pass"); return; } } }
570:
571: if(!(options&STAY_CONNECTED)) {
572: mswait(2000);
573: for(i=0;i<5;i++) {
574: dtr(5);
575: if(!(rioctl(IOSTATE)&DCD)) /* no carrier detect */
576: break;
577: lprintf("SCB: Dropping DTR failed to lower DCD.\r\n");
578: dtr(1);
579: mswait(2000); }
580: sprintf(str,"%sHANGUP.NOW",node_dir);
581: if((i=nopen(str,O_CREAT|O_RDWR))!=-1)
582: close(i); } }
583: }
584:
585: /******************************************************************************
586: Writes the MODUSER.DAT file.
587: ******************************************************************************/
588: void moduser()
589: {
590: FILE *stream;
591: char str[512];
592: int file;
593: long expire;
594: time_t now;
595:
596: now=time(NULL);
597:
598: if(user_expire>now)
599: expire=(user_expire+(atol(expiration)*24L*60L*60L));
600: else
601: expire=(now+(atol(expiration)*24L*60L*60L));
602:
603: sprintf(str,"%sMODUSER.DAT",node_dir);
604: if((stream=fopen(str,"wb"))!=NULL) {
605: fprintf(stream,"%s\r\n",credits);
606: fprintf(stream,"%s\r\n",level);
607: fprintf(stream,"\r\n");
608: fprintf(stream,"%s\r\n",flags1);
609: fprintf(stream,"%s\r\n",flags2);
610: fprintf(stream,"%s\r\n",exempt);
611: fprintf(stream,"%s\r\n",restrict);
612: fprintf(stream,"%s\r\n",atol(expiration) ? ultoa(expire,str,16) : "");
613: fprintf(stream,"%s\r\n",minutes);
614: fprintf(stream,"%s\r\n",flags3);
615: fprintf(stream,"%s\r\n",flags4);
616: fclose(stream);
617: }
618: else
619: bprintf("\7\r\nError opening %s for write.\r\n",str);
620: if(addfile[0] && phone_number[0]) {
621: if((file=nopen(addfile,O_WRONLY|O_APPEND|O_CREAT))!=-1) {
622: sprintf(str,"%s^\r\n",phone_number);
623: write(file,str,strlen(str));
624: close(file); }
625: else
626: bprintf("\7\r\nError opening %s for write.\r\n",addfile); }
627: if(sysop) {
628: sprintf(str,"\1c\1hSCB: \1y%s \1n\1cwas validated \1h%.24s\1n\r\n"
629: ,user_name,ctime(&now));
630: putsmsg(sysop,str); }
631: }
632:
633: /******************************************************************************
634: Writes the log file.
635: ******************************************************************************/
636: void write_info()
637: {
638: char str[512];
639: int file;
640: time_t now;
641:
642: now=time(NULL);
643: if((file=nopen("SCB.LOG",O_WRONLY|O_APPEND|O_CREAT))!=-1) {
644: sprintf(str,
645: "Node %-3d : %.24s\r\n"
646: "User Name : %s\r\n"
647: "Voice Number : %s\r\n"
648: "Modem Number : %s\r\n"
649: "Result : %s\r\n\r\n"
650: ,node_num,ctime(&now),user_name,user_phone,phone_number,result);
651: write(file,str,strlen(str));
652: close(file); }
653: else
654: bprintf("\7\r\nError opening SCB.LOG for write.\r\n");
655: sprintf(str,"%sNODE.LOG",node_dir);
656: if(com_port && (file=nopen(str,O_WRONLY|O_APPEND|O_CREAT))!=-1) {
657: sprintf(str,"cb Result: %s %s\r\n",result,phone_number);
658: write(file,str,strlen(str));
659: close(file); }
660: if(options&MODIFY_USER_NOTE) {
661: sprintf(str,"%sUSER\\USER.DAT",data_dir);
662: if((file=nopen(str,O_WRONLY|O_DENYNONE))!=-1) {
663: lseek(file,(long)((((long)user_number-1L)*U_LEN)+U_NOTE),SEEK_SET);
664: memset(str,'\3',30);
665: sprintf(str,"%s %s",result,phone_number);
666: str[strlen(str)]=3;
667: write(file,str,30);
668: close(file); } }
669: }
670:
671: /******************************************************************************
672: Returns the users' password.
673: ******************************************************************************/
674: char *get_user_pw()
675: {
676: static char pw[9];
677: char str[256];
678: int file,x;
679:
680: sprintf(str,"%sUSER\\USER.DAT",data_dir);
681: if((file=nopen(str,O_RDONLY))==-1) {
682: printf("Unable to open %s.",str); exit(1); }
683: lseek(file,(long)((((long)user_number-1L)*U_LEN)+U_PASS),SEEK_SET);
684: read(file,pw,8);
685: for(x=0;x<8;x++)
686: if(pw[x]==3) break;
687: pw[x]=0;
688: close(file);
689: return(pw);
690: }
691:
692: /******************************************************************************
693: Checks the phone number entered. 0=Good, 1=Bad.
694: ******************************************************************************/
695: char check_phone(char *insearch)
696: {
697: char str[256],search[256],c,found=0,allowed=0,long_distance=0;
698: int file,day,t;
699: FILE *stream;
700: time_t now;
701: struct date date;
702: struct time curtime;
703: struct tm *tblock;
704:
705: if(strlen(insearch)<min_phone_len) {
706: printfile("TOOSHORT.MSG");
707: return(PHONE_INVALID); }
708: if(strlen(insearch)>max_phone_len) {
709: printfile("TOOLONG.MSG");
710: return(PHONE_INVALID); }
711:
712: strcpy(str,"ALLOWED.DAT");
713: if((file=nopen(str,O_RDONLY|O_TEXT))!=-1)
714: if((stream=fdopen(file,"rt"))!=NULL) {
715: strcpy(search,insearch);
716: strupr(search);
717: while(!feof(stream) && !ferror(stream)) {
718: if(!fgets(str,81,stream))
719: break;
720: truncsp(str);
721: c=strlen(str);
722: if(c && !strncmp(str,search,c)) {
723: allowed=1;
724: break; } }
725: fclose(stream); }
726:
727: if(!allowed) {
728:
729: if(options&ALLOWED_ONLY)
730: long_distance=1;
731: else {
732: strcpy(str,"LDPREFIX.DAT");
733: if((file=nopen(str,O_RDONLY|O_TEXT))!=-1)
734: if((stream=fdopen(file,"rt"))!=NULL) {
735: strcpy(search,insearch);
736: strupr(search);
737: while(!feof(stream) && !ferror(stream)) {
738: if(!fgets(str,81,stream))
739: break;
740: truncsp(str);
741: c=strlen(str);
742: if(c && !strncmp(str,search,c)) {
743: long_distance=1;
744: break; } }
745: fclose(stream); } }
746:
747: if(!(options&START_WITH_0) && insearch[0]=='0') {
748: printfile("NO_ZERO.MSG");
749: return(PHONE_LD); }
750: if(!(options&START_WITH_1) && insearch[0]=='1') {
751: printfile("NO_ONE.MSG");
752: return(PHONE_LD); }
753: if(!(options&SAME_AREA_LD) && insearch[0]!='0' && insearch[0]!='1'
754: && long_distance) {
755: printfile("NO_LD.MSG");
756: return(PHONE_LD); }
757: if((insearch[0]=='1' || insearch[0]=='0' || long_distance) &&
758: (ldstart[day] || ldend[day])) {
759: now=time(NULL);
760: tblock=localtime(&now);
761: day=tblock->tm_wday;
762: unixtodos(now,&date,&curtime);
763: t=(curtime.ti_hour*60)+curtime.ti_min;
764:
765: if((ldstart[day]<ldend[day]
766: && (t<ldstart[day] || t>ldend[day]))
767:
768: || (ldstart[day]>ldend[day]
769: && (t<ldstart[day] && t>ldend[day]))
770:
771: ) {
772:
773: bprintf("\7\r\n\1n\1gLong distance calls are only allowed between "
774: "\1h%02d:%02d \1n\1gand \1h%02d:%02d\1n\1g.\r\n"
775: ,ldstart[day]/60,ldstart[day]%60
776: ,ldend[day]/60,ldend[day]%60);
777: printfile("LD_TIME.MSG");
778: return(PHONE_LD); } } }
779:
780: strcpy(str,canfile);
781: if((file=nopen(str,O_RDONLY|O_TEXT))==-1) {
782: if(fexist(str))
783: printf("ERROR: Unable to open %s for read.",str);
784: return(PHONE_OKAY); }
785: if((stream=fdopen(file,"rt"))==NULL) {
786: printf("ERROR: Converting %s to a stream.",str);
787: return(PHONE_OKAY); }
788: strcpy(search,insearch);
789: strupr(search);
790: while(!feof(stream) && !ferror(stream) && !found) {
791: if(!fgets(str,81,stream))
792: break;
793: truncsp(str);
794: c=strlen(str);
795: if(c) {
796: c--;
797: strupr(str);
798: if(str[c]=='~') {
799: str[c]=0;
800: if(strstr(search,str))
801: found=1; }
802:
803: else if(str[c]=='^') {
804: str[c]=0;
805: if(!strncmp(str,search,c))
806: found=1; }
807:
808: else if(!strcmp(str,search))
809: found=1; } }
810: fclose(stream);
811: if(found) {
812: printfile("PHONECAN.MSG");
813: return(PHONE_INVALID); }
814: if(!allowed && options&STAY_CONNECTED && options&SC_LOCAL_ONLY &&
815: (insearch[0]=='1' || insearch[0]=='0'))
816: options&=~STAY_CONNECTED;
817: return(PHONE_OKAY);
818: }
819:
820: /****************************************************************************/
821: /* Outputs a single character to the COM port */
822: /****************************************************************************/
823: void putcomch(char ch)
824: {
825: char lch;
826: int i=0;
827:
828: if(!com_port)
829: return;
830: while(outcom(ch)&TXBOF && i<1440) { /* 3 minute pause delay */
831: if(lkbrd(1)) {
832: lch=lkbrd(0); /* ctrl-c */
833: if(lch==3) {
834: lputs("local abort (putcomch)\r\n");
835: i=1440;
836: break; }
837: ungetkey(lch); }
838: if(!(rioctl(IOSTATE)&DCD))
839: break;
840: i++;
841: mswait(80); }
842: if(i==1440) { /* timeout - beep flush outbuf */
843: i=rioctl(TXBC);
844: lprintf("timeout(putcomch) %04X %04X\r\n",i,rioctl(IOFO));
845: outcom(7);
846: lputc(7);
847: rioctl(IOCS|PAUSE); }
848: }
849:
850: /****************************************************************************/
851: /* Sends string of characters to COM port. Interprets ^M and ~ (pause) */
852: /* Called from functions waitforcall and offhook */
853: /****************************************************************************/
854: void mdmcmd(char *str)
855: {
856: int i=0;
857: uint lch;
858:
859: lputs("\r\nModem command : ");
860: while(str[i]) {
861: if(str[i]=='~')
862: mswait(500);
863: else {
864: if(i && str[i-1]=='^' && str[i]!='^') /* control character */
865: putcomch(toupper(str[i])-64);
866: else if(str[i]!='^' || (i && str[i-1]=='^'))
867: putcomch(str[i]);
868: lputc(str[i]); }
869: i++; }
870: putcomch(CR);
871: i=0;
872: while(rioctl(TXSYNC) && i<10) { /* wait for modem to receive all chars */
873: if(lkbrd(1)) {
874: lch=lkbrd(0); /* ctrl-c */
875: if(lch==0x2e03) {
876: lputs("local abort (mdmcmd)\r\n");
877: break; }
878: if(lch==0xff00)
879: bail(1);
880: ungetkey(lch); }
881: i++; }
882: if(i==10) {
883: i=rioctl(TXBC);
884: lprintf("\r\n\7timeout(mdmcmd) %04X %04X\r\n",i,rioctl(IOFO)); }
885: lputs(crlf);
886: }
887: /****************************************************************************/
888: /* Returns CR terminated string from the COM port. */
889: /* Called from function waitforcall */
890: /****************************************************************************/
891: char getmdmstr(char *str, int sec)
892: {
893: uchar j=0,ch;
894: uint lch;
895: time_t start;
896:
897: lputs("Modem response : ");
898: start=time(NULL);
899: while(time(NULL)-start<sec && j<81) {
900: if(lkbrd(1)) {
901: lch=lkbrd(0); /* ctrl-c */
902: if(lch==0x2e03) {
903: lputs("local abort (getmdmstr)\r\n");
904: break; }
905: if(lch==0xff00)
906: bail(1);
907: ungetkey(lch); }
908: if((ch=incom())==CR && j)
909: break;
910: if(ch && (ch<0x20 || ch>0x7f)) /* ignore control characters and ex-ascii */
911: continue;
912: if(ch) {
913: str[j++]=ch;
914: lputc(ch); }
915: else mswait(0); }
916: mswait(500);
917: str[j]=0;
918: lputs(crlf);
919: return(j);
920: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.