aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Kraai <kraai@debian.org>2001-01-03 17:22:10 +0000
committerMatt Kraai <kraai@debian.org>2001-01-03 17:22:10 +0000
commitbe7499c83c45a5953580f24189fb3473e5ec01e4 (patch)
treee8256ba6a8372be48d9c5f37d8641ec41f206cfb
parenta9711a59695d0c0591e8786a2ea811940ef8735a (diff)
downloadbusybox-w32-be7499c83c45a5953580f24189fb3473e5ec01e4.tar.gz
busybox-w32-be7499c83c45a5953580f24189fb3473e5ec01e4.tar.bz2
busybox-w32-be7499c83c45a5953580f24189fb3473e5ec01e4.zip
Behave like GNU tar when matching excluded files.
-rw-r--r--archival/tar.c81
-rw-r--r--tar.c81
2 files changed, 78 insertions, 84 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 4971e4775..9a3cff361 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -51,6 +51,7 @@
51#include <sys/types.h> 51#include <sys/types.h>
52#include <sys/sysmacros.h> 52#include <sys/sysmacros.h>
53#include <getopt.h> 53#include <getopt.h>
54#include <fnmatch.h>
54 55
55#ifdef BB_FEATURE_TAR_GZIP 56#ifdef BB_FEATURE_TAR_GZIP
56extern int unzip(int in, int out); 57extern int unzip(int in, int out);
@@ -251,9 +252,6 @@ extern int tar_main(int argc, char **argv)
251 excludeList[excludeListSize] = *(++argv); 252 excludeList[excludeListSize] = *(++argv);
252 if (excludeList[excludeListSize] == NULL) 253 if (excludeList[excludeListSize] == NULL)
253 error_msg_and_die( "Option requires an argument: No file specified\n"); 254 error_msg_and_die( "Option requires an argument: No file specified\n");
254 /* Remove leading "/"s */
255 while (*excludeList[excludeListSize] =='/')
256 excludeList[excludeListSize]++;
257 /* Tack a NULL onto the end of the list */ 255 /* Tack a NULL onto the end of the list */
258 excludeList[++excludeListSize] = NULL; 256 excludeList[++excludeListSize] = NULL;
259 stopIt=TRUE; 257 stopIt=TRUE;
@@ -274,9 +272,6 @@ extern int tar_main(int argc, char **argv)
274 if (file[strlen(file)-1] == '\n') 272 if (file[strlen(file)-1] == '\n')
275 file[strlen(file)-1] = '\0'; 273 file[strlen(file)-1] = '\0';
276 excludeList[excludeListSize] = xstrdup(file); 274 excludeList[excludeListSize] = xstrdup(file);
277 /* Remove leading "/"s */
278 while (*excludeList[excludeListSize] == '/')
279 excludeList[excludeListSize]++;
280 /* Tack a NULL onto the end of the list */ 275 /* Tack a NULL onto the end of the list */
281 excludeList[++excludeListSize] = NULL; 276 excludeList[++excludeListSize] = NULL;
282 } 277 }
@@ -576,6 +571,32 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
576 return( FALSE); 571 return( FALSE);
577} 572}
578 573
574int exclude_file(char **excluded_files, const char *file)
575{
576 int i;
577
578 if (excluded_files == NULL)
579 return 0;
580
581 for (i = 0; excluded_files[i] != NULL; i++) {
582 if (excluded_files[i][0] == '/') {
583 if (fnmatch(excluded_files[i], file,
584 FNM_PATHNAME | FNM_LEADING_DIR) == 0)
585 return 1;
586 } else {
587 const char *p;
588
589 for (p = file; p[0] != '\0'; p++) {
590 if ((p == file || p[-1] == '/') && p[0] != '/' &&
591 fnmatch(excluded_files[i], p,
592 FNM_PATHNAME | FNM_LEADING_DIR) == 0)
593 return 1;
594 }
595 }
596 }
597
598 return 0;
599}
579 600
580/* 601/*
581 * Read a tar file and extract or list the specified files within it. 602 * Read a tar file and extract or list the specified files within it.
@@ -629,32 +650,19 @@ extern int readTarFile(int tarFd, int extractFlag, int listFlag,
629 } 650 }
630 651
631#if defined BB_FEATURE_TAR_EXCLUDE 652#if defined BB_FEATURE_TAR_EXCLUDE
632 { 653 if (exclude_file(excludeList, header.name)) {
633 int skipFlag=FALSE;
634 /* Check for excluded files.... */
635 for (tmpList=excludeList; tmpList && *tmpList; tmpList++) {
636 /* Do some extra hoop jumping for when directory names
637 * end in '/' but the entry in tmpList doesn't */
638 if (strncmp( *tmpList, header.name, strlen(*tmpList))==0 || (
639 header.name[strlen(header.name)-1]=='/'
640 && strncmp( *tmpList, header.name,
641 MIN(strlen(header.name)-1, strlen(*tmpList)))==0)) {
642 /* If it is a regular file, pretend to extract it with
643 * the extractFlag set to FALSE, so the junk in the tarball
644 * is properly skipped over */
645 if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
646 if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
647 errorFlag = TRUE;
648 }
649 skipFlag=TRUE;
650 break;
651 }
652 }
653 /* There are not the droids you're looking for, move along */ 654 /* There are not the droids you're looking for, move along */
654 if (skipFlag==TRUE) 655 /* If it is a regular file, pretend to extract it with
655 continue; 656 * the extractFlag set to FALSE, so the junk in the tarball
657 * is properly skipped over */
658 if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
659 if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
660 errorFlag = TRUE;
661 }
662 continue;
656 } 663 }
657#endif 664#endif
665
658 if (extractList != NULL) { 666 if (extractList != NULL) {
659 int skipFlag = TRUE; 667 int skipFlag = TRUE;
660 for (tmpList = extractList; *tmpList != NULL; tmpList++) { 668 for (tmpList = extractList; *tmpList != NULL; tmpList++) {
@@ -1036,9 +1044,6 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
1036{ 1044{
1037 struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; 1045 struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData;
1038 const char *header_name; 1046 const char *header_name;
1039#if defined BB_FEATURE_TAR_EXCLUDE
1040 char** tmpList;
1041#endif
1042 1047
1043 /* 1048 /*
1044 ** Check to see if we are dealing with a hard link. 1049 ** Check to see if we are dealing with a hard link.
@@ -1090,16 +1095,8 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
1090 return TRUE; 1095 return TRUE;
1091 1096
1092#if defined BB_FEATURE_TAR_EXCLUDE 1097#if defined BB_FEATURE_TAR_EXCLUDE
1093 /* Check for excluded files.... */ 1098 if (exclude_file(tbInfo->excludeList, header_name)) {
1094 for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) { 1099 return SKIP;
1095 /* Do some extra hoop jumping for when directory names
1096 * end in '/' but the entry in tmpList doesn't */
1097 if (strncmp( *tmpList, header_name, strlen(*tmpList))==0 || (
1098 fileName[strlen(fileName)-1]=='/'
1099 && strncmp( *tmpList, fileName,
1100 MIN(strlen(fileName)-1, strlen(*tmpList)))==0)) {
1101 return SKIP;
1102 }
1103 } 1100 }
1104#endif 1101#endif
1105 1102
diff --git a/tar.c b/tar.c
index 4971e4775..9a3cff361 100644
--- a/tar.c
+++ b/tar.c
@@ -51,6 +51,7 @@
51#include <sys/types.h> 51#include <sys/types.h>
52#include <sys/sysmacros.h> 52#include <sys/sysmacros.h>
53#include <getopt.h> 53#include <getopt.h>
54#include <fnmatch.h>
54 55
55#ifdef BB_FEATURE_TAR_GZIP 56#ifdef BB_FEATURE_TAR_GZIP
56extern int unzip(int in, int out); 57extern int unzip(int in, int out);
@@ -251,9 +252,6 @@ extern int tar_main(int argc, char **argv)
251 excludeList[excludeListSize] = *(++argv); 252 excludeList[excludeListSize] = *(++argv);
252 if (excludeList[excludeListSize] == NULL) 253 if (excludeList[excludeListSize] == NULL)
253 error_msg_and_die( "Option requires an argument: No file specified\n"); 254 error_msg_and_die( "Option requires an argument: No file specified\n");
254 /* Remove leading "/"s */
255 while (*excludeList[excludeListSize] =='/')
256 excludeList[excludeListSize]++;
257 /* Tack a NULL onto the end of the list */ 255 /* Tack a NULL onto the end of the list */
258 excludeList[++excludeListSize] = NULL; 256 excludeList[++excludeListSize] = NULL;
259 stopIt=TRUE; 257 stopIt=TRUE;
@@ -274,9 +272,6 @@ extern int tar_main(int argc, char **argv)
274 if (file[strlen(file)-1] == '\n') 272 if (file[strlen(file)-1] == '\n')
275 file[strlen(file)-1] = '\0'; 273 file[strlen(file)-1] = '\0';
276 excludeList[excludeListSize] = xstrdup(file); 274 excludeList[excludeListSize] = xstrdup(file);
277 /* Remove leading "/"s */
278 while (*excludeList[excludeListSize] == '/')
279 excludeList[excludeListSize]++;
280 /* Tack a NULL onto the end of the list */ 275 /* Tack a NULL onto the end of the list */
281 excludeList[++excludeListSize] = NULL; 276 excludeList[++excludeListSize] = NULL;
282 } 277 }
@@ -576,6 +571,32 @@ readTarHeader(struct TarHeader *rawHeader, struct TarInfo *header)
576 return( FALSE); 571 return( FALSE);
577} 572}
578 573
574int exclude_file(char **excluded_files, const char *file)
575{
576 int i;
577
578 if (excluded_files == NULL)
579 return 0;
580
581 for (i = 0; excluded_files[i] != NULL; i++) {
582 if (excluded_files[i][0] == '/') {
583 if (fnmatch(excluded_files[i], file,
584 FNM_PATHNAME | FNM_LEADING_DIR) == 0)
585 return 1;
586 } else {
587 const char *p;
588
589 for (p = file; p[0] != '\0'; p++) {
590 if ((p == file || p[-1] == '/') && p[0] != '/' &&
591 fnmatch(excluded_files[i], p,
592 FNM_PATHNAME | FNM_LEADING_DIR) == 0)
593 return 1;
594 }
595 }
596 }
597
598 return 0;
599}
579 600
580/* 601/*
581 * Read a tar file and extract or list the specified files within it. 602 * Read a tar file and extract or list the specified files within it.
@@ -629,32 +650,19 @@ extern int readTarFile(int tarFd, int extractFlag, int listFlag,
629 } 650 }
630 651
631#if defined BB_FEATURE_TAR_EXCLUDE 652#if defined BB_FEATURE_TAR_EXCLUDE
632 { 653 if (exclude_file(excludeList, header.name)) {
633 int skipFlag=FALSE;
634 /* Check for excluded files.... */
635 for (tmpList=excludeList; tmpList && *tmpList; tmpList++) {
636 /* Do some extra hoop jumping for when directory names
637 * end in '/' but the entry in tmpList doesn't */
638 if (strncmp( *tmpList, header.name, strlen(*tmpList))==0 || (
639 header.name[strlen(header.name)-1]=='/'
640 && strncmp( *tmpList, header.name,
641 MIN(strlen(header.name)-1, strlen(*tmpList)))==0)) {
642 /* If it is a regular file, pretend to extract it with
643 * the extractFlag set to FALSE, so the junk in the tarball
644 * is properly skipped over */
645 if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
646 if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
647 errorFlag = TRUE;
648 }
649 skipFlag=TRUE;
650 break;
651 }
652 }
653 /* There are not the droids you're looking for, move along */ 654 /* There are not the droids you're looking for, move along */
654 if (skipFlag==TRUE) 655 /* If it is a regular file, pretend to extract it with
655 continue; 656 * the extractFlag set to FALSE, so the junk in the tarball
657 * is properly skipped over */
658 if ( header.type==REGTYPE || header.type==REGTYPE0 ) {
659 if (tarExtractRegularFile(&header, FALSE, FALSE) == FALSE)
660 errorFlag = TRUE;
661 }
662 continue;
656 } 663 }
657#endif 664#endif
665
658 if (extractList != NULL) { 666 if (extractList != NULL) {
659 int skipFlag = TRUE; 667 int skipFlag = TRUE;
660 for (tmpList = extractList; *tmpList != NULL; tmpList++) { 668 for (tmpList = extractList; *tmpList != NULL; tmpList++) {
@@ -1036,9 +1044,6 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
1036{ 1044{
1037 struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; 1045 struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData;
1038 const char *header_name; 1046 const char *header_name;
1039#if defined BB_FEATURE_TAR_EXCLUDE
1040 char** tmpList;
1041#endif
1042 1047
1043 /* 1048 /*
1044 ** Check to see if we are dealing with a hard link. 1049 ** Check to see if we are dealing with a hard link.
@@ -1090,16 +1095,8 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void*
1090 return TRUE; 1095 return TRUE;
1091 1096
1092#if defined BB_FEATURE_TAR_EXCLUDE 1097#if defined BB_FEATURE_TAR_EXCLUDE
1093 /* Check for excluded files.... */ 1098 if (exclude_file(tbInfo->excludeList, header_name)) {
1094 for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) { 1099 return SKIP;
1095 /* Do some extra hoop jumping for when directory names
1096 * end in '/' but the entry in tmpList doesn't */
1097 if (strncmp( *tmpList, header_name, strlen(*tmpList))==0 || (
1098 fileName[strlen(fileName)-1]=='/'
1099 && strncmp( *tmpList, fileName,
1100 MIN(strlen(fileName)-1, strlen(*tmpList)))==0)) {
1101 return SKIP;
1102 }
1103 } 1100 }
1104#endif 1101#endif
1105 1102