unsigned status:16; /* was:14 */ /* has to fit STATUS_HASH_PRIME */
} status_node_t;
-/* Were statically declared here, but such a big bss is nommu-unfriendly */
-static char **name_hashtable; /* [NAME_HASH_PRIME + 1] */
-static common_node_t **package_hashtable; /* [PACKAGE_HASH_PRIME + 1] */
-static status_node_t **status_hashtable; /* [STATUS_HASH_PRIME + 1] */
+
+/* Globals */
+struct globals {
+ char *name_hashtable[NAME_HASH_PRIME + 1];
+ common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
+ status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
+};
+#define G (*ptr_to_globals)
+#define name_hashtable (G.name_hashtable )
+#define package_hashtable (G.package_hashtable)
+#define status_hashtable (G.status_hashtable )
+#define INIT_G() do { \
+ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
+} while (0)
+
/* Even numbers are for 'extras', like ored dependencies or null */
enum edge_type_e {
return FALSE;
}
-
static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator)
{
unsigned probe_address;
return "is not installed or flagged to be installed";
}
-
static void index_status_file(const char *filename)
{
FILE *status_file;
return (remove_flag == 0);
}
-static int run_package_script(const char *package_name, const char *script_type)
+static void run_package_script_or_die(const char *package_name, const char *script_type)
{
- struct stat path_stat;
char *script_path;
int result;
script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
- /* If the file doesnt exist is isnt a fatal */
- result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path);
+ /* If the file doesnt exist is isnt fatal */
+ result = access(script_path, F_OK) ? EXIT_SUCCESS : system(script_path);
free(script_path);
- return result;
+ if (result)
+ bb_error_msg_and_die("%s failed, exit code %d", script_type, result);
}
/*
The policy manual defines what scripts get called when and with
what arguments. I realize that busybox does not support all of
these scenarios, but it does support some of them; it does not,
-however, run them with any parameters in run_package_script().
+however, run them with any parameters in run_package_script_or_die().
Here are the scripts:
preinst install
if (noisy)
printf("Removing %s (%s)...\n", package_name, package_version);
- /* run prerm script */
- if (run_package_script(package_name, "prerm") != 0) {
- bb_error_msg_and_die("script failed, prerm failure");
- }
+ /* Run prerm script */
+ run_package_script_or_die(package_name, "prerm");
/* Create a list of files to remove, and a separate list of those to keep */
sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list");
exclude_files = create_list(conffile_name);
/* Some directories can't be removed straight away, so do multiple passes */
- while (remove_file_array(remove_files, exclude_files)) /*repeat */;
+ while (remove_file_array(remove_files, exclude_files))
+ continue;
free_array(exclude_files);
free_array(remove_files);
printf("Purging %s (%s)...\n", package_name, package_version);
- /* run prerm script */
- if (run_package_script(package_name, "prerm") != 0) {
- bb_error_msg_and_die("script failed, prerm failure");
- }
+ /* Run prerm script */
+ run_package_script_or_die(package_name, "prerm");
/* Create a list of files to remove */
sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list");
free_array(remove_files);
free(exclude_files);
- /* run postrm script */
- if (run_package_script(package_name, "postrm") != 0) {
- bb_error_msg_and_die("postrm failure.. set status to what?");
- }
+ /* Run postrm script */
+ run_package_script_or_die(package_name, "postrm");
/* Change package status */
set_status(status_num, "not-installed", 3);
unpack_ar_archive(archive_handle);
/* Run the preinst prior to extracting */
- if (run_package_script(package_name, "preinst") != 0) {
- /* when preinst returns exit code != 0 then quit installation process */
- bb_error_msg_and_die("subprocess pre-installation script returned error");
- }
+ run_package_script_or_die(package_name, "preinst");
/* Extract data.tar.gz to the root directory */
archive_handle = init_archive_deb_ar(deb_file->filename);
printf("Setting up %s (%s)...\n", package_name, package_version);
/* Run the postinst script */
- if (run_package_script(package_name, "postinst") != 0) {
- /* TODO: handle failure gracefully */
- bb_error_msg_and_die("postinst failure.. set status to what?");
- }
+ /* TODO: handle failure gracefully */
+ run_package_script_or_die(package_name, "postinst");
+
/* Change status to reflect success */
set_status(status_num, "install", 1);
set_status(status_num, "installed", 3);
OPT_unpack = 0x40,
};
+ INIT_G();
+
opt = getopt32(argv, "CF:ilPru", &str_f);
//if (opt & OPT_configure) ... // -C
if (opt & OPT_force_ignore_depends) { // -F (--force in official dpkg)
if (!opt || (!argv[0] && !(opt && OPT_list_installed)))
bb_show_usage();
- name_hashtable = xzalloc(sizeof(name_hashtable[0]) * (NAME_HASH_PRIME + 1));
- package_hashtable = xzalloc(sizeof(package_hashtable[0]) * (PACKAGE_HASH_PRIME + 1));
- status_hashtable = xzalloc(sizeof(status_hashtable[0]) * (STATUS_HASH_PRIME + 1));
-
/* puts("(Reading database ... xxxxx files and directories installed.)"); */
index_status_file("/var/lib/dpkg/status");