home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) Dave Settle, March 1987
- * Permission is granted to do anything with this program, except remove
- * this copyright notice, or sell it for profit.
- *
- *
- * io.c: routines to talk to the device directly.
- *
- * dread and dwrite act like read(2) and write(2), execpt that they always
- * either succeed or exit, so the caller doesn't have to check.
- *
- * hangup drops the DTR line to the modem, so that it will (hopefully) hang up
- * the phone line. It keeps it this way for 5 seconds.
- *
- * findspeed takes an ascii speed, and returns the corresponing baud rate.
- *
- * uuexit is a dodgy routine to make UUCP happy.
- */
-
- #include <sys/errno.h>
- #include <termio.h>
- #include <fcntl.h>
-
- #include "modem.h"
-
- char *sys_errlist[]; /* error list */
- #define RETRY 5 /* retry failed writes */
- /*
- * dwrite: write some characters to the modem.
- * If your modem likes characters to be written s-l-o-w-l-y, define 'SLOW'
- */
- dwrite(f, s, n)
- int f;
- unsigned n;
- char *s;
- {
- struct termio termio;
- int r, retry = 0, i = 0;
- static int error = 0; /* error occurred on last call */
- while((i < n) && (retry < RETRY)) {
- if(locked()) uuexit(0);
- errno = 0;
- if(r = write(f, s + i, 1) == 1) i++; /* Success! */
- else {
- retry++;
- fixline();
- }
- #ifdef SLOW
- sleep(1); /* Let the modem deal with it */
- #endif
- }
- if(i != n) {
- ioctl(dev, TCGETA, &termio);
- printf("Tried %d times, still got %d/%d written. [error = %s]\n",
- retry, i, n, sys_errlist[errno]);
- printf("FAIL: dev %d, iflag %x, oflag %x, cflag %x, lflag %x, line %d\n",
- dev, termio.c_iflag,termio.c_oflag,termio.c_cflag,
- termio.c_lflag, termio.c_line);
- error = 1;
- }
- else if(retry > 1) printf("Write problem: fixed on retry %d\n", retry - 1);
- if(error && i == n) {
- ioctl(dev, TCGETA, &termio);
- printf("OK: iflag %x, oflag %x, cflag %x, lflag %x, line %d\n",
- termio.c_iflag,termio.c_oflag,termio.c_cflag,
- termio.c_lflag, termio.c_line);
- }
- if(i == n) error = 0;
- return(r);
- }
- /*
- * read one character at a time, checking before (and after) each read for
- * a lock file. If one exists, then exit.
- */
- dread(f, s, n)
- int f, n;
- char *s;
- {
- int i, w;
- for(i=0;i<n;i++, s++) {
- if(locked()) uuexit(0);
- while((w = read(f, s, 1)) < 1) {
- if(locked()) uuexit(0);
- if(w == -1) switch(errno) {
- case EINTR:
- break;
- default:
- perror("dread");
- }
- }
- }
- }
- /*
- * hangup(): hangup the phone, and close the device.
- * I've had problems with indefinate echoes from the modem when a connection
- * has closed - my modem transmits crap. This ought to hangup the phone and
- * prevent this.
- *
- * Oct 87: This problem should now be fixed, with the introduction of the
- * DCD control from the modem - we should now receive a hangup signal when
- * the line drops.
- */
- hangup(device) {
- struct termio term;
- if(ioctl(device, TCGETA, &term) == -1) perror("hangup: TCGETA");
- term.c_lflag &= ~(ECHO | ECHOE | ECHOK);
- term.c_cflag &= ~CBAUD;
- term.c_cflag |= B0; /* hangup */
- if(ioctl(device, TCSETA, &term) == -1) perror("hangup: TCSETA");
- if(ioctl(device, TCFLSH, 2) == -1) perror("hangup: TCFLSH");
- sleep(5); /* 5 seconds with DTR down */
- return(0);
- }
- /*
- * findspeed: convert ascii baud rate into termio parameter.
- */
- findspeed(s)
- char *s;
- {
- int baud = atoi(s);
- switch(baud) {
- case 110: baud = B110;
- break;
- case 300: baud = B300;
- break;
- case 1200: baud = B1200;
- break;
- case 2400: baud = B2400;
- break;
- default:
- printf("findspeed: unknown baud rate %s\n", s);
- baud = B1200;
- }
- return(baud);
- }
- /*
- * uuexit: make line useable by UUCP.
- * Because UUCP is pretty determined about using a "modem", it clears CLOCAL
- * which means that it can't write any characters at this point (modem not
- * online, so DCD not asserted). Not suprisingly, it doesn't work.
- * Solution: turn it on again, while UUCP isn't looking; this seems to work
- * fine, although I'm a little puzzled about the timing: this is a
- * definate "trial and error" solution.
- * This unfortunately also means that UUCP won't detect a line hangup,
- * so we have to rely on it's timeout facilities ...
- */
- #define DIALTIME 5 /* time to continue to assert CLOCAL */
- uuexit(code)
- {
- struct termio term;
- register int i;
- for(i=0;i<DIALTIME;i++) {
- close(open(dname, O_RDONLY | O_NDELAY)); /* vital magic */
- if(ioctl(dev, TCGETA, &term) == -1) perror("qx TCGETA");
- term.c_cflag |= CLOCAL;
- if(ioctl(dev, TCSETA, &term) == -1) perror("qx TCSETA");
- close(open(dname, O_RDONLY | O_NDELAY)); /* vital magic */
- sleep(1);
- }
- exit(code);
- }
- /*
- * extensions for send & expect
- */
- myread()
- {
- char c;
- dread(dev, &c, 1);
- return(c);
- }
- void mywrite(s)
- char *s;
- {
- dwrite(dev, s, strlen(s));
- }
-
-