diff options
Diffstat (limited to 'dpkg.c')
-rw-r--r-- | dpkg.c | 127 |
1 files changed, 54 insertions, 73 deletions
@@ -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++) { |