File:  [MW Coherent from dump] / coherent / d / etc / getty.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:37 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * Rec'd from Lauren Weinstein, 7-16-84.
 * Read a user name from a terminal.
 * Attempt to determine the proper line
 * speed and mode. Call login. This version
 * explicitly sets all sgtty and tchars values
 * to allow proper resetting of the console device.
 * 
 * Responds to explicitly set erase and kill chars,
 * and ALSO to (erase == '#') and (kill == '@').
 *
 * Compile -s -n -i
 */

#include <stdio.h>
#include <ctype.h>
#include <sgtty.h>
#if NEWTTYS
#include <sys/tty.h>
#endif
#include <sys/deftty.h>
#include <signal.h>
#include <sys/stat.h>

#define FALSE	0
#define TRUE	1

#define MAXTIME 60			/* Maximum attempt time in seconds */
#define	NTYPE	(sizeof stypes/sizeof stypes[0])
#define	GMODE	(ECHO|XTABS|CRT|CRMOD)
#define	LA36M	GMODE			/* Should have LA36 delays w/a */
#define	MAXNAME	50			/* Maximum characters in a name */
#define	LOGMSG	"/etc/logmsg"		/* alternate login msg file */

char	defm[] = "\n\r\7Coherent login: "; /* default login prompt */

int	xflags;				/* Extra flags to set */
char	remote = FALSE;			/* TRUE for remote tty line */
int 	timeout();			/* forward declaration */

/*
 * Structure for each speed table.
 * The 's_nindex' entry is the next
 * indent in the current table to
 * use (for fixed-speed entries, it
 * should be always 0).
 */
struct	stable	{
	char	s_nindex;
	int	s_mode;
	char	s_ispeed;
	char	s_ospeed;
	char	*s_lmsg;
};

/*
 * Fixed-speed tables.
 */
struct	stable	sA[] = {0, GMODE, B50, B50, defm};
struct	stable	sB[] = {0, GMODE, B75, B75, defm};
struct	stable	sC[] = {0, GMODE, B110, B110, defm};
struct	stable	sD[] = {0, GMODE, B134, B134, defm};
struct	stable	sE[] = {0, GMODE, B150, B150, defm};
struct	stable	sF[] = {0, GMODE, B200, B200, defm};
struct	stable	sG[] = {0, GMODE, B300, B300, defm};
struct	stable	sH[] = {0, GMODE, B600, B600, defm};
struct	stable	sI[] = {0, GMODE, B1200, B1200, defm};
struct	stable	sJ[] = {0, GMODE, B1800, B1800, defm};
struct	stable	sK[] = {0, GMODE, B2000, B2000, defm};
struct	stable	sL[] = {0, GMODE, B2400, B2400, defm};
struct	stable	sM[] = {0, GMODE, B3600, B3600, defm};
struct	stable	sN[] = {0, GMODE, B4800, B4800, defm};
struct	stable	sO[] = {0, GMODE, B7200, B7200, defm};
struct	stable	sP[] = {0, GMODE, B9600, B9600, defm};
struct	stable	sQ[] = {0, GMODE, B19200, B19200, defm};
struct	stable	sR[] = {0, GMODE, EXTA, EXTA, defm};
struct	stable	sS[] = {0, GMODE, EXTB, EXTB, defm};

/*
 * Variable-speed tables.
 */
struct	stable	sdash[] = {	/* TTY 33 */
	0,	GMODE,	B110,	B110,	defm
};

struct	stable	s0[] = {	/* Default--various terminals */
	1,	GMODE,	B300,	B300,	defm,
	2,	GMODE,	B1200,	B1200,	defm,
	3,	GMODE,	B150,	B150,	defm,
	0,	GMODE,	B110,	B110,	defm
};

struct	stable	s1[] = {	/* 150 baud TTY 37 */
	0,	GMODE,	B150,	B150,	defm
};

struct	stable	s2[] = {	/* 9600 baud - Tek 4104 */
	0,	GMODE,	B9600,	B9600,	defm
};

struct	stable	s3[] = {	/* v22.bis & 212 datasets (2400,1200,300) */
	1,	GMODE,	B2400,	B2400,	defm,
	2,	GMODE,	B1200,	B1200,	defm,
	0,	GMODE,	B300,	B300,	defm
};

struct	stable	s5[] = {	/* Reverse of 's3' */
	1,	GMODE,	B300,	B300,	defm,
	0,	GMODE,	B1200,	B1200,	defm
};

struct	stable	s4[] = {	/* LA36 (needs its delays) */
	0,	LA36M,	B300,	B300,	defm
};

struct  stable  s9[] = {	/* 212 with auto speed select via CTS */
	1,	GMODE,	B1200,	B1200,	defm,  /* 1200 */
	2,	GMODE,  B300,	B300,	defm,  /* then 300 */
	0,	GMODE,	B110, 	B110,	defm   /* then 110 */
};

/*
 * This table is used to map
 * a speed character argument, passed
 * to "getty" from "init", into a speed
 * table base.
 */
struct	stypes	{
	int	s_name;
	struct	stable	*s_ptr;
}	stypes[] = {
	'-',	sdash,
	'0',	s0,
	'1',	s1,
	'2',	s2,
	'3',	s3,
	'4',	s4,
	'5',	s5,
	'9',	s9,	/* 212 with auto speed select */
	'A',	sA,
	'B',	sB,
	'C',	sC,
	'D',	sD,
	'E',	sE,
	'F',	sF,
	'G',	sG,
	'H',	sH,
	'I',	sI,
	'J',	sJ,
	'K',	sK,
	'L',	sL,
	'M',	sM,
	'N',	sN,
	'O',	sO,
	'P',	sP,
	'Q',	sQ,
	'R',	sR,
	'S',	sS
};

/*
 * Default sgtty and tchars settings.
 */

struct	sgttyb	defsgt = {		/* Initial sgtty */
	DEF_SG_ISPEED,
	DEF_SG_OSPEED,
	DEF_SG_ERASE,
	DEF_SG_KILL,
	DEF_SG_FLAGS
};
	
struct	tchars	deftch = {		/* Initial tchars */
	DEF_T_INTRC,
	DEF_T_QUITC,
	DEF_T_STARTC,
	DEF_T_STOPC,
	DEF_T_EOFC,
	DEF_T_BRKC
};


main(argc, argv)
char *argv[];
{
	register struct stable	*sp;
	register struct stable	*stpp;
	register struct stypes  *stp;
	register int index;
	char name[MAXNAME];
	char *ttyn;	/* pointer to current tty name */
	extern char *ttyname();

	if (argc != 2) {
		write(1, "Usage: /etc/getty baudtype\r\n", 28);
		slexit(1);		  /* error exit */
	}

	signal(SIGINT, SIG_IGN);	  /* ignore int and quit */
	signal(SIGQUIT, SIG_IGN);

	if ((ttyn = ttyname(1)) == NULL)  /* get current tty name */
	{  write(1, "getty: can't get tty name!\r\n", 28);
	   slexit(1);  /* error exit */
	}
	if (chmod(ttyn, 04000) < 0)  /* setuid bit to indicate line in use */
	{  write(1, "getty: can't chmod!\r\n", 21);
	   slexit(1);  /* error exit */
 	}

#if NEWTTYS
	if (argv[0][0] == '-' && argv[0][1] == 'r') {
		remote = TRUE;
		signal(SIGALRM, &timeout);     /* catch alarm timeouts */
		alarm(MAXTIME);		  /* timeout interval */
	}
#endif

	stpp = s0;
	if (argc > 1) {
		for (stp = stypes; stp < &stypes[NTYPE]; stp++)
			if (*argv[1] == stp->s_name) {
				stpp = stp->s_ptr;
				break;
			}
	}
	for (index=0; ; index=sp->s_nindex) {
		sp = &stpp[index];
		xflags = 0;
		/* a '9' indicates autospeed mode for first index only */
		dostty(sp, RAW, 0, (index == 0 && stp->s_name == '9'));
		if (readname(name, sp) != 0)
			break;
	}
#if NEWTTYS
	alarm(0);  /* turn off login alarm timeout */
#endif
	dostty(sp, 0, RAW, 0);		/* set sgtty modes */
	ioctl(1, TIOCSETC, &deftch);	/* set tchars modes */
	execl("/bin/login", (remote) ? "-r" : "-", name, NULL);
	slexit(1);
}

/*
 * Do a "stty" on the terminal.
 * The erase and kill characters come
 * from the defaults in "defsgt".
 * The speeds and the basic mode come
 * from the "stable" pointed to by
 * "sp". The "on" and "off" masks
 * change the modes.
 * If "automode" is non-zero, 212 auto speed
 * mode has been selected.
 */
dostty(stabp, on, off, automode)
register struct stable *stabp;
{
#if NEWTTYS
	unsigned msr;

	if (automode) 		               /* 212 auto speed mode? */
	   if (ioctl(1, TIOCRMSR, &msr) == 0)  /* get modem status register */
	      stabp->s_ispeed = stabp->s_ospeed 
	         = ((msr & MSRCTS) ? B1200 : B300);  /* CTS high means 1200 */  
#endif

	defsgt.sg_ispeed = stabp->s_ispeed;
	defsgt.sg_ospeed = stabp->s_ospeed;
	defsgt.sg_flags  = stabp->s_mode;
	defsgt.sg_flags |= xflags|on;
	defsgt.sg_flags &= ~off;
	ioctl(1, TIOCSETP, &defsgt);	      /* set modes */
}

/*
 * Read a name from the terminal.
 * Return true if you get a name, or false
 * if the speed should be cycled. Use the
 * editing characters from the initial
 * defaults.
 */
readname(s, sp)
char	*s;
struct	stable	*sp;
{
	register char	*cp;
	register int	c;
	register int	seenupper;
	register int	seenlower;
	FILE		*msgfp;
	char		last;

loop:
	seenlower = 0;
	seenupper = 0;
	xflags  = 0;
	if ((msgfp = fopen(LOGMSG, "r")) != NULL) {
		/* Read from login message file. */
		for (last = '\n'; (c = fgetc(msgfp)) != EOF; last = c) {
			if (last == '\n')
				write(1, "\r", 1);
			write(1, &last, 1);
		}
		if (last != '\n')
			write(1, &last, 1);
		fclose(msgfp);
	} else   
		write(1, sp->s_lmsg, strlen(sp->s_lmsg));  /* use standard msg */

	cp = s;
	for (;;) {
		if ((c = getchar() & 0x7F) == 0) 
	   	   return(0);    	      /* break advances speed table */
		if (c==' ' || c=='\t' || c=='\f')
		   continue;                  /* ignore this char */
		if (c == deftch.t_eofc)      /* EOF returns to init */
		   slexit(1);		
		if (c == defsgt.sg_kill || c == '@')  /* kill this line */
		{	write(1, "\r\n", 2);
			seenupper = seenlower = 0;
			xflags = 0;
			cp = s;
			continue;
		}
		if (c == defsgt.sg_erase || c == '#')  /* erase this char */
		{	if (sp != s)
			   --cp;
			continue;
		}
		if (c == '\n') 
		{	putchar('\r');
			break;
		}
		if (c == '\r')
		{	putchar('\n');
			xflags |= CRMOD;
			break;
		}
		if (isupper(c))
			seenupper = 1;
		else if (islower(c))
			seenlower = 1;
		if (cp < s+MAXNAME)
			*cp++ = c;
	}
	if (cp == s)
		goto loop;
	*cp = 0;
	if (seenupper!=0 && seenlower==0) 
	{	xflags |= LCASE;
		for (cp=s; *cp!=0; ++cp) 
		{   if (isupper(*cp))
		       *cp = tolower(*cp);
		}
	}
	return(1);
}

/* login attempt timeout routine */
timeout()
{
	printf("\r\n"); 	/* neatness */
	slexit(1); 		/* terminate and try force hangup */
}

/* sleep to make sure output has flushed, then exit */
slexit(status)
{
    sleep(3);
    exit(status);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.