diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c new file mode 100644 index 000000000..b20cc2695 --- /dev/null +++ b/archival/dpkg_deb.c @@ -0,0 +1,159 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include "busybox.h" + +typedef struct ar_headers_s { + char *name; + size_t size; + uid_t uid; + gid_t gid; + mode_t mode; + time_t mtime; + off_t offset; + struct ar_headers_s *next; +} ar_headers_t; + +extern ar_headers_t get_headers(int srcFd); +extern int tar_unzip_init(int tarFd); +extern int readTarFile(int tarFd, int extractFlag, int listFlag, + int tostdoutFlag, int verboseFlag, char** extractList, + char** excludeList); + +extern int dpkg_deb_main(int argc, char **argv) +{ + const int dpkg_deb_contents = 1; + const int dpkg_deb_control = 2; + const int dpkg_deb_info = 4; + const int dpkg_deb_extract = 8; + const int dpkg_deb_verbose_extract = 16; + int opt=0; + int optflag=0; + int extract_flag = FALSE; + int list_flag = FALSE; + int verbose_flag = FALSE; + int extract_to_stdout = FALSE; + char ar_filename[15]; + int srcFd=0; + int status=0; + ar_headers_t *ar_headers = NULL; + char **extract_list=NULL; + char *target_dir=NULL; + + while ((opt = getopt(argc, argv, "cexX")) != -1) { + switch (opt) { + case 'c': + optflag |= dpkg_deb_contents; + break; + case 'e': + optflag |= dpkg_deb_control; + break; +/* case 'I': + optflag |= dpkg_deb_info; + break; +*/ + case 'x': + optflag |= dpkg_deb_extract; + break; + case 'X': + optflag |= dpkg_deb_verbose_extract; + break; + default: + usage(dpkg_deb_usage); + return EXIT_FAILURE; + } + } + + if (((optind + 1 ) > argc) || (optflag == 0)) { + usage(dpkg_deb_usage); + return(EXIT_FAILURE); + } + + if (optflag & dpkg_deb_contents) { + list_flag = TRUE; + verbose_flag = TRUE; + strcpy(ar_filename, "data.tar.gz"); + } + else if (optflag & dpkg_deb_control) { + extract_flag = TRUE; + strcpy(ar_filename, "control.tar.gz"); + if ( (optind + 1) == argc ) { + target_dir = (char *) xmalloc(7); + strcpy(target_dir, "DEBIAN"); + } + else { + target_dir = (char *) xmalloc(strlen(argv[optind+1])); + + strcpy(target_dir, argv[optind+1]); + } + } +/* else if (optflag & dpkg_deb_info) { + extract_flag = TRUE; + extract_to_stdout = TRUE; + strcpy(ar_filename, "control.tar.gz"); + extract_list = argv+optind+1; + printf("list one is [%s]\n",extract_list[0]); + } +*/ + else if (optflag & dpkg_deb_extract) { + extract_flag = TRUE; + strcpy(ar_filename, "data.tar.gz"); + if ( (optind + 2) > argc ) { + error_msg_and_die("No directory specified\n"); + } + target_dir = (char *) xmalloc(strlen(argv[optind+1])); + strcpy(target_dir, argv[optind+1]); + } + else if (optflag & dpkg_deb_verbose_extract) { + extract_flag = TRUE; + list_flag = TRUE; + strcpy(ar_filename, "data.tar.gz"); + if ( (optind + 2) > argc ) { + error_msg_and_die("No directory specified\n"); + } + target_dir = (char *) xmalloc(strlen(argv[optind+1])); + strcpy(target_dir, argv[optind+1]); + } + + ar_headers = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); + srcFd = open(argv[optind], O_RDONLY); + + *ar_headers = get_headers(srcFd); + if (ar_headers->next==NULL) + error_msg_and_die("Couldnt find %s in %s\n",ar_filename, argv[optind]); + + while (ar_headers->next != NULL) { + if (strcmp(ar_headers->name, ar_filename)==0) + break; + ar_headers = ar_headers->next; + } + + lseek(srcFd, ar_headers->offset, SEEK_SET); + srcFd = tar_unzip_init(srcFd); + if ( target_dir != NULL) { + if (is_directory(target_dir, TRUE, NULL)==FALSE) { + mkdir(target_dir, 0755); + } + if (chdir(target_dir)==-1) { + error_msg_and_die("Cannot change to dir %s\n",argv[optind+1]); + } + } + status = readTarFile(srcFd, extract_flag, list_flag, extract_to_stdout, verbose_flag, NULL, extract_list); + return(EXIT_SUCCESS); +} diff --git a/dpkg_deb.c b/dpkg_deb.c new file mode 100644 index 000000000..b20cc2695 --- /dev/null +++ b/dpkg_deb.c @@ -0,0 +1,159 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include "busybox.h" + +typedef struct ar_headers_s { + char *name; + size_t size; + uid_t uid; + gid_t gid; + mode_t mode; + time_t mtime; + off_t offset; + struct ar_headers_s *next; +} ar_headers_t; + +extern ar_headers_t get_headers(int srcFd); +extern int tar_unzip_init(int tarFd); +extern int readTarFile(int tarFd, int extractFlag, int listFlag, + int tostdoutFlag, int verboseFlag, char** extractList, + char** excludeList); + +extern int dpkg_deb_main(int argc, char **argv) +{ + const int dpkg_deb_contents = 1; + const int dpkg_deb_control = 2; + const int dpkg_deb_info = 4; + const int dpkg_deb_extract = 8; + const int dpkg_deb_verbose_extract = 16; + int opt=0; + int optflag=0; + int extract_flag = FALSE; + int list_flag = FALSE; + int verbose_flag = FALSE; + int extract_to_stdout = FALSE; + char ar_filename[15]; + int srcFd=0; + int status=0; + ar_headers_t *ar_headers = NULL; + char **extract_list=NULL; + char *target_dir=NULL; + + while ((opt = getopt(argc, argv, "cexX")) != -1) { + switch (opt) { + case 'c': + optflag |= dpkg_deb_contents; + break; + case 'e': + optflag |= dpkg_deb_control; + break; +/* case 'I': + optflag |= dpkg_deb_info; + break; +*/ + case 'x': + optflag |= dpkg_deb_extract; + break; + case 'X': + optflag |= dpkg_deb_verbose_extract; + break; + default: + usage(dpkg_deb_usage); + return EXIT_FAILURE; + } + } + + if (((optind + 1 ) > argc) || (optflag == 0)) { + usage(dpkg_deb_usage); + return(EXIT_FAILURE); + } + + if (optflag & dpkg_deb_contents) { + list_flag = TRUE; + verbose_flag = TRUE; + strcpy(ar_filename, "data.tar.gz"); + } + else if (optflag & dpkg_deb_control) { + extract_flag = TRUE; + strcpy(ar_filename, "control.tar.gz"); + if ( (optind + 1) == argc ) { + target_dir = (char *) xmalloc(7); + strcpy(target_dir, "DEBIAN"); + } + else { + target_dir = (char *) xmalloc(strlen(argv[optind+1])); + + strcpy(target_dir, argv[optind+1]); + } + } +/* else if (optflag & dpkg_deb_info) { + extract_flag = TRUE; + extract_to_stdout = TRUE; + strcpy(ar_filename, "control.tar.gz"); + extract_list = argv+optind+1; + printf("list one is [%s]\n",extract_list[0]); + } +*/ + else if (optflag & dpkg_deb_extract) { + extract_flag = TRUE; + strcpy(ar_filename, "data.tar.gz"); + if ( (optind + 2) > argc ) { + error_msg_and_die("No directory specified\n"); + } + target_dir = (char *) xmalloc(strlen(argv[optind+1])); + strcpy(target_dir, argv[optind+1]); + } + else if (optflag & dpkg_deb_verbose_extract) { + extract_flag = TRUE; + list_flag = TRUE; + strcpy(ar_filename, "data.tar.gz"); + if ( (optind + 2) > argc ) { + error_msg_and_die("No directory specified\n"); + } + target_dir = (char *) xmalloc(strlen(argv[optind+1])); + strcpy(target_dir, argv[optind+1]); + } + + ar_headers = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); + srcFd = open(argv[optind], O_RDONLY); + + *ar_headers = get_headers(srcFd); + if (ar_headers->next==NULL) + error_msg_and_die("Couldnt find %s in %s\n",ar_filename, argv[optind]); + + while (ar_headers->next != NULL) { + if (strcmp(ar_headers->name, ar_filename)==0) + break; + ar_headers = ar_headers->next; + } + + lseek(srcFd, ar_headers->offset, SEEK_SET); + srcFd = tar_unzip_init(srcFd); + if ( target_dir != NULL) { + if (is_directory(target_dir, TRUE, NULL)==FALSE) { + mkdir(target_dir, 0755); + } + if (chdir(target_dir)==-1) { + error_msg_and_die("Cannot change to dir %s\n",argv[optind+1]); + } + } + status = readTarFile(srcFd, extract_flag, list_flag, extract_to_stdout, verbose_flag, NULL, extract_list); + return(EXIT_SUCCESS); +}