Annotation of coherent/d/bin/mail/usermail/send.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     The code that passes an individual message to the mail system.
                      3:  */
                      4: 
                      5: #include "mail.h"
                      6: 
                      7: #define SITENAMELEN    32      /* max length of sitename */
                      8: #define NODENAME       "/etc/uucpname"
                      9: #define DOMAINNAME     "/etc/domain"
                     10: char   domain [64];
                     11: 
                     12: extern char    *strtok();
                     13: static char    **allist;
                     14: static char    **tolist;
                     15: static char    **cclist = NULL;
                     16: 
                     17: char   mysite[SITENAMELEN];    /* this host's uucpname */
                     18: 
                     19: extern char    *temp;
                     20: extern int     myuid;          /* User-id of mail user */
                     21: extern int     mygid;          /* Group-id of mail user */
                     22: extern char    cmdname[];      /* Command for x{en,de}code filter */
                     23:                                /* and for tail recursion to uumail */
                     24:                                /* and for editor recursion */
                     25: extern char    *editname;      /* name of editor          */
                     26: extern char    *askcc;         /* Ask for CC: list? (YES/NO) */
                     27: extern int     callmexmail;    /* Xmail modifier present */
                     28: extern char    wrerr[];
                     29: extern char    myname[];       /* User name */
                     30: extern char    myfullname[];   /* full user name */
                     31: extern int     mflag;          /* `You have mail.' message to recipient */
                     32: extern int     verbflag;       /* verbose flag */
                     33: extern char    templ[];        /* Temp file name template */
                     34: extern char    mydead[];       /* $HOME/dead.letter */
                     35: extern char    mysig[];
                     36: extern char    nosave[];
                     37: extern int     callmermail;
                     38: 
                     39: static int     eflag;          /* Edit this mail */
                     40: static int     senderr;
                     41: struct tm      *tp;
                     42: char   toerr[] = "Cannot create temporary file\n";
                     43: char   header[BUFSIZ];         /* Message header */
                     44: char   boxname[256];           /* Destination mailbox */
                     45: char   remotefrom [32];        /* "remote from uucp" */
                     46: 
                     47: char   nosend[] = "Can't send mail to '%s'\n";
                     48: char   nopubk[] = "Can't send xmail to '%s'\n";
                     49: static int fromtty;
                     50: 
                     51: /*
                     52:  * Send the message found on
                     53:  * the file pointer to the list
                     54:  * of people (argv style) with
                     55:  * a NULL pointer at the end.
                     56:  * The message is copied to a temp-file
                     57:  * from position `start' to `end' (or EOF).
                     58:  */
                     59: send2(fp, users, start, end, asksubj)
                     60: FILE *fp;
                     61: register char **users;
                     62: fsize_t start, end;
                     63: int    asksubj;
                     64: {
                     65:        char    **getcc(), **listpp;
                     66:        FILE    *xfp, *tfp, *sigfp;
                     67:        time_t  curtime;
                     68: 
                     69:        uucpname();
                     70:        domainname();
                     71:        senderr = 0;
                     72:        temp = templ;
                     73: 
                     74:        fromtty = isatty(fileno(stdin));
                     75:        if ((tfp = fopen(temp, "w")) != NULL) {
                     76:                fclose(tfp);
                     77:                if ((tfp = fopen(temp, "r+w")) == NULL)
                     78:                        merr(toerr);
                     79:        } else
                     80:                merr(toerr);
                     81:        chown(temp, myuid, mygid);
                     82:        unlink(temp);
                     83:        temp = NULL;
                     84:        fseek(fp, start, 0);
                     85:        end -= start;
                     86: 
                     87:        eflag = 0;
                     88:        if (fromtty && asksubj && !callmermail) {
                     89:                fprintf(stdout, "Subject: ");
                     90:                fflush(stdout);
                     91:                if (fgets(msgline, NLINE, fp) != NULL) {
                     92:                        if (strlen(msgline) > 1)
                     93:                                fprintf(tfp, "Subject: %s", msgline);
                     94:                }
                     95:        }
                     96: 
                     97:        if (intcheck()) {
                     98:                fclose(tfp);
                     99:                return(1);
                    100:        }
                    101: 
                    102:        for (;;) {
                    103:                if (fgets(msgline, NLINE, fp) == NULL)
                    104:                        break;
                    105:                if (fp == stdin)
                    106:                        if ((strcmp(".\n", msgline)==0))
                    107:                                break;
                    108:                        else if ((strcmp("?\n", msgline)==0)) {
                    109:                                eflag = 1;
                    110:                                break;
                    111:                        }
                    112:                fputs(msgline, tfp);
                    113:                if ( (end-=strlen(msgline)) <= 0 )
                    114:                        break;
                    115:        }
                    116: 
                    117:        if (intcheck()) {
                    118:                fclose(tfp);
                    119:                return(1);
                    120:        }
                    121: 
                    122:        if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) {
                    123:                fputs("\n", tfp);
                    124:                while (fgets(msgline, NLINE, sigfp) != NULL)
                    125:                        fputs(msgline, tfp);
                    126:                fclose(sigfp);
                    127:        }
                    128: 
                    129:        /*
                    130:         * Now, see if user wants to edit the message
                    131:         */
                    132: 
                    133:        if (eflag) {
                    134:                xfp = tfp;
                    135:                temp = templ;
                    136:                if ((tfp = fopen(temp, "wr")) == NULL)
                    137:                        merr(toerr);
                    138:                chown(temp, myuid, mygid);
                    139:                mcopy(xfp, tfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
                    140:                fclose(xfp);
                    141:                sprintf(cmdname, "exec %s %s", editname, templ);
                    142:                system(cmdname);
                    143:                unlink(temp);
                    144:                temp = NULL;
                    145:        }
                    146: 
                    147:        /*
                    148:         * if empty message, bug out.
                    149:         */
                    150: 
                    151:        if (ftell(tfp) == 0) {
                    152:                fclose(tfp);
                    153:                return(1);
                    154:        }
                    155: 
                    156:        /*
                    157:         * Now see if a copy list is requested.
                    158:         */
                    159: 
                    160:        tolist = users;
                    161:        cclist = (askcc && fromtty && !callmermail) ? getcc(): NULL;
                    162:        allist = listcat(tolist, cclist);
                    163:        
                    164:        if ( verbflag ) {
                    165:                mmsg(
                    166:        "Recipient List:\n\n");
                    167:                for (listpp=allist; *listpp != NULL; listpp++)
                    168:                        mmsg("\t%s\n", *listpp);
                    169:        }
                    170: 
                    171:        /*
                    172:         * Now send the message.
                    173:         */
                    174: 
                    175:        time(&curtime);
                    176:        tp = localtime(&curtime);
                    177: 
                    178:        if (callmexmail)
                    179:                xsend(allist, tfp);
                    180:        else
                    181:                usend(allist, tfp);
                    182: 
                    183:        return( senderr );
                    184: }
                    185: 
                    186: usend(users, tfp)
                    187: char **users;
                    188: FILE *tfp;
                    189: {
                    190:        FILE *xfp;
                    191:        char *name;
                    192:        char **ulist, **listpp;
                    193:        char command[CMDLINE];
                    194:        char *arpadate();
                    195:        FILE *popen();
                    196: 
                    197:        logdump("Date: %s  From: %s!%s (%s)\n",
                    198:                        arpadate(tp), mysite, myname, myfullname);
                    199:        for (ulist = users; (name=*ulist) != NULL; ulist++)
                    200:                logdump("To: \"%s\"\n", name);
                    201: 
                    202:        /* Build the command line to the delivery program.  */
                    203:        if ( callmexmail ) {
                    204:                strcpy(command, XDELIVER); /* usually "/bin/rxmail" */
                    205:        } else {
                    206:                strcpy(command, DELIVER); /* usually "/bin/rmail" */
                    207:        } /* if ( callmexmail ) */
                    208: 
                    209:        /* Add the list of recipients to the command line.  */
                    210:        for (listpp = users; *listpp != NULL; listpp++) {
                    211:                strcat(command, " ");
                    212:                strcat(command, *listpp);
                    213:        }
                    214:        
                    215:        /* NB:  I think there may be a security problem
                    216:           here, since popen ought to exec $SHELL.  Check this.  */
                    217:        /* Now actually call the mail delivery agent.  */
                    218:        if ( (xfp = popen(command, "w")) == NULL ) {
                    219:                /* Report a send error and return.  */
                    220:        }
                    221: 
                    222:        /* Pump the headers into the delivery agent. */
                    223:        build_header(xfp);
                    224: 
                    225:        /* Pump the message into the delivery agent.  */
                    226:        rewind(tfp);
                    227:        mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
                    228: 
                    229:        fclose(xfp);
                    230:        fclose(tfp);
                    231: }
                    232: 
                    233: xsend(users, tfp) char **users; FILE *tfp;
                    234: {
                    235:        register char **ulist;
                    236:        register char *cp;
                    237:        register struct passwd *pwp;
                    238:        FILE *xfp;
                    239: 
                    240:        for (ulist = users; *ulist!=NULL; ulist++) {
                    241:                rewind(tfp);
                    242:                sprintf(boxname, "%s%s", SPOOLDIR, *ulist);
                    243:                sprintf(cmdname, "xencode %s >> %s", *ulist, boxname);
                    244:                if (index(*ulist, '!') != NULL
                    245:                 || (pwp = getpwnam(*ulist)) == NULL) {
                    246:                        mmsg(nosend, *ulist);
                    247:                        continue;
                    248:                }
                    249:                if (xaccess(*ulist) == 0) {
                    250:                        mmsg(nopubk, *ulist);
                    251:                        continue;
                    252:                }
                    253:                mlock(pwp->pw_uid);
                    254:                if ((xfp = fopen(boxname, "a")) == NULL) {
                    255:                        mmsg(nosend, *ulist);
                    256:                        munlock();
                    257:                        continue;
                    258:                }
                    259:                chown(boxname, pwp->pw_uid, pwp->pw_gid);
                    260:                fprintf(xfp, "From xmail %s %s\n", cp,
                    261:                        tzname[tp->tm_isdst ? 1 : 0]);
                    262:                fclose(xfp);
                    263:                if ((xfp = popen(cmdname, "w")) == NULL) {
                    264:                        mmsg("Can't pipe to xencode\n");
                    265:                        continue;
                    266:                }
                    267:                if (fwrite(header, strlen(header), 1, xfp) != 1
                    268:                 || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) {
                    269:                        merr(wrerr, cmdname);
                    270:                }
                    271:                pclose(xfp);
                    272:                munlock();
                    273:        }
                    274:        fclose(tfp);
                    275: }
                    276: 
                    277: uucpname()
                    278: {
                    279:        FILE *uufile;
                    280: 
                    281:        if (NULL == (uufile = fopen(NODENAME, "r"))) {
                    282:                strcpy(mysite, "<unknown>");
                    283:                return;
                    284:        }
                    285:        fgets(mysite, sizeof mysite, uufile);
                    286:        mysite[strlen(mysite) - 1] = '\0';      /* remove '\n' */
                    287:        fclose(uufile);
                    288:        return;
                    289: }
                    290: 
                    291: domainname()
                    292: {
                    293:        FILE *domfile;
                    294:        if((domfile = fopen(DOMAINNAME, "r")) == NULL) {
                    295:                strcpy(domain, ".UNKNOWN");
                    296:                return;
                    297:        }
                    298:        fgets(domain, sizeof domain, domfile);
                    299:        domain [strlen(domain) - 1] = '\0';
                    300:        fclose (domfile);
                    301:        return;
                    302: }
                    303: 
                    304: char *
                    305: arpadate(tp)
                    306: struct tm      *tp;
                    307: {
                    308:        static  char arpabuf [64];
                    309:        static  char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
                    310:        sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d",
                    311:                tp->tm_mday,
                    312:                months[tp->tm_mon * 3],
                    313:                months[tp->tm_mon * 3 + 1],
                    314:                months[tp->tm_mon * 3 + 2],
                    315:                tp->tm_year,
                    316:                tp->tm_hour, tp->tm_min, tp->tm_sec);
                    317:        return arpabuf;
                    318: }
                    319: 
                    320: char *
                    321: msgid(tp)
                    322: struct tm      *tp;
                    323: {
                    324:        static  char    msgidbuf [32];
                    325:        sprintf(msgidbuf, "%02d%02d%02d%02d%02d",
                    326:        tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min);
                    327:        return msgidbuf;
                    328: }
                    329: 
                    330: build_header(xfp)
                    331: FILE   *xfp;
                    332: {
                    333:        char    **ulist;
                    334:        int     processid;
                    335: 
                    336:        /* Generate a Message-Id.  */
                    337:        processid = getpid();
                    338:        sprintf(header, "Message-Id: <%s.AA%d.V%s@%s.%s>\n",
                    339:                msgid(tp), processid, revnop(), mysite, domain);
                    340:        if (fwrite(header, strlen(header), 1, xfp) != 1)
                    341:                return 0;
                    342: 
                    343:        /* generate Date: and From: lines.  */
                    344:        sprintf(header, "Date: %s\nFrom: %s@%s.%s (%s)\n",
                    345:                arpadate(tp), myname, mysite, domain, myfullname);
                    346:        if (fwrite(header, strlen(header), 1, xfp) != 1)
                    347:                return 0;
                    348: 
                    349:        /* Generate the full To: lines.  We just spit addresses out
                    350:           verbatum, with no cleanup.  */
                    351:        strcpy(header, "To:");
                    352:        for (ulist=tolist; *ulist != NULL; ulist++) {
                    353:                strcat(header, " ");
                    354:                strcat(header, *ulist);
                    355:        }
                    356:        strcat(header, "\n");
                    357:        if (fwrite(header, strlen(header), 1, xfp) != 1)
                    358:                return 0;
                    359: 
                    360:        /* Generate a Cc: line if needed.  */
                    361:        if (cclist[0] != NULL) {
                    362:                strcpy(header, "Cc:");
                    363:                for (ulist=cclist; *ulist != NULL; ulist++) {
                    364:                        strcat(header, " ");
                    365:                        strcat(header, *ulist);
                    366:                }
                    367:                strcat(header, "\n");
                    368:                if (fwrite(header, strlen(header), 1, xfp) != 1)
                    369:                        return 0;
                    370:        }
                    371:        return 1;
                    372: }
                    373: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.