📄 dpkg.c
字号:
tmp_string += strspn(tmp_string, " \n\t"); status_from_file = xstrndup(tmp_string, strcspn(tmp_string, "\n")); } else { status_from_file = NULL; } /* Find this package in the status hashtable */ status_num = search_status_hashtable(package_name); if (status_hashtable[status_num] != NULL) { const char *status_from_hashtable = name_hashtable[status_hashtable[status_num]->status]; if (strcmp(status_from_file, status_from_hashtable) != 0) { /* New status isnt exactly the same as old status */ const int state_status = get_status(status_num, 3); if ((strcmp("installed", name_hashtable[state_status]) == 0) || (strcmp("unpacked", name_hashtable[state_status]) == 0)) { /* We need to add the control file from the package */ i = 0; while(deb_file[i] != NULL) { if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) { /* Write a status file entry with a modified status */ /* remove trailing \n's */ write_buffer_no_status(new_status_file, deb_file[i]->control_file); set_status(status_num, "ok", 2); fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); write_flag = TRUE; break; } i++; } /* This is temperary, debugging only */ if (deb_file[i] == NULL) { error_msg_and_die("ALERT: Couldnt find a control file, your status file may be broken, status may be incorrect for %s", package_name); } } else if (strcmp("not-installed", name_hashtable[state_status]) == 0) { /* Only write the Package, Status, Priority and Section lines */ fprintf(new_status_file, "Package: %s\n", package_name); fprintf(new_status_file, "Status: %s\n", status_from_hashtable); while (1) { char *field_name; char *field_value; field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value); if (field_name == NULL) { break; } if ((strcmp(field_name, "Priority") == 0) || (strcmp(field_name, "Section") == 0)) { fprintf(new_status_file, "%s: %s\n", field_name, field_value); } } write_flag = TRUE; fputs("\n", new_status_file); } else if (strcmp("config-files", name_hashtable[state_status]) == 0) { /* only change the status line */ while (1) { char *field_name; char *field_value; field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value); if (field_name == NULL) { break; } /* Setup start point for next field */ if (strcmp(field_name, "Status") == 0) { fprintf(new_status_file, "Status: %s\n", status_from_hashtable); } else { fprintf(new_status_file, "%s: %s\n", field_name, field_value); } } write_flag = TRUE; fputs("\n", new_status_file); } } } /* If the package from the status file wasnt handle above, do it now*/ if (! write_flag) { fprintf(new_status_file, "%s\n\n", control_buffer); } if (status_from_file != NULL) { free(status_from_file); } free(package_name); free(control_buffer); } /* Write any new packages */ for(i = 0; deb_file[i] != NULL; i++) { status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]); if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) { write_buffer_no_status(new_status_file, deb_file[i]->control_file); set_status(status_num, "ok", 2); fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]); } } fclose(old_status_file); fclose(new_status_file); /* Create a seperate backfile to dpkg */ if (rename("/var/lib/dpkg/status", "/var/lib/dpkg/status.udeb.bak") == -1) { struct stat stat_buf; if (stat("/var/lib/dpkg/status", &stat_buf) == 0) { error_msg_and_die("Couldnt create backup status file"); } /* Its ok if renaming the status file fails becasue status * file doesnt exist, maybe we are starting from scratch */ error_msg("No status file found, creating new one"); } if (rename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status") == -1) { error_msg_and_die("DANGER: Couldnt create status file, you need to manually repair your status file"); }}int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count){ int *conflicts = NULL; int conflicts_num = 0; int state_status; int state_flag; int state_want; int i = deb_start; int j; /* Check for conflicts * TODO: TEST if conflicts with other packages to be installed * * Add install packages and the packages they provide * to the list of files to check conflicts for */ /* Create array of package numbers to check against * installed package for conflicts*/ while (deb_file[i] != NULL) { const unsigned int package_num = deb_file[i]->package; conflicts = xrealloc(conflicts, sizeof(int) * (conflicts_num + 1)); conflicts[conflicts_num] = package_num; conflicts_num++; /* add provides to conflicts list */ for (j = 0; j < package_hashtable[package_num]->num_of_edges; j++) { if (package_hashtable[package_num]->edge[j]->type == EDGE_PROVIDES) { const int conflicts_package_num = search_package_hashtable( package_hashtable[package_num]->edge[j]->name, package_hashtable[package_num]->edge[j]->version, package_hashtable[package_num]->edge[j]->operator); if (package_hashtable[conflicts_package_num] == NULL) { /* create a new package */ common_node_t *new_node = (common_node_t *) xmalloc(sizeof(common_node_t)); new_node->name = package_hashtable[package_num]->edge[j]->name; new_node->version = package_hashtable[package_num]->edge[j]->version; new_node->num_of_edges = 0; new_node->edge = NULL; package_hashtable[conflicts_package_num] = new_node; } conflicts = xrealloc(conflicts, sizeof(int) * (conflicts_num + 1)); conflicts[conflicts_num] = conflicts_package_num; conflicts_num++; } } i++; } /* Check conflicts */ i = 0; while (deb_file[i] != NULL) { const common_node_t *package_node = package_hashtable[deb_file[i]->package]; int status_num = 0; status_num = search_status_hashtable(name_hashtable[package_node->name]); if (get_status(status_num, 3) == search_name_hashtable("installed")) { i++; continue; } for (j = 0; j < package_node->num_of_edges; j++) { const edge_t *package_edge = package_node->edge[j]; const unsigned int package_num = search_package_hashtable(package_edge->name, package_edge->version, package_edge->operator); if (package_edge->type == EDGE_CONFLICTS) { int result = 0; if (package_hashtable[package_num] != NULL) { status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]); state_status = get_status(status_num, 3); state_flag = get_status(status_num, 1); result = (state_status == search_name_hashtable("installed")) || (state_flag == search_name_hashtable("want-install")); if (result) { result = test_version(package_hashtable[deb_file[i]->package]->version, package_edge->version, package_edge->operator); } } if (result) { error_msg_and_die("Package %s conflicts with %s", name_hashtable[package_node->name], name_hashtable[package_edge->name]); } } } i++; } /* Check dependendcies */ i = 0; while (deb_file[i] != NULL) { const common_node_t *package_node = package_hashtable[deb_file[i]->package]; int status_num = 0; status_num = search_status_hashtable(name_hashtable[package_node->name]); state_status = get_status(status_num, 3); state_want = get_status(status_num, 1); if (state_status == search_name_hashtable("installed")) { i++; continue; } for (j = 0; j < package_hashtable[deb_file[i]->package]->num_of_edges; j++) { const edge_t *package_edge = package_node->edge[j]; unsigned int package_num; package_num = search_package_hashtable(package_edge->name, package_edge->version, package_edge->operator); switch (package_edge->type) { case(EDGE_PRE_DEPENDS): case(EDGE_OR_PRE_DEPENDS): { int result=1; /* It must be already installed */ /* NOTE: This is untested, nothing apropriate in my status file */ if (package_hashtable[package_num] != NULL) { status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]); state_status = get_status(status_num, 3); state_want = get_status(status_num, 1); result = (state_status != search_name_hashtable("installed")); } if (result) { error_msg_and_die("Package %s pre-depends on %s, but it is not installed", name_hashtable[package_node->name], name_hashtable[package_edge->name]); } break; } case(EDGE_DEPENDS): case(EDGE_OR_DEPENDS): { int result=1; if (package_hashtable[package_num] != NULL) { status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]); state_status = get_status(status_num, 3); state_want = get_status(status_num, 1); result=(state_status != search_name_hashtable("installed")) && (state_want != search_name_hashtable("want-install")); } /* It must be already installed, or to be installed */ if (result) { error_msg_and_die("Package %s depends on %s, but it is not installed, or flaged to be installed", name_hashtable[package_node->name], name_hashtable[package_edge->name]); } break; } } } i++; } free(conflicts); return(TRUE);}char **create_list(const char *filename){ FILE *list_stream; char **file_list = NULL; char *line = NULL; int length = 0; int count = 0; /* dont use [xw]fopen here, handle error ourself */ list_stream = fopen(filename, "r"); if (list_stream == NULL) { return(NULL); } while (getline(&line, &length, list_stream) != -1) { file_list = xrealloc(file_list, sizeof(char *) * (count + 2)); chomp(line); file_list[count] = xstrdup(line); count++; } fclose(list_stream); free(line); if (count == 0) { return(NULL); } else { file_list[count] = NULL; return(file_list); }}/* maybe i should try and hook this into remove_file.c somehow */int remove_file_array(char **remove_names, char **exclude_names){ struct stat path_stat; int match_flag; int remove_flag = FALSE; int i,j; if (remove_names == NULL) { return(FALSE); } for (i = 0; remove_names[i] != NULL; i++) { match_flag = FALSE; if (exclude_names != NULL) { for (j = 0; exclude_names[j] != 0; j++) { if (strcmp(remove_names[i], exclude_names[j]) == 0) { match_flag = TRUE; break; } } } if (!match_flag) { if (lstat(remove_names[i], &path_stat) < 0) { continue; } if (S_ISDIR(path_stat.st_mode)) { if (rmdir(remove_names[i]) != -1) { remove_flag = TRUE; } } else { if (unlink(remove_names[i]) != -1) { remove_flag = TRUE; } } } } return(remove_flag);}int run_package_script(const char *package_name, const char *script_type){ struct stat path_stat; char *script_path; int result; script_path = xmalloc(strlen(package_name) + strlen(script_type) + 21); sprintf(script_path, "/var/lib/dpkg/info/%s.%s", package_name, script_type); /* If the file doesnt exist is isnt a fatal */ if (lstat(script_path, &path_stat) < 0) { result = EXIT_SUCCESS; } else { result = system(script_path); } free(script_path); return(result);}char **all_control_list(const char *package_name){ const char *extensions[11] = {"preinst", "postinst", "prerm", "postrm", "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL }; unsigned short i = 0; char **remove_files; /* Create a list of all /var/lib/dpkg/info/<package> files */ remove_files = malloc(sizeof(char *) * 11); while (extensions[i]) { remove_files[i] = xmalloc(strlen(package_name) + strlen(extensions[i]) + 21); sprintf(remove_files[i], "/var/lib/dpkg/info/%s.%s", package_name, extensions[i]); i++; } remove_files[10] = NULL; return(remove_files);}void free_array(char **array){ if (array) { unsigned short i = 0; while (array[i]) { free(array[i]); i++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -