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

1.1     ! root        1: #include <stdio.h>
        !             2: #include <sys/types.h>
        !             3: #include <sys/mdata.h>
        !             4: #include <time.h>
        !             5: #include <pwd.h>
        !             6: #include <utmp.h>
        !             7: #include <sys/stat.h>
        !             8: #include "mail.h"
        !             9: 
        !            10: #define SITENAMELEN    32      /* max length of sitename */
        !            11: #define NODENAME       "/etc/uucpname"
        !            12: #define DOMAINNAME     "/etc/domain"
        !            13: #define        ALIAS   "/usr/lib/mail/aliases"
        !            14: char   domain [64];
        !            15: 
        !            16: extern char    *strtok();
        !            17: FILE   *aliasfp;
        !            18: char   aliasbuf [BUFSIZ];
        !            19: char   *findalias();
        !            20: static **gusers;
        !            21: char mysite[SITENAMELEN];      /* this host's uucpname */
        !            22: 
        !            23: extern char    *temp;
        !            24: extern int     myuid;          /* User-id of mail user */
        !            25: extern int     mygid;          /* Group-id of mail user */
        !            26: extern char    cmdname[];      /* Command for x{en,de}code filter */
        !            27:                                /* and for tail recursion to uumail */
        !            28:                                /* and for editor recursion */
        !            29: extern char    *editname;      /* name of editor          */
        !            30: extern char    *askcc;         /* Ask for CC: list? (YES/NO) */
        !            31: extern int     callmexmail;    /* Xmail modifier present */
        !            32: extern char    wrerr[];
        !            33: extern char    myname[];       /* User name */
        !            34: extern char    myfullname[];   /* full user name */
        !            35: extern int     mflag;          /* `You have mail.' message to recipient */
        !            36: extern int     verbflag;       /* verbose flag */
        !            37: extern char    templ[];        /* Temp file name template */
        !            38: extern char    mydead[];       /* $HOME/dead.letter */
        !            39: extern char    mysig[];
        !            40: extern char    nosave[];
        !            41: extern int     callmermail;
        !            42: 
        !            43: static int     eflag;          /* Edit this mail */
        !            44: static int     senderr;
        !            45: struct tm      *tp;
        !            46: char   toerr[] = "Cannot create temporary file\n";
        !            47: char   header[BUFSIZ];         /* Message header */
        !            48: char   boxname[256];           /* Destination mailbox */
        !            49: char   aftralias [BUFSIZ];             /* name after alias processing */
        !            50: char   remotefrom [32];        /* "remote from uucp" */
        !            51: 
        !            52: char   nosend[] = "Can't send mail to '%s'\n";
        !            53: char   nopubk[] = "Can't send xmail to '%s'\n";
        !            54: static int fromtty;
        !            55: 
        !            56: /*
        !            57:  * Send the message found on
        !            58:  * the file pointer to the list
        !            59:  * of people (argv style) with
        !            60:  * a NULL pointer at the end.
        !            61:  * The message is copied to a temp-file
        !            62:  * from position `start' to `end' (or EOF).
        !            63:  */
        !            64: send2(fp, users, start, end, asksubj)
        !            65: FILE *fp;
        !            66: register char **users;
        !            67: fsize_t start, end;
        !            68: int    asksubj;
        !            69: {
        !            70:        char    **getcc();
        !            71:        FILE    *xfp, *tfp, *sigfp;
        !            72:        time_t  curtime;
        !            73: 
        !            74:        uucpname();
        !            75:        domainname();
        !            76:        senderr = 0;
        !            77:        temp = templ;
        !            78: /*fprintf(stderr, "send2(fp, users, %ld, %ld, %d)\n", start, end, asksubj);*/
        !            79:        fromtty = isatty(fileno(fp));
        !            80:        if ((tfp = fopen(temp, "w")) != NULL) {
        !            81:                fclose(tfp);
        !            82:                if ((tfp = fopen(temp, "r+w")) == NULL)
        !            83:                        merr(toerr);
        !            84:        } else
        !            85:                merr(toerr);
        !            86:        chown(temp, myuid, mygid);
        !            87:        unlink(temp);
        !            88:        temp = NULL;
        !            89:        fseek(fp, start, 0);
        !            90:        end -= start;
        !            91: 
        !            92:        eflag = 0;
        !            93:        if (fromtty && asksubj && !callmermail) {
        !            94:                fprintf(stdout, "Subject: ");
        !            95:                fflush(stdout);
        !            96:                if (fgets(msgline, NLINE, fp) != NULL) {
        !            97:                        if (strlen(msgline) > 1)
        !            98:                                fprintf(tfp, "Subject: %s", msgline);
        !            99:                }
        !           100:        }
        !           101:        for (;;) {
        !           102:                if (fgets(msgline, NLINE, fp) == NULL)
        !           103:                        break;
        !           104:                if (fp == stdin)
        !           105:                        if ((strcmp(".\n", msgline)==0))
        !           106:                                break;
        !           107:                        else if ((strcmp("?\n", msgline)==0)) {
        !           108:                                eflag = 1;
        !           109:                                break;
        !           110:                        }
        !           111: /*             fprintf(stderr, ":%s:", msgline);       */
        !           112:                fputs(msgline, tfp);
        !           113:                end -= strlen(msgline); /* compiler bug */              
        !           114:                if (end <= 0) {
        !           115:                        break;
        !           116:                }
        !           117:        }
        !           118:        if (!callmermail && (sigfp = fopen(mysig, "r")) != NULL) {
        !           119:                fputs("\n", tfp);
        !           120:                while (fgets(msgline, NLINE, sigfp) != NULL) {
        !           121:                        fputs(msgline, tfp);
        !           122:                }
        !           123:                fclose(sigfp);
        !           124:        }
        !           125:        /*
        !           126:         * If interrupted, bug out.
        !           127:         */
        !           128:        if (intcheck()) {
        !           129:                fclose(tfp);
        !           130:                return;
        !           131:        }
        !           132:        /*
        !           133:         * Now, see if user wants to edit the message
        !           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, "%s %s", editname, templ);
        !           144:                system(cmdname);
        !           145:                unlink(temp);
        !           146:                temp = NULL;
        !           147:        }
        !           148:        /*
        !           149:         * Otherwise if empty message, bug out.
        !           150:         */
        !           151:        else if (ftell(tfp) == 0) {
        !           152:                fclose(tfp);
        !           153:                return;
        !           154:        }
        !           155:        /*
        !           156:         * Now see if a copy list is requested.
        !           157:         */
        !           158:        if (askcc)
        !           159:                users = getcc(users);
        !           160:        gusers = users;
        !           161:        /*
        !           162:         * Now send the message.
        !           163:         */
        !           164:        time(&curtime);
        !           165:        tp = localtime(&curtime);
        !           166:        if (callmexmail)
        !           167:                xsend(users, tfp);
        !           168:        else
        !           169:                usend(users, tfp);
        !           170: }
        !           171: 
        !           172: usend(users, tfp)
        !           173: char **users;
        !           174: FILE *tfp;
        !           175: {
        !           176:        FILE *xfp;
        !           177:        char    *cp, *ap;
        !           178:        char    **ulist;
        !           179:        register struct passwd *pwp;
        !           180: 
        !           181:        for (ulist = users; *ulist != NULL; ulist++) {
        !           182:                rewind(tfp);
        !           183:                strcpy(aftralias, *ulist);
        !           184:                if (index(*ulist, '!') == 0) {
        !           185:                        ap = findalias(*ulist);
        !           186:                        if (ap != NULL) {
        !           187:                                strcpy(aftralias, ap);
        !           188:                                if (verbflag && strcmp(aftralias, ap))
        !           189:                                        fprintf(stderr,
        !           190:                                        "name %s aliased to %s\n",
        !           191:                                        *ulist, aftralias);
        !           192:                        }
        !           193:                }
        !           194:                if ((cp = index(aftralias, '!')) != NULL) {
        !           195:                        *cp++ = '\0';
        !           196:                        if (rsend(aftralias, cp, tfp) != 0) 
        !           197:                                senderr = 1;
        !           198:                        continue;
        !           199:                }
        !           200:                sprintf(boxname, "%s%s", SPOOLDIR, aftralias);
        !           201:                if ((pwp = getpwnam(aftralias)) == NULL) {
        !           202:                        mmsg(nosend, aftralias);
        !           203:                        senderr = 1;
        !           204:                        continue;
        !           205:                }
        !           206:                mlock(pwp->pw_uid);
        !           207:                if ((xfp = fopen(boxname, "a")) == NULL) {
        !           208:                        mmsg(nosend, aftralias);
        !           209:                        senderr = 1;
        !           210:                        munlock();
        !           211:                        continue;
        !           212:                }
        !           213:                chown(boxname, pwp->pw_uid, pwp->pw_gid);
        !           214:                if (build_header(aftralias, NULL, tfp, xfp) != 1
        !           215:                  || mcopy(tfp, xfp, ftell(tfp), (fsize_t)MAXLONG, 0)) {
        !           216:                        merr(wrerr, boxname);
        !           217:                        senderr = 1;
        !           218:                } else
        !           219:                        fprintf(xfp, "\1\1\n");
        !           220:                fflush(xfp);
        !           221:                munlock();
        !           222:                advise(aftralias);
        !           223:        }
        !           224:        if (senderr && fromtty && ! callmexmail) {
        !           225:                if (maccess(mydead) < 0
        !           226:                 || (xfp = fopen(mydead, "a")) == NULL
        !           227:                 || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0))
        !           228:                        mmsg(nosave, mydead);
        !           229:                else
        !           230:                        mmsg("Letter saved in %s\n", mydead);
        !           231:                if (xfp != NULL) {
        !           232:                        chown(mydead, myuid, mygid);
        !           233:                        fclose(xfp);
        !           234:                }
        !           235:        }
        !           236:        fclose(tfp);
        !           237: }
        !           238: 
        !           239: rsend(system, user, tfp)
        !           240: char   *user;
        !           241: char   *system;
        !           242: FILE   *tfp;
        !           243: {
        !           244:        FILE    *xfp;
        !           245:        int     i;
        !           246: 
        !           247:        sprintf(cmdname, "uux -r - %s!rmail '(%s)'", system, user);
        !           248:        if (verbflag)
        !           249:                fprintf(stderr, "Queueing remote mail to %s!%s\n",
        !           250:                system, user);
        !           251:        if ((xfp = popen(cmdname, "w")) == NULL) {
        !           252:                mmsg("Can't pipe to %s\n", cmdname);
        !           253:                return 1;
        !           254:        }
        !           255:        if (build_header(user, mysite, tfp, xfp) != 1 
        !           256:          || mcopy(tfp, xfp, ftell(tfp), (fsize_t)MAXLONG, 0)) {
        !           257:                merr(wrerr, cmdname);
        !           258:                return 1;
        !           259:        }
        !           260:        if (i = (pclose(xfp) != 0)) {
        !           261:                mmsg("uux has failed, status %d\n", i);
        !           262:                return 1;
        !           263:        }
        !           264:        return 0;
        !           265: }
        !           266: 
        !           267: xsend(users, tfp) char **users; FILE *tfp;
        !           268: {
        !           269:        register char **ulist;
        !           270:        register char *cp;
        !           271:        register struct passwd *pwp;
        !           272:        FILE *xfp;
        !           273: 
        !           274:        for (ulist = users; *ulist!=NULL; ulist++) {
        !           275:                rewind(tfp);
        !           276:                sprintf(boxname, "%s%s", SPOOLDIR, *ulist);
        !           277:                sprintf(cmdname, "xencode %s >> %s", *ulist, boxname);
        !           278:                if (index(*ulist, '!') != NULL
        !           279:                 || (pwp = getpwnam(*ulist)) == NULL) {
        !           280:                        mmsg(nosend, *ulist);
        !           281:                        continue;
        !           282:                }
        !           283:                if (xaccess(*ulist) == 0) {
        !           284:                        mmsg(nopubk, *ulist);
        !           285:                        continue;
        !           286:                }
        !           287:                mlock(pwp->pw_uid);
        !           288:                if ((xfp = fopen(boxname, "a")) == NULL) {
        !           289:                        mmsg(nosend, *ulist);
        !           290:                        munlock();
        !           291:                        continue;
        !           292:                }
        !           293:                chown(boxname, pwp->pw_uid, pwp->pw_gid);
        !           294:                fprintf(xfp, "From xmail %s %s\n", cp,
        !           295:                        tzname[tp->tm_isdst ? 1 : 0]);
        !           296:                fclose(xfp);
        !           297:                if ((xfp = popen(cmdname, "w")) == NULL) {
        !           298:                        mmsg("Can't pipe to xencode\n");
        !           299:                        continue;
        !           300:                }
        !           301:                if (fwrite(header, strlen(header), 1, xfp) != 1
        !           302:                 || mcopy(tfp, xfp, (fsize_t)0, (fsize_t)MAXLONG, 0)) {
        !           303:                        merr(wrerr, cmdname);
        !           304:                }
        !           305:                pclose(xfp);
        !           306:                munlock();
        !           307:        }
        !           308:        fclose(tfp);
        !           309: }
        !           310: 
        !           311: /*
        !           312:  * If the `-m' option is specified, advise
        !           313:  * the recipient of the presence of mail.
        !           314:  */
        !           315: advise(recipient)
        !           316: char *recipient;
        !           317: {
        !           318:        register FILE *fp;
        !           319:        register FILE *tfp;
        !           320:        struct utmp ut;
        !           321:        char tty[30];
        !           322:        struct stat sb;
        !           323: 
        !           324:        if (!mflag)
        !           325:                return;
        !           326:        if ((fp = fopen("/etc/utmp", "r")) == NULL)
        !           327:                return;
        !           328:        while (fread(&ut, sizeof ut, 1, fp) == 1)
        !           329:                if (strncmp(ut.ut_name, recipient, DIRSIZ) == 0) {
        !           330:                        sprintf(tty, "/dev/%s", ut.ut_line);
        !           331:                        if (stat(tty, &sb)<0 || (sb.st_mode&S_IEXEC)==0)
        !           332:                                continue;
        !           333:                        if ((tfp = fopen(tty, "w")) != NULL) {
        !           334:                                fprintf(tfp, "\7%s: you have mail.\n", myname);
        !           335:                                fclose(tfp);
        !           336:                        }
        !           337:                }
        !           338:        fclose(fp);
        !           339: }
        !           340: 
        !           341: uucpname()
        !           342: {
        !           343:        FILE *uufile;
        !           344: 
        !           345:        if (NULL == (uufile = fopen(NODENAME, "r"))) {
        !           346:                strcpy(mysite, "<unknown>");
        !           347:                return;
        !           348:        }
        !           349:        fgets(mysite, sizeof mysite, uufile);
        !           350:        mysite[strlen(mysite) - 1] = '\0';      /* remove '\n' */
        !           351:        fclose(uufile);
        !           352:        return;
        !           353: }
        !           354: 
        !           355: domainname()
        !           356: {
        !           357:        FILE *domfile;
        !           358:        if((domfile = fopen(DOMAINNAME, "r")) == NULL) {
        !           359:                strcpy(domain, ".UNKNOWN");
        !           360:                return;
        !           361:        }
        !           362:        fgets(domain, sizeof domain, domfile);
        !           363:        domain [strlen(domain) - 1] = '\0';
        !           364:        fclose (domfile);
        !           365:        return;
        !           366: }
        !           367: 
        !           368: char   *
        !           369: findalias(who)
        !           370: {
        !           371:        char    *name, *newname;
        !           372:        static  whobuf [64];
        !           373:        int     recurcount;
        !           374:        int     hit;
        !           375: 
        !           376:        if (aliasfp == NULL) {
        !           377:                if ((aliasfp = fopen(ALIAS, "r")) == NULL) {
        !           378:                        mmsg("Cannot open alias file\n");
        !           379:                        return who;
        !           380:                }
        !           381:        }
        !           382:        recurcount = 0;
        !           383:        strcpy(whobuf, who);
        !           384:        for (; ; ) {
        !           385:                fseek(aliasfp, 0L, 0);
        !           386:                hit = 0;
        !           387:                while (fgets(aliasbuf, BUFSIZ, aliasfp) != NULL) {
        !           388:                        name = strtok(aliasbuf," #:\t");
        !           389:                        newname = strtok(NULL, "#(), \t\n");
        !           390:                        if (strcmp(name, whobuf) == 0) {
        !           391:                                strcpy(whobuf, newname);
        !           392:                                if (recurcount++ > 4) {
        !           393:                                        sprintf(whobuf,
        !           394:                                        "Too many alias recursions for %s\n",
        !           395:                                                who);
        !           396:                                        mmsg(whobuf);
        !           397:                                        return who;
        !           398:                                }
        !           399:                                hit = 1;
        !           400:                                break;
        !           401:                        }
        !           402:                }
        !           403:                if (hit == 0)
        !           404:                        return whobuf;
        !           405:        }
        !           406:        return whobuf;
        !           407: }
        !           408: 
        !           409: char *
        !           410: arpadate(tp)
        !           411: struct tm      *tp;
        !           412: {
        !           413:        static  char arpabuf [64];
        !           414:        static  char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
        !           415:        sprintf(arpabuf, "%d %c%c%c %d %02d:%02d:%02d",
        !           416:                tp->tm_mday,
        !           417:                months[tp->tm_mon * 3],
        !           418:                months[tp->tm_mon * 3 + 1],
        !           419:                months[tp->tm_mon * 3 + 2],
        !           420:                tp->tm_year,
        !           421:                tp->tm_hour, tp->tm_min, tp->tm_sec);
        !           422:        return arpabuf;
        !           423: }
        !           424: 
        !           425: char *
        !           426: msgid(tp)
        !           427: struct tm      *tp;
        !           428: {
        !           429:        static  char    msgidbuf [32];
        !           430:        sprintf(msgidbuf, "%02d%02d%02d%02d%02d",
        !           431:        tp->tm_year, tp->tm_mon + 1, tp->tm_mday, tp->tm_hour, tp->tm_min);
        !           432:        return msgidbuf;
        !           433: }
        !           434: 
        !           435: build_header(user, site, tfp, xfp)
        !           436: char   *user;
        !           437: char   *site;
        !           438: FILE   *tfp;
        !           439: FILE   *xfp;
        !           440: {
        !           441:        char    *cp;
        !           442:        char    **ulist;
        !           443:        long    pos;
        !           444:        int     processid;
        !           445: 
        !           446:        cp = asctime(tp);
        !           447:        cp[strlen(cp)-1] = 0;
        !           448: /*     if (!callmermail) {     */
        !           449:                sprintf(header, "From %s %s %s", myname, cp,
        !           450:                        tzname[tp->tm_isdst ? 1 : 0]);
        !           451:                if (site != NULL) {
        !           452:                        strcat(header, " remote from ");
        !           453:                        strcat(header, site);
        !           454:                }
        !           455:                strcat(header, "\n");
        !           456: /*     }       */
        !           457:        if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           458:                return 0;
        !           459:        pos = ftell(tfp);
        !           460:        /* scan to end of From_ lines */
        !           461:        while (fgets(header, NLINE, tfp) != NULL) {
        !           462:                if ((strncmp (header, "From ", 5) != 0) &&
        !           463:                        (strncmp (header, ">From ", 6) != 0)) {
        !           464:                        break;
        !           465:                }
        !           466:                if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           467:                        return 0;
        !           468:                pos = ftell(tfp);
        !           469:        }
        !           470:        fseek(tfp, pos, 0);
        !           471:        processid = getpid();
        !           472:        if (callmermail) {
        !           473:                sprintf(header,
        !           474:                "Received: by %s (mail v %s)\n\tid AA%d; %s\n",
        !           475:                        mysite, revnop(), processid, arpadate(tp));
        !           476:                if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           477:                        return 0;
        !           478:        } else {
        !           479:                sprintf(header, "Message-Id: <%s.AA%d.V%s.%s@%s>\n",
        !           480:                        msgid(tp), processid, revnop(), mysite, domain);
        !           481:                if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           482:                        return 0;
        !           483:                sprintf(header, "Date: %s\nFrom: %s!%s (%s)\n",
        !           484:                        arpadate(tp), mysite, myname, myfullname);
        !           485:                if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           486:                        return 0;
        !           487:                sprintf(header, "To:   %s\n", user);
        !           488:                if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           489:                        return 0;
        !           490:                if (gusers[0] != NULL && gusers[1] != NULL) {
        !           491:                        strcpy(header, "cc:");
        !           492:                        for (ulist = gusers; *ulist != NULL; ulist++) {
        !           493:                                strcat(header, " ");
        !           494:                                strcat(header, *ulist);
        !           495:                        }
        !           496:                        strcat(header, "\n");
        !           497:                        if (fwrite(header, strlen(header), 1, xfp) != 1)
        !           498:                                return 0;
        !           499:                }
        !           500:        }
        !           501:        return 1;
        !           502: }
        !           503: 

unix.superglobalmegacorp.com

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