diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-13 23:22:58 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-13 23:22:58 +0000 |
commit | 334fa9bcb50df9a03288be252096750dcec14404 (patch) | |
tree | 2214f98fe538d87d3159a8774fd3668e7ba5700b | |
parent | 87468857f685863cd763ae361c2cb3be0ee53a68 (diff) | |
download | busybox-w32-334fa9bcb50df9a03288be252096750dcec14404.tar.gz busybox-w32-334fa9bcb50df9a03288be252096750dcec14404.tar.bz2 busybox-w32-334fa9bcb50df9a03288be252096750dcec14404.zip |
dpkg: use nitfields which are a bit closer to typical ushort.
Code size -800.
-rw-r--r-- | archival/dpkg.c | 127 |
1 files 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 @@ | |||
53 | * and available file */ | 53 | * and available file */ |
54 | #define PACKAGE_HASH_PRIME 10007 | 54 | #define PACKAGE_HASH_PRIME 10007 |
55 | typedef struct edge_s { | 55 | typedef struct edge_s { |
56 | unsigned operator:3; | 56 | unsigned operator:4; /* was:3 */ |
57 | unsigned type:4; | 57 | unsigned type:4; |
58 | unsigned name:14; | 58 | unsigned name:16; /* was:14 */ |
59 | unsigned version:14; | 59 | unsigned version:16; /* was:14 */ |
60 | } edge_t; | 60 | } edge_t; |
61 | 61 | ||
62 | typedef struct common_node_s { | 62 | typedef struct common_node_s { |
63 | unsigned name:14; | 63 | unsigned name:16; /* was:14 */ |
64 | unsigned version:14; | 64 | unsigned version:16; /* was:14 */ |
65 | unsigned num_of_edges:14; | 65 | unsigned num_of_edges:16; /* was:14 */ |
66 | edge_t **edge; | 66 | edge_t **edge; |
67 | } common_node_t; | 67 | } common_node_t; |
68 | 68 | ||
@@ -71,8 +71,8 @@ typedef struct common_node_s { | |||
71 | * likely to be installed at any one time, so there is a bit of leeway here */ | 71 | * likely to be installed at any one time, so there is a bit of leeway here */ |
72 | #define STATUS_HASH_PRIME 8191 | 72 | #define STATUS_HASH_PRIME 8191 |
73 | typedef struct status_node_s { | 73 | typedef struct status_node_s { |
74 | unsigned package:14; /* has to fit PACKAGE_HASH_PRIME */ | 74 | unsigned package:16; /* was:14 */ /* has to fit PACKAGE_HASH_PRIME */ |
75 | unsigned status:14; /* has to fit STATUS_HASH_PRIME */ | 75 | unsigned status:16; /* was:14 */ /* has to fit STATUS_HASH_PRIME */ |
76 | } status_node_t; | 76 | } status_node_t; |
77 | 77 | ||
78 | /* Were statically declared here, but such a big bss is nommu-unfriendly */ | 78 | /* Were statically declared here, but such a big bss is nommu-unfriendly */ |
@@ -107,13 +107,13 @@ enum operator_e { | |||
107 | typedef struct deb_file_s { | 107 | typedef struct deb_file_s { |
108 | char *control_file; | 108 | char *control_file; |
109 | char *filename; | 109 | char *filename; |
110 | unsigned package:14; | 110 | unsigned package:16; /* was:14 */ |
111 | } deb_file_t; | 111 | } deb_file_t; |
112 | 112 | ||
113 | 113 | ||
114 | static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime) | 114 | static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime) |
115 | { | 115 | { |
116 | unsigned long int hash_num = key[0]; | 116 | unsigned long hash_num = key[0]; |
117 | int len = strlen(key); | 117 | int len = strlen(key); |
118 | int i; | 118 | int i; |
119 | 119 | ||
@@ -472,9 +472,13 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole | |||
472 | or_edge->version++; | 472 | or_edge->version++; |
473 | 473 | ||
474 | add_edge_to_node(parent_node, edge); | 474 | add_edge_to_node(parent_node, edge); |
475 | } while ((field2 = strtok_r(NULL, "|", &line_ptr2)) != NULL); | 475 | field2 = strtok_r(NULL, "|", &line_ptr2); |
476 | } while (field2 != NULL); | ||
477 | |||
476 | free(line2); | 478 | free(line2); |
477 | } while ((field = strtok_r(NULL, ",", &line_ptr1)) != NULL); | 479 | field = strtok_r(NULL, ",", &line_ptr1); |
480 | } while (field != NULL); | ||
481 | |||
478 | free(line); | 482 | free(line); |
479 | } | 483 | } |
480 | 484 | ||
@@ -579,7 +583,7 @@ static unsigned fill_package_struct(char *control_buffer) | |||
579 | { | 583 | { |
580 | static const char *const field_names[] = { "Package", "Version", | 584 | static const char *const field_names[] = { "Package", "Version", |
581 | "Pre-Depends", "Depends","Replaces", "Provides", | 585 | "Pre-Depends", "Depends","Replaces", "Provides", |
582 | "Conflicts", "Suggests", "Recommends", "Enhances", 0 | 586 | "Conflicts", "Suggests", "Recommends", "Enhances", NULL |
583 | }; | 587 | }; |
584 | 588 | ||
585 | common_node_t *new_node = xzalloc(sizeof(common_node_t)); | 589 | 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 | |||
705 | free(new_status); | 709 | free(new_status); |
706 | } | 710 | } |
707 | 711 | ||
708 | static const char *describe_status(int status_num) { | 712 | static const char *describe_status(int status_num) |
713 | { | ||
709 | int status_want, status_state ; | 714 | int status_want, status_state ; |
710 | if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0) | 715 | if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0) |
711 | return "is not installed or flagged to be installed\n"; | 716 | return "is not installed or flagged to be installed\n"; |
@@ -721,7 +726,7 @@ static const char *describe_status(int status_num) { | |||
721 | if (status_want == search_name_hashtable("purge")) | 726 | if (status_want == search_name_hashtable("purge")) |
722 | return "is marked to be purged"; | 727 | return "is marked to be purged"; |
723 | } | 728 | } |
724 | if (status_want == search_name_hashtable("unknown")) | 729 | if (status_want == search_name_hashtable("unknown")) |
725 | return "is in an indeterminate state"; | 730 | return "is in an indeterminate state"; |
726 | if (status_want == search_name_hashtable("install")) | 731 | if (status_want == search_name_hashtable("install")) |
727 | return "is marked to be installed"; | 732 | return "is marked to be installed"; |
@@ -793,7 +798,8 @@ static void write_status_file(deb_file_t **deb_file) | |||
793 | 798 | ||
794 | /* Update previously known packages */ | 799 | /* Update previously known packages */ |
795 | while ((control_buffer = xmalloc_fgets_str(old_status_file, "\n\n")) != NULL) { | 800 | while ((control_buffer = xmalloc_fgets_str(old_status_file, "\n\n")) != NULL) { |
796 | if ((tmp_string = strstr(control_buffer, "Package:")) == NULL) { | 801 | tmp_string = strstr(control_buffer, "Package:"); |
802 | if (tmp_string == NULL) { | ||
797 | continue; | 803 | continue; |
798 | } | 804 | } |
799 | 805 | ||
@@ -818,8 +824,9 @@ static void write_status_file(deb_file_t **deb_file) | |||
818 | if (strcmp(status_from_file, status_from_hashtable) != 0) { | 824 | if (strcmp(status_from_file, status_from_hashtable) != 0) { |
819 | /* New status isnt exactly the same as old status */ | 825 | /* New status isnt exactly the same as old status */ |
820 | const int state_status = get_status(status_num, 3); | 826 | const int state_status = get_status(status_num, 3); |
821 | if ((strcmp("installed", name_hashtable[state_status]) == 0) || | 827 | if ((strcmp("installed", name_hashtable[state_status]) == 0) |
822 | (strcmp("unpacked", name_hashtable[state_status]) == 0)) { | 828 | || (strcmp("unpacked", name_hashtable[state_status]) == 0) |
829 | ) { | ||
823 | /* We need to add the control file from the package */ | 830 | /* We need to add the control file from the package */ |
824 | i = 0; | 831 | i = 0; |
825 | while (deb_file[i] != NULL) { | 832 | while (deb_file[i] != NULL) { |
@@ -884,7 +891,7 @@ static void write_status_file(deb_file_t **deb_file) | |||
884 | } | 891 | } |
885 | } | 892 | } |
886 | /* If the package from the status file wasnt handle above, do it now*/ | 893 | /* If the package from the status file wasnt handle above, do it now*/ |
887 | if (! write_flag) { | 894 | if (!write_flag) { |
888 | fprintf(new_status_file, "%s\n\n", control_buffer); | 895 | fprintf(new_status_file, "%s\n\n", control_buffer); |
889 | } | 896 | } |
890 | 897 | ||
@@ -1065,12 +1072,14 @@ static int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count) | |||
1065 | const edge_t *package_edge = package_node->edge[j]; | 1072 | const edge_t *package_edge = package_node->edge[j]; |
1066 | unsigned package_num; | 1073 | unsigned package_num; |
1067 | 1074 | ||
1068 | if (package_edge->type == EDGE_OR_PRE_DEPENDS || | 1075 | if (package_edge->type == EDGE_OR_PRE_DEPENDS |
1069 | package_edge->type == EDGE_OR_DEPENDS) { /* start an EDGE_OR_ list */ | 1076 | || package_edge->type == EDGE_OR_DEPENDS |
1077 | ) { /* start an EDGE_OR_ list */ | ||
1070 | number_of_alternatives = package_edge->version; | 1078 | number_of_alternatives = package_edge->version; |
1071 | root_of_alternatives = package_edge; | 1079 | root_of_alternatives = package_edge; |
1072 | continue; | 1080 | continue; |
1073 | } else if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */ | 1081 | } |
1082 | if (number_of_alternatives == 0) { /* not in the middle of an EDGE_OR_ list */ | ||
1074 | number_of_alternatives = 1; | 1083 | number_of_alternatives = 1; |
1075 | root_of_alternatives = NULL; | 1084 | root_of_alternatives = NULL; |
1076 | } | 1085 | } |
@@ -1120,14 +1129,14 @@ static int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count) | |||
1120 | name_hashtable[package_node->name], | 1129 | name_hashtable[package_node->name], |
1121 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", | 1130 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", |
1122 | name_hashtable[root_of_alternatives->name]); | 1131 | name_hashtable[root_of_alternatives->name]); |
1123 | else | 1132 | bb_error_msg_and_die( |
1124 | bb_error_msg_and_die( | 1133 | "package %s %sdepends on %s, which %s\n", |
1125 | "package %s %sdepends on %s, which %s\n", | 1134 | name_hashtable[package_node->name], |
1126 | name_hashtable[package_node->name], | 1135 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", |
1127 | package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", | 1136 | name_hashtable[package_edge->name], |
1128 | name_hashtable[package_edge->name], | 1137 | describe_status(status_num)); |
1129 | describe_status(status_num)); | 1138 | } |
1130 | } else if (result == 0 && number_of_alternatives) { | 1139 | if (result == 0 && number_of_alternatives) { |
1131 | /* we've found a package which | 1140 | /* we've found a package which |
1132 | * satisfies the dependency, | 1141 | * satisfies the dependency, |
1133 | * so skip over the rest of | 1142 | * so skip over the rest of |
@@ -1165,49 +1174,42 @@ static char **create_list(const char *filename) | |||
1165 | 1174 | ||
1166 | if (count == 0) { | 1175 | if (count == 0) { |
1167 | return NULL; | 1176 | return NULL; |
1168 | } else { | ||
1169 | file_list[count] = NULL; | ||
1170 | return file_list; | ||
1171 | } | 1177 | } |
1178 | file_list[count] = NULL; | ||
1179 | return file_list; | ||
1172 | } | 1180 | } |
1173 | 1181 | ||
1174 | /* maybe i should try and hook this into remove_file.c somehow */ | 1182 | /* maybe i should try and hook this into remove_file.c somehow */ |
1175 | static int remove_file_array(char **remove_names, char **exclude_names) | 1183 | static int remove_file_array(char **remove_names, char **exclude_names) |
1176 | { | 1184 | { |
1177 | struct stat path_stat; | 1185 | struct stat path_stat; |
1178 | int match_flag; | 1186 | int remove_flag = 1; /* not removed anything yet */ |
1179 | int remove_flag = FALSE; | 1187 | int i, j; |
1180 | int i,j; | ||
1181 | 1188 | ||
1182 | if (remove_names == NULL) { | 1189 | if (remove_names == NULL) { |
1183 | return FALSE; | 1190 | return 0; |
1184 | } | 1191 | } |
1185 | for (i = 0; remove_names[i] != NULL; i++) { | 1192 | for (i = 0; remove_names[i] != NULL; i++) { |
1186 | match_flag = FALSE; | ||
1187 | if (exclude_names != NULL) { | 1193 | if (exclude_names != NULL) { |
1188 | for (j = 0; exclude_names[j] != 0; j++) { | 1194 | for (j = 0; exclude_names[j] != NULL; j++) { |
1189 | if (strcmp(remove_names[i], exclude_names[j]) == 0) { | 1195 | if (strcmp(remove_names[i], exclude_names[j]) == 0) { |
1190 | match_flag = TRUE; | 1196 | goto skip; |
1191 | break; | ||
1192 | } | 1197 | } |
1193 | } | 1198 | } |
1194 | } | 1199 | } |
1195 | if (!match_flag) { | 1200 | /* TODO: why we are checking lstat? we can just try rm/rmdir */ |
1196 | if (lstat(remove_names[i], &path_stat) < 0) { | 1201 | if (lstat(remove_names[i], &path_stat) < 0) { |
1197 | continue; | 1202 | continue; |
1198 | } | ||
1199 | if (S_ISDIR(path_stat.st_mode)) { | ||
1200 | if (rmdir(remove_names[i]) != -1) { | ||
1201 | remove_flag = TRUE; | ||
1202 | } | ||
1203 | } else { | ||
1204 | if (unlink(remove_names[i]) != -1) { | ||
1205 | remove_flag = TRUE; | ||
1206 | } | ||
1207 | } | ||
1208 | } | 1203 | } |
1204 | if (S_ISDIR(path_stat.st_mode)) { | ||
1205 | remove_flag &= rmdir(remove_names[i]); /* 0 if no error */ | ||
1206 | } else { | ||
1207 | remove_flag &= unlink(remove_names[i]); /* 0 if no error */ | ||
1208 | } | ||
1209 | skip: | ||
1210 | continue; | ||
1209 | } | 1211 | } |
1210 | return remove_flag; | 1212 | return (remove_flag == 0); |
1211 | } | 1213 | } |
1212 | 1214 | ||
1213 | static int run_package_script(const char *package_name, const char *script_type) | 1215 | 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) | |||
1224 | return result; | 1226 | return result; |
1225 | } | 1227 | } |
1226 | 1228 | ||
1227 | static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm", | 1229 | static const char *all_control_files[] = { |
1228 | "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL }; | 1230 | "preinst", "postinst", "prerm", "postrm", |
1231 | "list", "md5sums", "shlibs", "conffiles", | ||
1232 | "config", "templates", NULL | ||
1233 | }; | ||
1229 | 1234 | ||
1230 | static char **all_control_list(const char *package_name) | 1235 | static char **all_control_list(const char *package_name) |
1231 | { | 1236 | { |
@@ -1244,7 +1249,6 @@ static char **all_control_list(const char *package_name) | |||
1244 | 1249 | ||
1245 | static void free_array(char **array) | 1250 | static void free_array(char **array) |
1246 | { | 1251 | { |
1247 | |||
1248 | if (array) { | 1252 | if (array) { |
1249 | unsigned i = 0; | 1253 | unsigned i = 0; |
1250 | while (array[i]) { | 1254 | while (array[i]) { |
@@ -1267,8 +1271,7 @@ static void list_packages(void) | |||
1267 | puts("+++-==============-=============="); | 1271 | puts("+++-==============-=============="); |
1268 | 1272 | ||
1269 | /* go through status hash, dereference package hash and finally strings */ | 1273 | /* go through status hash, dereference package hash and finally strings */ |
1270 | for (i=0; i<STATUS_HASH_PRIME+1; i++) { | 1274 | for (i = 0; i < STATUS_HASH_PRIME+1; i++) { |
1271 | |||
1272 | if (status_hashtable[i]) { | 1275 | if (status_hashtable[i]) { |
1273 | const char *stat_str; /* status string */ | 1276 | const char *stat_str; /* status string */ |
1274 | const char *name_str; /* package name */ | 1277 | const char *name_str; /* package name */ |
@@ -1285,7 +1288,7 @@ static void list_packages(void) | |||
1285 | s1 = stat_str[0] == 'i' ? 'i' : 'r'; | 1288 | s1 = stat_str[0] == 'i' ? 'i' : 'r'; |
1286 | 1289 | ||
1287 | /* get abbreviation for status field 2 */ | 1290 | /* get abbreviation for status field 2 */ |
1288 | for (j=0, spccnt=0; stat_str[j] && spccnt<2; j++) { | 1291 | for (j = 0, spccnt = 0; stat_str[j] && spccnt < 2; j++) { |
1289 | if (stat_str[j] == ' ') spccnt++; | 1292 | if (stat_str[j] == ' ') spccnt++; |
1290 | } | 1293 | } |
1291 | s2 = stat_str[j]; | 1294 | s2 = stat_str[j]; |
@@ -1293,7 +1296,7 @@ static void list_packages(void) | |||
1293 | /* print out the line formatted like Debian dpkg */ | 1296 | /* print out the line formatted like Debian dpkg */ |
1294 | printf("%c%c %-14s %s\n", s1, s2, name_str, vers_str); | 1297 | printf("%c%c %-14s %s\n", s1, s2, name_str, vers_str); |
1295 | } | 1298 | } |
1296 | } | 1299 | } |
1297 | } | 1300 | } |
1298 | 1301 | ||
1299 | static void remove_package(const unsigned package_num, int noisy) | 1302 | static void remove_package(const unsigned package_num, int noisy) |