LCOV - code coverage report
Current view: top level - libpkg - pkg_add.c (source / functions) Hit Total Coverage
Test: cov.info Lines: 188 350 53.7 %
Date: 2015-08-15 Functions: 7 10 70.0 %

          Line data    Source code
       1             : /*-
       2             :  * Copyright (c) 2011-2013 Baptiste Daroussin <bapt@FreeBSD.org>
       3             :  * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
       4             :  * All rights reserved.
       5             :  * 
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  * 1. Redistributions of source code must retain the above copyright
      10             :  *    notice, this list of conditions and the following disclaimer
      11             :  *    in this position and unchanged.
      12             :  * 2. Redistributions in binary form must reproduce the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer in the
      14             :  *    documentation and/or other materials provided with the distribution.
      15             :  * 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
      17             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      18             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      19             :  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
      20             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      21             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      22             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      23             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      24             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      25             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : 
      28             : #ifdef HAVE_CONFIG_H
      29             : #include "pkg_config.h"
      30             : #endif
      31             : 
      32             : #include <archive.h>
      33             : #include <archive_entry.h>
      34             : #include <assert.h>
      35             : #include <libgen.h>
      36             : #include <string.h>
      37             : #include <errno.h>
      38             : #include <glob.h>
      39             : 
      40             : #include "pkg.h"
      41             : #include "private/event.h"
      42             : #include "private/utils.h"
      43             : #include "private/pkg.h"
      44             : #include "private/pkgdb.h"
      45             : 
      46             : #if defined(UF_NOUNLINK)
      47             : #define NOCHANGESFLAGS  (UF_IMMUTABLE | UF_APPEND | UF_NOUNLINK | SF_IMMUTABLE | SF_APPEND | SF_NOUNLINK)
      48             : #else
      49             : #define NOCHANGESFLAGS  (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
      50             : #endif
      51             : 
      52             : 
      53             : static const unsigned char litchar[] =
      54             : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
      55             : 
      56             : static void
      57          15 : pkg_add_file_random_suffix(char *buf, int buflen, int suflen)
      58             : {
      59          15 :         int nchars = strlen(buf);
      60             :         char *pos;
      61             :         int r;
      62             : 
      63          15 :         if (nchars + suflen > buflen - 1) {
      64           0 :                 suflen = buflen - nchars - 1;
      65           0 :                 if (suflen <= 0)
      66          15 :                         return;
      67             :         }
      68             : 
      69          15 :         buf[nchars++] = '.';
      70          15 :         pos = buf + nchars;
      71             : 
      72         210 :         while(suflen --) {
      73             : #ifndef HAVE_ARC4RANDOM
      74             :                 r = rand() % (sizeof(litchar) - 1);
      75             : #else
      76         180 :                 r = arc4random_uniform(sizeof(litchar) - 1);
      77             : #endif
      78         180 :                 *pos++ = litchar[r];
      79             :         }
      80             : 
      81          15 :         *pos = '\0';
      82             : }
      83             : 
      84             : static void
      85           0 : attempt_to_merge(bool renamed, struct pkg_config_file *rcf,
      86             :   struct pkg *local, char *pathname, const char *path, struct sbuf *newconf)
      87             : {
      88           0 :         const struct pkg_file *lf = NULL;
      89           0 :         struct pkg_config_file *lcf = NULL;
      90             : 
      91           0 :         char *localconf = NULL;
      92             :         size_t sz;
      93             :         char *localsum;
      94             : 
      95           0 :         if (!renamed) {
      96           0 :                 pkg_debug(3, "Not renamed");
      97           0 :                 return;
      98             :         }
      99             : 
     100           0 :         if (rcf == NULL) {
     101           0 :                 pkg_debug(3, "No remote config file");
     102           0 :                 return;
     103             :         }
     104             : 
     105           0 :         if (local == NULL) {
     106           0 :                 pkg_debug(3, "No local package");
     107           0 :                 return;
     108             :         }
     109             : 
     110           0 :         if (!pkg_is_config_file(local, path, &lf, &lcf)) {
     111           0 :                 pkg_debug(3, "No local package");
     112           0 :                 return;
     113             :         }
     114             : 
     115           0 :         if (lcf->content == NULL) {
     116           0 :                 pkg_debug(3, "Empty configuration content for local package");
     117           0 :                 return;
     118             :         }
     119             :         
     120           0 :         pkg_debug(1, "Config file found %s", pathname);
     121           0 :         file_to_buffer(pathname, &localconf, &sz);
     122             : 
     123           0 :         pkg_debug(2, "size: %d vs %d", sz, strlen(lcf->content));
     124             : 
     125           0 :         if (sz == strlen(lcf->content)) {
     126           0 :                 pkg_debug(2, "Ancient vanilla and deployed conf are the same size testing checksum");
     127           0 :                 localsum = pkg_checksum_data(localconf, sz,
     128             :                     PKG_HASH_TYPE_SHA256_HEX);
     129           0 :                 if (localsum && strcmp(localsum, lf->sum) == 0) {
     130           0 :                         pkg_debug(2, "Checksum are the same %d", strlen(localconf));
     131           0 :                         free(localconf);
     132           0 :                         free(localsum);
     133           0 :                         return;
     134             :                 }
     135           0 :                 free(localsum);
     136           0 :                 pkg_debug(2, "Checksum are different %d", strlen(localconf));
     137             :         }
     138             : 
     139           0 :         pkg_debug(1, "Attempting to merge %s", pathname);
     140           0 :         if (merge_3way(lcf->content, localconf, rcf->content, newconf) != 0) {
     141           0 :                 pkg_emit_error("Impossible to merge configuration file");
     142           0 :                 sbuf_clear(newconf);
     143           0 :                 strlcat(pathname, ".pkgnew", MAXPATHLEN);
     144             :         }
     145           0 :         free(localconf);
     146             : }
     147             : 
     148             : static int
     149          18 : do_extract(struct archive *a, struct archive_entry *ae, const char *location,
     150             :     int nfiles, struct pkg *pkg, struct pkg *local)
     151             : {
     152          18 :         int     retcode = EPKG_OK;
     153          18 :         int     ret = 0, cur_file = 0;
     154             :         char    path[MAXPATHLEN], pathname[MAXPATHLEN], rpath[MAXPATHLEN];
     155             :         struct stat st;
     156             :         const struct stat *aest;
     157          18 :         bool renamed = false;
     158             :         const struct pkg_file *rf;
     159             :         struct pkg_config_file *rcf;
     160             :         struct sbuf *newconf;
     161          18 :         bool automerge = pkg_object_bool(pkg_config_get("AUTOMERGE"));
     162             :         unsigned long set, clear;
     163             : 
     164             : #ifndef HAVE_ARC4RANDOM
     165             :         srand(time(NULL));
     166             : #endif
     167             : 
     168          18 :         if (nfiles == 0)
     169           0 :                 return (EPKG_OK);
     170             : 
     171          18 :         pkg_emit_extract_begin(pkg);
     172          18 :         pkg_emit_progress_start(NULL);
     173             : 
     174          18 :         newconf = sbuf_new_auto();
     175             : 
     176             :         do {
     177          18 :                 ret = ARCHIVE_OK;
     178          18 :                 sbuf_clear(newconf);
     179          18 :                 rf = NULL;
     180          18 :                 rcf = NULL;
     181          18 :                 pkg_absolutepath(archive_entry_pathname(ae), path, sizeof(path));
     182          18 :                 snprintf(pathname, sizeof(pathname), "%s%s%s",
     183          18 :                     location ? location : "", *path == '/' ? "" : "/",
     184             :                     path
     185             :                 );
     186          18 :                 strlcpy(rpath, pathname, sizeof(rpath));
     187             : 
     188          18 :                 aest = archive_entry_stat(ae);
     189          18 :                 archive_entry_fflags(ae, &set, &clear);
     190          18 :                 if (lstat(rpath, &st) != -1) {
     191             :                         /*
     192             :                          * We have an existing file on the path, so handle it
     193             :                          */
     194          15 :                         if (!S_ISDIR(aest->st_mode)) {
     195          15 :                                 pkg_debug(2, "Old version found, renaming");
     196          15 :                                 pkg_add_file_random_suffix(rpath, sizeof(rpath), 12);
     197          15 :                                 renamed = true;
     198             :                         }
     199             : 
     200          15 :                         if (!S_ISDIR(st.st_mode) && S_ISDIR(aest->st_mode)) {
     201           0 :                                 if (S_ISLNK(st.st_mode)) {
     202           0 :                                         if (stat(rpath, &st) == -1) {
     203           0 :                                                 pkg_emit_error("Dead symlink %s", rpath);
     204             :                                         } else {
     205           0 :                                                 pkg_debug(2, "Directory is a symlink, use it");
     206           0 :                                                 pkg_emit_progress_tick(cur_file++, nfiles);
     207           0 :                                                 continue;
     208             :                                         }
     209             :                                 }
     210             :                         }
     211             :                 }
     212             : 
     213          18 :                 archive_entry_set_pathname(ae, rpath);
     214             : 
     215             :                 /* load in memory the content of config files */
     216          18 :                 if (pkg_is_config_file(pkg, path, &rf, &rcf)) {
     217           0 :                         pkg_debug(1, "Populating config_file %s", pathname);
     218           0 :                         size_t len = archive_entry_size(ae);
     219           0 :                         rcf->content = malloc(len);
     220           0 :                         archive_read_data(a, rcf->content, len);
     221           0 :                         if (renamed && (!automerge || local == NULL))
     222           0 :                                 strlcat(pathname, ".pkgnew", sizeof(pathname));
     223             :                 }
     224             : 
     225             :                 /*
     226             :                  * check if the file is already provided by previous package
     227             :                  */
     228          18 :                 if (!automerge)
     229           0 :                         attempt_to_merge(renamed, rcf, local, pathname, path, newconf);
     230             : 
     231          36 :                 if (sbuf_len(newconf) == 0 && (rcf == NULL || rcf->content == NULL)) {
     232          18 :                         pkg_debug(1, "Extracting: %s", archive_entry_pathname(ae));
     233          18 :                         int install_as_user = (getenv("INSTALL_AS_USER") != NULL);
     234          18 :                         int extract_flags = EXTRACT_ARCHIVE_FLAGS;
     235          18 :                         if (install_as_user) {
     236             :                                 /* when installing as user don't try to set file ownership */
     237          18 :                                 extract_flags &= ~ARCHIVE_EXTRACT_OWNER;
     238             :                         }
     239          18 :                         ret = archive_read_extract(a, ae, extract_flags);
     240             :                 } else {
     241           0 :                         if (sbuf_len(newconf) == 0) {
     242           0 :                                 sbuf_cat(newconf, rcf->content);
     243           0 :                                 sbuf_finish(newconf);
     244             :                         }
     245           0 :                         pkg_debug(2, "Writing conf in %s", pathname);
     246           0 :                         unlink(rpath);
     247           0 :                         FILE *f = fopen(rpath, "w+");
     248           0 :                         fprintf(f, "%s", sbuf_data(newconf));
     249           0 :                         fclose(f);
     250             :                 }
     251             : 
     252          18 :                 if (ret != ARCHIVE_OK) {
     253             :                         /*
     254             :                          * show error except when the failure is during
     255             :                          * extracting a directory and that the directory already
     256             :                          * exists.
     257             :                          * this allow to install packages linux_base from
     258             :                          * package for example
     259             :                          */
     260           0 :                         if (archive_entry_filetype(ae) != AE_IFDIR ||
     261           0 :                             !is_dir(pathname)) {
     262           0 :                                 pkg_emit_error("archive_read_extract(): %s",
     263             :                                     archive_error_string(a));
     264           0 :                                 retcode = EPKG_FATAL;
     265           0 :                                 goto cleanup;
     266             :                         }
     267             :                 }
     268             :                 /* Reapply modes to the directories to work around a problem on FreeBSD 9 */
     269          18 :                 if (archive_entry_filetype(ae) == AE_IFDIR)
     270           0 :                         chmod(pathname, aest->st_mode);
     271             : 
     272          18 :                 pkg_emit_progress_tick(cur_file++, nfiles);
     273             : 
     274             :                 /* Rename old file */
     275          18 :                 if (renamed) {
     276             : 
     277          15 :                         pkg_debug(1, "Renaming %s -> %s", rpath, pathname);
     278             : #ifdef HAVE_CHFLAGS
     279          15 :                         bool old = false;
     280          15 :                         if (set & NOCHANGESFLAGS)
     281           0 :                                 chflags(rpath, 0);
     282             : 
     283          15 :                         if (lstat(pathname, &st) != -1) {
     284          15 :                                 old = true;
     285          15 :                                 if (st.st_flags & NOCHANGESFLAGS)
     286           0 :                                         chflags(pathname, 0);
     287             :                         }
     288             : #endif
     289             : 
     290          15 :                         if (rename(rpath, pathname) == -1) {
     291             : #ifdef HAVE_CHFLAGS
     292             :                                 /* restore flags */
     293           0 :                                 if (old)
     294           0 :                                         chflags(pathname, st.st_flags);
     295             : #endif
     296           0 :                                 pkg_emit_error("cannot rename %s to %s: %s", rpath, pathname,
     297           0 :                                         strerror(errno));
     298           0 :                                 retcode = EPKG_FATAL;
     299           0 :                                 goto cleanup;
     300             :                         }
     301             : #ifdef HAVE_CHFLAGS
     302             :                         /* Restore flags */
     303          15 :                         chflags(pathname, set);
     304             : #endif
     305             :                 }
     306             : 
     307          18 :                 if (string_end_with(pathname, ".pkgnew"))
     308           0 :                         pkg_emit_notice("New configuration file: %s", pathname);
     309             : 
     310          18 :                 renamed = false;
     311          18 :         } while ((ret = archive_read_next_header(a, &ae)) == ARCHIVE_OK);
     312             : 
     313          18 :         if (ret != ARCHIVE_EOF) {
     314           0 :                 pkg_emit_error("archive_read_next_header(): %s",
     315             :                     archive_error_string(a));
     316           0 :                 retcode = EPKG_FATAL;
     317             :         }
     318             : 
     319             : cleanup:
     320             : 
     321          18 :         pkg_emit_progress_tick(nfiles, nfiles);
     322          18 :         pkg_emit_extract_finished(pkg);
     323             : 
     324          18 :         if (renamed && retcode == EPKG_FATAL) {
     325             : #ifdef HAVE_CHFLAGS
     326           0 :                 if (set & NOCHANGESFLAGS)
     327           0 :                         chflags(rpath, set & ~NOCHANGESFLAGS);
     328             : #endif
     329           0 :                 unlink(rpath);
     330             :         }
     331             : 
     332          18 :         return (retcode);
     333             : }
     334             : 
     335             : static char *
     336           1 : pkg_globmatch(char *pattern, const char *name)
     337             : {
     338             :         glob_t g;
     339             :         int i;
     340             :         char *buf, *buf2;
     341           1 :         char *path = NULL;
     342             : 
     343           1 :         if (glob(pattern, 0, NULL, &g) == GLOB_NOMATCH) {
     344           0 :                 globfree(&g);
     345             : 
     346           0 :                 return (NULL);
     347             :         }
     348             : 
     349           3 :         for (i = 0; i < g.gl_pathc; i++) {
     350             :                 /* the version starts here */
     351           2 :                 buf = strrchr(g.gl_pathv[i], '-');
     352           2 :                 if (buf == NULL)
     353           0 :                         continue;
     354           2 :                 buf2 = strchr(g.gl_pathv[i], '/');
     355           2 :                 if (buf2 == NULL)
     356           0 :                         buf2 = g.gl_pathv[i];
     357             :                 else
     358           2 :                         buf2++;
     359             :                 /* ensure we have match the proper name */
     360           2 :                 if (strncmp(buf2, name, buf - buf2) != 0)
     361           1 :                         continue;
     362           1 :                 if (path == NULL) {
     363           1 :                         path = g.gl_pathv[i];
     364           1 :                         continue;
     365             :                 }
     366           0 :                 if (pkg_version_cmp(path, g.gl_pathv[i]) == '>')
     367           0 :                         path = g.gl_pathv[i];
     368             :         }
     369           1 :         path = strdup(path);
     370           1 :         globfree(&g);
     371             : 
     372           1 :         return (path);
     373             : }
     374             : 
     375             : static int
     376          11 : pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
     377             :         const char *path, int flags,
     378             :         struct pkg_manifest_key *keys, const char *location)
     379             : {
     380             :         const char      *arch;
     381             :         int     ret, retcode;
     382          11 :         struct pkg_dep  *dep = NULL;
     383             :         char    bd[MAXPATHLEN], *basedir;
     384             :         char    dpath[MAXPATHLEN], *ppath;
     385             :         const char      *ext;
     386          11 :         struct pkg      *pkg_inst = NULL;
     387             : 
     388          11 :         arch = pkg->abi != NULL ? pkg->abi : pkg->arch;
     389             : 
     390          11 :         if (!is_valid_abi(arch, true)) {
     391           0 :                 if ((flags & PKG_ADD_FORCE) == 0) {
     392           0 :                         return (EPKG_FATAL);
     393             :                 }
     394             :         }
     395             : 
     396             :         /* XX check */
     397          11 :         ret = pkg_try_installed(db, pkg->origin, &pkg_inst, PKG_LOAD_BASIC);
     398          11 :         if (ret == EPKG_OK) {
     399           0 :                 if ((flags & PKG_ADD_FORCE) == 0) {
     400           0 :                         pkg_emit_already_installed(pkg_inst);
     401           0 :                         pkg_free(pkg_inst);
     402           0 :                         pkg_inst = NULL;
     403           0 :                         return (EPKG_INSTALLED);
     404             :                 }
     405           0 :                 else if (pkg_inst->locked) {
     406           0 :                         pkg_emit_locked(pkg_inst);
     407           0 :                         pkg_free(pkg_inst);
     408           0 :                         pkg_inst = NULL;
     409           0 :                         return (EPKG_LOCKED);
     410             :                 }
     411             :                 else {
     412           0 :                         pkg_emit_notice("package %s is already installed, forced install",
     413             :                                 pkg->name);
     414           0 :                         pkg_free(pkg_inst);
     415           0 :                         pkg_inst = NULL;
     416             :                 }
     417          11 :         } else if (ret != EPKG_END) {
     418           0 :                 return (ret);
     419             :         }
     420             : 
     421             :         /*
     422             :          * Check for dependencies by searching the same directory as
     423             :          * the package archive we're reading.  Of course, if we're
     424             :          * reading from a file descriptor or a unix domain socket or
     425             :          * whatever, there's no valid directory to search.
     426             :          */
     427          11 :         strlcpy(bd, path, sizeof(bd));
     428          11 :         if (strncmp(path, "-", 2) != 0) {
     429           8 :                 basedir = dirname(bd);
     430           8 :                 if ((ext = strrchr(path, '.')) == NULL) {
     431           0 :                         pkg_emit_error("%s has no extension", path);
     432           0 :                         return (EPKG_FATAL);
     433             :                 }
     434             :         } else {
     435           3 :                 ext = NULL;
     436           3 :                 basedir = NULL;
     437             :         }
     438             : 
     439          11 :         retcode = EPKG_FATAL;
     440          11 :         pkg_emit_add_deps_begin(pkg);
     441             : 
     442          25 :         while (pkg_deps(pkg, &dep) == EPKG_OK) {
     443           5 :                 if (pkg_is_installed(db, dep->name) == EPKG_OK)
     444           0 :                         continue;
     445             : 
     446           5 :                 if (basedir == NULL) {
     447           2 :                         pkg_emit_missing_dep(pkg, dep);
     448           2 :                         if ((flags & PKG_ADD_FORCE_MISSING) == 0)
     449           1 :                                 goto cleanup;
     450           1 :                         continue;
     451             :                 }
     452             : 
     453           3 :                 if (dep->version != NULL && dep->version[0] != '\0') {
     454           4 :                         snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
     455           4 :                                 dep->name, dep->version, ext);
     456             : 
     457           5 :                         if ((flags & PKG_ADD_UPGRADE) == 0 &&
     458           2 :                             access(dpath, F_OK) == 0) {
     459           0 :                                 ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC,
     460             :                                     keys, location);
     461             : 
     462           0 :                                 if (ret != EPKG_OK)
     463           0 :                                         goto cleanup;
     464             :                         } else {
     465           2 :                                 pkg_emit_missing_dep(pkg, dep);
     466           2 :                                 if ((flags & PKG_ADD_FORCE_MISSING) == 0)
     467           1 :                                         goto cleanup;
     468             :                         }
     469             :                 } else {
     470           1 :                         snprintf(dpath, sizeof(dpath), "%s/%s-*%s", basedir,
     471           1 :                             dep->name, ext);
     472           1 :                         ppath = pkg_globmatch(dpath, dep->name);
     473           1 :                         if (ppath == NULL) {
     474           0 :                                 pkg_emit_missing_dep(pkg, dep);
     475           0 :                                 if ((flags & PKG_ADD_FORCE_MISSING) == 0)
     476           0 :                                         goto cleanup;
     477           0 :                                 continue;
     478             :                         }
     479           2 :                         if ((flags & PKG_ADD_UPGRADE) == 0 &&
     480           1 :                             access(ppath, F_OK) == 0) {
     481           1 :                                 ret = pkg_add(db, ppath, PKG_ADD_AUTOMATIC,
     482             :                                     keys, location);
     483             : 
     484           1 :                                 free(ppath);
     485           2 :                                 if (ret != EPKG_OK)
     486           0 :                                         goto cleanup;
     487             :                         } else {
     488           0 :                                 free(ppath);
     489           0 :                                 pkg_emit_missing_dep(pkg, dep);
     490           0 :                                 if ((flags & PKG_ADD_FORCE_MISSING) == 0)
     491           0 :                                         goto cleanup;
     492           0 :                                 continue;
     493             :                         }
     494             :                 }
     495             :         }
     496             : 
     497           9 :         retcode = EPKG_OK;
     498             : cleanup:
     499          11 :         pkg_emit_add_deps_finished(pkg);
     500             : 
     501          11 :         return (retcode);
     502             : }
     503             : 
     504             : static int
     505           0 : pkg_add_cleanup_old(struct pkgdb *db, struct pkg *old, struct pkg *new, int flags)
     506             : {
     507             :         struct pkg_file *f;
     508           0 :         int ret = EPKG_OK;
     509             :         bool handle_rc;
     510             : 
     511           0 :         handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));
     512           0 :         if (handle_rc)
     513           0 :                 pkg_start_stop_rc_scripts(old, PKG_RC_STOP);
     514             : 
     515             :         /*
     516             :          * Execute pre deinstall scripts
     517             :          */
     518           0 :         if ((flags & PKG_ADD_NOSCRIPT) == 0) {
     519           0 :                 if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS)
     520           0 :                         ret = pkg_script_run(old, PKG_SCRIPT_PRE_UPGRADE);
     521             :                 else
     522           0 :                         ret = pkg_script_run(old, PKG_SCRIPT_PRE_DEINSTALL);
     523           0 :                 if (ret != EPKG_OK)
     524           0 :                         return (ret);
     525             :         }
     526             : 
     527             :         /* Now remove files that no longer exist in the new package */
     528           0 :         if (new != NULL) {
     529           0 :                 f = NULL;
     530           0 :                 while (pkg_files(old, &f) == EPKG_OK) {
     531           0 :                         if (!pkg_has_file(new, f->path)) {
     532           0 :                                 pkg_debug(2, "File %s is not in the new package", f->path);
     533           0 :                                 pkg_delete_file(old, f, flags & PKG_DELETE_FORCE ? 1 : 0);
     534             :                         }
     535             :                 }
     536             : 
     537           0 :                 pkg_delete_dirs(db, old, new);
     538             :         }
     539             : 
     540           0 :         return (ret);
     541             : }
     542             : 
     543             : static int
     544          23 : pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
     545             :     struct pkg_manifest_key *keys, const char *reloc, struct pkg *remote,
     546             :     struct pkg *local)
     547             : {
     548             :         struct archive  *a;
     549             :         struct archive_entry *ae;
     550          23 :         struct pkg      *pkg = NULL;
     551             :         const char      *location;
     552          23 :         bool             extract = true;
     553          23 :         bool             handle_rc = false;
     554          23 :         int              retcode = EPKG_OK;
     555             :         int              ret;
     556             :         int nfiles;
     557             : 
     558          23 :         assert(path != NULL);
     559             : 
     560          23 :         if (local != NULL)
     561           0 :                 flags |= PKG_ADD_UPGRADE;
     562             : 
     563          23 :         location = reloc;
     564          23 :         if (pkg_rootdir != NULL)
     565           0 :                 location = pkg_rootdir;
     566             : 
     567             :         /*
     568             :          * Open the package archive file, read all the meta files and set the
     569             :          * current archive_entry to the first non-meta file.
     570             :          * If there is no non-meta files, EPKG_END is returned.
     571             :          */
     572          23 :         ret = pkg_open2(&pkg, &a, &ae, path, keys, 0, -1);
     573          23 :         if (ret == EPKG_END)
     574           3 :                 extract = false;
     575          20 :         else if (ret != EPKG_OK) {
     576           0 :                 retcode = ret;
     577           0 :                 goto cleanup;
     578             :         }
     579          23 :         if ((flags & PKG_ADD_UPGRADE) == 0)
     580          11 :                 pkg_emit_install_begin(pkg);
     581             :         else {
     582          12 :                 if (local != NULL)
     583           0 :                         pkg_emit_upgrade_begin(pkg, local);
     584             :                 else
     585          12 :                         pkg_emit_install_begin(pkg);
     586             :         }
     587             : 
     588          23 :         if (pkg_is_valid(pkg) != EPKG_OK) {
     589           0 :                 pkg_emit_error("the package is not valid");
     590           0 :                 return (EPKG_FATAL);
     591             :         }
     592             : 
     593          23 :         if (flags & PKG_ADD_AUTOMATIC)
     594          10 :                 pkg->automatic = true;
     595             : 
     596             :         /*
     597             :          * Additional checks for non-remote package
     598             :          */
     599          23 :         if (remote == NULL) {
     600          11 :                 ret = pkg_add_check_pkg_archive(db, pkg, path, flags, keys,
     601             :                     location);
     602          11 :                 if (ret != EPKG_OK) {
     603             :                         /* Do not return error on installed package */
     604           2 :                         retcode = (ret == EPKG_INSTALLED ? EPKG_OK : ret);
     605           2 :                         goto cleanup;
     606             :                 }
     607             :         }
     608             :         else {
     609          12 :                 if (remote->repo != NULL) {
     610             :                         /* Save reponame */
     611          12 :                         pkg_kv_add(&pkg->annotations, "repository", remote->repo->name, "annotation");
     612          12 :                         pkg_kv_add(&pkg->annotations, "repo_type", remote->repo->ops->type, "annotation");
     613             :                 }
     614             : 
     615          12 :                 free(pkg->digest);
     616          12 :                 pkg->digest = strdup(remote->digest);
     617             :                 /* only preserve flags is -A has not been passed */
     618          12 :                 if ((flags & PKG_ADD_AUTOMATIC) == 0)
     619           4 :                         pkg->automatic = remote->automatic;
     620             :         }
     621             : 
     622          21 :         if (pkg_rootdir == NULL && location != NULL)
     623           0 :                 pkg_kv_add(&pkg->annotations, "relocated", location, "annotation");
     624             : 
     625             :         /* register the package before installing it in case there are
     626             :          * problems that could be caught here. */
     627          21 :         retcode = pkgdb_register_pkg(db, pkg,
     628             :                         flags & PKG_ADD_UPGRADE,
     629             :                         flags & PKG_ADD_FORCE);
     630             : 
     631          21 :         if (retcode != EPKG_OK)
     632           0 :                 goto cleanup;
     633             : 
     634          21 :         if (local != NULL) {
     635           0 :                 pkg_debug(1, "Cleaning up old version");
     636           0 :                 if (pkg_add_cleanup_old(db, local, pkg, flags) != EPKG_OK) {
     637           0 :                         retcode = EPKG_FATAL;
     638           0 :                         goto cleanup;
     639             :                 }
     640             :         }
     641             : 
     642             :         /*
     643             :          * Execute pre-install scripts
     644             :          */
     645          21 :         if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0)
     646          20 :                 pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);
     647             : 
     648             :         /* add the user and group if necessary */
     649             : 
     650          21 :         nfiles = kh_count(pkg->files);
     651             :         /*
     652             :          * Extract the files on disk.
     653             :          */
     654          39 :         if (extract &&
     655          18 :             (retcode = do_extract(a, ae, location, nfiles, pkg, local))
     656             :             != EPKG_OK) {
     657             :                 /* If the add failed, clean up (silently) */
     658           0 :                 pkg_delete_files(pkg, 2);
     659           0 :                 pkg_delete_dirs(db, pkg, NULL);
     660           0 :                 goto cleanup_reg;
     661             :         }
     662             : 
     663             :         /* Update configuration file content with db with newer versions */
     664          21 :         pkgdb_update_config_file_content(pkg, db->sqlite);
     665             : 
     666             :         /*
     667             :          * Execute post install scripts
     668             :          */
     669          21 :         if ((flags & PKG_ADD_NOSCRIPT) == 0) {
     670          20 :                 if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS)
     671           0 :                         pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
     672             :                 else
     673          20 :                         pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
     674             :         }
     675             : 
     676             :         /*
     677             :          * start the different related services if the users do want that
     678             :          * and that the service is running
     679             :          */
     680             : 
     681          21 :         handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));
     682          21 :         if (handle_rc)
     683           0 :                 pkg_start_stop_rc_scripts(pkg, PKG_RC_START);
     684             : 
     685             :         cleanup_reg:
     686          21 :         if ((flags & PKG_ADD_UPGRADE) == 0)
     687           9 :                 pkgdb_register_finale(db, retcode);
     688             : 
     689          21 :         if (retcode == EPKG_OK) {
     690          21 :                 if ((flags & PKG_ADD_UPGRADE) == 0)
     691           9 :                         pkg_emit_install_finished(pkg);
     692             :                 else {
     693          12 :                         if (local != NULL)
     694           0 :                                 pkg_emit_upgrade_finished(pkg, local);
     695             :                         else
     696          12 :                                 pkg_emit_install_finished(pkg);
     697             :                 }
     698             :         }
     699             : 
     700             :         cleanup:
     701          23 :         if (a != NULL) {
     702          23 :                 archive_read_close(a);
     703          23 :                 archive_read_free(a);
     704             :         }
     705             : 
     706          23 :         pkg_free(pkg);
     707             : 
     708          23 :         return (retcode);
     709             : }
     710             : 
     711             : int
     712          11 : pkg_add(struct pkgdb *db, const char *path, unsigned flags,
     713             :     struct pkg_manifest_key *keys, const char *location)
     714             : {
     715          11 :         return pkg_add_common(db, path, flags, keys, location, NULL, NULL);
     716             : }
     717             : 
     718             : int
     719          12 : pkg_add_from_remote(struct pkgdb *db, const char *path, unsigned flags,
     720             :     struct pkg_manifest_key *keys, const char *location, struct pkg *rp)
     721             : {
     722          12 :         return pkg_add_common(db, path, flags, keys, location, rp, NULL);
     723             : }
     724             : 
     725             : int
     726           0 : pkg_add_upgrade(struct pkgdb *db, const char *path, unsigned flags,
     727             :     struct pkg_manifest_key *keys, const char *location,
     728             :     struct pkg *rp, struct pkg *lp)
     729             : {
     730           0 :         if (pkgdb_ensure_loaded(db, lp,
     731             :             PKG_LOAD_FILES|PKG_LOAD_SCRIPTS|PKG_LOAD_DIRS) != EPKG_OK)
     732           0 :                 return (EPKG_FATAL);
     733             : 
     734           0 :         return pkg_add_common(db, path, flags, keys, location, rp, lp);
     735             : }

Generated by: LCOV version 1.10