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

📄 dpkg.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 4 页
字号:
		}		free(array);	}}/* This function lists information on the installed packages. It loops through * the status_hashtable to retrieve the info. This results in smaller code than * scanning the status file. The resulting list, however, is unsorted.  */void list_packages(void){        int i;	printf("    Name           Version\n");	printf("+++-==============-==============\n");		/* go through status hash, dereference package hash and finally strings */	for (i=0; i<STATUS_HASH_PRIME+1; i++) {	        if (status_hashtable[i]) {		        const char *stat_str;  /* status string */			const char *name_str;  /* package name */			const char *vers_str;  /* version */			char  s1, s2;          /* status abbreviations */			int   spccnt;          /* space count */      			int   j;						stat_str = name_hashtable[status_hashtable[i]->status];			name_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->name];			vers_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->version];						/* get abbreviation for status field 1 */			s1 = stat_str[0] == 'i' ? 'i' : 'r';						/* get abbreviation for status field 2 */			for (j=0, spccnt=0; stat_str[j] && spccnt<2; j++) {			        if (stat_str[j] == ' ') spccnt++;			}			s2 = stat_str[j];						/* print out the line formatted like Debian dpkg */			printf("%c%c  %-14s %s\n", s1, s2, name_str, vers_str);		}    }}void remove_package(const unsigned int package_num){	const char *package_name = name_hashtable[package_hashtable[package_num]->name];	const unsigned int status_num = search_status_hashtable(package_name);	const int package_name_length = strlen(package_name);	char **remove_files;	char **exclude_files;	char list_name[package_name_length + 25];	char conffile_name[package_name_length + 30];	int return_value;	printf("Removing %s ...\n", package_name);	/* run prerm script */	return_value = run_package_script(package_name, "prerm");	if (return_value == -1) {		error_msg_and_die("script failed, prerm failure");	}	/* Create a list of files to remove, and a seperate list of those to keep */	sprintf(list_name, "/var/lib/dpkg/info/%s.list", package_name);	remove_files = create_list(list_name);	sprintf(conffile_name, "/var/lib/dpkg/info/%s.conffiles", package_name);	exclude_files = create_list(conffile_name);	/* Some directories cant be removed straight away, so do multiple passes */	while (remove_file_array(remove_files, exclude_files));	free_array(exclude_files);	free_array(remove_files);	/* Create a list of files in /var/lib/dpkg/info/<package>.* to keep  */	exclude_files = xmalloc(sizeof(char*) * 3);	exclude_files[0] = xstrdup(conffile_name);	exclude_files[1] = xmalloc(package_name_length + 27);	sprintf(exclude_files[1], "/var/lib/dpkg/info/%s.postrm", package_name);	exclude_files[2] = NULL;	/* Create a list of all /var/lib/dpkg/info/<package> files */	remove_files = all_control_list(package_name);	remove_file_array(remove_files, exclude_files);	free_array(remove_files);	free_array(exclude_files);	/* rename <package>.conffile to <package>.list */	rename(conffile_name, list_name);	/* Change package status */	set_status(status_num, "deinstall", 1);	set_status(status_num, "config-files", 3);}void purge_package(const unsigned int package_num){	const char *package_name = name_hashtable[package_hashtable[package_num]->name];	const unsigned int status_num = search_status_hashtable(package_name);	char **remove_files;	char **exclude_files;	char list_name[strlen(package_name) + 25];	/* run prerm script */	if (run_package_script(package_name, "prerm") != 0) {		error_msg_and_die("script failed, prerm failure");	}	/* Create a list of files to remove */	sprintf(list_name, "/var/lib/dpkg/info/%s.list", package_name);	remove_files = create_list(list_name);	exclude_files = xmalloc(sizeof(char*));	exclude_files[0] = NULL;	/* Some directories cant be removed straight away, so do multiple passes */	while (remove_file_array(remove_files, exclude_files));	free_array(remove_files);	/* Create a list of all /var/lib/dpkg/info/<package> files */	remove_files = all_control_list(package_name);	remove_file_array(remove_files, exclude_files);	free_array(remove_files);	free(exclude_files);	/* run postrm script */	if (run_package_script(package_name, "postrm") == -1) {		error_msg_and_die("postrm fialure.. set status to what?");	}	/* Change package status */	set_status(status_num, "purge", 1);	set_status(status_num, "not-installed", 3);}void unpack_package(deb_file_t *deb_file){	const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];	const unsigned int status_num = search_status_hashtable(package_name);	const unsigned int status_package_num = status_hashtable[status_num]->package;	FILE *out_stream;	char *info_prefix;	/* If existing version, remove it first */	if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {		/* Package is already installed, remove old version first */		printf("Preparing to replace %s %s (using %s) ...\n", package_name,			name_hashtable[package_hashtable[status_package_num]->version],			deb_file->filename);		remove_package(status_package_num);	} else {		printf("Unpacking %s (from %s) ...\n", package_name, deb_file->filename);	}	/* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */	info_prefix = (char *) xmalloc(strlen(package_name) + 20 + 4 + 2);	sprintf(info_prefix, "/var/lib/dpkg/info/%s.", package_name);	deb_extract(deb_file->filename, stdout, (extract_quiet | extract_control_tar_gz | extract_all_to_fs | extract_unconditional), info_prefix, NULL);	/* Run the preinst prior to extracting */	if (run_package_script(package_name, "preinst") != 0) {		/* when preinst returns exit code != 0 then quit installation process */		error_msg_and_die("subprocess pre-installation script returned error.");	}		/* Extract data.tar.gz to the root directory */	deb_extract(deb_file->filename, stdout, (extract_quiet | extract_data_tar_gz | extract_all_to_fs | extract_unconditional), "/", NULL);	/* Create the list file */	strcat(info_prefix, "list");	out_stream = xfopen(info_prefix, "w");				deb_extract(deb_file->filename, out_stream, (extract_quiet | extract_data_tar_gz | extract_list), "/", NULL);	fclose(out_stream);	/* change status */	set_status(status_num, "install", 1);	set_status(status_num, "unpacked", 3);	free(info_prefix);}void configure_package(deb_file_t *deb_file){	const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];	const char *package_version = name_hashtable[package_hashtable[deb_file->package]->version];	const int status_num = search_status_hashtable(package_name);	printf("Setting up %s (%s)\n", package_name, package_version);	/* Run the postinst script */	if (run_package_script(package_name, "postinst") != 0) {		/* TODO: handle failure gracefully */		error_msg_and_die("postrm failure.. set status to what?");	}	/* Change status to reflect success */	set_status(status_num, "install", 1);	set_status(status_num, "installed", 3);}int dpkg_main(int argc, char **argv){	deb_file_t **deb_file = NULL;	status_node_t *status_node;	int opt;	int package_num;	int dpkg_opt = 0;	int deb_count = 0;	int state_status;	int status_num;	int i;	while ((opt = getopt(argc, argv, "CF:ilPru")) != -1) {		switch (opt) {			case 'C': // equivalent to --configure in official dpkg				dpkg_opt |= dpkg_opt_configure;				dpkg_opt |= dpkg_opt_package_name;				break;			case 'F': // equivalent to --force in official dpkg				if (strcmp(optarg, "depends") == 0) {					dpkg_opt |= dpkg_opt_force_ignore_depends;				}							case 'i':				dpkg_opt |= dpkg_opt_install;				dpkg_opt |= dpkg_opt_filename;				break;			case 'l':				dpkg_opt |= dpkg_opt_list_installed;				break;			case 'P':				dpkg_opt |= dpkg_opt_purge;				dpkg_opt |= dpkg_opt_package_name;				break;			case 'r':				dpkg_opt |= dpkg_opt_remove;				dpkg_opt |= dpkg_opt_package_name;				break;			case 'u':	/* Equivalent to --unpack in official dpkg */				dpkg_opt |= dpkg_opt_unpack;				dpkg_opt |= dpkg_opt_filename;				break;			default:				show_usage();		}	}	/* check for non-otion argument if expected  */	if ((dpkg_opt == 0) || ((argc == optind) && !(dpkg_opt && dpkg_opt_list_installed))) {		show_usage();	}/*	puts("(Reading database ... xxxxx files and directories installed.)"); */	index_status_file("/var/lib/dpkg/status");	/* if the list action was given print the installed packages and exit */	if (dpkg_opt & dpkg_opt_list_installed) {		list_packages();		return(EXIT_SUCCESS);	}		/* Read arguments and store relevant info in structs */	while (optind < argc) {		/* deb_count = nb_elem - 1 and we need nb_elem + 1 to allocate terminal node [NULL pointer] */		deb_file = xrealloc(deb_file, sizeof(deb_file_t *) * (deb_count + 2));		deb_file[deb_count] = (deb_file_t *) xmalloc(sizeof(deb_file_t));		if (dpkg_opt & dpkg_opt_filename) {			deb_file[deb_count]->filename = xstrdup(argv[optind]);			deb_file[deb_count]->control_file = deb_extract(argv[optind], stdout, (extract_control_tar_gz | extract_one_to_buffer), NULL, "./control");			if (deb_file[deb_count]->control_file == NULL) {				error_msg_and_die("Couldnt extract control file");			}			package_num = fill_package_struct(deb_file[deb_count]->control_file);			if (package_num == -1) {				error_msg("Invalid control file in %s", argv[optind]);				continue;			}			deb_file[deb_count]->package = (unsigned int) package_num;			/* Add the package to the status hashtable */			if ((dpkg_opt & dpkg_opt_unpack) || (dpkg_opt & dpkg_opt_install)) {				status_node = (status_node_t *) xmalloc(sizeof(status_node_t));				status_node->package = deb_file[deb_count]->package;				/* Try and find a currently installed version of this package */				status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);				/* If no previous entry was found initialise a new entry */				if ((status_hashtable[status_num] == NULL) ||					(status_hashtable[status_num]->status == 0)) {					/* reinstreq isnt changed to "ok" until the package control info					 * is written to the status file*/					status_node->status = search_name_hashtable("want-install reinstreq not-installed");					status_hashtable[status_num] = status_node;				} else {					status_hashtable[status_num]->status = search_name_hashtable("want-install reinstreq not-installed");				}			}		}		else if (dpkg_opt & dpkg_opt_package_name) {			deb_file[deb_count]->filename = NULL;			deb_file[deb_count]->control_file = NULL;			deb_file[deb_count]->package = search_package_hashtable(				search_name_hashtable(argv[optind]),				search_name_hashtable("ANY"), VER_ANY);			if (package_hashtable[deb_file[deb_count]->package] == NULL) {				error_msg_and_die("Package %s is uninstalled or unknown\n", argv[optind]);			}			state_status = get_status(search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]), 3);			/* check package status is "installed" */			if (dpkg_opt & dpkg_opt_remove) {				if ((strcmp(name_hashtable[state_status], "not-installed") == 0) ||					(strcmp(name_hashtable[state_status], "config-files") == 0)) {					error_msg_and_die("%s is already removed.", name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);				}			}			else if (dpkg_opt & dpkg_opt_purge) {				/* if package status is "conf-files" then its ok */				if (strcmp(name_hashtable[state_status], "not-installed") == 0) {					error_msg_and_die("%s is already purged.", name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);				}			}		}		deb_count++;		optind++;	}	deb_file[deb_count] = NULL;	/* Check that the deb file arguments are installable */	/* TODO: check dependencies before removing */	if ((dpkg_opt & dpkg_opt_force_ignore_depends) != dpkg_opt_force_ignore_depends) {		if (!check_deps(deb_file, 0, deb_count)) {			error_msg_and_die("Dependency check failed");		}	}	for (i = 0; i < deb_count; i++) {		/* Remove or purge packages */		if (dpkg_opt & dpkg_opt_remove) {			remove_package(deb_file[i]->package);		}		else if (dpkg_opt & dpkg_opt_purge) {			purge_package(deb_file[i]->package);		}		else if (dpkg_opt & dpkg_opt_unpack) {			unpack_package(deb_file[i]);		}		else if (dpkg_opt & dpkg_opt_install) {			unpack_package(deb_file[i]);			configure_package(deb_file[i]);		}		else if (dpkg_opt & dpkg_opt_configure) {			configure_package(deb_file[i]);		}	}	write_status_file(deb_file);	for (i = 0; i < deb_count; i++) {		free(deb_file[i]->control_file);		free(deb_file[i]->filename);		free(deb_file[i]);	}	free(deb_file);	for (i = 0; i < NAME_HASH_PRIME; i++) {		if (name_hashtable[i] != NULL) {			free(name_hashtable[i]);		}	}	for (i = 0; i < PACKAGE_HASH_PRIME; i++) {		if (package_hashtable[i] != NULL) {			free_package(package_hashtable[i]);		}	}	for (i = 0; i < STATUS_HASH_PRIME; i++) {		if (status_hashtable[i] != NULL) {			free(status_hashtable[i]);		}	}	return(EXIT_SUCCESS);}

⌨️ 快捷键说明

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