po: Update German man pages translation
[dpkg.git] / src / main / script.c
blobe9aee0bf92b1730204f0658f62d97d9abe7023bd
1 /*
2 * dpkg - main program for package management
3 * script.c - maintainer script routines
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2007-2014 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 <sys/types.h>
26 #include <sys/stat.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <stdlib.h>
33 #ifdef WITH_LIBSELINUX
34 #include <selinux/selinux.h>
35 #endif
37 #include <dpkg/i18n.h>
38 #include <dpkg/debug.h>
39 #include <dpkg/dpkg.h>
40 #include <dpkg/dpkg-db.h>
41 #include <dpkg/pkg.h>
42 #include <dpkg/subproc.h>
43 #include <dpkg/command.h>
44 #include <dpkg/triglib.h>
45 #include <dpkg/db-ctrl.h>
46 #include <dpkg/db-fsys.h>
48 #include "main.h"
50 void
51 post_postinst_tasks(struct pkginfo *pkg, enum pkgstatus new_status)
53 if (new_status < PKG_STAT_TRIGGERSAWAITED)
54 pkg_set_status(pkg, new_status);
55 else if (pkg->trigaw.head)
56 pkg_set_status(pkg, PKG_STAT_TRIGGERSAWAITED);
57 else if (pkg->trigpend_head)
58 pkg_set_status(pkg, PKG_STAT_TRIGGERSPENDING);
59 else
60 pkg_set_status(pkg, PKG_STAT_INSTALLED);
61 modstatdb_note(pkg);
63 debug(dbg_triggersdetail, "post_postinst_tasks - trig_incorporate");
64 trig_incorporate(modstatdb_get_status());
67 static void
68 post_script_tasks(void)
70 debug(dbg_triggersdetail, "post_script_tasks - ensure_diversions");
71 ensure_diversions();
73 debug(dbg_triggersdetail, "post_script_tasks - trig_incorporate");
74 trig_incorporate(modstatdb_get_status());
77 static void
78 cu_post_script_tasks(int argc, void **argv)
80 post_script_tasks();
83 static void
84 setexecute(const char *path, struct stat *stab)
86 if ((stab->st_mode & 0555) == 0555)
87 return;
88 if (!chmod(path, 0755))
89 return;
90 ohshite(_("unable to set execute permissions on '%.250s'"), path);
93 /**
94 * Returns the path to the script inside the chroot.
96 static const char *
97 maintscript_pre_exec(struct command *cmd)
99 const char *instdir = dpkg_fsys_get_dir();
100 const char *admindir = dpkg_db_get_dir();
101 const char *changedir;
102 size_t instdirlen = strlen(instdir);
104 if (instdirlen > 0 && in_force(FORCE_SCRIPT_CHROOTLESS))
105 changedir = instdir;
106 else
107 changedir = "/";
109 if (instdirlen > 0 && !in_force(FORCE_SCRIPT_CHROOTLESS)) {
110 int rc;
112 if (strncmp(admindir, instdir, instdirlen) != 0)
113 ohshit(_("admindir must be inside instdir for dpkg to work properly"));
114 if (setenv("DPKG_ADMINDIR", admindir + instdirlen, 1) < 0)
115 ohshite(_("unable to setenv for subprocesses"));
116 if (setenv("DPKG_ROOT", "", 1) < 0)
117 ohshite(_("unable to setenv for subprocesses"));
119 rc = chroot(instdir);
120 if (rc && in_force(FORCE_NON_ROOT) && errno == EPERM)
121 ohshit(_("not enough privileges to change root "
122 "directory with --force-not-root, consider "
123 "using --force-script-chrootless?"));
124 else if (rc)
125 ohshite(_("failed to chroot to '%.250s'"), instdir);
127 /* Switch to a known good directory to give the maintainer script
128 * a saner environment, also needed after the chroot(). */
129 if (chdir(changedir))
130 ohshite(_("failed to chdir to '%.255s'"), changedir);
131 if (debug_has_flag(dbg_scripts)) {
132 struct varbuf args = VARBUF_INIT;
133 const char **argv = cmd->argv;
135 while (*++argv) {
136 varbuf_add_char(&args, ' ');
137 varbuf_add_str(&args, *argv);
139 debug(dbg_scripts, "fork/exec %s (%s )", cmd->filename,
140 varbuf_str(&args));
141 varbuf_destroy(&args);
143 if (instdirlen == 0 || in_force(FORCE_SCRIPT_CHROOTLESS))
144 return cmd->filename;
146 if (strlen(cmd->filename) < instdirlen)
147 internerr("maintscript name '%s' length < instdir length %zd",
148 cmd->filename, instdirlen);
150 return cmd->filename + instdirlen;
154 * Set a new security execution context for the maintainer script.
156 * Try to create a new execution context based on the current one and the
157 * specific maintainer script filename. If it's the same as the current
158 * one, use the given fallback.
160 static int
161 maintscript_set_exec_context(struct command *cmd)
163 #ifdef WITH_LIBSELINUX
164 return setexecfilecon(cmd->filename, "dpkg_script_t");
165 #else
166 return 0;
167 #endif
170 static int
171 maintscript_exec(struct pkginfo *pkg, struct pkgbin *pkgbin,
172 struct command *cmd, struct stat *stab, int warn)
174 pid_t pid;
175 int rc;
177 setexecute(cmd->filename, stab);
179 push_cleanup(cu_post_script_tasks, ehflag_bombout, 0);
181 pid = subproc_fork();
182 if (pid == 0) {
183 char *pkg_count;
184 const char *maintscript_debug;
186 pkg_count = str_fmt("%d", pkgset_installed_instances(pkg->set));
188 maintscript_debug = debug_has_flag(dbg_scripts) ? "1" : "0";
190 if (setenv("DPKG_MAINTSCRIPT_PACKAGE", pkg->set->name, 1) ||
191 setenv("DPKG_MAINTSCRIPT_PACKAGE_REFCOUNT", pkg_count, 1) ||
192 setenv("DPKG_MAINTSCRIPT_ARCH", pkgbin->arch->name, 1) ||
193 setenv("DPKG_MAINTSCRIPT_NAME", cmd->argv[0], 1) ||
194 setenv("DPKG_MAINTSCRIPT_DEBUG", maintscript_debug, 1) ||
195 setenv("DPKG_RUNNING_VERSION", PACKAGE_VERSION, 1))
196 ohshite(_("unable to setenv for maintainer script"));
198 cmd->filename = cmd->argv[0] = maintscript_pre_exec(cmd);
200 if (maintscript_set_exec_context(cmd) < 0)
201 ohshite(_("cannot set security execution context for "
202 "maintainer script"));
204 command_exec(cmd);
206 subproc_signals_ignore(cmd->name);
207 rc = subproc_reap(pid, cmd->name, warn);
208 subproc_signals_restore();
210 pop_cleanup(ehflag_normaltidy);
212 return rc;
215 static int
216 vmaintscript_installed(struct pkginfo *pkg, const char *scriptname,
217 const char *desc, va_list args)
219 struct command cmd;
220 const char *scriptpath;
221 struct stat stab;
222 char *buf;
224 scriptpath = pkg_infodb_get_file(pkg, &pkg->installed, scriptname);
225 m_asprintf(&buf, _("installed %s package %s script"),
226 pkg_name(pkg, pnaw_nonambig), desc);
228 command_init(&cmd, scriptpath, buf);
229 command_add_arg(&cmd, scriptname);
230 command_add_argv(&cmd, args);
232 if (stat(scriptpath, &stab)) {
233 command_destroy(&cmd);
235 if (errno == ENOENT) {
236 debug(dbg_scripts,
237 "vmaintscript_installed nonexistent %s",
238 scriptname);
239 free(buf);
240 return 0;
242 ohshite(_("unable to stat %s '%.250s'"), buf, scriptpath);
244 maintscript_exec(pkg, &pkg->installed, &cmd, &stab, 0);
246 command_destroy(&cmd);
247 free(buf);
249 return 1;
253 * All ...'s in maintscript_* are const char *'s.
257 maintscript_installed(struct pkginfo *pkg, const char *scriptname,
258 const char *desc, ...)
260 va_list args;
261 int rc;
263 va_start(args, desc);
264 rc = vmaintscript_installed(pkg, scriptname, desc, args);
265 va_end(args);
267 if (rc)
268 post_script_tasks();
270 return rc;
274 maintscript_postinst(struct pkginfo *pkg, ...)
276 va_list args;
277 int rc;
279 va_start(args, pkg);
280 rc = vmaintscript_installed(pkg, POSTINSTFILE, "post-installation", args);
281 va_end(args);
283 if (rc)
284 ensure_diversions();
286 return rc;
290 maintscript_new(struct pkginfo *pkg, const char *scriptname,
291 const char *desc, const char *cidir, char *cidirrest, ...)
293 struct command cmd;
294 struct stat stab;
295 va_list args;
296 char *buf;
298 strcpy(cidirrest, scriptname);
299 m_asprintf(&buf, _("new %s package %s script"),
300 pkg_name(pkg, pnaw_nonambig), desc);
302 va_start(args, cidirrest);
303 command_init(&cmd, cidir, buf);
304 command_add_arg(&cmd, scriptname);
305 command_add_argv(&cmd, args);
306 va_end(args);
308 if (stat(cidir, &stab)) {
309 command_destroy(&cmd);
311 if (errno == ENOENT) {
312 debug(dbg_scripts,
313 "maintscript_new nonexistent %s '%s'",
314 scriptname, cidir);
315 free(buf);
316 return 0;
318 ohshite(_("unable to stat %s '%.250s'"), buf, cidir);
320 maintscript_exec(pkg, &pkg->available, &cmd, &stab, 0);
322 command_destroy(&cmd);
323 free(buf);
324 post_script_tasks();
326 return 1;
330 maintscript_fallback(struct pkginfo *pkg,
331 const char *scriptname, const char *desc,
332 const char *cidir, char *cidirrest,
333 const char *ifok, const char *iffallback)
335 struct command cmd;
336 const char *oldscriptpath;
337 struct stat stab;
338 char *buf;
340 oldscriptpath = pkg_infodb_get_file(pkg, &pkg->installed, scriptname);
341 m_asprintf(&buf, _("old %s package %s script"),
342 pkg_name(pkg, pnaw_nonambig), desc);
344 command_init(&cmd, oldscriptpath, buf);
345 command_add_args(&cmd, scriptname, ifok,
346 versiondescribe(&pkg->available.version, vdew_nonambig),
347 NULL);
349 if (stat(oldscriptpath, &stab)) {
350 if (errno == ENOENT) {
351 debug(dbg_scripts,
352 "maintscript_fallback nonexistent %s '%s'",
353 scriptname, oldscriptpath);
354 command_destroy(&cmd);
355 free(buf);
356 return 0;
358 warning(_("unable to stat %s '%.250s': %s"),
359 cmd.name, oldscriptpath, strerror(errno));
360 } else if (!maintscript_exec(pkg, &pkg->installed, &cmd, &stab, SUBPROC_WARN)) {
361 command_destroy(&cmd);
362 free(buf);
363 post_script_tasks();
364 return 1;
366 notice(_("trying script from the new package instead ..."));
368 strcpy(cidirrest, scriptname);
369 m_asprintf(&buf, _("new %s package %s script"),
370 pkg_name(pkg, pnaw_nonambig), desc);
372 command_destroy(&cmd);
373 command_init(&cmd, cidir, buf);
374 command_add_args(&cmd, scriptname, iffallback,
375 versiondescribe(&pkg->installed.version, vdew_nonambig),
376 versiondescribe(&pkg->available.version, vdew_nonambig),
377 NULL);
379 if (stat(cidir, &stab)) {
380 command_destroy(&cmd);
382 if (errno == ENOENT)
383 ohshit(_("there is no script in the new version of the package - giving up"));
384 else
385 ohshite(_("unable to stat %s '%.250s'"), buf, cidir);
388 maintscript_exec(pkg, &pkg->available, &cmd, &stab, 0);
389 notice(_("... it looks like that went OK"));
391 command_destroy(&cmd);
392 free(buf);
393 post_script_tasks();
395 return 1;