|
|
1.1 ! root 1: /* $Source: /newbits/usr/bin/pax/shipping/RCS/ustar.c,v $ ! 2: * ! 3: * $Revision: 1.2 $ ! 4: * ! 5: * ustar.c - tar specific functions for archive handling ! 6: * ! 7: * DESCRIPTION ! 8: * ! 9: * These routines provide a tar conforming interface to the pax ! 10: * program. ! 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: ustar.c,v $ ! 33: * Revision 1.2 91/06/19 09:57:37 bin ! 34: * udated by vlad for restoring ownership/permissions ! 35: * ! 36: * Revision 1.1 91/02/05 11:59:47 bin ! 37: * Initial revision ! 38: * ! 39: * Revision 1.2 89/02/12 10:06:05 mark ! 40: * 1.2 release fixes ! 41: * ! 42: * Revision 1.1 88/12/23 18:02:38 mark ! 43: * Initial revision ! 44: * ! 45: */ ! 46: ! 47: #ifndef lint ! 48: static char *ident = "$Id: ustar.c,v 1.2 91/06/19 09:57:37 bin Exp Locker: bin $"; ! 49: static char *copyright ="Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved."; ! 50: #endif /* not lint */ ! 51: ! 52: /* Headers */ ! 53: ! 54: #include "pax.h" ! 55: ! 56: ! 57: /* Defines */ ! 58: ! 59: #define DEF_BLOCKING 1 /* default blocking factor for extract */ ! 60: ! 61: ! 62: /* Function Prototypes */ ! 63: ! 64: #if __STDC__ ! 65: ! 66: static int taropt(int , char **, char *); ! 67: static void usage(void); ! 68: ! 69: #else /* !__STDC__ */ ! 70: ! 71: static int taropt(); ! 72: static void usage(); ! 73: ! 74: #endif /* __STDC__ */ ! 75: ! 76: ! 77: /* do_tar - main routine for ustar. ! 78: * ! 79: * DESCRIPTION ! 80: * ! 81: * Provides a tar interface to the PAX program. All tar standard ! 82: * command line options are supported. ! 83: * ! 84: * PARAMETERS ! 85: * ! 86: * int argc - argument count (argc from main) ! 87: * char **argv - argument list (argv from main) ! 88: * ! 89: * RETURNS ! 90: * ! 91: * zero ! 92: */ ! 93: ! 94: #if __STDC__ ! 95: ! 96: int do_tar(int argc, char **argv) ! 97: ! 98: #else ! 99: ! 100: int do_tar(argc, argv) ! 101: int argc; /* argument count (argc from main) */ ! 102: char **argv; /* argument list (argv from main) */ ! 103: ! 104: #endif ! 105: { ! 106: int c; /* Option letter */ ! 107: ! 108: /* Set default option values */ ! 109: names_from_stdin = 0; ! 110: ar_file = getenv("TAPE"); /* From environment, or */ ! 111: if (ar_file == 0) { ! 112: ar_file = DEF_AR_FILE; /* From Makefile */ ! 113: } ! 114: ! 115: /* ! 116: * set up the flags to reflect the default pax inteface. Unfortunately ! 117: * the pax interface has several options which are completely opposite ! 118: * of the tar and/or cpio interfaces... ! 119: */ ! 120: f_unconditional = 1; ! 121: f_mtime = 1; ! 122: f_dir_create = 1; ! 123: blocking = 0; ! 124: ar_interface = TAR; ! 125: ar_format = TAR; ! 126: msgfile=stderr; ! 127: ! 128: /* Parse options */ ! 129: while ((c = taropt(argc, argv, "b:cf:hlmortvwx")) != EOF) { ! 130: switch (c) { ! 131: case 'b': /* specify blocking factor */ ! 132: /* ! 133: * FIXME - we should use a conversion routine that does ! 134: * some kind of reasonable error checking, but... ! 135: */ ! 136: blocking = atoi(optarg); ! 137: break; ! 138: case 'c': /* create a new archive */ ! 139: f_create = 1; ! 140: break; ! 141: case 'f': /* specify input/output file */ ! 142: ar_file = optarg; ! 143: break; ! 144: case 'h': ! 145: f_follow_links = 1; /* follow symbolic links */ ! 146: break; ! 147: case 'l': /* report unresolved links */ ! 148: f_linksleft = 1; ! 149: break; ! 150: case 'm': /* don't restore modification times */ ! 151: f_modified = 1; ! 152: break; ! 153: case 'o': /* take on user's group rather than */ ! 154: f_owner = 1; /* archives */ ! 155: break; ! 156: case 'r': /* named files are appended to archive */ ! 157: f_append = 1; ! 158: break; ! 159: case 't': ! 160: f_list = 1; /* list files in archive */ ! 161: break; ! 162: case 'v': /* verbose mode */ ! 163: f_verbose = 1; ! 164: break; ! 165: case 'w': /* user interactive mode */ ! 166: f_disposition = 1; ! 167: break; ! 168: case 'x': /* named files are extracted from archive */ ! 169: f_extract = 1; ! 170: break; ! 171: case '?': ! 172: usage(); ! 173: exit(EX_ARGSBAD); ! 174: } ! 175: } ! 176: ! 177: /* check command line argument sanity */ ! 178: if (f_create + f_extract + f_list + f_append != 1) { ! 179: (void) fprintf(stderr, ! 180: "%s: you must specify exactly one of the c, t, r, or x options\n", ! 181: myname); ! 182: usage(); ! 183: exit(EX_ARGSBAD); ! 184: } ! 185: ! 186: /* set the blocking factor, if not set by the user */ ! 187: if (blocking == 0) { ! 188: #ifdef USG ! 189: if (f_extract || f_list) { ! 190: blocking = DEF_BLOCKING; ! 191: } else { ! 192: blocking = 1; ! 193: } ! 194: #else /* !USG */ ! 195: blocking = 20; ! 196: #endif /* USG */ ! 197: } ! 198: blocksize = blocking * BLOCKSIZE; ! 199: buf_allocate((OFFSET) blocksize); ! 200: ! 201: if (f_create) { ! 202: open_archive(AR_WRITE); ! 203: create_archive(); /* create the archive */ ! 204: } else if (f_extract) { ! 205: open_archive(AR_READ); ! 206: read_archive(); /* extract files from archive */ ! 207: } else if (f_list) { ! 208: open_archive(AR_READ); ! 209: read_archive(); /* read and list contents of archive */ ! 210: } else if (f_append) { ! 211: open_archive(AR_APPEND); ! 212: append_archive(); /* append files to archive */ ! 213: } ! 214: ! 215: if (f_linksleft) { ! 216: linkleft(); /* report any unresolved links */ ! 217: } ! 218: ! 219: return (0); ! 220: } ! 221: ! 222: ! 223: /* taropt - ustar specific getopt ! 224: * ! 225: * DESCRIPTION ! 226: * ! 227: * Plug-compatible replacement for getopt() for parsing tar-like ! 228: * arguments. If the first argument begins with "-", it uses getopt; ! 229: * otherwise, it uses the old rules used by tar, dump, and ps. ! 230: * ! 231: * PARAMETERS ! 232: * ! 233: * int argc - argument count (argc from main) ! 234: * char **argv - argument list (argv from main) ! 235: * char *optstring - sring which describes allowable options ! 236: * ! 237: * RETURNS ! 238: * ! 239: * Returns the next option character in the option string(s). If the ! 240: * option requires an argument and an argument was given, the argument ! 241: * is pointed to by "optarg". If no option character was found, ! 242: * returns an EOF. ! 243: * ! 244: */ ! 245: ! 246: #if __STDC__ ! 247: ! 248: static int taropt(int argc, char **argv, char *optstring) ! 249: ! 250: #else ! 251: ! 252: static int taropt(argc, argv, optstring) ! 253: int argc; ! 254: char **argv; ! 255: char *optstring; ! 256: ! 257: #endif ! 258: { ! 259: extern char *optarg; /* Points to next arg */ ! 260: extern int optind; /* Global argv index */ ! 261: static char *key; /* Points to next keyletter */ ! 262: static char use_getopt; /* !=0 if argv[1][0] was '-' */ ! 263: char c; ! 264: char *place; ! 265: ! 266: optarg = (char *)NULL; ! 267: ! 268: if (key == (char *)NULL) { /* First time */ ! 269: if (argc < 2) ! 270: return EOF; ! 271: key = argv[1]; ! 272: if (*key == '-') ! 273: use_getopt++; ! 274: else ! 275: optind = 2; ! 276: } ! 277: if (use_getopt) { ! 278: return getopt(argc, argv, optstring); ! 279: } ! 280: ! 281: c = *key++; ! 282: if (c == '\0') { ! 283: key--; ! 284: return EOF; ! 285: } ! 286: place = strchr(optstring, c); ! 287: ! 288: if (place == (char *)NULL || c == ':') { ! 289: fprintf(stderr, "%s: unknown option %c\n", argv[0], c); ! 290: return ('?'); ! 291: } ! 292: place++; ! 293: if (*place == ':') { ! 294: if (optind < argc) { ! 295: optarg = argv[optind]; ! 296: optind++; ! 297: } else { ! 298: fprintf(stderr, "%s: %c argument missing\n", ! 299: argv[0], c); ! 300: return ('?'); ! 301: } ! 302: } ! 303: return (c); ! 304: } ! 305: ! 306: ! 307: /* usage - print a helpful message and exit ! 308: * ! 309: * DESCRIPTION ! 310: * ! 311: * Usage prints out the usage message for the TAR interface and then ! 312: * exits with a non-zero termination status. This is used when a user ! 313: * has provided non-existant or incompatible command line arguments. ! 314: * ! 315: * RETURNS ! 316: * ! 317: * Returns an exit status of 1 to the parent process. ! 318: * ! 319: */ ! 320: ! 321: #if __STDC__ ! 322: ! 323: static void usage(void) ! 324: ! 325: #else ! 326: ! 327: static void usage() ! 328: ! 329: #endif ! 330: { ! 331: fprintf(stderr, "Usage: %s -c[bfvw] device block filename..\n", myname); ! 332: fprintf(stderr, " %s -r[bvw] device block [filename...]\n", myname); ! 333: fprintf(stderr, " %s -t[vf] device\n", myname); ! 334: fprintf(stderr, " %s -x[flmovw] device [filename...]\n", myname); ! 335: exit(1); ! 336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.