USG_PG3/usr/source/cmd3/login.c
#
/*
* login [ name ]
*/
struct utmp {
char name[8];
int line;
int time[2];
int pid;
} utmp;
struct {
int regs[2];
int tflags;
} ttyb;
struct {
int junk[5];
int size;
int more[12];
} statb;
int cbuf[256];
char *ttyx;
char zero[16];
char *utmpf "/etc/utmp";
char *wtmpf "/etc/wtmp";
int lid;
#define ECHO 010
main(argc, argv)
char **argv;
{
register struct utmp *p;
register char *namep,*np;
char pbuf[128];
char pwbuf[9];
int f, c, uid;
struct{
char lobyte;
char hibyte;
};
signal(3, 1);
signal(2, 1);
ttyx = "/dev/ln\0\0";
lid = lnxx(0);
if(lid.lobyte == 'x' && lid.hibyte == 'x'){
write(1, "Sorry.\n", 7);
exit(-1);
}
ttyx[7] = lid.lobyte;
ttyx[8] = lid.hibyte;
loop:
namep = utmp.name;
if (argc>1) {
np = argv[1];
while (namep<utmp.name+8 && *np)
*namep++ = *np++;
argc = 0;
} else {
write(1, "Name: ", 7);
while ((c = getchar()) != '\n') {
if (c==0)
exit(-1);
if (namep < utmp.name+8)
*namep++ = c;
}
}
while (namep < utmp.name+8)
*namep++ = ' ';
if (getpwentry(utmp.name, pbuf))
goto bad;
np = colon(pbuf);
if (*np!=':') {
gtty(0, &ttyb);
f = ttyb.tflags;
ttyb.tflags =& ~ ECHO;
stty(0, &ttyb);
write(1, "Password: ", 10);
namep = pwbuf;
while ((c=getchar()) != '\n') {
if (c==0)
exit(-1);
if (namep<pwbuf+8)
*namep++ = c;
}
*namep++ = '\0';
ttyb.tflags = f;
stty(0, &ttyb);
write(1, "\n", 1);
namep = crypt(pwbuf);
while (*namep++ == *np++);
if (*--namep!='\0' || *--np!=':')
goto bad;
}
np = colon(np);
uid = 0;
while (*np != ':')
uid = uid*10 + *np++ - '0';
np++;
np = colon(np);
namep = np;
np = colon(np);
if (chdir(namep)<0) {
write(1, "No directory\n", 13);
goto loop;
}
lnacctg();
if ((f = open("/etc/motd", 0)) >= 0) {
while(read(f, &c, 1) > 0)
write(1, &c, 1);
close(f);
}
if (stat(".mail", &statb) >= 0 && statb.size)
write(1, "You have mail.\n", 15);
chown(ttyx, uid);
setgid(1);
setuid(uid);
if (*np == '\0')
np = "/bin/sh";
execl(np, "-", 0);
write(1, "No shell.\n", 9);
exit(-1);
bad:
write(1, "Login incorrect.\n", 17);
goto loop;
}
getpwentry(name, buf)
char *name, *buf;
{
extern fin;
int fi, r, c;
register char *gnp, *rnp;
fi = fin;
r = 1;
if((fin = open("/etc/passwd", 0)) < 0)
goto ret;
loop:
gnp = name;
rnp = buf;
while((c=getchar()) != '\n') {
if(c == '\0')
goto ret;
*rnp++ = c;
}
*rnp++ = '\0';
rnp = buf;
while (*gnp++ == *rnp++);
if ((*--gnp!=' ' && gnp<name+8) || *--rnp!=':')
goto loop;
r = 0;
ret:
close(fin);
fin = 0;
(&fin)[1] = 0;
(&fin)[2] = 0;
return(r);
}
colon(p)
char *p;
{
register char *rp;
rp = p;
while (*rp != ':') {
if (*rp++ == '\0') {
write(1, "Bad /etc/passwd\n", 16);
exit(-1);
}
}
*rp++ = '\0';
return(rp);
}
/*
* Login presumes that an entry(in utmp) with the
* activated line already exists. Thus its accounting
* procedure merely searches for a matching line id and
* stamps a new time into the time field.
*/
lnacctg()
{
register struct utmp *p;
register rw,k;
if((rw=open(utmpf,2)) < 0) return;
while((k=read(rw,&cbuf,512)) > 0) {
for(p = &cbuf; (k =- 16) >= 0; p++){
if(p->line != lid) continue;
utmp.name[0] =| 0200; /*line process*/
utmp.line = p->line;
time(utmp.time);
utmp.pid = p->pid;
seek(rw,-(k+16),1); /*relative offset from end*/
write(rw,&utmp,16);
close(rw);
if ((rw = open(wtmpf, 1)) >= 0) {
seek(rw, 0, 2);
write(rw, &utmp, 16);
close(rw);
}
return;
}
}
}