282 lines
4.1 KiB
C
282 lines
4.1 KiB
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);
|
|
}
|