home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- WWIV Version 4
- Copyright (C) 1988 by Wayne Bell
-
- Distribution of the source code for WWIV, in any form, modified or unmodified,
- without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
- Distribution of compiled versions of WWIV is limited to copies compiled BY
- THE AUTHOR. Distribution of any copies of WWIV not compiled by the author
- is expressly prohibited.
-
-
- *****************************************************************************/
-
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <process.h>
- #include <dos.h>
- #include <math.h>
- #include <io.h>
- #include <fcntl.h>
- #include <dir.h>
-
- #include "vardec.h"
-
-
- void far *funcs[25];
- /****************************************************************************/
-
- void ansic(int n);
- unsigned char getkey();
- char inkey();
- void pausescr();
- void backspace();
- void nl();
- void outstr(char *s);
- void outchr(char c);
- void checkhangup();
- void outcomch(char ch);
- long timer1();
- void checka(int *abort, int *next);
- /****************************************************************************/
- char *xenviron[50],newprompt[161];
- char ver_no1[51];
-
-
- int topline=0,screenbottom=24,tempio,curatr=0x07,lines_listed=0,outcom=0;
- int hangup=0,hungup=0,echo=1,lecho=1,input_extern=0,ctc=0,ccc=0;
- int defscreenbottom=24;
-
- char charbuffer[161]="",endofline[81]="";
- int charbufferpointer=0;
- int ansiptr=0;
-
- int oldx,oldy,flow_control;
- char ansistr[81];
- int change_color;
- userrec thisuser;
-
- unsigned int baud_rate;
-
- long timelastchar1,hanguptime1;
-
- unsigned char andwith=255;
-
- char cdir[81];
-
-
- volatile int head,tail;
- volatile char buffer[max_buf];
- int base,async_irq,useron,in_extern,ok_modem_stuff;
- int outcom,incom,using_modem,chatting,screenlinest;
-
- /****************************************************************************/
-
-
- void my_video_int()
- {
- static unsigned short sav_bp;
-
- __emit__(0x56, 0x57); /* push si, push di */
- sav_bp = _BP;
- geninterrupt(0x10);
- _BP = sav_bp;
- __emit__(0x5f, 0x5e); /* pop di, pop si */
- }
-
-
- /****************************************************************************/
-
- int okansi()
- /* This function checks the status of the current user's record to see if
- * the user has specified that he wants ANSI graphics displayed.
- */
- {
- if (thisuser.sysstatus & sysstatus_ansi)
- return(1);
- else
- return(0);
- }
-
-
- void wait1(long l)
- {
- long l1;
-
- l1 = timer1()+l;
-
- enable();
- while (timer1()<l1)
- ;
- }
-
-
-
-
- #define frequency 500
-
- void setbeep(int i)
- {
- int i1,i2;
-
- if (i) {
- i1 = 0x34DD / frequency;
- i2 = inportb(0x61);
- if (!(i2 & 0x03)) {
- outportb(0x61, i2 | 0x03);
- outportb(0x43, 0xB6);
- }
- outportb(0x42, i1 & 0x0F);
- outportb(0x42, i1 >> 4);
- } else
- outportb(0x61, inportb(0x61) & 0xFC);
- }
-
- void pla(char *s, int *abort)
- {
- int i,next;
-
- i=0;
- checkhangup();
- if (hangup)
- *abort=1;
- checka(abort,&next);
- while ((s[i]) && (!(*abort))) {
- outchr(s[i++]);
- checka(abort,&next);
- }
- if (!(*abort))
- nl();
- }
-
-
- void checka(int *abort, int *next)
- {
- char ch;
-
- while ((!empty()) && (!(*abort)) && (!hangup)) {
- checkhangup();
- ch=inkey();
- switch(ch) {
- case 14:
- *next=1;
- case 3:
- case 32:
- case 24:
- *abort=1;
- break;
- case 'P':
- case 'p':
- case 19:
- ch=getkey();
- break;
- }
- }
- }
-
-
-
- void inli(char *s, char *rollover, int maxlen, int crend)
- {
- int cp,i,i1,done,cm,begx;
- char s1[255];
- unsigned char ch;
-
- cm=chatting;
-
- begx=wherex();
- if (rollover[0]!=0) {
- if (charbufferpointer) {
- strcpy(s1,rollover);
- strcat(s1,&charbuffer[charbufferpointer]);
- strcpy(&charbuffer[1],s1);
- charbufferpointer=1;
- } else {
- strcpy(&charbuffer[1],rollover);
- charbufferpointer=1;
- }
- rollover[0]=0;
- }
- cp=0;
- done=0;
- do {
- ch=getkey();
- if (cm)
- if (chatting==0)
- ch=13;
- if ((ch>=32)) {
- if ((wherex()<(thisuser.screenchars-1)) && (cp<maxlen)) {
- s[cp++]=ch;
- outchr(ch);
- if (wherex()==(thisuser.screenchars-1))
- done=1;
- } else {
- if (wherex()>=(thisuser.screenchars-1))
- done=1;
- }
- } else
- switch(ch) {
- case 7:
- if ((chatting) && (outcom))
- outcomch(7);
- break;
- case 13: /* C/R */
- s[cp]=0;
- done=1;
- break;
- case 8: /* Backspace */
- if (cp) {
- if (s[cp-2]==3) {
- cp-=2;
- ansic(0);
- } else
- if (s[cp-1]==8) {
- cp--;
- outchr(32);
- } else {
- cp--;
- backspace();
- }
- }
- break;
- case 24: /* Ctrl-X */
- while (wherex()>begx) {
- backspace();
- cp=0;
- }
- ansic(0);
- break;
- case 23: /* Ctrl-W */
- if (cp) {
- do {
- if (s[cp-2]==3) {
- cp-=2;
- ansic(0);
- } else
- if (s[cp-1]==8) {
- cp--;
- outchr(32);
- } else {
- cp--;
- backspace();
- }
- } while ((cp) && (s[cp-1]!=32) && (s[cp-1]!=8) && (s[cp-2]!=3));
- }
- break;
- case 14: /* Ctrl-N */
- if ((wherex()) && (cp<maxlen)) {
- outchr(8);
- s[cp++]=8;
- }
- break;
- case 16: /* Ctrl-P */
- if (cp<maxlen-1) {
- ch=getkey();
- if ((ch>='0') && (ch<='7')) {
- s[cp++]=3;
- s[cp++]=ch;
- ansic(ch-'0');
- }
- }
- break;
- case 9: /* Tab */
- i=5-(cp % 5);
- if (((cp+i)<maxlen) && ((wherex()+i)<thisuser.screenchars)) {
- i=5-((wherex()+1) % 5);
- for (i1=0; i1<i; i1++) {
- s[cp++]=32;
- outchr(32);
- }
- }
- break;
- }
- } while ((done==0) && (hangup==0));
- if (ch!=13) {
- i=cp-1;
- while ((i>0) && (s[i]!=32) && (s[i]!=8) || (s[i-1]==3))
- i--;
- if ((i>(wherex()/2)) && (i!=(cp-1))) {
- i1=cp-i-1;
- for (i=0; i<i1; i++)
- outchr(8);
- for (i=0; i<i1; i++)
- outchr(32);
- for (i=0; i<i1; i++)
- rollover[i]=s[cp-i1+i];
- rollover[i1]=0;
- cp -= i1;
- }
- s[cp++]=1;
- s[cp]=0;
- }
- if (crend)
- nl();
-
- }
-
-
-
-
- long timer1()
- /* This function returns the time, in seconds since midnight. */
- {
- unsigned short h,m;
- long l;
-
- m=peek(0x0040,0x006c);
- h=peek(0x0040,0x006e);
- l=((long)h)*65536 + ((long)m);
- return(l);
- }
-
- #define SCROLL_UP(t,b,l) \
- _CH=t;\
- _DH=b;\
- _BH=curatr;\
- _AL=l;\
- _CL=0;\
- _DL=79;\
- _AH=6;\
- my_video_int();
-
- void movecsr(int x,int y)
- /* This, obviously, moves the cursor to the location specified, offset from
- * the protected dispaly at the top of the screen
- */
- {
- if (x<0)
- x=0;
- if (x>79)
- x=79;
- if (y<0)
- y=0;
- y+=topline;
- if (y>screenbottom)
- y=screenbottom;
-
- _BH=0x00;
- _DH=y;
- _DL=x;
- _AH=0x02;
- my_video_int();
- }
-
-
-
- int wherex()
- /* This function returns the current X cursor position, as the number of
- * characters from the left hand side of the screen. An X position of zero
- * means the cursor is at the left-most position
- */
- {
- _BH=0x00;
- _AH=0x03;
- my_video_int();
- tempio=_DL;
- return(tempio);
- }
-
-
-
- int wherey()
- /* This function returns the Y cursor position, as the line number from
- * the top of the logical window. The offset due to the protected top
- * of the screen display is taken into account. A wherey() of zero means
- * the cursor is at the top-most position it can be at.
- */
- {
- _BH=0x00;
- _AH=0x03;
- my_video_int();
- tempio=_DH;
- return(tempio-topline);
- }
-
-
-
- void lf()
- /* This function performs a linefeed to the screen (but not remotely) by
- * either moving the cursor down one line, or scrolling the logical screen
- * up one line.
- */
- {
- _BH=0x00;
- _AH=0x03;
- my_video_int();
- tempio=_DL;
- if (_DH==screenbottom) {
- SCROLL_UP(topline,screenbottom,1);
- _DL=tempio;
- _DH=screenbottom;
- _BH=0;
- _AH=0x02;
- my_video_int();
- } else {
- tempio=_DH+1;
- _DH=tempio;
- _AH=0x02;
- my_video_int();
- }
- }
-
-
-
- void cr()
- /* This short function returns the local cursor to the left-most position
- * on the screen.
- */
- {
- _BH=0x00;
- _AH=0x03;
- my_video_int();
- _DL=0x00;
- _AH=2;
- my_video_int();
- }
-
- void clrscrb()
- /* This clears the local logical screen */
- {
- SCROLL_UP(topline,screenbottom,0);
- movecsr(0,0);
- lines_listed=0;
- }
-
-
-
- void bs()
- /* This function moves the cursor one position to the left, or if the cursor
- * is currently at its left-most position, the cursor is moved to the end of
- * the previous line, except if it is on the top line, in which case nothing
- * happens.
- */
- {
- _BH=0;
- _AH=3;
- my_video_int();
- if (_DL==0) {
- if (_DH != topline) {
- _DL=79;
- tempio=_DH-1;
- _DH=tempio;
- _AH=2;
- my_video_int();
- }
- } else {
- _DL--;
- _AH=2;
- my_video_int();
- }
- }
-
-
-
- void out1chx(unsigned char ch)
- /* This function outputs one character to the screen, then updates the
- * cursor position accordingly, scolling the screen if necessary. Not that
- * this function performs no commands such as a C/R or L/F. If a value of
- * 8, 7, 13, 10, 12 (backspace, beep, C/R, L/F, TOF), or any other command-
- * type characters are passed, the appropriate corresponding "graphics"
- * symbol will be output to the screen as a normal character.
- */
- {
- _BL=curatr;
- _BH=0x00;
- _CX=0x01;
- _AL=ch;
- _AH=0x09;
- my_video_int();
- _BH=0x00;
- _AH=0x03;
- my_video_int();
- ++_DL;
- if (_DL==80) {
- _DL=0;
- if (_DH==screenbottom) {
- SCROLL_UP(topline,screenbottom,1);
- _DH=screenbottom;
- _DL=0;
- _BH=0;
- _AH=0x02;
- my_video_int();
- } else {
- tempio=_DH+1;
- _DH=tempio;
- _AH=0x02;
- my_video_int();
- }
- } else {
- _AH=0x02;
- my_video_int();
- }
- }
-
-
-
-
- void out1ch(unsigned char ch)
- /* This function outputs one character to the local screen. C/R, L/F, TOF,
- * BS, and BELL are interpreted as commands instead of characters.
- */
- {
- if (ch>31)
- out1chx(ch);
- else
- if (ch==13)
- cr();
- else
- if (ch==10)
- lf();
- else
- if (ch==12)
- clrscrb();
- else
- if (ch==8)
- bs();
- else
- if (ch==7)
- if (outcom==0) {
- setbeep(1);
- wait1(4);
- setbeep(0);
- }
- }
-
-
-
- /****************************************************************************/
- void far interrupt async_isr ()
- /* This function is called every time a char is received on the com port.
- * The character is stored in the buffer[] array, and the head pointer is
- * updated.
- */
- {
- buffer[head++] = inportb(base);
- if (head == max_buf)
- head = 0;
- outportb(0x20, 0x20);
- }
-
-
-
- void outcomch(char ch)
- /* This function outputs one character to the com port */
- {
- while (!(inportb(base + 5) & 0x20))
- ;
- if (flow_control)
- while (!(inportb(base + 6) & 0x10))
- ;
- outportb(base, ch);
- }
-
-
-
-
- char get1c()
- /* This function returns one character from the com port, or a zero if
- * no character is waiting
- */
- {
- char c1;
-
- if (head != tail) {
- disable();
- c1 = buffer[tail++];
- if (tail == max_buf)
- tail = 0;
- enable();
- return(c1);
- } else
- return(0);
- }
-
-
-
- int comhit()
- /* This returns a value telling if there is a character waiting in the com
- * buffer.
- */
- {
- return(head != tail);
- }
-
-
-
- void dump()
- /* This function clears the com buffer */
- {
- disable();
- head = tail = 0;
- enable();
- }
-
-
-
- void set_baud(unsigned int rate)
- /* This function sets the com speed to that passed */
- {
- float rl;
-
- if ((rate > 49) && (rate < 57601)) {
- rl = 115200.0 / ((float) rate);
- rate = (int) rl;
- outportb(base + 3, inportb(base + 3) | 0x80);
- outportb(base, (rate & 0x00FF));
- outportb(base + 1, ((rate >> 8) & 0x00FF));
- outportb(base + 3, inportb(base + 3) & 0x7F);
- }
- }
-
-
- void initport(int portnum)
- /* This function initializes the com buffer, setting up the interrupt,
- * and com parameters
- */
- {
- int temp;
-
- temp=portnum;
-
- setvect(8 + async_irq, async_isr);
- head = tail = 0;
- outportb(base + 3, 0x03);
- disable();
- temp = inportb(base + 5);
- temp = inportb(base);
- temp = inportb(0x21);
- temp = temp & ((1 << async_irq) ^ 0x00FF);
- outportb(0x21, temp);
- outportb(base + 1, 0x01);
- temp=inportb(base + 4);
- outportb(base + 4, temp | 0x0B);
- enable();
- set_baud(baud_rate);
- }
-
-
-
- void closeport()
- /* This function closes out the com port, removing the interrupt routine,
- * etc.
- */
- {
- int temp;
-
- disable();
- temp = inportb(0x21);
- temp = temp | ((1 << async_irq));
- outportb(0x21, temp | 0x10);
- outportb(base + 2, 0);
- outportb(base + 4, 1);
- enable();
- }
-
-
- int cdet()
- /* This returns the status of the carrier detect lead from the modem */
- {
- return((inportb(base + 6) & 0x80) ? 1 : 0);
- }
-
-
-
- void checkhangup()
- /* This function checks to see if the user logged on to the com port has
- * hung up. Obviously, if no user is logged on remotely, this does nothing.
- * If carrier detect is detected to be low, it is checked 100 times
- * sequentially to make sure it stays down, and is not just a quirk.
- */
- {
- int i, ok;
-
- if (!hangup && using_modem && !cdet()) {
- ok = 0;
- for (i = 0; (i < 500) && !ok; i++)
- if (cdet())
- ok = 1;
- if (!ok) {
- hangup = hungup = 1;
- }
- }
- }
-
-
-
-
- void addto(char *s, int i)
- {
- char temp[20];
-
- if (s[0])
- strcat(s, ";");
- else
- strcpy(s, "\x1B[");
- itoa(i, temp, 10);
- strcat(s, temp);
- }
-
-
-
- void makeansi(unsigned char attr, char *s)
- /* Passed to this function is a one-byte attribute as defined for IBM type
- * screens. Returned is a string which, when printed, will change the
- * display to the color desired, from the current function.
- */
- {
- unsigned char catr;
- char *temp = "04261537";
-
- catr = curatr;
- s[0] = 0;
- if (attr != catr) {
- if ((catr & 0x88) ^ (attr & 0x88)) {
- addto(s, 0);
- addto(s, 30 + temp[attr & 0x07] - '0');
- addto(s, 40 + temp[(attr & 0x70) >> 4] - '0');
- catr = attr & 0x77;
- }
- if ((catr & 0x07) != (attr & 0x07))
- addto(s, 30 + temp[attr & 0x07] - '0');
- if ((catr & 0x70) != (attr & 0x70))
- addto(s, 40 + temp[(attr & 0x70) >> 4] - '0');
- if ((catr & 0x08) ^ (attr & 0x08))
- addto(s, 1);
- if ((catr & 0x80) ^ (attr & 0x80))
- addto(s, 5);
- }
- if (s[0])
- strcat(s, "m");
- if (!okansi())
- s[0]=0;
- }
-
-
-
- void setfgc(int i)
- /* This sets the foreground color to that passed. It is called only from
- * execute_ansi
- */
- {
- curatr = (curatr & 0xf8) | i;
- }
-
-
-
- void setbgc(int i)
- /* This sets the background color to that passed. It is called only from
- * execute_ansi
- */
- {
- curatr = (curatr & 0x8f) | (i << 4);
- }
-
-
- void execute_ansi()
- /* This function executes an ANSI string to change color, position the
- * cursor, etc.
- */
- {
- int args[10], argptr, count, ptr, tempptr, ox, oy;
- char cmd, temp[10], teol[81], *clrlst = "04261537";
-
- if (ansistr[1] != '[') {
-
- /* do nothing if invalid ANSI string. */
-
- } else {
- argptr = tempptr = 0;
- ptr = 2;
- for (count = 0; count < 10; count++)
- args[count] = temp[count] = 0;
- cmd = ansistr[ansiptr - 1];
- ansistr[ansiptr - 1] = 0;
- while (ansistr[ptr]) {
- if (ansistr[ptr] == ';') {
- temp[tempptr] = 0;
- tempptr = 0;
- args[argptr++] = atoi(temp);
- } else
- temp[tempptr++] = ansistr[ptr];
- ++ptr;
- }
- if (tempptr) {
- temp[tempptr] = 0;
- args[argptr++] = atoi(temp);
- }
- if ((cmd >= 'A') && (cmd <= 'D') && !args[0])
- args[0] = 1;
- switch (cmd) {
- case 'f':
- case 'H':
- movecsr(args[1] - 1, args[0] - 1);
- break;
- case 'A':
- movecsr(wherex(), wherey() - args[0]);
- break;
- case 'B':
- movecsr(wherex(), wherey() + args[0]);
- break;
- case 'C':
- movecsr(wherex() + args[0], wherey());
- break;
- case 'D':
- movecsr(wherex() - args[0], wherey());
- break;
- case 's':
- oldx = wherex();
- oldy = wherey();
- break;
- case 'u':
- movecsr(oldx, oldy);
- break;
- case 'J':
- if (args[0] == 2)
- clrscrb();
- break;
- case 'k':
- case 'K':
- ox = wherex();
- oy = wherey();
- _CX = 80 - ox;
- _AH = 0x09;
- _BH = 0x00;
- _AL = 32;
- _BL = curatr;
- my_video_int();
- movecsr(ox, oy);
- break;
- case 'm':
- if (!argptr) {
- argptr = 1;
- args[0] = 0;
- }
- for (count = 0; count < argptr; count++)
- switch (args[count]) {
- case 0: curatr = 0x07; break;
- case 1: curatr = curatr | 0x08; break;
- case 4: break;
- case 5: curatr = curatr | 0x80; break;
- case 7:
- ptr = curatr & 0x77;
- curatr = (curatr & 0x88) | (ptr << 4) | (ptr >> 4);
- break;
- case 8: curatr = 0; break;
- default:
- if ((args[count] >= 30) && (args[count] <= 37))
- setfgc(clrlst[args[count] - 30] - '0');
- else if ((args[count] >= 40) && (args[count] <= 47))
- setbgc(clrlst[args[count] - 40] - '0');
- }
- break;
- }
- }
- ansiptr = 0;
- }
-
-
-
- void outchr(char c)
- /* This function outputs one character to the screen, and if output to the
- * com port is enabled, the character is output there too. ANSI graphics
- * are also trapped here, and the ansi function is called to execute the
- * ANSI codes
- */
- {
- int i, i1;
-
- if (change_color) {
- change_color = 0;
- if ((c >= '0') && (c <= '7'))
- ansic(c - '0');
- return;
- }
- if (c == 3) {
- change_color = 1;
- return;
- }
- if ((c == 10) && endofline[0]) {
- if (!in_extern)
- outstr(endofline);
- endofline[0] = 0;
- }
- if (outcom && (c != 9))
- outcomch(echo ? c : 'X');
- if (ansiptr) {
- ansistr[ansiptr++] = c;
- ansistr[ansiptr] = 0;
- if (((c > '@') && (c != '[')) || (ansistr[1] != '['))
- execute_ansi();
- } else if (c == 27) {
- ansistr[0] = 27;
- ansiptr = 1;
- } else if (c == 9) {
- i1 = wherex();
- for (i = i1; i< (((i1 / 8) + 1) * 8); i++)
- outchr(32);
- } else if (echo || lecho) {
- out1ch(c);
- if (c == 10) {
- ++lines_listed;
- if ((sysstatus_pause_on_page & thisuser.sysstatus) &&
- (lines_listed >= screenlinest - 1)) {
- pausescr();
- lines_listed = 0;
- }
- }
- } else
- out1ch('X');
- }
-
-
-
- void outstr(char *s)
- /* This function outputs a string of characters to the screen (and remotely
- * if applicable). The com port is also checked first to see if a remote
- * user has hung up
- */
- {
- int i=0;
-
- checkhangup();
- if (!hangup)
- while (s[i])
- outchr(s[i++]);
- }
-
-
-
- void nl()
- /* This function performs a CR/LF sequence to move the cursor to the next
- * line. If any end-of-line ANSI codes are set (such as changing back to
- * the default color) are specified, those are executed first.
- */
- {
- if (endofline[0]) {
- outstr(endofline);
- endofline[0] = 0;
- }
- outstr("\r\n");
- }
-
-
-
- void backspace()
- /* This function executes a backspace, space, backspace sequence. */
- {
- int i;
-
- i = echo;
- echo = 1;
- outstr("\b \b");
- echo = i;
- }
-
-
-
- void setc(unsigned char ch)
- /* This sets the current color (both locally and remotely) to that
- * specified (in IBM format).
- */
- {
- char s[30];
-
- makeansi(ch, s);
- outstr(s);
- }
-
-
-
- void pausescr()
- /* This will pause output, displaying the [PAUSE] message, and wait for
- * a key to be hit.
- */
- {
- int i;
-
- if (okansi()) {
- i = curatr;
- setc((thisuser.sysstatus & sysstatus_color) ? thisuser.colors[3] :
- thisuser.bwcolors[3]);
- outstr("[PAUSE]\x1b[7D");
- setc(i);
- getkey();
- outstr(" \x1b[7D");
- } else {
- outstr("[PAUSE]");
- getkey();
- for (i = 0; i < 7; i++)
- backspace();
- }
- }
-
-
-
- void pl(char *s)
- {
- outstr(s);
- nl();
- }
-
-
- int kbhitb()
- {
- union REGS r;
-
- r.h.ah = 1;
- int86(0x16, &r, &r);
- return((r.x.flags & 64) == 0);
- }
-
-
- int empty()
- {
- if (kbhitb() || (incom && (head != tail)) ||
- (charbufferpointer && charbuffer[charbufferpointer]) ||
- (in_extern == 2))
- return(0);
- return(1);
- }
-
-
-
- void skey1(char *ch)
- {
- char c;
-
- c = *ch;
- if (c == 127)
- c = 8;
- switch(c) {
- case 1:
- case 4:
- case 6:
- if (!charbufferpointer) {
- if (c == 1)
- c = 2;
- else if (c == 4)
- c = 0;
- else if (c == 6)
- c = 1;
- strcpy(charbuffer, &(thisuser.macros[c][0]));
- c = charbuffer[0];
- if (c)
- charbufferpointer = 1;
- }
- break;
- }
- *ch = c;
- }
-
- char getchd()
- {
- union REGS r;
-
- r.h.ah = 0x07;
- int86(0x69, &r, &r);
- return(r.h.al);
- }
-
-
- char getchd1()
- {
- union REGS r;
-
- r.h.ah = 0x06;
- r.h.dl = 0xFF;
- int86(0x69, &r, &r);
- return((r.x.flags & 0x40) ? 255 : r.h.al);
- }
-
-
- char inkey()
- /* This function checks both the local keyboard, and the remote terminal
- * (if any) for input. If there is input, the key is returned. If there
- * is no input, a zero is returned. Function keys hit are interpreted as
- * such within the routine and not returned.
- */
- {
- char ch=0;
-
- if (charbufferpointer) {
- if (!charbuffer[charbufferpointer])
- charbufferpointer = charbuffer[0] = 0;
- else
- return(charbuffer[charbufferpointer++]);
- }
- if (kbhitb() || (in_extern == 2)) {
- ch = getchd1();
- if (!ch) {
- if (in_extern)
- in_extern = 2;
- else {
- ch = getchd1();
- ch=0;
- }
- } else if (in_extern)
- in_extern = 1;
- timelastchar1=timer1();
- } else if (incom && comhit()) {
- ch = (get1c() & andwith);
- }
- skey1(&ch);
- return(ch);
- }
-
-
-
- void mpl(int i)
- /* This will make a reverse-video prompt line i characters long, repositioning
- * the cursor at the beginning of the input prompt area. Of course, if the
- * user does not want ansi, this routine does nothing.
- */
- {
- int i1;
- char s[81];
-
- if (okansi()) {
- ansic(4);
- for (i1 = 0; i1 < i; i1++)
- outchr(' ');
- outstr("\x1b[");
- itoa(i,s,10);
- outstr(s);
- outstr("D");
- }
- }
-
-
-
- char upcase(char ch)
- /* This converts a character to uppercase */
- {
- if ((ch > '`') && (ch < '{'))
- ch = ch - 32;
- return(ch);
- }
-
-
- unsigned char getkey()
- /* This function returns one character from either the local keyboard or
- * remote com port (if applicable). After 1.5 minutes of inactivity, a
- * beep is sounded. After 3 minutes of inactivity, the user is hung up.
- */
- {
- unsigned char ch;
- int beepyet;
- long dd;
-
- beepyet = 0;
- timelastchar1=timer1();
-
- lines_listed = 0;
- do {
- while (empty() && !hangup) {
- dd = timer1();
- if (labs(dd - timelastchar1) > 65536L)
- timelastchar1 -= 1572480L;
- if (((dd - timelastchar1) > 1638L) && (!beepyet)) {
- beepyet = 1;
- outchr(7);
- }
- if (labs(dd - timelastchar1) > 3276L) {
- nl();
- outstr("Call back later when you are there.");
- nl();
- hangup = 1;
- }
- checkhangup();
- }
- ch = inkey();
- } while (!ch && !in_extern && !hangup);
- return(ch);
- }
-
-
-
- void input1(char *s, int maxlen, int lc, int crend)
- /* This will input a line of data, maximum maxlen characters long, terminated
- * by a C/R. if (lc) is non-zero, lowercase is allowed, otherwise all
- * characters are converted to uppercase.
- */
- {
- int curpos=0, done=0;
- unsigned char ch;
-
- while (!done && !hangup) {
- ch = getkey();
- if (ch > 31) {
- if (curpos < maxlen) {
- if (!lc)
- ch = upcase(ch);
- s[curpos++] = ch;
- outchr(ch);
- }
- } else
- switch(ch) {
- case 14:
- case 13:
- s[curpos] = 0;
- done = echo = 1;
- if (crend)
- nl();
- break;
- case 26:
- if (input_extern) {
- s[curpos++] = 26;
- outstr("^Z");
- }
- break;
- case 8:
- if (curpos) {
- curpos--;
- backspace();
- if (s[curpos] == 26)
- backspace();
- }
- break;
- case 24:
- while (curpos) {
- curpos--;
- backspace();
- if (s[curpos] == 26)
- backspace();
- }
- break;
- }
- }
- if (hangup)
- s[0] = 0;
- }
-
-
-
- void input(char *s, int len)
- /* This will input an upper-case string */
- {
- input1(s, len, 0, 1);
- }
-
-
-
- void inputl(char *s, int len)
- /* This will input an upper or lowercase string of characters */
- {
- input1(s, len, 1, 1);
- }
-
-
-
- int yn()
- /* The keyboard is checked for either a Y, N, or C/R to be hit. C/R is
- * assumed to be the same as a N. Yes or No is output, and yn is set to
- * zero if No was returned, and yn() is non-zero if Y was hit.
- */
- {
- char ch=0;
-
- ansic(1);
- while (!hangup && ((ch = upcase(getkey())) != 'Y') && (ch != 'N') && (ch != 13))
- ;
- outstr((ch == 'Y') ? "Yes" : "No");
- nl();
- return(ch == 'Y');
- }
-
-
-
- int ny()
- /* This is the same as yn(), except C/R is assumed to be "Y" */
- {
- char ch=0;
-
- ansic(1);
- while (!hangup && ((ch = upcase(getkey())) != 'Y') && (ch != 'N') && (ch != 13))
- ;
- outstr((ch == 'N') ? "No" : "Yes");
- nl();
- return((ch == 'Y') || (ch==13));
- }
-
-
- void ansic(int n)
- {
- char s[81], c;
-
- c = ((thisuser.sysstatus & sysstatus_color) ? thisuser.colors[n] :
- thisuser.bwcolors[n]);
- if (c == curatr)
- return;
- makeansi(c, s);
- outstr(s);
- makeansi((thisuser.sysstatus & sysstatus_color) ? thisuser.colors[0] :
- thisuser.bwcolors[0],endofline);
- }
-
-
- char onek(char *s)
- {
- char ch;
-
- while (!strchr(s, ch = upcase(getkey())) && !hangup)
- ;
- if (hangup)
- ch = s[0];
- outchr(ch);
- nl();
- return(ch);
- }
-
-
- void prt(int i, char *s)
- {
- ansic(i);
- outstr(s);
- ansic(0);
- }
-
- /****************************************************************************/
- #pragma warn -par
-
- void far interrupt inlii(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1, char *s2, int i1, int i2)
- {
- inli(s1,s2,i1,i2);
- }
-
- void far interrupt checkai(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- int *i1, int *i2)
- {
- checka(i1,i2);
- }
-
-
- void far interrupt plai(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1, int *i1)
- {
- pla(s1,i1);
- }
-
-
- void far interrupt outchri(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char ch)
- {
- outchr(ch);
- }
-
-
- void far interrupt outstri(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1)
- {
- outstr(s1);
- }
-
-
- void far interrupt nli(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- nl();
- }
-
-
- void far interrupt pli(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1)
- {
- pl(s1);
- }
-
-
- void far interrupt emptyi(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- ax=empty();
- }
-
-
- void far interrupt inkeyi(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- ax=(unsigned) empty();
- }
-
-
- void far interrupt getkeyi(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- ax=(unsigned) getkey();
- }
-
-
- void far interrupt inputi(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1, int i)
- {
- input(s1,i);
- }
-
-
- void far interrupt inputli(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1, int i)
- {
- inputl(s1,i);
- }
-
-
- void far interrupt yni(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- ax=yn();
- }
-
-
-
- void far interrupt nyi(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- ax=ny();
- }
-
-
- void far interrupt ansici(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- int i1)
- {
- ansic(i1);
- }
-
-
- void far interrupt oneki(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- char *s1)
- {
- ax=(unsigned) onek(s1);
- }
-
-
- void far interrupt prti(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- int i1, char *s1)
- {
- prt(i1,s1);
- }
-
-
-
- void far interrupt mpli(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags,
- int i1)
- {
- mpl(i1);
- }
-
-
- #pragma warn +par
-
- /****************************************************************************/
-
- unsigned char getkeyext()
- {
- unsigned char ch;
- static int holding=0;
- static char held=0;
-
- if (holding) {
- holding=0;
- return(held);
- }
- ch=getkey();
- if (charbufferpointer==0) {
- if (ch==16) {
- ch=getkey();
- if ((ch==1) && (charbufferpointer==0)) {
- strcpy(charbuffer,&(thisuser.macros[2][0]));
- ch=charbuffer[0];
- if (ch) {
- charbufferpointer=1;
- return(ch);
- } else
- return(getkeyext());
- } else
- if ((ch==4) && (charbufferpointer==0)) {
- strcpy(charbuffer,&(thisuser.macros[0][0]));
- ch=charbuffer[0];
- if (ch) {
- charbufferpointer=1;
- return(ch);
- } else
- return(getkeyext());
- } else
- if ((ch==6) && (charbufferpointer==0)) {
- strcpy(charbuffer,&(thisuser.macros[1][0]));
- ch=charbuffer[0];
- if (ch) {
- charbufferpointer=1;
- return(ch);
- } else
- return(getkeyext());
- } else {
- holding=1;
- held=ch;
- return(16);
- }
- }
- }
- return(ch);
- }
-
-
- int do_it(char *cl)
- {
- int i,i1,l;
- char s[160];
- char *ss[30];
-
- strcpy(s,cl);
- ss[0]=s;
- i=1;
- l=strlen(s);
- for (i1=1; i1<l; i1++)
- if (s[i1]==32) {
- s[i1]=0;
- ss[i++]=&(s[i1+1]);
- }
- ss[i]=NULL;
- i=(spawnvpe(P_WAIT,ss[0],ss,xenviron) & 0x00ff);
- /* spawnvp(P_WAIT,ss[0],ss); */
- return(i);
- }
-
-
-
- int do_remote(char *s, int ccc)
- {
- int rc,xx;
- char x[161];
-
- checkhangup();
- if (hangup)
- return(32767);
- strcpy(x,getenv("COMSPEC"));
- strcat(x," /C ");
- strcat(x,s);
- if (ccc)
- rc=do_it(x);
- else
- rc=do_it(s);
- chdir(cdir);
- setdisk(cdir[0]-'A');
- return(rc);
- }
-
-
- void checka2()
- {
- union REGS r;
- int pause,ctrl_c;
- long d1;
-
- pause=0;
- ctrl_c=0;
- r.h.ah=1;
- int86(0x16,&r,&r);
- if ((r.x.flags & 64)==0) {
- if (r.x.ax==11779)
- ctrl_c=1;
- if (r.x.ax==7955)
- pause=1;
- }
- if (head!=tail) {
- if (buffer[tail]==3)
- ctrl_c=1;
- if (buffer[tail]==19)
- pause=1;
- }
- if (pause) {
- while (inkey()!=0)
- ;
- d1=timer1();
- while ((inkey()==0) && (labs(timer1()-d1)<3276L) && (!hangup))
- checkhangup();
- lines_listed=0;
- }
- if ((ctrl_c) && (ctc)) {
- while (inkey()!=0)
- ;
- pl("^C");
- r.x.ax=0x4c00;
- int86(0x69,&r,&r);
- }
- }
-
-
-
- void outdosstr(char *s)
- /* This function outputs a string of characters to the screen (and remotely
- * if applicable). The com port is also checked first to see if a remote
- * user has hung up
- */
- {
- int i;
-
- checkhangup();
- if (hangup==0) {
- i=0;
- while ((s[i] !='$') && (i<1024)) {
- checka2();
- outchr(s[i++]);
- }
- }
- }
-
-
-
- #pragma warn -par
-
- void far interrupt newintr1(unsigned bp, unsigned di, unsigned si,
- unsigned ds, unsigned es, unsigned dx,
- unsigned cx, unsigned bx, unsigned ax,
- unsigned ip, unsigned cs, unsigned flags)
- {
- union REGS r;
- struct SREGS s;
- unsigned n;
- char ch,ch1,ss[10],ch2;
- unsigned char *st;
-
- r.x.ax=ax;
- r.x.bx=bx;
- r.x.cx=cx;
- r.x.dx=dx;
- r.x.si=si;
- r.x.di=di;
- r.x.flags=flags;
- s.ds=ds;
- s.es=es;
-
- ch=r.h.ah;
- ch1=0;
-
- if (ch==0x01) {
- ch=getkeyext();
- outchr(ch);
- if (hangup)
- ch=3;
- r.h.al=ch;
- ch1=1;
- } else
- if (ch==0x02) {
- outchr(r.h.dl);
- ch1=1;
- checka2();
- } else
- if (ch==0x06) {
- if (r.h.dl!=0xff) {
- outchr(r.h.dl);
- ch1=1;
- } else {
- if (empty()) {
- r.x.flags |= 64;
- } else {
- r.x.flags &= (0xffff ^ 64);
- r.h.al=getkeyext();
- }
- }
- } else
- if (ch==0x07) {
- ch1=1;
- r.h.al=getkeyext();
- } else
- if (ch==0x08) {
- ch1=1;
- r.h.al=getkeyext();
- } else
- if (ch==0x09) {
- outdosstr((char *) MK_FP(s.ds,r.x.dx));
- ch1=1;
- } else
- if (ch==0x0a) {
- st=(char *) MK_FP(s.ds,r.x.dx);
- n=(unsigned int)(st[0]);
- if (n<0)
- n=127;
- if (in_extern==2)
- getkeyext();
- in_extern=0;
- input_extern=1;
- input1(&(st[2]),n-2,1,0);
- input_extern=0;
- in_extern=1;
- st[1]=strlen(&(st[2]));
- strcat(&(st[2]),"\r");
- if ((hangup)) {
- strcpy(&(st[2]),"EXIT\r");
- st[1]=4;
- }
- ch1=1;
- } else
- if (ch==0x0b) {
- if (empty())
- r.h.al=0x00;
- else
- r.h.al=0xff;
- ch1=1;
- } else
- if (ch==0x0c) {
- r.h.ah=r.h.al;
- int86x(0x21,&r,&r,&s);
- ch1=1;
- } else
- if (ch==0x3f) {
- if (r.x.bx==0x0000) {
- st=(char *)MK_FP(s.ds,r.x.dx);
- inputl(st,r.x.cx);
- strcat(st,"\r\n");
- r.x.ax=strlen(st);
- if (hangup)
- r.x.ax=0;
- r.x.flags &=(0xffff ^ 1);
- ch1=1;
- } else
- int86x(0x69,&r,&r,&s);
- } else
- if (ch==0x40) {
- if ((r.x.bx==0x0001) || (r.x.bx==0x0002)) {
- st=(char *)MK_FP(s.ds,r.x.dx);
- for (n=0; n<r.x.cx; n++) {
- outchr(st[n]);
- checka2();
- }
- r.x.ax=r.x.cx;
- r.x.flags &=(0xffff ^ 1);
- ch1=1;
- } else
- int86x(0x69,&r,&r,&s);
- } else
- int86x(0x69,&r,&r,&s);
-
- ax=r.x.ax;
- bx=r.x.bx;
- cx=r.x.cx;
- dx=r.x.dx;
- si=r.x.si;
- di=r.x.di;
- flags=r.x.flags;
- ds=s.ds;
- es=s.es;
- if (ch1) {
- checkhangup();
- if (hangup) {
- if (hanguptime1<0L) {
- hanguptime1=timer1();
- r.x.ax=0x4c00;
- int86x(0x69,&r,&r,&s);
- } else {
- if (labs(timer1()-hanguptime1)>36L) {
- hanguptime1=timer1();
- r.x.ax=0x4c00;
- int86x(0x69,&r,&r,&s);
- }
- }
- }
- }
- }
-
-
- #pragma warn +par
-
-
- int full_external(char *s, int ccc)
- {
- unsigned short sav;
- int xx,cy,cx,xxx;
-
- checkhangup();
- if (hangup)
- return(0);
- in_extern=1;
- hanguptime1=-1L;
- setvect(0x69,getvect(0x21));
-
- setvect(0x21,newintr1);
-
- if ((screenlinest<=defscreenbottom) && (screenlinest>20)) {
- screenbottom=screenlinest-1;
- cy=wherey();
- cx=wherex();
- xxx=cy-screenbottom+topline;
- if (xxx>0) {
- SCROLL_UP(topline,defscreenbottom,xxx);
- movecsr(cx,screenbottom);
- }
- }
-
- do_remote(s,ccc);
-
- setvect(0x21,getvect(0x69));
-
- if (in_extern==2)
- getkey();
- in_extern=0;
- return(0);
- }
-
-
- /****************************************************************************/
-
- #define READ(x) read(i,&(x),sizeof(x))
-
- int init_r()
- {
- int i;
-
- for (i=0; i<25; i++)
- funcs[i]=NULL;
- funcs[0]=(void far *)inlii;
- funcs[1]=(void far *)checkai;
- funcs[2]=(void far *)plai;
- funcs[3]=(void far *)outchri;
- funcs[4]=(void far *)outstri;
- funcs[5]=(void far *)nli;
- funcs[8]=(void far *)pli;
- funcs[9]=(void far *)emptyi;
- funcs[10]=(void far *)inkeyi;
- funcs[11]=(void far *)getkeyi;
- funcs[12]=(void far *)inputi;
- funcs[13]=(void far *)inputli;
- funcs[14]=(void far *)yni;
- funcs[15]=(void far *)nyi;
- funcs[16]=(void far *)ansici;
- funcs[17]=(void far *)oneki;
- funcs[18]=(void far *)prti;
- funcs[19]=(void far *)mpli;
- setvect(0x6a,(void far interrupt (*) (void))funcs);
-
- i=open("stat.wwv",O_RDONLY | O_BINARY);
- if (i<0)
- return(1);
-
- READ(incom);
- READ(outcom);
- using_modem=incom || outcom;
- READ(thisuser);
- READ(flow_control);
- READ(async_irq);
- READ(baud_rate);
- READ(base);
- READ(andwith);
- READ(ctc);
- READ(defscreenbottom);
- READ(ok_modem_stuff);
-
- close(i);
-
- if (ok_modem_stuff)
- initport(0);
- return(0);
- }
-
- void get_dir(char *s, int be)
- {
- strcpy(s,"X:\\");
- s[0]='A'+getdisk();
- getcurdir(0,&(s[3]));
- if (be) {
- if (s[strlen(s)-1]!='\\')
- strcat(s,"\\");
- }
- }
-
-
- void cd_to(char *s)
- {
- char s1[81];
- int i,db;
-
- strcpy(s1,s);
- i=strlen(s1)-1;
- db=(s1[i]=='\\');
- if (i==0)
- db=0;
- if ((i==2) && (s1[1]==':'))
- db=0;
- if (db)
- s1[i]=0;
- chdir(s1);
- if (s[1]==':')
- setdisk(s[0]-'A');
- }
-
- void setup_stuff()
- {
- char s[161];
- int i;
-
- strcpy(ver_no1,"BBS=");
- strcat(ver_no1,VERSION_NUMBER);
-
-
- strcpy(s,getenv("PROMPT"));
- strcpy(newprompt,"PROMPT=WWIV: ");
- if (s[0])
- strcat(newprompt,s);
- else
- strcat(newprompt,"$P$G");
- i=0;
- while (environ[i]!=NULL) {
- if (strncmp(environ[i],"PROMPT=",7)==0)
- xenviron[i]=newprompt;
- else
- xenviron[i]=environ[i];
- ++i;
- }
- if (s[0]==0)
- xenviron[i++]=newprompt;
- xenviron[i++]=ver_no1;
- xenviron[i]=NULL;
- }
-
- /****************************************************************************/
- void do_it_1(char *cl)
- {
- char *ss1;
-
- ss1=(char far *)getvect(0x6b);
- *ss1=1;
- ss1++;
- strcpy(ss1,searchpath(cl));
- ss1=MK_FP(FP_SEG(ss1),0x0080);
- *ss1=0;
- ++ss1;
- *ss1=0x0d;
- exit(0);
- }
-
- /****************************************************************************/
-
-
- void main(int argc, char *argv[])
- {
- int i,i1;
- char s[130];
-
-
- i=atoi(argv[1]);
- ccc=atoi(argv[2]);
-
-
- get_dir(cdir,0);
-
- setup_stuff();
- if (argc>=3) {
- s[0]=0;
- for (i1=3; i1<argc; i1++) {
- strcat(s,argv[i1]);
- strcat(s," ");
- }
- if (i) {
- if (!init_r()) {
- if (incom || outcom)
- screenbottom=thisuser.screenlines-1;
- else
- screenbottom=defscreenbottom;
- screenlinest=screenbottom+1;
- full_external(s,ccc);
- pl("Returning...");
- if (ok_modem_stuff)
- closeport();
- setvect(0x6a,NULL);
- } else
- pl("Couldn't find data");
- } else
- do_remote(s,ccc);
- }
- cd_to(cdir);
- do_it_1("BBS.EXE");
- }
-
-