Annotation of coherent/e/bin/pax/create.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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