USG_PG3/usr/source/cmd6/write.c
#
#define ALARM 14
/*
* write to another user
*/
struct utmp
{
char name[8];
int ttyno;
int fill[3];
};
struct
{
char pad[4];
int flag;
};
char me[10] "???";
char tty[] "/dev/ln\0\0";
char *him;
int ttyno;
int mytty;
int histty;
int logcnt;
char buf[512];
int tf;
int eof();
int timout();
main(argc, argv)
char *argv[];
{
register i,k;
register struct utmp *p;
int c1, c2, uf;
struct{
char lobyte;
char hibyte;
};
if(argc < 2) {
prs(1, "usage: write user [lineno]\n");
exit(1);
}
him = argv[1];
if(argc > 2){
ttyno.lobyte = argv[2][0];
ttyno.hibyte = argv[2][1];
}
if((uf=open("/etc/utmp",0)) < 0){
prs(1, "cannot open /etc/utmp\n");
exit();
}
mytty = lnxx(1);
if(mytty.lobyte == 'x' && mytty.hibyte == 'x'){
prs(1,"nonexistent line\n");
exit();
}
while((k=read(uf,buf,512)) > 0){
for(p=buf;(k =- 16) >= 0;p++){
if(p->name[0] >= 0)continue;
p->name[0] =& ~0200;
if(mytty == p->ttyno)
for(i=0; i<8; i++) {
c1 = p->name[i];
if(c1 == ' ')c1 = 0;
me[i] = c1;
if(c1 == 0) break;
}
if(him[0] != '-' || him[1] != 0)
for(i=0; i<8; i++) {
c1 = him[i];
c2 = p->name[i];
if(c1 == 0)
if(c2 == 0 || c2 == ' ') break;
if(c1 != c2) goto loop;
}
logcnt++;
c1 = p->ttyno;
if(ttyno != 0 && ttyno != c1) continue;
if(histty == 0) histty = c1;
loop:
;
}
}
close(uf);
if(ttyno == 0 && logcnt > 1 && *him != '-')
printf("%s multiply logged in\nwriting to ln%-2.2s\n",
him,&histty);
if(histty == 0) {
prs(1, him);
if(logcnt)
prs(1, " not on that line\n");
else
prs(1, " not logged in\n");
exit(1);
}
tty[7] = histty.lobyte;
tty[8] = histty.hibyte;
signal(ALARM, timout);
alarm(5);
tf = open(tty, 1);
alarm(0);
if((tf<0) || (fstat(tf,buf)<0) ||
((buf->flag & 2) == 0 && getuid())){
prs(1,"Permission denied\n");
exit(1);
}
sigs(eof);
prs(tf, "\nMessage from ");
prs(tf, me);
write(tf," (ln",4);
write(tf,&mytty,2);
write(tf,")...\n",5);
for(;;) {
i = read(0, buf, 512);
if(i <= 0) eof();
if(buf[0] == '!') {
buf[i] = 0;
ex();
continue;
}
write(tf, buf, i);
}
}
timout()
{
prs(1, "Timeout opening his line\n");
exit(1);
}
eof()
{
prs(tf, "EOT\n");
exit(0);
}
prs(f, s)
char *s;
{
register n;
for(n=0; s[n]; n++);
write(f, s, n);
}
ex()
{
register i;
sigs(1);
i = fork();
if(i < 0) {
prs(1, "Try again\n");
sigs(eof);
}
if(i == 0) {
sigs(0);
execl("/bin/sh", "sh", "-c", buf+1, 0);
exit(0);
}
while(wait(buf) != i);
prs(1, "!\n");
}
sigs(sig)
{
register i;
for(i=1; i<4; i++) signal(i,sig);
}