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 source tree.
   6 */
   7//config:config DPKG_DEB
   8//config:       bool "dpkg-deb (30 kb)"
   9//config:       default y
  10//config:       select FEATURE_SEAMLESS_GZ
  11//config:       help
  12//config:       dpkg-deb unpacks and provides information about Debian archives.
  13//config:
  14//config:       This implementation of dpkg-deb cannot pack archives.
  15//config:
  16//config:       Unless you have a specific application which requires dpkg-deb,
  17//config:       say N here.
  18
  19//applet:IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, BB_DIR_USR_BIN, BB_SUID_DROP, dpkg_deb))
  20
  21//kbuild:lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o
  22
  23//usage:#define dpkg_deb_trivial_usage
  24//usage:       "[-cefxX] FILE [DIR]"
  25//usage:#define dpkg_deb_full_usage "\n\n"
  26//usage:       "Perform actions on Debian packages (.deb)\n"
  27//usage:     "\n        -c      List files"
  28//usage:     "\n        -f      Print control fields"
  29//usage:     "\n        -e      Extract control files to DIR (default: ./DEBIAN)"
  30//usage:     "\n        -x      Extract files to DIR (no default)"
  31//usage:     "\n        -X      Verbose -x"
  32//usage:
  33//usage:#define dpkg_deb_example_usage
  34//usage:       "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n"
  35
  36#include "libbb.h"
  37#include "bb_archive.h"
  38
  39#define DPKG_DEB_OPT_CONTENTS         1
  40#define DPKG_DEB_OPT_CONTROL          2
  41#define DPKG_DEB_OPT_FIELD            4
  42#define DPKG_DEB_OPT_EXTRACT_VERBOSE  8
  43#define DPKG_DEB_OPT_EXTRACT         16
  44
  45int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  46int dpkg_deb_main(int argc UNUSED_PARAM, char **argv)
  47{
  48        archive_handle_t *ar_archive;
  49        archive_handle_t *tar_archive;
  50        llist_t *control_tar_llist = NULL;
  51        unsigned opt;
  52        const char *extract_dir;
  53
  54        /* Setup the tar archive handle */
  55        tar_archive = init_handle();
  56
  57        /* Setup an ar archive handle that refers to the gzip sub archive */
  58        ar_archive = init_handle();
  59        ar_archive->dpkg__sub_archive = tar_archive;
  60        ar_archive->filter = filter_accept_list_reassign;
  61
  62        llist_add_to(&ar_archive->accept, (char*)"data.tar");
  63        llist_add_to(&control_tar_llist, (char*)"control.tar");
  64#if ENABLE_FEATURE_SEAMLESS_GZ
  65        llist_add_to(&ar_archive->accept, (char*)"data.tar.gz");
  66        llist_add_to(&control_tar_llist, (char*)"control.tar.gz");
  67#endif
  68#if ENABLE_FEATURE_SEAMLESS_BZ2
  69        llist_add_to(&ar_archive->accept, (char*)"data.tar.bz2");
  70        llist_add_to(&control_tar_llist, (char*)"control.tar.bz2");
  71#endif
  72#if ENABLE_FEATURE_SEAMLESS_LZMA
  73        llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma");
  74        llist_add_to(&control_tar_llist, (char*)"control.tar.lzma");
  75#endif
  76#if ENABLE_FEATURE_SEAMLESS_XZ
  77        llist_add_to(&ar_archive->accept, (char*)"data.tar.xz");
  78        llist_add_to(&control_tar_llist, (char*)"control.tar.xz");
  79#endif
  80
  81        /* Must have 1 or 2 args */
  82        opt = getopt32(argv, "^" "cefXx"
  83                        "\0" "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"
  84        );
  85        argv += optind;
  86        //argc -= optind;
  87
  88        extract_dir = argv[1];
  89        if (opt & DPKG_DEB_OPT_CONTENTS) { // -c
  90                tar_archive->action_header = header_verbose_list;
  91                if (extract_dir)
  92                        bb_show_usage();
  93        }
  94        if (opt & DPKG_DEB_OPT_FIELD) { // -f
  95                /* Print the entire control file */
  96//TODO: standard tool accepts an optional list of fields to print
  97                ar_archive->accept = control_tar_llist;
  98                llist_add_to(&(tar_archive->accept), (char*)"./control");
  99                tar_archive->filter = filter_accept_list;
 100                tar_archive->action_data = data_extract_to_stdout;
 101                if (extract_dir)
 102                        bb_show_usage();
 103        }
 104        if (opt & DPKG_DEB_OPT_CONTROL) { // -e
 105                ar_archive->accept = control_tar_llist;
 106                tar_archive->action_data = data_extract_all;
 107                if (!extract_dir)
 108                        extract_dir = "./DEBIAN";
 109        }
 110        if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { // -Xx
 111                if (opt & DPKG_DEB_OPT_EXTRACT_VERBOSE)
 112                        tar_archive->action_header = header_list;
 113                tar_archive->action_data = data_extract_all;
 114                if (!extract_dir)
 115                        bb_show_usage();
 116        }
 117
 118        /* Standard tool supports "-" */
 119        tar_archive->src_fd = ar_archive->src_fd = xopen_stdin(argv[0]);
 120
 121        if (extract_dir) {
 122                mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */
 123                xchdir(extract_dir);
 124        }
 125
 126        /* Do it */
 127        unpack_ar_archive(ar_archive);
 128
 129        /* Cleanup */
 130        if (ENABLE_FEATURE_CLEAN_UP)
 131                close(ar_archive->src_fd);
 132
 133        return EXIT_SUCCESS;
 134}
 135