2 * dpkg - main program for package management
3 * configure.c - configure packages
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 1999, 2002 Wichert Akkerman <wichert@deephackmode.org>
7 * Copyright © 2007-2015 Guillem Jover <guillem@debian.org>
8 * Copyright © 2011 Linaro Limited
9 * Copyright © 2011 Raphaël Hertzog <hertzog@debian.org>
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
28 #include <sys/types.h>
44 #include <dpkg/macros.h>
45 #include <dpkg/i18n.h>
46 #include <dpkg/dpkg.h>
47 #include <dpkg/dpkg-db.h>
49 #include <dpkg/string.h>
50 #include <dpkg/buffer.h>
51 #include <dpkg/file.h>
52 #include <dpkg/path.h>
53 #include <dpkg/subproc.h>
54 #include <dpkg/command.h>
55 #include <dpkg/pager.h>
56 #include <dpkg/triglib.h>
57 #include <dpkg/db-fsys.h>
61 enum DPKG_ATTR_ENUM_FLAGS conffopt
{
62 CFOF_PROMPT
= DPKG_BIT(0),
63 CFOF_KEEP
= DPKG_BIT(1),
64 CFOF_INSTALL
= DPKG_BIT(2),
65 CFOF_BACKUP
= DPKG_BIT(3),
66 CFOF_NEW_CONFF
= DPKG_BIT(4),
67 CFOF_IS_NEW
= DPKG_BIT(5),
68 CFOF_IS_OLD
= DPKG_BIT(6),
69 CFOF_USER_DEL
= DPKG_BIT(7),
72 CFO_IDENTICAL
= CFOF_KEEP
,
73 CFO_INSTALL
= CFOF_INSTALL
,
74 CFO_NEW_CONFF
= CFOF_NEW_CONFF
| CFOF_INSTALL
,
75 CFO_PROMPT
= CFOF_PROMPT
,
76 CFO_PROMPT_KEEP
= CFOF_PROMPT
| CFOF_KEEP
,
77 CFO_PROMPT_INSTALL
= CFOF_PROMPT
| CFOF_INSTALL
,
80 static int conffoptcells
[2][2] = {
81 /* Distro !edited. */ /* Distro edited. */
82 { CFO_KEEP
, CFO_INSTALL
}, /* User !edited. */
83 { CFO_KEEP
, CFO_PROMPT_KEEP
}, /* User edited. */
87 show_prompt(const char *cfgfile
, const char *realold
, const char *realnew
,
88 int useredited
, int distedited
, enum conffopt what
)
93 /* Flush the terminal's input in case the user involuntarily
94 * typed some characters. */
95 tcflush(STDIN_FILENO
, TCIFLUSH
);
98 if (strcmp(cfgfile
, realold
) == 0)
99 fprintf(stderr
, _("Configuration file '%s'\n"), cfgfile
);
101 fprintf(stderr
, _("Configuration file '%s' (actually '%s')\n"),
104 if (what
& CFOF_IS_NEW
) {
106 _(" ==> File on system created by you or by a script.\n"
107 " ==> File also in package provided by package maintainer.\n"));
109 fprintf(stderr
, !useredited
?
110 _(" Not modified since installation.\n") :
111 !(what
& CFOF_USER_DEL
) ?
112 _(" ==> Modified (by you or by a script) since installation.\n") :
113 _(" ==> Deleted (by you or by a script) since installation.\n"));
115 fprintf(stderr
, distedited
?
116 _(" ==> Package distributor has shipped an updated version.\n") :
117 _(" Version in package is the same as at last installation.\n"));
120 /* No --force-confdef but a forcible situation. */
121 /* TODO: check if this condition can not be simplified to
122 * just !in_force(FORCE_CONFF_DEF) */
123 if (!(in_force(FORCE_CONFF_DEF
) && (what
& (CFOF_INSTALL
| CFOF_KEEP
)))) {
124 if (in_force(FORCE_CONFF_NEW
)) {
126 _(" ==> Using new file as you requested.\n"));
128 } else if (in_force(FORCE_CONFF_OLD
)) {
130 _(" ==> Using current old file as you requested.\n"));
135 /* Force the default action (if there is one. */
136 if (in_force(FORCE_CONFF_DEF
)) {
137 if (what
& CFOF_KEEP
) {
139 _(" ==> Keeping old config file as default.\n"));
141 } else if (what
& CFOF_INSTALL
) {
143 _(" ==> Using new config file as default.\n"));
149 _(" What would you like to do about it ? Your options are:\n"
150 " Y or I : install the package maintainer's version\n"
151 " N or O : keep your currently-installed version\n"
152 " D : show the differences between the versions\n"
153 " Z : start a shell to examine the situation\n"));
155 if (what
& CFOF_KEEP
)
157 _(" The default action is to keep your current version.\n"));
158 else if (what
& CFOF_INSTALL
)
160 _(" The default action is to install the new version.\n"));
162 s
= path_basename(cfgfile
);
163 fprintf(stderr
, "*** %s (Y/I/N/O/D/Z) %s ? ", s
,
164 (what
& CFOF_KEEP
) ? _("[default=N]") :
165 (what
& CFOF_INSTALL
) ? _("[default=Y]") :
169 ohshite(_("error writing to stderr, discovered before conffile prompt"));
172 while ((c
= getchar()) != EOF
&& c
!= '\n')
173 if (!isspace(c
) && !cc
)
178 ohshite(_("read error on stdin at conffile prompt"));
179 ohshit(_("end of file on stdin at conffile prompt"));
183 if (what
& CFOF_KEEP
)
185 else if (what
& CFOF_INSTALL
)
193 * Show a diff between two files.
195 * @param old The path to the old file.
196 * @param new The path to the new file.
199 show_diff(const char *old
, const char *new)
204 pager
= pager_spawn(_("conffile difference visualizer"));
206 pid
= subproc_fork();
211 command_init(&cmd
, DIFF
, _("conffile difference visualizer"));
212 command_add_arg(&cmd
, DIFF
);
213 command_add_arg(&cmd
, "-Nu");
214 command_add_arg(&cmd
, old
);
215 command_add_arg(&cmd
, new);
219 /* Parent process. */
220 subproc_reap(pid
, _("conffile difference visualizer"), SUBPROC_NOCHECK
);
227 * Create a subprocess and execute a shell to allow the user to manually
228 * solve the conffile conflict.
230 * @param confold The path to the old conffile.
231 * @param confnew The path to the new conffile.
234 spawn_shell(const char *confold
, const char *confnew
)
238 fputs(_("Useful environment variables:\n"), stderr
);
239 fputs(" - DPKG_SHELL_REASON\n", stderr
);
240 fputs(" - DPKG_CONFFILE_OLD\n", stderr
);
241 fputs(" - DPKG_CONFFILE_NEW\n", stderr
);
242 fputs(_("Type 'exit' when you're done.\n"), stderr
);
244 pid
= subproc_fork();
246 /* Set useful variables for the user. */
247 setenv("DPKG_SHELL_REASON", "conffile-prompt", 1);
248 setenv("DPKG_CONFFILE_OLD", confold
, 1);
249 setenv("DPKG_CONFFILE_NEW", confnew
, 1);
251 command_shell(NULL
, _("conffile shell"));
254 /* Parent process. */
255 subproc_reap(pid
, _("conffile shell"), SUBPROC_NOCHECK
);
259 * Prompt the user for how to resolve a conffile conflict.
261 * When encountering a conffile conflict during configuration, the user will
262 * normally be presented with a textual menu of possible actions. This
263 * behavior is modified via various --force flags and perhaps on whether
264 * or not a terminal is available to do the prompting.
266 * @param pkg The package owning the conffile.
267 * @param cfgfile The path to the old conffile.
268 * @param realold The path to the old conffile, dereferenced in case of a
269 * symlink, otherwise equal to cfgfile.
270 * @param realnew The path to the new conffile, dereferenced in case of a
272 * @param useredited A flag to indicate whether the file has been edited
273 * locally. Set to nonzero to indicate that the file has been modified.
274 * @param distedited A flag to indicate whether the file has been updated
275 * between package versions. Set to nonzero to indicate that the file
277 * @param what Hints on what action should be taken by default.
279 * @return The action which should be taken based on user input and/or the
280 * default actions as configured by cmdline/configuration options.
283 promptconfaction(struct pkginfo
*pkg
, const char *cfgfile
,
284 const char *realold
, const char *realnew
,
285 int useredited
, int distedited
, enum conffopt what
)
289 if (!(what
& CFOF_PROMPT
))
292 statusfd_send("status: %s : %s : '%s' '%s' %i %i ",
293 cfgfile
, "conffile-prompt",
294 realold
, realnew
, useredited
, distedited
);
297 cc
= show_prompt(cfgfile
, realold
, realnew
,
298 useredited
, distedited
, what
);
300 /* FIXME: Say something if silently not install. */
302 show_diff(realold
, realnew
);
305 spawn_shell(realold
, realnew
);
306 } while (!strchr("yino", cc
));
308 log_message("conffile %s %s", cfgfile
,
309 (cc
== 'i' || cc
== 'y') ? "install" : "keep");
311 what
&= CFOF_USER_DEL
;
316 what
|= CFOF_INSTALL
| CFOF_BACKUP
;
321 what
|= CFOF_KEEP
| CFOF_BACKUP
;
325 internerr("unknown response '%d'", cc
);
332 * Configure the ghost conffile instance.
334 * When the first instance of a package set is configured, the *.dpkg-new
335 * files gets installed into their destination, which makes configuration of
336 * conffiles from subsequent package instances be skipped along with updates
337 * to the Conffiles field hash.
339 * In case the conffile has already been processed, sync the hash from an
340 * already configured package instance conffile.
342 * @param pkg The current package being configured.
343 * @param conff The current conffile being configured.
346 deferred_configure_ghost_conffile(struct pkginfo
*pkg
, struct conffile
*conff
)
348 struct pkginfo
*otherpkg
;
349 struct conffile
*otherconff
;
351 for (otherpkg
= &pkg
->set
->pkg
; otherpkg
; otherpkg
= otherpkg
->arch_next
) {
354 if (otherpkg
->status
<= PKG_STAT_HALFCONFIGURED
)
357 for (otherconff
= otherpkg
->installed
.conffiles
; otherconff
;
358 otherconff
= otherconff
->next
) {
359 if (otherconff
->obsolete
|| otherconff
->remove_on_upgrade
)
362 /* Check if we need to propagate the new hash from
363 * an already processed conffile in another package
365 if (strcmp(otherconff
->name
, conff
->name
) == 0) {
366 conff
->hash
= otherconff
->hash
;
375 deferred_configure_conffile(struct pkginfo
*pkg
, struct conffile
*conff
)
377 struct fsys_namenode
*usenode
;
378 char currenthash
[MD5HASHLEN
+ 1], newdisthash
[MD5HASHLEN
+ 1];
379 int useredited
, distedited
;
382 struct varbuf cdr
= VARBUF_INIT
, cdr2
= VARBUF_INIT
;
386 usenode
= namenodetouse(fsys_hash_find_node(conff
->name
, FHFF_NO_COPY
),
387 pkg
, &pkg
->installed
);
389 rc
= conffderef(pkg
, &cdr
, usenode
->name
);
391 conff
->hash
= EMPTYHASHFLAG
;
394 md5hash(pkg
, currenthash
, cdr
.buf
);
396 varbuf_set_varbuf(&cdr2
, &cdr
);
397 /* XXX: Make sure there's enough room for extensions. */
398 varbuf_grow(&cdr2
, 50);
399 cdr2rest
= cdr2
.buf
+ strlen(cdr
.buf
);
400 /* From now on we can just strcpy(cdr2rest, extension); */
402 strcpy(cdr2rest
, DPKGNEWEXT
);
403 /* If the .dpkg-new file is no longer there, ignore this one. */
404 if (lstat(cdr2
.buf
, &stab
)) {
405 if (errno
== ENOENT
) {
406 /* But, sync the conffile hash value from another
407 * package set instance. */
408 deferred_configure_ghost_conffile(pkg
, conff
);
411 ohshite(_("unable to stat new distributed conffile '%.250s'"),
414 md5hash(pkg
, newdisthash
, cdr2
.buf
);
416 /* Copy the permissions from the installed version to the new
417 * distributed version. */
418 if (!stat(cdr
.buf
, &stab
))
419 file_copy_perms(cdr
.buf
, cdr2
.buf
);
420 else if (errno
!= ENOENT
)
421 ohshite(_("unable to stat current installed conffile '%.250s'"),
424 /* Select what to do. */
425 if (strcmp(currenthash
, newdisthash
) == 0) {
426 /* They're both the same so there's no point asking silly
430 what
= CFO_IDENTICAL
;
431 } else if (strcmp(currenthash
, NONEXISTENTFLAG
) == 0 && in_force(FORCE_CONFF_MISS
)) {
434 "Configuration file '%s', does not exist on system.\n"
435 "Installing new config file as you requested.\n"),
437 what
= CFO_NEW_CONFF
;
440 } else if (strcmp(conff
->hash
, NEWCONFFILEFLAG
) == 0) {
441 if (strcmp(currenthash
, NONEXISTENTFLAG
) == 0) {
442 what
= CFO_NEW_CONFF
;
448 what
= conffoptcells
[useredited
][distedited
] |
452 useredited
= strcmp(conff
->hash
, currenthash
) != 0;
453 distedited
= strcmp(conff
->hash
, newdisthash
) != 0;
455 if (in_force(FORCE_CONFF_ASK
) && useredited
)
456 what
= CFO_PROMPT_KEEP
;
458 what
= conffoptcells
[useredited
][distedited
];
460 if (strcmp(currenthash
, NONEXISTENTFLAG
) == 0)
461 what
|= CFOF_USER_DEL
;
465 "deferred_configure '%s' (= '%s') useredited=%d distedited=%d what=%o",
466 usenode
->name
, cdr
.buf
, useredited
, distedited
, what
);
468 what
= promptconfaction(pkg
, usenode
->name
, cdr
.buf
, cdr2
.buf
,
469 useredited
, distedited
, what
);
471 switch (what
& ~(CFOF_IS_NEW
| CFOF_USER_DEL
)) {
472 case CFO_KEEP
| CFOF_BACKUP
:
473 strcpy(cdr2rest
, DPKGOLDEXT
);
474 if (unlink(cdr2
.buf
) && errno
!= ENOENT
)
475 warning(_("%s: failed to remove old backup '%.250s': %s"),
476 pkg_name(pkg
, pnaw_nonambig
), cdr2
.buf
,
479 varbuf_add_str(&cdr
, DPKGDISTEXT
);
480 varbuf_end_str(&cdr
);
481 strcpy(cdr2rest
, DPKGNEWEXT
);
482 trig_path_activate(usenode
, pkg
);
483 if (rename(cdr2
.buf
, cdr
.buf
))
484 warning(_("%s: failed to rename '%.250s' to '%.250s': %s"),
485 pkg_name(pkg
, pnaw_nonambig
), cdr2
.buf
, cdr
.buf
,
489 strcpy(cdr2rest
, DPKGNEWEXT
);
490 if (unlink(cdr2
.buf
))
491 warning(_("%s: failed to remove '%.250s': %s"),
492 pkg_name(pkg
, pnaw_nonambig
), cdr2
.buf
,
495 case CFO_INSTALL
| CFOF_BACKUP
:
496 strcpy(cdr2rest
, DPKGDISTEXT
);
497 if (unlink(cdr2
.buf
) && errno
!= ENOENT
)
498 warning(_("%s: failed to remove old distributed version '%.250s': %s"),
499 pkg_name(pkg
, pnaw_nonambig
), cdr2
.buf
,
501 strcpy(cdr2rest
, DPKGOLDEXT
);
502 if (unlink(cdr2
.buf
) && errno
!= ENOENT
)
503 warning(_("%s: failed to remove '%.250s' (before overwrite): %s"),
504 pkg_name(pkg
, pnaw_nonambig
), cdr2
.buf
,
506 if (!(what
& CFOF_USER_DEL
))
507 if (link(cdr
.buf
, cdr2
.buf
))
508 warning(_("%s: failed to link '%.250s' to '%.250s': %s"),
509 pkg_name(pkg
, pnaw_nonambig
), cdr
.buf
,
510 cdr2
.buf
, strerror(errno
));
513 printf(_("Installing new version of config file %s ...\n"),
517 strcpy(cdr2rest
, DPKGNEWEXT
);
518 trig_path_activate(usenode
, pkg
);
519 if (rename(cdr2
.buf
, cdr
.buf
))
520 ohshite(_("unable to install '%.250s' as '%.250s'"),
524 internerr("unknown conffopt '%d'", what
);
527 conff
->hash
= nfstrsave(newdisthash
);
530 varbuf_destroy(&cdr
);
531 varbuf_destroy(&cdr2
);
535 * Process the deferred configure package.
537 * @param pkg The package to act on.
540 deferred_configure(struct pkginfo
*pkg
)
542 struct varbuf aemsgs
= VARBUF_INIT
;
543 struct conffile
*conff
;
544 struct pkginfo
*otherpkg
;
547 if (pkg
->status
== PKG_STAT_NOTINSTALLED
)
548 ohshit(_("no package named '%s' is installed, cannot configure"),
549 pkg_name(pkg
, pnaw_nonambig
));
550 if (pkg
->status
== PKG_STAT_INSTALLED
)
551 ohshit(_("package %.250s is already installed and configured"),
552 pkg_name(pkg
, pnaw_nonambig
));
553 if (pkg
->status
!= PKG_STAT_UNPACKED
&&
554 pkg
->status
!= PKG_STAT_HALFCONFIGURED
)
555 ohshit(_("package %.250s is not ready for configuration\n"
556 " cannot configure (current status '%.250s')"),
557 pkg_name(pkg
, pnaw_nonambig
),
558 pkg_status_name(pkg
));
560 for (otherpkg
= &pkg
->set
->pkg
; otherpkg
; otherpkg
= otherpkg
->arch_next
) {
563 if (otherpkg
->status
<= PKG_STAT_CONFIGFILES
)
566 if (otherpkg
->status
< PKG_STAT_UNPACKED
)
567 ohshit(_("package %s cannot be configured because "
568 "%s is not ready (current status '%s')"),
569 pkg_name(pkg
, pnaw_always
),
570 pkg_name(otherpkg
, pnaw_always
),
571 pkg_status_name(otherpkg
));
573 if (dpkg_version_compare(&pkg
->installed
.version
,
574 &otherpkg
->installed
.version
))
575 ohshit(_("package %s %s cannot be configured because "
576 "%s is at a different version (%s)"),
577 pkg_name(pkg
, pnaw_always
),
578 versiondescribe(&pkg
->installed
.version
,
580 pkg_name(otherpkg
, pnaw_always
),
581 versiondescribe(&otherpkg
->installed
.version
,
585 if (dependtry
>= DEPEND_TRY_CYCLES
)
586 if (findbreakcycle(pkg
))
589 ok
= dependencies_ok(pkg
, NULL
, &aemsgs
);
590 if (ok
== DEP_CHECK_DEFER
) {
591 varbuf_destroy(&aemsgs
);
592 ensure_package_clientdata(pkg
);
593 pkg
->clientdata
->istobe
= PKG_ISTOBE_INSTALLNEW
;
594 enqueue_package(pkg
);
598 trigproc_reset_cycle();
601 * At this point removal from the queue is confirmed. This
602 * represents irreversible progress wrt trigger cycles. Only
603 * packages in PKG_STAT_UNPACKED are automatically added to the
604 * configuration queue, and during configuration and trigger
605 * processing new packages can't enter into unpacked.
608 ok
= breakses_ok(pkg
, &aemsgs
) ? ok
: DEP_CHECK_HALT
;
609 if (ok
== DEP_CHECK_HALT
) {
611 varbuf_end_str(&aemsgs
);
612 notice(_("dependency problems prevent configuration of %s:\n%s"),
613 pkg_name(pkg
, pnaw_nonambig
), aemsgs
.buf
);
614 varbuf_destroy(&aemsgs
);
615 ohshit(_("dependency problems - leaving unconfigured"));
616 } else if (aemsgs
.used
) {
617 varbuf_end_str(&aemsgs
);
618 notice(_("%s: dependency problems, but configuring anyway as you requested:\n%s"),
619 pkg_name(pkg
, pnaw_nonambig
), aemsgs
.buf
);
621 varbuf_destroy(&aemsgs
);
624 if (pkg
->eflag
& PKG_EFLAG_REINSTREQ
)
625 forcibleerr(FORCE_REMOVE_REINSTREQ
,
626 _("package is in a very bad inconsistent state; you should\n"
627 " reinstall it before attempting configuration"));
629 printf(_("Setting up %s (%s) ...\n"), pkg_name(pkg
, pnaw_nonambig
),
630 versiondescribe(&pkg
->installed
.version
, vdew_nonambig
));
631 log_action("configure", pkg
, &pkg
->installed
);
633 trig_activate_packageprocessing(pkg
);
636 pkg_set_status(pkg
, PKG_STAT_INSTALLED
);
637 ensure_package_clientdata(pkg
);
638 pkg
->clientdata
->istobe
= PKG_ISTOBE_NORMAL
;
642 if (pkg
->status
== PKG_STAT_UNPACKED
) {
643 debug(dbg_general
, "deferred_configure updating conffiles");
644 /* This will not do at all the right thing with overridden
645 * conffiles or conffiles that are the ‘target’ of an override;
646 * all the references here would be to the ‘contested’
647 * filename, and in any case there'd only be one hash for both
648 * ‘versions’ of the conffile.
650 * Overriding conffiles is a silly thing to do anyway :-). */
654 /* On entry, the ‘new’ version of each conffile has been
655 * unpacked as ‘*.dpkg-new’, and the ‘installed’ version is
656 * as-yet untouched in ‘*’. The hash of the ‘old distributed’
657 * version is in the conffiles data for the package. If
658 * ‘*.dpkg-new’ no longer exists we assume that we've
659 * already processed this one. */
660 for (conff
= pkg
->installed
.conffiles
; conff
; conff
= conff
->next
) {
661 if (conff
->obsolete
|| conff
->remove_on_upgrade
)
663 deferred_configure_conffile(pkg
, conff
);
666 pkg_set_status(pkg
, PKG_STAT_HALFCONFIGURED
);
669 if (pkg
->status
!= PKG_STAT_HALFCONFIGURED
)
670 internerr("package %s in state %s, instead of half-configured",
671 pkg_name(pkg
, pnaw_always
), pkg_status_name(pkg
));
675 maintscript_postinst(pkg
, "configure",
676 dpkg_version_is_informative(&pkg
->configversion
) ?
677 versiondescribe(&pkg
->configversion
,
681 pkg_reset_eflags(pkg
);
682 pkg
->trigpend_head
= NULL
;
683 post_postinst_tasks(pkg
, PKG_STAT_INSTALLED
);
687 * Dereference a file by following all possibly used symlinks.
689 * @param[in] pkg The package to act on.
690 * @param[out] result The dereference conffile path.
691 * @param[in] in The conffile path to dereference.
693 * @return An error code for the operation.
694 * @retval 0 Everything went ok.
695 * @retval -1 Otherwise.
698 conffderef(struct pkginfo
*pkg
, struct varbuf
*result
, const char *in
)
700 static struct varbuf target
= VARBUF_INIT
;
704 varbuf_set_str(result
, dpkg_fsys_get_dir());
705 varbuf_add_str(result
, in
);
706 varbuf_end_str(result
);
711 debug(dbg_conffdetail
, "conffderef in='%s' current working='%s'",
713 if (lstat(result
->buf
, &stab
)) {
715 warning(_("%s: unable to stat config file '%s'\n"
717 pkg_name(pkg
, pnaw_nonambig
), in
,
718 result
->buf
, strerror(errno
));
719 debug(dbg_conffdetail
, "conffderef nonexistent");
721 } else if (S_ISREG(stab
.st_mode
)) {
722 debug(dbg_conff
, "conffderef in='%s' result='%s'",
725 } else if (S_ISLNK(stab
.st_mode
)) {
728 debug(dbg_conffdetail
, "conffderef symlink loopprotect=%d",
730 if (loopprotect
++ >= 25) {
731 warning(_("%s: config file '%s' is a circular link\n"
733 pkg_name(pkg
, pnaw_nonambig
), in
,
738 linksize
= file_readlink(result
->buf
, &target
, stab
.st_size
);
740 warning(_("%s: unable to readlink conffile '%s'\n"
742 pkg_name(pkg
, pnaw_nonambig
), in
,
743 result
->buf
, strerror(errno
));
745 } else if (linksize
!= stab
.st_size
) {
746 warning(_("symbolic link '%.250s' size has "
747 "changed from %jd to %zd"),
748 result
->buf
, (intmax_t)stab
.st_size
,
750 /* If the returned size is smaller, let's
751 * proceed, otherwise error out. */
752 if (linksize
> stab
.st_size
)
756 debug(dbg_conffdetail
,
757 "conffderef readlink gave %zd, '%s'",
758 linksize
, target
.buf
);
760 if (target
.buf
[0] == '/') {
761 varbuf_set_str(result
, dpkg_fsys_get_dir());
762 debug(dbg_conffdetail
,
763 "conffderef readlink absolute");
767 for (r
= result
->used
- 1; r
> 0 && result
->buf
[r
] != '/'; r
--)
770 warning(_("%s: conffile '%.250s' resolves to degenerate filename\n"
771 " ('%s' is a symlink to '%s')"),
772 pkg_name(pkg
, pnaw_nonambig
),
773 in
, result
->buf
, target
.buf
);
776 if (result
->buf
[r
] == '/')
778 varbuf_trunc(result
, r
);
779 debug(dbg_conffdetail
,
780 "conffderef readlink relative to '%.*s'",
781 (int)result
->used
, result
->buf
);
783 varbuf_add_varbuf(result
, &target
);
784 varbuf_end_str(result
);
786 warning(_("%s: conffile '%.250s' is not a plain file or symlink (= '%s')"),
787 pkg_name(pkg
, pnaw_nonambig
), in
, result
->buf
);
794 * Generate a file contents MD5 hash.
796 * The caller is responsible for providing a buffer for the hash result
797 * at least MD5HASHLEN + 1 characters long.
799 * @param[in] pkg The package to act on.
800 * @param[out] hashbuf The buffer to store the generated hash.
801 * @param[in] fn The filename.
804 md5hash(struct pkginfo
*pkg
, char *hashbuf
, const char *fn
)
806 struct dpkg_error err
;
809 fd
= open(fn
, O_RDONLY
);
812 push_cleanup(cu_closefd
, ehflag_bombout
, 1, &fd
);
813 if (fd_md5(fd
, hashbuf
, -1, &err
) < 0)
814 ohshit(_("cannot compute MD5 digest for file '%s': %s"),
816 pop_cleanup(ehflag_normaltidy
); /* fd = open(cdr.buf) */
818 } else if (errno
== ENOENT
) {
819 strcpy(hashbuf
, NONEXISTENTFLAG
);
821 warning(_("%s: unable to open %s to compute its digest: %s"),
822 pkg_name(pkg
, pnaw_nonambig
), fn
, strerror(errno
));
823 strcpy(hashbuf
, EMPTYHASHFLAG
);