busybox/archival/dpkg_deb.c
<<
>>
Prefs
   1/* vi: set sw=4 ts=4: */
   2/*
   3 * dpkg-deb packs, unpacks and provides information about Debian archives.
   4 *
   5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
   6 */
   7#include "libbb.h"
   8#include "unarchive.h"
   9
  10#define DPKG_DEB_OPT_CONTENTS   1
  11#define DPKG_DEB_OPT_CONTROL    2
  12#define DPKG_DEB_OPT_FIELD      4
  13#define DPKG_DEB_OPT_EXTRACT    8
  14#define DPKG_DEB_OPT_EXTRACT_VERBOSE    16
  15
  16int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  17int dpkg_deb_main(int argc, char **argv)
  18{
  19        archive_handle_t *ar_archive;
  20        archive_handle_t *tar_archive;
  21        llist_t *control_tar_llist = NULL;
  22        unsigned opt;
  23        const char *extract_dir;
  24        int need_args;
  25
  26        /* Setup the tar archive handle */
  27        tar_archive = init_handle();
  28
  29        /* Setup an ar archive handle that refers to the gzip sub archive */
  30        ar_archive = init_handle();
  31        ar_archive->sub_archive = tar_archive;
  32        ar_archive->filter = filter_accept_list_reassign;
  33
  34#if ENABLE_FEATURE_SEAMLESS_GZ
  35        llist_add_to(&(ar_archive->accept), (char*)"data.tar.gz");
  36        llist_add_to(&control_tar_llist, (char*)"control.tar.gz");
  37#endif
  38
  39#if ENABLE_FEATURE_SEAMLESS_BZ2
  40        llist_add_to(&(ar_archive->accept), (char*)"data.tar.bz2");
  41        llist_add_to(&control_tar_llist, (char*)"control.tar.bz2");
  42#endif
  43
  44        opt_complementary = "c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX";
  45        opt = getopt32(argv, "cefXx");
  46        argv += optind;
  47        argc -= optind;
  48
  49        if (opt & DPKG_DEB_OPT_CONTENTS) {
  50                tar_archive->action_header = header_verbose_list;
  51        }
  52        extract_dir = NULL;
  53        need_args = 1;
  54        if (opt & DPKG_DEB_OPT_CONTROL) {
  55                ar_archive->accept = control_tar_llist;
  56                tar_archive->action_data = data_extract_all;
  57                if (1 == argc) {
  58                        extract_dir = "./DEBIAN";
  59                } else {
  60                        need_args++;
  61                }
  62        }
  63        if (opt & DPKG_DEB_OPT_FIELD) {
  64                /* Print the entire control file
  65                 * it should accept a second argument which specifies a
  66                 * specific field to print */
  67                ar_archive->accept = control_tar_llist;
  68                llist_add_to(&(tar_archive->accept), (char*)"./control");
  69                tar_archive->filter = filter_accept_list;
  70                tar_archive->action_data = data_extract_to_stdout;
  71        }
  72        if (opt & DPKG_DEB_OPT_EXTRACT) {
  73                tar_archive->action_header = header_list;
  74        }
  75        if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) {
  76                tar_archive->action_data = data_extract_all;
  77                need_args = 2;
  78        }
  79
  80        if (need_args != argc) {
  81                bb_show_usage();
  82        }
  83
  84        tar_archive->src_fd = ar_archive->src_fd = xopen(argv[0], O_RDONLY);
  85
  86        /* Work out where to extract the files */
  87        /* 2nd argument is a dir name */
  88        if (argv[1]) {
  89                extract_dir = argv[1];
  90        }
  91        if (extract_dir) {
  92                mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */
  93                xchdir(extract_dir);
  94        }
  95
  96        /* Do it */
  97        unpack_ar_archive(ar_archive);
  98
  99        /* Cleanup */
 100        if (ENABLE_FEATURE_CLEAN_UP)
 101                close(ar_archive->src_fd);
 102
 103        return EXIT_SUCCESS;
 104}
 105