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 : }
|