test: Fix varbuf memory leak in t-pkg-format test
[dpkg.git] / src / common / force.c
blobc4401f0d6a1f8f58dcbdc5a79cc9f9fa09605cb3
1 /*
2 * dpkg - main program for package management
3 * force.c - force operation support
5 * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2006-2019 Guillem Jover <guillem@debian.org>
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 #include <config.h>
23 #include <compat.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <stdbool.h>
28 #include <stdarg.h>
29 #include <stdlib.h>
30 #include <stdio.h>
32 #include <dpkg/macros.h>
33 #include <dpkg/i18n.h>
34 #include <dpkg/dpkg.h>
35 #include <dpkg/dpkg-db.h>
36 #include <dpkg/options.h>
38 #include "force.h"
40 static int force_mask;
41 static int force_flags;
43 enum forcetype {
44 FORCETYPE_DISABLED,
45 FORCETYPE_ENABLED,
46 FORCETYPE_DAMAGE,
49 static const char *
50 forcetype_str(enum forcetype type)
52 switch (type) {
53 case FORCETYPE_DISABLED:
54 return " ";
55 case FORCETYPE_ENABLED:
56 return "[*]";
57 case FORCETYPE_DAMAGE:
58 return "[!]";
59 default:
60 internerr("unknown force type '%d'", type);
64 static const struct forceinfo {
65 const char *name;
66 int flag;
67 char type;
68 const char *desc;
69 } forceinfos[] = {
71 "all",
72 FORCE_ALL,
73 FORCETYPE_DAMAGE,
74 N_("Set all force options"),
75 }, {
76 "security-mac",
77 FORCE_SECURITY_MAC,
78 FORCETYPE_ENABLED,
79 N_("Use MAC based security if available"),
80 }, {
81 "downgrade",
82 FORCE_DOWNGRADE,
83 FORCETYPE_ENABLED,
84 N_("Replace a package with a lower version"),
85 }, {
86 "configure-any",
87 FORCE_CONFIGURE_ANY,
88 FORCETYPE_DISABLED,
89 N_("Configure any package which may help this one"),
90 }, {
91 "hold",
92 FORCE_HOLD,
93 FORCETYPE_DISABLED,
94 N_("Install or remove incidental packages even when on hold"),
95 }, {
96 "not-root",
97 FORCE_NON_ROOT,
98 FORCETYPE_DISABLED,
99 N_("Try to (de)install things even when not root"),
100 }, {
101 "bad-path",
102 FORCE_BAD_PATH,
103 FORCETYPE_DISABLED,
104 N_("PATH is missing important programs, problems likely"),
105 }, {
106 "bad-verify",
107 FORCE_BAD_VERIFY,
108 FORCETYPE_DISABLED,
109 N_("Install a package even if it fails authenticity check"),
110 }, {
111 "bad-version",
112 FORCE_BAD_VERSION,
113 FORCETYPE_DISABLED,
114 N_("Process even packages with wrong versions"),
115 }, {
116 "statoverride-add",
117 FORCE_STATOVERRIDE_ADD,
118 FORCETYPE_DISABLED,
119 N_("Overwrite an existing stat override when adding it"),
120 }, {
121 "statoverride-remove",
122 FORCE_STATOVERRIDE_DEL,
123 FORCETYPE_DISABLED,
124 N_("Ignore a missing stat override when removing it"),
125 }, {
126 "overwrite",
127 FORCE_OVERWRITE,
128 FORCETYPE_DISABLED,
129 N_("Overwrite a file from one package with another"),
130 }, {
131 "overwrite-diverted",
132 FORCE_OVERWRITE_DIVERTED,
133 FORCETYPE_DISABLED,
134 N_("Overwrite a diverted file with an undiverted version"),
135 }, {
136 "overwrite-dir",
137 FORCE_OVERWRITE_DIR,
138 FORCETYPE_DAMAGE,
139 N_("Overwrite one package's directory with another's file"),
140 }, {
141 "unsafe-io",
142 FORCE_UNSAFE_IO,
143 FORCETYPE_DAMAGE,
144 N_("Do not perform safe I/O operations when unpacking"),
145 }, {
146 "script-chrootless",
147 FORCE_SCRIPT_CHROOTLESS,
148 FORCETYPE_DAMAGE,
149 N_("Do not chroot into maintainer script environment"),
150 }, {
151 "confnew",
152 FORCE_CONFF_NEW,
153 FORCETYPE_DAMAGE,
154 N_("Always use the new config files, don't prompt"),
155 }, {
156 "confold",
157 FORCE_CONFF_OLD,
158 FORCETYPE_DAMAGE,
159 N_("Always use the old config files, don't prompt"),
160 }, {
161 "confdef",
162 FORCE_CONFF_DEF,
163 FORCETYPE_DAMAGE,
164 N_("Use the default option for new config files if one\n"
165 "is available, don't prompt. If no default can be found,\n"
166 "you will be prompted unless one of the confold or\n"
167 "confnew options is also given"),
168 }, {
169 "confmiss",
170 FORCE_CONFF_MISS,
171 FORCETYPE_DAMAGE,
172 N_("Always install missing config files"),
173 }, {
174 "confask",
175 FORCE_CONFF_ASK,
176 FORCETYPE_DAMAGE,
177 N_("Offer to replace config files with no new versions"),
178 }, {
179 "architecture",
180 FORCE_ARCHITECTURE,
181 FORCETYPE_DAMAGE,
182 N_("Process even packages with wrong or no architecture"),
183 }, {
184 "breaks",
185 FORCE_BREAKS,
186 FORCETYPE_DAMAGE,
187 N_("Install even if it would break another package"),
188 }, {
189 "conflicts",
190 FORCE_CONFLICTS,
191 FORCETYPE_DAMAGE,
192 N_("Allow installation of conflicting packages"),
193 }, {
194 "depends",
195 FORCE_DEPENDS,
196 FORCETYPE_DAMAGE,
197 N_("Turn all dependency problems into warnings"),
198 }, {
199 "depends-version",
200 FORCE_DEPENDS_VERSION,
201 FORCETYPE_DAMAGE,
202 N_("Turn dependency version problems into warnings"),
203 }, {
204 "remove-reinstreq",
205 FORCE_REMOVE_REINSTREQ,
206 FORCETYPE_DAMAGE,
207 N_("Remove packages which require installation"),
208 }, {
209 "remove-protected",
210 FORCE_REMOVE_PROTECTED,
211 FORCETYPE_DAMAGE,
212 N_("Remove a protected package"),
213 }, {
214 "remove-essential",
215 FORCE_REMOVE_ESSENTIAL,
216 FORCETYPE_DAMAGE,
217 N_("Remove an essential package"),
218 }, {
219 NULL
223 bool
224 in_force(int flags)
226 return (flags & force_flags) == flags;
229 void
230 set_force(int flags)
232 force_flags |= flags;
235 void
236 reset_force(int flags)
238 force_flags &= ~flags;
241 char *
242 get_force_string(void)
244 const struct forceinfo *fip;
245 struct varbuf vb = VARBUF_INIT;
247 for (fip = forceinfos; fip->name; fip++) {
248 if ((enum force_flags)fip->flag == FORCE_ALL ||
249 (fip->flag & force_mask) != fip->flag ||
250 !in_force(fip->flag))
251 continue;
253 if (vb.used)
254 varbuf_add_char(&vb, ',');
255 varbuf_add_str(&vb, fip->name);
257 varbuf_end_str(&vb);
259 return varbuf_detach(&vb);
262 static inline void
263 print_forceinfo_line(int type, const char *name, const char *desc)
265 printf(" %s %-18s %s\n", forcetype_str(type), name, desc);
268 static void
269 print_forceinfo(const struct forceinfo *fi)
271 char *desc, *line;
273 desc = m_strdup(gettext(fi->desc));
275 line = strtok(desc, "\n");
276 print_forceinfo_line(fi->type, fi->name, line);
277 while ((line = strtok(NULL, "\n")))
278 print_forceinfo_line(FORCETYPE_DISABLED, "", line);
280 free(desc);
283 void
284 parse_force(const char *value, bool set)
286 const struct forceinfo *fip;
288 if (strcmp(value, "help") == 0) {
289 char *force_string = get_force_string();
291 printf(_(
292 "%s forcing options - control behavior when problems found:\n"
293 " warn but continue: --force-<thing>,<thing>,...\n"
294 " stop with error: --refuse-<thing>,<thing>,... | --no-force-<thing>,...\n"
295 " Forcing things:\n"), dpkg_get_progname());
297 for (fip = forceinfos; fip->name; fip++)
298 if ((enum force_flags)fip->flag == FORCE_ALL ||
299 (fip->flag & force_mask) == fip->flag)
300 print_forceinfo(fip);
302 printf(_(
303 "\n"
304 "WARNING - use of options marked [!] can seriously damage your installation.\n"
305 "Forcing options marked [*] are enabled by default.\n"));
306 m_output(stdout, _("<standard output>"));
308 printf(_(
309 "\n"
310 "Currently enabled options:\n"
311 " %s\n"), force_string);
313 free(force_string);
315 exit(0);
318 for (;;) {
319 const char *comma;
320 size_t l;
322 comma = strchrnul(value, ',');
323 l = (size_t)(comma - value);
324 for (fip = forceinfos; fip->name; fip++)
325 if (strncmp(fip->name, value, l) == 0 &&
326 strlen(fip->name) == l)
327 break;
329 if (!fip->name) {
330 badusage(_("unknown force/refuse option '%.*s'"),
331 (int)min(l, 250), value);
332 } else if (fip->flag) {
333 if (set)
334 set_force(fip->flag);
335 else
336 reset_force(fip->flag);
337 } else {
338 warning(_("obsolete force/refuse option '%s'"),
339 fip->name);
342 if (*comma == '\0')
343 break;
344 value = ++comma;
348 void
349 set_force_default(int mask)
351 const char *force_env;
352 const struct forceinfo *fip;
354 force_mask = mask;
356 /* If we get passed force options from the environment, do not
357 * initialize from the built-in defaults. */
358 force_env = getenv("DPKG_FORCE");
359 if (force_env != NULL) {
360 if (force_env[0] != '\0')
361 parse_force(force_env, 1);
362 return;
365 for (fip = forceinfos; fip->name; fip++)
366 if (fip->type == FORCETYPE_ENABLED)
367 set_force(fip->flag);
370 void
371 set_force_option(const struct cmdinfo *cip, const char *value)
373 bool set = cip->arg_int;
375 parse_force(value, set);
378 void
379 reset_force_option(const struct cmdinfo *cip, const char *value)
381 reset_force(cip->arg_int);
384 void
385 forcibleerr(int forceflag, const char *fmt, ...)
387 va_list args;
389 va_start(args, fmt);
390 if (in_force(forceflag)) {
391 warning(_("overriding problem because --force enabled:"));
392 warningv(fmt, args);
393 } else {
394 ohshitv(fmt, args);
396 va_end(args);
400 forcible_nonroot_error(int rc)
402 if (in_force(FORCE_NON_ROOT) && errno == EPERM)
403 return 0;
404 return rc;