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