diff options
author | Matt Kraai <kraai@debian.org> | 2000-12-19 06:24:08 +0000 |
---|---|---|
committer | Matt Kraai <kraai@debian.org> | 2000-12-19 06:24:08 +0000 |
commit | a1f977598138ebf8f5f1672daa936255cf3affc1 (patch) | |
tree | a655709eabc453ddd518c8d0090c3b7cd2ef8219 | |
parent | 24ac0179617e43ab517141fe5497f4ebac108678 (diff) | |
download | busybox-w32-a1f977598138ebf8f5f1672daa936255cf3affc1.tar.gz busybox-w32-a1f977598138ebf8f5f1672daa936255cf3affc1.tar.bz2 busybox-w32-a1f977598138ebf8f5f1672daa936255cf3affc1.zip |
Fix tar handling of absolute paths and excluded directories.
-rw-r--r-- | archival/tar.c | 66 | ||||
-rw-r--r-- | busybox.h | 1 | ||||
-rw-r--r-- | include/busybox.h | 1 | ||||
-rw-r--r-- | tar.c | 66 | ||||
-rw-r--r-- | utility.c | 13 |
5 files changed, 73 insertions, 74 deletions
diff --git a/archival/tar.c b/archival/tar.c index c6a2a6627..463cc50c7 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -252,8 +252,8 @@ extern int tar_main(int argc, char **argv) | |||
252 | if (excludeList[excludeListSize] == NULL) | 252 | if (excludeList[excludeListSize] == NULL) |
253 | error_msg_and_die( "Option requires an argument: No file specified\n"); | 253 | error_msg_and_die( "Option requires an argument: No file specified\n"); |
254 | /* Remove leading "/"s */ | 254 | /* Remove leading "/"s */ |
255 | if (*excludeList[excludeListSize] =='/') | 255 | while (*excludeList[excludeListSize] =='/') |
256 | excludeList[excludeListSize] = (excludeList[excludeListSize])+1; | 256 | excludeList[excludeListSize]++; |
257 | /* Tack a NULL onto the end of the list */ | 257 | /* Tack a NULL onto the end of the list */ |
258 | excludeList[++excludeListSize] = NULL; | 258 | excludeList[++excludeListSize] = NULL; |
259 | stopIt=TRUE; | 259 | stopIt=TRUE; |
@@ -940,43 +940,12 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st | |||
940 | { | 940 | { |
941 | long chksum=0; | 941 | long chksum=0; |
942 | struct TarHeader header; | 942 | struct TarHeader header; |
943 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
944 | char** tmpList; | ||
945 | #endif | ||
946 | const unsigned char *cp = (const unsigned char *) &header; | 943 | const unsigned char *cp = (const unsigned char *) &header; |
947 | ssize_t size = sizeof(struct TarHeader); | 944 | ssize_t size = sizeof(struct TarHeader); |
948 | 945 | ||
949 | memset( &header, 0, size); | 946 | memset( &header, 0, size); |
950 | 947 | ||
951 | if (*fileName=='/') { | 948 | strncpy(header.name, fileName, sizeof(header.name)); |
952 | static int alreadyWarned=FALSE; | ||
953 | if (alreadyWarned==FALSE) { | ||
954 | error_msg("Removing leading '/' from member names\n"); | ||
955 | alreadyWarned=TRUE; | ||
956 | } | ||
957 | strncpy(header.name, fileName+1, sizeof(header.name)); | ||
958 | } | ||
959 | else { | ||
960 | strncpy(header.name, fileName, sizeof(header.name)); | ||
961 | } | ||
962 | |||
963 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
964 | /* Check for excluded files.... */ | ||
965 | for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) { | ||
966 | /* Do some extra hoop jumping for when directory names | ||
967 | * end in '/' but the entry in tmpList doesn't */ | ||
968 | if (strncmp( *tmpList, header.name, strlen(*tmpList))==0 || ( | ||
969 | header.name[strlen(header.name)-1]=='/' | ||
970 | && strncmp( *tmpList, header.name, | ||
971 | MIN(strlen(header.name)-1, strlen(*tmpList)))==0)) { | ||
972 | /* Set the mode to something that is not a regular file, thereby | ||
973 | * faking out writeTarFile into thinking that nothing further need | ||
974 | * be done for this file. Yes, I know this is ugly, but it works. */ | ||
975 | statbuf->st_mode = 0; | ||
976 | return( TRUE); | ||
977 | } | ||
978 | } | ||
979 | #endif | ||
980 | 949 | ||
981 | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); | 950 | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); |
982 | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); | 951 | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); |
@@ -1065,6 +1034,9 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st | |||
1065 | static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData) | 1034 | static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData) |
1066 | { | 1035 | { |
1067 | struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; | 1036 | struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; |
1037 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
1038 | char** tmpList; | ||
1039 | #endif | ||
1068 | 1040 | ||
1069 | /* | 1041 | /* |
1070 | ** Check to see if we are dealing with a hard link. | 1042 | ** Check to see if we are dealing with a hard link. |
@@ -1097,11 +1069,37 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* | |||
1097 | return( TRUE); | 1069 | return( TRUE); |
1098 | } | 1070 | } |
1099 | 1071 | ||
1072 | while (fileName[0] == '/') { | ||
1073 | static int alreadyWarned=FALSE; | ||
1074 | if (alreadyWarned==FALSE) { | ||
1075 | error_msg("Removing leading '/' from member names\n"); | ||
1076 | alreadyWarned=TRUE; | ||
1077 | } | ||
1078 | fileName++; | ||
1079 | } | ||
1080 | |||
1100 | if (strlen(fileName) >= NAME_SIZE) { | 1081 | if (strlen(fileName) >= NAME_SIZE) { |
1101 | error_msg(name_longer_than_foo, NAME_SIZE); | 1082 | error_msg(name_longer_than_foo, NAME_SIZE); |
1102 | return ( TRUE); | 1083 | return ( TRUE); |
1103 | } | 1084 | } |
1104 | 1085 | ||
1086 | if (fileName[0] == '\0') | ||
1087 | return TRUE; | ||
1088 | |||
1089 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
1090 | /* Check for excluded files.... */ | ||
1091 | for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) { | ||
1092 | /* Do some extra hoop jumping for when directory names | ||
1093 | * end in '/' but the entry in tmpList doesn't */ | ||
1094 | if (strncmp( *tmpList, fileName, strlen(*tmpList))==0 || ( | ||
1095 | fileName[strlen(fileName)-1]=='/' | ||
1096 | && strncmp( *tmpList, fileName, | ||
1097 | MIN(strlen(fileName)-1, strlen(*tmpList)))==0)) { | ||
1098 | return SKIP; | ||
1099 | } | ||
1100 | } | ||
1101 | #endif | ||
1102 | |||
1105 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { | 1103 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { |
1106 | return( FALSE); | 1104 | return( FALSE); |
1107 | } | 1105 | } |
@@ -47,6 +47,7 @@ | |||
47 | /* Some useful definitions */ | 47 | /* Some useful definitions */ |
48 | #define FALSE ((int) 0) | 48 | #define FALSE ((int) 0) |
49 | #define TRUE ((int) 1) | 49 | #define TRUE ((int) 1) |
50 | #define SKIP ((int) 2) | ||
50 | 51 | ||
51 | /* for mtab.c */ | 52 | /* for mtab.c */ |
52 | #define MTAB_GETMOUNTPT '1' | 53 | #define MTAB_GETMOUNTPT '1' |
diff --git a/include/busybox.h b/include/busybox.h index 442352537..ae256fe7b 100644 --- a/include/busybox.h +++ b/include/busybox.h | |||
@@ -47,6 +47,7 @@ | |||
47 | /* Some useful definitions */ | 47 | /* Some useful definitions */ |
48 | #define FALSE ((int) 0) | 48 | #define FALSE ((int) 0) |
49 | #define TRUE ((int) 1) | 49 | #define TRUE ((int) 1) |
50 | #define SKIP ((int) 2) | ||
50 | 51 | ||
51 | /* for mtab.c */ | 52 | /* for mtab.c */ |
52 | #define MTAB_GETMOUNTPT '1' | 53 | #define MTAB_GETMOUNTPT '1' |
@@ -252,8 +252,8 @@ extern int tar_main(int argc, char **argv) | |||
252 | if (excludeList[excludeListSize] == NULL) | 252 | if (excludeList[excludeListSize] == NULL) |
253 | error_msg_and_die( "Option requires an argument: No file specified\n"); | 253 | error_msg_and_die( "Option requires an argument: No file specified\n"); |
254 | /* Remove leading "/"s */ | 254 | /* Remove leading "/"s */ |
255 | if (*excludeList[excludeListSize] =='/') | 255 | while (*excludeList[excludeListSize] =='/') |
256 | excludeList[excludeListSize] = (excludeList[excludeListSize])+1; | 256 | excludeList[excludeListSize]++; |
257 | /* Tack a NULL onto the end of the list */ | 257 | /* Tack a NULL onto the end of the list */ |
258 | excludeList[++excludeListSize] = NULL; | 258 | excludeList[++excludeListSize] = NULL; |
259 | stopIt=TRUE; | 259 | stopIt=TRUE; |
@@ -940,43 +940,12 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st | |||
940 | { | 940 | { |
941 | long chksum=0; | 941 | long chksum=0; |
942 | struct TarHeader header; | 942 | struct TarHeader header; |
943 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
944 | char** tmpList; | ||
945 | #endif | ||
946 | const unsigned char *cp = (const unsigned char *) &header; | 943 | const unsigned char *cp = (const unsigned char *) &header; |
947 | ssize_t size = sizeof(struct TarHeader); | 944 | ssize_t size = sizeof(struct TarHeader); |
948 | 945 | ||
949 | memset( &header, 0, size); | 946 | memset( &header, 0, size); |
950 | 947 | ||
951 | if (*fileName=='/') { | 948 | strncpy(header.name, fileName, sizeof(header.name)); |
952 | static int alreadyWarned=FALSE; | ||
953 | if (alreadyWarned==FALSE) { | ||
954 | error_msg("Removing leading '/' from member names\n"); | ||
955 | alreadyWarned=TRUE; | ||
956 | } | ||
957 | strncpy(header.name, fileName+1, sizeof(header.name)); | ||
958 | } | ||
959 | else { | ||
960 | strncpy(header.name, fileName, sizeof(header.name)); | ||
961 | } | ||
962 | |||
963 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
964 | /* Check for excluded files.... */ | ||
965 | for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) { | ||
966 | /* Do some extra hoop jumping for when directory names | ||
967 | * end in '/' but the entry in tmpList doesn't */ | ||
968 | if (strncmp( *tmpList, header.name, strlen(*tmpList))==0 || ( | ||
969 | header.name[strlen(header.name)-1]=='/' | ||
970 | && strncmp( *tmpList, header.name, | ||
971 | MIN(strlen(header.name)-1, strlen(*tmpList)))==0)) { | ||
972 | /* Set the mode to something that is not a regular file, thereby | ||
973 | * faking out writeTarFile into thinking that nothing further need | ||
974 | * be done for this file. Yes, I know this is ugly, but it works. */ | ||
975 | statbuf->st_mode = 0; | ||
976 | return( TRUE); | ||
977 | } | ||
978 | } | ||
979 | #endif | ||
980 | 949 | ||
981 | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); | 950 | putOctal(header.mode, sizeof(header.mode), statbuf->st_mode); |
982 | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); | 951 | putOctal(header.uid, sizeof(header.uid), statbuf->st_uid); |
@@ -1065,6 +1034,9 @@ writeTarHeader(struct TarBallInfo *tbInfo, const char *fileName, struct stat *st | |||
1065 | static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData) | 1034 | static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* userData) |
1066 | { | 1035 | { |
1067 | struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; | 1036 | struct TarBallInfo *tbInfo = (struct TarBallInfo *)userData; |
1037 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
1038 | char** tmpList; | ||
1039 | #endif | ||
1068 | 1040 | ||
1069 | /* | 1041 | /* |
1070 | ** Check to see if we are dealing with a hard link. | 1042 | ** Check to see if we are dealing with a hard link. |
@@ -1097,11 +1069,37 @@ static int writeFileToTarball(const char *fileName, struct stat *statbuf, void* | |||
1097 | return( TRUE); | 1069 | return( TRUE); |
1098 | } | 1070 | } |
1099 | 1071 | ||
1072 | while (fileName[0] == '/') { | ||
1073 | static int alreadyWarned=FALSE; | ||
1074 | if (alreadyWarned==FALSE) { | ||
1075 | error_msg("Removing leading '/' from member names\n"); | ||
1076 | alreadyWarned=TRUE; | ||
1077 | } | ||
1078 | fileName++; | ||
1079 | } | ||
1080 | |||
1100 | if (strlen(fileName) >= NAME_SIZE) { | 1081 | if (strlen(fileName) >= NAME_SIZE) { |
1101 | error_msg(name_longer_than_foo, NAME_SIZE); | 1082 | error_msg(name_longer_than_foo, NAME_SIZE); |
1102 | return ( TRUE); | 1083 | return ( TRUE); |
1103 | } | 1084 | } |
1104 | 1085 | ||
1086 | if (fileName[0] == '\0') | ||
1087 | return TRUE; | ||
1088 | |||
1089 | #if defined BB_FEATURE_TAR_EXCLUDE | ||
1090 | /* Check for excluded files.... */ | ||
1091 | for (tmpList=tbInfo->excludeList; tmpList && *tmpList; tmpList++) { | ||
1092 | /* Do some extra hoop jumping for when directory names | ||
1093 | * end in '/' but the entry in tmpList doesn't */ | ||
1094 | if (strncmp( *tmpList, fileName, strlen(*tmpList))==0 || ( | ||
1095 | fileName[strlen(fileName)-1]=='/' | ||
1096 | && strncmp( *tmpList, fileName, | ||
1097 | MIN(strlen(fileName)-1, strlen(*tmpList)))==0)) { | ||
1098 | return SKIP; | ||
1099 | } | ||
1100 | } | ||
1101 | #endif | ||
1102 | |||
1105 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { | 1103 | if (writeTarHeader(tbInfo, fileName, statbuf)==FALSE) { |
1106 | return( FALSE); | 1104 | return( FALSE); |
1107 | } | 1105 | } |
@@ -663,17 +663,18 @@ int recursive_action(const char *fileName, | |||
663 | if (S_ISDIR(statbuf.st_mode)) { | 663 | if (S_ISDIR(statbuf.st_mode)) { |
664 | DIR *dir; | 664 | DIR *dir; |
665 | 665 | ||
666 | dir = opendir(fileName); | ||
667 | if (!dir) { | ||
668 | perror_msg("%s", fileName); | ||
669 | return FALSE; | ||
670 | } | ||
671 | if (dirAction != NULL && depthFirst == FALSE) { | 666 | if (dirAction != NULL && depthFirst == FALSE) { |
672 | status = dirAction(fileName, &statbuf, userData); | 667 | status = dirAction(fileName, &statbuf, userData); |
673 | if (status == FALSE) { | 668 | if (status == FALSE) { |
674 | perror_msg("%s", fileName); | 669 | perror_msg("%s", fileName); |
675 | return FALSE; | 670 | return FALSE; |
676 | } | 671 | } else if (status == SKIP) |
672 | return TRUE; | ||
673 | } | ||
674 | dir = opendir(fileName); | ||
675 | if (!dir) { | ||
676 | perror_msg("%s", fileName); | ||
677 | return FALSE; | ||
677 | } | 678 | } |
678 | while ((next = readdir(dir)) != NULL) { | 679 | while ((next = readdir(dir)) != NULL) { |
679 | char nextFile[BUFSIZ + 1]; | 680 | char nextFile[BUFSIZ + 1]; |