/* search the local database for a matching package */ static int query_search(alpm_list_t *targets) { alpm_list_t *i, *searchlist; int freelist; alpm_db_t *db_local = alpm_option_get_localdb(config->handle); /* if we have a targets list, search for packages matching it */ if(targets) { searchlist = alpm_db_search(db_local, targets); freelist = 1; } else { searchlist = alpm_db_get_pkgcache(db_local); freelist = 0; } if(searchlist == NULL) { return 1; } for(i = searchlist; i; i = alpm_list_next(i)) { alpm_list_t *grp; alpm_pkg_t *pkg = alpm_list_getdata(i); if(!config->quiet) { printf("local/%s %s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg)); } else { printf("%s", alpm_pkg_get_name(pkg)); } if(!config->quiet) { if((grp = alpm_pkg_get_groups(pkg)) != NULL) { alpm_list_t *k; printf(" ("); for(k = grp; k; k = alpm_list_next(k)) { const char *group = alpm_list_getdata(k); printf("%s", group); if(alpm_list_next(k)) { /* only print a spacer if there are more groups */ printf(" "); } } printf(")"); } /* we need a newline and initial indent first */ printf("\n "); indentprint(alpm_pkg_get_desc(pkg), 4); } printf("\n"); } /* we only want to free if the list was a search list */ if(freelist) { alpm_list_free(searchlist); } return 0; }
/** * @brief Upgrade a specified list of packages. * * @param targets a list of packages (as strings) to upgrade * * @return 0 on success, 1 on failure */ int pacman_upgrade(alpm_list_t *targets) { alpm_list_t *i; alpm_siglevel_t level = alpm_option_get_default_siglevel(config->handle); if(targets == NULL) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } /* Check for URL targets and process them */ for(i = targets; i; i = alpm_list_next(i)) { if(strstr(i->data, "://")) { char *str = alpm_fetch_pkgurl(config->handle, i->data); if(str == NULL) { pm_fprintf(stderr, ALPM_LOG_ERROR, "'%s': %s\n", (char *)i->data, alpm_strerror(alpm_errno(config->handle))); return 1; } else { free(i->data); i->data = str; } } } /* Step 1: create a new transaction */ if(trans_init(config->flags, 1) == -1) { return 1; } printf(_("loading packages...\n")); /* add targets to the created transaction */ for(i = targets; i; i = alpm_list_next(i)) { char *targ = alpm_list_getdata(i); alpm_pkg_t *pkg; if(alpm_pkg_load(config->handle, targ, 1, level, &pkg) != 0) { pm_fprintf(stderr, ALPM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerror(alpm_errno(config->handle))); trans_release(); return 1; } if(alpm_add_pkg(config->handle, pkg) == -1) { pm_fprintf(stderr, ALPM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerror(alpm_errno(config->handle))); alpm_pkg_free(pkg); trans_release(); return 1; } config->explicit_adds = alpm_list_add(config->explicit_adds, pkg); } /* now that targets are resolved, we can hand it all off to the sync code */ return sync_prepare_execute(); }
static int query_group(alpm_list_t *targets) { alpm_list_t *i, *j; char *grpname = NULL; int ret = 0; alpm_db_t *db_local = alpm_option_get_localdb(config->handle); if(targets == NULL) { for(j = alpm_db_get_groupcache(db_local); j; j = alpm_list_next(j)) { alpm_group_t *grp = alpm_list_getdata(j); const alpm_list_t *p; for(p = grp->packages; p; p = alpm_list_next(p)) { alpm_pkg_t *pkg = alpm_list_getdata(p); printf("%s %s\n", grp->name, alpm_pkg_get_name(pkg)); } } } else { for(i = targets; i; i = alpm_list_next(i)) { alpm_group_t *grp; grpname = alpm_list_getdata(i); grp = alpm_db_readgroup(db_local, grpname); if(grp) { const alpm_list_t *p; for(p = grp->packages; p; p = alpm_list_next(p)) { if(!config->quiet) { printf("%s %s\n", grpname, alpm_pkg_get_name(alpm_list_getdata(p))); } else { printf("%s\n", alpm_pkg_get_name(alpm_list_getdata(p))); } } } else { pm_fprintf(stderr, ALPM_LOG_ERROR, _("group '%s' was not found\n"), grpname); ret++; } } } return ret; }
int alpm_list_to_any_table(lua_State *L, alpm_list_t *list, enum types value_type) { size_t j = 1; lua_newtable(L); while (list) { void *value = alpm_list_getdata(list); if (push_typed_object(L, value_type, value)) lua_rawseti(L, -2, j++); list = alpm_list_next(list); } return 1; }
/* Loop through the packages. For each package, * loop through files to check if they exist. */ static int check(alpm_pkg_t *pkg) { alpm_list_t *i; const char *root; int allfiles = 0, errors = 0; size_t rootlen; char f[PATH_MAX]; root = alpm_option_get_root(config->handle); rootlen = strlen(root); if(rootlen + 1 > PATH_MAX) { /* we are in trouble here */ pm_fprintf(stderr, ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); return 1; } strcpy(f, root); const char *pkgname = alpm_pkg_get_name(pkg); for(i = alpm_pkg_get_files(pkg); i; i = alpm_list_next(i)) { struct stat st; const alpm_file_t *file = alpm_list_getdata(i); const char *path = file->name; if(rootlen + 1 + strlen(path) > PATH_MAX) { pm_fprintf(stderr, ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path); continue; } strcpy(f + rootlen, path); allfiles++; /* use lstat to prevent errors from symlinks */ if(lstat(f, &st) != 0) { if(config->quiet) { printf("%s %s\n", pkgname, f); } else { pm_printf(ALPM_LOG_WARNING, "%s: %s (%s)\n", pkgname, f, strerror(errno)); } errors++; } } if(!config->quiet) { printf(_n("%s: %d total file, ", "%s: %d total files, ", (unsigned long)allfiles), pkgname, allfiles); printf(_n("%d missing file\n", "%d missing files\n", (unsigned long)errors), errors); } return (errors != 0 ? 1 : 0); }
int pacman_deptest(alpm_list_t *targets) { alpm_list_t *i; alpm_list_t *deps = alpm_deptest(alpm_option_get_localdb(), targets); if(deps == NULL) { return(0); } for(i = deps; i; i = alpm_list_next(i)) { const char *dep; dep = alpm_list_getdata(i); printf("%s\n", dep); } alpm_list_free(deps); return(127); }
VALUE db_groups ( VALUE self ) { alpm_list_t * iter; INITDBPTR; VALUE grphash = rb_hash_new(); iter = alpm_db_get_grpcache( db ); while ( iter != NULL ) { pmgrp_t * grp = alpm_list_getdata( iter ); VALUE grpname = rb_str_new2( alpm_grp_get_name( grp )); VALUE pkgs = alpmpkglist_to_ary( alpm_grp_get_pkgs( grp )); rb_hash_aset( grphash, grpname, pkgs ); iter = alpm_list_next( iter ); } return grphash; }
static int is_foreign(alpm_pkg_t *pkg) { const char *pkgname = alpm_pkg_get_name(pkg); alpm_list_t *j; alpm_list_t *sync_dbs = alpm_option_get_syncdbs(config->handle); int match = 0; for(j = sync_dbs; j; j = alpm_list_next(j)) { alpm_db_t *db = alpm_list_getdata(j); alpm_pkg_t *findpkg = alpm_db_get_pkg(db, pkgname); if(findpkg) { match = 1; break; } } if(match == 0) { return 1; } return 0; }
static int validate_deltas(alpm_handle_t *handle, alpm_list_t *deltas, alpm_list_t **data) { int errors = 0, ret = 0; alpm_list_t *i; alpm_trans_t *trans = handle->trans; if(!deltas) { return 0; } /* Check integrity of deltas */ EVENT(trans, ALPM_TRANS_EVT_DELTA_INTEGRITY_START, NULL, NULL); for(i = deltas; i; i = i->next) { alpm_delta_t *d = alpm_list_getdata(i); char *filepath = _alpm_filecache_find(handle, d->delta); if(test_md5sum(trans, filepath, d->delta_md5) != 0) { errors++; *data = alpm_list_add(*data, strdup(d->delta)); } FREE(filepath); } if(errors) { handle->pm_errno = ALPM_ERR_DLT_INVALID; return -1; } EVENT(trans, ALPM_TRANS_EVT_DELTA_INTEGRITY_DONE, NULL, NULL); /* Use the deltas to generate the packages */ EVENT(trans, ALPM_TRANS_EVT_DELTA_PATCHES_START, NULL, NULL); ret = apply_deltas(handle); EVENT(trans, ALPM_TRANS_EVT_DELTA_PATCHES_DONE, NULL, NULL); return ret; }
/** * helper function for resolvedeps: search for dep satisfier in dbs * * @param handle the context handle * @param dep is the dependency to search for * @param dbs are the databases to search * @param excluding are the packages to exclude from the search * @param prompt if true, will cause an unresolvable dependency to issue an * interactive prompt asking whether the package should be removed from * the transaction or the transaction aborted; if false, simply returns * an error code without prompting * @return the resolved package **/ static pmpkg_t *resolvedep(pmhandle_t *handle, pmdepend_t *dep, alpm_list_t *dbs, alpm_list_t *excluding, int prompt) { alpm_list_t *i, *j; int ignored = 0; alpm_list_t *providers = NULL; int count; /* 1. literals */ for(i = dbs; i; i = i->next) { pmpkg_t *pkg = _alpm_db_get_pkgfromcache(i->data, dep->name); if(pkg && _alpm_depcmp(pkg, dep) && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(handle, pkg)) { int install = 0; if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { _alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version); } if(!install) { ignored = 1; continue; } } return pkg; } } /* 2. satisfiers (skip literals here) */ for(i = dbs; i; i = i->next) { for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) { pmpkg_t *pkg = j->data; if(_alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(handle, pkg)) { int install = 0; if(prompt) { QUESTION(handle->trans, PM_TRANS_CONV_INSTALL_IGNOREPKG, pkg, NULL, NULL, &install); } else { _alpm_log(handle, PM_LOG_WARNING, _("ignoring package %s-%s\n"), pkg->name, pkg->version); } if(!install) { ignored = 1; continue; } } _alpm_log(handle, PM_LOG_DEBUG, "provider found (%s provides %s)\n", pkg->name, dep->name); providers = alpm_list_add(providers, pkg); /* keep looking for other providers in the all dbs */ } } } /* first check if one provider is already installed locally */ for(i = providers; i; i = i->next) { pmpkg_t *pkg = i->data; if(_alpm_pkghash_find(_alpm_db_get_pkgcache_hash(handle->db_local), pkg->name)) { alpm_list_free(providers); return pkg; } } count = alpm_list_count(providers); if(count >= 1) { /* default to first provider if there is no QUESTION callback */ int index = 0; if(count > 1) { /* if there is more than one provider, we ask the user */ QUESTION(handle->trans, PM_TRANS_CONV_SELECT_PROVIDER, providers, dep, NULL, &index); } if(index >= 0 && index < count) { pmpkg_t *pkg = alpm_list_getdata(alpm_list_nth(providers, index)); alpm_list_free(providers); return pkg; } alpm_list_free(providers); providers = NULL; } if(ignored) { /* resolvedeps will override these */ handle->pm_errno = PM_ERR_PKG_IGNORED; } else { handle->pm_errno = PM_ERR_PKG_NOT_FOUND; } return NULL; }
/** * @brief Upgrade a specified list of packages. * * @param targets a list of packages (as strings) to upgrade * * @return 0 on success, 1 on failure */ int pacman_upgrade(alpm_list_t *targets) { alpm_list_t *i, *data = NULL; pgp_verify_t check_sig = alpm_option_get_default_sigverify(config->handle); int retval = 0; if(targets == NULL) { pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } /* Check for URL targets and process them */ for(i = targets; i; i = alpm_list_next(i)) { if(strstr(i->data, "://")) { char *str = alpm_fetch_pkgurl(config->handle, i->data); if(str == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", (char *)i->data, alpm_strerror(alpm_errno(config->handle))); return 1; } else { free(i->data); i->data = str; } } } /* Step 1: create a new transaction */ if(trans_init(config->flags) == -1) { return 1; } /* add targets to the created transaction */ for(i = targets; i; i = alpm_list_next(i)) { char *targ = alpm_list_getdata(i); pmpkg_t *pkg; if(alpm_pkg_load(config->handle, targ, 1, check_sig, &pkg) != 0) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerror(alpm_errno(config->handle))); trans_release(); return 1; } if(alpm_add_pkg(config->handle, pkg) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerror(alpm_errno(config->handle))); alpm_pkg_free(pkg); trans_release(); return 1; } } /* Step 2: "compute" the transaction based on targets and flags */ /* TODO: No, compute nothing. This is stupid. */ if(alpm_trans_prepare(config->handle, &data) == -1) { enum _pmerrno_t err = alpm_errno(config->handle); pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"), alpm_strerror(err)); switch(err) { case PM_ERR_PKG_INVALID_ARCH: for(i = data; i; i = alpm_list_next(i)) { char *pkg = alpm_list_getdata(i); printf(_(":: package %s does not have a valid architecture\n"), pkg); } break; case PM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); char *depstring = alpm_dep_compute_string(miss->depend); /* TODO indicate if the error was a virtual package or not: * :: %s: requires %s, provided by %s */ printf(_(":: %s: requires %s\n"), miss->target, depstring); free(depstring); } break; case PM_ERR_CONFLICTING_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmconflict_t *conflict = alpm_list_getdata(i); if(strcmp(conflict->package1, conflict->reason) == 0 || strcmp(conflict->package2, conflict->reason) == 0) { printf(_(":: %s and %s are in conflict\n"), conflict->package1, conflict->package2); } else { printf(_(":: %s and %s are in conflict (%s)\n"), conflict->package1, conflict->package2, conflict->reason); } } break; default: break; } trans_release(); FREELIST(data); return 1; } /* Step 3: perform the installation */ alpm_list_t *packages = alpm_trans_get_add(config->handle); if(config->print) { print_packages(packages); trans_release(); return 0; } /* print targets and ask user confirmation */ if(packages == NULL) { /* we are done */ printf(_(" there is nothing to do\n")); trans_release(); return retval; } display_targets(alpm_trans_get_remove(config->handle), 0); display_targets(alpm_trans_get_add(config->handle), 1); printf("\n"); int confirm = yesno(_("Proceed with installation?")); if(!confirm) { trans_release(); return retval; } if(alpm_trans_commit(config->handle, &data) == -1) { enum _pmerrno_t err = alpm_errno(config->handle); pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"), alpm_strerror(err)); switch(err) { case PM_ERR_FILE_CONFLICTS: for(i = data; i; i = alpm_list_next(i)) { pmfileconflict_t *conflict = alpm_list_getdata(i); switch(conflict->type) { case PM_FILECONFLICT_TARGET: printf(_("%s exists in both '%s' and '%s'\n"), conflict->file, conflict->target, conflict->ctarget); break; case PM_FILECONFLICT_FILESYSTEM: printf(_("%s: %s exists in filesystem\n"), conflict->target, conflict->file); break; } } break; case PM_ERR_PKG_INVALID: case PM_ERR_DLT_INVALID: for(i = data; i; i = alpm_list_next(i)) { char *filename = alpm_list_getdata(i); printf(_("%s is invalid or corrupted\n"), filename); } break; default: break; } FREELIST(data); trans_release(); return 1; } if(trans_release() == -1) { retval = 1; } return retval; }
/** * @brief Remove a specified list of packages. * * @param targets a list of packages (as strings) to remove from the system * * @return 0 on success, 1 on failure */ int pacman_remove(alpm_list_t *targets) { int retval = 0; alpm_list_t *i, *data = NULL; if(targets == NULL) { pm_printf(PM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return(1); } /* Step 0: create a new transaction */ if(trans_init(PM_TRANS_TYPE_REMOVE, config->flags) == -1) { return(1); } /* Step 1: add targets to the created transaction */ for(i = targets; i; i = alpm_list_next(i)) { char *targ = alpm_list_getdata(i); if(alpm_trans_addtarget(targ) == -1) { if(pm_errno == PM_ERR_PKG_NOT_FOUND) { printf(_("%s not found, searching for group...\n"), targ); pmgrp_t *grp = alpm_db_readgrp(db_local, targ); if(grp == NULL) { pm_fprintf(stderr, PM_LOG_ERROR, _("'%s': not found in local db\n"), targ); retval = 1; goto cleanup; } else { alpm_list_t *p, *pkgnames = NULL; /* convert packages to package names */ for(p = alpm_grp_get_pkgs(grp); p; p = alpm_list_next(p)) { pmpkg_t *pkg = alpm_list_getdata(p); pkgnames = alpm_list_add(pkgnames, (void *)alpm_pkg_get_name(pkg)); } printf(_(":: group %s:\n"), targ); list_display(" ", pkgnames); int all = yesno(1, _(" Remove whole content?")); for(p = pkgnames; p; p = alpm_list_next(p)) { char *pkgn = alpm_list_getdata(p); if(all || yesno(1, _(":: Remove %s from group %s?"), pkgn, targ)) { if(alpm_trans_addtarget(pkgn) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerrorlast()); retval = 1; alpm_list_free(pkgnames); goto cleanup; } } } alpm_list_free(pkgnames); } } else { pm_fprintf(stderr, PM_LOG_ERROR, "'%s': %s\n", targ, alpm_strerrorlast()); retval = 1; goto cleanup; } } } /* Step 2: prepare the transaction based on its type, targets and flags */ if(alpm_trans_prepare(&data) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, _("failed to prepare transaction (%s)\n"), alpm_strerrorlast()); switch(pm_errno) { case PM_ERR_UNSATISFIED_DEPS: for(i = data; i; i = alpm_list_next(i)) { pmdepmissing_t *miss = alpm_list_getdata(i); pmdepend_t *dep = alpm_miss_get_dep(miss); char *depstring = alpm_dep_get_string(dep); printf(_(":: %s: requires %s\n"), alpm_miss_get_target(miss), depstring); free(depstring); } FREELIST(data); break; default: break; } retval = 1; goto cleanup; } /* Warn user in case of dangerous operation */ if(config->flags & PM_TRANS_FLAG_RECURSE || config->flags & PM_TRANS_FLAG_CASCADE) { /* list transaction targets */ alpm_list_t *pkglist = alpm_trans_get_pkgs(); display_targets(pkglist, 0); printf("\n"); /* get confirmation */ if(yesno(1, _("Do you want to remove these packages?")) == 0) { retval = 1; goto cleanup; } } /* Step 3: actually perform the removal */ if(alpm_trans_commit(NULL) == -1) { pm_fprintf(stderr, PM_LOG_ERROR, _("failed to commit transaction (%s)\n"), alpm_strerrorlast()); retval = 1; } /* Step 4: release transaction resources */ cleanup: if(trans_release() == -1) { retval = 1; } return(retval); }
int pacman_query(alpm_list_t *targets) { int ret = 0; int match = 0; alpm_list_t *i; alpm_pkg_t *pkg = NULL; alpm_db_t *db_local; /* First: operations that do not require targets */ /* search for a package */ if(config->op_q_search) { ret = query_search(targets); return ret; } /* looking for groups */ if(config->group) { ret = query_group(targets); return ret; } if(config->op_q_foreign || config->op_q_upgrade) { if(check_syncdbs(1, 1)) { return 1; } } db_local = alpm_option_get_localdb(config->handle); /* operations on all packages in the local DB * valid: no-op (plain -Q), list, info, check * invalid: isfile, owns */ if(targets == NULL) { if(config->op_q_isfile || config->op_q_owns) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) { pkg = alpm_list_getdata(i); if(filter(pkg)) { int value = display(pkg); if(value != 0) { ret = 1; } match = 1; } } if(!match) { ret = 1; } return ret; } /* Second: operations that require target(s) */ /* determine the owner of a file */ if(config->op_q_owns) { ret = query_fileowner(targets); return ret; } /* operations on named packages in the local DB * valid: no-op (plain -Q), list, info, check */ for(i = targets; i; i = alpm_list_next(i)) { char *strname = alpm_list_getdata(i); if(config->op_q_isfile) { alpm_pkg_load(config->handle, strname, 1, 0, &pkg); } else { pkg = alpm_db_get_pkg(db_local, strname); } if(pkg == NULL) { switch(alpm_errno(config->handle)) { case ALPM_ERR_PKG_NOT_FOUND: pm_fprintf(stderr, ALPM_LOG_ERROR, _("package '%s' was not found\n"), strname); if(!config->op_q_isfile && access(strname, R_OK) == 0) { pm_fprintf(stderr, ALPM_LOG_WARNING, _("'%s' is a file, you might want to use %s.\n"), strname, "-p/--file"); } break; default: pm_fprintf(stderr, ALPM_LOG_ERROR, _("could not load package '%s': %s\n"), strname, alpm_strerror(alpm_errno(config->handle))); break; } ret = 1; continue; } if(filter(pkg)) { int value = display(pkg); if(value != 0) { ret = 1; } match = 1; } if(config->op_q_isfile) { alpm_pkg_free(pkg); pkg = NULL; } } if(!match) { ret = 1; } return ret; }
static int query_fileowner(alpm_list_t *targets) { int ret = 0; char path[PATH_MAX]; const char *root; size_t rootlen; alpm_list_t *t; alpm_db_t *db_local; /* This code is here for safety only */ if(targets == NULL) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("no file was specified for --owns\n")); return 1; } /* Set up our root path buffer. We only need to copy the location of root in * once, then we can just overwrite whatever file was there on the previous * iteration. */ root = alpm_option_get_root(config->handle); rootlen = strlen(root); if(rootlen + 1 > PATH_MAX) { /* we are in trouble here */ pm_fprintf(stderr, ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); return 1; } strcpy(path, root); db_local = alpm_option_get_localdb(config->handle); for(t = targets; t; t = alpm_list_next(t)) { char *filename, *dname, *rpath; const char *bname; struct stat buf; alpm_list_t *i; int found = 0; filename = strdup(alpm_list_getdata(t)); if(lstat(filename, &buf) == -1) { /* if it is not a path but a program name, then check in PATH */ if(strchr(filename, '/') == NULL) { if(search_path(&filename, &buf) == -1) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("failed to find '%s' in PATH: %s\n"), filename, strerror(errno)); ret++; free(filename); continue; } } else { pm_fprintf(stderr, ALPM_LOG_ERROR, _("failed to read file '%s': %s\n"), filename, strerror(errno)); ret++; free(filename); continue; } } if(S_ISDIR(buf.st_mode)) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("cannot determine ownership of directory '%s'\n"), filename); ret++; free(filename); continue; } bname = mbasename(filename); dname = mdirname(filename); /* for files in '/', there is no directory name to match */ if(strcmp(dname, "") == 0) { rpath = NULL; } else { rpath = resolve_path(dname); if(!rpath) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("cannot determine real path for '%s': %s\n"), filename, strerror(errno)); free(filename); free(dname); free(rpath); ret++; continue; } } free(dname); for(i = alpm_db_get_pkgcache(db_local); i && !found; i = alpm_list_next(i)) { alpm_pkg_t *info = alpm_list_getdata(i); alpm_filelist_t *filelist = alpm_pkg_get_files(info); size_t j; for(j = 0; j < filelist->count; j++) { const alpm_file_t *file = filelist->files + j; char *ppath, *pdname; const char *pkgfile = file->name; /* avoid the costly resolve_path usage if the basenames don't match */ if(strcmp(mbasename(pkgfile), bname) != 0) { continue; } /* for files in '/', there is no directory name to match */ if(!rpath) { print_query_fileowner(filename, info); found = 1; continue; } if(rootlen + 1 + strlen(pkgfile) > PATH_MAX) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, pkgfile); } /* concatenate our file and the root path */ strcpy(path + rootlen, pkgfile); pdname = mdirname(path); ppath = resolve_path(pdname); free(pdname); if(ppath && strcmp(ppath, rpath) == 0) { print_query_fileowner(filename, info); found = 1; } free(ppath); } } if(!found) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("No package owns %s\n"), filename); ret++; } free(filename); free(rpath); } return ret; }
int pacman_query(alpm_list_t *targets) { int ret = 0; int match = 0; alpm_list_t *i; alpm_pkg_t *pkg = NULL; alpm_db_t *db_local; /* First: operations that do not require targets */ /* search for a package */ if(config->op_q_search) { ret = query_search(targets); return ret; } /* looking for groups */ if(config->group) { ret = query_group(targets); return ret; } if(config->op_q_foreign || config->op_q_upgrade) { if(check_syncdbs(1, 1)) { return 1; } } db_local = alpm_option_get_localdb(config->handle); /* operations on all packages in the local DB * valid: no-op (plain -Q), list, info, check * invalid: isfile, owns */ if(targets == NULL) { if(config->op_q_isfile || config->op_q_owns) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } for(i = alpm_db_get_pkgcache(db_local); i; i = alpm_list_next(i)) { pkg = alpm_list_getdata(i); if(filter(pkg)) { int value = display(pkg); if(value != 0) { ret = 1; } match = 1; } } if(!match) { ret = 1; } return ret; } /* Second: operations that require target(s) */ /* determine the owner of a file */ if(config->op_q_owns) { ret = query_fileowner(targets); return ret; } /* operations on named packages in the local DB * valid: no-op (plain -Q), list, info, check */ for(i = targets; i; i = alpm_list_next(i)) { char *strname = alpm_list_getdata(i); if(config->op_q_isfile) { alpm_pkg_load(config->handle, strname, 1, 0, &pkg); } else { pkg = alpm_db_get_pkg(db_local, strname); } if(pkg == NULL) { pm_fprintf(stderr, ALPM_LOG_ERROR, _("package \"%s\" not found\n"), strname); ret = 1; continue; } if(filter(pkg)) { int value = display(pkg); if(value != 0) { ret = 1; } match = 1; } if(config->op_q_isfile) { alpm_pkg_free(pkg); pkg = NULL; } } if(!match) { ret = 1; } return ret; }