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

unix.superglobalmegacorp.com

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