LCOV - code coverage report
Current view: top level - src/common - force.c (source / functions) Hit Total Coverage
Test: dpkg 1.21.11 C code coverage Lines: 24 101 23.8 %
Date: 2022-12-03 00:40:01 Functions: 4 13 30.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 14 54 25.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * dpkg - main program for package management
       3                 :            :  * force.c - force operation support
       4                 :            :  *
       5                 :            :  * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
       6                 :            :  * Copyright © 2006-2019 Guillem Jover <guillem@debian.org>
       7                 :            :  *
       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.
      12                 :            :  *
      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.
      17                 :            :  *
      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/>.
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : #include <compat.h>
      24                 :            : 
      25                 :            : #include <errno.h>
      26                 :            : #include <string.h>
      27                 :            : #include <stdbool.h>
      28                 :            : #include <stdarg.h>
      29                 :            : #include <stdlib.h>
      30                 :            : #include <stdio.h>
      31                 :            : 
      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>
      37                 :            : 
      38                 :            : #include "force.h"
      39                 :            : 
      40                 :            : static int force_mask;
      41                 :            : static int force_flags;
      42                 :            : 
      43                 :            : enum forcetype {
      44                 :            :         FORCETYPE_DISABLED,
      45                 :            :         FORCETYPE_ENABLED,
      46                 :            :         FORCETYPE_DAMAGE,
      47                 :            : };
      48                 :            : 
      49                 :            : static const char *
      50                 :          0 : forcetype_str(enum forcetype type)
      51                 :            : {
      52   [ #  #  #  # ]:          0 :         switch (type) {
      53                 :          0 :         case FORCETYPE_DISABLED:
      54                 :          0 :                 return "   ";
      55                 :          0 :         case FORCETYPE_ENABLED:
      56                 :          0 :                 return "[*]";
      57                 :          0 :         case FORCETYPE_DAMAGE:
      58                 :          0 :                 return "[!]";
      59                 :          0 :         default:
      60                 :          0 :                 internerr("unknown force type '%d'", type);
      61                 :            :         }
      62                 :            : }
      63                 :            : 
      64                 :            : static const struct forceinfo {
      65                 :            :         const char *name;
      66                 :            :         int flag;
      67                 :            :         char type;
      68                 :            :         const char *desc;
      69                 :            : } forceinfos[] = {
      70                 :            :         {
      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
     220                 :            :         }
     221                 :            : };
     222                 :            : 
     223                 :            : bool
     224                 :       1392 : in_force(int flags)
     225                 :            : {
     226                 :       1392 :         return (flags & force_flags) == flags;
     227                 :            : }
     228                 :            : 
     229                 :            : void
     230                 :        190 : set_force(int flags)
     231                 :            : {
     232                 :        190 :         force_flags |= flags;
     233                 :        190 : }
     234                 :            : 
     235                 :            : void
     236                 :          0 : reset_force(int flags)
     237                 :            : {
     238                 :          0 :         force_flags &= ~flags;
     239                 :          0 : }
     240                 :            : 
     241                 :            : char *
     242                 :         48 : get_force_string(void)
     243                 :            : {
     244                 :            :         const struct forceinfo *fip;
     245                 :         48 :         struct varbuf vb = VARBUF_INIT;
     246                 :            : 
     247         [ +  + ]:       1440 :         for (fip = forceinfos; fip->name; fip++) {
     248         [ +  + ]:       1392 :                 if ((enum force_flags)fip->flag == FORCE_ALL ||
     249         [ +  - ]:       1344 :                     (fip->flag & force_mask) != fip->flag ||
     250         [ +  + ]:       1344 :                     !in_force(fip->flag))
     251                 :       1296 :                         continue;
     252                 :            : 
     253         [ +  + ]:         96 :                 if (vb.used)
     254                 :         48 :                         varbuf_add_char(&vb, ',');
     255                 :         96 :                 varbuf_add_str(&vb, fip->name);
     256                 :            :         }
     257                 :         48 :         varbuf_end_str(&vb);
     258                 :            : 
     259                 :         48 :         return varbuf_detach(&vb);
     260                 :            : }
     261                 :            : 
     262                 :            : static inline void
     263                 :          0 : print_forceinfo_line(int type, const char *name, const char *desc)
     264                 :            : {
     265                 :          0 :         printf("  %s %-18s %s\n", forcetype_str(type), name, desc);
     266                 :          0 : }
     267                 :            : 
     268                 :            : static void
     269                 :          0 : print_forceinfo(const struct forceinfo *fi)
     270                 :            : {
     271                 :            :         char *desc, *line;
     272                 :            : 
     273                 :          0 :         desc = m_strdup(gettext(fi->desc));
     274                 :            : 
     275                 :          0 :         line = strtok(desc, "\n");
     276                 :          0 :         print_forceinfo_line(fi->type, fi->name, line);
     277         [ #  # ]:          0 :         while ((line = strtok(NULL, "\n")))
     278                 :          0 :                 print_forceinfo_line(FORCETYPE_DISABLED, "", line);
     279                 :            : 
     280                 :          0 :         free(desc);
     281                 :          0 : }
     282                 :            : 
     283                 :            : void
     284                 :          0 : parse_force(const char *value, bool set)
     285                 :            : {
     286                 :            :         const char *comma;
     287                 :            :         size_t l;
     288                 :            :         const struct forceinfo *fip;
     289                 :            : 
     290         [ #  # ]:          0 :         if (strcmp(value, "help") == 0) {
     291                 :          0 :                 char *force_string = get_force_string();
     292                 :            : 
     293                 :          0 :                 printf(_(
     294                 :            : "%s forcing options - control behaviour when problems found:\n"
     295                 :            : "  warn but continue:  --force-<thing>,<thing>,...\n"
     296                 :            : "  stop with error:    --refuse-<thing>,<thing>,... | --no-force-<thing>,...\n"
     297                 :            : " Forcing things:\n"), dpkg_get_progname());
     298                 :            : 
     299         [ #  # ]:          0 :                 for (fip = forceinfos; fip->name; fip++)
     300         [ #  # ]:          0 :                         if ((enum force_flags)fip->flag == FORCE_ALL ||
     301         [ #  # ]:          0 :                             (fip->flag & force_mask) == fip->flag)
     302                 :          0 :                                 print_forceinfo(fip);
     303                 :            : 
     304                 :          0 :                 printf(_(
     305                 :            : "\n"
     306                 :            : "WARNING - use of options marked [!] can seriously damage your installation.\n"
     307                 :            : "Forcing options marked [*] are enabled by default.\n"));
     308                 :          0 :                 m_output(stdout, _("<standard output>"));
     309                 :            : 
     310                 :          0 :                 printf(_(
     311                 :            : "\n"
     312                 :            : "Currently enabled options:\n"
     313                 :            : " %s\n"), force_string);
     314                 :            : 
     315                 :          0 :                 free(force_string);
     316                 :            : 
     317                 :          0 :                 exit(0);
     318                 :            :         }
     319                 :            : 
     320                 :            :         for (;;) {
     321                 :          0 :                 comma = strchrnul(value, ',');
     322                 :          0 :                 l = (size_t)(comma - value);
     323         [ #  # ]:          0 :                 for (fip = forceinfos; fip->name; fip++)
     324         [ #  # ]:          0 :                         if (strncmp(fip->name, value, l) == 0 &&
     325         [ #  # ]:          0 :                             strlen(fip->name) == l)
     326                 :          0 :                                 break;
     327                 :            : 
     328         [ #  # ]:          0 :                 if (!fip->name) {
     329         [ #  # ]:          0 :                         badusage(_("unknown force/refuse option '%.*s'"),
     330                 :            :                                  (int)min(l, 250), value);
     331         [ #  # ]:          0 :                 } else if (fip->flag) {
     332         [ #  # ]:          0 :                         if (set)
     333                 :          0 :                                 set_force(fip->flag);
     334                 :            :                         else
     335                 :          0 :                                 reset_force(fip->flag);
     336                 :            :                 } else {
     337                 :          0 :                         warning(_("obsolete force/refuse option '%s'"),
     338                 :          0 :                                 fip->name);
     339                 :            :                 }
     340                 :            : 
     341         [ #  # ]:          0 :                 if (*comma == '\0')
     342                 :          0 :                         break;
     343                 :          0 :                 value = ++comma;
     344                 :            :         }
     345                 :          0 : }
     346                 :            : 
     347                 :            : void
     348                 :         95 : set_force_default(int mask)
     349                 :            : {
     350                 :            :         const char *force_env;
     351                 :            :         const struct forceinfo *fip;
     352                 :            : 
     353                 :         95 :         force_mask = mask;
     354                 :            : 
     355                 :            :         /* If we get passed force options from the environment, do not
     356                 :            :          * initialize from the built-in defaults. */
     357                 :         95 :         force_env = getenv("DPKG_FORCE");
     358         [ -  + ]:         95 :         if (force_env != NULL) {
     359         [ #  # ]:          0 :                 if (force_env[0] != '\0')
     360                 :          0 :                         parse_force(force_env, 1);
     361                 :          0 :                 return;
     362                 :            :         }
     363                 :            : 
     364         [ +  + ]:       2850 :         for (fip = forceinfos; fip->name; fip++)
     365         [ +  + ]:       2755 :                 if (fip->type == FORCETYPE_ENABLED)
     366                 :        190 :                         set_force(fip->flag);
     367                 :            : }
     368                 :            : 
     369                 :            : void
     370                 :          0 : set_force_option(const struct cmdinfo *cip, const char *value)
     371                 :            : {
     372                 :          0 :         bool set = cip->arg_int;
     373                 :            : 
     374                 :          0 :         parse_force(value, set);
     375                 :          0 : }
     376                 :            : 
     377                 :            : void
     378                 :          0 : reset_force_option(const struct cmdinfo *cip, const char *value)
     379                 :            : {
     380                 :          0 :         reset_force(cip->arg_int);
     381                 :          0 : }
     382                 :            : 
     383                 :            : void
     384                 :          0 : forcibleerr(int forceflag, const char *fmt, ...)
     385                 :            : {
     386                 :            :         va_list args;
     387                 :            : 
     388                 :          0 :         va_start(args, fmt);
     389         [ #  # ]:          0 :         if (in_force(forceflag)) {
     390                 :          0 :                 warning(_("overriding problem because --force enabled:"));
     391                 :          0 :                 warningv(fmt, args);
     392                 :            :         } else {
     393                 :          0 :                 ohshitv(fmt, args);
     394                 :            :         }
     395                 :          0 :         va_end(args);
     396                 :          0 : }
     397                 :            : 
     398                 :            : int
     399                 :          0 : forcible_nonroot_error(int rc)
     400                 :            : {
     401   [ #  #  #  # ]:          0 :         if (in_force(FORCE_NON_ROOT) && errno == EPERM)
     402                 :          0 :                 return 0;
     403                 :          0 :         return rc;
     404                 :            : }

Generated by: LCOV version 1.16