// connect.c - modem control (dial-up line) through a serial port #include #include #include #include #include #define STDIN 0 #define STDOUT 1 #define STDERR 2 #define INCOMING 3 #define OUTGOING 4 #define FOREVER for(;;) #define ESC 033 #define CR 015 struct fax { char *portname; char *tty; char *lock; char *phone_number; unsigned short speed; unsigned short size; unsigned short mode; unsigned short startstop; }; struct fax ttystuff[] = { "office","/dev/ttyS0","/var/tmp/LOCKMODEM","ATDT6562258",B38400, CS8,CREAD|HUPCL,IXOFF, "westall","/dev/ttyS0","/var/tmp/LOCKMODEM","ATDT6565868",B38400, CS8,CREAD|HUPCL,IXOFF, "dept","/dev/ttyS0","/var/tmp/LOCKMODEM","ATDT6565879",B19200, CS8,CREAD|HUPCL|PARENB,IXOFF, 0 }; void incoming() { char buf; FOREVER while(read(INCOMING, &buf, 1)) write(STDOUT, &buf, 1); } void outgoing() { char buf; FOREVER while(read(STDIN,&buf,1)) { // what's a good escape character? if (buf=='#') return; write(OUTGOING,&buf,1); } } void commanderror() { struct fax *ptr; printf("syntax: connect \n"); printf("portnames available are:\n"); ptr=ttystuff; while(ptr->portname){ printf("%s\n",ptr->portname); ptr++; } exit(1); } void dial(struct fax *ptr) { char c; write(OUTGOING,ptr->phone_number,strlen(ptr->phone_number)); c=CR; write(OUTGOING,&c,1); } void hangup() { char buf[4]; buf[0]='+'; buf[1]='+'; buf[2]='+'; buf[3]=CR; sleep(2); write(OUTGOING,buf,4); buf[0]='A'; buf[1]='T'; buf[2]='H'; buf[3]=CR; sleep(2); write(OUTGOING,buf,4); } int main(int argc,char **argv) { struct termio modemport, controlport, saveport; struct fax *ptr; int pid,status; if (argc != 2) commanderror(); // this is an exit ptr=ttystuff; while(ptr->portname){ if(strcmp(ptr->portname,argv[1])==0) break; ptr++; } if(ptr->portname == 0) commanderror(); if(access(ptr->lock,F_OK) >= 0) { printf("port in use\n"); exit(1); } if(close(creat(ptr->lock,0)) < 0) { printf("system bug: \n"); printf("cannot lock port\n"); exit(1); } if(open(ptr->tty,0) != INCOMING) { printf("cannot open %s for read\n",ptr->tty); unlink(ptr->lock); exit(1); } if(open(ptr->tty,1) != OUTGOING) { printf("cannot open %s for write\n",ptr->tty); unlink(ptr->lock); exit(1); } // set control terminal to raw mode ioctl(STDIN,TCGETA,&saveport); controlport = saveport; controlport.c_cflag &= ~(PARENB|CSIZE); controlport.c_cflag |= CS8; controlport.c_lflag &= ~(ECHO|ICANON|ISIG); controlport.c_oflag &= ~OPOST; controlport.c_iflag |= IGNBRK; controlport.c_iflag &= ~(ISTRIP|INLCR|IGNCR|ICRNL|IXON); ioctl(STDIN,TCSETA,&controlport); ioctl(STDOUT,TCSETA,&controlport); // set io port ioctl(OUTGOING,TCGETA,&modemport); modemport.c_cflag = ptr->speed; modemport.c_cflag |= ptr->size; modemport.c_cflag |= ptr->mode; modemport.c_lflag &= ~ECHO; // local echo can be annoying modemport.c_iflag = ptr->startstop; ioctl(OUTGOING,TCSETA,&modemport); ioctl(INCOMING,TCSETA,&modemport); switch(pid=fork()) { case -1: printf("OOPS - no fork!\n"); exit(1); case 0: // child incoming(); break; default: // parent dial(ptr); outgoing(); kill(pid, SIGKILL); // kill the kid while(wait(&status) != pid); hangup(); // restore control terminal settings ioctl(STDIN,TCSETA,&saveport); ioctl(STDOUT,TCSETA,&saveport); unlink(ptr->lock); break; } return(0); }