/* // PLP - An implementation of the PSION link protocol // // // The code in this file was written by Rudolf Koenig // (rfkoenig@immd4.informatik.uni-erlangen.de). (from his p3nfs code) // The Copyright remains his // // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // e-mail philip.proudman@btinternet.com */ #include #include #include /* for usleep() */ #include /* for bzero() */ #include #if defined(linux) || defined(_IBMR2) || defined(__NetBSD__) # include /* for ioctl() */ #endif #include #ifdef sun # include /* sun has TIOCEXCL there */ #endif #if defined (__SVR4) #include #endif static struct termios sti; #ifndef hpux # define mflag int #else /* hpux */ # include # include #endif /* #if !defined(CRTSCTS) && defined(_IBMR2) #define CRTSCTS 0x80000000 #endif */ #ifdef __sgi #define CRTSCTS CNEW_RTSCTS #endif #ifndef O_NOCTTY # define O_NOCTTY 0 #endif int init_serial(const char *dev, int speed, int debug, int background) { int fd, baud, clocal; struct termios ti; #ifdef hpux struct termiox tx; #endif static struct baudRate { int speed, baud; } btable[] = { { 9600, B9600}, #ifdef B19200 { 19200, B19200}, #else # ifdef EXTA { 19200, EXTA}, # endif #endif #ifdef B38400 { 38400, B38400}, #else # ifdef EXTB { 38400, EXTB}, # endif #endif # ifdef B57600 { 57600, B57600}, # endif # ifdef B115200 { 115200, B115200}, # endif { 4800, B4800}, { 2400, B2400}, { 1200, B1200}, { 300, B300}, { 75, B75}, { 50, B50}, {0,0} }, *bptr; if(speed) { for (bptr = btable; bptr->speed; bptr++) if (bptr->speed == speed) break; if (!bptr->baud) { fprintf(stderr, "Cannot match selected speed %d\n", speed); exit(1); } baud = bptr->baud; } else { baud = 0; } if(background) { int uid, euid; if(debug) printf("using %s...\n", dev); euid = geteuid(); uid = getuid(); #ifdef hpux #define seteuid(a) setresuid(-1, a, -1) #endif clocal = CLOCAL; if (seteuid(uid)) { perror("seteuid"); exit(1); } if((fd = open(dev, O_RDWR | O_NDELAY | O_NOCTTY , 0)) < 0) { perror(dev); exit(1); } if (seteuid(euid)) { perror("seteuid back"); exit(1); } if(debug) printf("open done\n"); #ifdef TIOCEXCL ioctl(fd, TIOCEXCL, (char *) 0); /* additional open() calls shall fail */ #else fprintf(stderr, "WARNING: opened %s non-exclusive!\n", dev); #endif } else { char *f; fd = dup(0); if(tcgetattr(fd, &ti) < 0) { perror("tcgetattr serial"); exit(1); } sti = ti ; /* Save the state for shutdown time */ clocal = ti.c_cflag & CLOCAL ; /* and for setup */ close(0); /* Let's close 0,1,2 */ f = "/dev/null"; if(open(f, O_RDONLY, 0) != 0) { perror(f); exit(0); } close(1); f = "/tmp/p3nfsd.out"; if(open(f, O_WRONLY|O_CREAT|O_APPEND, 0666) != 1) { perror(f); exit(0); } fprintf(stderr, "p3nfsd: output written to %s\n", f); close(2); dup(1); } memset(&ti, 0, sizeof(struct termios)); #if defined(hpux) || defined(_IBMR2) ti.c_cflag = CS8 | HUPCL | clocal | CREAD; #endif #if defined(sun) || defined(linux) || defined(__sgi) || defined(__NetBSD__) || defined(__FreeBSD__) ti.c_cflag = CS8 | HUPCL | clocal | CRTSCTS | CREAD; ti.c_iflag = IGNBRK | IGNPAR; ti.c_cc[VMIN] = 1; ti.c_cc[VTIME] = 0; #endif cfsetispeed(&ti, baud); cfsetospeed(&ti, baud); if(tcsetattr(fd, TCSADRAIN, &ti) < 0) perror("tcsetattr TCSADRAIN"); #ifdef hpux bzero(&tx, sizeof(struct termiox)); tx.x_hflag = RTSXOFF | CTSXON; if (ioctl(fd, TCSETXW, &tx) < 0) perror("TCSETXW"); #endif #if defined(_IBMR2) ioctl(fd, TXDELCD, "dtr"); ioctl(fd, TXDELCD, "xon"); ioctl(fd, TXADDCD, "rts"); /* That's how AIX does CRTSCTS */ #endif return fd; } void ser_exit(int fd) { struct termios ti; if(tcgetattr(fd, &ti) < 0) { perror("TCGETSW"); } ti.c_cflag &= ~CRTSCTS; if(tcsetattr(fd, TCSANOW, &ti) < 0) { perror("TCSETSW"); } (void) close(fd); }