diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-07-18 15:47:21 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-07-18 15:47:21 +0000 |
commit | c3fbec73fb45997918bef927cea519866e1e1c9d (patch) | |
tree | 5c1fd9758c4c9894bb050d9c152e1735bc007536 | |
parent | 8d3b0497a4d8866f0cafd873f241971c2871d580 (diff) | |
download | busybox-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.c | 127 | ||||
-rw-r--r-- | archival/dpkg_deb.c | 13 | ||||
-rw-r--r-- | dpkg.c | 127 | ||||
-rw-r--r-- | dpkg_deb.c | 13 | ||||
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | libbb/libbb.h | 2 | ||||
-rw-r--r-- | libbb/read_package_field.c | 90 |
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 | } |
563 | fill_package_struct_cleanup: | 546 | fill_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 | ||
725 | void 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 */ |
743 | void write_status_file(deb_file_t **deb_file) | 743 | void 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 | ||
1220 | void unpack_package(deb_file_t *deb_file) | 1202 | void 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 | } |
@@ -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 | } |
563 | fill_package_struct_cleanup: | 546 | fill_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 | ||
725 | void 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 */ |
743 | void write_status_file(deb_file_t **deb_file) | 743 | void 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 | ||
1220 | void unpack_package(deb_file_t *deb_file) | 1202 | void 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); |
246 | char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function, | 246 | char *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); |
248 | char *read_package_field(const char *package_buffer); | 248 | int read_package_field(const char *package_buffer, char **field_name, char **field_value); |
249 | char *fgets_str(FILE *file, const char *terminating_string); | 249 | char *fgets_str(FILE *file, const char *terminating_string); |
250 | 250 | ||
251 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 251 | extern 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); |
246 | char *deb_extract(const char *package_filename, FILE *out_stream, const int extract_function, | 246 | char *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); |
248 | char *read_package_field(const char *package_buffer); | 248 | int read_package_field(const char *package_buffer, char **field_name, char **field_value); |
249 | char *fgets_str(FILE *file, const char *terminating_string); | 249 | char *fgets_str(FILE *file, const char *terminating_string); |
250 | 250 | ||
251 | extern int unzip(FILE *l_in_file, FILE *l_out_file); | 251 | extern 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 | */ |
8 | extern char *read_package_field(const char *package_buffer) | 9 | int 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 | ||