1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/*
* 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--;
}
|