diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/filesdb.c | 209 | ||||
-rw-r--r-- | src/filesdb.h | 122 |
2 files changed, 1 insertions, 330 deletions
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 */ |