aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2001-07-18 15:47:21 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2001-07-18 15:47:21 +0000
commitc3fbec73fb45997918bef927cea519866e1e1c9d (patch)
tree5c1fd9758c4c9894bb050d9c152e1735bc007536
parent8d3b0497a4d8866f0cafd873f241971c2871d580 (diff)
downloadbusybox-w32-c3fbec73fb45997918bef927cea519866e1e1c9d.tar.gz
busybox-w32-c3fbec73fb45997918bef927cea519866e1e1c9d.tar.bz2
busybox-w32-c3fbec73fb45997918bef927cea519866e1e1c9d.zip
Change read_package_field interface, and rewrite using low level functions
Fixes for a few bugs that have crept into dpkg in the last few days
-rw-r--r--archival/dpkg.c127
-rw-r--r--archival/dpkg_deb.c13
-rw-r--r--dpkg.c127
-rw-r--r--dpkg_deb.c13
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/libbb.h2
-rw-r--r--libbb/read_package_field.c90
7 files changed, 205 insertions, 169 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c
index e9afe5f6e..f207b23ac 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -499,34 +499,17 @@ unsigned int fill_package_struct(char *control_buffer)
499{ 499{
500 common_node_t *new_node = (common_node_t *) xcalloc(1, sizeof(common_node_t)); 500 common_node_t *new_node = (common_node_t *) xcalloc(1, sizeof(common_node_t));
501 501
502 char *field; 502 char *field_name = xmalloc(sizeof(char *));
503 char *field_name; 503 char *field_value = xmalloc(sizeof(char *));
504 char *field_value;
505 int field_start = 0; 504 int field_start = 0;
506 int field_length;
507 int seperator_offset;
508 int num = -1; 505 int num = -1;
509 int buffer_length = strlen(control_buffer); 506 int buffer_length = strlen(control_buffer);
510 507
511 new_node->version = search_name_hashtable("unknown"); 508 new_node->version = search_name_hashtable("unknown");
512 while (field_start < buffer_length) { 509 while (field_start < buffer_length) {
513 field = read_package_field(&control_buffer[field_start]); 510 field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
514
515 /* Setup start point for next field */
516 field_length = strlen(field);
517 field_start += (field_length + 1);
518
519 seperator_offset = strcspn(field, ":");
520 if (seperator_offset == 0) {
521 free(field);
522 continue;
523 }
524 field_name = xstrndup(field, seperator_offset);
525 field_value = field + seperator_offset + 1;
526 field_value += strspn(field_value, " \n\t");
527 511
528 /* Should be able to replace this strlen with pointer arithmatic */ 512 if (field_name == NULL) {
529 if (strlen(field_value) == 0) {
530 goto fill_package_struct_cleanup; // Oh no, the dreaded goto statement !! 513 goto fill_package_struct_cleanup; // Oh no, the dreaded goto statement !!
531 } 514 }
532 515
@@ -562,7 +545,7 @@ unsigned int fill_package_struct(char *control_buffer)
562 } 545 }
563fill_package_struct_cleanup: 546fill_package_struct_cleanup:
564 free(field_name); 547 free(field_name);
565 free(field); 548 free(field_value);
566 } 549 }
567 if (new_node->version == search_name_hashtable("unknown")) { 550 if (new_node->version == search_name_hashtable("unknown")) {
568 free_package(new_node); 551 free_package(new_node);
@@ -739,6 +722,23 @@ char *get_depends_field(common_node_t *package, const int depends_type)
739 return(depends); 722 return(depends);
740} 723}
741 724
725void write_buffer_no_status(FILE *new_status_file, const char *control_buffer)
726{
727 char *name;
728 char *value;
729 int start = 0;
730 while (1) {
731 start += read_package_field(&control_buffer[start], &name, &value);
732 if (name == NULL) {
733 break;
734 }
735 if (strcmp(name, "Status") != 0) {
736 fprintf(new_status_file, "%s: %s\n", name, value);
737 }
738 }
739 return;
740}
741
742/* This could do with a cleanup */ 742/* This could do with a cleanup */
743void write_status_file(deb_file_t **deb_file) 743void write_status_file(deb_file_t **deb_file)
744{ 744{
@@ -748,11 +748,8 @@ void write_status_file(deb_file_t **deb_file)
748 char *status_from_file; 748 char *status_from_file;
749 char *control_buffer = NULL; 749 char *control_buffer = NULL;
750 char *tmp_string; 750 char *tmp_string;
751 char *field;
752 int status_num; 751 int status_num;
753 int field_length;
754 int field_start = 0; 752 int field_start = 0;
755 int buffer_length;
756 int write_flag; 753 int write_flag;
757 int i = 0; 754 int i = 0;
758 755
@@ -762,7 +759,6 @@ void write_status_file(deb_file_t **deb_file)
762 tmp_string += strspn(tmp_string, " \n\t"); 759 tmp_string += strspn(tmp_string, " \n\t");
763 package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n\0")); 760 package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n\0"));
764 write_flag = FALSE; 761 write_flag = FALSE;
765
766 tmp_string = strstr(control_buffer, "Status:"); 762 tmp_string = strstr(control_buffer, "Status:");
767 if (tmp_string != NULL) { 763 if (tmp_string != NULL) {
768 /* Seperate the status value from the control buffer */ 764 /* Seperate the status value from the control buffer */
@@ -786,20 +782,11 @@ void write_status_file(deb_file_t **deb_file)
786 i = 0; 782 i = 0;
787 while(deb_file[i] != NULL) { 783 while(deb_file[i] != NULL) {
788 if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) { 784 if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) {
789 char *last_char;
790 /* Write a status file entry with a modified status */ 785 /* Write a status file entry with a modified status */
791 /* remove trailing \n's */ 786 /* remove trailing \n's */
792 while(1) { 787 write_buffer_no_status(new_status_file, deb_file[i]->control_file);
793 last_char = last_char_is(deb_file[i]->control_file, '\n');
794 if (last_char) {
795 *last_char = '\0';
796 } else {
797 break;
798 }
799 }
800 fputs(deb_file[i]->control_file, new_status_file);
801 set_status(status_num, "ok", 2); 788 set_status(status_num, "ok", 2);
802 fprintf(new_status_file, "\nStatus: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); 789 fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
803 write_flag = TRUE; 790 write_flag = TRUE;
804 break; 791 break;
805 } 792 }
@@ -814,16 +801,17 @@ void write_status_file(deb_file_t **deb_file)
814 /* Only write the Package, Status, Priority and Section lines */ 801 /* Only write the Package, Status, Priority and Section lines */
815 fprintf(new_status_file, "Package: %s\n", package_name); 802 fprintf(new_status_file, "Package: %s\n", package_name);
816 fprintf(new_status_file, "Status: %s\n", status_from_hashtable); 803 fprintf(new_status_file, "Status: %s\n", status_from_hashtable);
817 buffer_length = strlen(control_buffer); 804
818 while (field_start < buffer_length) { 805 while (1) {
819 field = read_package_field(&control_buffer[field_start]); 806 char *field_name;
820 field_length = strlen(field); 807 char *field_value;
821 field_start += (field_length + 1); 808 field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
822 if (strncmp(field, "Priority:", 9) == 0) { 809 if (field_name == NULL) {
823 fprintf(new_status_file, "Priority:%s\n", field + 9); 810 break;
824 } 811 }
825 if (strncmp(field, "Section:", 8) == 0) { 812 if ((strcmp(field_name, "Priority") == 0) ||
826 fprintf(new_status_file, "Section:%s\n", field + 8); 813 (strcmp(field_name, "Section") == 0)) {
814 fprintf(new_status_file, "%s: %s\n", field_name, field_value);
827 } 815 }
828 } 816 }
829 write_flag = TRUE; 817 write_flag = TRUE;
@@ -831,25 +819,26 @@ void write_status_file(deb_file_t **deb_file)
831 } 819 }
832 else if (strcmp("config-files", name_hashtable[state_status]) == 0) { 820 else if (strcmp("config-files", name_hashtable[state_status]) == 0) {
833 /* only change the status line */ 821 /* only change the status line */
834 buffer_length = strlen(control_buffer); 822// buffer_length = strlen(control_buffer);
835 while (field_start < buffer_length) { 823 while (1) {
836 field = read_package_field(&control_buffer[field_start]); 824 char *field_name;
825 char *field_value;
826 field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
827 if (field_name == NULL) {
828 break;
829 }
837 /* Setup start point for next field */ 830 /* Setup start point for next field */
838 field_length = strlen(field); 831 if (strcmp(field_name, "Status") == 0) {
839 field_start += (field_length + 1);
840 if (strncmp(field, "Status:", 7) == 0) {
841 fprintf(new_status_file, "Status: %s\n", status_from_hashtable); 832 fprintf(new_status_file, "Status: %s\n", status_from_hashtable);
842 } else { 833 } else {
843 fprintf(new_status_file, "%s\n", field); 834 fprintf(new_status_file, "%s: %s\n", field_name, field_value);
844 } 835 }
845 free(field);
846 } 836 }
847 write_flag = TRUE; 837 write_flag = TRUE;
848 fputs("\n", new_status_file); 838 fputs("\n", new_status_file);
849 } 839 }
850 } 840 }
851 } 841 }
852
853 /* If the package from the status file wasnt handle above, do it now*/ 842 /* If the package from the status file wasnt handle above, do it now*/
854 if (write_flag == FALSE) { 843 if (write_flag == FALSE) {
855 fprintf(new_status_file, "%s\n\n", control_buffer); 844 fprintf(new_status_file, "%s\n\n", control_buffer);
@@ -866,20 +855,9 @@ void write_status_file(deb_file_t **deb_file)
866 for(i = 0; deb_file[i] != NULL; i++) { 855 for(i = 0; deb_file[i] != NULL; i++) {
867 status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]); 856 status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]);
868 if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) { 857 if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) {
869 char *last_char; 858 write_buffer_no_status(new_status_file, deb_file[i]->control_file);
870 /* remove trailing \n's */
871 while(1) {
872 last_char = last_char_is(deb_file[i]->control_file, '\n');
873 if (last_char) {
874 *last_char = '\0';
875 } else {
876 break;
877 }
878 }
879
880 fputs(deb_file[i]->control_file, new_status_file);
881 set_status(status_num, "ok", 2); 859 set_status(status_num, "ok", 2);
882 fprintf(new_status_file, "\nStatus: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); 860 fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
883 } 861 }
884 } 862 }
885 fclose(old_status_file); 863 fclose(old_status_file);
@@ -1037,9 +1015,11 @@ char **create_list(const char *filename)
1037 int length = 0; 1015 int length = 0;
1038 int count = 0; 1016 int count = 0;
1039 1017
1040 list_stream = xfopen(filename, "r"); 1018 /* dont use [xw]fopen here, handle error ourself */
1019 list_stream = fopen(filename, "r");
1041 if (list_stream == NULL) { 1020 if (list_stream == NULL) {
1042 return(NULL); 1021 *file_list = NULL;
1022 return(file_list);
1043 } 1023 }
1044 while (getline(&line, &length, list_stream) != -1) { 1024 while (getline(&line, &length, list_stream) != -1) {
1045 file_list = xrealloc(file_list, sizeof(char *) * (length + 1)); 1025 file_list = xrealloc(file_list, sizeof(char *) * (length + 1));
@@ -1053,6 +1033,7 @@ char **create_list(const char *filename)
1053 length = 0; 1033 length = 0;
1054 } 1034 }
1055 fclose(list_stream); 1035 fclose(list_stream);
1036
1056 if (count == 0) { 1037 if (count == 0) {
1057 return(NULL); 1038 return(NULL);
1058 } else { 1039 } else {
@@ -1212,6 +1193,7 @@ void purge_package(const unsigned int package_num)
1212 if (run_package_script(package_name, "postrm") == -1) { 1193 if (run_package_script(package_name, "postrm") == -1) {
1213 error_msg_and_die("postrm fialure.. set status to what?"); 1194 error_msg_and_die("postrm fialure.. set status to what?");
1214 } 1195 }
1196
1215 /* Change package status */ 1197 /* Change package status */
1216 set_status(status_num, "purge", 1); 1198 set_status(status_num, "purge", 1);
1217 set_status(status_num, "not-installed", 3); 1199 set_status(status_num, "not-installed", 3);
@@ -1219,7 +1201,6 @@ void purge_package(const unsigned int package_num)
1219 1201
1220void unpack_package(deb_file_t *deb_file) 1202void unpack_package(deb_file_t *deb_file)
1221{ 1203{
1222// const unsigned int package_name_num = package_hashtable[deb_file->package]->name;
1223 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name]; 1204 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
1224 const unsigned int status_num = search_status_hashtable(package_name); 1205 const unsigned int status_num = search_status_hashtable(package_name);
1225 const unsigned int status_package_num = status_hashtable[status_num]->status; 1206 const unsigned int status_package_num = status_hashtable[status_num]->status;
@@ -1248,7 +1229,6 @@ void unpack_package(deb_file_t *deb_file)
1248 1229
1249 /* Create the list file */ 1230 /* Create the list file */
1250 strcat(info_prefix, "list"); 1231 strcat(info_prefix, "list");
1251
1252 out_stream = xfopen(info_prefix, "w"); 1232 out_stream = xfopen(info_prefix, "w");
1253 deb_extract(deb_file->filename, out_stream, (extract_quiet | extract_data_tar_gz | extract_list), NULL, NULL); 1233 deb_extract(deb_file->filename, out_stream, (extract_quiet | extract_data_tar_gz | extract_list), NULL, NULL);
1254 fclose(out_stream); 1234 fclose(out_stream);
@@ -1393,7 +1373,7 @@ extern int dpkg_main(int argc, char **argv)
1393 /* TODO: check dependencies before removing */ 1373 /* TODO: check dependencies before removing */
1394 if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) { 1374 if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {
1395 if (!check_deps(deb_file, 0, deb_count)) { 1375 if (!check_deps(deb_file, 0, deb_count)) {
1396 error_msg_and_die("Dependency check fialed"); 1376 error_msg_and_die("Dependency check failed");
1397 } 1377 }
1398 } 1378 }
1399 1379
@@ -1416,6 +1396,7 @@ extern int dpkg_main(int argc, char **argv)
1416 configure_package(deb_file[i]); 1396 configure_package(deb_file[i]);
1417 } 1397 }
1418 } 1398 }
1399
1419 write_status_file(deb_file); 1400 write_status_file(deb_file);
1420 1401
1421 for (i = 0; i < NAME_HASH_PRIME; i++) { 1402 for (i = 0; i < NAME_HASH_PRIME; i++) {
diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c
index 7f4dcbf01..a933c6948 100644
--- a/archival/dpkg_deb.c
+++ b/archival/dpkg_deb.c
@@ -110,12 +110,17 @@ extern int dpkg_deb_main(int argc, char **argv)
110 } 110 }
111 else if (arg_type == arg_type_field) { 111 else if (arg_type == arg_type_field) {
112 char *field = NULL; 112 char *field = NULL;
113 char *name;
114 char *value;
113 int field_start = 0; 115 int field_start = 0;
114 116
115 while ((field = read_package_field(&output_buffer[field_start])) != NULL) { 117 while (1) {
116 field_start += (strlen(field) + 1); 118 field_start += read_package_field(&output_buffer[field_start], &name, &value);
117 if (strstr(field, argv[optind + 1]) == field) { 119 if (name == NULL) {
118 puts(field + strlen(argv[optind + 1]) + 2); 120 break;
121 }
122 if (strcmp(name, argv[optind + 1]) == 0) {
123 puts(value);
119 } 124 }
120 free(field); 125 free(field);
121 } 126 }
diff --git a/dpkg.c b/dpkg.c
index e9afe5f6e..f207b23ac 100644
--- a/dpkg.c
+++ b/dpkg.c
@@ -499,34 +499,17 @@ unsigned int fill_package_struct(char *control_buffer)
499{ 499{
500 common_node_t *new_node = (common_node_t *) xcalloc(1, sizeof(common_node_t)); 500 common_node_t *new_node = (common_node_t *) xcalloc(1, sizeof(common_node_t));
501 501
502 char *field; 502 char *field_name = xmalloc(sizeof(char *));
503 char *field_name; 503 char *field_value = xmalloc(sizeof(char *));
504 char *field_value;
505 int field_start = 0; 504 int field_start = 0;
506 int field_length;
507 int seperator_offset;
508 int num = -1; 505 int num = -1;
509 int buffer_length = strlen(control_buffer); 506 int buffer_length = strlen(control_buffer);
510 507
511 new_node->version = search_name_hashtable("unknown"); 508 new_node->version = search_name_hashtable("unknown");
512 while (field_start < buffer_length) { 509 while (field_start < buffer_length) {
513 field = read_package_field(&control_buffer[field_start]); 510 field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
514
515 /* Setup start point for next field */
516 field_length = strlen(field);
517 field_start += (field_length + 1);
518
519 seperator_offset = strcspn(field, ":");
520 if (seperator_offset == 0) {
521 free(field);
522 continue;
523 }
524 field_name = xstrndup(field, seperator_offset);
525 field_value = field + seperator_offset + 1;
526 field_value += strspn(field_value, " \n\t");
527 511
528 /* Should be able to replace this strlen with pointer arithmatic */ 512 if (field_name == NULL) {
529 if (strlen(field_value) == 0) {
530 goto fill_package_struct_cleanup; // Oh no, the dreaded goto statement !! 513 goto fill_package_struct_cleanup; // Oh no, the dreaded goto statement !!
531 } 514 }
532 515
@@ -562,7 +545,7 @@ unsigned int fill_package_struct(char *control_buffer)
562 } 545 }
563fill_package_struct_cleanup: 546fill_package_struct_cleanup:
564 free(field_name); 547 free(field_name);
565 free(field); 548 free(field_value);
566 } 549 }
567 if (new_node->version == search_name_hashtable("unknown")) { 550 if (new_node->version == search_name_hashtable("unknown")) {
568 free_package(new_node); 551 free_package(new_node);
@@ -739,6 +722,23 @@ char *get_depends_field(common_node_t *package, const int depends_type)
739 return(depends); 722 return(depends);
740} 723}
741 724
725void write_buffer_no_status(FILE *new_status_file, const char *control_buffer)
726{
727 char *name;
728 char *value;
729 int start = 0;
730 while (1) {
731 start += read_package_field(&control_buffer[start], &name, &value);
732 if (name == NULL) {
733 break;
734 }
735 if (strcmp(name, "Status") != 0) {
736 fprintf(new_status_file, "%s: %s\n", name, value);
737 }
738 }
739 return;
740}
741
742/* This could do with a cleanup */ 742/* This could do with a cleanup */
743void write_status_file(deb_file_t **deb_file) 743void write_status_file(deb_file_t **deb_file)
744{ 744{
@@ -748,11 +748,8 @@ void write_status_file(deb_file_t **deb_file)
748 char *status_from_file; 748 char *status_from_file;
749 char *control_buffer = NULL; 749 char *control_buffer = NULL;
750 char *tmp_string; 750 char *tmp_string;
751 char *field;
752 int status_num; 751 int status_num;
753 int field_length;
754 int field_start = 0; 752 int field_start = 0;
755 int buffer_length;
756 int write_flag; 753 int write_flag;
757 int i = 0; 754 int i = 0;
758 755
@@ -762,7 +759,6 @@ void write_status_file(deb_file_t **deb_file)
762 tmp_string += strspn(tmp_string, " \n\t"); 759 tmp_string += strspn(tmp_string, " \n\t");
763 package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n\0")); 760 package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n\0"));
764 write_flag = FALSE; 761 write_flag = FALSE;
765
766 tmp_string = strstr(control_buffer, "Status:"); 762 tmp_string = strstr(control_buffer, "Status:");
767 if (tmp_string != NULL) { 763 if (tmp_string != NULL) {
768 /* Seperate the status value from the control buffer */ 764 /* Seperate the status value from the control buffer */
@@ -786,20 +782,11 @@ void write_status_file(deb_file_t **deb_file)
786 i = 0; 782 i = 0;
787 while(deb_file[i] != NULL) { 783 while(deb_file[i] != NULL) {
788 if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) { 784 if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) {
789 char *last_char;
790 /* Write a status file entry with a modified status */ 785 /* Write a status file entry with a modified status */
791 /* remove trailing \n's */ 786 /* remove trailing \n's */
792 while(1) { 787 write_buffer_no_status(new_status_file, deb_file[i]->control_file);
793 last_char = last_char_is(deb_file[i]->control_file, '\n');
794 if (last_char) {
795 *last_char = '\0';
796 } else {
797 break;
798 }
799 }
800 fputs(deb_file[i]->control_file, new_status_file);
801 set_status(status_num, "ok", 2); 788 set_status(status_num, "ok", 2);
802 fprintf(new_status_file, "\nStatus: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); 789 fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
803 write_flag = TRUE; 790 write_flag = TRUE;
804 break; 791 break;
805 } 792 }
@@ -814,16 +801,17 @@ void write_status_file(deb_file_t **deb_file)
814 /* Only write the Package, Status, Priority and Section lines */ 801 /* Only write the Package, Status, Priority and Section lines */
815 fprintf(new_status_file, "Package: %s\n", package_name); 802 fprintf(new_status_file, "Package: %s\n", package_name);
816 fprintf(new_status_file, "Status: %s\n", status_from_hashtable); 803 fprintf(new_status_file, "Status: %s\n", status_from_hashtable);
817 buffer_length = strlen(control_buffer); 804
818 while (field_start < buffer_length) { 805 while (1) {
819 field = read_package_field(&control_buffer[field_start]); 806 char *field_name;
820 field_length = strlen(field); 807 char *field_value;
821 field_start += (field_length + 1); 808 field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
822 if (strncmp(field, "Priority:", 9) == 0) { 809 if (field_name == NULL) {
823 fprintf(new_status_file, "Priority:%s\n", field + 9); 810 break;
824 } 811 }
825 if (strncmp(field, "Section:", 8) == 0) { 812 if ((strcmp(field_name, "Priority") == 0) ||
826 fprintf(new_status_file, "Section:%s\n", field + 8); 813 (strcmp(field_name, "Section") == 0)) {
814 fprintf(new_status_file, "%s: %s\n", field_name, field_value);
827 } 815 }
828 } 816 }
829 write_flag = TRUE; 817 write_flag = TRUE;
@@ -831,25 +819,26 @@ void write_status_file(deb_file_t **deb_file)
831 } 819 }
832 else if (strcmp("config-files", name_hashtable[state_status]) == 0) { 820 else if (strcmp("config-files", name_hashtable[state_status]) == 0) {
833 /* only change the status line */ 821 /* only change the status line */
834 buffer_length = strlen(control_buffer); 822// buffer_length = strlen(control_buffer);
835 while (field_start < buffer_length) { 823 while (1) {
836 field = read_package_field(&control_buffer[field_start]); 824 char *field_name;
825 char *field_value;
826 field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
827 if (field_name == NULL) {
828 break;
829 }
837 /* Setup start point for next field */ 830 /* Setup start point for next field */
838 field_length = strlen(field); 831 if (strcmp(field_name, "Status") == 0) {
839 field_start += (field_length + 1);
840 if (strncmp(field, "Status:", 7) == 0) {
841 fprintf(new_status_file, "Status: %s\n", status_from_hashtable); 832 fprintf(new_status_file, "Status: %s\n", status_from_hashtable);
842 } else { 833 } else {
843 fprintf(new_status_file, "%s\n", field); 834 fprintf(new_status_file, "%s: %s\n", field_name, field_value);
844 } 835 }
845 free(field);
846 } 836 }
847 write_flag = TRUE; 837 write_flag = TRUE;
848 fputs("\n", new_status_file); 838 fputs("\n", new_status_file);
849 } 839 }
850 } 840 }
851 } 841 }
852
853 /* If the package from the status file wasnt handle above, do it now*/ 842 /* If the package from the status file wasnt handle above, do it now*/
854 if (write_flag == FALSE) { 843 if (write_flag == FALSE) {
855 fprintf(new_status_file, "%s\n\n", control_buffer); 844 fprintf(new_status_file, "%s\n\n", control_buffer);
@@ -866,20 +855,9 @@ void write_status_file(deb_file_t **deb_file)
866 for(i = 0; deb_file[i] != NULL; i++) { 855 for(i = 0; deb_file[i] != NULL; i++) {
867 status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]); 856 status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]);
868 if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) { 857 if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) {
869 char *last_char; 858 write_buffer_no_status(new_status_file, deb_file[i]->control_file);
870 /* remove trailing \n's */
871 while(1) {
872 last_char = last_char_is(deb_file[i]->control_file, '\n');
873 if (last_char) {
874 *last_char = '\0';
875 } else {
876 break;
877 }
878 }
879
880 fputs(deb_file[i]->control_file, new_status_file);
881 set_status(status_num, "ok", 2); 859 set_status(status_num, "ok", 2);
882 fprintf(new_status_file, "\nStatus: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); 860 fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
883 } 861 }
884 } 862 }
885 fclose(old_status_file); 863 fclose(old_status_file);
@@ -1037,9 +1015,11 @@ char **create_list(const char *filename)
1037 int length = 0; 1015 int length = 0;
1038 int count = 0; 1016 int count = 0;
1039 1017
1040 list_stream = xfopen(filename, "r"); 1018 /* dont use [xw]fopen here, handle error ourself */
1019 list_stream = fopen(filename, "r");
1041 if (list_stream == NULL) { 1020 if (list_stream == NULL) {
1042 return(NULL); 1021 *file_list = NULL;
1022 return(file_list);
1043 } 1023 }
1044 while (getline(&line, &length, list_stream) != -1) { 1024 while (getline(&line, &length, list_stream) != -1) {
1045 file_list = xrealloc(file_list, sizeof(char *) * (length + 1)); 1025 file_list = xrealloc(file_list, sizeof(char *) * (length + 1));
@@ -1053,6 +1033,7 @@ char **create_list(const char *filename)
1053 length = 0; 1033 length = 0;
1054 } 1034 }
1055 fclose(list_stream); 1035 fclose(list_stream);
1036
1056 if (count == 0) { 1037 if (count == 0) {
1057 return(NULL); 1038 return(NULL);
1058 } else { 1039 } else {
@@ -1212,6 +1193,7 @@ void purge_package(const unsigned int package_num)
1212 if (run_package_script(package_name, "postrm") == -1) { 1193 if (run_package_script(package_name, "postrm") == -1) {
1213 error_msg_and_die("postrm fialure.. set status to what?"); 1194 error_msg_and_die("postrm fialure.. set status to what?");
1214 } 1195 }
1196
1215 /* Change package status */ 1197 /* Change package status */
1216 set_status(status_num, "purge", 1); 1198 set_status(status_num, "purge", 1);
1217 set_status(status_num, "not-installed", 3); 1199 set_status(status_num, "not-installed", 3);
@@ -1219,7 +1201,6 @@ void purge_package(const unsigned int package_num)
1219 1201
1220void unpack_package(deb_file_t *deb_file) 1202void unpack_package(deb_file_t *deb_file)
1221{ 1203{
1222// const unsigned int package_name_num = package_hashtable[deb_file->package]->name;
1223 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name]; 1204 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
1224 const unsigned int status_num = search_status_hashtable(package_name); 1205 const unsigned int status_num = search_status_hashtable(package_name);
1225 const unsigned int status_package_num = status_hashtable[status_num]->status; 1206 const unsigned int status_package_num = status_hashtable[status_num]->status;
@@ -1248,7 +1229,6 @@ void unpack_package(deb_file_t *deb_file)
1248 1229
1249 /* Create the list file */ 1230 /* Create the list file */
1250 strcat(info_prefix, "list"); 1231 strcat(info_prefix, "list");
1251
1252 out_stream = xfopen(info_prefix, "w"); 1232 out_stream = xfopen(info_prefix, "w");
1253 deb_extract(deb_file->filename, out_stream, (extract_quiet | extract_data_tar_gz | extract_list), NULL, NULL); 1233 deb_extract(deb_file->filename, out_stream, (extract_quiet | extract_data_tar_gz | extract_list), NULL, NULL);
1254 fclose(out_stream); 1234 fclose(out_stream);
@@ -1393,7 +1373,7 @@ extern int dpkg_main(int argc, char **argv)
1393 /* TODO: check dependencies before removing */ 1373 /* TODO: check dependencies before removing */
1394 if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) { 1374 if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {
1395 if (!check_deps(deb_file, 0, deb_count)) { 1375 if (!check_deps(deb_file, 0, deb_count)) {
1396 error_msg_and_die("Dependency check fialed"); 1376 error_msg_and_die("Dependency check failed");
1397 } 1377 }
1398 } 1378 }
1399 1379
@@ -1416,6 +1396,7 @@ extern int dpkg_main(int argc, char **argv)
1416 configure_package(deb_file[i]); 1396 configure_package(deb_file[i]);
1417 } 1397 }
1418 } 1398 }
1399
1419 write_status_file(deb_file); 1400 write_status_file(deb_file);
1420 1401
1421 for (i = 0; i < NAME_HASH_PRIME; i++) { 1402 for (i = 0; i < NAME_HASH_PRIME; i++) {
diff --git a/dpkg_deb.c b/dpkg_deb.c
index 7f4dcbf01..a933c6948 100644
--- a/dpkg_deb.c
+++ b/dpkg_deb.c
@@ -110,12 +110,17 @@ extern int dpkg_deb_main(int argc, char **argv)
110 } 110 }
111 else if (arg_type == arg_type_field) { 111 else if (arg_type == arg_type_field) {
112 char *field = NULL; 112 char *field = NULL;
113 char *name;
114 char *value;
113 int field_start = 0; 115 int field_start = 0;
114 116
115 while ((field = read_package_field(&output_buffer[field_start])) != NULL) { 117 while (1) {
116 field_start += (strlen(field) + 1); 118 field_start += read_package_field(&output_buffer[field_start], &name, &value);
117 if (strstr(field, argv[optind + 1]) == field) { 119 if (name == NULL) {
118 puts(field + strlen(argv[optind + 1]) + 2); 120 break;
121 }
122 if (strcmp(name, argv[optind + 1]) == 0) {
123 puts(value);
119 } 124 }
120 free(field); 125 free(field);
121 } 126 }
diff --git a/include/libbb.h b/include/libbb.h
index a9c1a870f..bf5f0c1c5 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -245,7 +245,7 @@ char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_header)
245 const int extract_function, const char *prefix, char **extract_names); 245 const int extract_function, const char *prefix, char **extract_names);
246char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function, 246char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function,
247 const char *prefix, const char *filename); 247 const char *prefix, const char *filename);
248char *read_package_field(const char *package_buffer); 248int read_package_field(const char *package_buffer, char **field_name, char **field_value);
249char *fgets_str(FILE *file, const char *terminating_string); 249char *fgets_str(FILE *file, const char *terminating_string);
250 250
251extern int unzip(FILE *l_in_file, FILE *l_out_file); 251extern int unzip(FILE *l_in_file, FILE *l_out_file);
diff --git a/libbb/libbb.h b/libbb/libbb.h
index a9c1a870f..bf5f0c1c5 100644
--- a/libbb/libbb.h
+++ b/libbb/libbb.h
@@ -245,7 +245,7 @@ char *unarchive(FILE *src_stream, FILE *out_stream, file_header_t *(*get_header)
245 const int extract_function, const char *prefix, char **extract_names); 245 const int extract_function, const char *prefix, char **extract_names);
246char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function, 246char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function,
247 const char *prefix, const char *filename); 247 const char *prefix, const char *filename);
248char *read_package_field(const char *package_buffer); 248int read_package_field(const char *package_buffer, char **field_name, char **field_value);
249char *fgets_str(FILE *file, const char *terminating_string); 249char *fgets_str(FILE *file, const char *terminating_string);
250 250
251extern int unzip(FILE *l_in_file, FILE *l_out_file); 251extern int unzip(FILE *l_in_file, FILE *l_out_file);
diff --git a/libbb/read_package_field.c b/libbb/read_package_field.c
index 3715230fe..f561df831 100644
--- a/libbb/read_package_field.c
+++ b/libbb/read_package_field.c
@@ -3,25 +3,89 @@
3#include "libbb.h" 3#include "libbb.h"
4 4
5/* 5/*
6 * Returns a [multi-line] package field 6 * Gets the next package field from package_buffer, seperated into the field name
7 * and field value, it returns the int offset to the first character of the next field
7 */ 8 */
8extern char *read_package_field(const char *package_buffer) 9int read_package_field(const char *package_buffer, char **field_name, char **field_value)
9{ 10{
10 int field_length = 0; 11 int offset_name_start = 0;
11 int buffer_length = 0; 12 int offset_name_end = 0;
13 int offset_value_start = 0;
14 int offset_value_end = 0;
15 int offset = 0;
16 int next_offset;
17 int name_length;
18 int value_length;
19 int exit_flag = FALSE;
12 20
13 if (package_buffer == NULL) { 21 if (package_buffer == NULL) {
14 return(NULL); 22 *field_name = NULL;
23 *field_value = NULL;
24 return(-1);
15 } 25 }
16 buffer_length = strlen(package_buffer); 26 while (1) {
17 field_length = strcspn(package_buffer, "\n"); 27 next_offset = offset + 1;
18 while (field_length < buffer_length) { 28 switch (package_buffer[offset]) {
19 if (package_buffer[field_length + 1] != ' ') { 29 case('\0'):
20 return(xstrndup(package_buffer, field_length)); 30 exit_flag = TRUE;
31 break;
32 case(':'):
33 if (offset_name_end == 0) {
34 offset_name_end = offset;
35 offset_value_start = next_offset;
36 }
37 /* TODO: Name might still have trailing spaces if ':' isnt
38 * immediately after name */
39 break;
40 case('\n'):
41 /* TODO: The char next_offset may be out of bounds */
42 if (package_buffer[next_offset] != ' ') {
43 exit_flag = TRUE;
44 break;
45 }
46 case('\t'):
47 case(' '):
48 /* increment the value start point if its a just filler */
49 if (offset_name_start == offset) {
50 offset_name_start++;
51 }
52 if (offset_value_start == offset) {
53 offset_value_start++;
54 }
55 break;
21 } 56 }
22 field_length++; 57 if (exit_flag == TRUE) {
23 field_length += strcspn(&package_buffer[field_length], "\n"); 58 /* Check that the names are valid */
59 offset_value_end = offset;
60 name_length = offset_name_end - offset_name_start;
61 value_length = offset_value_end - offset_value_start;
62 if (name_length == 0) {
63 break;
64 }
65 if ((name_length > 0) && (value_length > 0)) {
66 break;
67 }
68
69 /* If not valid, start fresh with next field */
70 exit_flag = FALSE;
71 offset_name_start = offset + 1;
72 offset_name_end = 0;
73 offset_value_start = offset + 1;
74 offset_value_end = offset + 1;
75 offset++;
76 }
77 offset++;
78 }
79 if (name_length == 0) {
80 *field_name = NULL;
81 } else {
82 *field_name = xstrndup(&package_buffer[offset_name_start], name_length);
83 }
84 if (value_length > 0) {
85 *field_value = xstrndup(&package_buffer[offset_value_start], value_length);
86 } else {
87 *field_value = NULL;
24 } 88 }
25 return(xstrdup(package_buffer)); 89 return(next_offset);
26} 90}
27 91