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) |
