|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5864 (0x16e8)
Types: TextFile
Notes: UNIX file
Names: »getty.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/getty.c«
/*
* Read a user name from a terminal.
* Attempt to determine the proper line
* speed and mode. Call login. This version
* asks the tty for the erase and kill
* characters, so that whatever the system
* sets up in "ttopen" will be preserved.
*/
#include <stdio.h>
#include <ctype.h>
#include <sgtty.h>
#include <signal.h>
#define NTYPE (sizeof stypes/sizeof stypes[0])
#define GMODE (ECHO|XTABS|CRT)
#define LA36M GMODE /* Should have LA36 delays w/a */
#define MAXNAME 50 /* Maximum characters in a name */
char defm[] = "\n\r\7Coherent login: "; /* default login prompt */
struct sgttyb isgttyb; /* Initial stty */
struct tchars itchars; /* Initial tchars */
int xflags; /* Extra flags to set */
int intflag; /* Interrupt */
/*
* 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[] = { /* 212 datasets (1200,300,...) */
1, 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,
};
/*
* 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,
'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
};
main(argc, argv)
char *argv[];
{
register struct stable *sp;
register struct stable *stpp;
register int index;
extern int catch();
char name[MAXNAME];
ioctl(1, TIOCGETP, &isgttyb);
ioctl(1, TIOCGETC, &itchars);
signal(SIGINT, &catch);
stpp = s0;
if (argc > 1) {
register struct stypes *stp;
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;
dostty(sp, RAW, 0);
if (readname(name, sp) != 0)
break;
}
dostty(sp, 0, RAW);
execl("/bin/login", "-", name, NULL);
exit(1);
}
/*
* Do a "stty" on the terminal.
* The erase and kill characters come
* from the defaults in "isgttyb".
* The speeds and the basic mode come
* from the "stable" pointed to by
* "sp". The "on" and "off" masks
* change the modes.
*/
dostty(stabp, on, off)
register struct stable *stabp;
{
struct sgttyb sgttyb;
sgttyb.sg_ispeed = stabp->s_ispeed;
sgttyb.sg_ospeed = stabp->s_ospeed;
sgttyb.sg_erase = isgttyb.sg_erase;
sgttyb.sg_kill = isgttyb.sg_kill;
sgttyb.sg_flags = stabp->s_mode;
sgttyb.sg_flags |= xflags|on;
sgttyb.sg_flags &= ~off;
ioctl(1, TIOCSETP, &sgttyb);
}
/*
* 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;
loop:
seenlower = 0;
seenupper = 0;
intflag = 0;
xflags = 0;
write(1, sp->s_lmsg, strlen(sp->s_lmsg));
cp = s;
for (;;) {
if ((c=getchar()&0x7F)==0 || c==itchars.t_intrc)
return (0);
if (intflag != 0) {
intflag = 0;
return (0);
}
if (cp==s && c==itchars.t_eofc)
return (0);
if (c==' ' || c=='\t' || c=='\f')
continue;
if (c == isgttyb.sg_kill) {
write(1, "\r\n", 2);
seenlower = 0;
seenupper = 0;
xflags = 0;
cp = s;
continue;
}
if (c == isgttyb.sg_erase) {
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);
}
/*
* Set a flag on interrupt.
*/
catch()
{
intflag = 1;
}