Annotation of 41BSD/cmd/ucbmail/fio.c, revision 1.1

1.1     ! root        1: #
        !             2: 
        !             3: #include "rcv.h"
        !             4: #include <sys/stat.h>
        !             5: #include <errno.h>
        !             6: 
        !             7: /*
        !             8:  * Mail -- a mail program
        !             9:  *
        !            10:  * File I/O.
        !            11:  */
        !            12: 
        !            13: /*
        !            14:  * Set up the input pointers while copying the mail file into
        !            15:  * /tmp.
        !            16:  */
        !            17: 
        !            18: setptr(ibuf)
        !            19:        FILE *ibuf;
        !            20: {
        !            21:        register int count, s, l;
        !            22:        off_t offset;
        !            23:        char linebuf[LINESIZE];
        !            24:        int maybe, mestmp, flag;
        !            25:        struct message this;
        !            26:        extern char tempSet[];
        !            27: 
        !            28:        if ((mestmp = opentemp(tempSet)) < 0)
        !            29:                exit(1);
        !            30:        msgCount = 0;
        !            31:        offset = 0;
        !            32:        s = 0;
        !            33:        l = 0;
        !            34:        maybe = 1;
        !            35:        flag = MUSED;
        !            36:        if (value("hold") != NOSTR)
        !            37:                flag = MPRESERVE|MUSED;
        !            38:        for (;;) {
        !            39:                if ((count = readline(ibuf, linebuf)) == 0) {
        !            40:                        this.m_flag = flag;
        !            41:                        this.m_offset = offsetof(offset);
        !            42:                        this.m_block = blockof(offset);
        !            43:                        this.m_size = s;
        !            44:                        this.m_lines = l;
        !            45:                        if (append(&this, mestmp)) {
        !            46:                                perror(tempSet);
        !            47:                                exit(1);
        !            48:                        }
        !            49:                        fclose(ibuf);
        !            50:                        makemessage(mestmp);
        !            51:                        close(mestmp);
        !            52:                        return;
        !            53:                }
        !            54:                if (putline(otf, linebuf) < 0) {
        !            55:                        perror("/tmp");
        !            56:                        exit(1);
        !            57:                }
        !            58:                if (maybe && ishead(linebuf)) {
        !            59:                        msgCount++;
        !            60:                        this.m_flag = flag;
        !            61:                        this.m_block = blockof(offset);
        !            62:                        this.m_offset = offsetof(offset);
        !            63:                        this.m_size = s;
        !            64:                        this.m_lines = l;
        !            65:                        s = 0;
        !            66:                        l = 0;
        !            67:                        if (append(&this, mestmp)) {
        !            68:                                perror(tempSet);
        !            69:                                exit(1);
        !            70:                        }
        !            71:                }
        !            72:                offset += count;
        !            73:                s += count;
        !            74:                l++;
        !            75:                maybe = 0;
        !            76:                if (linebuf[0] == 0)
        !            77:                        maybe = 1;
        !            78:        }
        !            79: }
        !            80: 
        !            81: /*
        !            82:  * Drop the passed line onto the passed output buffer.
        !            83:  * If a write error occurs, return -1, else the count of
        !            84:  * characters written, including the newline.
        !            85:  */
        !            86: 
        !            87: putline(obuf, linebuf)
        !            88:        FILE *obuf;
        !            89:        char *linebuf;
        !            90: {
        !            91:        register int c;
        !            92: 
        !            93:        c = strlen(linebuf);
        !            94:        fputs(linebuf, obuf);
        !            95:        putc('\n', obuf);
        !            96:        if (ferror(obuf))
        !            97:                return(-1);
        !            98:        return(c+1);
        !            99: }
        !           100: 
        !           101: /*
        !           102:  * Read up a line from the specified input into the line
        !           103:  * buffer.  Return the number of characters read.  Do not
        !           104:  * include the newline at the end.
        !           105:  */
        !           106: 
        !           107: readline(ibuf, linebuf)
        !           108:        FILE *ibuf;
        !           109:        char *linebuf;
        !           110: {
        !           111:        register char *cp;
        !           112:        register int c;
        !           113: 
        !           114:        do {
        !           115:                clearerr(ibuf);
        !           116:                c = getc(ibuf);
        !           117:                for (cp = linebuf; c != '\n' && c != EOF; c = getc(ibuf)) {
        !           118:                        if (c == 0)
        !           119:                                continue;
        !           120:                        if (cp - linebuf < LINESIZE-2)
        !           121:                                *cp++ = c;
        !           122:                }
        !           123:        } while (ferror(ibuf) && ibuf == stdin);
        !           124:        *cp = 0;
        !           125:        if (c == EOF && cp == linebuf)
        !           126:                return(0);
        !           127:        return(cp - linebuf + 1);
        !           128: }
        !           129: 
        !           130: /*
        !           131:  * Return a file buffer all ready to read up the
        !           132:  * passed message pointer.
        !           133:  */
        !           134: 
        !           135: FILE *
        !           136: setinput(mp)
        !           137:        register struct message *mp;
        !           138: {
        !           139:        off_t off;
        !           140: 
        !           141:        fflush(otf);
        !           142:        off = mp->m_block;
        !           143:        off <<= 9;
        !           144:        off += mp->m_offset;
        !           145:        if (fseek(itf, off, 0) < 0) {
        !           146:                perror("fseek");
        !           147:                panic("temporary file seek");
        !           148:        }
        !           149:        return(itf);
        !           150: }
        !           151: 
        !           152: /*
        !           153:  * Take the data out of the passed ghost file and toss it into
        !           154:  * a dynamically allocated message structure.
        !           155:  */
        !           156: 
        !           157: makemessage(f)
        !           158: {
        !           159:        register struct message *m;
        !           160:        register char *mp;
        !           161:        register count;
        !           162: 
        !           163:        mp = calloc((unsigned) (msgCount + 1), sizeof *m);
        !           164:        if (mp == NOSTR) {
        !           165:                printf("Insufficient memory for %d messages\n", msgCount);
        !           166:                exit(1);
        !           167:        }
        !           168:        message = (struct message *) mp;
        !           169:        dot = message;
        !           170:        lseek(f, 0L, 0);
        !           171:        while (count = read(f, mp, BUFSIZ))
        !           172:                mp += count;
        !           173:        for (m = &message[0]; m < &message[msgCount]; m++) {
        !           174:                m->m_size = (m+1)->m_size;
        !           175:                m->m_lines = (m+1)->m_lines;
        !           176:        }
        !           177:        message[msgCount].m_size = 0;
        !           178:        message[msgCount].m_lines = 0;
        !           179: }
        !           180: 
        !           181: /*
        !           182:  * Append the passed message descriptor onto the temp file.
        !           183:  * If the write fails, return 1, else 0
        !           184:  */
        !           185: 
        !           186: append(mp, f)
        !           187:        struct message *mp;
        !           188: {
        !           189:        if (write(f, (char *) mp, sizeof *mp) != sizeof *mp)
        !           190:                return(1);
        !           191:        return(0);
        !           192: }
        !           193: 
        !           194: /*
        !           195:  * Delete a file, but only if the file is a plain file.
        !           196:  */
        !           197: 
        !           198: remove(name)
        !           199:        char name[];
        !           200: {
        !           201:        struct stat statb;
        !           202:        extern int errno;
        !           203: 
        !           204:        if (stat(name, &statb) < 0)
        !           205:                return(-1);
        !           206:        if ((statb.st_mode & S_IFMT) != S_IFREG) {
        !           207:                errno = EISDIR;
        !           208:                return(-1);
        !           209:        }
        !           210:        return(unlink(name));
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * Terminate an editing session by attempting to write out the user's
        !           215:  * file from the temporary.
        !           216:  */
        !           217: 
        !           218: edstop()
        !           219: {
        !           220:        register int gotcha, c;
        !           221:        register struct message *mp;
        !           222:        FILE *obuf;
        !           223: 
        !           224:        for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++)
        !           225:                if (mp->m_flag & (MODIFY|MDELETED)) {
        !           226:                        gotcha++;
        !           227:                        break;
        !           228:                }
        !           229:        if (!gotcha)
        !           230:                return;
        !           231:        printf("\"%s\" ", editfile);
        !           232:        flush();
        !           233:        if ((obuf = fopen(editfile, "w")) == NULL) {
        !           234:                perror(editfile);
        !           235:                reset(0);
        !           236:        }
        !           237:        c = 0;
        !           238:        for (mp = &message[0]; mp < &message[msgCount]; mp++) {
        !           239:                if ((mp->m_flag & MDELETED) != 0)
        !           240:                        continue;
        !           241:                c++;
        !           242:                if (send(mp, obuf) < 0) {
        !           243:                        perror(editfile);
        !           244:                        reset(0);
        !           245:                }
        !           246:        }
        !           247:        fflush(obuf);
        !           248:        if (ferror(obuf)) {
        !           249:                perror(editfile);
        !           250:                reset(0);
        !           251:        }
        !           252:        if (c == 0) {
        !           253:                remove(editfile);
        !           254:                printf("removed\n");
        !           255:        }
        !           256:        else
        !           257:                printf("complete\n");
        !           258:        flush();
        !           259: }
        !           260: 
        !           261: /*
        !           262:  * Empty the output buffer.
        !           263:  */
        !           264: 
        !           265: clrbuf(buf)
        !           266:        register FILE *buf;
        !           267: {
        !           268: 
        !           269:        buf = stdout;
        !           270:        buf->_ptr = buf->_base;
        !           271:        buf->_cnt = BUFSIZ;
        !           272: }
        !           273: 
        !           274: /*
        !           275:  * Open a temp file by creating, closing, unlinking, and
        !           276:  * reopening.  Return the open file descriptor.
        !           277:  */
        !           278: 
        !           279: opentemp(file)
        !           280:        char file[];
        !           281: {
        !           282:        register int f;
        !           283: 
        !           284:        if ((f = creat(file, 0600)) < 0) {
        !           285:                perror(file);
        !           286:                return(-1);
        !           287:        }
        !           288:        close(f);
        !           289:        if ((f = open(file, 2)) < 0) {
        !           290:                perror(file);
        !           291:                remove(file);
        !           292:                return(-1);
        !           293:        }
        !           294:        remove(file);
        !           295:        return(f);
        !           296: }
        !           297: 
        !           298: /*
        !           299:  * Flush the standard output.
        !           300:  */
        !           301: 
        !           302: flush()
        !           303: {
        !           304:        fflush(stdout);
        !           305:        fflush(stderr);
        !           306: }
        !           307: 
        !           308: /*
        !           309:  * Determine the size of the file possessed by
        !           310:  * the passed buffer.
        !           311:  */
        !           312: 
        !           313: off_t
        !           314: fsize(iob)
        !           315:        FILE *iob;
        !           316: {
        !           317:        register int f;
        !           318:        struct stat sbuf;
        !           319: 
        !           320:        f = fileno(iob);
        !           321:        if (fstat(f, &sbuf) < 0)
        !           322:                return(0);
        !           323:        return(sbuf.st_size);
        !           324: }
        !           325: 
        !           326: /*
        !           327:  * Take a file name, possibly with shell meta characters
        !           328:  * in it and expand it by using "sh -c echo filename"
        !           329:  * Return the file name as a dynamic string.
        !           330:  */
        !           331: 
        !           332: char *
        !           333: expand(name)
        !           334:        char name[];
        !           335: {
        !           336:        char xname[BUFSIZ];
        !           337:        char cmdbuf[BUFSIZ];
        !           338:        register int pid, l, rc;
        !           339:        register char *cp, *Shell;
        !           340:        int s, pivec[2], (*sigint)();
        !           341:        struct stat sbuf;
        !           342: 
        !           343:        if (!anyof(name, "~{[*?$`'\"\\"))
        !           344:                return(name);
        !           345:        /* sigint = signal(SIGINT, SIG_IGN); */
        !           346:        if (pipe(pivec) < 0) {
        !           347:                perror("pipe");
        !           348:                /* signal(SIGINT, sigint) */
        !           349:                return(name);
        !           350:        }
        !           351:        sprintf(cmdbuf, "echo %s", name);
        !           352:        if ((pid = vfork()) == 0) {
        !           353:                Shell = value("SHELL");
        !           354:                if (Shell == NOSTR)
        !           355:                        Shell = SHELL;
        !           356:                close(pivec[0]);
        !           357:                close(1);
        !           358:                dup(pivec[1]);
        !           359:                close(pivec[1]);
        !           360:                close(2);
        !           361:                execl(Shell, Shell, "-c", cmdbuf, 0);
        !           362:                _exit(1);
        !           363:        }
        !           364:        if (pid == -1) {
        !           365:                perror("fork");
        !           366:                close(pivec[0]);
        !           367:                close(pivec[1]);
        !           368:                return(NOSTR);
        !           369:        }
        !           370:        close(pivec[1]);
        !           371:        l = read(pivec[0], xname, BUFSIZ);
        !           372:        close(pivec[0]);
        !           373:        while (wait(&s) != pid);
        !           374:                ;
        !           375:        s &= 0377;
        !           376:        if (s != 0 && s != SIGPIPE) {
        !           377:                fprintf(stderr, "\"Echo\" failed\n");
        !           378:                goto err;
        !           379:        }
        !           380:        if (l < 0) {
        !           381:                perror("read");
        !           382:                goto err;
        !           383:        }
        !           384:        if (l == 0) {
        !           385:                fprintf(stderr, "\"%s\": No match\n", name);
        !           386:                goto err;
        !           387:        }
        !           388:        if (l == BUFSIZ) {
        !           389:                fprintf(stderr, "Buffer overflow expanding \"%s\"\n", name);
        !           390:                goto err;
        !           391:        }
        !           392:        xname[l] = 0;
        !           393:        for (cp = &xname[l-1]; *cp == '\n' && cp > xname; cp--)
        !           394:                ;
        !           395:        *++cp = '\0';
        !           396:        if (any(' ', xname) && stat(xname, &sbuf) < 0) {
        !           397:                fprintf(stderr, "\"%s\": Ambiguous\n", name);
        !           398:                goto err;
        !           399:        }
        !           400:        /* signal(SIGINT, sigint) */
        !           401:        return(savestr(xname));
        !           402: 
        !           403: err:
        !           404:        /* signal(SIGINT, sigint); */
        !           405:        return(NOSTR);
        !           406: }
        !           407: 
        !           408: /*
        !           409:  * A nicer version of Fdopen, which allows us to fclose
        !           410:  * without losing the open file.
        !           411:  */
        !           412: 
        !           413: FILE *
        !           414: Fdopen(fildes, mode)
        !           415:        char *mode;
        !           416: {
        !           417:        register int f;
        !           418:        FILE *fdopen();
        !           419: 
        !           420:        f = dup(fildes);
        !           421:        if (f < 0) {
        !           422:                perror("dup");
        !           423:                return(NULL);
        !           424:        }
        !           425:        return(fdopen(f, mode));
        !           426: }

unix.superglobalmegacorp.com

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