LCOV - code coverage report
Current view: top level - src/common - force.c (source / functions) Coverage Total Hit
Test: dpkg 1.22.7-3-g89f48 C code coverage Lines: 22.8 % 101 23
Test Date: 2024-07-17 02:53:43 Functions: 30.8 % 13 4
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 25.9 % 54 14

             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                 :             : 
     258                 :          48 :         return varbuf_detach(&vb);
     259                 :             : }
     260                 :             : 
     261                 :             : static inline void
     262                 :           0 : print_forceinfo_line(int type, const char *name, const char *desc)
     263                 :             : {
     264                 :           0 :         printf("  %s %-18s %s\n", forcetype_str(type), name, desc);
     265                 :           0 : }
     266                 :             : 
     267                 :             : static void
     268                 :           0 : print_forceinfo(const struct forceinfo *fi)
     269                 :             : {
     270                 :             :         char *desc, *line;
     271                 :             : 
     272                 :           0 :         desc = m_strdup(gettext(fi->desc));
     273                 :             : 
     274                 :           0 :         line = strtok(desc, "\n");
     275                 :           0 :         print_forceinfo_line(fi->type, fi->name, line);
     276         [ #  # ]:           0 :         while ((line = strtok(NULL, "\n")))
     277                 :           0 :                 print_forceinfo_line(FORCETYPE_DISABLED, "", line);
     278                 :             : 
     279                 :           0 :         free(desc);
     280                 :           0 : }
     281                 :             : 
     282                 :             : void
     283                 :           0 : parse_force(const char *value, bool set)
     284                 :             : {
     285                 :             :         const struct forceinfo *fip;
     286                 :             : 
     287         [ #  # ]:           0 :         if (strcmp(value, "help") == 0) {
     288                 :           0 :                 char *force_string = get_force_string();
     289                 :             : 
     290                 :           0 :                 printf(_(
     291                 :             : "%s forcing options - control behavior when problems found:\n"
     292                 :             : "  warn but continue:  --force-<thing>,<thing>,...\n"
     293                 :             : "  stop with error:    --refuse-<thing>,<thing>,... | --no-force-<thing>,...\n"
     294                 :             : " Forcing things:\n"), dpkg_get_progname());
     295                 :             : 
     296         [ #  # ]:           0 :                 for (fip = forceinfos; fip->name; fip++)
     297         [ #  # ]:           0 :                         if ((enum force_flags)fip->flag == FORCE_ALL ||
     298         [ #  # ]:           0 :                             (fip->flag & force_mask) == fip->flag)
     299                 :           0 :                                 print_forceinfo(fip);
     300                 :             : 
     301                 :           0 :                 printf(_(
     302                 :             : "\n"
     303                 :             : "WARNING - use of options marked [!] can seriously damage your installation.\n"
     304                 :             : "Forcing options marked [*] are enabled by default.\n"));
     305                 :           0 :                 m_output(stdout, _("<standard output>"));
     306                 :             : 
     307                 :           0 :                 printf(_(
     308                 :             : "\n"
     309                 :             : "Currently enabled options:\n"
     310                 :             : " %s\n"), force_string);
     311                 :             : 
     312                 :           0 :                 free(force_string);
     313                 :             : 
     314                 :           0 :                 exit(0);
     315                 :             :         }
     316                 :             : 
     317                 :           0 :         for (;;) {
     318                 :             :                 const char *comma;
     319                 :             :                 size_t l;
     320                 :             : 
     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 2.0-1