Annotation of coherent/d/usr/bin/pax/shipping/create.c, revision 1.1

1.1     ! root        1: /* $Source: /newbits/usr/bin/pax/shipping/RCS/create.c,v $
        !             2:  *
        !             3:  * $Revision: 1.2 $
        !             4:  *
        !             5:  * create.c - Create a tape archive. 
        !             6:  *
        !             7:  * DESCRIPTION
        !             8:  *
        !             9:  *     These functions are used to create/write and archive from an set of
        !            10:  *     named files.
        !            11:  *
        !            12:  * AUTHOR
        !            13:  *
        !            14:  *             Mark H. Colburn, NAPS International ([email protected])
        !            15:  *
        !            16:  * Sponsored by The USENIX Association for public distribution. 
        !            17:  *
        !            18:  * Copyright (c) 1989 Mark H. Colburn.
        !            19:  * All rights reserved.
        !            20:  *
        !            21:  * Redistribution and use in source and binary forms are permitted
        !            22:  * provided that the above copyright notice is duplicated in all such 
        !            23:  * forms and that any documentation, advertising materials, and other 
        !            24:  * materials related to such distribution and use acknowledge that the 
        !            25:  * software was developed * by Mark H. Colburn and sponsored by The 
        !            26:  * USENIX Association. 
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            29:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            30:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            31:  *
        !            32:  * $Log:       create.c,v $
        !            33:  * Revision 1.2  91/11/11  15:33:03  bin
        !            34:  * update by vlad to fix bug with long filenames and SV/posix readability
        !            35:  * 
        !            36:  * Revision 1.1        91/02/05  11:55:38      bin
        !            37:  * Initial revision
        !            38:  * 
        !            39:  * Revision 1.3  89/02/12  10:29:37  mark
        !            40:  * Fixed misspelling of Replstr
        !            41:  * 
        !            42:  * Revision 1.2  89/02/12  10:04:17  mark
        !            43:  * 1.2 release fixes
        !            44:  * 
        !            45:  * Revision 1.1  88/12/23  18:02:06  mark
        !            46:  * Initial revision
        !            47:  * 
        !            48:  */
        !            49: 
        !            50: #ifndef lint
        !            51: static char *ident = "$Id: create.c,v 1.2 91/11/11 15:33:03 bin Exp Locker: bin $";
        !            52: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
        !            53: #endif /* ! lint */
        !            54: 
        !            55: 
        !            56: /* Headers */
        !            57: 
        !            58: #include "pax.h"
        !            59: 
        !            60: 
        !            61: /* Function Prototypes */
        !            62: 
        !            63: #if __STDC__
        !            64: 
        !            65: static void writetar(char *, Stat *);
        !            66: static void writecpio(char *, Stat *);
        !            67: static char tartype(int);
        !            68: 
        !            69: #else /* !__STDC__ */
        !            70: 
        !            71: static void writetar();
        !            72: static void writecpio();
        !            73: static char tartype();
        !            74: 
        !            75: #endif /* __STDC__ */
        !            76: 
        !            77: 
        !            78: /* create_archive - create a tar archive.
        !            79:  *
        !            80:  * DESCRIPTION
        !            81:  *
        !            82:  *     Create_archive is used as an entry point to both create and append
        !            83:  *     archives.  Create archive goes through the files specified by the
        !            84:  *     user and writes each one to the archive if it can.  Create_archive
        !            85:  *     knows how to write both cpio and tar headers and the padding which
        !            86:  *     is needed for each type of archive.
        !            87:  *
        !            88:  * RETURNS
        !            89:  *
        !            90:  *     Always returns 0
        !            91:  */
        !            92: 
        !            93: #if __STDC__
        !            94: 
        !            95: int create_archive(void)
        !            96: 
        !            97: #else
        !            98: 
        !            99: int create_archive()
        !           100: 
        !           101: #endif
        !           102: {
        !           103:     char            name[PATH_MAX + 1];
        !           104:     Stat            sb;
        !           105:     int             fd;
        !           106: 
        !           107:     while (name_next(name, &sb) != -1) {
        !           108:        if ((fd = openin(name, &sb)) < 0) {
        !           109:            /* FIXME: pax wants to exit here??? */
        !           110:            continue;
        !           111:        }
        !           112:        if (rplhead != (Replstr *)NULL) {
        !           113:            rpl_name(name);
        !           114:            if (strlen(name) == 0) {
        !           115:                continue;
        !           116:            }
        !           117:        }
        !           118:        if (get_disposition("add", name) || get_newname(name, sizeof(name))) {
        !           119:            /* skip file... */
        !           120:            if (fd) {
        !           121:                close(fd);
        !           122:            }
        !           123:            continue;
        !           124:        } 
        !           125: 
        !           126:        if (!f_link && sb.sb_nlink > 1) {
        !           127:            if (islink(name, &sb)) {
        !           128:                sb.sb_size = 0;
        !           129:            }
        !           130:            linkto(name, &sb);
        !           131:        }
        !           132:        if (ar_format == TAR) {
        !           133:            /* SV tar does not understand POSIX tar header.
        !           134:             * Trailing '/' in directory name alows SV tar to unarchive
        !           135:             * POSIX tar archive. So, we add '/' to the "name" if it is
        !           136:             * a directory name.
        !           137:             * SV tar will produce error messages, but
        !           138:             * will do the job. Vlad 11-8-91
        !           139:             */
        !           140:            if ((sb.sb_stat.st_mode & S_IFMT) == S_IFDIR) {
        !           141:                int     il;
        !           142:                
        !           143:                il = strlen(name);
        !           144:                name[il++] = '/';
        !           145:                name[il] = 0;
        !           146:            }
        !           147:            writetar(name, &sb);
        !           148:        } else {
        !           149:            writecpio(name, &sb);
        !           150:        }
        !           151:        if (fd) {
        !           152:            outdata(fd, name, sb.sb_size);
        !           153:        }
        !           154:        if (f_verbose) {
        !           155:            print_entry(name, &sb);
        !           156:        }
        !           157:     }
        !           158: 
        !           159:     write_eot();
        !           160:     close_archive();
        !           161:     return (0);
        !           162: }
        !           163: 
        !           164: 
        !           165: /* writetar - write a header block for a tar file
        !           166:  *
        !           167:  * DESCRIPTION
        !           168:  *
        !           169:  *     Make a header block for the file name whose stat info is in st.  
        !           170:  *     Return header pointer for success, NULL if the name is too long.
        !           171:  *
        !           172:  *     The tar header block is structured as follows:
        !           173:  *
        !           174:  *             FIELD NAME      OFFSET          SIZE
        !           175:  *             -------------|---------------|------
        !           176:  *             name              0             100
        !           177:  *             mode            100               8
        !           178:  *             uid             108               8
        !           179:  *             gid             116               8
        !           180:  *             size            124              12
        !           181:  *             mtime           136              12
        !           182:  *             chksum          148               8
        !           183:  *             typeflag        156               1
        !           184:  *             linkname        157             100
        !           185:  *             magic           257               6
        !           186:  *             version         263               2
        !           187:  *             uname           265              32
        !           188:  *             gname           297              32
        !           189:  *             devmajor        329               8
        !           190:  *             devminor        337               8
        !           191:  *             prefix          345             155
        !           192:  *
        !           193:  * PARAMETERS
        !           194:  *
        !           195:  *     char    *name   - name of file to create a header block for
        !           196:  *     Stat    *asb    - pointer to the stat structure for the named file
        !           197:  *
        !           198:  */
        !           199: 
        !           200: #if __STDC__
        !           201: 
        !           202: static void writetar(char *name, Stat *asb)
        !           203: 
        !           204: #else
        !           205:     
        !           206: static void writetar(name, asb)
        !           207: char           *name;
        !           208: Stat           *asb;
        !           209: 
        !           210: #endif
        !           211: {
        !           212:     char          *p;
        !           213:     char           *prefix = (char *)NULL;
        !           214:     int             i;
        !           215:     int             sum;
        !           216:     char            hdr[BLOCKSIZE];
        !           217:     Link           *from;
        !           218: 
        !           219:     memset(hdr, 0, BLOCKSIZE);
        !           220:     if ((int) strlen(name) > 255) {
        !           221:        warn(name, "name too long");
        !           222:        return;
        !           223:     } 
        !           224:     /* 
        !           225:      * If the pathname is longer than TNAMLEN, but less than 255, then
        !           226:      * we can split it up into the prefix and the filename.
        !           227:      */
        !           228:     if (strlen(name) > 100) {
        !           229:        prefix = name;
        !           230:        name += 155;
        !           231:        while (name > prefix && *name != '/') {
        !           232:            name--;
        !           233:        }
        !           234: 
        !           235:        /* no slash found....hmmm.... */
        !           236:        if (name == prefix) {
        !           237:            warn(prefix, "Name too long");
        !           238:            return;
        !           239:        }
        !           240:        *name++ = '\0';
        !           241:     }
        !           242: 
        !           243: #ifdef S_IFLNK
        !           244:     if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
        !           245:        strcpy(&hdr[157], asb->sb_link);
        !           246:        asb->sb_size = 0;
        !           247:     }
        !           248: #endif
        !           249:     strcpy(hdr, name);
        !           250:     sprintf(&hdr[100], "%06o \0", asb->sb_mode & ~S_IFMT);
        !           251:     sprintf(&hdr[108], "%06o \0", asb->sb_uid);
        !           252:     sprintf(&hdr[116], "%06o \0", asb->sb_gid);
        !           253:     sprintf(&hdr[124], "%011lo ", (long) asb->sb_size);
        !           254:     sprintf(&hdr[136], "%011lo ", (long) asb->sb_mtime);
        !           255:     strncpy(&hdr[148], "        ", 8);
        !           256:     hdr[156] = tartype(asb->sb_mode);
        !           257:     if (asb->sb_nlink > 1 && (from = linkfrom(name, asb)) != (Link *)NULL) {
        !           258:        strcpy(&hdr[157], from->l_name);
        !           259:        hdr[156] = LNKTYPE;
        !           260:     }
        !           261:     strcpy(&hdr[257], TMAGIC);
        !           262:     strncpy(&hdr[263], TVERSION, 2);
        !           263:     strcpy(&hdr[265], finduname((int) asb->sb_uid));
        !           264:     strcpy(&hdr[297], findgname((int) asb->sb_gid));
        !           265:     sprintf(&hdr[329], "%06o \0", major(asb->sb_rdev));
        !           266:     sprintf(&hdr[337], "%06o \0", minor(asb->sb_rdev));
        !           267:     if (prefix != (char *)NULL) {
        !           268:        strncpy(&hdr[345], prefix, 155);
        !           269:     }
        !           270: 
        !           271:     /* Calculate the checksum */
        !           272: 
        !           273:     sum = 0;
        !           274:     p = hdr;
        !           275:     for (i = 0; i < 500; i++) {
        !           276:        sum += 0xFF & *p++;
        !           277:     }
        !           278: 
        !           279:     /* Fill in the checksum field. */
        !           280: 
        !           281:     sprintf(&hdr[148], "%06o \0", sum);
        !           282: 
        !           283:     outwrite(hdr, BLOCKSIZE);
        !           284: }
        !           285: 
        !           286: 
        !           287: /* tartype - return tar file type from file mode
        !           288:  *
        !           289:  * DESCRIPTION
        !           290:  *
        !           291:  *     tartype returns the character which represents the type of file
        !           292:  *     indicated by "mode". 
        !           293:  *
        !           294:  * PARAMETERS
        !           295:  *
        !           296:  *     int     mode    - file mode from a stat block
        !           297:  *
        !           298:  * RETURNS
        !           299:  *
        !           300:  *     The character which represents the particular file type in the 
        !           301:  *     ustar standard headers.
        !           302:  */
        !           303: 
        !           304: #if __STDC__
        !           305: 
        !           306: static char tartype(int mode)
        !           307: 
        !           308: #else
        !           309:     
        !           310: static char tartype(mode)
        !           311: int        mode;
        !           312: 
        !           313: #endif
        !           314: {
        !           315:     switch (mode & S_IFMT) {
        !           316: 
        !           317: #ifdef S_IFCTG
        !           318:     case S_IFCTG:
        !           319:        return(CONTTYPE);
        !           320: #endif
        !           321: 
        !           322:     case S_IFDIR:
        !           323:        return (DIRTYPE);
        !           324: 
        !           325: #ifdef S_IFLNK
        !           326:     case S_IFLNK:
        !           327:        return (SYMTYPE);
        !           328: #endif
        !           329: 
        !           330: #ifdef S_IFFIFO
        !           331:     case S_IFIFO:
        !           332:        return (FIFOTYPE);
        !           333: #endif
        !           334: 
        !           335: #ifdef S_IFCHR
        !           336:     case S_IFCHR:
        !           337:        return (CHRTYPE);
        !           338: #endif
        !           339: 
        !           340: #ifdef S_IFBLK
        !           341:     case S_IFBLK:
        !           342:        return (BLKTYPE);
        !           343: #endif
        !           344: 
        !           345:     default:
        !           346:        return (REGTYPE);
        !           347:     }
        !           348: }
        !           349: 
        !           350: 
        !           351: /* writecpio - write a cpio archive header
        !           352:  *
        !           353:  * DESCRIPTION
        !           354:  *
        !           355:  *     Writes a new CPIO style archive header for the file specified.
        !           356:  *
        !           357:  * PARAMETERS
        !           358:  *
        !           359:  *     char    *name   - name of file to create a header block for
        !           360:  *     Stat    *asb    - pointer to the stat structure for the named file
        !           361:  */
        !           362: 
        !           363: #if __STDC__
        !           364: 
        !           365: static void writecpio(char *name, Stat *asb)
        !           366: 
        !           367: #else
        !           368:     
        !           369: static void writecpio(name, asb)
        !           370: char           *name;
        !           371: Stat           *asb;
        !           372: 
        !           373: #endif
        !           374: {
        !           375:     uint            namelen;
        !           376:     char            header[M_STRLEN + H_STRLEN + 1];
        !           377: 
        !           378:     namelen = (uint) strlen(name) + 1;
        !           379:     strcpy(header, M_ASCII);
        !           380:     sprintf(header + M_STRLEN, "%06o%06o%06o%06o%06o",
        !           381:            USH(asb->sb_dev), USH(asb->sb_ino), USH(asb->sb_mode), 
        !           382:            USH(asb->sb_uid), USH(asb->sb_gid));
        !           383:     sprintf(header + M_STRLEN + 30, "%06o%06o%011lo%06o%011lo",
        !           384:            USH(asb->sb_nlink), USH(asb->sb_rdev),
        !           385:            f_mtime ? asb->sb_mtime : time((time_t *) 0),
        !           386:            namelen, asb->sb_size);
        !           387:     outwrite(header, M_STRLEN + H_STRLEN);
        !           388:     outwrite(name, namelen);
        !           389: #ifdef S_IFLNK
        !           390:     if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
        !           391:        outwrite(asb->sb_link, (uint) asb->sb_size);
        !           392:     }
        !           393: #endif /* S_IFLNK */
        !           394: }

unix.superglobalmegacorp.com

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