blob: c8c0103b257e1e218d9cb9af6c013c8c6209b674 [file] [log] [blame]
/*
* dpkg - main program for package management
* divertdb.c - management of database of diverted files
*
* Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
* Copyright © 2000, 2001 Wichert Akkerman <wakkerma@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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <compat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <dpkg/i18n.h>
#include <dpkg/dpkg.h>
#include <dpkg/dpkg-db.h>
#include "filesdb.h"
#include "main.h"
static struct diversion *diversions = NULL;
static FILE *diversionsfile = NULL;
static char *diversionsname;
void
ensure_diversions(void)
{
struct stat stab1, stab2;
char linebuf[MAXDIVERTFILENAME];
FILE *file;
struct diversion *ov, *oicontest, *oialtname;
if (diversionsname != NULL)
free(diversionsname);
diversionsname = dpkg_db_get_path(DIVERSIONSFILE);
onerr_abort++;
file = fopen(diversionsname, "r");
if (!file) {
if (errno != ENOENT)
ohshite(_("failed to open diversions file"));
if (!diversionsfile) {
onerr_abort--;
return;
}
} else if (diversionsfile) {
if (fstat(fileno(diversionsfile), &stab1))
ohshite(_("failed to fstat previous diversions file"));
if (fstat(fileno(file), &stab2))
ohshite(_("failed to fstat diversions file"));
if (stab1.st_dev == stab2.st_dev &&
stab1.st_ino == stab2.st_ino) {
fclose(file);
onerr_abort--;
return;
}
}
if (diversionsfile)
fclose(diversionsfile);
diversionsfile = file;
setcloexec(fileno(diversionsfile), diversionsname);
for (ov = diversions; ov; ov = ov->next) {
ov->useinstead->divert->camefrom->divert = NULL;
ov->useinstead->divert = NULL;
}
diversions = NULL;
if (!file) {
onerr_abort--;
return;
}
while (fgets_checked(linebuf, sizeof(linebuf), file, diversionsname) >= 0) {
oicontest = nfmalloc(sizeof(struct diversion));
oialtname = nfmalloc(sizeof(struct diversion));
oialtname->camefrom = findnamenode(linebuf, 0);
oialtname->useinstead = NULL;
fgets_must(linebuf, sizeof(linebuf), file, diversionsname);
oicontest->useinstead = findnamenode(linebuf, 0);
oicontest->camefrom = NULL;
fgets_must(linebuf, sizeof(linebuf), file, diversionsname);
oicontest->pkg = oialtname->pkg = strcmp(linebuf, ":") ?
pkg_db_find(linebuf) : NULL;
if (oialtname->camefrom->divert ||
oicontest->useinstead->divert)
ohshit(_("conflicting diversions involving `%.250s' or `%.250s'"),
oialtname->camefrom->name, oicontest->useinstead->name);
oialtname->camefrom->divert = oicontest;
oicontest->useinstead->divert = oialtname;
oicontest->next = diversions;
diversions = oicontest;
}
onerr_abort--;
}