static int register_repo(config_repo_t *repo) { alpm_list_t *i; alpm_db_t *db; repo->siglevel = merge_siglevel(config->siglevel, repo->siglevel, repo->siglevel_mask); db = alpm_register_syncdb(config->handle, repo->name, repo->siglevel); if(db == NULL) { pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"), repo->name, alpm_strerror(alpm_errno(config->handle))); return 1; } pm_printf(ALPM_LOG_DEBUG, "setting usage of %d for %s repository\n", repo->usage == 0 ? ALPM_DB_USAGE_ALL : repo->usage, repo->name); alpm_db_set_usage(db, repo->usage == 0 ? ALPM_DB_USAGE_ALL : repo->usage); for(i = repo->servers; i; i = alpm_list_next(i)) { char *value = i->data; if(_add_mirror(db, value) != 0) { pm_printf(ALPM_LOG_ERROR, _("could not add mirror '%s' to database '%s' (%s)\n"), value, repo->name, alpm_strerror(alpm_errno(config->handle))); return 1; } } return 0; }
static int remove_target(const char *target) { alpm_pkg_t *pkg; alpm_db_t *db_local = alpm_get_localdb(config->handle); alpm_list_t *p; if((pkg = alpm_db_get_pkg(db_local, target)) != NULL) { if(alpm_remove_pkg(config->handle, pkg) == -1) { pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", target, alpm_strerror(alpm_errno(config->handle))); return -1; } config->explicit_removes = alpm_list_add(config->explicit_removes, pkg); return 0; } /* fallback to group */ alpm_group_t *grp = alpm_db_get_group(db_local, target); if(grp == NULL) { pm_printf(ALPM_LOG_ERROR, _("target not found: %s\n"), target); return -1; } for(p = grp->packages; p; p = alpm_list_next(p)) { pkg = p->data; if(alpm_remove_pkg(config->handle, pkg) == -1) { pm_printf(ALPM_LOG_ERROR, "'%s': %s\n", target, alpm_strerror(alpm_errno(config->handle))); return -1; } config->explicit_removes = alpm_list_add(config->explicit_removes, pkg); } return 0; }
static int _add_mirror(alpm_db_t *db, char *value) { const char *dbname = alpm_db_get_name(db); /* let's attempt a replacement for the current repo */ char *temp = strreplace(value, "$repo", dbname); /* let's attempt a replacement for the arch */ const char *arch = config->arch; char *server; if(arch) { server = strreplace(temp, "$arch", arch); free(temp); } else { if(strstr(temp, "$arch")) { free(temp); pm_printf(ALPM_LOG_ERROR, _("mirror '%s' contains the '%s' variable, but no '%s' is defined.\n"), value, "$arch", "Architecture"); return 1; } server = temp; } if(alpm_db_add_server(db, server) != 0) { /* pm_errno is set by alpm_db_setserver */ pm_printf(ALPM_LOG_ERROR, _("could not add server URL to database '%s': %s (%s)\n"), dbname, server, alpm_strerror(alpm_errno(config->handle))); free(server); return 1; } free(server); return 0; }
static int files_list(alpm_list_t *syncs, alpm_list_t *targets) { alpm_list_t *i, *j; int ret = 0, found = 0; if(targets != NULL) { for(i = targets; i; i = alpm_list_next(i)) { char *targ = i->data; char *repo = NULL; char *c = strchr(targ, '/'); if(c) { if(! *(c + 1)) { pm_printf(ALPM_LOG_ERROR, _("invalid package: '%s'\n"), targ); ret += 1; continue; } repo = strndup(targ, c - targ); targ = c + 1; } for(j = syncs; j; j = alpm_list_next(j)) { alpm_pkg_t *pkg; alpm_db_t *db = j->data; if(repo) { if(strcmp(alpm_db_get_name(db), repo) != 0) { continue; } } if((pkg = alpm_db_get_pkg(db, targ)) != NULL) { found = 1; dump_file_list(pkg); break; } } if(!found) { targ = i->data; pm_printf(ALPM_LOG_ERROR, _("package '%s' was not found\n"), targ); ret += 1; } free(repo); } } else { for(i = syncs; i; i = alpm_list_next(i)) { alpm_db_t *db = i->data; for(j = alpm_db_get_pkgcache(db); j; j = alpm_list_next(j)) { alpm_pkg_t *pkg = j->data; dump_file_list(pkg); } } } return ret; }
/* Loop through the files of the package to check if they exist. */ int check_pkg_fast(alpm_pkg_t *pkg) { const char *root, *pkgname; size_t errors = 0; size_t rootlen; char filepath[PATH_MAX]; alpm_filelist_t *filelist; size_t i; root = alpm_option_get_root(config->handle); rootlen = strlen(root); if(rootlen + 1 > PATH_MAX) { /* we are in trouble here */ pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); return 1; } strcpy(filepath, root); pkgname = alpm_pkg_get_name(pkg); filelist = alpm_pkg_get_files(pkg); for(i = 0; i < filelist->count; i++) { const alpm_file_t *file = filelist->files + i; struct stat st; int exists; const char *path = file->name; size_t plen = strlen(path); if(rootlen + 1 + plen > PATH_MAX) { pm_printf(ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path); continue; } strcpy(filepath + rootlen, path); exists = check_file_exists(pkgname, filepath, rootlen, &st); if(exists == 0) { int expect_dir = path[plen - 1] == '/' ? 1 : 0; int is_dir = S_ISDIR(st.st_mode) ? 1 : 0; if(expect_dir != is_dir) { pm_printf(ALPM_LOG_WARNING, _("%s: %s (File type mismatch)\n"), pkgname, filepath); ++errors; } } else if(exists == 1) { ++errors; } } if(!config->quiet) { printf(_n("%s: %jd total file, ", "%s: %jd total files, ", (unsigned long)filelist->count), pkgname, (intmax_t)filelist->count); printf(_n("%jd missing file\n", "%jd missing files\n", (unsigned long)errors), (intmax_t)errors); } return (errors != 0 ? 1 : 0); }
/** * @brief Modify the 'local' package database. * * @param targets a list of packages (as strings) to modify * * @return 0 on success, 1 on failure */ int pacman_database(alpm_list_t *targets) { alpm_list_t *i; alpm_db_t *db_local; int retval = 0; alpm_pkgreason_t reason; if(targets == NULL) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } if(config->flags & ALPM_TRANS_FLAG_ALLDEPS) { /* --asdeps */ reason = ALPM_PKG_REASON_DEPEND; } else if(config->flags & ALPM_TRANS_FLAG_ALLEXPLICIT) { /* --asexplicit */ reason = ALPM_PKG_REASON_EXPLICIT; } else { pm_printf(ALPM_LOG_ERROR, _("no install reason specified (use -h for help)\n")); return 1; } /* Lock database */ if(trans_init(0, 0) == -1) { return 1; } db_local = alpm_option_get_localdb(config->handle); for(i = targets; i; i = alpm_list_next(i)) { char *pkgname = i->data; alpm_pkg_t *pkg = alpm_db_get_pkg(db_local, pkgname); if(!pkg || alpm_db_set_pkgreason(config->handle, pkg, reason)) { pm_printf(ALPM_LOG_ERROR, _("could not set install reason for package %s (%s)\n"), pkgname, alpm_strerror(alpm_errno(config->handle))); retval = 1; } else { if(reason == ALPM_PKG_REASON_DEPEND) { printf(_("%s: install reason has been set to 'installed as dependency'\n"), pkgname); } else { printf(_("%s: install reason has been set to 'explicitly installed'\n"), pkgname); } } } /* Unlock database */ if(trans_release() == -1) { return 1; } return retval; }
void trans_init_error(void) { alpm_errno_t err = alpm_errno(config->handle); pm_printf(ALPM_LOG_ERROR, _("failed to init transaction (%s)\n"), alpm_strerror(err)); if(err == ALPM_ERR_HANDLE_LOCK) { const char *lockfile = alpm_option_get_lockfile(config->handle); pm_printf(ALPM_LOG_ERROR, _("could not lock database: %s\n"), strerror(errno)); if(access(lockfile, F_OK) == 0) { fprintf(stderr, _(" if you're sure a package manager is not already\n" " running, you can remove %s\n"), lockfile); } } }
static int process_usage(alpm_list_t *values, alpm_db_usage_t *usage, const char *file, int linenum) { alpm_list_t *i; alpm_db_usage_t level = *usage; int ret = 0; for(i = values; i; i = i->next) { char *key = i->data; if(strcmp(key, "Sync") == 0) { level |= ALPM_DB_USAGE_SYNC; } else if(strcmp(key, "Search") == 0) { level |= ALPM_DB_USAGE_SEARCH; } else if(strcmp(key, "Install") == 0) { level |= ALPM_DB_USAGE_INSTALL; } else if(strcmp(key, "Upgrade") == 0) { level |= ALPM_DB_USAGE_UPGRADE; } else if(strcmp(key, "All") == 0) { level |= ALPM_DB_USAGE_ALL; } else { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: '%s' option '%s' not recognized\n"), file, linenum, "Usage", key); ret = 1; } } *usage = level; return ret; }
config_t *config_new(void) { config_t *newconfig = calloc(1, sizeof(config_t)); if(!newconfig) { pm_printf(ALPM_LOG_ERROR, _("malloc failure: could not allocate %zd bytes\n"), sizeof(config_t)); return NULL; } /* defaults which may get overridden later */ newconfig->op = PM_OP_MAIN; newconfig->logmask = ALPM_LOG_ERROR | ALPM_LOG_WARNING; newconfig->configfile = strdup(CONFFILE); newconfig->deltaratio = 0.0; if(alpm_capabilities() & ALPM_CAPABILITY_SIGNATURES) { newconfig->siglevel = ALPM_SIG_PACKAGE | ALPM_SIG_PACKAGE_OPTIONAL | ALPM_SIG_DATABASE | ALPM_SIG_DATABASE_OPTIONAL; newconfig->localfilesiglevel = ALPM_SIG_USE_DEFAULT; newconfig->remotefilesiglevel = ALPM_SIG_USE_DEFAULT; } newconfig->colstr.colon = ":: "; newconfig->colstr.title = ""; newconfig->colstr.repo = ""; newconfig->colstr.version = ""; newconfig->colstr.groups = ""; newconfig->colstr.meta = ""; newconfig->colstr.warn = ""; newconfig->colstr.err = ""; newconfig->colstr.nocolor = ""; return newconfig; }
int pacman_files(alpm_list_t *targets) { alpm_list_t *files_dbs = NULL; if(check_syncdbs(1, 0)) { return 1; } files_dbs = alpm_get_syncdbs(config->handle); if(config->op_s_sync) { /* grab a fresh package list */ colon_printf(_("Synchronizing package databases...\n")); alpm_logaction(config->handle, PACMAN_CALLER_PREFIX, "synchronizing package lists\n"); if(!sync_syncdbs(config->op_s_sync, files_dbs)) { return 1; } } if(targets == NULL && (config->op_q_owns | config->op_s_search)) { pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n")); return 1; } /* determine the owner of a file */ if(config->op_q_owns) { return files_fileowner(files_dbs, targets); } /* search for a file */ if(config->op_s_search) { return files_search(files_dbs, targets, config->op_f_regex); } /* get a listing of files in sync DBs */ if(config->op_q_list) { return files_list(files_dbs, targets); } if(targets != NULL) { pm_printf(ALPM_LOG_ERROR, _("no options specified (use -h for help)\n")); return 1; } return 0; }
static int _parse_repo(const char *key, char *value, const char *file, int line, struct section_t *section) { int ret = 0; config_repo_t *repo = section->repo; if(strcmp(key, "Server") == 0) { if(!value) { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"), file, line, key); ret = 1; } else { repo->servers = alpm_list_add(repo->servers, strdup(value)); } } else if(strcmp(key, "SigLevel") == 0) { if(!value) { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"), file, line, key); } else { alpm_list_t *values = NULL; setrepeatingoption(value, "SigLevel", &values); if(values) { ret = process_siglevel(values, &repo->siglevel, &repo->siglevel_mask, file, line); FREELIST(values); } } } else if(strcmp(key, "Usage") == 0) { alpm_list_t *values = NULL; setrepeatingoption(value, "Usage", &values); if(values) { if(process_usage(values, &repo->usage, file, line)) { FREELIST(values); return 1; } FREELIST(values); } } else { pm_printf(ALPM_LOG_WARNING, _("config file %s, line %d: directive '%s' in section '%s' not recognized.\n"), file, line, key, repo->name); } return ret; }
/** Parse a configuration file. * @param file path to the config file * @return 0 on success, non-zero on error */ int parseconfig(const char *file) { int ret; struct section_t section; memset(§ion, 0, sizeof(struct section_t)); pm_printf(ALPM_LOG_DEBUG, "config: attempting to read file %s\n", file); if((ret = parse_ini(file, _parse_directive, §ion))) { return ret; } pm_printf(ALPM_LOG_DEBUG, "config: finished parsing %s\n", file); if((ret = setup_libalpm())) { return ret; } alpm_list_free_inner(config->repos, (alpm_list_fn_free) config_repo_free); alpm_list_free(config->repos); config->repos = NULL; return ret; }
int trans_release(void) { if(alpm_trans_release(config->handle) == -1) { pm_printf(ALPM_LOG_ERROR, _("failed to release transaction (%s)\n"), alpm_strerror(alpm_errno(config->handle))); return -1; } return 0; }
static void invalid_opt(int used, const char *opt1, const char *opt2) { if(used) { pm_printf(ALPM_LOG_ERROR, _("invalid option: '%s' and '%s' may not be used together\n"), opt1, opt2); cleanup(1); } }
/** * @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(); }
/* Loop through the files of the package to check if they exist. */ int check_pkg_fast(alpm_pkg_t *pkg) { const char *root, *pkgname; size_t errors = 0; size_t rootlen; char filepath[PATH_MAX]; alpm_filelist_t *filelist; size_t i; root = alpm_option_get_root(config->handle); rootlen = strlen(root); if(rootlen + 1 > PATH_MAX) { /* we are in trouble here */ pm_printf(ALPM_LOG_ERROR, _("path too long: %s%s\n"), root, ""); return 1; } strcpy(filepath, root); pkgname = alpm_pkg_get_name(pkg); filelist = alpm_pkg_get_files(pkg); for(i = 0; i < filelist->count; i++) { const alpm_file_t *file = filelist->files + i; struct stat st; const char *path = file->name; if(rootlen + 1 + strlen(path) > PATH_MAX) { pm_printf(ALPM_LOG_WARNING, _("path too long: %s%s\n"), root, path); continue; } strcpy(filepath + rootlen, path); errors += check_file_exists(pkgname, filepath, &st); } if(!config->quiet) { printf(_n("%s: %jd total file, ", "%s: %jd total files, ", (unsigned long)filelist->count), pkgname, (intmax_t)filelist->count); printf(_n("%jd missing file\n", "%jd missing files\n", (unsigned long)errors), (intmax_t)errors); } return (errors != 0 ? 1 : 0); }
/** * Wrap up a section once we have reached the end of it. This should be called * when a subsequent section is encountered, or when we have reached the end of * the root config file. Once called, all existing saved config pieces on the * section struct are freed. * @param section the current parsed and saved section data * @param parse_options whether we are parsing options or repo data * @return 0 on success, 1 on failure */ static int finish_section(struct section_t *section, int parse_options) { int ret = 0; alpm_list_t *i; alpm_db_t *db; pm_printf(ALPM_LOG_DEBUG, "config: finish section '%s'\n", section->name); /* parsing options (or nothing)- nothing to do except free the pieces */ if(!section->name || parse_options || section->is_options) { goto cleanup; } /* if we are not looking at options sections only, register a db */ db = alpm_register_syncdb(config->handle, section->name, section->siglevel); if(db == NULL) { pm_printf(ALPM_LOG_ERROR, _("could not register '%s' database (%s)\n"), section->name, alpm_strerror(alpm_errno(config->handle))); ret = 1; goto cleanup; } for(i = section->servers; i; i = alpm_list_next(i)) { char *value = i->data; if(_add_mirror(db, value) != 0) { pm_printf(ALPM_LOG_ERROR, _("could not add mirror '%s' to database '%s' (%s)\n"), value, section->name, alpm_strerror(alpm_errno(config->handle))); ret = 1; goto cleanup; } free(value); } cleanup: alpm_list_free(section->servers); section->servers = NULL; section->siglevel = ALPM_SIG_USE_DEFAULT; free(section->name); section->name = NULL; return ret; }
static int _parse_directive(const char *file, int linenum, const char *name, char *key, char *value, void *data) { struct section_t *section = data; if(!name && !key && !value) { pm_printf(ALPM_LOG_ERROR, _("config file %s could not be read: %s\n"), file, strerror(errno)); return 1; } else if(!key && !value) { section->name = name; pm_printf(ALPM_LOG_DEBUG, "config: new section '%s'\n", name); if(strcmp(name, "options") == 0) { section->repo = NULL; } else { section->repo = calloc(sizeof(config_repo_t), 1); section->repo->name = strdup(name); section->repo->siglevel = ALPM_SIG_USE_DEFAULT; section->repo->usage = 0; config->repos = alpm_list_add(config->repos, section->repo); } return 0; } if(strcmp(key, "Include") == 0) { return process_include(value, data, file, linenum); } if(section->name == NULL) { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: All directives must belong to a section.\n"), file, linenum); return 1; } if(!section->repo) { /* we are either in options ... */ return _parse_options(key, value, file, linenum); } else { /* ... or in a repo section */ return _parse_repo(key, value, file, linenum, section); } }
/** Add repeating options such as NoExtract, NoUpgrade, etc to libalpm * settings. Refactored out of the parseconfig code since all of them did * the exact same thing and duplicated code. * @param ptr a pointer to the start of the multiple options * @param option the string (friendly) name of the option, used for messages * @param list the list to add the option to */ static void setrepeatingoption(char *ptr, const char *option, alpm_list_t **list) { char *val, *saveptr = NULL; val = strtok_r(ptr, " ", &saveptr); while(val) { *list = alpm_list_add(*list, strdup(val)); pm_printf(ALPM_LOG_DEBUG, "config: %s: %s\n", option, val); val = strtok_r(NULL, " ", &saveptr); } }
int config_set_arch(const char *arch) { if(strcmp(arch, "auto") == 0) { struct utsname un; uname(&un); config->arch = strdup(un.machine); } else { config->arch = strdup(arch); } pm_printf(ALPM_LOG_DEBUG, "config: arch: %s\n", config->arch); return 0; }
/** Parse a configuration file. * @param file path to the config file * @return 0 on success, non-zero on error */ int parseconfig(const char *file) { int ret; struct section_t section; memset(§ion, 0, sizeof(struct section_t)); section.siglevel = ALPM_SIG_USE_DEFAULT; /* the config parse is a two-pass affair. We first parse the entire thing for * the [options] section so we can get all default and path options set. * Next, we go back and parse everything but [options]. */ /* call the real parseconfig function with a null section & db argument */ pm_printf(ALPM_LOG_DEBUG, "parseconfig: options pass\n"); if((ret = _parseconfig(file, §ion, 1, 0))) { return ret; } if((ret = setup_libalpm())) { return ret; } /* second pass, repo section parsing */ pm_printf(ALPM_LOG_DEBUG, "parseconfig: repo pass\n"); return _parseconfig(file, §ion, 0, 0); }
static int process_include(const char *value, void *data, const char *file, int linenum) { glob_t globbuf; int globret, ret = 0; size_t gindex; struct section_t *section = data; static const int config_max_recursion = 10; if(value == NULL) { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: directive '%s' needs a value\n"), file, linenum, "Include"); return 1; } if(section->depth >= config_max_recursion) { pm_printf(ALPM_LOG_ERROR, _("config parsing exceeded max recursion depth of %d.\n"), config_max_recursion); return 1; } section->depth++; /* Ignore include failures... assume non-critical */ globret = glob(value, GLOB_NOCHECK, NULL, &globbuf); switch(globret) { case GLOB_NOSPACE: pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: include globbing out of space\n", file, linenum); break; case GLOB_ABORTED: pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: include globbing read error for %s\n", file, linenum, value); break; case GLOB_NOMATCH: pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: no include found for %s\n", file, linenum, value); break; default: for(gindex = 0; gindex < globbuf.gl_pathc; gindex++) { pm_printf(ALPM_LOG_DEBUG, "config file %s, line %d: including %s\n", file, linenum, globbuf.gl_pathv[gindex]); ret = parse_ini(globbuf.gl_pathv[gindex], _parse_directive, data); if(ret) { goto cleanup; } } break; } cleanup: section->depth--; globfree(&globbuf); return ret; }
/* Loop through the packages. For each package, * loop through files to check if they exist. */ static int check(alpm_pkg_t *pkg) { const char *root, *pkgname; size_t errors = 0; size_t rootlen; char f[PATH_MAX]; alpm_filelist_t *filelist; size_t i; 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); pkgname = alpm_pkg_get_name(pkg); filelist = alpm_pkg_get_files(pkg); for(i = 0; i < filelist->count; i++) { const alpm_file_t *file = filelist->files + i; struct stat st; 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); /* 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: %jd total file, ", "%s: %jd total files, ", (unsigned long)filelist->count), pkgname, (intmax_t)filelist->count); printf(_n("%jd missing file\n", "%jd missing files\n", (unsigned long)errors), (intmax_t)errors); } return (errors != 0 ? 1 : 0); }
static int check_file_link(const char *pkgname, const char *filepath, struct stat *st, struct archive_entry *entry) { size_t length = st->st_size + 1; char link[length]; if(readlink(filepath, link, length) != st->st_size) { /* this should not happen */ pm_printf(ALPM_LOG_ERROR, _("unable to read symlink contents: %s\n"), filepath); return 1; } link[length - 1] = '\0'; if(strcmp(link, archive_entry_symlink(entry)) != 0) { if(!config->quiet) { pm_printf(ALPM_LOG_WARNING, _("%s: %s (Symlink path mismatch)\n"), pkgname, filepath); } return 1; } return 0; }
int check_syncdbs(size_t need_repos, int check_valid) { int ret = 0; alpm_list_t *i; alpm_list_t *sync_dbs = alpm_get_syncdbs(config->handle); if(need_repos && sync_dbs == NULL) { pm_printf(ALPM_LOG_ERROR, _("no usable package repositories configured.\n")); return 1; } if(check_valid) { /* ensure all known dbs are valid */ for(i = sync_dbs; i; i = alpm_list_next(i)) { alpm_db_t *db = i->data; if(alpm_db_get_valid(db)) { pm_printf(ALPM_LOG_ERROR, _("database '%s' is not valid (%s)\n"), alpm_db_get_name(db), alpm_strerror(alpm_errno(config->handle))); ret = 1; } } } return ret; }
static int check_file_permissions(const char *pkgname, const char *filepath, struct stat *st, struct archive_entry *entry) { int errors = 0; mode_t fsmode; /* uid */ if(st->st_uid != archive_entry_uid(entry)) { errors++; if(!config->quiet) { pm_printf(ALPM_LOG_WARNING, _("%s: %s (UID mismatch)\n"), pkgname, filepath); } } /* gid */ if(st->st_gid != archive_entry_gid(entry)) { errors++; if(!config->quiet) { pm_printf(ALPM_LOG_WARNING, _("%s: %s (GID mismatch)\n"), pkgname, filepath); } } /* mode */ fsmode = st->st_mode & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO); if(fsmode != (~AE_IFMT & archive_entry_mode(entry))) { errors++; if(!config->quiet) { pm_printf(ALPM_LOG_WARNING, _("%s: %s (Permissions mismatch)\n"), pkgname, filepath); } } return (errors != 0 ? 1 : 0); }
/** Free the resources. * * @param ret the return value */ static void cleanup(int ret) { if(config) { /* free alpm library resources */ if(config->handle && alpm_release(config->handle) == -1) { pm_printf(ALPM_LOG_ERROR, "error releasing alpm library\n"); } config_free(config); config = NULL; } /* free memory */ FREELIST(pm_targets); exit(ret); }
static int check_file_exists(const char *pkgname, const char * filepath, struct stat * st) { /* use lstat to prevent errors from symlinks */ if(lstat(filepath, st) != 0) { if(config->quiet) { printf("%s %s\n", pkgname, filepath); } else { pm_printf(ALPM_LOG_WARNING, "%s: %s (%s)\n", pkgname, filepath, strerror(errno)); } return 1; } return 0; }
static int process_cleanmethods(alpm_list_t *values, const char *file, int linenum) { alpm_list_t *i; for(i = values; i; i = alpm_list_next(i)) { const char *value = i->data; if(strcmp(value, "KeepInstalled") == 0) { config->cleanmethod |= PM_CLEAN_KEEPINST; } else if(strcmp(value, "KeepCurrent") == 0) { config->cleanmethod |= PM_CLEAN_KEEPCUR; } else { pm_printf(ALPM_LOG_ERROR, _("config file %s, line %d: invalid value for '%s' : '%s'\n"), file, linenum, "CleanMethod", value); return 1; } } return 0; }
/** Displays the list in table format * * @param title the tables title * @param header the column headers. column count is determined by the nr * of headers * @param rows the rows to display as a list of lists of strings. the outer * list represents the rows, the inner list the cells (= columns) * @param cols the number of columns available in the terminal * @return -1 if not enough terminal cols available, else 0 */ static int table_display(const alpm_list_t *header, const alpm_list_t *rows, unsigned short cols) { const unsigned short padding = 2; const alpm_list_t *i, *first; size_t *widths = NULL, totalcols, totalwidth; int *has_data = NULL; if(rows == NULL) { return 0; } /* we want the first row. if no headers are provided, use the first * entry of the rows array. */ first = header ? header : rows->data; totalcols = alpm_list_count(first); totalwidth = table_calc_widths(first, rows, padding, totalcols, &widths, &has_data); /* return -1 if terminal is not wide enough */ if(totalwidth > cols) { pm_printf(ALPM_LOG_WARNING, _("insufficient columns available for table display\n")); return -1; } if(!totalwidth || !widths || !has_data) { return -1; } if (header) { table_print_line(header, padding, totalcols, widths, has_data); printf("\n"); } for(i = rows; i; i = alpm_list_next(i)) { table_print_line(i->data, padding, totalcols, widths, has_data); } free(widths); free(has_data); return 0; }