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