📄 pkg.c
字号:
/* pkg.c - the itsy package management system Carl D. Worth Copyright (C) 2001 University of Southern California This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.*/#include "ipkg.h"#include <ctype.h>#include <string.h>#include <errno.h>#include "pkg.h"#include "pkg_parse.h"#include "pkg_extract.h"#include "ipkg_message.h"#include "ipkg_utils.h"#include "sprintf_alloc.h"#include "file_util.h"#include "str_util.h"#include "xsystem.h"#include "ipkg_conf.h"typedef struct enum_map enum_map_t;struct enum_map{ int value; char *str;};static const enum_map_t pkg_state_want_map[] = { { SW_UNKNOWN, "unknown"}, { SW_INSTALL, "install"}, { SW_DEINSTALL, "deinstall"}, { SW_PURGE, "purge"}};static const enum_map_t pkg_state_flag_map[] = { { SF_OK, "ok"}, { SF_REINSTREQ, "reinstreq"}, { SF_HOLD, "hold"}, { SF_REPLACE, "replace"}, { SF_NOPRUNE, "noprune"}, { SF_PREFER, "prefer"}, { SF_OBSOLETE, "obsolete"}, { SF_USER, "user"},};static const enum_map_t pkg_state_status_map[] = { { SS_NOT_INSTALLED, "not-installed" }, { SS_UNPACKED, "unpacked" }, { SS_HALF_CONFIGURED, "half-configured" }, { SS_INSTALLED, "installed" }, { SS_HALF_INSTALLED, "half-installed" }, { SS_CONFIG_FILES, "config-files" }, { SS_POST_INST_FAILED, "post-inst-failed" }, { SS_REMOVAL_FAILED, "removal-failed" }};static int verrevcmp(const char *val, const char *ref);pkg_t *pkg_new(void){ pkg_t *pkg; pkg = malloc(sizeof(pkg_t)); if (pkg == NULL) { fprintf(stderr, "%s: out of memory\n", __FUNCTION__); return NULL; } pkg_init(pkg); return pkg;}int pkg_init(pkg_t *pkg){ memset(pkg, 0, sizeof(pkg_t)); pkg->name = NULL; pkg->epoch = 0; pkg->version = NULL; pkg->revision = NULL; pkg->familiar_revision = NULL; pkg->dest = NULL; pkg->src = NULL; pkg->architecture = NULL; pkg->maintainer = NULL; pkg->section = NULL; pkg->description = NULL; pkg->state_want = SW_UNKNOWN; pkg->state_flag = SF_OK; pkg->state_status = SS_NOT_INSTALLED; pkg->depends_str = NULL; pkg->provides_str = NULL; pkg->depends_count = 0; pkg->depends = NULL; pkg->suggests_str = NULL; pkg->recommends_str = NULL; pkg->suggests_count = 0; pkg->recommends_count = 0; /* Abhaya: added init for conflicts fields */ pkg->conflicts = NULL; pkg->conflicts_count = 0; /* added for replaces. Jamey 7/23/2002 */ pkg->replaces = NULL; pkg->replaces_count = 0; pkg->pre_depends_count = 0; pkg->pre_depends_str = NULL; pkg->provides_count = 0; pkg->provides = NULL; pkg->filename = NULL; pkg->local_filename = NULL; pkg->tmp_unpack_dir = NULL; pkg->md5sum = NULL; pkg->size = NULL; pkg->installed_size = NULL; pkg->priority = NULL; pkg->source = NULL; conffile_list_init(&pkg->conffiles); pkg->installed_files = NULL; pkg->installed_files_ref_cnt = 0; pkg->essential = 0; pkg->provided_by_hand = 0; return 0;}void pkg_deinit(pkg_t *pkg){ free(pkg->name); pkg->name = NULL; pkg->epoch = 0; free(pkg->version); pkg->version = NULL; /* revision and familiar_revision share storage with version, so don't free */ pkg->revision = NULL; pkg->familiar_revision = NULL; /* owned by ipkg_conf_t */ pkg->dest = NULL; /* owned by ipkg_conf_t */ pkg->src = NULL; free(pkg->architecture); pkg->architecture = NULL; free(pkg->maintainer); pkg->maintainer = NULL; free(pkg->section); pkg->section = NULL; free(pkg->description); pkg->description = NULL; pkg->state_want = SW_UNKNOWN; pkg->state_flag = SF_OK; pkg->state_status = SS_NOT_INSTALLED; free(pkg->depends_str); pkg->depends_str = NULL; free(pkg->provides_str); pkg->provides_str = NULL; pkg->depends_count = 0; /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->depends ? */ pkg->pre_depends_count = 0; free(pkg->pre_depends_str); pkg->pre_depends_str = NULL; pkg->provides_count = 0; /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->provides ? */ /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->suggests ? */ free(pkg->filename); pkg->filename = NULL; free(pkg->local_filename); pkg->local_filename = NULL; /* CLEANUP: It'd be nice to pullin the cleanup function from ipkg_install.c here. See comment in ipkg_install.c:cleanup_temporary_files */ free(pkg->tmp_unpack_dir); pkg->tmp_unpack_dir = NULL; free(pkg->md5sum); pkg->md5sum = NULL; free(pkg->size); pkg->size = NULL; free(pkg->installed_size); pkg->installed_size = NULL; free(pkg->priority); pkg->priority = NULL; free(pkg->source); pkg->source = NULL; conffile_list_deinit(&pkg->conffiles); /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so, since if they are calling deinit, they should know. Maybe do an assertion here instead? */ pkg->installed_files_ref_cnt = 1; pkg_free_installed_files(pkg); pkg->essential = 0;}int pkg_init_from_file(pkg_t *pkg, const char *filename){ int err; char **raw; FILE *control_file; err = pkg_init(pkg); if (err) { return err; } pkg->local_filename = strdup(filename); control_file = tmpfile(); err = pkg_extract_control_file_to_stream(pkg, control_file); if (err) { return err; } rewind(control_file); raw = read_raw_pkgs_from_stream(control_file); pkg_parse_raw(pkg, &raw, NULL, NULL); fclose(control_file); return 0;}/* Merge any new information in newpkg into oldpkg *//* XXX: CLEANUP: This function shouldn't actually modify anything in newpkg, but should leave it usable. This rework is so that pkg_hash_insert doesn't clobber the pkg that you pass into it. *//* * uh, i thought that i had originally written this so that it took * two pkgs and returned a new one? we can do that again... -sma */int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status){ if (oldpkg == newpkg) { return 0; } if (!oldpkg->src) oldpkg->src = newpkg->src; if (!oldpkg->dest) oldpkg->dest = newpkg->dest; if (!oldpkg->architecture) oldpkg->architecture = str_dup_safe(newpkg->architecture); if (!oldpkg->arch_priority) oldpkg->arch_priority = newpkg->arch_priority; if (!oldpkg->section) oldpkg->section = str_dup_safe(newpkg->section); if(!oldpkg->maintainer) oldpkg->maintainer = str_dup_safe(newpkg->maintainer); if(!oldpkg->description) oldpkg->description = str_dup_safe(newpkg->description); if (set_status) { /* merge the state_flags from the new package */ oldpkg->state_want = newpkg->state_want; oldpkg->state_status = newpkg->state_status; oldpkg->state_flag = newpkg->state_flag; } else { if (oldpkg->state_want == SW_UNKNOWN) oldpkg->state_want = newpkg->state_want; if (oldpkg->state_status == SS_NOT_INSTALLED) oldpkg->state_status = newpkg->state_status; oldpkg->state_flag |= newpkg->state_flag; } if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) { oldpkg->depends_str = newpkg->depends_str; newpkg->depends_str = NULL; oldpkg->depends_count = newpkg->depends_count; newpkg->depends_count = 0; oldpkg->depends = newpkg->depends; newpkg->depends = NULL; oldpkg->pre_depends_str = newpkg->pre_depends_str; newpkg->pre_depends_str = NULL; oldpkg->pre_depends_count = newpkg->pre_depends_count; newpkg->pre_depends_count = 0; oldpkg->recommends_str = newpkg->recommends_str; newpkg->recommends_str = NULL; oldpkg->recommends_count = newpkg->recommends_count; newpkg->recommends_count = 0; oldpkg->suggests_str = newpkg->suggests_str; newpkg->suggests_str = NULL; oldpkg->suggests_count = newpkg->suggests_count; newpkg->suggests_count = 0; } if (!oldpkg->provides_str) { oldpkg->provides_str = newpkg->provides_str; newpkg->provides_str = NULL; oldpkg->provides_count = newpkg->provides_count; newpkg->provides_count = 0; oldpkg->provides = newpkg->provides; newpkg->provides = NULL; } if (!oldpkg->conflicts_str) { oldpkg->conflicts_str = newpkg->conflicts_str; newpkg->conflicts_str = NULL; oldpkg->conflicts_count = newpkg->conflicts_count; newpkg->conflicts_count = 0; oldpkg->conflicts = newpkg->conflicts; newpkg->conflicts = NULL; } if (!oldpkg->replaces_str) { oldpkg->replaces_str = newpkg->replaces_str; newpkg->replaces_str = NULL; oldpkg->replaces_count = newpkg->replaces_count; newpkg->replaces_count = 0; oldpkg->replaces = newpkg->replaces; newpkg->replaces = NULL; } if (!oldpkg->filename) oldpkg->filename = str_dup_safe(newpkg->filename); if (0) fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n", oldpkg->name, oldpkg->local_filename, newpkg->local_filename); if (!oldpkg->local_filename) oldpkg->local_filename = str_dup_safe(newpkg->local_filename); if (!oldpkg->tmp_unpack_dir) oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir); if (!oldpkg->md5sum) oldpkg->md5sum = str_dup_safe(newpkg->md5sum); if (!oldpkg->size) oldpkg->size = str_dup_safe(newpkg->size); if (!oldpkg->installed_size) oldpkg->installed_size = str_dup_safe(newpkg->installed_size); if (!oldpkg->priority) oldpkg->priority = str_dup_safe(newpkg->priority); if (!oldpkg->source) oldpkg->source = str_dup_safe(newpkg->source); if (oldpkg->conffiles.head == NULL){ oldpkg->conffiles = newpkg->conffiles; conffile_list_init(&newpkg->conffiles); } if (!oldpkg->installed_files){ oldpkg->installed_files = newpkg->installed_files; oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt; newpkg->installed_files = NULL; } if (!oldpkg->essential) oldpkg->essential = newpkg->essential; return 0;}abstract_pkg_t *abstract_pkg_new(void){ abstract_pkg_t * ab_pkg; ab_pkg = malloc(sizeof(abstract_pkg_t)); if (ab_pkg == NULL) { fprintf(stderr, "%s: out of memory\n", __FUNCTION__); return NULL; } if ( abstract_pkg_init(ab_pkg) < 0 ) return NULL; return ab_pkg;}int abstract_pkg_init(abstract_pkg_t *ab_pkg){ memset(ab_pkg, 0, sizeof(abstract_pkg_t)); ab_pkg->provided_by = abstract_pkg_vec_alloc(); if (ab_pkg->provided_by==NULL){ return -1; } ab_pkg->dependencies_checked = 0; ab_pkg->state_status = SS_NOT_INSTALLED; return 0;}void set_flags_from_control(ipkg_conf_t *conf, pkg_t *pkg){ char * temp_str; char **raw =NULL; char **raw_start=NULL; temp_str = (char *) malloc (strlen(pkg->dest->info_dir)+strlen(pkg->name)+12); if (temp_str == NULL ){ ipkg_message(conf, IPKG_INFO, "Out of memory in %s\n", __FUNCTION__); return; } sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name); raw = raw_start = read_raw_pkgs_from_file(temp_str); if (raw == NULL ){ ipkg_message(conf, IPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__); return; } while(*raw){ if (!pkg_valorize_other_field(pkg, &raw ) == 0) { ipkg_message(conf, IPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name); } } raw = raw_start; while (*raw) { if (raw!=NULL) free(*raw++); } free(raw_start); free(temp_str); return ;}char * pkg_formatted_info(pkg_t *pkg ){ char *line; char * buff; buff = malloc(8192); if (buff == NULL) { fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -