From 941f8c810fd050c91a18a6c7ead6b34c8d12ead3 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Sun, 1 Jun 2014 01:31:33 +0200 Subject: dpkg: Factor out deb_parse_conffiles() from process_archive() --- src/unpack.c | 177 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 74 deletions(-) (limited to 'src') diff --git a/src/unpack.c b/src/unpack.c index 8f5b38f7d..943287d42 100644 --- a/src/unpack.c +++ b/src/unpack.c @@ -197,6 +197,106 @@ get_control_dir(char *cidir) return cidir; } +/** + * Read the conffiles, and copy the hashes across. + */ +static void +deb_parse_conffiles(struct pkginfo *pkg, const char *control_conffiles, + struct filenamenode_queue *newconffiles) +{ + FILE *conff; + char conffilenamebuf[MAXCONFFILENAME]; + + conff = fopen(control_conffiles, "r"); + if (conff == NULL) { + if (errno == ENOENT) + return; + ohshite(_("error trying to open %.250s"), control_conffiles); + } + + push_cleanup(cu_closestream, ehflag_bombout, NULL, 0, 1, conff); + + while (fgets(conffilenamebuf, MAXCONFFILENAME - 2, conff)) { + struct pkginfo *otherpkg; + struct filepackages_iterator *iter; + struct filenamenode *namenode; + struct fileinlist *newconff; + struct conffile *searchconff; + char *p; + + p = conffilenamebuf + strlen(conffilenamebuf); + assert(p != conffilenamebuf); + if (p[-1] != '\n') + ohshit(_("conffile name '%s' is too long, or missing final newline"), + conffilenamebuf); + while (p > conffilenamebuf && isspace(p[-1])) + --p; + if (p == conffilenamebuf) + continue; + *p = '\0'; + + namenode = findnamenode(conffilenamebuf, 0); + namenode->oldhash = NEWCONFFILEFLAG; + newconff = filenamenode_queue_push(newconffiles, namenode); + + /* + * Let's see if any packages have this file. + * + * If they do we check to see if they listed it as a conffile, + * and if they did we copy the hash across. Since (for plain + * file conffiles, which is the only kind we are supposed to + * have) there will only be one package which ‘has’ the file, + * this will usually mean we only look in the package which + * we are installing now. + * + * The ‘conffiles’ data in the status file is ignored when a + * package is not also listed in the file ownership database as + * having that file. If several packages are listed as owning + * the file we pick one at random. + */ + searchconff = NULL; + + iter = filepackages_iter_new(newconff->namenode); + while ((otherpkg = filepackages_iter_next(iter))) { + debug(dbg_conffdetail, + "process_archive conffile '%s' in package %s - conff ?", + newconff->namenode->name, pkg_name(otherpkg, pnaw_always)); + for (searchconff = otherpkg->installed.conffiles; + searchconff && strcmp(newconff->namenode->name, searchconff->name); + searchconff = searchconff->next) + debug(dbg_conffdetail, + "process_archive conffile '%s' in package %s - conff ? not '%s'", + newconff->namenode->name, pkg_name(otherpkg, pnaw_always), + searchconff->name); + if (searchconff) { + debug(dbg_conff, + "process_archive conffile '%s' package=%s %s hash=%s", + newconff->namenode->name, pkg_name(otherpkg, pnaw_always), + otherpkg == pkg ? "same" : "different!", + searchconff->hash); + if (otherpkg == pkg) + break; + } + } + filepackages_iter_free(iter); + + if (searchconff) { + /* We don't copy ‘obsolete’; it's not obsolete in the new package. */ + newconff->namenode->oldhash = searchconff->hash; + } else { + debug(dbg_conff, "process_archive conffile '%s' no package, no hash", + newconff->namenode->name); + } + newconff->namenode->flags |= fnnf_new_conff; + } + + if (ferror(conff)) + ohshite(_("read error in %.250s"), control_conffiles); + pop_cleanup(ehflag_normaltidy); /* conff = fopen() */ + if (fclose(conff)) + ohshite(_("error closing %.250s"), control_conffiles); +} + static struct pkg_queue conflictors = PKG_QUEUE_INIT; void @@ -421,20 +521,17 @@ void process_archive(const char *filename) { struct pkginfo *pkg, *otherpkg; struct pkg_list *conflictor_iter; char *cidir = NULL; - char *cidirrest, *p; - char conffilenamebuf[MAXCONFFILENAME]; + char *cidirrest; char *psize; const char *pfilename; struct fileinlist *newfileslist; - struct fileinlist *newconff; struct fileinlist *cfile; struct filenamenode_queue newconffiles; struct reversefilelistiter rlistit; - struct conffile *searchconff, **iconffileslastp, *newiconff; + struct conffile **iconffileslastp, *newiconff; struct dependency *dsearch, *newdeplist, **newdeplistlastp; struct dependency *newdep, *dep, *providecheck; struct deppossi *psearch, **newpossilastp, *possi, *newpossi, *pdep; - FILE *conff; struct filenamenode *namenode; struct stat stab, oldfs; struct pkg_deconf_list *deconpil; @@ -623,75 +720,7 @@ void process_archive(const char *filename) { newconffiles.tail = &newconffiles.head; push_cleanup(cu_fileslist, ~0, NULL, 0, 0); strcpy(cidirrest,CONFFILESFILE); - conff= fopen(cidir,"r"); - if (conff) { - push_cleanup(cu_closestream, ehflag_bombout, NULL, 0, 1, (void *)conff); - while (fgets(conffilenamebuf,MAXCONFFILENAME-2,conff)) { - struct filepackages_iterator *iter; - - p= conffilenamebuf + strlen(conffilenamebuf); - assert(p != conffilenamebuf); - if (p[-1] != '\n') - ohshit(_("conffile name '%s' is too long, or missing final newline"), - conffilenamebuf); - while (p > conffilenamebuf && isspace(p[-1])) --p; - if (p == conffilenamebuf) continue; - *p = '\0'; - namenode= findnamenode(conffilenamebuf, 0); - namenode->oldhash= NEWCONFFILEFLAG; - newconff = filenamenode_queue_push(&newconffiles, namenode); - - /* Let's see if any packages have this file. If they do we - * check to see if they listed it as a conffile, and if they did - * we copy the hash across. Since (for plain file conffiles, - * which is the only kind we are supposed to have) there will - * only be one package which ‘has’ the file, this will usually - * mean we only look in the package which we're installing now. - * The ‘conffiles’ data in the status file is ignored when a - * package isn't also listed in the file ownership database as - * having that file. If several packages are listed as owning - * the file we pick one at random. */ - searchconff = NULL; - - iter = filepackages_iter_new(newconff->namenode); - while ((otherpkg = filepackages_iter_next(iter))) { - debug(dbg_conffdetail, - "process_archive conffile '%s' in package %s - conff ?", - newconff->namenode->name, pkg_name(otherpkg, pnaw_always)); - for (searchconff = otherpkg->installed.conffiles; - searchconff && strcmp(newconff->namenode->name, searchconff->name); - searchconff = searchconff->next) - debug(dbg_conffdetail, - "process_archive conffile '%s' in package %s - conff ? not '%s'", - newconff->namenode->name, pkg_name(otherpkg, pnaw_always), - searchconff->name); - if (searchconff) { - debug(dbg_conff, - "process_archive conffile '%s' package=%s %s hash=%s", - newconff->namenode->name, pkg_name(otherpkg, pnaw_always), - otherpkg == pkg ? "same" : "different!", - searchconff->hash); - if (otherpkg == pkg) - break; - } - } - filepackages_iter_free(iter); - - if (searchconff) { - newconff->namenode->oldhash= searchconff->hash; - /* We don't copy ‘obsolete’; it's not obsolete in the new package. */ - } else { - debug(dbg_conff, "process_archive conffile '%s' no package, no hash", - newconff->namenode->name); - } - newconff->namenode->flags |= fnnf_new_conff; - } - if (ferror(conff)) ohshite(_("read error in %.250s"),cidir); - pop_cleanup(ehflag_normaltidy); /* conff = fopen() */ - if (fclose(conff)) ohshite(_("error closing %.250s"),cidir); - } else { - if (errno != ENOENT) ohshite(_("error trying to open %.250s"),cidir); - } + deb_parse_conffiles(pkg, cidir, &newconffiles); /* All the old conffiles are marked with a flag, so that we don't delete * them if they seem to disappear completely. */ -- cgit v1.2.3