static char SccsId
[] = "@(#)mail.c 4.1 10/1/80";
#define DELIVERMAIL "/etc/delivermail"
/*remote mail, add rmtmsg */
/* zap header and trailing empty line */
#define MAXLET 300 /* maximum number of letters */
#define MAILMODE (~0644) /* mode of created mail */
#define RMAIL "/usr/net/bin/sendberkmail"
char lettmp
[] = "/tmp/maXXXXX";
char maildir
[] = "/usr/spool/mail/";
char mailfile
[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char dead
[] = "dead.letter";
char forwmsg
[] = " forwarded\n";
struct passwd
*getpwuid();
if (my_name
== NULL
|| strlen(my_name
) == 0) {
pwent
= getpwuid(getuid());
my_name
= pwent
->pw_name
;
if(setjmp(sjbuf
)) done();
tmpf
= fopen(lettmp
, "w");
fprintf(stderr
, "mail: cannot open %s for writing\n", lettmp
);
if (argv
[0][0] != 'r' && /* no favors for rmail*/
(argc
== 1 || argv
[1][0] == '-' && !any(argv
[1][1], "rhd")))
if(signal(i
, SIG_IGN
)!=SIG_IGN
)
cat(mailfile
, maildir
, my_name
);
if (stat(mailfile
, &statb
) >= 0
&& (statb
.st_mode
& S_IFMT
) == S_IFDIR
) {
strcat(mailfile
, my_name
);
for (; argc
>1; argv
++, argc
--) {
else if (argv
[1][1]=='p') {
} else if (argv
[1][1]=='f') {
strcpy(mailfile
, argv
[2]);
} else if (argv
[1][1]=='r') {
} else if (argv
[1][1]=='h') {
fprintf(stderr
, "mail: unknown option %c\n", argv
[1][1]);
malf
= fopen(mailfile
, "r");
fprintf(stdout
, "No mail.\n");
tmpf
= fopen(lettmp
, "r");
for (i
= 0; i
< nlet
; ) {
j
= forward
? i
: nlet
- i
- 1;
copylet(j
, stdout
, ORDINARY
);
if (fgets(resp
, LSIZE
, stdin
) == NULL
)
fprintf(stderr
, "usage\n");
fprintf(stderr
, "q\tquit\n");
fprintf(stderr
, "x\texit without changing mail\n");
fprintf(stderr
, "p\tprint\n");
fprintf(stderr
, "s[file]\tsave (default mbox)\n");
fprintf(stderr
, "w[file]\tsame without header\n");
fprintf(stderr
, "-\tprint previous\n");
fprintf(stderr
, "d\tdelete\n");
fprintf(stderr
, "+\tnext (no delete)\n");
fprintf(stderr
, "m user\tmail to user\n");
fprintf(stderr
, "! cmd\texecute cmd\n");
if (resp
[1] != '\n' && resp
[1] != ' ') {
if (resp
[1] == '\n' || resp
[1] == '\0') {
for (p
= resp
+1; (p
= getarg(lfil
, p
)) != NULL
; ) {
fprintf(stdout
, "mail: cannot append to %s\n", lfil
);
copylet(j
, malf
, resp
[0]=='w'? ZAP
: ORDINARY
);
if (resp
[1] == '\n' || resp
[1] == '\0') {
printf("invalid command\n");
for (p
= resp
+1; (p
= getarg(lfil
, p
)) != NULL
; )
if (!sendrmt(j
, lfil
, "/bin/mail")) /* couldn't send it */
copyback() /* copy temp or whatever back to /usr/spool/mail */
signal(SIGQUIT
, SIG_IGN
);
if (stbuf
.st_size
!= let
[nlet
].adr
) { /* new mail has arrived */
malf
= fopen(mailfile
, "r");
fprintf(stdout
, "mail: can't re-read %s\n", mailfile
);
fseek(malf
, let
[nlet
].adr
, 0);
tmpf
= fopen(lettmp
, "a");
fseek(tmpf
, let
[nlet
].adr
, 0);
while ((c
= fgetc(malf
)) != EOF
)
tmpf
= fopen(lettmp
, "r");
let
[++nlet
].adr
= stbuf
.st_size
;
malf
= fopen(mailfile
, "w");
fprintf(stderr
, "mail: can't rewrite %s\n", lfil
);
for (i
= 0; i
< nlet
; i
++)
if (let
[i
].change
!= 'd') {
copylet(i
, malf
, ORDINARY
);
fprintf(stdout
, "new mail arrived\n");
copymt(f1
, f2
) /* copy mail (f1) to temp (f2) */
while (fgets(line
, LSIZE
, f1
) != NULL
) {
let
[nlet
++].adr
= nextadr
;
let
[nlet
].adr
= nextadr
; /* last plus 1 */
copylet(n
, f
, type
) FILE *f
;
fseek(tmpf
, let
[n
].adr
, 0);
k
= let
[n
+1].adr
- let
[n
].adr
;
while(k
-- > 1 && (ch
=fgetc(tmpf
))!='\n')
if(type
!=ZAP
) fputc(ch
,f
);
fprintf(f
, " remote from %s\n", thissys
);
fputc(ch
=fgetc(tmpf
), f
);
if(type
!=ZAP
|| ch
!= '\n')
fprintf(stderr
, "puke\n");
for (vp
= argv
, ap
= newargv
+ 1; (*ap
= *vp
++) != 0; ap
++)
if (ap
[0][0] == '-' && ap
[0][1] == 'd')
/* give it to delivermail, rah rah! */
* When we fall out of this, argv[1] should be first name,
* argc should be number of names + 1.
while (argc
> 1 && *argv
[1] == '-') {
strcpy(truename
, argv
[1]);
fgets(line
, LSIZE
, stdin
);
if (strcmpn("From", line
, 4) == 0)
strcpy(truename
, my_name
);
if (argc > 4 && strcmp(argv[1], "-r") == 0) {
strcpy(truename, argv[2]);
fgets(line, LSIZE, stdin);
if (strcmpn("From", line, 4) == 0)
strcpy(truename, my_name);
fprintf(tmpf
, "%s%s %s", from
, truename
, ctime(&iop
));
for (first
= 1;; first
= 0) {
if (first
&& line
[0] == '\0' && fgets(line
, LSIZE
, stdin
) == NULL
)
if (!first
&& fgets(line
, LSIZE
, stdin
) == NULL
)
if (line
[0] == '.' && line
[1] == '\n' && isatty(fileno(stdin
)))
let
[1].adr
= ftell(tmpf
);
tmpf
= fopen(lettmp
, "r");
fprintf(stderr
, "mail: cannot reopen %s for reading\n", lettmp
);
if (!send(0, *++argv
, truename
))
fprintf(stdout
, "mail: cannot open %s\n", dead
);
fprintf(stdout
, "Mail saved in %s\n", dead
);
while (p
= index(name
, '^'))
if (strncmp(name
, "researc", 7)) {
strcpy(rsys
, "research");
for(p
=rsys
; *name
!='!'; *p
++ = *name
++)
if ((!local
&& *name
=='\0') || (local
&& *rsys
=='\0')) {
fprintf(stdout
, "null name\n");
if ((pid
= fork()) == -1) {
fprintf(stderr
, "mail: can't create proc for remote\n");
while (wait(&sts
) != pid
) {
sprintf(cmd
, "%s %s", rcmd
, rsys
);
sprintf(cmd
, "uux - %s!rmail \\(%s\\)", rsys
, name
+1);
sprintf(cmd
, "uux - %s!rmail %s", rsys
, name
+1);
if ((rmf
=popen(cmd
, "w")) == NULL
)
copylet(n
, rmf
, local
? !strcmp(rcmd
, "/bin/mail") ? FORWARD
: ORDINARY
: REMOTE
);
* Send mail on the Berkeley network.
* Sorry Bill, sendrmt() is so awful we just gave up.
sendberkmail(n
, name
, fromaddr
)
sprintf(cmd
, "%s -h %d -f %s -t %s", RMAIL
, hseqno
, fromaddr
, name
);
if ((cmdf
= popen(cmd
, "w")) == NULL
) {
copylet(n
, cmdf
, ORDINARY
);
fprintf(stderr
, "Usage: mail [ -f ] people . . .\n");
struct passwd
*pw
, *getpwnam();
if(*name
== ':')name
++; /* skip colon in to-name */
for(p
=name
; *p
!=':' && *p
!='!' && *p
!='^' &&*p
!='\0'; p
++);
/* if(*p == ':') return(sendrmt(n, name, RMAIL)); */
return(sendberkmail(n
, name
, fromaddr
));
else if (*p
=='\0' && strcmp(name
, "msgs") == 0)
return(sendrmt(n
, "-s", "/usr/ucb/msgs"));
for(p
=name
; *p
!='!'&&*p
!='^' &&*p
!='\0'; p
++)
return(sendrmt(n
, name
, 0));
if ((pw
= getpwnam(name
)) == NULL
) {
fprintf(stdout
, "mail: can't send to %s\n", name
);
cat(file
, maildir
, name
);
if (stat(file
, &statb
) >= 0 && (statb
.st_mode
& S_IFMT
) == S_IFDIR
) {
fprintf(stdout
, "mail: cannot append to %s\n", file
);
chown(file
, pw
->pw_uid
, pw
->pw_gid
);
copylet(n
, malf
, ORDINARY
);
* Lock the specified mail file by setting the file mailfile.lock.
* We must, of course, be careful to unlink the lock file by a call
* to unlock before we stop. The algorithm used here is to see if
* the lock exists, and if it does, to check its modify time. If it
* is older than 30 seconds, we assume error and set our own file.
* Otherwise, we wait for 5 seconds and try again.
char *maillock
= ".lock"; /* Lock suffix for mailname */
char *lockname
= "/usr/spool/mail/tmXXXXXX";
char locktmp
[30]; /* Usable lock temporary */
char curlock
[50]; /* Last used name of lock */
int locked
; /* To note that we locked it */
strcat(curlock
, maillock
);
strcpy(locktmp
, lockname
);
f
= lock1(locktmp
, curlock
);
if (stat(curlock
, &sbuf
) < 0) {
if (curtime
< sbuf
.st_ctime
+ 30) {
* Remove the mail lock, and note that we no longer
* Attempt to set the lock by creating the temporary file,
* then doing a link/unlink. If it fails, return -1 else 0
if (link(tempfile
, name
) < 0) {
char *to
, *from1
, *from2
;
char *getarg(s
, p
) /* copy p... into s, update p */
while (*p
== ' ' || *p
== '\t')
if (*p
== '\n' || *p
== '\0')
while (*p
!= ' ' && *p
!= '\t' && *p
!= '\n' && *p
!= '\0')
stripfx(prefix string, pointer to string)
takes a ptr to string and compares it to prefix string.
may be called multiple times
register char *cp
= *name
;
while (*pfx
&& (*cp
== *pfx
|| *cp
== toupper(*pfx
)))
if (*cp
!= ':' || *pfx
!= 0)