# /* send_local.c * * This file contains the routines concerned with mailing a file to * a local user. The routines contained are: * send_local copy mail file to end of user's mailbox * get_mbox find out name of user's mailbox * findlocal get local user's home directory * cre_mbox create a mailbox for a user if needed * getpwchar get characters from the password file */ #include #include "rqfile.h" #include "extern.h" #include "tcode.h" #include "init_rec.h" send_local (mlfile, rqp, uname) /* Send the specified mail file to the specified user. Find the name * of the user's mailbox, and append the contents of the mail file to * it. If no such user, try for a distribution list. Returns: * TOK on success * TACESS if unable to access a file * TNOUSR if the specified user doesn't exist * TDSTRB if the mail is sent to a distribution list * TFRWD if the mail is to be forwarded * * Arguments: */ char *mlfile; /* name of file containing mail */ register struct req_rec *rqp; /* ptr. to request record */ char *uname; /* name of dest. user */ { int status; /* return status of get_mbox */ register int sz; /* size of block read */ int mlfd; /* mail file descriptor */ int mbfd; /* mailbox file descriptor */ char mailbox[NAMSIZ]; /* user's mailbox file name */ char buffer[BIGBUF]; /* buffer for copy */ if ((status = get_mbox (uname, mailbox)) != TOK && status != TFRWRD) return (send_distrib (mlfile, rqp, uname)); if (status == TFRWRD) { strcpy (rqp->rq_name, mailbox); rqp->rq_retries = RETRIES + 1; return (TFRWRD); } if ((mlfd = open (mlfile, 0)) < 0) return (TACESS); if ((mbfd = open (mailbox, 1)) < 0) return (TACESS); seek (mbfd, 0, 2); /* seek to end of mailbox */ write (mbfd, MSGSEP, MSGSEPL); /* write message separators */ while ((sz = read (mlfd, buffer, BIGBUF)) > 0) write (mbfd, buffer, sz); write (mbfd, MSGSEP, MSGSEPL); close (mbfd); close (mlfd); return (TOK); } get_mbox (uname, mailbox) /* Look up the user in the password file; if he exists, try to open * his .mail.init file. If success, get the mailbox name from there * (if the .mail.init file specifies forwarding, get the forward-to * name and return TFRWRD instead). If no .mail.init file, use the * default mailbox name. If no such user exists, presently craps * out; it will try to open a distribution file with that name. * Returns the mailbox (or forward-to) name in mailbox. * Returns: * TOK if successful * TACESS if unable to access a file * TNOUSR if the specified user doesn't exist * TFRWRD if the mail is to be forwarded (and the name of the * person to whom it is to go, in mailbox) * * Arguments: */ char *uname; /* name of destination user */ char *mailbox; /* string to get mailbox name */ { struct inode statb; /* buffer for stat call */ struct init_rec inir; /* user's .mail.init record */ char innam[NAMSIZ]; /* name of user's .mail.init file */ int infd; /* .mail.init file descriptor */ register char *p; /* temp pointer */ for (p = &uname[strlen (uname) - 1]; (p > uname) && (*p == ' '); p--) *p = '\0'; /* trim off trailing blanks in name */ if (getpwent (uname, mailbox) == 0) return (TNOUSR); strcpy (innam, mailbox); strcat (innam, "/"); strcat (innam, INITFILE); if ((infd = open (innam, 0)) < 0) strcat (mailbox, mboxname); /* add "/.mail" to get name */ else { /* found init file; get mbox name */ read (infd, &inir, sizeof (inir)); close (infd); if (inir.in_frwrd) { /* user request mail forwarding? */ if (strcmp (uname, inir.in_mail) == 0) /* loop? */ return (TACESS); /* yes, error */ strcpy (mailbox, inir.in_mail); /* no */ return (TFRWRD); } else { strcat (mailbox, "/"); strcat (mailbox, inir.in_mail); /* no; get mbox name */ } } if (stat (mailbox, &statb) < 0) return (cre_mbox (uname)); return (TOK); } cre_mbox (uname) /* Fork program to create a mailbox for the user. It's a separate * program because it must run as superuser, and we want to minimize * privileged code. * Returns TOK on success, TACESS if unable to create the mailbox, or * TUNDEF if unable to fork (this will cause the mail daemon to try * again next time around). * * Arguments: */ char *uname; /* dest. user name */ { register int pid; /* subprocess id */ int status; /* subprocess return status */ register int i; /* temp index */ register int waitpid; /* pid of waited-for child */ if ((pid = fork ()) == -1) { printf ("maild: can't fork for mailbox create\n"); return (TUNDEF); } else if (pid == 0) { for (i = 0; i < MAXFILES; i++) close (i); execl ("/bin/creat_mbox", "/bin/creat_mbox", uname, 0); } while ((waitpid = wait (&status)) != pid && waitpid != -1); return (status == 0 ? TOK : TACESS); }