Annotation of coherent/b/bin/mail/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: 
                    123:        if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) {
                    124:                fputs("\n", tfp);
                    125:                while (fgets(msgline, NLINE, sigfp) != NULL)
                    126:                        fputs(msgline, tfp);
                    127:                fclose(sigfp);
                    128:        }
                    129: 
                    130: 
                    131:        /*
                    132:         * Now, see if user wants to edit the message
                    133:         */
                    134: 
                    135:        if (eflag) {
                    136:                xfp = tfp;
                    137:                temp = templ;
                    138:                if ((tfp = fopen(temp, "wr")) == NULL)
                    139:                        merr(toerr);
                    140:                chown(temp, myuid, mygid);
                    141:                mcopy(xfp, tfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
                    142:                fclose(xfp);
                    143:                sprintf(cmdname, "exec %s %s", editname, templ);
                    144:                system(cmdname);
                    145:                unlink(temp);
                    146:                temp = NULL;
                    147:        }
                    148: 
                    149:        /*
                    150:         * if empty message, bug out.
                    151:         */
                    152: 
                    153:        if (ftell(tfp) == 0) {
                    154:                fclose(tfp);
                    155:                return(1);
                    156:        }
                    157: 
                    158:        /*
                    159:         * Now see if a copy list is requested.
                    160:         */
                    161: 
                    162:        tolist = users;
                    163:        cclist = (askcc && fromtty && !callmermail) ? getcc(): NULL;
                    164:        allist = listcat(tolist, cclist);
                    165:        
                    166:        if ( verbflag ) {
                    167:                mmsg(
                    168:        "Recipient List:\n\n");
                    169:                for (listpp=allist; *listpp != NULL; listpp++)
                    170:                        mmsg("\t%s\n", *listpp);
                    171:        }
                    172: 
                    173:        /*
                    174:         * Now send the message.
                    175:         */
                    176: 
                    177:        time(&curtime);
                    178:        tp = localtime(&curtime);
                    179: 
                    180:        if (callmexmail){
                    181:                xsend(allist, tfp);
                    182:        }else{
                    183:                usend(allist, tfp);
                    184:        }
                    185: 
                    186:        return( senderr );
                    187: }
                    188: 
                    189: usend(users, tfp)
                    190: char **users;
                    191: FILE *tfp;
                    192: {
                    193:        FILE *xfp;
                    194:        char *name;
                    195:        char **ulist, **listpp;
                    196:        char command[CMDLINE];
                    197:        char *arpadate();
                    198:        FILE *popen();
                    199: 
                    200:        logdump("Date: %s  From: %s!%s (%s)\n",
                    201:                        arpadate(tp), mysite, myname, myfullname);
                    202:        for (ulist = users; (name=*ulist) != NULL; ulist++)
                    203:                logdump("To: \"%s\"\n", name);
                    204: 
                    205:        /* Build the command line to the delivery program.  */
                    206:        if ( callmexmail ) {
                    207:                strcpy(command, XDELIVER); /* usually "/bin/rxmail" */
                    208:        } else {
                    209:                strcpy(command, DELIVER); /* usually "/bin/rmail" */
                    210:        } /* if ( callmexmail ) */
                    211: 
                    212:        /* Add the list of recipients to the command line.  */
                    213: 
                    214:        for (listpp = users; *listpp != NULL; listpp++) {
                    215:                strcat(command, " ");
                    216:                strcat(command, *listpp);
                    217:        }
                    218: 
                    219:        /* NB:  I think there may be a security problem
                    220:           here, since popen ought to exec $SHELL.  Check this.  */
                    221:        /* Now actually call the mail delivery agent.  */
                    222: 
                    223: 
                    224:        if ( (xfp = popen(command, "w")) == NULL ) {
                    225:                /* Report a send error and return.  */
                    226:        }
                    227: 
                    228:        /* Pump the headers into the delivery agent. */
                    229: 
                    230:        build_header(xfp);
                    231: 
                    232:        /* Pump the message into the delivery agent.  */
                    233: 
                    234:        rewind(tfp);
                    235:        mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0);
                    236: 
                    237:        fclose(xfp);
                    238:        fclose(tfp);
                    239: }
                    240: 
                    241: xsend(users, tfp) char **users; FILE *tfp;
                    242: {
                    243:        register char **ulist;
                    244:        register char *cp;
                    245:        register struct passwd *pwp;
                    246:        FILE *xfp;
                    247: 
                    248:        for (ulist = users; *ulist!=NULL; ulist++) {
                    249:                rewind(tfp);
                    250:                sprintf(boxname, "%s%s", SPOOLDIR, *ulist);
                    251:                sprintf(cmdname, "xencode %s >> %s", *ulist, boxname);
                    252:                if (index(*ulist, '!') != NULL
                    253:                 || (pwp = getpwnam(*ulist)) == NULL) {
                    254:                        mmsg(nosend, *ulist);
                    255:                        continue;
                    256:                }
                    257:                if (xaccess(*ulist) == 0) {
                    258:                        mmsg(nopubk, *ulist);
                    259:                        continue;
                    260:                }
                    261:                mlock(pwp->pw_uid);
                    262:                if ((xfp = fopen(boxname, "a")) == NULL) {
                    263:                        mmsg(nosend, *ulist);
                    264:                        munlock();
                    265:                        continue;
                    266:                }
                    267:                chown(boxname, pwp->pw_uid, pwp->pw_gid);
                    268:                fprintf(xfp, "From xmail %s %s\n", cp,
                    269:                        tzname[tp->tm_isdst ? 1 : 0]);
                    270:                fclose(xfp);
                    271:                if ((xfp = popen(cmdname, "w")) == NULL) {
                    272:                        mmsg("Can't pipe to xencode\n");
                    273:                        continue;
                    274:                }
                    275:                if (fwrite(header, strlen(header), 1, xfp) != 1
                    276:                 || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) {
                    277:                        merr(wrerr, cmdname);
                    278:                }
                    279:                pclose(xfp);
                    280:                munlock();
                    281:        }
                    282:        fclose(tfp);
                    283: }
                    284: 
                    285: uucpname()
                    286: {
                    287:        FILE *uufile;
                    288: 
                    289:        if (NULL == (uufile = fopen(NODENAME, "r"))) {
                    290:                strcpy(mysite, "<unknown>");
                    291:                return;
                    292:        }
                    293:        fgets(mysite, sizeof mysite, uufile);
                    294:        mysite[strlen(mysite) - 1] = '\0';      /* remove '\n' */
                    295:        fclose(uufile);
                    296:        return;
                    297: }
                    298: 
                    299: domainname()
                    300: {
                    301:        FILE *domfile;
                    302:        if((domfile = fopen(DOMAINNAME, "r")) == NULL) {
                    303:                strcpy(domain, ".UNKNOWN");
                    304:                return;
                    305:        }
                    306:        fgets(domain, sizeof domain, domfile);
                    307:        domain [strlen(domain) - 1] = '\0';
                    308:        fclose (domfile);
                    309:        return;
                    310: }
                    311: 
                    312: char *
                    313: arpadate(tp)
                    314: struct tm      *tp;
                    315: {
                    316:        static  char arpabuf [64];
                    317:        static  char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
                    318:        sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d",
                    319:                tp->tm_mday,
                    320:                months[tp->tm_mon * 3],
                    321:                months[tp->tm_mon * 3 + 1],
                    322:                months[tp->tm_mon * 3 + 2],
                    323:                tp->tm_year,
                    324:                tp->tm_hour, tp->tm_min, tp->tm_sec);
                    325:        return arpabuf;
                    326: }
                    327: 
                    328: char *
                    329: msgid(tp)
                    330: struct tm      *tp;
                    331: {
                    332:        static  char    msgidbuf [32];
                    333:        sprintf(msgidbuf, "%02d%02d%02d%02d%02d",
                    334:        tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min);
                    335:        return msgidbuf;
                    336: }
                    337: 
                    338: build_header(xfp)
                    339: FILE   *xfp;
                    340: {
                    341:        char    **ulist;
                    342:        int     processid;
                    343: 
                    344:        /* Generate a Message-Id.  */
                    345:        processid = getpid();
                    346:        sprintf(header, "Message-Id: <%s.AA%d.V%s@%s.%s>\n",
                    347:                msgid(tp), processid, revnop(), mysite, domain);
                    348:        if (fwrite(header, strlen(header), 1, xfp) != 1)
                    349:                return 0;
                    350: 
                    351:        /* generate Date: and From: lines.  */
                    352:        sprintf(header, "Date: %s\nFrom: %s@%s.%s (%s)\n",
                    353:                arpadate(tp), myname, mysite, domain, myfullname);
                    354:        if (fwrite(header, strlen(header), 1, xfp) != 1)
                    355:                return 0;
                    356: 
                    357:        /* Generate the full To: lines.  We just spit addresses out
                    358:           verbatum, with no cleanup.  */
                    359:        strcpy(header, "To:");
                    360:        for (ulist=tolist; *ulist != NULL; ulist++) {
                    361:                strcat(header, " ");
                    362:                strcat(header, *ulist);
                    363:        }
                    364:        strcat(header, "\n");
                    365:        if (fwrite(header, strlen(header), 1, xfp) != 1)
                    366:                return 0;
                    367: 
                    368:        /* Generate a Cc: line if needed.  */
                    369:        if (cclist[0] != NULL) {
                    370:                strcpy(header, "Cc:");
                    371:                for (ulist=cclist; *ulist != NULL; ulist++) {
                    372:                        strcat(header, " ");
                    373:                        strcat(header, *ulist);
                    374:                }
                    375:                strcat(header, "\n");
                    376:                if (fwrite(header, strlen(header), 1, xfp) != 1)
                    377:                        return 0;
                    378:        }
                    379:        return 1;
                    380: }
                    381: 

unix.superglobalmegacorp.com

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