/* * If mask is nonzero, will not write any file whose filenamenode * has any flag bits set in mask. */ void write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin, struct fileinlist *list, enum fnnflags mask) { struct atomic_file *file; const char *listfile; listfile = pkg_infodb_get_file(pkg, pkgbin, LISTFILE); file = atomic_file_new(listfile, 0); atomic_file_open(file); while (list) { if (!(mask && (list->namenode->flags & mask))) { fputs(list->namenode->name, file->fp); putc('\n', file->fp); } list= list->next; } atomic_file_sync(file); atomic_file_close(file); atomic_file_commit(file); atomic_file_free(file); dir_sync_path(pkg_infodb_get_dir()); note_must_reread_files_inpackage(pkg); }
const char * pkg_infodb_reset_dir(void) { free(db_infodir); db_infodir = NULL; return pkg_infodb_get_dir(); }
static void pkg_files_optimize_load(struct pkg_array *array) { struct statfs fs; int i; /* Get the filesystem block size. */ if (statfs(pkg_infodb_get_dir(), &fs) < 0) return; /* Sort packages by the physical location of their list files, so that * scanning them later will minimize disk drive head movements. */ for (i = 0; i < array->n_pkgs; i++) { struct pkginfo *pkg = array->pkgs[i]; struct { struct fiemap fiemap; struct fiemap_extent extent; } fm; const char *listfile; int fd; ensure_package_clientdata(pkg); if (pkg->status == stat_notinstalled || pkg->clientdata->listfile_phys_offs != 0) continue; pkg->clientdata->listfile_phys_offs = -1; listfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE); fd = open(listfile, O_RDONLY); if (fd < 0) continue; memset(&fm, 0, sizeof(fm)); fm.fiemap.fm_start = 0; fm.fiemap.fm_length = fs.f_bsize; fm.fiemap.fm_flags = 0; fm.fiemap.fm_extent_count = 1; if (ioctl(fd, FS_IOC_FIEMAP, (unsigned long)&fm) == 0) pkg->clientdata->listfile_phys_offs = fm.fiemap.fm_extents[0].fe_physical; close(fd); } pkg_array_sort(array, pkg_sorter_by_listfile_phys_offs); }
const char * pkg_infodb_get_file(const struct pkginfo *pkg, const struct pkgbin *pkgbin, const char *filetype) { static struct varbuf vb; enum pkg_infodb_format format; /* Make sure to always read and verify the format version. */ format = pkg_infodb_get_format(); varbuf_reset(&vb); varbuf_add_str(&vb, pkg_infodb_get_dir()); varbuf_add_char(&vb, '/'); varbuf_add_str(&vb, pkg->set->name); if (pkgbin->multiarch == PKG_MULTIARCH_SAME && format == PKG_INFODB_FORMAT_MULTIARCH) varbuf_add_archqual(&vb, pkgbin->arch); varbuf_add_char(&vb, '.'); varbuf_add_str(&vb, filetype); varbuf_end_str(&vb); return vb.buf; }