Annotation of coherent/b/bin/mail/send.c, revision 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.