Print this page
3474 tar should support -C on extract
Reviewed by: Robert Mustacchi <rm@joyent.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2012 Milan Jurik. All rights reserved.

  24  */
  25 
  26 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27 /*        All Rights Reserved   */
  28 
  29 /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  30 /*        All Rights Reserved   */
  31 
  32 /*
  33  * Portions of this source code were derived from Berkeley 4.3 BSD
  34  * under license from the Regents of the University of California.
  35  */
  36 
  37 #include <unistd.h>
  38 #include <sys/types.h>
  39 #include <sys/param.h>
  40 #include <sys/stat.h>
  41 #include <sys/mkdev.h>
  42 #include <sys/wait.h>
  43 #include <dirent.h>


 544     char *name, int oflag, mode_t mode);
 545 static char *skipslashes(char *string, char *start);
 546 static void chop_endslashes(char *path);
 547 static pid_t compress_file(void);
 548 static void compress_back(void);
 549 static void decompress_file(void);
 550 static pid_t uncompress_file(void);
 551 static void *compress_malloc(size_t);
 552 static void check_compression(void);
 553 static char *bz_suffix(void);
 554 static char *gz_suffix(void);
 555 static char *xz_suffix(void);
 556 static char *add_suffix();
 557 static void wait_pid(pid_t);
 558 static void verify_compress_opt(const char *t);
 559 static void detect_compress(void);
 560 
 561 static  struct stat stbuf;
 562 
 563 static  char    *myname;

 564 static  int     checkflag = 0;
 565 static  int     Xflag, Fflag, iflag, hflag, Bflag, Iflag;
 566 static  int     rflag, xflag, vflag, tflag, mt, svmt, cflag, mflag, pflag;
 567 static  int     uflag;
 568 static  int     errflag;
 569 static  int     oflag;
 570 static  int     bflag, Aflag;
 571 static  int     Pflag;                  /* POSIX conformant archive */
 572 static  int     Eflag;                  /* Allow files greater than 8GB */
 573 static  int     atflag;                 /* traverse extended attributes */
 574 static  int     saflag;                 /* traverse extended sys attributes */
 575 static  int     Dflag;                  /* Data change flag */
 576 static  int     jflag;                  /* flag to use 'bzip2' */
 577 static  int     zflag;                  /* flag to use 'gzip' */
 578 static  int     Zflag;                  /* flag to use 'compress' */
 579 static  int     Jflag;                  /* flag to use 'xz' */
 580 static  int     aflag;                  /* flag to use autocompression */
 581 
 582 /* Trusted Extensions */
 583 static  int     Tflag;                  /* Trusted Extensions attr flags */


1121                         compress_back();
1122         } else if (xflag || tflag) {
1123                 /*
1124                  * for each argument, check to see if there is a "-I file" pair.
1125                  * if so, move the 3rd argument into "-I"'s place, build_table()
1126                  * using "file"'s name and increment argc one (the second
1127                  * increment appears in the for loop) which removes the two
1128                  * args "-I" and "file" from the argument vector.
1129                  */
1130                 for (argc = 0; argv[argc]; argc++) {
1131                         if (strcmp(argv[argc], "-I") == 0) {
1132                                 if (!argv[argc+1]) {
1133                                         (void) fprintf(stderr, gettext(
1134                                         "tar: missing argument for -I flag\n"));
1135                                         done(2);
1136                                 } else {
1137                                         Iflag = 1;
1138                                         argv[argc] = argv[argc+2];
1139                                         build_table(include_tbl, argv[++argc]);
1140                                 }













1141                         }
1142                 }

1143                 if (strcmp(usefile, "-") == 0) {
1144                         mt = dup(0);
1145                         ++bflag;
1146                         /* try to recover from short reads when reading stdin */
1147                         ++Bflag;
1148                 } else if ((mt = open(usefile, 0)) < 0)
1149                         vperror(1, "%s", usefile);
1150 
1151                 /* Decompress if the file is compressed */
1152 
1153                 if (strcmp(usefile, "-") != 0) {
1154                         check_compression();
1155                         if (compress_opt != NULL) {
1156                                 pid = uncompress_file();
1157                                 wait_pid(pid);
1158                         }
1159                 }
1160                 if (xflag) {






1161                         if (Aflag && vflag)
1162                                 (void) printf(gettext(
1163                                     "Suppressing absolute pathnames.\n"));
1164 
1165                         doxtract(argv);
1166                 } else if (tflag)
1167                         dotable(argv);
1168         }
1169         else
1170                 usage();
1171 
1172         done(Errflg);
1173 
1174         /* Not reached:  keep compiler quiet */
1175         return (1);
1176 }
1177 
1178 static void
1179 usage(void)
1180 {




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2012 Milan Jurik. All rights reserved.
  24  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  25  */
  26 
  27 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  28 /*        All Rights Reserved   */
  29 
  30 /*      Copyright (c) 1987, 1988 Microsoft Corporation  */
  31 /*        All Rights Reserved   */
  32 
  33 /*
  34  * Portions of this source code were derived from Berkeley 4.3 BSD
  35  * under license from the Regents of the University of California.
  36  */
  37 
  38 #include <unistd.h>
  39 #include <sys/types.h>
  40 #include <sys/param.h>
  41 #include <sys/stat.h>
  42 #include <sys/mkdev.h>
  43 #include <sys/wait.h>
  44 #include <dirent.h>


 545     char *name, int oflag, mode_t mode);
 546 static char *skipslashes(char *string, char *start);
 547 static void chop_endslashes(char *path);
 548 static pid_t compress_file(void);
 549 static void compress_back(void);
 550 static void decompress_file(void);
 551 static pid_t uncompress_file(void);
 552 static void *compress_malloc(size_t);
 553 static void check_compression(void);
 554 static char *bz_suffix(void);
 555 static char *gz_suffix(void);
 556 static char *xz_suffix(void);
 557 static char *add_suffix();
 558 static void wait_pid(pid_t);
 559 static void verify_compress_opt(const char *t);
 560 static void detect_compress(void);
 561 
 562 static  struct stat stbuf;
 563 
 564 static  char    *myname;
 565 static  char    *xtract_chdir = NULL;
 566 static  int     checkflag = 0;
 567 static  int     Xflag, Fflag, iflag, hflag, Bflag, Iflag;
 568 static  int     rflag, xflag, vflag, tflag, mt, svmt, cflag, mflag, pflag;
 569 static  int     uflag;
 570 static  int     errflag;
 571 static  int     oflag;
 572 static  int     bflag, Aflag;
 573 static  int     Pflag;                  /* POSIX conformant archive */
 574 static  int     Eflag;                  /* Allow files greater than 8GB */
 575 static  int     atflag;                 /* traverse extended attributes */
 576 static  int     saflag;                 /* traverse extended sys attributes */
 577 static  int     Dflag;                  /* Data change flag */
 578 static  int     jflag;                  /* flag to use 'bzip2' */
 579 static  int     zflag;                  /* flag to use 'gzip' */
 580 static  int     Zflag;                  /* flag to use 'compress' */
 581 static  int     Jflag;                  /* flag to use 'xz' */
 582 static  int     aflag;                  /* flag to use autocompression */
 583 
 584 /* Trusted Extensions */
 585 static  int     Tflag;                  /* Trusted Extensions attr flags */


1123                         compress_back();
1124         } else if (xflag || tflag) {
1125                 /*
1126                  * for each argument, check to see if there is a "-I file" pair.
1127                  * if so, move the 3rd argument into "-I"'s place, build_table()
1128                  * using "file"'s name and increment argc one (the second
1129                  * increment appears in the for loop) which removes the two
1130                  * args "-I" and "file" from the argument vector.
1131                  */
1132                 for (argc = 0; argv[argc]; argc++) {
1133                         if (strcmp(argv[argc], "-I") == 0) {
1134                                 if (!argv[argc+1]) {
1135                                         (void) fprintf(stderr, gettext(
1136                                         "tar: missing argument for -I flag\n"));
1137                                         done(2);
1138                                 } else {
1139                                         Iflag = 1;
1140                                         argv[argc] = argv[argc+2];
1141                                         build_table(include_tbl, argv[++argc]);
1142                                 }
1143                         } else if (strcmp(argv[argc], "-C") == 0) {
1144                                 if (!argv[argc+1]) {
1145                                         (void) fprintf(stderr, gettext("tar: "
1146                                             "missing argument for -C flag\n"));
1147                                         done(2);
1148                                 } else if (xtract_chdir != NULL) {
1149                                         (void) fprintf(stderr, gettext("tar: "
1150                                             "extract should have only one -C "
1151                                             "flag\n"));
1152                                         done(2);
1153                                 } else {
1154                                         argv[argc] = argv[argc+2];
1155                                         xtract_chdir = argv[++argc];
1156                                 }
1157                         }
1158                 }
1159                 if (strcmp(usefile, "-") == 0) {
1160                         mt = dup(0);
1161                         ++bflag;
1162                         /* try to recover from short reads when reading stdin */
1163                         ++Bflag;
1164                 } else if ((mt = open(usefile, 0)) < 0)
1165                         vperror(1, "%s", usefile);
1166 
1167                 /* Decompress if the file is compressed */
1168 
1169                 if (strcmp(usefile, "-") != 0) {
1170                         check_compression();
1171                         if (compress_opt != NULL) {
1172                                 pid = uncompress_file();
1173                                 wait_pid(pid);
1174                         }
1175                 }
1176                 if (xflag) {
1177                         if (xtract_chdir != NULL) {
1178                                 if (tar_chdir(xtract_chdir) < 0) {
1179                                         vperror(1, gettext("can't change "
1180                                             "directories to %s"), xtract_chdir);
1181                                 }
1182                         }
1183                         if (Aflag && vflag)
1184                                 (void) printf(gettext(
1185                                     "Suppressing absolute pathnames.\n"));
1186 
1187                         doxtract(argv);
1188                 } else if (tflag)
1189                         dotable(argv);
1190         }
1191         else
1192                 usage();
1193 
1194         done(Errflg);
1195 
1196         /* Not reached:  keep compiler quiet */
1197         return (1);
1198 }
1199 
1200 static void
1201 usage(void)
1202 {