📄 dpkg.c
字号:
}/* * Create one new node and one new edge for every dependency. */void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type){ char *line = xstrdup(whole_line); char *line2; char *line_ptr1 = NULL; char *line_ptr2 = NULL; char *field; char *field2; char *version; edge_t *edge; int offset_ch; int type; field = strtok_r(line, ",", &line_ptr1); do { line2 = xstrdup(field); field2 = strtok_r(line2, "|", &line_ptr2); if ((edge_type == EDGE_DEPENDS) && (strcmp(field, field2) != 0)) { type = EDGE_OR_DEPENDS; } else if ((edge_type == EDGE_PRE_DEPENDS) && (strcmp(field, field2) != 0)) { type = EDGE_OR_PRE_DEPENDS; } else { type = edge_type; } do { edge = (edge_t *) xmalloc(sizeof(edge_t)); edge->type = type; /* Skip any extra leading spaces */ field2 += strspn(field2, " "); /* Get dependency version info */ version = strchr(field2, '('); if (version == NULL) { edge->operator = VER_ANY; /* Get the versions hash number, adding it if the number isnt already in there */ edge->version = search_name_hashtable("ANY"); } else { /* Skip leading ' ' or '(' */ version += strspn(field2, " "); version += strspn(version, "("); /* Calculate length of any operator charactors */ offset_ch = strspn(version, "<=>"); /* Determine operator */ if (offset_ch > 0) { if (strncmp(version, "=", offset_ch) == 0) { edge->operator = VER_EQUAL; } else if (strncmp(version, "<<", offset_ch) == 0) { edge->operator = VER_LESS; } else if (strncmp(version, "<=", offset_ch) == 0) { edge->operator = VER_LESS_EQUAL; } else if (strncmp(version, ">>", offset_ch) == 0) { edge->operator = VER_MORE; } else if (strncmp(version, ">=", offset_ch) == 0) { edge->operator = VER_MORE_EQUAL; } else { error_msg_and_die("Illegal operator\n"); } } /* skip to start of version numbers */ version += offset_ch; version += strspn(version, " "); /* Truncate version at trailing ' ' or ')' */ version[strcspn(version, " )")] = '\0'; /* Get the versions hash number, adding it if the number isnt already in there */ edge->version = search_name_hashtable(version); } /* Get the dependency name */ field2[strcspn(field2, " (")] = '\0'; edge->name = search_name_hashtable(field2); /* link the new edge to the current node */ parent_node->num_of_edges++; parent_node->edge = xrealloc(parent_node->edge, sizeof(edge_t) * (parent_node->num_of_edges + 1)); parent_node->edge[parent_node->num_of_edges - 1] = edge; } while ((field2 = strtok_r(NULL, "|", &line_ptr2)) != NULL); free(line2); } while ((field = strtok_r(NULL, ",", &line_ptr1)) != NULL); free(line); return;}void free_package(common_node_t *node){ unsigned short i; if (node) { for (i = 0; i < node->num_of_edges; i++) { if (node->edge[i]) { free(node->edge[i]); } } if (node->edge) { free(node->edge); } free(node); }}unsigned int fill_package_struct(char *control_buffer){ common_node_t *new_node = (common_node_t *) xcalloc(1, sizeof(common_node_t)); char *field_name; char *field_value; int field_start = 0; int num = -1; int buffer_length = strlen(control_buffer); new_node->version = search_name_hashtable("unknown"); while (field_start < buffer_length) { field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value); if (field_name == NULL) { goto fill_package_struct_cleanup; // Oh no, the dreaded goto statement !! } if (strcmp(field_name, "Package") == 0) { new_node->name = search_name_hashtable(field_value); } else if (strcmp(field_name, "Version") == 0) { new_node->version = search_name_hashtable(field_value); } else if (strcmp(field_name, "Pre-Depends") == 0) { add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS); } else if (strcmp(field_name, "Depends") == 0) { add_split_dependencies(new_node, field_value, EDGE_DEPENDS); } else if (strcmp(field_name, "Replaces") == 0) { add_split_dependencies(new_node, field_value, EDGE_REPLACES); } else if (strcmp(field_name, "Provides") == 0) { add_split_dependencies(new_node, field_value, EDGE_PROVIDES); } else if (strcmp(field_name, "Conflicts") == 0) { add_split_dependencies(new_node, field_value, EDGE_CONFLICTS); } else if (strcmp(field_name, "Suggests") == 0) { add_split_dependencies(new_node, field_value, EDGE_SUGGESTS); } else if (strcmp(field_name, "Recommends") == 0) { add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS); } else if (strcmp(field_name, "Enhances") == 0) { add_split_dependencies(new_node, field_value, EDGE_ENHANCES); }fill_package_struct_cleanup: if (field_name) { free(field_name); } if (field_value) { free(field_value); } } if (new_node->version == search_name_hashtable("unknown")) { free_package(new_node); return(-1); } num = search_package_hashtable(new_node->name, new_node->version, VER_EQUAL); if (package_hashtable[num] == NULL) { package_hashtable[num] = new_node; } else { free_package(new_node); } return(num);}/* if num = 1, it returns the want status, 2 returns flag, 3 returns status */unsigned int get_status(const unsigned int status_node, const int num){ char *status_string = name_hashtable[status_hashtable[status_node]->status]; char *state_sub_string; unsigned int state_sub_num; int len; int i; /* set tmp_string to point to the start of the word number */ for (i = 1; i < num; i++) { /* skip past a word */ status_string += strcspn(status_string, " "); /* skip past the seperating spaces */ status_string += strspn(status_string, " "); } len = strcspn(status_string, " \n\0"); state_sub_string = xstrndup(status_string, len); state_sub_num = search_name_hashtable(state_sub_string); free(state_sub_string); return(state_sub_num);}void set_status(const unsigned int status_node_num, const char *new_value, const int position){ const unsigned int new_value_len = strlen(new_value); const unsigned int new_value_num = search_name_hashtable(new_value); unsigned int want = get_status(status_node_num, 1); unsigned int flag = get_status(status_node_num, 2); unsigned int status = get_status(status_node_num, 3); int want_len = strlen(name_hashtable[want]); int flag_len = strlen(name_hashtable[flag]); int status_len = strlen(name_hashtable[status]); char *new_status; switch (position) { case (1): want = new_value_num; want_len = new_value_len; break; case (2): flag = new_value_num; flag_len = new_value_len; break; case (3): status = new_value_num; status_len = new_value_len; break; default: error_msg_and_die("DEBUG ONLY: this shouldnt happen"); } new_status = (char *) xmalloc(want_len + flag_len + status_len + 3); sprintf(new_status, "%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]); status_hashtable[status_node_num]->status = search_name_hashtable(new_status); free(new_status); return;}void index_status_file(const char *filename){ FILE *status_file; char *control_buffer; char *status_line; status_node_t *status_node = NULL; unsigned int status_num; status_file = xfopen(filename, "r"); while ((control_buffer = fgets_str(status_file, "\n\n")) != NULL) { const unsigned int package_num = fill_package_struct(control_buffer); if (package_num != -1) { status_node = xmalloc(sizeof(status_node_t)); /* fill_package_struct doesnt handle the status field */ status_line = strstr(control_buffer, "Status:"); if (status_line != NULL) { status_line += 7; status_line += strspn(status_line, " \n\t"); status_line = xstrndup(status_line, strcspn(status_line, "\n\0")); status_node->status = search_name_hashtable(status_line); free(status_line); } status_node->package = package_num; status_num = search_status_hashtable(name_hashtable[package_hashtable[status_node->package]->name]); status_hashtable[status_num] = status_node; } free(control_buffer); } fclose(status_file); return;}char *get_depends_field(common_node_t *package, const int depends_type){ char *depends = NULL; char *old_sep = (char *)xcalloc(1, 3); char *new_sep = (char *)xcalloc(1, 3); int line_size = 0; int depends_size; int i; for (i = 0; i < package->num_of_edges; i++) { if ((package->edge[i]->type == EDGE_OR_PRE_DEPENDS) || (package->edge[i]->type == EDGE_OR_DEPENDS)) { } if ((package->edge[i]->type == depends_type) || (package->edge[i]->type == depends_type + 1)) { /* Check if its the first time through */ depends_size = 8 + strlen(name_hashtable[package->edge[i]->name]) + strlen(name_hashtable[package->edge[i]->version]); line_size += depends_size; depends = (char *) xrealloc(depends, line_size + 1); /* Check to see if this dependency is the type we are looking for * +1 to check for 'extra' types, e.g. ored dependecies */ strcpy(old_sep, new_sep); if (package->edge[i]->type == depends_type) { strcpy(new_sep, ", "); } else if (package->edge[i]->type == depends_type + 1) { strcpy(new_sep, "| "); } if (depends_size == line_size) { strcpy(depends, ""); } else { if ((strcmp(old_sep, "| ") == 0) && (strcmp(new_sep, "| ") == 0)) { strcat(depends, " | "); } else { strcat(depends, ", "); } } strcat(depends, name_hashtable[package->edge[i]->name]); if (strcmp(name_hashtable[package->edge[i]->version], "NULL") != 0) { if (package->edge[i]->operator == VER_EQUAL) { strcat(depends, " (= "); } else if (package->edge[i]->operator == VER_LESS) { strcat(depends, " (<< "); } else if (package->edge[i]->operator == VER_LESS_EQUAL) { strcat(depends, " (<= "); } else if (package->edge[i]->operator == VER_MORE) { strcat(depends, " (>> "); } else if (package->edge[i]->operator == VER_MORE_EQUAL) { strcat(depends, " (>= "); } else { strcat(depends, " ("); } strcat(depends, name_hashtable[package->edge[i]->version]); strcat(depends, ")"); } } } return(depends);}void write_buffer_no_status(FILE *new_status_file, const char *control_buffer){ char *name; char *value; int start = 0; while (1) { start += read_package_field(&control_buffer[start], &name, &value); if (name == NULL) { break; } if (strcmp(name, "Status") != 0) { fprintf(new_status_file, "%s: %s\n", name, value); } } return;}/* This could do with a cleanup */void write_status_file(deb_file_t **deb_file){ FILE *old_status_file = xfopen("/var/lib/dpkg/status", "r"); FILE *new_status_file = xfopen("/var/lib/dpkg/status.udeb", "w"); char *package_name; char *status_from_file; char *control_buffer = NULL; char *tmp_string; int status_num; int field_start = 0; int write_flag; int i = 0; /* Update previously known packages */ while ((control_buffer = fgets_str(old_status_file, "\n\n")) != NULL) { if ((tmp_string = strstr(control_buffer, "Package:")) == NULL) { continue; } tmp_string += 8; tmp_string += strspn(tmp_string, " \n\t"); package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n\0")); write_flag = FALSE; tmp_string = strstr(control_buffer, "Status:"); if (tmp_string != NULL) { /* Seperate the status value from the control buffer */ tmp_string += 7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -