home *** CD-ROM | disk | FTP | other *** search
- /*
- * AMIGA.C - 19th Aug 1988 - System dependent functions.
- * Pete Hardie VE5VA
- *
- */
-
- #include "mb.h"
- #include <intuition/intuition.h>
- #include <intuition/intuitionbase.h>
- #include <graphics/text.h>
- #include <devices/serial.h>
- #include <ctype.h>
- #include <time.h>
- #include "rexxhostbase.h"
-
- extern struct RexxHost *rexx_host;
- extern long rexxbit;
- extern struct Window *mywindow;
- extern struct IntuiMessage *NewMessage;
- short interflag = 0;
- short debug;
- long serfirst = 0L;
- char tmpstr[300];
- extern struct IOExtSer *Ser_Read;
- extern struct IOStdReq *Con_Read,*Con_Write;
- extern unsigned char rs_in[2];
- extern struct IOExtSer *Ser_Write;
- extern unsigned char rs_out[2];
- extern char optflags[];
- unsigned char gotstream = 0;
- extern char *tcmds[];
- /*
- {
- "cono on\n",
- "cono of\n",
- "m on\n",
- "m of\n"
- };
- */
- char passchr = 0,hfstream = 0,vhfstream = 0;
- char l_date[7], l_time[5];
- char z_date[7], z_time[5];
- char pt_flag = 0;
- extern short tapr_flag;
- short done_flag = 1;
- /*
- * Set the current I/O device.
- */
-
- ioport(pp)
- PORTS *pp;
- {
- port = pp;
- }
-
- /*
- * Return non-zero if a character waits at current input.
- */
-
- instat()
- {
- register int st;
-
- if (port->dev is p_console) {
- /* check for char at console */
- if(CheckIO((struct IORequest *)Con_Read))return(1);
- else return(0);
- }
- if(port->dev is p_tnc) {
- /* check for char at serial port */
- if(CheckIO((struct IORequest *)Ser_Read)) {
- if(optflags[4])interflag = 1;
- return(1);
- }
- else return(0);
- }
- return(0);
- }
- /* output char to serial port */
- outi(ch)
- char ch;
- {
- schar(ch);
- }
-
- /*
- * Put the character out the current port,
- * echo to console if the current port is not the console.
- * Note special handling of end-of-line character.
- */
-
- outchar(ch)
- char ch;
- {
- if (ch is '\r') return;
- if (ch is '\n') ch = '\r';
- /*
- * Put it out to the console, if it is going there.
- */
-
- if ((port->dev is p_console) or port->ec) {
- if (ch is '\r') ttputc('\n');/* output '\n' */;
- if(ch != passchr)ttputc(ch);
- }
-
- /*
- * If the port is the console, nothing more to do.
- */
-
- if (port->dev is p_console) return;
-
- /*
- * Stuff this byte out the port.
- */
-
- outi(ch);
- if (ch is '\r')
- if (port->flags & p_lf) outi('\n');
- }
- unsigned char procstr[linelen];
- /* This routine must not use tmpstr to process the string because tmpstr
- might be the input
- */
- outstr(cp)
- unsigned char *cp;
- {
- register unsigned char *p,*q;
- register int beepcount;
- /* count the number of beeps in the line so that we can give an audible
- as well as visual beep
- */
- if((port->dev is p_console) || port->ec) {
- beepcount = 0;
- for(q = cp,p = &procstr[0];*q && p < &procstr[linelen-1];q++) {
- if(*q is '\r')continue;
- *p++ = *q;
- if(*q == '\007')beepcount++;
- }
- *p = 0;
- Con_Write->io_Data = (APTR) &procstr[0];
- Con_Write->io_Length = p-&procstr[0];
- Con_Write->io_Command = CMD_WRITE;
- DoIO((struct IORequest *)Con_Write);
- while(beepcount--) {
- beep();
- Delay(15L);
- }
- }
- /* now do the TNC if it is required.
- The TNC appears to drop characters if I send the whole line
- in one I/O so leave it at one character at a time. At 1200
- baud this is not a problem.
- */
- if(port->dev is p_console)return;
- for(q = cp,p = &procstr[0];*q && p < &procstr[linelen-1];q++) {
- if(*q is '\r')continue;
- if(*q is '\n') {
- *p++ = '\r';
- if (port->flags & p_lf)*p++ = '\n';
- }
- else *p++ = *q;
- }
- *p = 0;
- Ser_Write->IOSer.io_Command = CMD_WRITE;
- Ser_Write->IOSer.io_Length = p-&procstr[0];
- Ser_Write->IOSer.io_Data = (APTR) &procstr[0];
- DoIO((struct IORequest *)Ser_Write);
- }
-
- short wait_timeout = 0;
- char cmdstring[100];
- FILE *fd;
- PORTS *devtnc;
- char *inittnc(infile,force)
- int force;
- char *infile;
- {
- /* This routine MUST NOT use tmpstr while the infile string is being used.
- infile could be the tmpstr!
- */
- register char *cp;
- register char c;
- register PORTS *p;
- PORTS *oldport;
- oldport = port;
- wait_timeout = 0;
- devtnc = 0;
- /* Find the tnc port and set it as the current port */
- for(p=porthd; p != NULL; p = p->next) {
- if((devtnc == 0) && (p->id != 'Z'))devtnc = p;
- }
- if(devtnc == 0) {
- printf("Can't find port\n");
- donebeep();
- endtimer();
- cleanser();
- freefcb();
- closeterm();
- clrbusy();
- exit(1);
- }
- ioport(devtnc);
- if((devtnc->dev == p_serial) || (devtnc->dev == p_nulmdm)) {
- devtnc->ec = 1;
- goto file_only;
- }
- if(!force)goto file_only;
- /* Force a ^Q^C X to the KAM or other TNC. If KAM is in mode other
- than packet this will force it back.
- If already in packet mode this will be interpreted as an XFLOW
- request ... which won't hurt anything
- */
- outstr("\021\003X\n\n");
- waitcmd(10);
- /* have to turn off monitoring and conok so that nothing interferes
- with the startup
- */
- alloff();
- outstr("echo off\n"); /* echo MUST be off too */
- waitcmd(10);
- /* If wait_timeout is too big then the TNC probably isn't there
- so let's get outta here
- */
- if(wait_timeout >= 3) {
- fclose(port->fl);
- donebeep();
- endtimer();
- cleanser();
- freefcb();
- closeterm();
- clrbusy();
- printf("Too many timeouts from TNC - possible reasons are:\n");
- printf("1. TNC and AMIGA are not using same baudrate\n");
- printf("2. The TNC is not plugged into the AMIGA\n");
- printf("3. The TNC PARITY is not set to NONE (or SPACE)\n");
- printf("4. There's too much monitored information buffered\n");
- printf(" and it took too long to clear it - try again\n");
- exit(1);
- }
- /* get the thing into sync with what comes in from the TNC which
- may have stored up a lot of monitored stuff
- Do this by sending out a command and watch for the reply.
- */
- outstr("txd\n");
- do {
- if((c = toupper(rdchar())) != 'T') {
- ttputc(c);
- continue;
- }
- ttputc('T');
- if((c = toupper(rdchar())) != 'X') {
- ttputc(c);
- continue;
- }
- ttputc('X');
- if((c = toupper(rdchar())) != 'D') {
- ttputc(c);
- continue;
- }
- ttputc('D');
- break;
- }while(1);
- waitcmd(0);
- if(!passchr) {
- outstr("pass\n");
- while((c = toupper(rdchar())) != 'P') {
- ttputc(c);
- /* If the reply contains '?' then there's no pass command */
- if(c == '?') {
- ttputs("NO PASS COMMAND\n\n");
- goto file_only;
- }
- }
- ttputc(c);
- while((c = toupper(rdchar())) != '$')ttputc(c);
- ttputc(c);
- ttputc(c = rdchar());
- passchr = hex(c) << 4;
- ttputc(c = rdchar());
- passchr |= hex(c);
- waitcmd(0);
- }
- /* Now find out what the stream switching character(s) is(are) */
- /* but forget it if there is no pass char */
- if(passchr && !hfstream && !vhfstream) { /* if not done before */
- outstr("streamsw\n");
- while((c = toupper(rdchar())) != 'W') {
- ttputc(c);
- if(c == '?') {
- /* something's gone wrong. If there is a passchar then there
- must also be a streamswitch. If not then clear passchr and
- announce the problem
- */
- passchr = 0;
- ttputs("Error from STREAMSW command - streamswitching off\n");
- waitcmd(0);
- goto file_only;
- }
- }
- ttputc(c);
- while((c = toupper(rdchar())) != '$')ttputc(c);
- ttputc(c);
- ttputc(c = rdchar());
- vhfstream = hex(c) << 4;
- ttputc(c = rdchar());
- vhfstream |= hex(c);
- /* IF it is a KAM there are two streamswitching chars to read */
- if((c = rdchar()) == '/') {
- ttputc(c);
- hfstream = vhfstream;
- ttputc(rdchar()); /* do the $ sign */
- ttputc(c = rdchar());
- vhfstream = hex(c) << 4;
- ttputc(c = rdchar());
- vhfstream |= hex(c);
- }
- else ttputc(c);
- waitcmd(0);
- }
- sprintf(cmdstring,"\nPASS = $%02x, streamswitch VHF = ",passchr);
- ttputs(cmdstring);
- if((vhfstream > ' ') && (vhfstream < 0177))
- sprintf(cmdstring,"%c",vhfstream);
- else
- sprintf(cmdstring,"$%02x",vhfstream);
- ttputs(cmdstring);
- if(hfstream) {
- if((hfstream > ' ') && (hfstream < 0177))
- sprintf(cmdstring," , HF = %c",hfstream);
- else
- sprintf(cmdstring," , HF = $%02x",hfstream);
- ttputs(cmdstring);
- }
- ttputc('\n');
- file_only:
- if((fd = fopen(infile,"r")) == NULL) {
- sprintf(tmpstr,"Can't open %s\n",infile);
- ioport(oldport);
- return(tmpstr);
- }
- while(fgets(cmdstring,99,fd) != NULL) {
- /* Ignore blank lines and comments */
- if((cmdstring[0] == 0) || (cmdstring[0] == 012)
- || (cmdstring[0] == '#'))continue;
- if(cmdstring[0] == '!') {
- remnl(&cmdstring[0]);
- do_system(&cmdstring[1]);
- continue;
- }
- if(cmdstring[0] == '^') {
- /* If it is ^S, send it and don't bother to read any more
- of the file as the TNC won't respond anyway
- */
- if(toupper(cmdstring[1]) == 'S') {
- outchar('\023');
- break;
- }
- /* Ignore anything else. There's no point allowing ^Q because
- the startup code at the beginning of inittnc must force ^Q
- anyway, otherwise it wouldn't be able to get the tnc to
- respond.
- */
- continue;
- }
- outstr(cmdstring);
- waitcmd(0);
-
- }
- fclose(fd);
- ioport(oldport);
- return((char *)0);
- }
- hex(c)
- char c;
- {
- char k;
- k = c;
- if((c >= '0') && (c <= '9'))return(c - '0');
- k = toupper(c);
- if((k >= 'A') && (c <= 'F'))return(c - 'A' + 10);
- return(-1);
- }
- flipdebug()
- {
- debug ^= 1;
- if(debug) {
- ttputs("debug now ON\n");
- }
- else {
- ttputs("debug now OFF\n");
- }
- }
- extern unsigned char ichar;
- extern long keybit,windbit,readbit,timerbit;
- long getbits;
- struct timeRequest {
- struct IORequest tr_node;
- struct timeval tr_time;
- };
- extern struct timeRequest timermsg;
-
- /* replace the original do_idle because it busy-waited ...
- this version sleeps until there is something to do
- */
- extern short cursecs;
- do_idle()
- {
- register unsigned char ch,*cp;
- register PORTS *p;
- int curmin,curmon;
- ULONG class,error;
- UWORD code;
- struct RexxMsg *rexxmessage; /* incoming rexx messages */
- STRPTR Arg; /* Temporary string pointer */
- PORTS *saveport;
- long waitbits; /* waitbits MUST be local in CBBS because it is changed
- by various other routines as they see fit */
-
- cursor_off();
- ioport(devtnc);
- allon();
- if((devtnc->dev == p_serial) || (devtnc->dev == p_nulmdm)) {
- ttputs("\nIDLE\n");
- }
- cp = (unsigned char *) devtnc->line;
- /* figure out time to next forward and set timer */
- curtim();
- curmin = 60 - cursecs;
- settimer(curmin);
- /* There might already be an unread char at the serial or console port */
- serfirst = 0L;
- clrbusy();
- if(CheckIO((struct IORequest *)Ser_Read)) {
- serfirst |= readbit;
- Wait(readbit);
- }
- if(CheckIO((struct IORequest *)Con_Read)) {
- serfirst |= keybit;
- Wait(keybit);
- }
- waitbits = windbit | readbit | timerbit | keybit | rexxbit;
- while(1) {
- /* If there was already a tnc char waiting then do it now */
- if(serfirst) {
- getbits = serfirst;
- serfirst = 0L;
- }
- else {
- getbits = Wait(waitbits);
- }
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == IDCMP_CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
- /* Need this to cancel out the clrbusy in done() */
- setbusy();
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == wchar) {
- ioport(cport);
- cursor_on();
- /* could have a timerbit set here.
- readbit could also be set but must handle that a
- different way.
- */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- return;
- }
- if(ch == '\033') {
- ttputs("do_idle\n");
- }
- }
- if(readbit & getbits) {
- /* save a line and if it is a CONNECT then return */
- if(error = WaitIO((struct IORequest *)Ser_Read)) {
- printf("DO_IDLE error %ld\n",error);
- }
- ch = rs_in[0];
- if(tapr_flag)ch &= 0177;
- *cp = ch; /* autolf is off so don't need to look for '\n' */
- if((cp++ == (unsigned char *)devtnc->line + linelen -2)
- || (ch == '\r')) {
- if(ch == '\r')cp--;
- *cp++ = '\n';
- *cp = 0;
- /* Str_search cleans up the line and then does outstr */
- ioport(cport);
- str_search(devtnc->line);
- ioport(devtnc);
- p->flags setbit p_give;
- if(iscon(devtnc->line)) {
- /* readbit has been handled but timerbit could be set */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- BeginIO((struct IORequest *)Ser_Read);
- return;
- }
- monitor();
- cp = (unsigned char *)devtnc->line;
- }
- else if(ch == '\n')cp--;
- BeginIO((struct IORequest *)Ser_Read);
- }
- /* REXX must turn off the clock because the forward may do it
- anyway. Then once the forward is over, start the clock up
- again.
- */
- if(rexxbit & getbits) {
- while(rexxmessage = GetRexxMsg(rexx_host,0L)) {
- /* If Arg is non-zero then this is an AREXX message from another
- process.
- If Arg is null then it is the result of a ReplyRexxCommand
- from another process. This can't happen yet because we do not
- send messages out.
- */
- if(Arg = GetRexxCommand(rexxmessage)) {
- /* Must turn off the clock because the forward may do it
- anyway. Then once the forward is over, start the clock up
- again.
- */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- getbits &= ~timerbit;
- saveport = port;
- /* Have to force it to use the console port for this */
- ioport(cport);
- port->opt1 = *Arg++;
- port->opt2 = *Arg;
- /* Have to reply to it early so that the sysop, or other
- process doesn't have to wait for the forward to finish.
- Send a non-zero secondary result to indicate OK.
- */
- ReplyRexxCommand(rexxmessage,0L,1L,0L);
- alloff();
- acmd();
- allon();
- ioport(saveport);
- /* Turn clock back on again */
- /* figure out time to next forward and set timer */
- curtim();
- curmin = 60 - cursecs;
- settimer(curmin);
- }
- else {
- FreeRexxCommand(rexxmessage);
- }
- }
- }
- /* This code is deliberately placed last. If a timer bit occurs
- at the same time as a character arrives from the serial port
- then this code will hang the serial port up because afwd()
- tries to use the port again without clearing the existing char.
- So workaround it. Putting the timer code here guarantees that
- even if the ser char did occur it will be handled first and the
- ser char code handles the problem of returning from this routine
- with a timer bit set.
- */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- /* call the forwarding routine */
- curtim();
- curmin = 10 * (l_time[2] - '0') + (l_time[3] - '0');
- afwd(curmin);
- curmon = 10 * (l_date[2] - '0') + (l_date[3] - '0');
-
- if (s_param & s_log_on) if (curmon isnt log_mon) chglog();
-
- settimer(60);
- }
- }
- }
- /* IMPLEMENTATION BUG. In the original getdat it busy-idles and
- if the port is transparent and DCD goes off while the port is
- not idle, then it forces the mode to discon and then returns(true).
- This code can only do this properly IF it can wait for DCD to go
- off. I haven't even tried to implement this yet and not sure if it
- can be done properly. I assume that there's a way to Wait() for a
- DCD event but haven't checked it out
- */
- char *cp;
- /* MAXLEN is the longest unterminated line the justification routine
- will accept before it rips out the word and keeps it for later use.
- MAXJUST is the longest word that the routine will keep ... if the word
- is any longer than this then it will just allow you to mess up the line!
- */
- #define MAXLEN 77
- #define MAXJUST 20
- unsigned char x_pos = 0; /* Position on line for right justification */
- unsigned char s_pos = 0; /* Position of last space on the line */
- char saveword[MAXJUST+2];
- getdat()
- {
- register char *q;
- register char ch;
- register PORTS *p;
- int eflag;
- int curmin,serflg;
- ULONG class,waitbits;
- USHORT code;
-
-
- p = port;
- cp = p->line;
- x_pos = s_pos = 0;
- /* If there was a justified word left over from previous line .. put it
- in here now.
- */
- if(*saveword) {
- q = saveword;
- while(*q) {
- ttputc(*q);
- *cp++ = *q++;
- x_pos++;
- }
- }
- *saveword = 0;
- *cp = 0;
- /* Is a timeout timer required? */
- curmin = 0;
- if(p->flags & p_dotmr) {
- if((p->mode & idle) && (p->dev == p_tnc))
- curmin = 2;
- else
- curmin = p->ctime;
- }
- /* The timer counts curmin down and each time it ticks the program
- queries the serial driver to see if CD is still on if the user
- is logged in on the modem. It doesn't bother for the sysop because
- the modem won't be active.
- I don't think that p_nulmdm needs to worry about this timer.
- */
- if(curmin) {
- if(p->dev != p_serial) {
- settimer(curmin);
- }
- else {
- settimer(1); /* set timeout timer if required to look for CD */
- }
- }
- p->flags setbit p_dotmr;
-
- serfirst = 0L;
- if(CheckIO((struct IORequest *)Ser_Read)) {
- serfirst |= readbit;
- Wait(readbit);
- }
- if(p == cport) {
- waitbits = windbit | timerbit | keybit;
- }
- else {
- if(CheckIO((struct IORequest *)Con_Read)) {
- serfirst |= keybit;
- Wait(keybit);
- }
- waitbits = windbit | readbit | timerbit | keybit;
- }
- while(1) {
- if(serfirst) {
- getbits = serfirst;
- serfirst = 0L;
- }
- else {
- getbits = Wait(waitbits);
- }
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == IDCMP_CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == '\033') {
- if(p == cport)ttputs("getdatCON\n");
- else ttputs("getdatTNC\n");
- }
- eflag = 0;
- if(p != cport) {
- if(ch == achar) {
- p->mode = forced;
- eflag = 1;
- }
- if(ch == tchar) {
- p->flags setbit p_opreq;
- eflag = 1;
- }
- }
- else {
- if(charf(ch)) {
- eflag = 1;
- }
- }
- /* If any of the previous three if statements want to
- exit then check that the timer is off and then get out
- */
- if(eflag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- if(curmin)cantimer();
- }
- *cp = 0;
- return(true);
- }
- }
- if(readbit & getbits) {
- WaitIO((struct IORequest *)Ser_Read);
- ch = rs_in[0];
- if(tapr_flag)ch &= 0177;
- BeginIO((struct IORequest *)Ser_Read);
- if(optflags[4])interflag = 1;
- /* ignore stuff from the port if we are reading the console */
- if((p != cport) && charf(ch)) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- if(curmin)cantimer();
- }
- if(!(p->flags & p_trans)) {
- if(isdis(p->line)) {
- if(!(p->mode & idle))p->mode = discon;
- return (true);
- }
- if(isretry(p->line)) {
- return (false);
- }
- if(isreq(p->line)) {
- p->flags setbit p_req;
- pcall(p->rcall,p->line+20);
- p->flags clrbit p_dotmr;
- return (false);
- }
- }
- return (true);
- }
- }
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- if((curmin -= 1) <= 0) {
- if(!(p->mode & idle))p->mode = timeout;
- *cp = 0;
- return (true);
- }
- /* Look for drop of carrier detect on the serial port */
- if(p->dev == p_serial) {
- if(getserstat() & 0x20) {
- p->mode = discon;
- *cp = 0;
- return(true);
- }
- }
- settimer(1);
- }
- }
- }
- charf(s)
- unsigned char s;
- {
- register unsigned char ch;
- PORTS *p;
- register char *q,*r;
- register int i;
-
-
- p = port;
- ch = s;
- /* Ignore characters with high order bit set...they tie up the TNC */
- if(ch > 0177)return(0);
- *cp = ch;
- if((cp >= p->line + linelen - 3) || (ch == '\r')) {
- do_lf:
- if(ch == '\r')*cp = '\n';
- *++cp = 0;
- if(p->dev != p_console)ttputs(p->line);
- if(p->flags & p_echo)ttputc('\n');
- return(1);
- }
- if((ch >= ' ') && (ch <= 0176)) {
- /*
- Do justification for local user.
- */
- if(p->dev == p_console) {
- if(ch == ' ') {
- s_pos = x_pos;
- /* If the space is at exactly the point we would have justified
- the line then fake a CR anyway
- */
- if(x_pos == MAXLEN) {
- ch = '\r';
- *saveword = 0;
- goto do_lf;
- }
- }
- else {
- /* It's not a space ... should we do the justify?
- */
- if(x_pos == MAXLEN) {
- /* This word can't be longer than MAXJUST or we just leave
- it alone and let them mess up the line
- */
- if((i = (MAXLEN - s_pos)) < MAXJUST) {
- q = saveword;
- r = &p->line[s_pos+1];
- do {
- *q++ = *r++;
- ttputs("\b \b");
- }while(--i);
- *q = 0;
- cp = &p->line[s_pos];
- ch = '\r';
- goto do_lf;
- }
- }
- }
- }
- x_pos++;
- if (p->flags & p_echo) ttputc(ch);
- cp++;
- return(0);
- }
- switch(ch) {
- default:
- break;
- case 26: /* Control - Z */
- cp++;
- x_pos++;
- break;
- case '\t':
- if(p->flags & p_echo) ttputc(ch);
- s_pos = x_pos;
- x_pos++;
- cp++;
- break;
- case '\b':
- if(cp > p->line) {
- cp--;
- if(p->flags & p_echo) ttputs("\b \b");
- x_pos--;
- /* If they wipe out a space we've got to find the previous one */
- if(*cp == ' ') {
- r = cp-1;
- while(r > p->line) {
- if(*r == ' ') break;
- r--;
- }
- s_pos = r - p->line;
- }
-
- }
- break;
-
- case '\n':
- if(cp is p->line) {
- *cp = '\0';
- return(1);
- }
- break;
- }
- return(0);
- }
-
-
- /* Remove the busy-wait in term() */
-
- term(s)
- PORTS *s;
- {
- register char ch,*cp;
- register PORTS *m;
- ULONG class,waitbits;
- USHORT code;
- byte ec;
-
- m = cport;
- m->flags clrbit p_give;
- ec = s->ec;
- s->ec = true;
- ioport(m);
- serfirst = 0L;
- if(CheckIO((struct IORequest *)Ser_Read)) {
- serfirst |= readbit;
- Wait(readbit);
- }
- waitbits = windbit | readbit | keybit;
- while(1) {
- if(serfirst) {
- getbits = serfirst;
- serfirst = 0L;
- }
- else {
- getbits = Wait(waitbits);
- }
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == IDCMP_CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == rchar) {
- m->flags setbit p_give;
- s->ec = ec;
- return;
- }
- if(ch == '\r')ch = '\n';
- ttputc(ch);
- if(ch == '\n') {
- schar('\r');
- if(s->flags & p_lf)schar('\n');
- }
- else schar(ch);
- if(m->fl isnt NULL) if(ch isnt cpmeof)putc(ch,m->fl);
- }
- if(readbit & getbits) {
- WaitIO((struct IORequest *)Ser_Read);
- ch = rs_in[0];
- if(tapr_flag)ch &= 0177;
- BeginIO((struct IORequest *)Ser_Read);
- /* if(streamswitch(ch))continue; */
- if(ch == '\r')ch = '\n';
- if(m->fl isnt NULL) if(ch isnt cpmeof)putc(ch,m->fl);
- ttputc(ch);
- }
- }
- }
-
- /* This handles the stream characters.
- BUT not any more ... KAM V3.0 has removed the streamdb command.
- The first streamswitch character is always printed but is not passed
- as data.
- The character immediately after the streamswitch is passed if it is the
- same streamswitch character, otherwise it is printed but also not passed
- as data.
- streamswitch(ch)
- unsigned char ch;
- {
- if(gotstream) {
- if(ch == gotstream) {
- gotstream = 0;
- }
- else {
- gotstream = 0;
- ttputc(ch);
- return(1);
- }
- }
- else {
- if(ch && ((ch == vhfstream) || (ch == hfstream))) {
- gotstream = ch;
- ttputc(ch);
- return(1);
- }
- }
- return(0);
- }
- */
-
-
- /* Replace the pause routine so that it can be used with TNC as well
- as the console. If routine times out after 2 minutes then it will
- return 'Q'.
- */
- pause()
- {
-
- register char ch,*q;
- ULONG class,waitbits;
- USHORT code;
-
- if (port->user->state & u_pause) return ' ';
-
- q = &tmpstr[0];
- prtx(pausemsg);
- if(port->mode != local)outchar('\n');
- settimer(120); /* set timeout timer */
- waitbits = windbit | readbit | timerbit | keybit;
- serfirst = 0L;
- if(CheckIO((struct IORequest *)Ser_Read)) {
- serfirst |= readbit;
- Wait(readbit);
- }
- while(1) {
- if(serfirst) {
- getbits = serfirst;
- serfirst = 0L;
- }
- else {
- getbits = Wait(waitbits);
- }
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == IDCMP_CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = toupper(ichar);
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- outchar('\n');
- return(ch);
- }
- if(readbit & getbits) {
- WaitIO((struct IORequest *)Ser_Read);
- ch = rs_in[0];
- if(tapr_flag)ch &= 0177;
- ch = toupper(ch);
- BeginIO((struct IORequest *)Ser_Read);
- *q++ = ch;
- if(ch == '\r') {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- return(tmpstr[0]);
- }
- }
- /* check for timeout */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- return('Q');
- }
- }
- }
-
- /* Force modem to hangup */
- force_modem()
- {
- /* if(getserstat() & 0x20)return;*/
- Delay(150L);
- outstr("+++");
- waitcmd(5);
- Delay(10L);
- outstr("ATH0\n");
- waitcmd(5);
- }
- /* Skips leading blanks and then converts next two hex digits to binary.
- returns -1 on error.
- */
- fromhex(s)
- char *s;
- {
- register int i,j;
- register char *p;
- p = s;
- i = 0;
-
- while(*p == ' ')p++;
- if((i = hex(*p++)) < 0)return(-1);
- j = hex(*p);
- if(j < 0)return(-1);
- i <<= 4;
- i |= j;
- return(i);
- }
- /* replace waitcmd from mbtnc to reduce busy waits */
- char *waitfor = "cmd:";
- short wait_read;
- waitcmd(x)
- int x;
- {
-
- register char ch;
- register int i;
- ULONG class,waitbits;
- USHORT code;
- wait_read = 0;
- if(port->dev == p_nulmdm)return;
- if(port->dev == p_serial) {
- waitfor = "ok\n\n";
- }
- else
- if(port->dev != p_tnc)return;
- if(s_flag & s_dv) i = 5;
- else i = 2;
- if(x) i = x;
- settimer(i); /* set timeout timer */
- i = 0;
- waitbits = windbit | readbit | timerbit | keybit;
- serfirst = 0L;
- if(CheckIO((struct IORequest *)Ser_Read)) {
- serfirst |= readbit;
- Wait(readbit);
- }
- while(1) {
- if(serfirst) {
- getbits = serfirst;
- serfirst = 0L;
- }
- else {
- getbits = Wait(waitbits);
- }
- if(windbit & getbits) {
- while(NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
- class = NewMessage->Class;
- code = NewMessage->Code;
- ReplyMsg((struct Message *)NewMessage);
- if(class == IDCMP_CLOSEWINDOW) {
- /* say a fond farewell, don't ask fer sure? */
- if(done_flag) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- SetWindowTitles(mywindow,(UBYTE *)"",(UBYTE *)-1L);
- done(1);
- }
- }
- }
- }
- if(getbits & keybit) {
- WaitIO((struct IORequest *)Con_Read);
- ch = ichar;
- Con_Read->io_Data = (APTR)&ichar;
- Con_Read->io_Command = CMD_READ;
- Con_Read->io_Length = 1;
- SendIO((struct IORequest *)Con_Read);
- if(ch == '\033') { /* ESC key forces termination */
- ttputs("ESC\n");
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- return;
- }
- }
- if(readbit & getbits) {
- WaitIO((struct IORequest *)Ser_Read);
- wait_read = 1;
- ch = rs_in[0];
- if(tapr_flag)ch &= 0177;
- BeginIO((struct IORequest *)Ser_Read);
- /* if(streamswitch(ch))continue; */
- if(ch == '\r') {
- ch = '\n';
- }
- ttputc(ch);
- if(tolower(ch) == waitfor[i]) {
- i++;
- if(i == strlen(waitfor)) {
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- }
- else {
- cantimer();
- }
- return;
- }
- }
- else {
- i = 0;
- }
- }
- /* check for timeout */
- if(timerbit & getbits) {
- WaitIO((struct IORequest *)&timermsg);
- wait_timeout++;
- return;
- }
- }
- }
-