+fill_package_struct_cleanup:
+ free(field_name);
+ 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 = bb_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:
+ bb_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 = bb_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 = bb_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;