perry@macom1.UUCP (Guru's Inc.) (12/20/89)
From article <1989Dec15.082753.709@larouch.uucp>, by jparnas@larouch.uucp (Jacob Parnas): > (This in response to John Kennedy's and Axel's request for front end C code) (Above article used as a vehicle, as I'm novice here) The following C codes are substitutions for getty or uugetty. One is for System III to make port bidirectional and autobaudable. The other is formated for System V. A third one is for Xenix. System III code requiring two consecutive carrage returns cut uugetty.c here>>!SYSIII static char Version[] = "@(#)/usr/src/uugetty.c 3.6 27 Nov 89 - Centel"; /*********************************************** uugetty: Bidirectional getty 3.6 27 Nov 89"; System III version P. Mathis ************************************************/ #include <stdio.h> /* used for database accesses only */ #include <termio.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #define CR 0x0D extern char * strcpy(); extern sleep(); static char port[20] = "/dev/", crtty[35] = "/usr/spool/uucp/cr", Lock[35] = "/usr/spool/uucp/LCK..", cbuf[50], buf[100], pbuf[20], prg[34], *device, *speed, *optn; int parent, child, i=0, mask; int intrexit(); FILE *dbf; static int fd1, fd2, lockfd, pterm; static struct termio targ; /***... Interrupt routines ...***/ trap0() {intrexit();} trap1() {track("hang"); signal( SIGHUP, trap1 );} trap2() {track("intr(2)"); intrexit();} trap3() {track("quit(3)"); intrexit();} trap15() {track("term(15)"); intrexit();} intrexit() { conprint(0); } conprint(n) /*** Send trace msg to crfile/console. ***/ int n; { close(fd1); if(n == 0) ; else { fd2 = open("/dev/console", 1); write(fd2, buf, (unsigned)strlen(buf) ); close(fd2); } sleep(n); exit(0); } track(msg) char *msg; { sprintf(buf, "%9s\n",msg); write(fd1, buf, (unsigned)strlen(buf) ); } /*** Make interface translucent. ***/ xlucent( term, targp ) int term; struct termio *targp; { int baud; ioctl( term, TCGETA, targp ); /* get terminal parameters */ switch( atoi(speed) ) { case 5: baud = B300; break; case 3: baud = B1200; break; case 6: baud = B2400; break; case 8: baud = B4800; break; case 2: baud = B9600; break; default: sprintf(buf, "%s: invalid baud %s\n",prg, speed); conprint(60); } targp->c_iflag = (IGNBRK| ISTRIP | IGNPAR); /* set configuration */ targp->c_oflag = (NULL); targp->c_cflag &= ~CBAUD; targp->c_cflag |= (baud); targp->c_lflag = (NULL); targp->c_cc[VMIN] = 1; targp->c_cc[VTIME] = 0; ioctl( term, TCSETA, targp ); } main( argc, argv ) int argc; char **argv; { int inithookup = 1; static char buf2[8], nuls[8] = '\0'; long lseek(), offset = 12L; int fd; signal( SIGHUP, trap1 ); /* 01 watch for hangups */ signal( SIGINT, trap2 ); /* 02 watch for interrupts */ signal( SIGQUIT, trap3 ); /* 03 watch for quit */ signal( SIGTERM, trap15 ); /* 15 watch for termination */ strcpy( &prg[0], argv[0] ); if (argc < 3) { sprintf(buf, "%s: Not Enough Arguments\n", prg); conprint(60); } device = argv[1]; speed = argv[2], optn = argv[3]; if( argv[3] == "" || argv[3] == "#" ) optn = "60"; strcpy( &port[5], argv[1] ); /* /dev/tty?? */ strcpy( &Lock[21], argv[1] ); /* LCK..tty?? */ strcpy( &crtty[18], argv[1] ); /* crtty?? */ fd = open ( "/etc/utmp", 2); /* clear last who */ while ( read (fd, buf2, 8) ) { if ( !(strcmp(buf2, argv[1])) ) { write (fd, nuls, 8); break; } else { lseek (fd, offset, 1); } } close(fd); sprintf(pbuf, "%10d\n%s\n", (getpid()), device ); /* get lockf ready */ fd1 = creat(crtty, 4); write(fd1, pbuf, 10 ); if(!(access(Lock, 0))) checkout(Lock); /* remove old lock if any */ if ((pterm = open( port, 2 )) < 0) { track("erropen"); sprintf( buf, "%s: cannot open port %s\n",prg, port ); conprint(60); } xlucent( pterm, &targ ); /* make port translucent */ ioctl( pterm, TCFLSH, 2 ); sprintf(buf, "chown uucp %s", port ); system(buf); /* give ownership */ while( wait_on_CR( pterm ) ) intread(); /* wait for connect request */ while (inithookup) { parent = getpid(); /* get id of this process */ if ((child = fork()) == 0) { sleep(5); exit(0); /* child holds line open */ } else { if (inithookup) { inithookup = 0; /* hookup is done */ execl("/etc/getty", "getty", device, speed, optn, 0); } } } } /*** end main ***/ wait_on_CR( term ) /*** Wait for connect message. ***/ int term; { char k, c; track("listen"); while (1) { if (read( term, &c, 1 ) <= 0) /* get a character from unix */ { k = c = '\0'; return (1); /* interrupt returned */ } if (!(access(Lock, 0))) checkout(Lock); if ( c == CR ) { if (k == CR ) { mask = umask(0); /* change mask */ lockfd = creat( Lock, 0444 ); /* create the lock file */ umask(mask); /* restore mask */ if ( lockfd < 0) { track("errlock"); sprintf(buf, "%s: cannot create lock %s\n",prg, device); conprint(60); } write( lockfd, pbuf, (unsigned)strlen(pbuf) ); close( lockfd ); track("incoming"); return(0); } } else { switch( atoi(speed) ) /* change baud rate */ { case 5: speed = "2"; break; case 3: speed = "6"; break; case 6: speed = "8"; break; case 8: speed = "5"; break; case 2: speed = "3"; break; } xlucent( pterm, &targ ); ioctl( pterm, TCFLSH, 2 ); track("break"); } k = c; } } checkout(lock) char *lock; { dbf = fopen(lock, "r"); fgets(buf, 20, dbf); fgets(cbuf, 10, dbf); fclose(dbf); if ( !(strcmp(pbuf+11, cbuf)) ) { unlink(lock); return; } /* tty=tty */ track("outgoing"); signal( SIGHUP, trap0 ); while (!(access(Lock, 0))) sleep(20); conprint(0); } intread() /*** die if here too often ***/ { track("IR-"); if ( ++i > 40 ) trap0(); } !SYSIII end System III uugetty.c cut System V version argetty.c here>>!SYSV static char Version[] = "@(#)/usr/lib/uucp/argetty 5.4 27 Mar 88 - Centel"; /************************************************* argetty: Bidirectional getty 5.4 27 Mar 88"; System V version. P. Mathis *************************************************/ #include <stdio.h> /* used for database accesses only */ #include <termio.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #define CR 0x0D /* incoming connect signal */ extern char * strcpy(); extern void exit(); extern sleep(); static char port[20] = "/dev/", trace[35] = "/usr/spool/locks/u", lock[35] = "/usr/spool/locks/LCK..", cbuf[60], buf[100], pbuf[20], prg[34], sspeed[10], *optt, *optn, *device, *speed; int parent, child, mask, i=0, r=1; int intrexit(); FILE *dbf; static int fd1, fd2, lockfd, pterm; static struct termio targ; /***... Interrupt routines ...***/ hangup() { signal(SIGHUP, hangup); track("HUP"); /* 01 watch for hangups */ conprint(0); } trap15() {track("TERM"); conprint(0);} conprint(n) /*** Send fatal msg to console and then die. ***/ int n; { close(fd1); if(n == 0) ; else { fd2 = open("/dev/console", 1); write(fd2, buf, (unsigned)strlen(buf) ); close(fd2); } sleep(n); exit(0); } track(msg) /*** Make tracks in uttyxx file ***/ char *msg; { sprintf(buf, "%10s\n",msg); write(fd1, buf, (unsigned)strlen(buf) ); } /*** Make interface translucent. ***/ xlucent( term, targp ) int term; struct termio *targp; { int baud; ioctl( term, TCGETA, targp ); /* get terminal parameters */ switch( atoi(sspeed) ) /* allow 9600, 9600H bauds */ { case 30: baud = B300; break; case 12: baud = B1200; break; case 24: baud = B2400; break; case 48: baud = B4800; break; case 96: baud = B9600; break; case 19: baud = B19200; break; default: sprintf(buf, "%s: invalid baud %s\n",prg, speed); conprint(60); } targp->c_iflag = (IGNBRK| ISTRIP | IGNPAR); /* set configuration */ targp->c_oflag = (NULL); targp->c_cflag &= ~CBAUD; targp->c_cflag |= (baud); targp->c_lflag = (NULL); targp->c_line = 0; targp->c_cc[VMIN] = 1; targp->c_cc[VTIME] = 0; ioctl( term, TCSETA, targp ); } main( argc, argv ) int argc; char **argv; { int inithookup = 1; static char buf2[8], nuls[8] = '\0'; long lseek(), offset = 12L; int fd; signal( SIGHUP, SIG_IGN ); /* 01 watch for hangups */ signal( SIGTERM, trap15 ); /* 15 watch for termination */ strcpy( &prg[0], argv[0] ); if (argc < 6) { sprintf(buf, "%s: Not enough Args\n", prg); conprint(60); } optt = argv[2]; optn = argv[3]; device = argv[4]; speed = argv[5]; strncat( sspeed, argv[5], 2 ); strcpy( &port[5], argv[4] ); /* /dev/tty?? */ strcpy( &lock[22], argv[4] ); /* LCK..tty?? */ strcpy( &trace[18], argv[4] ); /* utty?? */ sprintf(pbuf,"%10d\n\0",(getpid()) ); /* get current pid ready */ fd1 = creat(trace, 4); /* create tracking file */ track(pbuf); /* initialize with pid */ if(!(access(lock, 0))) checkout(lock,1); /* remove old lock if any */ if ((pterm = open( port, 2 )) < 0) { sprintf( buf, "%s: cannot open port %s\n",prg, port ); conprint(60); } xlucent( pterm, &targ ); /* make port translucent */ ioctl( pterm, TCFLSH, 2 ); sprintf(buf, "chown uucp %s", port ); system(buf); /* give ownership */ fd = open( "/etc/utmp", 2); /* clear last who */ while( read(fd, buf2, 8) ) { if (!(strcmp(buf2, argv[4]))) { write(fd, nuls, 8); break; } else lseek(fd, offset, 1); } close(fd); while(wait_on_CR( pterm )) intread(); /* wait for connect request */ while(inithookup) { parent = getpid(); /* get id of this process */ if ((child = fork()) == 0) { sleep(5); exit(0); /* child holds line open */ } else { if (inithookup) { inithookup = 0; /* hookup is done */ execl("/etc/getty", "getty", optt, optn, device, speed, 0); } } } return(0); } /*** end main ***/ /*** ---Wait for input; determine direction of line.--- Listen for incoming character other than null. If a lock file already exists the line is outgoing. While lock exists sleep 20 sec; when gone die. If no lock exists line is incoming; exec getty. ***/ wait_on_CR( term ) int term; { char c,k=CR; track("listen"); while (1) { if (read( term, &c, 1 ) <= 0) /* get a character from unix */ { c = '\0'; return (1); /* interrupt returned */ } if (( c == k )) { if (!(access(lock, 0))) checkout(lock,2); mask = umask(0); /* change mask */ lockfd = creat( lock, 0444 ); /* create the lock file */ umask(mask); /* restore mask */ if ( lockfd < 0) { sprintf(buf, "%s: cannot create lock %s\n",prg, device); conprint(60); } write( lockfd, pbuf, (unsigned)strlen(pbuf) ); close( lockfd ); track("incoming"); return(0); } k=c; signal( SIGHUP, hangup ); /* 01 watch for hangups */ ioctl( pterm, TCFLSH, 2 ); } } /*** Read lockfile for pid; set hangup pointer; see if lock active. If lock inactive unlink it if first time here and die. else wait on outgoing lock to release before dying. ***/ checkout(latch,n) char *latch, n; { dbf = fopen(latch, "r"); fgets(buf, 20, dbf); fclose(dbf); if(!(strcmp(pbuf, buf))) {track("selflock"); hangup();} sprintf(buf+10, " >/dev/null"); /* remove \n */ sprintf(cbuf, "ps -p%s", buf ); if( n == 1 ) sleep(2); r=system(cbuf); if( r == 0) { track("outgoing"); signal(SIGHUP, hangup);/* 01 watch for hangups */ while( (r=system(cbuf)) == 0 ) sleep(20); conprint(0); } else track("idle"); } intread() /*** track Interrupted Read; die if here too often.. ***/ { track("IR-"); if ( ++i > 40 ) hangup(); } !SYSV end System V version of argetty.c Xenix version: application uugin is automatically invoked by Xenix. Edit the file /etc/gettydefs and create a new line like this: R # B9600 CS8 SANE ICANON TAB3 IXANY # B9600 CS8 SANE TAB3 IXANY #..login: # R # AUTO /etc/uugin The above line should be entered as one continuous line even though it will wrap around. The letter 'R' is just an example. Edit the file /etc/ttys and modify the line that corresponds to the port the application 'uugin' will be run on to look like this: 1RttyA8t (example on the Zenith Z1000, a new machine) Cut xenix uugin.c here>>!Xenix static char Version[] = "@(#)/usr/src/uugin.c 1.0 11 Dec 89 - Centel"; /*********************************************** uugin: Bidirectional getty 1.0 11 Dec 89"; Z-1000 version P. Mathis ************************************************/ #include <stdio.h> #include <signal.h> #define CR 0x0D extern char * strcpy(); extern sleep(); static char port[20] = "/dev/",mtty[35] = "/usr/spool/uucp/ttyxxx/ttyxxx", Lock[35] = "/usr/spool/uucp/LCK..", cbuf[50], buf[100], pbuf[20], prg[34], *device; int parent, child, i=0, mask; int intrexit(); FILE *dbf; static int fd1, fd2, lockfd, pterm; /***... Interrupt routines ...***/ trap0() {intrexit();} trap1() {track("hang"); signal( SIGHUP, trap1 );} trap2() {track("intr(2)"); intrexit();} trap3() {track("quit(3)"); intrexit();} trap15() {track("term(15)"); intrexit();} intrexit() { conprint(0); } conprint(n) /*** Send trace msg to crfile/console. ***/ int n; { close(fd1); if(n == 0) ; else { fd2 = open("/dev/console", 1); write(fd2, buf, (unsigned)strlen(buf) ); close(fd2); } sleep(n); exit(0); } track(msg) char *msg; { sprintf(buf, "%9s\n",msg); write(fd1, buf, (unsigned)strlen(buf) ); } main( argc, argv ) int argc; char **argv; { int inithookup = 1; signal( SIGHUP, trap1 ); /* 01 watch for hangups */ signal( SIGINT, trap2 ); /* 02 watch for interrupts */ signal( SIGQUIT, trap3 ); /* 03 watch for quit */ signal( SIGTERM, trap15 ); /* 15 watch for termination */ strcpy( &prg[0], argv[0] ); if (argc < 1) { sprintf(buf, "%s: Not Enough Arguments\n", prg); conprint(60); } device = argv[1]; strcpy( &port[5], argv[1] ); /* /dev/tty?? */ strcpy( &Lock[21], argv[1] ); /* LCK..tty?? */ strcpy( &mtty[16], argv[1] ); /* ttyxxx/tty??t */ strcpy( &mtty[22], "/" ); /* ttyxxx/tty??t */ strcpy( &mtty[23], argv[1] ); /* ttyxxx/tty??t */ sprintf(pbuf, "%10d\n", (getpid()) ); /* get lockf ready */ fd1 = creat(mtty, 4); write(fd1, pbuf, 10 ); if(!(access(Lock, 0))) checkout(Lock); /* remove old lock if any */ if ((pterm = open( port, 2 )) < 0) { track("erropen"); sprintf( buf, "%s: cannot open port %s\n",prg, port ); conprint(60); } sprintf(buf, "chown uucp %s", port ); system(buf); /* give ownership */ while( wait_on_CR( pterm ) ) intread(); /* wait for connect request */ while (inithookup) { parent = getpid(); /* get id of this process */ if ((child = fork()) == 0) { sleep(5); exit(0); /* child holds line open */ } else { if (inithookup) { inithookup = 0; /* hookup is done */ sprintf(buf, "stty sane"); system(buf); execl("/etc/login", "login", 0); } } } return(0); } /*** end main ***/ wait_on_CR( term ) /*** Wait for connect message. ***/ int term; { char k, c; track("listen"); while (1) { if (read( term, &c, 1 ) <= 0) /* get a character from unix */ { k = c = '\0'; return (1); /* interrupt returned */ } if (!(access(Lock, 0))) checkout(Lock); if ( c == CR ) { if (k == CR ) { mask = umask(0); /* change mask */ lockfd = creat( Lock, 0444 ); /* create the lock file */ umask(mask); /* restore mask */ if ( lockfd < 0) { track("errlock"); sprintf(buf, "%s: cannot create lock %s\n",prg, device); conprint(60); } write( lockfd, pbuf, (unsigned)strlen(pbuf) ); close( lockfd ); track("incoming"); return(0); } } k = c; } } checkout(lock) char *lock; { dbf = fopen(lock, "r"); fgets(cbuf, 11, dbf); fclose(dbf); if ( !(strncmp(pbuf, cbuf, 10 )) ) { unlink(lock); return; } /* pid=pid */ track("outgoing"); signal( SIGHUP, trap0 ); while (!(access(Lock, 0))) sleep(20); conprint(0); } intread() /*** die if here too often ***/ { track("IR-"); if ( ++i > 40 ) trap0(); } !Xenix end uugin.c Above developed to inhibit login msg to modem/lan device until requested. This sample should give you some ideas, any comments inprovements, etc I would appreciate.