diff options
author | Guillem Jover <guillem@debian.org> | 2018-04-04 02:51:51 +0200 |
---|---|---|
committer | Guillem Jover <guillem@debian.org> | 2018-05-03 02:19:34 +0200 |
commit | f1cc66e522a475710aa51a6d164a8cc0eda3cae7 (patch) | |
tree | b2df955712203e52a8067a8569ae76067ac68a5c | |
parent | c2715071aa64807c9b95edd7c6e4cd8c3eb4ad8c (diff) | |
download | dpkg-f1cc66e522a475710aa51a6d164a8cc0eda3cae7.tar.gz |
libdpkg: Move filesystem nodename hash implementation into a new module
-rw-r--r-- | lib/dpkg/Makefile.am | 3 | ||||
-rw-r--r-- | lib/dpkg/fsys-hash.c | 169 | ||||
-rw-r--r-- | lib/dpkg/fsys-iter.c | 126 | ||||
-rw-r--r-- | lib/dpkg/fsys.h | 185 | ||||
-rw-r--r-- | lib/dpkg/libdpkg.map | 18 | ||||
-rw-r--r-- | po/POTFILES.in | 2 | ||||
-rw-r--r-- | src/filesdb.c | 209 | ||||
-rw-r--r-- | src/filesdb.h | 122 |
8 files changed, 504 insertions, 330 deletions
diff --git a/lib/dpkg/Makefile.am b/lib/dpkg/Makefile.am index 215d12ffb..65dd5811c 100644 --- a/lib/dpkg/Makefile.am +++ b/lib/dpkg/Makefile.am @@ -63,6 +63,8 @@ libdpkg_la_SOURCES = \ fdio.c \ file.c \ fields.c \ + fsys-iter.c \ + fsys-hash.c \ glob.c \ i18n.c i18n.h \ log.c \ @@ -121,6 +123,7 @@ pkginclude_HEADERS = \ error.h \ fdio.h \ file.h \ + fsys.h \ glob.h \ macros.h \ namevalue.h \ diff --git a/lib/dpkg/fsys-hash.c b/lib/dpkg/fsys-hash.c new file mode 100644 index 000000000..54d0d57b7 --- /dev/null +++ b/lib/dpkg/fsys-hash.c @@ -0,0 +1,169 @@ +/* + * libdpkg - Debian packaging suite library routines + * fsys-hash.c - filesystem nodes hash table + * + * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk> + * Copyright © 2000, 2001 Wichert Akkerman <wakkerma@debian.org> + * Copyright © 2008-2014 Guillem Jover <guillem@debian.org> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <compat.h> + +#include <string.h> +#include <stdlib.h> + +#include <dpkg/dpkg.h> +#include <dpkg/dpkg-db.h> +#include <dpkg/string.h> +#include <dpkg/path.h> + +#include "fsys.h" + +/* This must always be a prime for optimal performance. + * This is the closest one to 2^18 (262144). */ +#define BINS 262139 + +static struct filenamenode *bins[BINS]; +static int nfiles = 0; + +void +filesdbinit(void) +{ + struct filenamenode *fnn; + int i; + + for (i = 0; i < BINS; i++) { + for (fnn = bins[i]; fnn; fnn = fnn->next) { + fnn->flags = 0; + fnn->oldhash = NULL; + fnn->newhash = EMPTYHASHFLAG; + fnn->filestat = NULL; + } + } +} + +void +files_db_reset(void) +{ + int i; + + for (i = 0; i < BINS; i++) + bins[i] = NULL; +} + +int +fsys_hash_entries(void) +{ + return nfiles; +} + +struct filenamenode * +findnamenode(const char *name, enum fnnflags flags) +{ + struct filenamenode **pointerp, *newnode; + const char *orig_name = name; + + /* We skip initial slashes and ‘./’ pairs, and add our own single + * leading slash. */ + name = path_skip_slash_dotslash(name); + + pointerp = bins + (str_fnv_hash(name) % (BINS)); + while (*pointerp) { + /* XXX: This should not be needed, but it has been a constant + * source of assertions over the years. Hopefully with the + * internerr() we will get better diagnostics. */ + if ((*pointerp)->name[0] != '/') + internerr("filename node '%s' does not start with '/'", + (*pointerp)->name); + + if (strcmp((*pointerp)->name + 1, name) == 0) + break; + pointerp = &(*pointerp)->next; + } + if (*pointerp) + return *pointerp; + + if (flags & fnn_nonew) + return NULL; + + newnode = nfmalloc(sizeof(struct filenamenode)); + newnode->packages = NULL; + if ((flags & fnn_nocopy) && name > orig_name && name[-1] == '/') { + newnode->name = name - 1; + } else { + char *newname = nfmalloc(strlen(name) + 2); + + newname[0] = '/'; + strcpy(newname + 1, name); + newnode->name = newname; + } + newnode->flags = 0; + newnode->next = NULL; + newnode->divert = NULL; + newnode->statoverride = NULL; + newnode->oldhash = NULL; + newnode->newhash = EMPTYHASHFLAG; + newnode->filestat = NULL; + newnode->trig_interested = NULL; + *pointerp = newnode; + nfiles++; + + return newnode; +} + +/* + * Forward iterator. + */ + +struct fileiterator { + struct filenamenode *namenode; + int nbinn; +}; + +struct fileiterator * +files_db_iter_new(void) +{ + struct fileiterator *iter; + + iter = m_malloc(sizeof(struct fileiterator)); + iter->namenode = NULL; + iter->nbinn = 0; + + return iter; +} + +struct filenamenode * +files_db_iter_next(struct fileiterator *iter) +{ + struct filenamenode *r= NULL; + + while (!iter->namenode) { + if (iter->nbinn >= BINS) + return NULL; + iter->namenode = bins[iter->nbinn++]; + } + r = iter->namenode; + iter->namenode = r->next; + + return r; +} + +void +files_db_iter_free(struct fileiterator *iter) +{ + free(iter); +} diff --git a/lib/dpkg/fsys-iter.c b/lib/dpkg/fsys-iter.c new file mode 100644 index 000000000..aba31aa47 --- /dev/null +++ b/lib/dpkg/fsys-iter.c @@ -0,0 +1,126 @@ +/* + * libdpkg - Debian packaging suite library routines + * fsys-iter.c - filesystem nodes iterators + * + * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk> + * Copyright © 2000, 2001 Wichert Akkerman <wakkerma@debian.org> + * Copyright © 2008-2014 Guillem Jover <guillem@debian.org> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <compat.h> + +#include <stdlib.h> + +#include <dpkg/dpkg.h> +#include <dpkg/dpkg-db.h> +#include <dpkg/pkg-list.h> + +#include "fsys.h" + +/* + * Reverse fileinlist iterator. + */ + +/* + * Initializes an iterator that appears to go through the file list ‘files’ + * in reverse order, returning the namenode from each. What actually happens + * is that we walk the list here, building up a reverse list, and then peel + * it apart one entry at a time. + */ +void +reversefilelist_init(struct reversefilelistiter *iter, + struct fileinlist *files) +{ + struct fileinlist *newent; + + iter->todo = NULL; + while (files) { + newent = m_malloc(sizeof(struct fileinlist)); + newent->namenode = files->namenode; + newent->next = iter->todo; + iter->todo = newent; + files = files->next; + } +} + +struct filenamenode * +reversefilelist_next(struct reversefilelistiter *iter) +{ + struct filenamenode *ret; + struct fileinlist *todo; + + todo = iter->todo; + if (!todo) + return NULL; + ret = todo->namenode; + iter->todo = todo->next; + free(todo); + + return ret; +} + +/* + * Clients must call this function to clean up the reversefilelistiter + * if they wish to break out of the iteration before it is all done. + * Calling this function is not necessary if reversefilelist_next() has + * been called until it returned 0. + */ +void +reversefilelist_abort(struct reversefilelistiter *iter) +{ + while (reversefilelist_next(iter)) + ; +} + +/* + * Iterator for packages owning a file. + */ + +struct filepackages_iterator { + struct pkg_list *pkg_node; +}; + +struct filepackages_iterator * +filepackages_iter_new(struct filenamenode *fnn) +{ + struct filepackages_iterator *iter; + + iter = m_malloc(sizeof(*iter)); + iter->pkg_node = fnn->packages; + + return iter; +} + +struct pkginfo * +filepackages_iter_next(struct filepackages_iterator *iter) +{ + struct pkg_list *pkg_node; + + if (iter->pkg_node == NULL) + return NULL; + + pkg_node = iter->pkg_node; + iter->pkg_node = pkg_node->next; + + return pkg_node->pkg; +} + +void +filepackages_iter_free(struct filepackages_iterator *iter) +{ + free(iter); +} diff --git a/lib/dpkg/fsys.h b/lib/dpkg/fsys.h new file mode 100644 index 000000000..7d63b04e6 --- /dev/null +++ b/lib/dpkg/fsys.h @@ -0,0 +1,185 @@ +/* + * libdpkg - Debian packaging suite library routines + * fsys.h - filesystem nodes hash table + * + * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk> + * Copyright © 2008-2014 Guillem Jover <guillem@debian.org> + * + * 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 <https://www.gnu.org/licenses/>. + */ + +#ifndef LIBDPKG_FSYS_H +#define LIBDPKG_FSYS_H + +#include <dpkg/file.h> + +/* + * Data structure here is as follows: + * + * For each package we have a ‘struct fileinlist *’, the head of a list + * of files in that package. They are in ‘forwards’ order. Each entry has + * a pointer to the ‘struct filenamenode’. + * + * The struct filenamenodes are in a hash table, indexed by name. + * (This hash table is not visible to callers.) + * + * Each filenamenode 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 findnamenode(). + */ +enum fnnflags { + /** Do not need to copy filename. */ + fnn_nocopy = DPKG_BIT(0), + /** findnamenode may return NULL. */ + fnn_nonew = DPKG_BIT(1), +}; + +enum filenamenode_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), +}; + +struct filenamenode { + struct filenamenode *next; + const char *name; + + struct pkg_list *packages; + struct 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 cleared by filesdbinit(). + */ + + /** Set to zero when a new node is created. */ + enum filenamenode_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 stat *filestat; +}; + +/** + * 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 filenamenode has an diversion entry with + * useinstead set to point to the redirected filename's filenamenode; the + * redirected filenamenode has camefrom set to the contested filenamenode. + * 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 filenamenode in their per-file package lists (both in core and + * on disk). References are redirected to the other filenamenode's filename + * where appropriate. + */ +struct diversion { + struct filenamenode *useinstead; + struct filenamenode *camefrom; + struct pkgset *pkgset; + + /** The ‘contested’ halves are in this list for easy cleanup. */ + struct diversion *next; +}; + +struct fileinlist { + struct fileinlist *next; + struct filenamenode *namenode; +}; + +/** + * Queue of filenamenode entries. + */ +struct filenamenode_queue { + struct fileinlist *head, **tail; +}; + +/** + * Forward filesystem node iterator. + */ +struct fileiterator; + +/** + * Reverse filesystem node iterator. + */ +struct reversefilelistiter { + struct fileinlist *todo; +}; + +/** + * Forward filesystem node package owners iterator. + */ +struct filepackages_iterator; + + +void filesdbinit(void); +void files_db_reset(void); +int fsys_hash_entries(void); + +struct filenamenode *findnamenode(const char *filename, enum fnnflags flags); + +struct fileiterator *files_db_iter_new(void); +struct filenamenode *files_db_iter_next(struct fileiterator *iter); +void files_db_iter_free(struct fileiterator *iter); + +void reversefilelist_init(struct reversefilelistiter *iterptr, struct fileinlist *files); +struct filenamenode *reversefilelist_next(struct reversefilelistiter *iterptr); +void reversefilelist_abort(struct reversefilelistiter *iterptr); + +struct filepackages_iterator *filepackages_iter_new(struct filenamenode *fnn); +struct pkginfo *filepackages_iter_next(struct filepackages_iterator *iter); +void filepackages_iter_free(struct filepackages_iterator *iter); + +#endif /* LIBDPKG_FSYS_H */ diff --git a/lib/dpkg/libdpkg.map b/lib/dpkg/libdpkg.map index 85b8a1fa6..6f9b53e01 100644 --- a/lib/dpkg/libdpkg.map +++ b/lib/dpkg/libdpkg.map @@ -381,6 +381,24 @@ LIBDPKG_PRIVATE { modstatdb_shutdown; modstatdb_done; + # Filesystem node hash support + filesdbinit; + files_db_reset; + fsys_hash_entries; + findnamenode; + + files_db_iter_new; + files_db_iter_next; + files_db_iter_free; + + reversefilelist_init; + reversefilelist_next; + reversefilelist_abort; + + filepackages_iter_new; + filepackages_iter_next; + filepackages_iter_free; + # Triggers support trig_name_is_illegal; trigdef_set_methods; diff --git a/po/POTFILES.in b/po/POTFILES.in index 1b890c55e..e4c3815ae 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -21,6 +21,8 @@ lib/dpkg/error.c lib/dpkg/fdio.c lib/dpkg/fields.c lib/dpkg/file.c +lib/dpkg/fsys-iter.c +lib/dpkg/fsys-hash.c lib/dpkg/glob.c lib/dpkg/i18n.c lib/dpkg/log.c diff --git a/src/filesdb.c b/src/filesdb.c index 6e99c36f3..87bca58e3 100644 --- a/src/filesdb.c +++ b/src/filesdb.c @@ -54,47 +54,9 @@ #include "infodb.h" #include "main.h" -/*** filepackages support for tracking packages owning a file. ***/ - -struct filepackages_iterator { - struct pkg_list *pkg_node; -}; - -struct filepackages_iterator * -filepackages_iter_new(struct filenamenode *fnn) -{ - struct filepackages_iterator *iter; - - iter = m_malloc(sizeof(*iter)); - iter->pkg_node = fnn->packages; - - return iter; -} - -struct pkginfo * -filepackages_iter_next(struct filepackages_iterator *iter) -{ - struct pkg_list *pkg_node; - - if (iter->pkg_node == NULL) - return NULL; - - pkg_node = iter->pkg_node; - iter->pkg_node = pkg_node->next; - - return pkg_node->pkg; -} - -void -filepackages_iter_free(struct filepackages_iterator *iter) -{ - free(iter); -} - /*** Generic data structures and routines. ***/ static bool allpackagesdone = false; -static int nfiles= 0; void ensure_package_clientdata(struct pkginfo *pkg) @@ -473,174 +435,3 @@ write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin, note_must_reread_files_inpackage(pkg); } - -/* - * Initializes an iterator that appears to go through the file - * list ‘files’ in reverse order, returning the namenode from - * each. What actually happens is that we walk the list here, - * building up a reverse list, and then peel it apart one - * entry at a time. - */ -void -reversefilelist_init(struct reversefilelistiter *iter, struct fileinlist *files) -{ - struct fileinlist *newent; - - iter->todo = NULL; - while (files) { - newent= m_malloc(sizeof(struct fileinlist)); - newent->namenode= files->namenode; - newent->next = iter->todo; - iter->todo = newent; - files= files->next; - } -} - -struct filenamenode * -reversefilelist_next(struct reversefilelistiter *iter) -{ - struct filenamenode *ret; - struct fileinlist *todo; - - todo = iter->todo; - if (!todo) - return NULL; - ret= todo->namenode; - iter->todo = todo->next; - free(todo); - return ret; -} - -/* - * Clients must call this function to clean up the reversefilelistiter - * if they wish to break out of the iteration before it is all done. - * Calling this function is not necessary if reversefilelist_next has - * been called until it returned 0. - */ -void -reversefilelist_abort(struct reversefilelistiter *iter) -{ - while (reversefilelist_next(iter)); -} - -struct fileiterator { - struct filenamenode *namenode; - int nbinn; -}; - -/* This must always be a prime for optimal performance. - * This is the closest one to 2^18 (262144). */ -#define BINS 262139 - -static struct filenamenode *bins[BINS]; - -struct fileiterator * -files_db_iter_new(void) -{ - struct fileiterator *iter; - - iter = m_malloc(sizeof(struct fileiterator)); - iter->namenode = NULL; - iter->nbinn = 0; - - return iter; -} - -struct filenamenode * -files_db_iter_next(struct fileiterator *iter) -{ - struct filenamenode *r= NULL; - - while (!iter->namenode) { - if (iter->nbinn >= BINS) - return NULL; - iter->namenode = bins[iter->nbinn++]; - } - r = iter->namenode; - iter->namenode = r->next; - - return r; -} - -void -files_db_iter_free(struct fileiterator *iter) -{ - free(iter); -} - -void filesdbinit(void) { - struct filenamenode *fnn; - int i; - - for (i=0; i<BINS; i++) - for (fnn= bins[i]; fnn; fnn= fnn->next) { - fnn->flags= 0; - fnn->oldhash = NULL; - fnn->newhash = EMPTYHASHFLAG; - fnn->filestat = NULL; - } -} - -void -files_db_reset(void) -{ - int i; - - for (i = 0; i < BINS; i++) - bins[i] = NULL; -} - -int -fsys_hash_entries(void) -{ - return nfiles; -} - -struct filenamenode *findnamenode(const char *name, enum fnnflags flags) { - struct filenamenode **pointerp, *newnode; - const char *orig_name = name; - - /* We skip initial slashes and ‘./’ pairs, and add our own single - * leading slash. */ - name = path_skip_slash_dotslash(name); - - pointerp = bins + (str_fnv_hash(name) % (BINS)); - while (*pointerp) { - /* XXX: This should not be needed, but it has been a constant source - * of assertions over the years. Hopefully with the internerr() we will - * get better diagnostics. */ - if ((*pointerp)->name[0] != '/') - internerr("filename node '%s' does not start with '/'", - (*pointerp)->name); - - if (strcmp((*pointerp)->name + 1, name) == 0) - break; - pointerp= &(*pointerp)->next; - } - if (*pointerp) return *pointerp; - - if (flags & fnn_nonew) - return NULL; - - newnode= nfmalloc(sizeof(struct filenamenode)); - newnode->packages = NULL; - if((flags & fnn_nocopy) && name > orig_name && name[-1] == '/') - newnode->name = name - 1; - else { - char *newname= nfmalloc(strlen(name)+2); - newname[0]= '/'; strcpy(newname+1,name); - newnode->name= newname; - } - newnode->flags= 0; - newnode->next = NULL; - newnode->divert = NULL; - newnode->statoverride = NULL; - newnode->oldhash = NULL; - newnode->newhash = EMPTYHASHFLAG; - newnode->filestat = NULL; - newnode->trig_interested = NULL; - *pointerp= newnode; - nfiles++; - - return newnode; -} diff --git a/src/filesdb.h b/src/filesdb.h index 6a7c6afee..4fbe6b0a7 100644 --- a/src/filesdb.h +++ b/src/filesdb.h @@ -23,6 +23,7 @@ #define FILESDB_H #include <dpkg/file.h> +#include <dpkg/fsys.h> /* * Data structure here is as follows: @@ -46,120 +47,6 @@ struct pkginfo; -/** - * Flags to findnamenode(). - */ -enum fnnflags { - /** Do not need to copy filename. */ - fnn_nocopy = DPKG_BIT(0), - /** findnamenode may return NULL. */ - fnn_nonew = DPKG_BIT(1), -}; - -enum filenamenode_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), -}; - -struct filenamenode { - struct filenamenode *next; - const char *name; - struct pkg_list *packages; - struct 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; - - /* - * Fields from here on are used by archives.c &c, and cleared by - * filesdbinit. - */ - - /** Set to zero when a new node is created. */ - enum filenamenode_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 stat *filestat; - struct trigfileint *trig_interested; -}; - -struct fileinlist { - struct fileinlist *next; - struct filenamenode *namenode; -}; - -/** - * Queue of filenamenode entries. - */ -struct filenamenode_queue { - struct fileinlist *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 filenamenode has an diversion entry with - * useinstead set to point to the redirected filename's filenamenode; the - * redirected filenamenode has camefrom set to the contested filenamenode. - * 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 filenamenode in their per-file package lists (both in core and - * on disk). References are redirected to the other filenamenode's filename - * where appropriate. - */ -struct diversion { - struct filenamenode *useinstead; - struct filenamenode *camefrom; - struct pkgset *pkgset; - - /** The ‘contested’ halves are in this list for easy cleanup. */ - struct diversion *next; -}; - -struct filepackages_iterator; -struct filepackages_iterator *filepackages_iter_new(struct filenamenode *fnn); -struct pkginfo *filepackages_iter_next(struct filepackages_iterator *iter); -void filepackages_iter_free(struct filepackages_iterator *iter); - -void filesdbinit(void); -void files_db_reset(void); -int fsys_hash_entries(void); - -struct fileiterator; -struct fileiterator *files_db_iter_new(void); -struct filenamenode *files_db_iter_next(struct fileiterator *iter); -void files_db_iter_free(struct fileiterator *iter); - void ensure_package_clientdata(struct pkginfo *pkg); void ensure_diversions(void); @@ -181,17 +68,10 @@ void ensure_packagefiles_available(struct pkginfo *pkg); void ensure_allinstfiles_available(void); void ensure_allinstfiles_available_quiet(void); void note_must_reread_files_inpackage(struct pkginfo *pkg); -struct filenamenode *findnamenode(const char *filename, enum fnnflags flags); void parse_filehash(struct pkginfo *pkg, struct pkgbin *pkgbin); void write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin, struct fileinlist *list, enum filenamenode_flags mask); void write_filehash_except(struct pkginfo *pkg, struct pkgbin *pkgbin, struct fileinlist *list, enum filenamenode_flags mask); -struct reversefilelistiter { struct fileinlist *todo; }; - -void reversefilelist_init(struct reversefilelistiter *iterptr, struct fileinlist *files); -struct filenamenode *reversefilelist_next(struct reversefilelistiter *iterptr); -void reversefilelist_abort(struct reversefilelistiter *iterptr); - #endif /* FILESDB_H */ |