static int check_sha256sum(alpm_pkg_t *pkg) { int ret = 0; char path[PATH_MAX], *rel; pu_mtree_reader_t *reader; pu_mtree_t *m; if((reader = pu_mtree_reader_open_package(handle, pkg)) == NULL) { pu_ui_warn("%s: mtree data not available (%s)", alpm_pkg_get_name(pkg), strerror(errno)); return require_mtree; } strcpy(path, alpm_option_get_root(handle)); rel = path + strlen(alpm_option_get_root(handle)); if((m = pu_mtree_new()) == NULL) { pu_ui_warn("%s: error reading mtree data (%s)", alpm_pkg_get_name(pkg), strerror(errno)); pu_mtree_reader_free(reader); return require_mtree; } while(pu_mtree_reader_next(reader, m)) { char *sha; if(m->sha256digest[0] == '\0') { continue; } if(m->path[0] == '.') { continue; } if(skip_backups && match_backup(pkg, m->path)) { continue; } if(skip_noextract && match_noextract(handle, m->path)) { continue; } if(skip_noupgrade && match_noupgrade(handle, m->path)) { continue; } strcpy(rel, m->path); if((sha = alpm_compute_sha256sum(path)) == NULL) { pu_ui_warn("%s: '%s' read error (%s)", alpm_pkg_get_name(pkg), path, strerror(errno)); } else if(memcmp(m->sha256digest, sha, 32) != 0) { eprintf("%s: '%s' sha256sum mismatch (expected %s)\n", alpm_pkg_get_name(pkg), path, m->sha256digest); ret = 1; } free(sha); } pu_mtree_free(m); if(!reader->eof) { pu_ui_warn("%s: error reading mtree data (%s)", alpm_pkg_get_name(pkg), strerror(errno)); pu_mtree_reader_free(reader); return ret || require_mtree; } pu_mtree_reader_free(reader); if(!quiet && !ret) { eprintf("%s: all files match mtree sha256sums\n", alpm_pkg_get_name(pkg)); } return ret; }
/** * call-seq: * root() → a_string * * Returns the target path to install packages under. */ static VALUE root(VALUE self) { alpm_handle_t* p_alpm = NULL; Data_Get_Struct(self, alpm_handle_t, p_alpm); return rb_str_new2(alpm_option_get_root(p_alpm)); }
/* 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); }
/* 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); }
/** * call-seq: * inspect() → a_string * * Human-readable description. */ static VALUE inspect(VALUE self) { alpm_handle_t* p_alpm = NULL; char buf[256]; int len; Data_Get_Struct(self, alpm_handle_t, p_alpm); len = sprintf(buf, "#<%s target=%s db=%s>", rb_obj_classname(self), alpm_option_get_root(p_alpm), alpm_option_get_dbpath(p_alpm)); return rb_str_new(buf, len); }
static gboolean pk_backend_get_files_thread (PkBackend *self) { gchar **packages; GError *error = NULL; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (alpm != NULL, FALSE); packages = pk_backend_get_strv (self, "package_ids"); g_return_val_if_fail (packages != NULL, FALSE); for (; *packages != NULL; ++packages) { alpm_pkg_t *pkg; const gchar *root; GString *files; alpm_filelist_t *filelist; gsize i; if (pk_backend_cancelled (self)) { break; } pkg = pk_backend_find_pkg (self, *packages, &error); if (pkg == NULL) { break; } root = alpm_option_get_root (alpm); files = g_string_new (""); filelist = alpm_pkg_get_files (pkg); for (i = 0; i < filelist->count; ++i) { const gchar *file = filelist->files[i].name; g_string_append_printf (files, "%s%s;", root, file); } g_string_truncate (files, MAX (files->len, 1) - 1); pk_backend_job_files (self, *packages, files->str); g_string_free (files, TRUE); } return pk_backend_finish (self, error); }
/* 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); }
/* verify that the filesystem matches the package database */ static int check_files(alpm_pkg_t *pkg) { alpm_filelist_t *filelist = alpm_pkg_get_files(pkg); char path[PATH_MAX], *rel; const char *pkgname = alpm_pkg_get_name(pkg); unsigned int i; int ret = 0; size_t space; strncpy(path, alpm_option_get_root(handle), PATH_MAX); rel = path + strlen(path); space = PATH_MAX - (rel - path); for(i = 0; i < filelist->count; ++i) { alpm_file_t file = filelist->files[i]; int isdir = 0; size_t len; if(skip_noextract && match_noextract(handle, file.name)) { continue; } strncpy(rel, file.name, space); len = strlen(file.name); if(rel[len - 1] == '/') { isdir = 1; rel[len - 1] = '\0'; } if(check_file(pkgname, path, isdir) != 0) { ret = 1; } } if(include_db_files && check_db_files(pkg) != 0) { ret = 1; } if(!quiet && !ret) { eprintf("%s: all files match database\n", alpm_pkg_get_name(pkg)); } return ret; }
/* Display list of backup files and their modification states */ void dump_pkg_backups(alpm_pkg_t *pkg) { alpm_list_t *i; const char *root = alpm_option_get_root(config->handle); printf("%s%s%s", config->colstr.title, _("Backup Files:\n"), config->colstr.nocolor); if(alpm_pkg_get_backup(pkg)) { /* package has backup files, so print them */ for(i = alpm_pkg_get_backup(pkg); i; i = alpm_list_next(i)) { const alpm_backup_t *backup = i->data; const char *value; if(!backup->hash) { continue; } value = get_backup_file_status(root, backup); printf("%s\t%s%s\n", value, root, backup->name); } } else { /* package had no backup files */ printf(_("(none)\n")); } }
static gpointer pk_backend_pattern_chroot (PkBackend *backend, const gchar *needle, GError **error) { PkBackendAlpmPrivate *priv = pk_backend_get_user_data (backend); g_return_val_if_fail (needle != NULL, NULL); if (G_IS_DIR_SEPARATOR (*needle)) { const gchar *file = needle, *root = alpm_option_get_root (priv->alpm); /* adjust needle to the correct prefix */ for (; *file == *root; ++file, ++root) { if (*root == '\0') { needle = file - 1; break; } else if (*file == '\0') { break; } } } return (gpointer) needle; }
/* List all files contained in a package */ void dump_pkg_files(alpm_pkg_t *pkg, int quiet) { const char *pkgname, *root; alpm_filelist_t *pkgfiles; size_t i; pkgname = alpm_pkg_get_name(pkg); pkgfiles = alpm_pkg_get_files(pkg); root = alpm_option_get_root(config->handle); for(i = 0; i < pkgfiles->count; i++) { const alpm_file_t *file = pkgfiles->files + i; /* Regular: '<pkgname> <root><filepath>\n' * Quiet : '<root><filepath>\n' */ if(!quiet) { printf("%s%s%s ", config->colstr.title, pkgname, config->colstr.nocolor); } printf("%s%s\n", root, file->name); } fflush(stdout); }
/* Loop though files in a package and perform full file property checking. */ int check_pkg_full(alpm_pkg_t *pkg) { const char *root, *pkgname; size_t errors = 0; size_t rootlen; char filepath[PATH_MAX]; struct archive *mtree; struct archive_entry *entry = NULL; size_t file_count = 0; const alpm_list_t *lp; 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); mtree = alpm_pkg_mtree_open(pkg); if(mtree == NULL) { /* TODO: check error to confirm failure due to no mtree file */ if(!config->quiet) { printf(_("%s: no mtree file\n"), pkgname); } return 0; } while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) { struct stat st; const char *path = archive_entry_pathname(entry); mode_t type; size_t file_errors = 0; int backup = 0; /* strip leading "./" from path entries */ if(path[0] == '.' && path[1] == '/') { path += 2; } if(strcmp(path, ".INSTALL") == 0) { char filename[PATH_MAX]; snprintf(filename, PATH_MAX, "%slocal/%s-%s/install", alpm_option_get_dbpath(config->handle) + 1, pkgname, alpm_pkg_get_version(pkg)); archive_entry_set_pathname(entry, filename); path = archive_entry_pathname(entry); } else if(strcmp(path, ".CHANGELOG") == 0) { char filename[PATH_MAX]; snprintf(filename, PATH_MAX, "%slocal/%s-%s/changelog", alpm_option_get_dbpath(config->handle) + 1, pkgname, alpm_pkg_get_version(pkg)); archive_entry_set_pathname(entry, filename); path = archive_entry_pathname(entry); } else if(*path == '.') { continue; } file_count++; 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); if(check_file_exists(pkgname, filepath, &st) == 1) { errors++; continue; } type = archive_entry_filetype(entry); if(type != AE_IFDIR && type != AE_IFREG && type != AE_IFLNK) { pm_printf(ALPM_LOG_WARNING, _("file type not recognized: %s%s\n"), root, path); continue; } if(check_file_type(pkgname, filepath, &st, entry) == 1) { errors++; continue; } file_errors += check_file_permissions(pkgname, filepath, &st, entry); if(type == AE_IFLNK) { file_errors += check_file_link(pkgname, filepath, &st, entry); } /* the following checks are expected to fail if a backup file has been modified */ for(lp = alpm_pkg_get_backup(pkg); lp; lp = lp->next) { alpm_backup_t *bl = lp->data; if(strcmp(path, bl->name) == 0) { backup = 1; break; } } if(type != AE_IFDIR) { /* file or symbolic link */ file_errors += check_file_time(pkgname, filepath, &st, entry, backup); } if(type == AE_IFREG) { /* TODO: these are expected to be changed with backup files */ file_errors += check_file_size(pkgname, filepath, &st, entry, backup); /* file_errors += check_file_md5sum(pkgname, filepath, &st, entry, backup); */ } if(config->quiet && file_errors) { printf("%s %s\n", pkgname, filepath); } errors += (file_errors != 0 ? 1 : 0); } alpm_pkg_mtree_close(pkg, mtree); if(!config->quiet) { printf(_n("%s: %jd total file, ", "%s: %jd total files, ", (unsigned long)file_count), pkgname, (intmax_t)file_count); printf(_n("%jd altered file\n", "%jd altered files\n", (unsigned long)errors), (intmax_t)errors); } return (errors != 0 ? 1 : 0); }
/* check filesystem against extra mtree data if available, * NOT guaranteed to catch db/filesystem discrepencies */ static int check_file_properties(alpm_pkg_t *pkg) { char path[PATH_MAX], *rel; int ret = 0; size_t space; struct archive *mtree = alpm_pkg_mtree_open(pkg); struct archive_entry *entry; if(!mtree) { pu_ui_warn("%s: mtree data not available (%s)", alpm_pkg_get_name(pkg), strerror(errno)); return require_mtree; } strncpy(path, alpm_option_get_root(handle), PATH_MAX); rel = path + strlen(path); space = PATH_MAX - (rel - path); while(alpm_pkg_mtree_next(pkg, mtree, &entry) == ARCHIVE_OK) { const char *ppath = archive_entry_pathname(entry); const char *fpath; struct stat buf; if(strncmp("./", ppath, 2) == 0) { ppath += 2; } if(strcmp(ppath, ".INSTALL") == 0) { if((fpath = get_db_path(pkg, "install")) == NULL) { continue; } } else if(strcmp(ppath, ".CHANGELOG") == 0) { if((fpath = get_db_path(pkg, "changelog")) == NULL) { continue; } } else if(ppath[0] == '.') { continue; } else if(skip_noextract && match_noextract(handle, ppath)) { continue; } else { strncpy(rel, ppath, space); fpath = path; } if(lstat(fpath, &buf) != 0) { if(errno == ENOENT) { eprintf("%s: '%s' missing file\n", alpm_pkg_get_name(pkg), fpath); } else { pu_ui_warn("%s: '%s' read error (%s)", alpm_pkg_get_name(pkg), fpath, strerror(errno)); } ret = 1; continue; } if(cmp_type(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(skip_noupgrade && match_noupgrade(handle, ppath)) { continue; } if(cmp_mode(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(cmp_uid(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(cmp_gid(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(skip_backups && match_backup(pkg, ppath)) { continue; } if(S_ISLNK(buf.st_mode) && S_ISLNK(archive_entry_mode(entry))) { if(cmp_target(pkg, fpath, entry) != 0) { ret = 1; } } if(!S_ISDIR(buf.st_mode)) { if(cmp_mtime(pkg, fpath, entry, &buf) != 0) { ret = 1; } if(!S_ISLNK(buf.st_mode)) { /* always fails for directories and symlinks */ if(cmp_size(pkg, fpath, entry, &buf) != 0) { ret = 1; } } } } alpm_pkg_mtree_close(pkg, mtree); if(!quiet && !ret) { eprintf("%s: all files match mtree\n", alpm_pkg_get_name(pkg)); } return ret; }
/** * pacman_manager_get_root_path: * @manager: A #PacmanManager. * * Gets the directory that pacman will use as the root filesystem. * * Returns: A directory name. Do not free. */ const gchar *pacman_manager_get_root_path (PacmanManager *manager) { g_return_val_if_fail (manager != NULL, NULL); return alpm_option_get_root (); }
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; }