#include "ufk.h" #include #include #include #include #include #define R_CHUNK_SIZE 50 /* Number of characters to read at a time */ char lastchar, cons_set; jmp_buf env, popenv; struct sgttyb old_mode, new_mode, old_c_mode, new_c_mode; /* * Open communication port */ open_port(setcons,check_only) char setcons, check_only; { int opnint(); char tmpprt[20]; struct stat buf; sprintf(tmpprt,"/dev/tty%02d",ttyslot()); /* Get controlling terminal */ if ((strcmp(tty_descr,"Remote") == 0) || (strcmp(tty_descr,tmpprt) == 0)) remote = TRUE; else { remote = FALSE; strcpy(tmpprt,tty_descr); } if (stat(tmpprt,&buf)) return (NULL); /* unable to obtain status */ if ((buf.st_mode & S_IFMT) != S_IFCHR) return (NULL); /* Not a character device */ if (!check_only) /* Real open */ { if (!port_open || remote) { if (setjmp(popenv)) return (NULL); /* Interrupted during open */ signal(SIGINT,opnint); /* Catch ctrl-C interrupt */ ttyfd = open(tmpprt,2); if (ttyfd == ERROR) { signal(SIGINT,SIG_DFL); /* Default kbd interrupt */ return(NULL); } signal(SIGINT,SIG_IGN); /* Ignore kbd interrupt */ gtty(ttyfd,&old_mode); /* Get old characteristics */ gtty(ttyfd,&new_mode); /* Get copy */ new_mode.sg_speed &= ~0x1c; /* Mask old config bits */ new_mode.sg_speed |= (config << 2); /* Set new configuration */ new_mode.sg_flag |= RAW; /* Set raw mode */ new_mode.sg_flag &= ~(ECHO|CRMOD); /* No echo, no auto lf */ stty(ttyfd,&new_mode); /* Set new parameters */ port_open = TRUE; /* Flag it's open now */ } cons_set = FALSE; if (!remote) { if (call_baud) /* Only the first time ... */ { baud(tmpprt,speed); /* set baudrate */ call_baud = FALSE; /* Don't set it anymore */ } if (setcons && !nooutput) { cons_set = TRUE; /* Console set as well */ gtty(0,&old_c_mode); /* Get console characteristics */ gtty(0,&new_c_mode); /* Get copy */ new_c_mode.sg_flag |= RAW; /* Set raw mode */ new_c_mode.sg_flag &= ~(ECHO|CRMOD); /* No echo, no auto lf */ stty(0,&new_c_mode); /* Set new console parameters */ } } purgeline(ttyfd); /* eat old input */ aborted = FALSE; port_open = TRUE; /* Mark port open */ } return (TRUE); /* valid port found */ } opnint() { longjmp(popenv,TRUE); /* timeout during port open */ } /* * Close communication port */ close_port(scrflag,real_close) int scrflag, real_close; { if (!remote && cons_set) stty(0,&old_c_mode); if ((real_close || remote) && port_open) { stty(ttyfd,&old_mode); close(ttyfd); signal(SIGINT,SIG_DFL); /* Restore keyboard interrupt */ port_open = FALSE; } if (scrflag) posit(0,23); curs_on(); /* Re-enable cursor */ } /* * read data from port */ kread(dev,data,count) int dev,count; char *data; { int i, n, p, left, clkint(); i = 0; /* Timeout counter */ if (setjmp(env)) if ((aborted && !(sflg || rflg)) || ((i += 2) >= timint)) /* Return TIMOUT if aborted during inactive period, or after real timeout */ return TIMEOUT; /* Limit reached, timeout */ signal(SIGALRM,clkint); /* Setup timeout catch */ /* Due to the accuracy of the 'alarm' call one second can cause problems */ alarm(2); /* Set two seconds timeout */ read(dev,data,1); /* Try to get first character */ alarm(0); /* Got one character, reset timeout */ if (count > 1) /* If more to do ... */ { left = count - 1; /* What's left to do */ n = 1; /* Starting offset in data array */ while (left > 0) /* Until all has been done */ { p = (left > R_CHUNK_SIZE ? R_CHUNK_SIZE : left); /* Read in chunks */ /* of R_CHUNK_SIZE characters or less */ i = timint; /* so we will return at timeout */ alarm(timint); /* Set selected timeout */ read(dev,&data[n],p); /* Try to get the rest of the data */ alarm(0); /* Got the rest, reset timeout */ left -= R_CHUNK_SIZE; /* Count down */ n += R_CHUNK_SIZE; /* Adjust next array index */ } } lastchar = data[count-1]; /* get last entered character */ if (rflg || sflg) chr_rec += count; /* count chars if sending or receiving */ if (!remote && !nooutput) check_abort(); /* check for abort or toggle debug */ return NULL; /* normal termination */ } clkint() { check_abort(); /* check for user abort after timeout */ longjmp(env,TRUE); } /* * write characters to port */ kwrite(dev,data,count) int dev,count; char *data; { if (count == 0) /* determine count if not given */ count = strlen(data); write(dev,data,count); if (rflg || sflg) chr_sent += count; /* count chars if sending or receiving */ } /* * check for user abort */ check_abort() { char c; struct sgttyb mode; if (!cflg) /* only when connect is inactive */ { gtty(0,&mode); if (mode.sg_speed & INCHR) /* if character available */ read(0,&c,1); else { if (remote) c = lastchar; /* Only check typed character */ else /* if remote */ c = 0; } c &= 0177; /* strip parity */ lastchar = 0; if ((c == ABORTX) || (c == ABORTZ)) { /* and if it's the abort char */ aborted = c; /* flag abort */ return c; } else if (c == TOGDBG) /* Toggle debug ? */ { if (debug) { debug = FALSE; /* Switch off debug */ if (dbgfil != ERROR) { fclose(dbgfil); /* Close debug output file if open */ dbgfil = ERROR; } } else debug = TRUE; /* Switch on debug */ set_frame(); /* Make new display frame */ disp_params(); /* With the current parameters */ } else if (c == PANIC) { for (c = 0; c < 3; c++) beep(); /* Ring the bell three times */ kerm_exit(); /* Get the hell out of here */ } else if (dstop != NULL && c == dstop) /* Wait.... */ { do read(0,&c,1); while ((c & 0177) != dstart); /* Wait for start */ } } return NULL; /* no abort */ } /* * purge a line of input data */ purgeline(port) int port; { struct sgttyb mode; char c; while(TRUE) { gtty(port,&mode); if (mode.sg_speed & INCHR) /* eat characters */ read(port,&c,1); else break; } } /* send break */ send_break(port) int port; /* Not used */ { do_break(tty_descr); /* Use fixed string descriptor */ } kdelay(time) int time; { int timdummy(); if (time != 0) { signal(SIGALRM,timdummy); alarm(time); pause(); } } timdummy() { }