MiniUnix/usr/source/s2/mail.c
#
/* mail command usage
mail
prints your mail
mail people
sends standard input to people
*/
#define SIGINT 2
struct utmp {
char name[8];
char tty;
char pad1;
int ltime[2];
int pad2;
};
struct passwd {
char *pw_name;
char *pw_passwd;
int pw_uid;
int pw_gid;
char *pw_gecos;
char *pw_dir;
char *pw_shell;
};
char lettmp[] "/tmp/maxxxxx";
char preptmp[] "/tmp/mbxxxxx";
int pwfil;
main(argc, argv)
char **argv;
{
register me;
extern fout;
register struct passwd *p;
register char *cp;
static struct utmp ubuf;
int uf;
maketemp();
if (argc==1 || argc==2 && argv[1][0]=='-') {
printmail(argc, argv);
delexit();
}
signal(SIGINT, delexit);
fout = creat(lettmp, 0600);
if (((me=ttyn(1))!='x' || (me=ttyn(2))!='x')
&& (uf = open("/etc/utmp", 0)) > 0) {
while (read(uf, &ubuf, sizeof ubuf) == sizeof ubuf)
if (ubuf.tty == me) {
ubuf.name[8] = ' ';
close(uf);
for (cp=ubuf.name; *cp++!=' ';);
*--cp = 0;
bulkmail(argc, argv, ubuf.name);
}
}
me = getuid() & 0377;
setpw();
for (;;)
if ((p = getpwent()) && p->pw_uid == me)
bulkmail(argc, argv, p->pw_name);
fout = 1;
printf("Who are you?\n");
delexit();
}
printmail(argc, argv)
char **argv;
{
extern fin, fout;
register n, c, f;
if (fopen(".mail", &fin)>=0 && (c = getchar())) {
do {
putchar(c);
} while (c = getchar());
close(fin);
c = 'y';
if (argc<2) {
if (ttyn(0)!='x') {
printf("Save?");
fin = 0;
c = getchar();
}
} else
c = argv[1][1];
if (c=='y') {
prepend(".mail", "mbox");
printf("Saved mail in 'mbox'\n");
}
close(creat(".mail"));
} else
printf("No mail.\n");
}
bulkmail(argc, argv, from)
char **argv, *from;
{
extern fin, fout;
int tbuf[2];
register c;
fin = 0;
(&fin)[1] = 0;
time(tbuf);
printf("From %s %s", from, ctime(tbuf));
while (c = getchar())
putchar(c);
putchar('\n');
flush();
close(fout);
while (--argc > 0)
sendto(*++argv);
delexit();
}
sendto(person)
char *person;
{
static saved;
extern fout;
extern fin;
register struct passwd *p;
setpw();
while (p = getpwent()) {
if (equal(p->pw_name, person)) {
if (prepend(lettmp, cat(p->pw_dir, "/.mail"))==0)
break;
return;
}
}
fout = 1;
flush();
printf("Can't send to %s.\n", person);
if (ttyn(0)!='x' && saved==0) {
unlink("dead.letter");
saved++;
printf("Letter saved in 'dead.letter'\n");
prepend(lettmp, "dead.letter");
}
}
prepend(from, to)
char *from, *to;
{
extern int fin, fout;
fcreat(preptmp, &fout);
fopen(from, &fin);
while (putchar(getchar()));
close(fin);
fopen(to, &fin);
while (putchar(getchar()));
close(fin);
flush();
close(fout);
if (fcreat(to, &fout) < 0) {
fout = 1;
return(0);
}
fopen(preptmp, &fin);
while(putchar(getchar()));
flush();
close(fout);
close(fin);
fout = 1;
return(1);
}
setpw()
{
extern fin;
if (pwfil == 0) {
fopen("/etc/passwd", &fin);
pwfil = fin;
} else
fin = pwfil;
(&fin)[1] = 0;
seek(fin, 0, 0);
}
getpwent()
{
register char *p;
register c;
static struct passwd passwd;
static char line[100];
extern fin;
p = line;
while((c=getchar()) != '\n') {
if(c <= 0)
return(0);
if(p < line+98)
*p++ = c;
}
*p = 0;
p = line;
passwd.pw_name = p;
p = pwskip(p);
passwd.pw_passwd = p;
p = pwskip(p);
passwd.pw_uid = atoi(p);
p = pwskip(p);
passwd.pw_gid = atoi(p);
p = pwskip(p);
passwd.pw_gecos = p;
p = pwskip(p);
passwd.pw_dir = p;
p = pwskip(p);
passwd.pw_shell = p;
return(&passwd);
}
pwskip(ap)
char *ap;
{
register char *p;
p = ap;
while(*p != ':') {
if(*p == 0)
return(p);
p++;
}
*p++ = 0;
return(p);
}
delexit()
{
unlink(lettmp);
unlink(preptmp);
exit(0);
}
maketemp()
{
int i, pid, d;
pid = getpid();
for (i=11; i>=7; --i) {
d = (pid&07) + '0';
lettmp[i] = d;
preptmp[i] = d;
pid =>> 3;
}
}
equal(as1, as2)
{
register char *s1, *s2;
s1 = as1;
s2 = as2;
while (*s1++ == *s2)
if (*s2++ == 0)
return(1);
return(0);
}
cat(ap1, ap2)
char *ap1, *ap2;
{
register char *p1, *p2;
static char fn[32];
p1 = ap1;
p2 = fn;
while (*p2++ = *p1++);
p2--;
p1 = ap2;
while (*p2++ = *p1++);
return(fn);
}