Annotation of researchv10no/cmd/odist/tar/tarc.c, revision 1.1

1.1     ! root        1: #include <stddef.h>
        !             2: #include <stdio.h>
        !             3: #include <sys/types.h>
        !             4: #include <sys/stat.h>
        !             5: #include <libv.h>
        !             6: #include "ftwlk.h"
        !             7: #include "tar.h"
        !             8: #include "misc.h"
        !             9: 
        !            10: #define MIN(A, B) ((A) < (B) ? (A) : (B))
        !            11: 
        !            12: int vflag;
        !            13: 
        !            14: int nerr;
        !            15: 
        !            16: struct hardlink {
        !            17:        char *name;
        !            18:        int ino;
        !            19:        int dev;
        !            20:        struct hardlink *next;
        !            21: };
        !            22: 
        !            23: struct hardlink *links;
        !            24: 
        !            25: struct hardlink *
        !            26: findlink(char *name, int ino, int dev)
        !            27: {
        !            28:        struct hardlink *h;
        !            29: 
        !            30:        for (h = links; h; h = h->next)
        !            31:                if (ino == h->ino && dev == h->dev)
        !            32:                        return h;
        !            33:        h = xmalloc(sizeof (struct hardlink));
        !            34:        h->name = xstrdup(name);
        !            35:        h->ino = ino;
        !            36:        h->dev = dev;
        !            37:        h->next = links;
        !            38:        links = h;
        !            39:        return 0;       /* make a new entry, but say we didn't find it */
        !            40: }
        !            41: 
        !            42: #ifndef S_ISREG
        !            43: #define S_ISREG(M) (((M) & S_IFMT) == S_IFREG)
        !            44: #endif
        !            45: 
        !            46: void
        !            47: zeropad(long from, long to)
        !            48: {
        !            49:        static char zero[512];
        !            50:        static int n;
        !            51: 
        !            52:        while (from < to) {
        !            53:                n = MIN(to - from, sizeof zero);
        !            54:                if (fwrite(zero, 1, n, stdout) != n) {
        !            55:                        fprintf(stderr, "tarc: zero padding failed\n");
        !            56:                        exit(1);
        !            57:                }
        !            58:                from += n;
        !            59:        }
        !            60: }
        !            61: 
        !            62: int
        !            63: dofile(char *name, struct stat *st, int code, struct FTWLK *f)
        !            64: {
        !            65:        struct tarhdr hdr;
        !            66:        struct tarbuf buf;
        !            67:        struct hardlink *hl;
        !            68:        FILE *fp;
        !            69:        long cc;
        !            70: 
        !            71:        if (code == FTWLK_NSL || code == FTWLK_SL)
        !            72:                lstat(name, st);        /* fix ftwlk braindamage */
        !            73: 
        !            74:        memset(&hdr, 0, sizeof hdr);
        !            75:        if (strlen(name) > TNAMEMAX) {
        !            76:                fprintf(stderr, "tarc: file name too long '%s'\n", name);
        !            77:                exit(1);
        !            78:        }
        !            79: 
        !            80:        strcpy(hdr.name, name);
        !            81:        hdr.mode = st->st_mode & TMASK;
        !            82:        hdr.uid = st->st_uid;
        !            83:        hdr.gid = st->st_gid;
        !            84:        hdr.size = st->st_size;
        !            85:        hdr.mtime = st->st_mtime;
        !            86: 
        !            87:        switch (code) {
        !            88:        case FTWLK_D:
        !            89:                if (strlen(name) <= TNAMEMAX - 1)
        !            90:                        strcat(hdr.name, "/");
        !            91:                hdr.typeflag = DIRTYPE;
        !            92:                break;
        !            93: 
        !            94:        case FTWLK_F:
        !            95:                if (st->st_nlink > 1
        !            96:                && (hl = findlink(name, st->st_ino, st->st_dev))
        !            97:                && strlen(hl->name) <= TLINKMAX) {
        !            98:                        hdr.typeflag = LNKTYPE;
        !            99:                        strcpy(hdr.linkname, hl->name);
        !           100:                } else if (S_ISREG(st->st_mode))
        !           101:                        hdr.typeflag = REGTYPE;
        !           102:                else {
        !           103:                        fprintf(stderr, "tarc: not a regular file '%s'\n",
        !           104:                                name);
        !           105:                        ++nerr;
        !           106:                        return 0;
        !           107:                }
        !           108:                break;
        !           109: 
        !           110:        case FTWLK_SL:
        !           111:                if (f->level == 0) {
        !           112:                        f->quit = FTWLK_FOLLOW;
        !           113:                        return 0;
        !           114:                }
        !           115:                hdr.typeflag = SYMTYPE;
        !           116:                cc = readlink(name, hdr.linkname, sizeof hdr.linkname);
        !           117:                if (cc < 0) {
        !           118:                        fprintf(stderr, "tarc: can't read symlink '%s'\n",
        !           119:                                name);
        !           120:                        ++nerr;
        !           121:                        return 0;
        !           122:                }
        !           123:                break;
        !           124: 
        !           125:        default:
        !           126:                return 0;
        !           127:        }
        !           128: 
        !           129:        if (hdr.typeflag != REGTYPE)
        !           130:                hdr.size = 0;
        !           131:        if (vflag)
        !           132:                fprintf(stderr, "%s\n", hdr.name);
        !           133:        if (thdrput(&buf, &hdr) != 0) {
        !           134:                fprintf(stderr, "tarc: failed making header for '%s'\n", name);
        !           135:                ++nerr;
        !           136:                return 0;
        !           137:        }
        !           138:        if (hdr.typeflag == REGTYPE && !(fp = fopen(name, "r")))
        !           139:                return 0;
        !           140:        if (fwrite(&buf, sizeof buf, 1, stdout) != 1) {
        !           141:                fprintf(stderr, "tarc: write failed\n");
        !           142:                exit(1);
        !           143:        }
        !           144:        if (hdr.typeflag == REGTYPE) {
        !           145:                cc = fpcopy(stdout, fp, st->st_size);
        !           146:                if (cc < 0) {
        !           147:                        fprintf(stderr, "tarc: file copy failed '%s'\n", name);
        !           148:                        exit(1);
        !           149:                }
        !           150:                if (cc != st->st_size)
        !           151:                        fprintf(stderr, "tarc: warning: size change '%s'\n",
        !           152:                                name);
        !           153:                zeropad(cc, (st->st_size + TSIZE - 1) / TSIZE * TSIZE);
        !           154:                fclose(fp);
        !           155:        }
        !           156:        return 0;
        !           157: }
        !           158: 
        !           159: void
        !           160: usage(void)
        !           161: {
        !           162:        fprintf(stderr, "usage: tarc [-v] files...\n");
        !           163:        exit(1);
        !           164: }
        !           165: 
        !           166: int
        !           167: main(int argc, char *argv[])
        !           168: {
        !           169:        int i, c;
        !           170: 
        !           171:        prog = argv[0];
        !           172:        while ((c = getopt(argc, argv, "v")) != EOF)
        !           173:                switch (c) {
        !           174:                case 'v':
        !           175:                        ++vflag;
        !           176:                        break;
        !           177:                default:
        !           178:                        usage();
        !           179:                        break;
        !           180:                }
        !           181:        for (i = optind; i < argc; ++i)
        !           182:                ftwlk(argv[i], dofile, 10);
        !           183:        zeropad(0, 2 * TSIZE);
        !           184:        return nerr ? 1 : 0;
        !           185: }

unix.superglobalmegacorp.com

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