Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/pkg
Path: blob/main/libpkg/pkg_add.c
2645 views
1
/*-
2
* Copyright (c) 2011-2025 Baptiste Daroussin <[email protected]>
3
* Copyright (c) 2011-2012 Julien Laffaye <[email protected]>
4
* Copyright (c) 2016, Vsevolod Stakhov
5
* Copyright (c) 2024, Future Crew, LLC
6
* Author: Gleb Popov <[email protected]>
7
*
8
* SPDX-License-Identifier: BSD-2-Clause
9
*/
10
11
#ifdef HAVE_CONFIG_H
12
#include "pkg_config.h"
13
#endif
14
15
#include <archive.h>
16
#include <archive_entry.h>
17
#include <assert.h>
18
#include <libgen.h>
19
#include <string.h>
20
#include <errno.h>
21
#include <fcntl.h>
22
#include <glob.h>
23
#include <pwd.h>
24
#include <grp.h>
25
#include <sys/time.h>
26
#include <sys/wait.h>
27
#include <time.h>
28
#include <xstring.h>
29
30
#include "pkg.h"
31
#include "private/event.h"
32
#include "private/utils.h"
33
#include "private/pkg.h"
34
#include "private/pkgdb.h"
35
#include "private/add.h"
36
37
#if defined(UF_NOUNLINK)
38
#define NOCHANGESFLAGS (UF_IMMUTABLE | UF_APPEND | UF_NOUNLINK | SF_IMMUTABLE | SF_APPEND | SF_NOUNLINK)
39
#else
40
#define NOCHANGESFLAGS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND)
41
#endif
42
43
struct external_merge_tmp_file {
44
int fd;
45
const char *template;
46
char path[MAXPATHLEN];
47
const char *content;
48
size_t content_len;
49
};
50
51
static merge_status
52
merge_with_external_tool(const char *merge_tool, struct pkg_config_file *lcf,
53
size_t lcf_len, struct pkg_config_file *rcf, char *localconf, char **mergedconf)
54
{
55
pid_t wait_res;
56
int status;
57
FILE *inout[2];
58
59
char *tmpdir = getenv("TMPDIR");
60
if (tmpdir == NULL)
61
tmpdir = "/tmp";
62
63
int output_fd;
64
char output_path[MAXPATHLEN];
65
off_t output_sz;
66
67
strlcpy(output_path, tmpdir, sizeof(output_path));
68
strlcat(output_path, "/OUTPUT.XXXXXXXXXX", sizeof(output_path));
69
output_fd = mkstemp(output_path);
70
if (output_fd == -1) {
71
pkg_emit_error("Can't create %s", output_path);
72
return MERGE_FAILED;
73
}
74
close(output_fd);
75
76
struct external_merge_tmp_file tmp_files[] = {
77
{-1, "/BASE.XXXXXXXXXX", {0}, lcf->content, lcf_len},
78
{-1, "/LOCAL.XXXXXXXXXX", {0}, localconf, strlen(localconf)},
79
{-1, "/REMOTE.XXXXXXXXXX", {0}, rcf->content, strlen(rcf->content)}
80
};
81
bool tmp_files_ok = true;
82
for (int i = 0; i < NELEM(tmp_files); i++) {
83
int copied = strlcpy(tmp_files[i].path, tmpdir, sizeof(tmp_files[i].path));
84
if (copied >= sizeof(tmp_files[i].path)) {
85
pkg_emit_error("Temporary path too long: %s", tmp_files[i].path);
86
return MERGE_FAILED;
87
}
88
copied = strlcat(tmp_files[i].path, tmp_files[i].template, sizeof(tmp_files[i].path));
89
if (copied >= sizeof(tmp_files[i].path)) {
90
pkg_emit_error("Temporary path too long: %s", tmp_files[i].path);
91
return MERGE_FAILED;
92
}
93
94
tmp_files[i].fd = mkstemp(tmp_files[i].path);
95
if (tmp_files[i].fd == -1) {
96
pkg_emit_error("Can't create %s", tmp_files[i].path);
97
tmp_files_ok = false;
98
break;
99
}
100
if (write(tmp_files[i].fd, tmp_files[i].content, tmp_files[i].content_len) == -1) {
101
pkg_emit_error("Failed to write %s", tmp_files[i].path);
102
tmp_files_ok = false;
103
break;
104
}
105
close(tmp_files[i].fd);
106
tmp_files[i].fd = -1;
107
}
108
if (!tmp_files_ok) {
109
for (int i = 0; i < NELEM(tmp_files); i++) {
110
if (tmp_files[i].fd != -1)
111
close(tmp_files[i].fd);
112
if (strlen(tmp_files[i].path))
113
unlink(tmp_files[i].path);
114
}
115
return MERGE_FAILED;
116
}
117
118
char command[MAXPATHLEN];
119
for (int i = 0; *merge_tool != '\0'; i++, merge_tool++) {
120
if (*merge_tool != '%') {
121
command[i] = *merge_tool;
122
continue;
123
}
124
merge_tool++;
125
int tmp_files_index;
126
switch (*merge_tool) {
127
case 'b':
128
tmp_files_index = 0;
129
break;
130
case 'l':
131
tmp_files_index = 1;
132
break;
133
case 'r':
134
tmp_files_index = 2;
135
break;
136
case 'n':
137
i += strlcpy(&command[i], RELATIVE_PATH(rcf->path), sizeof(command) - i) - 1;
138
continue;
139
case 'o':
140
i += strlcpy(&command[i], output_path, sizeof(command) - i) - 1;
141
continue;
142
default:
143
pkg_emit_error("Unknown format string in the MERGETOOL command");
144
merge_tool--;
145
continue;
146
}
147
i += strlcpy(&command[i], tmp_files[tmp_files_index].path, sizeof(command) - i) - 1;
148
}
149
150
pid_t pid = process_spawn_pipe(inout, command);
151
wait_res = waitpid(pid, &status, 0);
152
153
fclose(inout[0]);
154
fclose(inout[1]);
155
for (int i = 0; i < sizeof(tmp_files); i++) {
156
unlink(tmp_files[i].path);
157
}
158
159
if (wait_res == -1 || WIFSIGNALED(status) || WEXITSTATUS(status)) {
160
unlink(output_path);
161
pkg_emit_error("External merge tool failed, retrying with builtin algorithm");
162
return MERGE_FAILED;
163
}
164
165
file_to_bufferat(AT_FDCWD, output_path, mergedconf, &output_sz);
166
unlink(output_path);
167
168
return MERGE_SUCCESS;
169
}
170
171
static void
172
attempt_to_merge(int rootfd, struct pkg_config_file *rcf, struct pkg *local,
173
bool merge, const char *merge_tool)
174
{
175
const struct pkg_file *lf = NULL;
176
struct stat st;
177
xstring *newconf;
178
struct pkg_config_file *lcf = NULL;
179
size_t lcf_len;
180
181
char *localconf = NULL;
182
off_t sz;
183
char *localsum;
184
185
if (local == NULL) {
186
pkg_debug(3, "No local package");
187
if (fstatat(rootfd, RELATIVE_PATH(rcf->path), &st, 0) == 0) {
188
rcf->status = MERGE_NOT_LOCAL;
189
}
190
return;
191
}
192
193
if (!pkg_is_config_file(local, rcf->path, &lf, &lcf)) {
194
pkg_debug(3, "No local package");
195
rcf->status = MERGE_FAILED;
196
return;
197
}
198
199
if (lcf->content == NULL) {
200
pkg_debug(3, "Empty configuration content for local package");
201
return;
202
}
203
204
pkg_debug(1, "Config file found %s", rcf->path);
205
if (file_to_bufferat(rootfd, RELATIVE_PATH(rcf->path), &localconf, &sz) != EPKG_OK)
206
return;
207
208
pkg_debug(2, "size: %jd vs %jd", (intmax_t)sz, (intmax_t)strlen(lcf->content));
209
210
lcf_len = strlen(lcf->content);
211
if (sz == lcf_len) {
212
pkg_debug(2, "Ancient vanilla and deployed conf are the same size testing checksum");
213
localsum = pkg_checksum_data(localconf, sz,
214
PKG_HASH_TYPE_SHA256_HEX);
215
if (localsum != NULL && lf->sum != NULL && STREQ(localsum, lf->sum)) {
216
pkg_debug(2, "Checksum are the same %jd", (intmax_t)strlen(localconf));
217
free(localsum);
218
goto ret;
219
}
220
if (lf->sum == NULL)
221
pkg_emit_error("3way merge: no checksum for the original local file");
222
free(localsum);
223
pkg_debug(2, "Checksum are different %jd", (intmax_t)strlen(localconf));
224
}
225
rcf->status = MERGE_FAILED;
226
if (!merge) {
227
goto ret;
228
}
229
230
pkg_debug(1, "Attempting to merge %s", rcf->path);
231
if (merge_tool) {
232
char* mergedconf = NULL;
233
rcf->status = merge_with_external_tool(merge_tool, lcf, lcf_len, rcf, localconf, &mergedconf);
234
rcf->newcontent = mergedconf;
235
if (rcf->status == MERGE_SUCCESS)
236
goto ret;
237
}
238
newconf = xstring_new();
239
if (merge_3way(lcf->content, localconf, rcf->content, newconf) != 0) {
240
xstring_free(newconf);
241
pkg_emit_error("Impossible to merge configuration file: %s", rcf->path);
242
} else {
243
char *conf = xstring_get(newconf);
244
rcf->newcontent = conf;
245
rcf->status = MERGE_SUCCESS;
246
}
247
ret:
248
free(localconf);
249
}
250
251
static int
252
set_chflags(int fd, const char *path, u_long fflags)
253
{
254
#ifdef HAVE_CHFLAGSAT
255
if (getenv("INSTALL_AS_USER"))
256
return (EPKG_OK);
257
if (fflags == 0)
258
return (EPKG_OK);
259
if (chflagsat(fd, RELATIVE_PATH(path), fflags, AT_SYMLINK_NOFOLLOW) == -1) {
260
pkg_fatal_errno("Fail to chflags %s", path);
261
}
262
#endif
263
return (EPKG_OK);
264
}
265
int
266
set_attrsat(int fd, const char *path, mode_t perm, uid_t uid, gid_t gid,
267
const struct timespec *ats, const struct timespec *mts)
268
{
269
struct stat st;
270
struct timespec times[2];
271
272
times[0] = *ats;
273
times[1] = *mts;
274
if (utimensat(fd, RELATIVE_PATH(path), times,
275
AT_SYMLINK_NOFOLLOW) == -1 && errno != EOPNOTSUPP){
276
pkg_fatal_errno("Fail to set time on %s", path);
277
}
278
279
if (getenv("INSTALL_AS_USER") == NULL) {
280
if (fchownat(fd, RELATIVE_PATH(path), uid, gid,
281
AT_SYMLINK_NOFOLLOW) == -1) {
282
if (errno == ENOTSUP) {
283
if (fchownat(fd, RELATIVE_PATH(path), uid, gid, 0) == -1) {
284
pkg_fatal_errno("Fail to chown(fallback) %s", path);
285
}
286
}
287
else {
288
pkg_fatal_errno("Fail to chown %s", path);
289
}
290
}
291
}
292
293
/* zfs drops the setuid on fchownat */
294
if (fchmodat(fd, RELATIVE_PATH(path), perm, AT_SYMLINK_NOFOLLOW) == -1) {
295
if (errno == ENOTSUP) {
296
/*
297
* Executing fchmodat on a symbolic link results in
298
* ENOENT (file not found) on platforms that do not
299
* support AT_SYMLINK_NOFOLLOW. The file mode of
300
* symlinks cannot be modified via file descriptor
301
* reference on these systems. The lchmod function is
302
* also not an option because it is not a posix
303
* standard, nor is implemented everywhere. Since
304
* symlink permissions have never been evaluated and
305
* thus cosmetic, just skip them on these systems.
306
*/
307
if (fstatat(fd, RELATIVE_PATH(path), &st, AT_SYMLINK_NOFOLLOW) == -1) {
308
pkg_fatal_errno("Fail to get file status %s", path);
309
}
310
if (!S_ISLNK(st.st_mode)) {
311
if (fchmodat(fd, RELATIVE_PATH(path), perm, 0) == -1) {
312
pkg_fatal_errno("Fail to chmod(fallback) %s", path);
313
}
314
}
315
}
316
else {
317
pkg_fatal_errno("Fail to chmod %s", path);
318
}
319
}
320
321
return (EPKG_OK);
322
}
323
324
static void
325
fill_timespec_buf(const struct stat *aest, struct timespec tspec[2])
326
{
327
#ifdef HAVE_STRUCT_STAT_ST_MTIM
328
tspec[0].tv_sec = aest->st_atim.tv_sec;
329
tspec[0].tv_nsec = 0;
330
tspec[1].tv_sec = aest->st_mtim.tv_sec;
331
tspec[1].tv_nsec = 0;
332
#else
333
# if defined(_DARWIN_C_SOURCE) || defined(__APPLE__)
334
tspec[0].tv_sec = aest->st_atimespec.tv_sec;
335
tspec[0].tv_nsec = 0;
336
tspec[1].tv_sec = aest->st_mtimespec.tv_sec;
337
tspec[1].tv_nsec = 0;
338
# else
339
/* Portable unix version */
340
tspec[0].tv_sec = aest->st_atime;
341
tspec[0].tv_nsec = 0;
342
tspec[1].tv_sec = aest->st_mtime;
343
tspec[1].tv_nsec = 0;
344
# endif
345
#endif
346
}
347
348
static void
349
reopen_tempdir(int rootfd, struct tempdir *t)
350
{
351
if (t->fd != -1)
352
return;
353
t->fd = openat(rootfd, RELATIVE_PATH(t->temp), O_DIRECTORY|O_CLOEXEC);
354
}
355
356
static struct tempdir *
357
get_tempdir(struct pkg_add_context *context, const char *path, tempdirs_t *tempdirs)
358
{
359
struct tempdir *tmpdir = NULL;
360
361
vec_foreach(*tempdirs, i) {
362
tmpdir = tempdirs->d[i];
363
if (strncmp(tmpdir->name, path, tmpdir->len) == 0 && path[tmpdir->len] == '/') {
364
reopen_tempdir(context->rootfd, tmpdir);
365
return (tmpdir);
366
}
367
}
368
369
tmpdir = open_tempdir(context, path);
370
if (tmpdir != NULL)
371
vec_push(tempdirs, tmpdir);
372
373
return (tmpdir);
374
}
375
376
static void
377
close_tempdir(struct tempdir *t)
378
{
379
if (t == NULL)
380
return;
381
if (t->fd != -1)
382
close(t->fd);
383
t->fd = -1;
384
}
385
386
static int
387
create_dir(struct pkg_add_context *context, struct pkg_dir *d,
388
tempdirs_t *tempdirs)
389
{
390
struct stat st;
391
struct tempdir *tmpdir;
392
const char *path;
393
int error, fd;
394
395
tmpdir = get_tempdir(context, d->path, tempdirs);
396
if (tmpdir == NULL) {
397
fd = context->rootfd;
398
path = d->path;
399
} else {
400
fd = tmpdir->fd;
401
path = d->path + tmpdir->len;
402
}
403
404
if (mkdirat(fd, RELATIVE_PATH(path), 0755) == -1) {
405
if (!mkdirat_p(fd, RELATIVE_PATH(path))) {
406
close_tempdir(tmpdir);
407
return (EPKG_FATAL);
408
}
409
}
410
411
if (fstatat(fd, RELATIVE_PATH(path), &st, 0) == -1) {
412
if (errno != ENOENT) {
413
close_tempdir(tmpdir);
414
pkg_fatal_errno("Fail to stat directory %s", d->path);
415
}
416
/* path is a dangling symlink. */
417
error = unlinkat(fd, RELATIVE_PATH(path), 0);
418
if (error != 0) {
419
close_tempdir(tmpdir);
420
pkg_fatal_errno("Fail to unlink dangling symlink %s",
421
d->path);
422
}
423
if (mkdirat(fd, RELATIVE_PATH(path), 0755) == -1) {
424
if (tmpdir != NULL) {
425
close_tempdir(tmpdir);
426
pkg_fatal_errno(
427
"Fail to create directory %s/%s",
428
tmpdir->temp, path);
429
} else {
430
pkg_fatal_errno("Fail to create directory %s",
431
path);
432
}
433
}
434
if (fstatat(fd, RELATIVE_PATH(path), &st, 0) == -1) {
435
close_tempdir(tmpdir);
436
pkg_fatal_errno("Fail to stat directory %s", d->path);
437
}
438
}
439
440
if (st.st_uid == d->uid && st.st_gid == d->gid &&
441
(st.st_mode & ~S_IFMT) == (d->perm & ~S_IFMT)) {
442
d->noattrs = true;
443
}
444
445
close_tempdir(tmpdir);
446
return (EPKG_OK);
447
}
448
449
/* In case of directories create the dir and extract the creds */
450
static int
451
do_extract_dir(struct pkg_add_context* context, struct archive *a __unused, struct archive_entry *ae,
452
const char *path, struct pkg *local __unused, tempdirs_t *tempdirs)
453
{
454
struct pkg_dir *d;
455
const struct stat *aest;
456
unsigned long clear;
457
458
d = pkg_get_dir(context->pkg, path);
459
if (d == NULL) {
460
pkg_emit_error("Directory %s not specified in the manifest, skipping",
461
path);
462
return (EPKG_OK);
463
}
464
aest = archive_entry_stat(ae);
465
d->perm = aest->st_mode;
466
d->uid = get_uid_from_uname(archive_entry_uname(ae));
467
d->gid = get_gid_from_gname(archive_entry_gname(ae));
468
free(d->uname);
469
d->uname = xstrdup(archive_entry_uname(ae));
470
free(d->gname);
471
d->gname = xstrdup(archive_entry_gname(ae));
472
fill_timespec_buf(aest, d->time);
473
archive_entry_fflags(ae, &d->fflags, &clear);
474
475
if (create_dir(context, d, tempdirs) == EPKG_FATAL) {
476
return (EPKG_FATAL);
477
}
478
479
metalog_add(PKG_METALOG_DIR, RELATIVE_PATH(path),
480
archive_entry_uname(ae), archive_entry_gname(ae),
481
aest->st_mode & ~S_IFDIR, d->fflags, NULL);
482
483
return (EPKG_OK);
484
}
485
486
487
static bool
488
try_mkdir(int fd, const char *path)
489
{
490
char *p = get_dirname(xstrdup(path));
491
492
if (!mkdirat_p(fd, RELATIVE_PATH(p))) {
493
free(p);
494
return (false);
495
}
496
free(p);
497
return (true);
498
}
499
500
static int
501
create_symlinks(struct pkg_add_context *context, struct pkg_file *f, const char *target, tempdirs_t *tempdirs)
502
{
503
struct tempdir *tmpdir = NULL;
504
int fd;
505
const char *path;
506
bool tried_mkdir = false;
507
508
tmpdir = get_tempdir(context, f->path, tempdirs);
509
if (tmpdir == NULL && errno == 0) {
510
char temppath[MAXPATHLEN] = { 0 };
511
hidden_tempfile(temppath, sizeof(temppath), f->path);
512
f->temppath = xstrdup(temppath);
513
}
514
if (tmpdir == NULL) {
515
fd = context->rootfd;
516
path = f->temppath;
517
} else {
518
fd = tmpdir->fd;
519
path = f->path + tmpdir->len;
520
}
521
retry:
522
if (symlinkat(target, fd, RELATIVE_PATH(path)) == -1) {
523
if (!tried_mkdir) {
524
if (!try_mkdir(fd, path)) {
525
close_tempdir(tmpdir);
526
return (EPKG_FATAL);
527
}
528
tried_mkdir = true;
529
goto retry;
530
}
531
532
pkg_fatal_errno("Fail to create symlink: %s", path);
533
}
534
535
if (set_attrsat(fd, path, f->perm, f->uid, f->gid,
536
&f->time[0], &f->time[1]) != EPKG_OK) {
537
close_tempdir(tmpdir);
538
return (EPKG_FATAL);
539
}
540
if (tmpdir != NULL)
541
set_chflags(fd, path, f->fflags);
542
close_tempdir(tmpdir);
543
544
return (EPKG_OK);
545
}
546
547
/* In case of a symlink create it directly with a random name */
548
static int
549
do_extract_symlink(struct pkg_add_context *context, struct archive *a __unused,
550
struct archive_entry *ae, const char *path, struct pkg *local __unused,
551
tempdirs_t *tempdirs)
552
{
553
struct pkg_file *f;
554
const struct stat *aest;
555
unsigned long clear;
556
557
f = pkg_get_file(context->pkg, path);
558
if (f == NULL) {
559
pkg_emit_error("Symlink %s not specified in the manifest", path);
560
return (EPKG_FATAL);
561
}
562
563
aest = archive_entry_stat(ae);
564
archive_entry_fflags(ae, &f->fflags, &clear);
565
f->uid = get_uid_from_uname(archive_entry_uname(ae));
566
f->gid = get_gid_from_gname(archive_entry_gname(ae));
567
free(f->uname);
568
f->uname = xstrdup(archive_entry_uname(ae));
569
free(f->gname);
570
f->gname = xstrdup(archive_entry_gname(ae));
571
f->perm = aest->st_mode;
572
fill_timespec_buf(aest, f->time);
573
archive_entry_fflags(ae, &f->fflags, &clear);
574
575
if (create_symlinks(context, f, archive_entry_symlink(ae), tempdirs) == EPKG_FATAL)
576
return (EPKG_FATAL);
577
578
metalog_add(PKG_METALOG_LINK, RELATIVE_PATH(path),
579
archive_entry_uname(ae), archive_entry_gname(ae),
580
aest->st_mode & ~S_IFLNK, f->fflags, archive_entry_symlink(ae));
581
582
return (EPKG_OK);
583
}
584
585
static int
586
create_hardlink(struct pkg_add_context *context, struct pkg_file *f, const char *path, tempdirs_t *tempdirs)
587
{
588
bool tried_mkdir = false;
589
struct pkg_file *fh;
590
int fd, fdh;
591
const char *pathfrom, *pathto;
592
struct tempdir *tmpdir = NULL;
593
struct tempdir *tmphdir = NULL;
594
595
tmpdir = get_tempdir(context, f->path, tempdirs);
596
if (tmpdir == NULL && errno == 0) {
597
char temppath[MAXPATHLEN] = { 0 };
598
hidden_tempfile(temppath, sizeof(temppath), f->path);
599
f->temppath = xstrdup(temppath);
600
}
601
if (tmpdir != NULL) {
602
fd = tmpdir->fd;
603
} else {
604
fd = context->rootfd;
605
}
606
fh = pkg_get_file(context->pkg, path);
607
if (fh == NULL) {
608
close_tempdir(tmpdir);
609
pkg_emit_error("Can't find the file %s is supposed to be"
610
" hardlinked to %s", f->path, path);
611
return (EPKG_FATAL);
612
}
613
if (fh->temppath == NULL) {
614
vec_foreach(*tempdirs, i) {
615
if (strncmp(tempdirs->d[i]->name, fh->path, tempdirs->d[i]->len) == 0 &&
616
fh->path[tempdirs->d[i]->len] == '/' ) {
617
tmphdir = tempdirs->d[i];
618
reopen_tempdir(context->rootfd, tmphdir);
619
break;
620
}
621
}
622
}
623
if (tmpdir == NULL) {
624
pathto = f->temppath;
625
fd = context->rootfd;
626
} else {
627
pathto = f->path + tmpdir->len;
628
fd = tmpdir->fd;
629
}
630
631
if (tmphdir == NULL) {
632
pathfrom = fh->temppath;
633
fdh = context->rootfd;
634
} else {
635
pathfrom = fh->path + tmphdir->len;
636
fdh = tmphdir->fd;
637
}
638
639
retry:
640
if (linkat(fdh, RELATIVE_PATH(pathfrom),
641
fd, RELATIVE_PATH(pathto), 0) == -1) {
642
if (!tried_mkdir) {
643
if (!try_mkdir(fd, pathto)) {
644
close_tempdir(tmpdir);
645
close_tempdir(tmphdir);
646
return (EPKG_FATAL);
647
}
648
tried_mkdir = true;
649
goto retry;
650
}
651
652
close_tempdir(tmpdir);
653
close_tempdir(tmphdir);
654
pkg_fatal_errno("Fail to create hardlink: %s <-> %s", pathfrom, pathto);
655
}
656
close_tempdir(tmpdir);
657
close_tempdir(tmphdir);
658
659
return (EPKG_OK);
660
}
661
662
static int
663
do_extract_hardlink(struct pkg_add_context *context, struct archive *a __unused, struct archive_entry *ae,
664
const char *path, struct pkg *local __unused, tempdirs_t *tempdirs)
665
{
666
struct pkg_file *f;
667
const struct stat *aest;
668
const char *lp;
669
670
f = pkg_get_file(context->pkg, path);
671
if (f == NULL) {
672
pkg_emit_error("Hardlink %s not specified in the manifest", path);
673
return (EPKG_FATAL);
674
}
675
lp = archive_entry_hardlink(ae);
676
aest = archive_entry_stat(ae);
677
678
if (create_hardlink(context, f, lp, tempdirs) == EPKG_FATAL)
679
return (EPKG_FATAL);
680
681
metalog_add(PKG_METALOG_FILE, RELATIVE_PATH(path),
682
archive_entry_uname(ae), archive_entry_gname(ae),
683
aest->st_mode & ~S_IFREG, 0, NULL);
684
685
return (EPKG_OK);
686
}
687
688
static int
689
open_tempfile(int rootfd, const char *path, int perm)
690
{
691
int fd;
692
bool tried_mkdir = false;
693
694
retry:
695
fd = openat(rootfd, RELATIVE_PATH(path), O_CREAT|O_WRONLY|O_EXCL, perm);
696
if (fd == -1) {
697
if (!tried_mkdir) {
698
if (!try_mkdir(rootfd, path))
699
return (-2);
700
tried_mkdir = true;
701
goto retry;
702
}
703
return (-1);
704
}
705
return (fd);
706
}
707
708
static int
709
create_regfile(struct pkg_add_context *context, struct pkg_file *f, struct archive *a,
710
struct archive_entry *ae, int fromfd, struct pkg *local, tempdirs_t *tempdirs)
711
{
712
int fd = -1;
713
size_t len;
714
char buf[32768];
715
char *path;
716
struct tempdir *tmpdir = NULL;
717
718
tmpdir = get_tempdir(context, f->path, tempdirs);
719
if (tmpdir == NULL && errno == 0) {
720
char temppath[MAXPATHLEN] = { 0 };
721
hidden_tempfile(temppath, sizeof(temppath), f->path);
722
f->temppath = xstrdup(temppath);
723
}
724
725
if (tmpdir != NULL) {
726
fd = open_tempfile(tmpdir->fd, f->path + tmpdir->len, f->perm);
727
} else {
728
fd = open_tempfile(context->rootfd, f->temppath, f->perm);
729
}
730
if (fd == -2) {
731
close_tempdir(tmpdir);
732
return (EPKG_FATAL);
733
}
734
735
if (fd == -1) {
736
if (tmpdir != NULL) {
737
close_tempdir(tmpdir);
738
pkg_fatal_errno("Fail to create temporary file '%s/%s' for %s", tmpdir->name, f->path + tmpdir->len, f->path);
739
}
740
pkg_fatal_errno("Fail to create temporary file for %s", f->path);
741
}
742
743
if (fromfd == -1) {
744
/* check if this is a config file */
745
f->config = pkghash_get_value(context->pkg->config_files_hash, f->path);
746
if (f->config) {
747
const char *cfdata;
748
bool merge = pkg_object_bool(pkg_config_get("AUTOMERGE"));
749
const char *merge_tool = pkg_object_string(pkg_config_get("MERGETOOL"));
750
751
pkg_debug(1, "Populating config_file %s", f->path);
752
len = archive_entry_size(ae);
753
f->config->content = xmalloc(len + 1);
754
archive_read_data(a, f->config->content, len);
755
f->config->content[len] = '\0';
756
cfdata = f->config->content;
757
attempt_to_merge(context->rootfd, f->config, local, merge, merge_tool);
758
if (f->config->status == MERGE_SUCCESS)
759
cfdata = f->config->newcontent;
760
dprintf(fd, "%s", cfdata);
761
if (f->config->newcontent != NULL)
762
free(f->config->newcontent);
763
} else {
764
if (ftruncate(fd, archive_entry_size(ae)) == -1) {
765
close_tempdir(tmpdir);
766
pkg_errno("Fail to truncate file: %s", f->temppath);
767
}
768
}
769
770
if (!f->config && archive_read_data_into_fd(a, fd) != ARCHIVE_OK) {
771
close_tempdir(tmpdir);
772
pkg_emit_error("Fail to extract %s from package: %s",
773
f->path, archive_error_string(a));
774
return (EPKG_FATAL);
775
}
776
} else {
777
while ((len = read(fromfd, buf, sizeof(buf))) > 0)
778
if (write(fd, buf, len) == -1) {
779
pkg_errno("Fail to write file: %s", f->temppath);
780
}
781
}
782
if (fd != -1)
783
close(fd);
784
if (tmpdir == NULL) {
785
fd = context->rootfd;
786
path = f->temppath;
787
} else {
788
fd = tmpdir->fd;
789
path = f->path + tmpdir->len;
790
}
791
792
if (set_attrsat(fd, path, f->perm, f->uid, f->gid,
793
&f->time[0], &f->time[1]) != EPKG_OK) {
794
close_tempdir(tmpdir);
795
return (EPKG_FATAL);
796
}
797
if (tmpdir != NULL)
798
set_chflags(fd, path, f->fflags);
799
800
close_tempdir(tmpdir);
801
return (EPKG_OK);
802
}
803
804
static int
805
do_extract_regfile(struct pkg_add_context *context, struct archive *a, struct archive_entry *ae,
806
const char *path, struct pkg *local, tempdirs_t *tempdirs)
807
{
808
struct pkg_file *f;
809
const struct stat *aest;
810
unsigned long clear;
811
812
f = pkg_get_file(context->pkg, path);
813
if (f == NULL) {
814
pkg_emit_error("File %s not specified in the manifest", path);
815
return (EPKG_FATAL);
816
}
817
818
aest = archive_entry_stat(ae);
819
archive_entry_fflags(ae, &f->fflags, &clear);
820
f->perm = aest->st_mode;
821
f->uid = get_uid_from_uname(archive_entry_uname(ae));
822
f->gid = get_gid_from_gname(archive_entry_gname(ae));
823
free(f->uname);
824
f->uname = xstrdup(archive_entry_uname(ae));
825
free(f->gname);
826
f->gname = xstrdup(archive_entry_gname(ae));
827
fill_timespec_buf(aest, f->time);
828
archive_entry_fflags(ae, &f->fflags, &clear);
829
830
if (create_regfile(context, f, a, ae, -1, local, tempdirs) == EPKG_FATAL)
831
return (EPKG_FATAL);
832
833
metalog_add(PKG_METALOG_FILE, RELATIVE_PATH(path),
834
archive_entry_uname(ae), archive_entry_gname(ae),
835
aest->st_mode & ~S_IFREG, f->fflags, NULL);
836
837
return (EPKG_OK);
838
}
839
840
static int
841
do_extract(struct archive *a, struct archive_entry *ae,
842
int nfiles, struct pkg *local, tempdirs_t *tempdirs,
843
struct pkg_add_context *context)
844
{
845
int retcode = EPKG_OK;
846
int ret = 0, cur_file = 0;
847
char path[MAXPATHLEN];
848
int (*extract_cb)(struct pkg_add_context *context, struct archive *a,
849
struct archive_entry *ae, const char *path, struct pkg *local,
850
tempdirs_t *tempdirs);
851
852
#ifndef HAVE_ARC4RANDOM
853
srand(time(NULL));
854
#endif
855
856
if (nfiles == 0)
857
return (EPKG_OK);
858
859
pkg_emit_extract_begin(context->pkg);
860
pkg_emit_progress_start(NULL);
861
862
do {
863
pkg_absolutepath(archive_entry_pathname(ae), path, sizeof(path), true);
864
if (match_ucl_lists(path,
865
pkg_config_get("FILES_IGNORE_GLOB"),
866
pkg_config_get("FILES_IGNORE_REGEX")))
867
continue;
868
switch (archive_entry_filetype(ae)) {
869
case AE_IFDIR:
870
extract_cb = do_extract_dir;
871
break;
872
case AE_IFLNK:
873
extract_cb = do_extract_symlink;
874
break;
875
case 0: /* HARDLINKS */
876
extract_cb = do_extract_hardlink;
877
break;
878
case AE_IFREG:
879
extract_cb = do_extract_regfile;
880
break;
881
case AE_IFMT:
882
pkg_emit_error("Archive contains an unsupported filetype (AE_IFMT): %s", path);
883
retcode = EPKG_FATAL;
884
goto cleanup;
885
break;
886
case AE_IFSOCK:
887
pkg_emit_error("Archive contains an unsupported filetype (AE_IFSOCK): %s", path);
888
retcode = EPKG_FATAL;
889
goto cleanup;
890
break;
891
case AE_IFCHR:
892
pkg_emit_error("Archive contains an unsupported filetype (AE_IFCHR): %s", path);
893
retcode = EPKG_FATAL;
894
goto cleanup;
895
break;
896
case AE_IFIFO:
897
pkg_emit_error("Archive contains an unsupported filetype (AE_IFIFO): %s", path);
898
retcode = EPKG_FATAL;
899
goto cleanup;
900
break;
901
case AE_IFBLK:
902
pkg_emit_error("Archive contains an unsupported filetype (AE_IFBLK): %s", path);
903
retcode = EPKG_FATAL;
904
goto cleanup;
905
break;
906
default:
907
pkg_emit_error("Archive contains an unsupported filetype (%d): %s", archive_entry_filetype(ae), path);
908
retcode = EPKG_FATAL;
909
goto cleanup;
910
break;
911
}
912
913
if (extract_cb(context, a, ae, path, local, tempdirs) != EPKG_OK) {
914
retcode = EPKG_FATAL;
915
goto cleanup;
916
}
917
if (archive_entry_filetype(ae) != AE_IFDIR) {
918
pkg_emit_progress_tick(cur_file++, nfiles);
919
}
920
} while ((ret = archive_read_next_header(a, &ae)) == ARCHIVE_OK);
921
pkg_emit_progress_tick(cur_file++, nfiles);
922
923
if (ret != ARCHIVE_EOF) {
924
pkg_emit_error("archive_read_next_header(): %s",
925
archive_error_string(a));
926
retcode = EPKG_FATAL;
927
}
928
929
cleanup:
930
pkg_emit_progress_tick(nfiles, nfiles);
931
pkg_emit_extract_finished(context->pkg);
932
933
return (retcode);
934
}
935
936
static void
937
backup_file_if_needed(struct pkg *p, struct pkg_file *f)
938
{
939
char path[MAXPATHLEN];
940
struct stat st;
941
char *sum;
942
pkg_checksum_type_t t;
943
944
if (fstatat(p->rootfd, RELATIVE_PATH(f->path), &st,
945
AT_SYMLINK_NOFOLLOW) == -1)
946
return;
947
948
if (S_ISLNK(st.st_mode))
949
return;
950
951
if (S_ISREG(st.st_mode)) {
952
t = pkg_checksum_file_get_type(f->sum, -1);
953
sum = pkg_checksum_generate_fileat(p->rootfd,
954
RELATIVE_PATH(f->path), t);
955
if (sum == NULL)
956
return;
957
958
if (STREQ(sum, f->sum)) {
959
free(sum);
960
return;
961
}
962
free(sum);
963
}
964
965
snprintf(path, sizeof(path), "%s.pkgsave", f->path);
966
renameat(p->rootfd, RELATIVE_PATH(f->path),
967
p->rootfd, RELATIVE_PATH(path));
968
}
969
970
static int
971
pkg_extract_finalize(struct pkg *pkg, tempdirs_t *tempdirs)
972
{
973
struct stat st;
974
struct pkg_file *f = NULL;
975
struct pkg_dir *d = NULL;
976
char path[MAXPATHLEN + 8];
977
const char *fto;
978
#ifdef HAVE_CHFLAGSAT
979
bool install_as_user;
980
981
install_as_user = (getenv("INSTALL_AS_USER") != NULL);
982
#endif
983
984
985
if (tempdirs != NULL) {
986
vec_foreach(*tempdirs, i) {
987
struct tempdir *t = tempdirs->d[i];
988
if (renameat(pkg->rootfd, RELATIVE_PATH(t->temp),
989
pkg->rootfd, RELATIVE_PATH(t->name)) != 0) {
990
pkg_fatal_errno("Fail to rename %s -> %s",
991
t->temp, t->name);
992
}
993
free(t);
994
}
995
}
996
while (pkg_files(pkg, &f) == EPKG_OK) {
997
998
if (match_ucl_lists(f->path,
999
pkg_config_get("FILES_IGNORE_GLOB"),
1000
pkg_config_get("FILES_IGNORE_REGEX")))
1001
continue;
1002
append_touched_file(f->path);
1003
if (f->temppath == NULL)
1004
continue;
1005
fto = f->path;
1006
if (f->config && f->config->status == MERGE_FAILED &&
1007
f->previous != PKG_FILE_NONE) {
1008
snprintf(path, sizeof(path), "%s.pkgnew", f->path);
1009
fto = path;
1010
}
1011
1012
if (f->config && f->config->status == MERGE_NOT_LOCAL) {
1013
backup_file_if_needed(pkg, f);
1014
}
1015
1016
/*
1017
* enforce an unlink of the file to workaround a bug that
1018
* results in renameat returning 0 of the from file is hardlink
1019
* on the to file, but the to file is not removed
1020
*/
1021
if (f->previous != PKG_FILE_NONE &&
1022
fstatat(pkg->rootfd, RELATIVE_PATH(fto), &st,
1023
AT_SYMLINK_NOFOLLOW) != -1) {
1024
#ifdef HAVE_CHFLAGSAT
1025
if (!install_as_user && st.st_flags & NOCHANGESFLAGS) {
1026
chflagsat(pkg->rootfd, RELATIVE_PATH(fto), 0,
1027
AT_SYMLINK_NOFOLLOW);
1028
}
1029
#endif
1030
/* if the files does not belong to any package, we do save it */
1031
if (f->previous == PKG_FILE_SAVE) {
1032
backup_file_if_needed(pkg, f);
1033
}
1034
unlinkat(pkg->rootfd, RELATIVE_PATH(fto), 0);
1035
}
1036
if (renameat(pkg->rootfd, RELATIVE_PATH(f->temppath),
1037
pkg->rootfd, RELATIVE_PATH(fto)) == -1) {
1038
pkg_fatal_errno("Fail to rename %s -> %s",
1039
f->temppath, fto);
1040
}
1041
1042
if (set_chflags(pkg->rootfd, fto, f->fflags) != EPKG_OK)
1043
return (EPKG_FATAL);
1044
}
1045
1046
while (pkg_dirs(pkg, &d) == EPKG_OK) {
1047
append_touched_dir(d->path);
1048
if (d->noattrs)
1049
continue;
1050
if (set_attrsat(pkg->rootfd, d->path, d->perm,
1051
d->uid, d->gid, &d->time[0], &d->time[1]) != EPKG_OK)
1052
return (EPKG_FATAL);
1053
if (set_chflags(pkg->rootfd, d->path, d->fflags) != EPKG_OK)
1054
return (EPKG_FATAL);
1055
}
1056
if (tempdirs != NULL)
1057
vec_free(tempdirs);
1058
1059
return (EPKG_OK);
1060
}
1061
1062
static char *
1063
pkg_globmatch(char *pattern, const char *name)
1064
{
1065
glob_t g;
1066
int i;
1067
char *buf, *buf2;
1068
char *path = NULL;
1069
1070
if (glob(pattern, 0, NULL, &g) == GLOB_NOMATCH) {
1071
globfree(&g);
1072
1073
return (NULL);
1074
}
1075
1076
for (i = 0; i < g.gl_pathc; i++) {
1077
/* the version starts here */
1078
buf = strrchr(g.gl_pathv[i], '-');
1079
if (buf == NULL)
1080
continue;
1081
buf2 = strrchr(g.gl_pathv[i], '/');
1082
if (buf2 == NULL)
1083
buf2 = g.gl_pathv[i];
1084
else
1085
buf2++;
1086
/* ensure we have match the proper name */
1087
if (strncmp(buf2, name, buf - buf2) != 0)
1088
continue;
1089
if (path == NULL) {
1090
path = g.gl_pathv[i];
1091
continue;
1092
}
1093
if (pkg_version_cmp(g.gl_pathv[i], path) == 1)
1094
path = g.gl_pathv[i];
1095
}
1096
if (path)
1097
path = xstrdup(path);
1098
globfree(&g);
1099
1100
return (path);
1101
}
1102
1103
bool
1104
append_pkg_if_newer(pkgs_t *localpkgs, struct pkg *p)
1105
{
1106
/* only keep the highest version if we find one */
1107
struct pkg **lp = pkgs_insert_sorted(localpkgs, p);
1108
if (lp != NULL) {
1109
if (pkg_version_cmp((*lp)->version, p->version) == -1) {
1110
pkg_free(*lp);
1111
*lp = p;
1112
return (true);
1113
}
1114
return (false);
1115
}
1116
return (true);
1117
}
1118
1119
static int
1120
pkg_add_check_pkg_archive(struct pkgdb *db, struct pkg *pkg,
1121
const char *path, int flags, const char *location)
1122
{
1123
const char *arch;
1124
int ret, retcode;
1125
struct pkg_dep *dep = NULL;
1126
char bd[MAXPATHLEN];
1127
char dpath[MAXPATHLEN], *ppath;
1128
const char *ext = NULL;
1129
struct pkg *pkg_inst = NULL;
1130
bool fromstdin;
1131
1132
arch = pkg->abi != NULL ? pkg->abi : pkg->altabi;
1133
1134
if (!is_valid_abi(arch, true) && (flags & PKG_ADD_FORCE) == 0) {
1135
return (EPKG_FATAL);
1136
}
1137
1138
if (!is_valid_os_version(pkg) && (flags & PKG_ADD_FORCE) == 0) {
1139
return (EPKG_FATAL);
1140
}
1141
1142
/* XX check */
1143
ret = pkg_try_installed(db, pkg->name, &pkg_inst, PKG_LOAD_BASIC);
1144
if (ret == EPKG_OK) {
1145
if ((flags & PKG_ADD_FORCE) == 0) {
1146
pkg_emit_already_installed(pkg_inst);
1147
pkg_free(pkg_inst);
1148
pkg_inst = NULL;
1149
return (EPKG_INSTALLED);
1150
}
1151
if (pkg_inst->locked) {
1152
pkg_emit_locked(pkg_inst);
1153
pkg_free(pkg_inst);
1154
pkg_inst = NULL;
1155
return (EPKG_LOCKED);
1156
}
1157
pkg_emit_notice("package %s is already installed, forced "
1158
"install", pkg->name);
1159
pkg_free(pkg_inst);
1160
pkg_inst = NULL;
1161
} else if (ret != EPKG_END) {
1162
return (ret);
1163
}
1164
1165
/*
1166
* Check for dependencies by searching the same directory as
1167
* the package archive we're reading. Of course, if we're
1168
* reading from a file descriptor or a unix domain socket or
1169
* whatever, there's no valid directory to search.
1170
*/
1171
fromstdin = STREQ(path, "-");
1172
strlcpy(bd, path, sizeof(bd));
1173
if (!fromstdin) {
1174
/* In-place truncate bd to the directory components. */
1175
char *basedir = strrchr(bd, '/');
1176
if (NULL == basedir) {
1177
bd[0]='.';
1178
bd[1]='\0';
1179
} else {
1180
*basedir = '\0';
1181
}
1182
if ((ext = strrchr(path, '.')) == NULL) {
1183
pkg_emit_error("%s has no extension", path);
1184
return (EPKG_FATAL);
1185
}
1186
}
1187
1188
retcode = EPKG_FATAL;
1189
pkg_emit_add_deps_begin(pkg);
1190
1191
while (pkg_deps(pkg, &dep) == EPKG_OK) {
1192
dpath[0] = '\0';
1193
1194
if (pkg_is_installed(db, dep->name) == EPKG_OK)
1195
continue;
1196
1197
if (fromstdin) {
1198
pkg_emit_missing_dep(pkg, dep);
1199
if ((flags & PKG_ADD_FORCE_MISSING) == 0)
1200
goto cleanup;
1201
continue;
1202
}
1203
1204
if (dep->version != NULL && dep->version[0] != '\0') {
1205
snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", bd,
1206
dep->name, dep->version, ext);
1207
}
1208
1209
if (strlen(dpath) == 0 || access(dpath, F_OK) != 0) {
1210
snprintf(dpath, sizeof(dpath), "%s/%s-*%s", bd,
1211
dep->name, ext);
1212
ppath = pkg_globmatch(dpath, dep->name);
1213
if (ppath == NULL) {
1214
pkg_emit_missing_dep(pkg, dep);
1215
if ((flags & PKG_ADD_FORCE_MISSING) == 0)
1216
goto cleanup;
1217
continue;
1218
}
1219
strlcpy(dpath, ppath, sizeof(dpath));
1220
free(ppath);
1221
}
1222
1223
if ((flags & PKG_ADD_UPGRADE) == 0 &&
1224
access(dpath, F_OK) == 0) {
1225
ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, location);
1226
1227
if (ret != EPKG_OK)
1228
goto cleanup;
1229
} else {
1230
pkg_emit_missing_dep(pkg, dep);
1231
if ((flags & PKG_ADD_FORCE_MISSING) == 0)
1232
goto cleanup;
1233
}
1234
}
1235
1236
retcode = EPKG_OK;
1237
cleanup:
1238
pkg_emit_add_deps_finished(pkg);
1239
1240
return (retcode);
1241
}
1242
1243
static int
1244
pkg_add_cleanup_old(struct pkgdb *db, struct pkg *old, struct pkg *new, struct triggers *t, int flags)
1245
{
1246
struct pkg_file *f;
1247
int ret = EPKG_OK;
1248
1249
pkg_start_stop_rc_scripts(old, PKG_RC_STOP);
1250
1251
/*
1252
* Execute pre deinstall scripts
1253
*/
1254
if ((flags & PKG_ADD_NOSCRIPT) == 0) {
1255
bool noexec = ((flags & PKG_ADD_NOEXEC) == PKG_ADD_NOEXEC);
1256
ret = pkg_lua_script_run(old, PKG_LUA_PRE_DEINSTALL, (old != NULL));
1257
if (ret != EPKG_OK && ctx.developer_mode) {
1258
return (ret);
1259
} else {
1260
ret = pkg_script_run(old, PKG_SCRIPT_PRE_DEINSTALL, (old != NULL),
1261
noexec);
1262
if (ret != EPKG_OK && (ctx.developer_mode || noexec)) {
1263
return (ret);
1264
} else {
1265
ret = EPKG_OK;
1266
}
1267
}
1268
}
1269
1270
/* Now remove files that no longer exist in the new package */
1271
if (new != NULL) {
1272
f = NULL;
1273
while (pkg_files(old, &f) == EPKG_OK) {
1274
if (!pkg_has_file(new, f->path) || match_ucl_lists(f->path,
1275
pkg_config_get("FILES_IGNORE_GLOB"),
1276
pkg_config_get("FILES_IGNORE_REGEX"))) {
1277
pkg_debug(2, "File %s is not in the new package", f->path);
1278
pkg_maybe_backup_library(db, old, f->path);
1279
trigger_is_it_a_cleanup(t, f->path);
1280
pkg_delete_file(old, f);
1281
}
1282
}
1283
1284
pkg_delete_dirs(db, old, new);
1285
}
1286
1287
return (ret);
1288
}
1289
1290
void
1291
pkg_rollback_pkg(struct pkg *p)
1292
{
1293
struct pkg_file *f = NULL;
1294
1295
while (pkg_files(p, &f) == EPKG_OK) {
1296
if (match_ucl_lists(f->path,
1297
pkg_config_get("FILES_IGNORE_GLOB"),
1298
pkg_config_get("FILES_IGNORE_REGEX")))
1299
continue;
1300
if (f->temppath != NULL) {
1301
unlinkat(p->rootfd, f->temppath, 0);
1302
}
1303
}
1304
}
1305
1306
void
1307
pkg_rollback_cb(void *data)
1308
{
1309
pkg_rollback_pkg((struct pkg *)data);
1310
}
1311
1312
int
1313
pkg_add_triggers(void)
1314
{
1315
return (triggers_execute(NULL));
1316
}
1317
1318
static int
1319
pkg_add_common(struct pkgdb *db, const char *path, unsigned flags,
1320
const char *reloc, struct pkg *remote,
1321
struct pkg *local, struct triggers *t)
1322
{
1323
struct archive *a;
1324
struct archive_entry *ae;
1325
struct pkg *pkg = NULL;
1326
xstring *message = NULL;
1327
struct pkg_message *msg;
1328
struct pkg_file *f;
1329
const char *msgstr;
1330
bool extract = true, openxact = false;
1331
int retcode = EPKG_OK;
1332
int ret;
1333
int nfiles;
1334
tempdirs_t tempdirs = vec_init();
1335
struct pkg_add_context context;
1336
1337
memset(&context, 0, sizeof(context));
1338
1339
assert(path != NULL);
1340
1341
/*
1342
* Open the package archive file, read all the meta files and set the
1343
* current archive_entry to the first non-meta file.
1344
* If there is no non-meta files, EPKG_END is returned.
1345
*/
1346
ret = pkg_open2(&pkg, &a, &ae, path, 0, -1);
1347
context.pkg = pkg;
1348
context.localpkg = local;
1349
if (ret == EPKG_END)
1350
extract = false;
1351
else if (ret != EPKG_OK) {
1352
retcode = ret;
1353
goto cleanup;
1354
}
1355
if ((flags & (PKG_ADD_UPGRADE | PKG_ADD_SPLITTED_UPGRADE)) !=
1356
PKG_ADD_UPGRADE)
1357
pkg_emit_install_begin(pkg);
1358
else
1359
pkg_emit_upgrade_begin(pkg, local);
1360
1361
if (pkg_is_valid(pkg) != EPKG_OK) {
1362
pkg_emit_error("the package is not valid");
1363
return (EPKG_FATAL);
1364
}
1365
1366
if (flags & PKG_ADD_AUTOMATIC)
1367
pkg->automatic = true;
1368
1369
if (flags & PKG_ADD_REGISTER_ONLY)
1370
extract = false;
1371
1372
/*
1373
* Additional checks for non-remote package
1374
*/
1375
if (remote == NULL) {
1376
ret = pkg_add_check_pkg_archive(db, pkg, path, flags, reloc);
1377
if (ret != EPKG_OK) {
1378
/* Do not return error on installed package */
1379
retcode = (ret == EPKG_INSTALLED ? EPKG_OK : ret);
1380
goto cleanup;
1381
}
1382
}
1383
else {
1384
if (remote->repo != NULL) {
1385
/* Save reponame */
1386
pkg_kv_add(&pkg->annotations, "repository", remote->repo->name, "annotation");
1387
pkg_kv_add(&pkg->annotations, "repo_type", remote->repo->ops->type, "annotation");
1388
}
1389
1390
free(pkg->digest);
1391
pkg->digest = xstrdup(remote->digest);
1392
/* only preserve flags if -A has not been passed */
1393
if ((flags & PKG_ADD_AUTOMATIC) == 0)
1394
pkg->automatic = remote->automatic;
1395
}
1396
1397
if (reloc != NULL)
1398
pkg_kv_add(&pkg->annotations, "relocated", reloc, "annotation");
1399
1400
pkg_open_root_fd(pkg);
1401
context.rootfd = pkg->rootfd;
1402
/* analyse previous files */
1403
f = NULL;
1404
while (pkg_files(pkg, &f) == EPKG_OK) {
1405
if (match_ucl_lists(f->path,
1406
pkg_config_get("FILES_IGNORE_GLOB"),
1407
pkg_config_get("FILES_IGNORE_REGEX"))) {
1408
continue;
1409
}
1410
if (faccessat(pkg->rootfd, RELATIVE_PATH(f->path), F_OK, 0) == 0) {
1411
f->previous = PKG_FILE_EXIST;
1412
if (!pkgdb_file_exists(db, f->path)) {
1413
f->previous = PKG_FILE_SAVE;
1414
}
1415
}
1416
}
1417
1418
/*
1419
* Register the package before installing it in case there are problems
1420
* that could be caught here.
1421
*/
1422
retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_FORCE, NULL);
1423
if (retcode != EPKG_OK)
1424
goto cleanup;
1425
openxact = true;
1426
1427
/*
1428
* Execute pre-install scripts
1429
*/
1430
if ((flags & PKG_ADD_NOSCRIPT) == 0) {
1431
if ((retcode = pkg_lua_script_run(pkg, PKG_LUA_PRE_INSTALL, (local != NULL))) != EPKG_OK)
1432
goto cleanup;
1433
if ((retcode = pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL, (local != NULL),
1434
((flags & PKG_ADD_NOEXEC) == PKG_ADD_NOEXEC))) != EPKG_OK)
1435
goto cleanup;
1436
}
1437
1438
1439
/* add the user and group if necessary */
1440
1441
nfiles = pkghash_count(pkg->filehash) + pkghash_count(pkg->dirhash);
1442
/*
1443
* Extract the files on disk.
1444
*/
1445
if (extract) {
1446
pkg_register_cleanup_callback(pkg_rollback_cb, pkg);
1447
retcode = do_extract(a, ae, nfiles, local, &tempdirs, &context);
1448
pkg_unregister_cleanup_callback(pkg_rollback_cb, pkg);
1449
if (retcode != EPKG_OK) {
1450
/* If the add failed, clean up (silently) */
1451
pkg_rollback_pkg(pkg);
1452
pkg_delete_dirs(db, pkg, NULL);
1453
goto cleanup;
1454
}
1455
}
1456
1457
/*
1458
* If this was a split upgrade, the old package has been entirely
1459
* removed already.
1460
*/
1461
if (local != NULL && (flags & PKG_ADD_SPLITTED_UPGRADE) == 0) {
1462
pkg_open_root_fd(local);
1463
pkg_debug(1, "Cleaning up old version");
1464
if (pkg_add_cleanup_old(db, local, pkg, t, flags) != EPKG_OK) {
1465
retcode = EPKG_FATAL;
1466
goto cleanup;
1467
}
1468
}
1469
1470
1471
/* Update configuration file content with db with newer versions */
1472
pkgdb_update_config_file_content(pkg, db->sqlite);
1473
1474
if (extract)
1475
retcode = pkg_extract_finalize(pkg, &tempdirs);
1476
1477
pkgdb_register_finale(db, retcode, NULL);
1478
openxact = false;
1479
1480
/*
1481
* Execute post install scripts
1482
*/
1483
1484
if (retcode != EPKG_OK)
1485
goto cleanup;
1486
if ((flags & PKG_ADD_NOSCRIPT) == 0) {
1487
bool noexec = ((flags & PKG_ADD_NOEXEC) == PKG_ADD_NOEXEC);
1488
pkg_lua_script_run(pkg, PKG_LUA_POST_INSTALL, (local != NULL));
1489
retcode = pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL, (local != NULL),
1490
noexec);
1491
if (retcode != EPKG_OK && noexec)
1492
goto cleanup;
1493
retcode = EPKG_OK;
1494
}
1495
1496
/*
1497
* start the different related services if the users do want that
1498
* and that the service is running
1499
*/
1500
1501
pkg_start_stop_rc_scripts(pkg, PKG_RC_START);
1502
1503
if ((flags & (PKG_ADD_UPGRADE | PKG_ADD_SPLITTED_UPGRADE)) !=
1504
PKG_ADD_UPGRADE)
1505
pkg_emit_install_finished(pkg, local);
1506
else
1507
pkg_emit_upgrade_finished(pkg, local);
1508
1509
vec_foreach(pkg->message, i) {
1510
msg = pkg->message.d[i];
1511
msgstr = NULL;
1512
if (msg->type == PKG_MESSAGE_ALWAYS) {
1513
msgstr = msg->str;
1514
} else if (local != NULL &&
1515
msg->type == PKG_MESSAGE_UPGRADE) {
1516
if (msg->maximum_version == NULL &&
1517
msg->minimum_version == NULL) {
1518
msgstr = msg->str;
1519
} else if (msg->maximum_version == NULL) {
1520
if (pkg_version_cmp(local->version, msg->minimum_version) == 1) {
1521
msgstr = msg->str;
1522
}
1523
} else if (msg->minimum_version == NULL) {
1524
if (pkg_version_cmp(local->version, msg->maximum_version) == -1) {
1525
msgstr = msg->str;
1526
}
1527
} else if (pkg_version_cmp(local->version, msg->maximum_version) == -1 &&
1528
pkg_version_cmp(local->version, msg->minimum_version) == 1) {
1529
msgstr = msg->str;
1530
}
1531
} else if (local == NULL &&
1532
msg->type == PKG_MESSAGE_INSTALL) {
1533
msgstr = msg->str;
1534
}
1535
if (msgstr != NULL) {
1536
if (message == NULL) {
1537
message = xstring_new();
1538
pkg_fprintf(message->fp, "=====\nMessage from "
1539
"%n-%v:\n\n", pkg, pkg);
1540
}
1541
fprintf(message->fp, "--\n%s\n", msgstr);
1542
}
1543
}
1544
if (pkg_has_message(pkg) && message != NULL) {
1545
fflush(message->fp);
1546
pkg_emit_message(message->buf);
1547
xstring_free(message);
1548
}
1549
1550
cleanup:
1551
if (openxact)
1552
pkgdb_register_finale(db, retcode, NULL);
1553
if (a != NULL) {
1554
archive_read_close(a);
1555
archive_read_free(a);
1556
}
1557
1558
pkg_free(pkg);
1559
1560
return (retcode);
1561
}
1562
1563
int
1564
pkg_add(struct pkgdb *db, const char *path, unsigned flags,
1565
const char *location)
1566
{
1567
return pkg_add_common(db, path, flags, location, NULL, NULL, NULL);
1568
}
1569
1570
int
1571
pkg_add_from_remote(struct pkgdb *db, const char *path, unsigned flags,
1572
const char *location, struct pkg *rp, struct triggers *t)
1573
{
1574
return pkg_add_common(db, path, flags, location, rp, NULL, t);
1575
}
1576
1577
int
1578
pkg_add_upgrade(struct pkgdb *db, const char *path, unsigned flags,
1579
const char *location,
1580
struct pkg *rp, struct pkg *lp, struct triggers *t)
1581
{
1582
if (pkgdb_ensure_loaded(db, lp,
1583
PKG_LOAD_FILES|PKG_LOAD_SCRIPTS|PKG_LOAD_DIRS|PKG_LOAD_LUA_SCRIPTS) != EPKG_OK)
1584
return (EPKG_FATAL);
1585
1586
return pkg_add_common(db, path, flags, location, rp, lp, t);
1587
}
1588
1589
static int
1590
pkg_group_dump(int fd, struct pkg *pkg)
1591
{
1592
ucl_object_t *o, *seq;
1593
struct pkg_dep *dep = NULL;
1594
1595
if (pkg->type != PKG_GROUP_REMOTE)
1596
return (EPKG_FATAL);
1597
o = ucl_object_typed_new(UCL_OBJECT);
1598
ucl_object_insert_key(o, ucl_object_fromstring(pkg->name), "name", 0, false);
1599
ucl_object_insert_key(o, ucl_object_fromstring(pkg->comment), "comment", 0, false);
1600
seq = ucl_object_typed_new(UCL_ARRAY);
1601
while (pkg_deps(pkg, &dep) == EPKG_OK)
1602
ucl_array_append(seq, ucl_object_fromstring(dep->name));
1603
ucl_object_insert_key(o, seq, "depends", 0, false);
1604
ucl_object_emit_fd(o, UCL_EMIT_CONFIG, fd);
1605
return (EPKG_OK);
1606
}
1607
1608
int
1609
pkg_add_group(struct pkg *pkg)
1610
{
1611
char temp[MAXPATHLEN];
1612
int dfd = pkg_get_dbdirfd();
1613
mkdirat(dfd, "groups", 0755);
1614
int gfd = openat(dfd, "groups", O_DIRECTORY|O_CLOEXEC);
1615
hidden_tempfile(temp, MAXPATHLEN, pkg->name);
1616
int fd = openat(gfd, temp, O_CREAT|O_EXCL|O_WRONLY, 0644);
1617
if (fd == -1) {
1618
pkg_emit_errno("impossible to create group file %s", pkg->name);
1619
return (EPKG_FATAL);
1620
}
1621
pkg_group_dump(fd, pkg);
1622
close(fd);
1623
if (renameat(gfd, temp, gfd, pkg->name) == -1) {
1624
unlinkat(gfd, temp, 0);
1625
pkg_emit_errno("impossible to create group file %s", pkg->name);
1626
return (EPKG_FATAL);
1627
}
1628
return (EPKG_OK);
1629
}
1630
1631
int
1632
pkg_add_fromdir(struct pkg *pkg, const char *src, struct pkgdb *db __unused)
1633
{
1634
struct stat st;
1635
struct pkg_dir *d = NULL;
1636
struct pkg_file *f = NULL;
1637
char target[MAXPATHLEN];
1638
struct passwd *pw, pwent;
1639
struct group *gr, grent;
1640
int err, fd, fromfd;
1641
int retcode;
1642
hardlinks_t hardlinks = vec_init();
1643
const char *path;
1644
char buffer[1024];
1645
size_t link_len;
1646
bool install_as_user;
1647
tempdirs_t tempdirs = vec_init();
1648
struct pkg_add_context context;
1649
1650
memset(&context, 0, sizeof(context));
1651
1652
install_as_user = (getenv("INSTALL_AS_USER") != NULL);
1653
1654
fromfd = open(src, O_DIRECTORY);
1655
if (fromfd == -1) {
1656
pkg_fatal_errno("Unable to open source directory '%s'", src);
1657
}
1658
pkg_open_root_fd(pkg);
1659
context.pkg = pkg;
1660
context.rootfd = pkg->rootfd;
1661
1662
while (pkg_dirs(pkg, &d) == EPKG_OK) {
1663
if (fstatat(fromfd, RELATIVE_PATH(d->path), &st, 0) == -1) {
1664
close(fromfd);
1665
pkg_fatal_errno("%s%s", src, d->path);
1666
}
1667
if (d->perm == 0)
1668
d->perm = st.st_mode & ~S_IFMT;
1669
if (d->uname != NULL) {
1670
err = getpwnam_r(d->uname, &pwent, buffer,
1671
sizeof(buffer), &pw);
1672
if (err != 0) {
1673
pkg_emit_errno("getpwnam_r", d->uname);
1674
retcode = EPKG_FATAL;
1675
goto cleanup;
1676
}
1677
d->uid = pwent.pw_uid;
1678
} else {
1679
d->uid = install_as_user ? st.st_uid : 0;
1680
}
1681
if (d->gname != NULL) {
1682
err = getgrnam_r(d->gname, &grent, buffer,
1683
sizeof(buffer), &gr);
1684
if (err != 0) {
1685
pkg_emit_errno("getgrnam_r", d->gname);
1686
retcode = EPKG_FATAL;
1687
goto cleanup;
1688
}
1689
d->gid = grent.gr_gid;
1690
} else {
1691
d->gid = st.st_gid;
1692
}
1693
#ifdef HAVE_STRUCT_STAT_ST_MTIM
1694
d->time[0] = st.st_atim;
1695
d->time[1] = st.st_mtim;
1696
#else
1697
#if defined(_DARWIN_C_SOURCE) || defined(__APPLE__)
1698
d->time[0] = st.st_atimespec;
1699
d->time[1] = st.st_mtimespec;
1700
#else
1701
d->time[0].tv_sec = st.st_atime;
1702
d->time[0].tv_nsec = 0;
1703
d->time[1].tv_sec = st.st_mtime;
1704
d->time[1].tv_nsec = 0;
1705
#endif
1706
#endif
1707
1708
if (create_dir(&context, d, &tempdirs) == EPKG_FATAL) {
1709
retcode = EPKG_FATAL;
1710
goto cleanup;
1711
}
1712
}
1713
1714
while (pkg_files(pkg, &f) == EPKG_OK) {
1715
if (match_ucl_lists(f->path,
1716
pkg_config_get("FILES_IGNORE_GLOB"),
1717
pkg_config_get("FILES_IGNORE_REGEX")))
1718
continue;
1719
if (fstatat(fromfd, RELATIVE_PATH(f->path), &st,
1720
AT_SYMLINK_NOFOLLOW) == -1) {
1721
vec_free_and_free(&hardlinks, free);
1722
close(fromfd);
1723
pkg_fatal_errno("%s%s", src, f->path);
1724
}
1725
if (f->uname != NULL) {
1726
err = getpwnam_r(f->uname, &pwent, buffer,
1727
sizeof(buffer), &pw);
1728
if (err != 0) {
1729
pkg_emit_errno("getpwnam_r", f->uname);
1730
retcode = EPKG_FATAL;
1731
goto cleanup;
1732
}
1733
f->uid = pwent.pw_uid;
1734
} else {
1735
f->uid = install_as_user ? st.st_uid : 0;
1736
}
1737
1738
if (f->gname != NULL) {
1739
err = getgrnam_r(f->gname, &grent, buffer,
1740
sizeof(buffer), &gr);
1741
if (err != 0) {
1742
pkg_emit_errno("getgrnam_r", f->gname);
1743
retcode = EPKG_FATAL;
1744
goto cleanup;
1745
}
1746
f->gid = grent.gr_gid;
1747
} else {
1748
f->gid = st.st_gid;
1749
}
1750
1751
if (f->perm == 0)
1752
f->perm = st.st_mode & ~S_IFMT;
1753
if (f->uid == 0 && install_as_user)
1754
f->uid = st.st_uid;
1755
#ifdef HAVE_STRUCT_STAT_ST_MTIM
1756
f->time[0] = st.st_atim;
1757
f->time[1] = st.st_mtim;
1758
#else
1759
#if defined(_DARWIN_C_SOURCE) || defined(__APPLE__)
1760
f->time[0] = st.st_atimespec;
1761
f->time[1] = st.st_mtimespec;
1762
#else
1763
f->time[0].tv_sec = st.st_atime;
1764
f->time[0].tv_nsec = 0;
1765
f->time[1].tv_sec = st.st_mtime;
1766
f->time[1].tv_nsec = 0;
1767
#endif
1768
#endif
1769
1770
if (S_ISLNK(st.st_mode)) {
1771
if ((link_len = readlinkat(fromfd,
1772
RELATIVE_PATH(f->path), target,
1773
sizeof(target))) == -1) {
1774
vec_free_and_free(&hardlinks, free);
1775
close(fromfd);
1776
pkg_fatal_errno("Impossible to read symlinks "
1777
"'%s'", f->path);
1778
}
1779
target[link_len] = '\0';
1780
if (create_symlinks(&context, f, target, &tempdirs) == EPKG_FATAL) {
1781
retcode = EPKG_FATAL;
1782
goto cleanup;
1783
}
1784
} else if (S_ISREG(st.st_mode)) {
1785
if ((fd = openat(fromfd, RELATIVE_PATH(f->path),
1786
O_RDONLY)) == -1) {
1787
vec_free_and_free(&hardlinks, free);
1788
close(fromfd);
1789
pkg_fatal_errno("Impossible to open source file"
1790
" '%s'", RELATIVE_PATH(f->path));
1791
}
1792
path = NULL;
1793
vec_foreach(hardlinks, i) {
1794
struct hardlink *hit = hardlinks.d[i];
1795
if (hit->ino == st.st_ino &&
1796
hit->dev == st.st_dev) {
1797
path = hit->path;
1798
break;
1799
}
1800
}
1801
if (path != NULL) {
1802
if (create_hardlink(&context, f, path, &tempdirs) == EPKG_FATAL) {
1803
close(fd);
1804
retcode = EPKG_FATAL;
1805
goto cleanup;
1806
}
1807
} else {
1808
if (create_regfile(&context, f, NULL, NULL, fd, NULL, &tempdirs) == EPKG_FATAL) {
1809
close(fd);
1810
retcode = EPKG_FATAL;
1811
goto cleanup;
1812
}
1813
struct hardlink *h = xcalloc(1, sizeof(*h));
1814
h->ino = st.st_ino;
1815
h->dev = st.st_dev;
1816
h->path = f->path;
1817
vec_push(&hardlinks, h);
1818
}
1819
close(fd);
1820
} else {
1821
pkg_emit_error("Invalid file type");
1822
retcode = EPKG_FATAL;
1823
goto cleanup;
1824
}
1825
}
1826
1827
retcode = pkg_extract_finalize(pkg, &tempdirs);
1828
1829
cleanup:
1830
vec_free_and_free(&hardlinks, free);
1831
close(fromfd);
1832
return (retcode);
1833
}
1834
1835
/*static bool
1836
belong_to_self(struct pkg_add_context *context, const char *path)
1837
{
1838
struct pkgdb_it *it = NULL;
1839
struct pkg *p = NULL;
1840
if (context->db != NULL && (it = pkgdb_query_which(context->db, path, false)) != NULL) {
1841
if (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) != EPKG_OK) {
1842
pkgdb_it_free(it);
1843
fprintf(stderr, "mais non\n");
1844
return (false);
1845
}
1846
pkgdb_it_free(it);
1847
if (STREQ(p->uid, context->pkg->uid)) {
1848
pkg_free(p);
1849
fprintf(stderr, "mais oui\n");
1850
return (true);
1851
}
1852
pkg_free(p);
1853
}
1854
fprintf(stderr, "mais nope\n");
1855
return (false);
1856
}*/
1857
1858
struct tempdir *
1859
open_tempdir(struct pkg_add_context *context, const char *path)
1860
{
1861
struct stat st;
1862
struct pkg *localpkg;
1863
char walk[MAXPATHLEN];
1864
char *dir;
1865
size_t cnt = 0, len;
1866
struct tempdir *t;
1867
int rootfd;
1868
1869
rootfd = context->rootfd;
1870
localpkg = context->localpkg;
1871
1872
strlcpy(walk, path, sizeof(walk));
1873
while ((dir = strrchr(walk, '/')) != NULL) {
1874
*dir = '\0';
1875
cnt++;
1876
/* accept symlinks pointing to directories */
1877
len = strlen(walk);
1878
if (len == 0 && cnt == 1)
1879
break;
1880
if (len > 0) {
1881
int flag;
1882
1883
flag = localpkg == NULL ? 0 : AT_SYMLINK_NOFOLLOW;
1884
if (fstatat(rootfd, RELATIVE_PATH(walk), &st,
1885
flag) == -1) {
1886
/*
1887
* A hack to ensure that intermediate
1888
* directories not registered with a package are
1889
* still logged in the metalog. This is not
1890
* really the right place, but to implement this
1891
* properly we need to clean up uses of
1892
* try_mkdir().
1893
*/
1894
metalog_add(PKG_METALOG_DIR,
1895
RELATIVE_PATH(walk),
1896
"root", "wheel", 0755, 0, NULL);
1897
continue;
1898
}
1899
if (S_ISLNK(st.st_mode) &&
1900
localpkg != NULL &&
1901
pkghash_get(localpkg->filehash, walk) == NULL &&
1902
fstatat(rootfd, RELATIVE_PATH(walk), &st, 0) == -1)
1903
continue;
1904
if (S_ISDIR(st.st_mode) && cnt == 1)
1905
break;
1906
if (!S_ISDIR(st.st_mode))
1907
continue;
1908
}
1909
*dir = '/';
1910
t = xcalloc(1, sizeof(*t));
1911
hidden_tempfile(t->temp, sizeof(t->temp), walk);
1912
if (mkdirat(rootfd, RELATIVE_PATH(t->temp), 0755) == -1) {
1913
pkg_errno("Fail to create temporary directory: %s", t->temp);
1914
free(t);
1915
return (NULL);
1916
}
1917
1918
strlcpy(t->name, walk, sizeof(t->name));
1919
t->len = strlen(t->name);
1920
t->fd = openat(rootfd, RELATIVE_PATH(t->temp), O_DIRECTORY);
1921
if (t->fd == -1) {
1922
pkg_errno("Fail to open directory %s", t->temp);
1923
free(t);
1924
return (NULL);
1925
}
1926
return (t);
1927
}
1928
errno = 0;
1929
return (NULL);
1930
}
1931
1932