/* * libdpkg - Debian packaging suite library routines * fsys.h - filesystem nodes hash table * * Copyright © 1995 Ian Jackson * Copyright © 2008-2014 Guillem Jover * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef LIBDPKG_FSYS_H #define LIBDPKG_FSYS_H #include #include DPKG_BEGIN_DECLS /* * Data structure here is as follows: * * For each package we have a ‘struct fsys_namenode_list *’, the head of a list of * files in that package. They are in ‘forwards’ order. Each entry has a * pointer to the ‘struct fsys_namenode’. * * The struct fsys_namenodes are in a hash table, indexed by name. * (This hash table is not visible to callers.) * * Each fsys_namenode has a (possibly empty) list of ‘struct filepackage’, * giving a list of the packages listing that filename. * * When we read files contained info about a particular package we set the * ‘files’ member of the clientdata struct to the appropriate thing. When * not yet set the files pointer is made to point to ‘fileslist_uninited’ * (this is available only internally, within filesdb.c - the published * interface is ensure_*_available). */ struct pkginfo; /** * Flags to fsys_hash_find_node(). */ enum fsys_hash_find_flags { /** Do not need to copy filename. */ FHFF_NOCOPY = DPKG_BIT(0), /** The find function might return NULL. */ FHFF_NONE = DPKG_BIT(1), }; enum fsys_namenode_flags { /** In the newconffiles list. */ FNNF_NEW_CONFF = DPKG_BIT(0), /** In the new filesystem archive. */ FNNF_NEW_INARCHIVE = DPKG_BIT(1), /** In the old package's conffiles list. */ FNNF_OLD_CONFF = DPKG_BIT(2), /** Obsolete conffile. */ FNNF_OBS_CONFF = DPKG_BIT(3), /** Must remove from other packages' lists. */ FNNF_ELIDE_OTHER_LISTS = DPKG_BIT(4), /** >= 1 instance is a dir, cannot rename over. */ FNNF_NO_ATOMIC_OVERWRITE = DPKG_BIT(5), /** New file has been placed on the disk. */ FNNF_PLACED_ON_DISK = DPKG_BIT(6), FNNF_DEFERRED_FSYNC = DPKG_BIT(7), FNNF_DEFERRED_RENAME = DPKG_BIT(8), /** Path being filtered. */ FNNF_FILTERED = DPKG_BIT(9), /** Conffile removal requested by upgrade. */ FNNF_RM_CONFF_ON_UPGRADE = DPKG_BIT(10), }; /** * Stores information to uniquely identify an on-disk file. */ struct file_ondisk_id { dev_t id_dev; ino_t id_ino; }; struct fsys_namenode { struct fsys_namenode *next; const char *name; struct pkg_list *packages; struct fsys_diversion *divert; /** We allow the administrator to override the owner, group and mode * of a file. If such an override is present we use that instead of * the stat information stored in the archive. * * This functionality used to be in the suidmanager package. */ struct file_stat *statoverride; struct trigfileint *trig_interested; /* * Fields from here on are used by archives.c &c, and cleared by * fsys_hash_init(). */ /** Set to zero when a new node is created. */ enum fsys_namenode_flags flags; /** Valid iff this namenode is in the newconffiles list. */ const char *oldhash; /** Valid iff the file was unpacked and hashed on this run. */ const char *newhash; struct file_ondisk_id *file_ondisk_id; }; struct fsys_namenode_list { struct fsys_namenode_list *next; struct fsys_namenode *namenode; }; /** * Queue of fsys_namenode entries. */ struct fsys_namenode_queue { struct fsys_namenode_list *head, **tail; }; /** * When we deal with an ‘overridden’ file, every package except the * overriding one is considered to contain the other file instead. Both * files have entries in the filesdb database, and they refer to each other * via these diversion structures. * * The contested filename's fsys_namenode has a diversion entry with * useinstead set to point to the redirected filename's fsys_namenode; the * redirected fsys_namenode has camefrom set to the contested fsys_namenode. * Both sides' diversion entries will have pkg set to the package (if any) * which is allowed to use the contended filename. * * Packages that contain either version of the file will all refer to the * contested fsys_namenode in their per-file package lists (both in core and * on disk). References are redirected to the other fsys_namenode's filename * where appropriate. */ struct fsys_diversion { struct fsys_namenode *useinstead; struct fsys_namenode *camefrom; struct pkgset *pkgset; /** The ‘contested’ halves are in this list for easy cleanup. */ struct fsys_diversion *next; }; struct fsys_node_pkgs_iter; struct fsys_node_pkgs_iter * fsys_node_pkgs_iter_new(struct fsys_namenode *fnn); struct pkginfo * fsys_node_pkgs_iter_next(struct fsys_node_pkgs_iter *iter); void fsys_node_pkgs_iter_free(struct fsys_node_pkgs_iter *iter); void fsys_hash_init(void); void fsys_hash_reset(void); void fsys_hash_report(FILE *file); int fsys_hash_entries(void); struct fsys_hash_iter; struct fsys_hash_iter * fsys_hash_iter_new(void); struct fsys_namenode * fsys_hash_iter_next(struct fsys_hash_iter *iter); void fsys_hash_iter_free(struct fsys_hash_iter *iter); struct fsys_namenode * fsys_hash_find_node(const char *filename, enum fsys_hash_find_flags flags); struct fsys_hash_rev_iter { struct fsys_namenode_list *todo; }; void fsys_hash_rev_iter_init(struct fsys_hash_rev_iter *iter, struct fsys_namenode_list *files); struct fsys_namenode * fsys_hash_rev_iter_next(struct fsys_hash_rev_iter *iter); void fsys_hash_rev_iter_abort(struct fsys_hash_rev_iter *iter); const char *dpkg_fsys_set_dir(const char *dir); const char *dpkg_fsys_get_dir(void); char *dpkg_fsys_get_path(const char *pathpart); DPKG_END_DECLS #endif /* LIBDPKG_FSYS_H */