[comp.dcom.modems] Telebit config Question c-code uugetty

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.