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