⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dpkg.c

📁 手机嵌入式Linux下可用的busybox源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return;}void free_package(common_node_t *node){	int i;	if (node != NULL) {		for (i = 0; i < node->num_of_edges; i++) {			if (node->edge[i] != NULL) {				free(node->edge[i]);			}		}		if (node->edge != NULL) {			free(node->edge);		}		if (node != NULL) {			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 = xmalloc(sizeof(char *));	char **field_value = xmalloc(sizeof(char *));	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);		}	}	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 = 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) {		tmp_string = strstr(control_buffer, "Package:") + 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;			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 == FALSE) {			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;	unsigned int status_package_num;	int i = deb_start;	int j, k;	/* 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 */	for (i = 0; i < conflicts_num; i++) {		/* Check for conflicts */		for (j = 0; j < STATUS_HASH_PRIME; j++) {			if (status_hashtable[j] == NULL) {				continue;			}			state_flag = get_status(j, 2);			state_status = get_status(j, 3);			if ((state_status != search_name_hashtable("installed"))				&& (state_flag != search_name_hashtable("want-install"))) {				continue;			}			status_package_num = status_hashtable[j]->package;			for (k = 0; k < package_hashtable[status_package_num]->num_of_edges; k++) {				const edge_t *package_edge = package_hashtable[status_package_num]->edge[k];				if (package_edge->type != EDGE_CONFLICTS) {					continue;				}				if (package_edge->name != package_hashtable[conflicts[i]]->name) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -