aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-13 23:22:58 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-13 23:22:58 +0000
commit334fa9bcb50df9a03288be252096750dcec14404 (patch)
tree2214f98fe538d87d3159a8774fd3668e7ba5700b
parent87468857f685863cd763ae361c2cb3be0ee53a68 (diff)
downloadbusybox-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.c127
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
55typedef struct edge_s { 55typedef 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
62typedef struct common_node_s { 62typedef 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
73typedef struct status_node_s { 73typedef 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 {
107typedef struct deb_file_s { 107typedef 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
114static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime) 114static 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
708static const char *describe_status(int status_num) { 712static 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 */
1175static int remove_file_array(char **remove_names, char **exclude_names) 1183static 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
1213static int run_package_script(const char *package_name, const char *script_type) 1215static 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
1227static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm", 1229static 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
1230static char **all_control_list(const char *package_name) 1235static 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
1245static void free_array(char **array) 1250static 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
1299static void remove_package(const unsigned package_num, int noisy) 1302static void remove_package(const unsigned package_num, int noisy)