Annotation of researchv10no/cmd/odist/tar/tarc.c, revision 1.1.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.