📄 pkg.c
字号:
} str_list_append(pkg->installed_files, installed_file_name); free(line); } fclose(list_file); return pkg->installed_files;}/* XXX: CLEANUP: This function and it's counterpart, (pkg_get_installed_files), do not match our init/deinit naming convention. Nor the alloc/free convention. But, then again, neither of these conventions currrently fit the way these two functions work. */int pkg_free_installed_files(pkg_t *pkg){ str_list_elt_t *iter; pkg->installed_files_ref_cnt--; if (pkg->installed_files_ref_cnt > 0) { return 0; } if (pkg->installed_files) { for (iter = pkg->installed_files->head; iter; iter = iter->next) { /* malloced in pkg_get_installed_files */ free (iter->data); iter->data = NULL; } str_list_deinit(pkg->installed_files); } pkg->installed_files = NULL; return 0;}int pkg_remove_installed_files_list(ipkg_conf_t *conf, pkg_t *pkg){ int err; char *list_file_name; //I don't think pkg_free_installed_files should be called here. Jamey //pkg_free_installed_files(pkg); sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name); if (!conf->noaction) { err = unlink(list_file_name); free(list_file_name); if (err) { return errno; } } return 0;}conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name){ conffile_list_elt_t *iter; conffile_t *conffile; if (pkg == NULL) { return NULL; } for (iter = pkg->conffiles.head; iter; iter = iter->next) { conffile = iter->data; if (strcmp(conffile->name, file_name) == 0) { return conffile; } } return NULL;}int pkg_run_script(ipkg_conf_t *conf, pkg_t *pkg, const char *script, const char *args){ int err; char *path; char *cmd; /* XXX: FEATURE: When conf->offline_root is set, we should run the maintainer script within a chroot environment. */ /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages have scripts in pkg->tmp_unpack_dir. */ if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) { if (pkg->dest == NULL) { fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n", __FUNCTION__, pkg->name); return EINVAL; } sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script); } else { if (pkg->tmp_unpack_dir == NULL) { fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n", __FUNCTION__, pkg->name); return EINVAL; } sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script); } ipkg_message(conf, IPKG_INFO, "Running script %s\n", path); if (conf->noaction) return 0; /* XXX: CLEANUP: There must be a better way to handle maintainer scripts when running with offline_root mode and/or a dest other than '/'. I've been playing around with some clever chroot tricks and I might come up with something workable. */ if (conf->offline_root) { setenv("IPKG_OFFLINE_ROOT", conf->offline_root, 1); } setenv("PKG_ROOT", pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1); if (! file_exists(path)) { free(path); return 0; } if (conf->offline_root) { fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script); free(path); return 0; } sprintf_alloc(&cmd, "%s %s", path, args); free(path); err = xsystem(cmd); free(cmd); if (err) { fprintf(stderr, "%s script returned status %d\n", script, err); return err; } return 0;}char *pkg_state_want_to_str(pkg_state_want_t sw){ int i; for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) { if (pkg_state_want_map[i].value == sw) { return strdup(pkg_state_want_map[i].str); } } fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n", __FUNCTION__, sw); return strdup("<STATE_WANT_UNKNOWN>");}pkg_state_want_t pkg_state_want_from_str(char *str){ int i; for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) { if (strcmp(str, pkg_state_want_map[i].str) == 0) { return pkg_state_want_map[i].value; } } fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n", __FUNCTION__, str); return SW_UNKNOWN;}char *pkg_state_flag_to_str(pkg_state_flag_t sf){ int i; int len = 3; /* ok\000 is minimum */ char *str = NULL; /* clear the temporary flags before converting to string */ sf &= SF_NONVOLATILE_FLAGS; if (sf == 0) { return strdup("ok"); } else { for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) { if (sf & pkg_state_flag_map[i].value) { len += strlen(pkg_state_flag_map[i].str) + 1; } } str = malloc(len); if ( str == NULL ) { fprintf(stderr, "%s: out of memory\n", __FUNCTION__); return NULL; } str[0] = 0; for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) { if (sf & pkg_state_flag_map[i].value) { strcat(str, pkg_state_flag_map[i].str); strcat(str, ","); } } len = strlen(str); str[len-1] = 0; /* squash last comma */ return str; }}pkg_state_flag_t pkg_state_flag_from_str(char *str){ int i; int sf = SF_OK; if (strcmp(str, "ok") == 0) { return SF_OK; } for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) { const char *sfname = pkg_state_flag_map[i].str; int sfname_len = strlen(sfname); if (strncmp(str, sfname, sfname_len) == 0) { sf |= pkg_state_flag_map[i].value; str += sfname_len; if (str[0] == ',') { str++; } else { break; } } } return sf;}char *pkg_state_status_to_str(pkg_state_status_t ss){ int i; for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) { if (pkg_state_status_map[i].value == ss) { return strdup(pkg_state_status_map[i].str); } } fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n", __FUNCTION__, ss); return strdup("<STATE_STATUS_UNKNOWN>");}pkg_state_status_t pkg_state_status_from_str(char *str){ int i; for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) { if (strcmp(str, pkg_state_status_map[i].str) == 0) { return pkg_state_status_map[i].value; } } fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n", __FUNCTION__, str); return SS_NOT_INSTALLED;}int pkg_arch_supported(ipkg_conf_t *conf, pkg_t *pkg){ nv_pair_list_elt_t *l; if (!pkg->architecture) return 1; l = conf->arch_list.head; while (l) { nv_pair_t *nv = l->data; if (strcmp(nv->name, pkg->architecture) == 0) { ipkg_message(conf, IPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name); return 1; } l = l->next; } ipkg_message(conf, IPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name); return 0;}int pkg_get_arch_priority(ipkg_conf_t *conf, const char *archname){ nv_pair_list_elt_t *l; l = conf->arch_list.head; while (l) { nv_pair_t *nv = l->data; if (strcmp(nv->name, archname) == 0) { int priority = strtol(nv->value, NULL, 0); return priority; } l = l->next; } return 0;}int pkg_info_preinstall_check(ipkg_conf_t *conf){ int i; hash_table_t *pkg_hash = &conf->pkg_hash; pkg_vec_t *available_pkgs = pkg_vec_alloc(); pkg_vec_t *installed_pkgs = pkg_vec_alloc(); ipkg_message(conf, IPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n"); pkg_hash_fetch_available(pkg_hash, available_pkgs); /* update arch_priority for each package */ for (i = 0; i < available_pkgs->len; i++) { pkg_t *pkg = available_pkgs->pkgs[i]; int arch_priority = 1; if (!pkg) continue; // ipkg_message(conf, IPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture); if (pkg->architecture) arch_priority = pkg_get_arch_priority(conf, pkg->architecture); else ipkg_message(conf, IPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name); // ipkg_message(conf, IPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority); pkg->arch_priority = arch_priority; } for (i = 0; i < available_pkgs->len; i++) { pkg_t *pkg = available_pkgs->pkgs[i]; if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) { /* clear flags and want for any uninstallable package */ ipkg_message(conf, IPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n", pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want); pkg->state_want = SW_UNKNOWN; pkg->state_flag = 0; } } pkg_vec_free(available_pkgs); /* update the file owner data structure */ ipkg_message(conf, IPKG_INFO, "pkg_info_preinstall_check: update file owner list\n"); pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs); for (i = 0; i < installed_pkgs->len; i++) { pkg_t *pkg = installed_pkgs->pkgs[i]; str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */ str_list_elt_t *iter; if (installed_files == NULL) { ipkg_message(conf, IPKG_ERROR, "No installed files for pkg %s\n", pkg->name); break; } for (iter = installed_files->head; iter; iter = iter->next) { char *installed_file = iter->data; // ipkg_message(conf, IPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file); file_hash_set_file_owner(conf, installed_file, pkg); } } pkg_vec_free(installed_pkgs); return 0;}struct pkg_write_filelist_data { ipkg_conf_t *conf; pkg_t *pkg; FILE *stream;};void pkg_write_filelist_helper(const char *key, void *entry_, void *data_){ struct pkg_write_filelist_data *data = data_; pkg_t *entry = entry_; if (entry == data->pkg) { fprintf(data->stream, "%s\n", key); }}int pkg_write_filelist(ipkg_conf_t *conf, pkg_t *pkg){ struct pkg_write_filelist_data data; char *list_file_name = NULL; int err = 0; if (!pkg) { ipkg_message(conf, IPKG_ERROR, "Null pkg\n"); return -EINVAL; } ipkg_message(conf, IPKG_INFO, " creating %s.list file\n", pkg->name); sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name); if (!list_file_name) { ipkg_message(conf, IPKG_ERROR, "Failed to alloc list_file_name\n"); return -ENOMEM; } ipkg_message(conf, IPKG_INFO, " creating %s file for pkg %s\n", list_file_name, pkg->name); data.stream = fopen(list_file_name, "w"); if (!data.stream) { ipkg_message(conf, IPKG_ERROR, "Could not open %s for writing: %s\n", list_file_name, strerror(errno)); return errno; } data.pkg = pkg; data.conf = conf; hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data); fclose(data.stream); free(list_file_name); return err;}int pkg_write_changed_filelists(ipkg_conf_t *conf){ pkg_vec_t *installed_pkgs = pkg_vec_alloc(); hash_table_t *pkg_hash = &conf->pkg_hash; int i; int err; if (conf->noaction) return 0; ipkg_message(conf, IPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__); pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs); for (i = 0; i < installed_pkgs->len; i++) { pkg_t *pkg = installed_pkgs->pkgs[i]; if (pkg->state_flag & SF_FILELIST_CHANGED) { ipkg_message(conf, IPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__); err = pkg_write_filelist(conf, pkg); if (err) ipkg_message(conf, IPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -