From 334fa9bcb50df9a03288be252096750dcec14404 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 13 Apr 2007 23:22:58 +0000 Subject: dpkg: use nitfields which are a bit closer to typical ushort. Code size -800. --- archival/dpkg.c | 127 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/archival/dpkg.c b/archival/dpkg.c index c64410096..c5deb0f71 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -53,16 +53,16 @@ * and available file */ #define PACKAGE_HASH_PRIME 10007 typedef struct edge_s { - unsigned operator:3; + unsigned operator:4; /* was:3 */ unsigned type:4; - unsigned name:14; - unsigned version:14; + unsigned name:16; /* was:14 */ + unsigned version:16; /* was:14 */ } edge_t; typedef struct common_node_s { - unsigned name:14; - unsigned version:14; - unsigned num_of_edges:14; + unsigned name:16; /* was:14 */ + unsigned version:16; /* was:14 */ + unsigned num_of_edges:16; /* was:14 */ edge_t **edge; } common_node_t; @@ -71,8 +71,8 @@ typedef struct common_node_s { * likely to be installed at any one time, so there is a bit of leeway here */ #define STATUS_HASH_PRIME 8191 typedef struct status_node_s { - unsigned package:14; /* has to fit PACKAGE_HASH_PRIME */ - unsigned status:14; /* has to fit STATUS_HASH_PRIME */ + unsigned package:16; /* was:14 */ /* has to fit PACKAGE_HASH_PRIME */ + 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 */ @@ -107,13 +107,13 @@ enum operator_e { typedef struct deb_file_s { char *control_file; char *filename; - unsigned package:14; + unsigned package:16; /* was:14 */ } deb_file_t; static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime) { - unsigned long int hash_num = key[0]; + unsigned long hash_num = key[0]; int len = strlen(key); int i; @@ -472,9 +472,13 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole or_edge->version++; add_edge_to_node(parent_node, edge); - } while ((field2 = strtok_r(NULL, "|", &line_ptr2)) != NULL); + field2 = strtok_r(NULL, "|", &line_ptr2); + } while (field2 != NULL); + free(line2); - } while ((field = strtok_r(NULL, ",", &line_ptr1)) != NULL); + field = strtok_r(NULL, ",", &line_ptr1); + } while (field != NULL); + free(line); } @@ -579,7 +583,7 @@ static unsigned fill_package_struct(char *control_buffer) { static const char *const field_names[] = { "Package", "Version", "Pre-Depends", "Depends","Replaces", "Provides", - "Conflicts", "Suggests", "Recommends", "Enhances", 0 + "Conflicts", "Suggests", "Recommends", "Enhances", NULL }; common_node_t *new_node = xzalloc(sizeof(common_node_t)); @@ -705,7 +709,8 @@ static void set_status(const unsigned status_node_num, const char *new_value, co free(new_status); } -static const char *describe_status(int status_num) { +static const char *describe_status(int status_num) +{ int status_want, status_state ; if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0) return "is not installed or flagged to be installed\n"; @@ -721,7 +726,7 @@ static const char *describe_status(int status_num) { if (status_want == search_name_hashtable("purge")) return "is marked to be purged"; } - if (status_want == search_name_hashtable("unknown")) + if (status_want == search_name_hashtable("unknown")) return "is in an indeterminate state"; if (status_want == search_name_hashtable("install")) return "is marked to be installed"; @@ -793,7 +798,8 @@ static void write_status_file(deb_file_t **deb_file) /* Update previously known packages */ while ((control_buffer = xmalloc_fgets_str(old_status_file, "\n\n")) != NULL) { - if ((tmp_string = strstr(control_buffer, "Package:")) == NULL) { + tmp_string = strstr(control_buffer, "Package:"); + if (tmp_string == NULL) { continue; } @@ -818,8 +824,9 @@ static void write_status_file(deb_file_t **deb_file) if (strcmp(status_from_file, status_from_hashtable) != 0) { /* New status isnt exactly the same as old status */ const int state_status = get_status(status_num, 3); - if ((strcmp("installed", name_hashtable[state_status]) == 0) || - (strcmp("unpacked", name_hashtable[state_status]) == 0)) { + if ((strcmp("installed", name_hashtable[state_status]) == 0) + || (strcmp("unpacked", name_hashtable[state_status]) == 0) + ) { /* We need to add the control file from the package */ i = 0; while (deb_file[i] != NULL) { @@ -884,7 +891,7 @@ static void write_status_file(deb_file_t **deb_file) } } /* If the package from the status file wasnt handle above, do it now*/ - if (! write_flag) { + if (!write_flag) { fprintf(new_status_file, "%s\n\n", control_buffer); } @@ -1065,12 +1072,14 @@ static int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count) const edge_t *package_edge = package_node->edge[j]; unsigned package_num; - if (package_edge->type == EDGE_OR_PRE_DEPENDS || - package_edge->type == EDGE_OR_DEPENDS) { /* start an EDGE_OR_ list */ + if (package_edge->type == EDGE_OR_PRE_DEPENDS + || package_edge->type == EDGE_OR_DEPENDS + ) { /* start an EDGE_OR_ list */ number_of_alternatives = package_edge->version; root_of_alternatives = package_edge; continue; - } else if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */ + } + if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */ number_of_alternatives = 1; root_of_alternatives = NULL; } @@ -1120,14 +1129,14 @@ static int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count) name_hashtable[package_node->name], package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", name_hashtable[root_of_alternatives->name]); - else - bb_error_msg_and_die( - "package %s %sdepends on %s, which %s\n", - name_hashtable[package_node->name], - package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", - name_hashtable[package_edge->name], - describe_status(status_num)); - } else if (result == 0 && number_of_alternatives) { + bb_error_msg_and_die( + "package %s %sdepends on %s, which %s\n", + name_hashtable[package_node->name], + package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", + name_hashtable[package_edge->name], + describe_status(status_num)); + } + if (result == 0 && number_of_alternatives) { /* we've found a package which * satisfies the dependency, * so skip over the rest of @@ -1165,49 +1174,42 @@ static char **create_list(const char *filename) if (count == 0) { return NULL; - } else { - file_list[count] = NULL; - return file_list; } + file_list[count] = NULL; + return file_list; } /* maybe i should try and hook this into remove_file.c somehow */ static int remove_file_array(char **remove_names, char **exclude_names) { struct stat path_stat; - int match_flag; - int remove_flag = FALSE; - int i,j; + int remove_flag = 1; /* not removed anything yet */ + int i, j; if (remove_names == NULL) { - return FALSE; + return 0; } for (i = 0; remove_names[i] != NULL; i++) { - match_flag = FALSE; if (exclude_names != NULL) { - for (j = 0; exclude_names[j] != 0; j++) { + for (j = 0; exclude_names[j] != NULL; j++) { if (strcmp(remove_names[i], exclude_names[j]) == 0) { - match_flag = TRUE; - break; + goto skip; } } } - if (!match_flag) { - if (lstat(remove_names[i], &path_stat) < 0) { - continue; - } - if (S_ISDIR(path_stat.st_mode)) { - if (rmdir(remove_names[i]) != -1) { - remove_flag = TRUE; - } - } else { - if (unlink(remove_names[i]) != -1) { - remove_flag = TRUE; - } - } + /* TODO: why we are checking lstat? we can just try rm/rmdir */ + if (lstat(remove_names[i], &path_stat) < 0) { + continue; } + if (S_ISDIR(path_stat.st_mode)) { + remove_flag &= rmdir(remove_names[i]); /* 0 if no error */ + } else { + remove_flag &= unlink(remove_names[i]); /* 0 if no error */ + } + skip: + continue; } - return remove_flag; + return (remove_flag == 0); } static int run_package_script(const char *package_name, const char *script_type) @@ -1224,8 +1226,11 @@ static int run_package_script(const char *package_name, const char *script_type) return result; } -static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm", - "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL }; +static const char *all_control_files[] = { + "preinst", "postinst", "prerm", "postrm", + "list", "md5sums", "shlibs", "conffiles", + "config", "templates", NULL +}; static char **all_control_list(const char *package_name) { @@ -1244,7 +1249,6 @@ static char **all_control_list(const char *package_name) static void free_array(char **array) { - if (array) { unsigned i = 0; while (array[i]) { @@ -1267,8 +1271,7 @@ static void list_packages(void) puts("+++-==============-=============="); /* go through status hash, dereference package hash and finally strings */ - for (i=0; i