Mon Apr 6 14:34:15 2009 UTC ()
pkg_install-20090406:
Remove premature return that broke dependency tracking for pkg_add -u.
Fixes PR 41143.


(joerg)
diff -r1.84 -r1.85 pkgsrc/pkgtools/pkg_install/files/add/perform.c
diff -r1.120 -r1.121 pkgsrc/pkgtools/pkg_install/files/lib/version.h

cvs diff -r1.84 -r1.85 pkgsrc/pkgtools/pkg_install/files/add/perform.c (switch to unified diff)

--- pkgsrc/pkgtools/pkg_install/files/add/perform.c 2009/03/08 14:50:36 1.84
+++ pkgsrc/pkgtools/pkg_install/files/add/perform.c 2009/04/06 14:34:15 1.85
@@ -1,1439 +1,1436 @@ @@ -1,1439 +1,1436 @@
1/* $NetBSD: perform.c,v 1.84 2009/03/08 14:50:36 joerg Exp $ */ 1/* $NetBSD: perform.c,v 1.85 2009/04/06 14:34:15 joerg Exp $ */
2#if HAVE_CONFIG_H 2#if HAVE_CONFIG_H
3#include "config.h" 3#include "config.h"
4#endif 4#endif
5#include <nbcompat.h> 5#include <nbcompat.h>
6#if HAVE_SYS_CDEFS_H 6#if HAVE_SYS_CDEFS_H
7#include <sys/cdefs.h> 7#include <sys/cdefs.h>
8#endif 8#endif
9__RCSID("$NetBSD: perform.c,v 1.84 2009/03/08 14:50:36 joerg Exp $"); 9__RCSID("$NetBSD: perform.c,v 1.85 2009/04/06 14:34:15 joerg Exp $");
10 10
11/*- 11/*-
12 * Copyright (c) 2003 Grant Beattie <grant@NetBSD.org> 12 * Copyright (c) 2003 Grant Beattie <grant@NetBSD.org>
13 * Copyright (c) 2005 Dieter Baron <dillo@NetBSD.org> 13 * Copyright (c) 2005 Dieter Baron <dillo@NetBSD.org>
14 * Copyright (c) 2007 Roland Illig <rillig@NetBSD.org> 14 * Copyright (c) 2007 Roland Illig <rillig@NetBSD.org>
15 * Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg@NetBSD.org> 15 * Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg@NetBSD.org>
16 * All rights reserved. 16 * All rights reserved.
17 * 17 *
18 * Redistribution and use in source and binary forms, with or without 18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions 19 * modification, are permitted provided that the following conditions
20 * are met: 20 * are met:
21 * 21 *
22 * 1. Redistributions of source code must retain the above copyright 22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer. 23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright 24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in 25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the 26 * the documentation and/or other materials provided with the
27 * distribution. 27 * distribution.
28 * 28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
32 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 32 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 33 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 34 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 35 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
37 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 37 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
38 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 38 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
39 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE. 40 * SUCH DAMAGE.
41 */ 41 */
42 42
43#include <sys/utsname.h> 43#include <sys/utsname.h>
44#if HAVE_ERR_H 44#if HAVE_ERR_H
45#include <err.h> 45#include <err.h>
46#endif 46#endif
47#include <errno.h> 47#include <errno.h>
48#if HAVE_FCNTL_H 48#if HAVE_FCNTL_H
49#include <fcntl.h> 49#include <fcntl.h>
50#endif 50#endif
51#include <stdlib.h> 51#include <stdlib.h>
52#include <string.h> 52#include <string.h>
53#include <unistd.h> 53#include <unistd.h>
54 54
55#include <archive.h> 55#include <archive.h>
56#include <archive_entry.h> 56#include <archive_entry.h>
57 57
58#include "lib.h" 58#include "lib.h"
59#include "add.h" 59#include "add.h"
60 60
61struct pkg_meta { 61struct pkg_meta {
62 char *meta_contents; 62 char *meta_contents;
63 char *meta_comment; 63 char *meta_comment;
64 char *meta_desc; 64 char *meta_desc;
65 char *meta_mtree; 65 char *meta_mtree;
66 char *meta_build_version; 66 char *meta_build_version;
67 char *meta_build_info; 67 char *meta_build_info;
68 char *meta_size_pkg; 68 char *meta_size_pkg;
69 char *meta_size_all; 69 char *meta_size_all;
70 char *meta_required_by; 70 char *meta_required_by;
71 char *meta_display; 71 char *meta_display;
72 char *meta_install; 72 char *meta_install;
73 char *meta_deinstall; 73 char *meta_deinstall;
74 char *meta_preserve; 74 char *meta_preserve;
75 char *meta_views; 75 char *meta_views;
76 char *meta_installed_info; 76 char *meta_installed_info;
77}; 77};
78 78
79struct pkg_task { 79struct pkg_task {
80 char *pkgname; 80 char *pkgname;
81 81
82 const char *prefix; 82 const char *prefix;
83 char *install_prefix; 83 char *install_prefix;
84 84
85 char *logdir; 85 char *logdir;
86 char *install_logdir; 86 char *install_logdir;
87 char *other_version; 87 char *other_version;
88 88
89 package_t plist; 89 package_t plist;
90 90
91 struct pkg_meta meta_data; 91 struct pkg_meta meta_data;
92 92
93 struct archive *archive; 93 struct archive *archive;
94 struct archive_entry *entry; 94 struct archive_entry *entry;
95 95
96 char *buildinfo[BI_ENUM_COUNT]; 96 char *buildinfo[BI_ENUM_COUNT];
97 97
98 size_t dep_length, dep_allocated; 98 size_t dep_length, dep_allocated;
99 char **dependencies; 99 char **dependencies;
100}; 100};
101 101
102static const struct pkg_meta_desc { 102static const struct pkg_meta_desc {
103 size_t entry_offset; 103 size_t entry_offset;
104 const char *entry_filename; 104 const char *entry_filename;
105 int required_file; 105 int required_file;
106 mode_t perm; 106 mode_t perm;
107} pkg_meta_descriptors[] = { 107} pkg_meta_descriptors[] = {
108 { offsetof(struct pkg_meta, meta_contents), CONTENTS_FNAME, 1, 0644 }, 108 { offsetof(struct pkg_meta, meta_contents), CONTENTS_FNAME, 1, 0644 },
109 { offsetof(struct pkg_meta, meta_comment), COMMENT_FNAME, 1, 0444}, 109 { offsetof(struct pkg_meta, meta_comment), COMMENT_FNAME, 1, 0444},
110 { offsetof(struct pkg_meta, meta_desc), DESC_FNAME, 1, 0444}, 110 { offsetof(struct pkg_meta, meta_desc), DESC_FNAME, 1, 0444},
111 { offsetof(struct pkg_meta, meta_install), INSTALL_FNAME, 0, 0555 }, 111 { offsetof(struct pkg_meta, meta_install), INSTALL_FNAME, 0, 0555 },
112 { offsetof(struct pkg_meta, meta_deinstall), DEINSTALL_FNAME, 0, 0555 }, 112 { offsetof(struct pkg_meta, meta_deinstall), DEINSTALL_FNAME, 0, 0555 },
113 { offsetof(struct pkg_meta, meta_display), DISPLAY_FNAME, 0, 0444 }, 113 { offsetof(struct pkg_meta, meta_display), DISPLAY_FNAME, 0, 0444 },
114 { offsetof(struct pkg_meta, meta_mtree), MTREE_FNAME, 0, 0444 }, 114 { offsetof(struct pkg_meta, meta_mtree), MTREE_FNAME, 0, 0444 },
115 { offsetof(struct pkg_meta, meta_build_version), BUILD_VERSION_FNAME, 0, 0444 }, 115 { offsetof(struct pkg_meta, meta_build_version), BUILD_VERSION_FNAME, 0, 0444 },
116 { offsetof(struct pkg_meta, meta_build_info), BUILD_INFO_FNAME, 0, 0444 }, 116 { offsetof(struct pkg_meta, meta_build_info), BUILD_INFO_FNAME, 0, 0444 },
117 { offsetof(struct pkg_meta, meta_size_pkg), SIZE_PKG_FNAME, 0, 0444 }, 117 { offsetof(struct pkg_meta, meta_size_pkg), SIZE_PKG_FNAME, 0, 0444 },
118 { offsetof(struct pkg_meta, meta_size_all), SIZE_ALL_FNAME, 0, 0444 }, 118 { offsetof(struct pkg_meta, meta_size_all), SIZE_ALL_FNAME, 0, 0444 },
119 { offsetof(struct pkg_meta, meta_preserve), PRESERVE_FNAME, 0, 0444 }, 119 { offsetof(struct pkg_meta, meta_preserve), PRESERVE_FNAME, 0, 0444 },
120 { offsetof(struct pkg_meta, meta_views), VIEWS_FNAME, 0, 0444 }, 120 { offsetof(struct pkg_meta, meta_views), VIEWS_FNAME, 0, 0444 },
121 { offsetof(struct pkg_meta, meta_required_by), REQUIRED_BY_FNAME, 0, 0644 }, 121 { offsetof(struct pkg_meta, meta_required_by), REQUIRED_BY_FNAME, 0, 0644 },
122 { offsetof(struct pkg_meta, meta_installed_info), INSTALLED_INFO_FNAME, 0, 0644 }, 122 { offsetof(struct pkg_meta, meta_installed_info), INSTALLED_INFO_FNAME, 0, 0644 },
123 { 0, NULL, 0 }, 123 { 0, NULL, 0 },
124}; 124};
125 125
126static int pkg_do(const char *, int, int); 126static int pkg_do(const char *, int, int);
127 127
128static int 128static int
129mkdir_p(const char *path) 129mkdir_p(const char *path)
130{ 130{
131 char *p, *cur_end; 131 char *p, *cur_end;
132 int done; 132 int done;
133 133
134 /* 134 /*
135 * Handle the easy case of direct success or 135 * Handle the easy case of direct success or
136 * pre-existing directory first. 136 * pre-existing directory first.
137 */ 137 */
138 if (mkdir(path, 0777) == 0 || errno == EEXIST) 138 if (mkdir(path, 0777) == 0 || errno == EEXIST)
139 return 0; 139 return 0;
140 if (errno != ENOENT) 140 if (errno != ENOENT)
141 return -1; 141 return -1;
142 142
143 cur_end = p = xstrdup(path); 143 cur_end = p = xstrdup(path);
144 144
145 for (;;) { 145 for (;;) {
146 /* 146 /*
147 * First skip leading slashes either from / or 147 * First skip leading slashes either from / or
148 * from the last iteration. 148 * from the last iteration.
149 */ 149 */
150 cur_end += strspn(cur_end, "/"); 150 cur_end += strspn(cur_end, "/");
151 /* Find end of actual directory name. */ 151 /* Find end of actual directory name. */
152 cur_end += strcspn(cur_end, "/"); 152 cur_end += strcspn(cur_end, "/");
153 153
154 /* 154 /*
155 * Remember if this is the last component and 155 * Remember if this is the last component and
156 * overwrite / if needed. 156 * overwrite / if needed.
157 */ 157 */
158 done = (*cur_end == '\0'); 158 done = (*cur_end == '\0');
159 *cur_end = '\0'; 159 *cur_end = '\0';
160 160
161 /* 161 /*
162 * ENOENT can only happen if something else races us, 162 * ENOENT can only happen if something else races us,
163 * in which case we should better give up. 163 * in which case we should better give up.
164 */ 164 */
165 if (mkdir(p, 0777) == -1 && errno != EEXIST) { 165 if (mkdir(p, 0777) == -1 && errno != EEXIST) {
166 free(p); 166 free(p);
167 return -1; 167 return -1;
168 } 168 }
169 if (done) 169 if (done)
170 break; 170 break;
171 *cur_end = '/'; 171 *cur_end = '/';
172 } 172 }
173 173
174 free(p); 174 free(p);
175 return 0;  175 return 0;
176} 176}
177 177
178/* 178/*
179 * Read meta data from archive. 179 * Read meta data from archive.
180 * Bail out if a required entry is missing or entries are in the wrong order. 180 * Bail out if a required entry is missing or entries are in the wrong order.
181 */ 181 */
182static int 182static int
183read_meta_data(struct pkg_task *pkg) 183read_meta_data(struct pkg_task *pkg)
184{ 184{
185 const struct pkg_meta_desc *descr, *last_descr; 185 const struct pkg_meta_desc *descr, *last_descr;
186 const char *fname; 186 const char *fname;
187 char **target; 187 char **target;
188 int64_t size; 188 int64_t size;
189 int r, found_required; 189 int r, found_required;
190 190
191 found_required = 0; 191 found_required = 0;
192 192
193 r = ARCHIVE_OK; 193 r = ARCHIVE_OK;
194 last_descr = 0; 194 last_descr = 0;
195 195
196 if (pkg->entry != NULL) 196 if (pkg->entry != NULL)
197 goto skip_header; 197 goto skip_header;
198 198
199 for (;;) { 199 for (;;) {
200 r = archive_read_next_header(pkg->archive, &pkg->entry); 200 r = archive_read_next_header(pkg->archive, &pkg->entry);
201 if (r != ARCHIVE_OK) 201 if (r != ARCHIVE_OK)
202 break; 202 break;
203skip_header: 203skip_header:
204 fname = archive_entry_pathname(pkg->entry); 204 fname = archive_entry_pathname(pkg->entry);
205 205
206 for (descr = pkg_meta_descriptors; descr->entry_filename; 206 for (descr = pkg_meta_descriptors; descr->entry_filename;
207 ++descr) { 207 ++descr) {
208 if (strcmp(descr->entry_filename, fname) == 0) 208 if (strcmp(descr->entry_filename, fname) == 0)
209 break; 209 break;
210 } 210 }
211 if (descr->entry_filename == NULL) 211 if (descr->entry_filename == NULL)
212 break; 212 break;
213 213
214 if (descr->required_file) 214 if (descr->required_file)
215 ++found_required; 215 ++found_required;
216 216
217 target = (char **)((char *)&pkg->meta_data + 217 target = (char **)((char *)&pkg->meta_data +
218 descr->entry_offset); 218 descr->entry_offset);
219 if (*target) { 219 if (*target) {
220 warnx("duplicate entry, package corrupt"); 220 warnx("duplicate entry, package corrupt");
221 return -1; 221 return -1;
222 } 222 }
223 if (descr < last_descr) { 223 if (descr < last_descr) {
224 warnx("misordered package"); 224 warnx("misordered package");
225 return -1; 225 return -1;
226 } 226 }
227 last_descr = descr; 227 last_descr = descr;
228 228
229 size = archive_entry_size(pkg->entry); 229 size = archive_entry_size(pkg->entry);
230 if (size > SSIZE_MAX - 1) { 230 if (size > SSIZE_MAX - 1) {
231 warnx("package meta data too large to process"); 231 warnx("package meta data too large to process");
232 return -1; 232 return -1;
233 } 233 }
234 *target = xmalloc(size + 1); 234 *target = xmalloc(size + 1);
235 if (archive_read_data(pkg->archive, *target, size) != size) { 235 if (archive_read_data(pkg->archive, *target, size) != size) {
236 warnx("cannot read package meta data"); 236 warnx("cannot read package meta data");
237 return -1; 237 return -1;
238 } 238 }
239 (*target)[size] = '\0'; 239 (*target)[size] = '\0';
240 } 240 }
241 241
242 if (r != ARCHIVE_OK) 242 if (r != ARCHIVE_OK)
243 pkg->entry = NULL; 243 pkg->entry = NULL;
244 if (r == ARCHIVE_EOF) 244 if (r == ARCHIVE_EOF)
245 r = ARCHIVE_OK; 245 r = ARCHIVE_OK;
246 246
247 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) { 247 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
248 if (descr->required_file) 248 if (descr->required_file)
249 --found_required; 249 --found_required;
250 } 250 }
251 251
252 return !found_required && r == ARCHIVE_OK ? 0 : -1; 252 return !found_required && r == ARCHIVE_OK ? 0 : -1;
253} 253}
254 254
255/* 255/*
256 * Free meta data. 256 * Free meta data.
257 */ 257 */
258static void 258static void
259free_meta_data(struct pkg_task *pkg) 259free_meta_data(struct pkg_task *pkg)
260{ 260{
261 const struct pkg_meta_desc *descr; 261 const struct pkg_meta_desc *descr;
262 char **target; 262 char **target;
263 263
264 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) { 264 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
265 target = (char **)((char *)&pkg->meta_data + 265 target = (char **)((char *)&pkg->meta_data +
266 descr->entry_offset); 266 descr->entry_offset);
267 free(*target); 267 free(*target);
268 *target = NULL; 268 *target = NULL;
269 } 269 }
270} 270}
271 271
272/* 272/*
273 * Parse PLIST and populate pkg. 273 * Parse PLIST and populate pkg.
274 */ 274 */
275static int 275static int
276pkg_parse_plist(struct pkg_task *pkg) 276pkg_parse_plist(struct pkg_task *pkg)
277{ 277{
278 plist_t *p; 278 plist_t *p;
279 279
280 parse_plist(&pkg->plist, pkg->meta_data.meta_contents); 280 parse_plist(&pkg->plist, pkg->meta_data.meta_contents);
281 if ((p = find_plist(&pkg->plist, PLIST_NAME)) == NULL) { 281 if ((p = find_plist(&pkg->plist, PLIST_NAME)) == NULL) {
282 warnx("Invalid PLIST: missing @name"); 282 warnx("Invalid PLIST: missing @name");
283 return -1; 283 return -1;
284 } 284 }
285 if (pkg->pkgname == NULL) 285 if (pkg->pkgname == NULL)
286 pkg->pkgname = xstrdup(p->name); 286 pkg->pkgname = xstrdup(p->name);
287 else if (strcmp(pkg->pkgname, p->name) != 0) { 287 else if (strcmp(pkg->pkgname, p->name) != 0) {
288 warnx("Signature and PLIST differ on package name"); 288 warnx("Signature and PLIST differ on package name");
289 return -1; 289 return -1;
290 } 290 }
291 if ((p = find_plist(&pkg->plist, PLIST_CWD)) == NULL) { 291 if ((p = find_plist(&pkg->plist, PLIST_CWD)) == NULL) {
292 warnx("Invalid PLIST: missing @cwd"); 292 warnx("Invalid PLIST: missing @cwd");
293 return -1; 293 return -1;
294 } 294 }
295 295
296 if (Prefix != NULL && 296 if (Prefix != NULL &&
297 strcmp(p->name, Prefix) != 0) { 297 strcmp(p->name, Prefix) != 0) {
298 size_t len; 298 size_t len;
299 299
300 delete_plist(&pkg->plist, FALSE, PLIST_CWD, NULL); 300 delete_plist(&pkg->plist, FALSE, PLIST_CWD, NULL);
301 add_plist_top(&pkg->plist, PLIST_CWD, Prefix); 301 add_plist_top(&pkg->plist, PLIST_CWD, Prefix);
302 free(pkg->meta_data.meta_contents); 302 free(pkg->meta_data.meta_contents);
303 stringify_plist(&pkg->plist, &pkg->meta_data.meta_contents, &len, 303 stringify_plist(&pkg->plist, &pkg->meta_data.meta_contents, &len,
304 Prefix); 304 Prefix);
305 pkg->prefix = Prefix; 305 pkg->prefix = Prefix;
306 } else 306 } else
307 pkg->prefix = p->name; 307 pkg->prefix = p->name;
308 308
309 if (Destdir != NULL) 309 if (Destdir != NULL)
310 pkg->install_prefix = xasprintf("%s/%s", Destdir, pkg->prefix); 310 pkg->install_prefix = xasprintf("%s/%s", Destdir, pkg->prefix);
311 else 311 else
312 pkg->install_prefix = xstrdup(pkg->prefix); 312 pkg->install_prefix = xstrdup(pkg->prefix);
313 313
314 return 0; 314 return 0;
315} 315}
316 316
317/* 317/*
318 * Helper function to extract value from a string of the 318 * Helper function to extract value from a string of the
319 * form key=value ending at eol. 319 * form key=value ending at eol.
320 */ 320 */
321static char * 321static char *
322dup_value(const char *line, const char *eol) 322dup_value(const char *line, const char *eol)
323{ 323{
324 const char *key; 324 const char *key;
325 char *val; 325 char *val;
326 326
327 key = strchr(line, '='); 327 key = strchr(line, '=');
328 val = xmalloc(eol - key); 328 val = xmalloc(eol - key);
329 memcpy(val, key + 1, eol - key - 1); 329 memcpy(val, key + 1, eol - key - 1);
330 val[eol - key - 1] = '\0'; 330 val[eol - key - 1] = '\0';
331 return val; 331 return val;
332} 332}
333 333
334static int 334static int
335check_already_installed(struct pkg_task *pkg) 335check_already_installed(struct pkg_task *pkg)
336{ 336{
337 char *filename; 337 char *filename;
338 int fd; 338 int fd;
339 339
340 if (Force) 340 if (Force)
341 return -1; 341 return -1;
342 342
343 filename = pkgdb_pkg_file(pkg->pkgname, CONTENTS_FNAME); 343 filename = pkgdb_pkg_file(pkg->pkgname, CONTENTS_FNAME);
344 fd = open(filename, O_RDONLY); 344 fd = open(filename, O_RDONLY);
345 free(filename); 345 free(filename);
346 if (fd == -1) 346 if (fd == -1)
347 return -1; 347 return -1;
348 348
349 /* We can only arrive here for explicitly requested packages. */ 349 /* We can only arrive here for explicitly requested packages. */
350 if (!Automatic && is_automatic_installed(pkg->pkgname)) { 350 if (!Automatic && is_automatic_installed(pkg->pkgname)) {
351 if (Fake || 351 if (Fake ||
352 mark_as_automatic_installed(pkg->pkgname, 0) == 0) 352 mark_as_automatic_installed(pkg->pkgname, 0) == 0)
353 warnx("package `%s' was already installed as " 353 warnx("package `%s' was already installed as "
354 "dependency, now marked as installed " 354 "dependency, now marked as installed "
355 "manually", pkg->pkgname); 355 "manually", pkg->pkgname);
356 } else { 356 } else {
357 warnx("package `%s' already recorded as installed", 357 warnx("package `%s' already recorded as installed",
358 pkg->pkgname); 358 pkg->pkgname);
359 } 359 }
360 close(fd); 360 close(fd);
361 return 0; 361 return 0;
362 362
363} 363}
364 364
365static int 365static int
366check_other_installed(struct pkg_task *pkg) 366check_other_installed(struct pkg_task *pkg)
367{ 367{
368 FILE *f, *f_pkg; 368 FILE *f, *f_pkg;
369 size_t len; 369 size_t len;
370 char *pkgbase, *iter, *filename; 370 char *pkgbase, *iter, *filename;
371 package_t plist; 371 package_t plist;
372 plist_t *p; 372 plist_t *p;
373 int status; 373 int status;
374 374
375 pkgbase = xstrdup(pkg->pkgname); 375 pkgbase = xstrdup(pkg->pkgname);
376 376
377 if ((iter = strrchr(pkgbase, '-')) == NULL) { 377 if ((iter = strrchr(pkgbase, '-')) == NULL) {
378 free(pkgbase); 378 free(pkgbase);
379 warnx("Invalid package name %s", pkg->pkgname); 379 warnx("Invalid package name %s", pkg->pkgname);
380 return -1; 380 return -1;
381 } 381 }
382 *iter = '\0'; 382 *iter = '\0';
383 pkg->other_version = find_best_matching_installed_pkg(pkgbase); 383 pkg->other_version = find_best_matching_installed_pkg(pkgbase);
384 free(pkgbase); 384 free(pkgbase);
385 if (pkg->other_version == NULL) 385 if (pkg->other_version == NULL)
386 return 0; 386 return 0;
387 387
388 if (!Replace) { 388 if (!Replace) {
389 /* XXX This is redundant to the implicit conflict check. */ 389 /* XXX This is redundant to the implicit conflict check. */
390 warnx("A different version of %s is already installed: %s", 390 warnx("A different version of %s is already installed: %s",
391 pkg->pkgname, pkg->other_version); 391 pkg->pkgname, pkg->other_version);
392 return -1; 392 return -1;
393 } 393 }
394 394
395 filename = pkgdb_pkg_file(pkg->other_version, REQUIRED_BY_FNAME); 395 filename = pkgdb_pkg_file(pkg->other_version, REQUIRED_BY_FNAME);
396 errno = 0; 396 errno = 0;
397 f = fopen(filename, "r"); 397 f = fopen(filename, "r");
398 free(filename); 398 free(filename);
399 if (f == NULL) { 399 if (f == NULL) {
400 if (errno == ENOENT) { 400 if (errno == ENOENT) {
401 /* No packages depend on this, so everything is well. */ 401 /* No packages depend on this, so everything is well. */
402 return 0;  402 return 0;
403 } 403 }
404 warnx("Can't open +REQUIRED_BY of %s", pkg->other_version); 404 warnx("Can't open +REQUIRED_BY of %s", pkg->other_version);
405 return -1; 405 return -1;
406 } 406 }
407 407
408 status = 0; 408 status = 0;
409 409
410 while ((iter = fgetln(f, &len)) != NULL) { 410 while ((iter = fgetln(f, &len)) != NULL) {
411 if (iter[len - 1] == '\n') 411 if (iter[len - 1] == '\n')
412 iter[len - 1] = '\0'; 412 iter[len - 1] = '\0';
413 filename = pkgdb_pkg_file(iter, CONTENTS_FNAME); 413 filename = pkgdb_pkg_file(iter, CONTENTS_FNAME);
414 if ((f_pkg = fopen(filename, "r")) == NULL) { 414 if ((f_pkg = fopen(filename, "r")) == NULL) {
415 warnx("Can't open +CONTENTS of depending package %s", 415 warnx("Can't open +CONTENTS of depending package %s",
416 iter); 416 iter);
417 fclose(f); 417 fclose(f);
418 return -1; 418 return -1;
419 } 419 }
420 read_plist(&plist, f_pkg); 420 read_plist(&plist, f_pkg);
421 fclose(f_pkg); 421 fclose(f_pkg);
422 for (p = plist.head; p != NULL; p = p->next) { 422 for (p = plist.head; p != NULL; p = p->next) {
423 if (p->type == PLIST_IGNORE) { 423 if (p->type == PLIST_IGNORE) {
424 p = p->next; 424 p = p->next;
425 continue; 425 continue;
426 } else if (p->type != PLIST_PKGDEP) 426 } else if (p->type != PLIST_PKGDEP)
427 continue; 427 continue;
428 /* 428 /*
429 * XXX This is stricter than necessary. 429 * XXX This is stricter than necessary.
430 * XXX One pattern might be fulfilled by 430 * XXX One pattern might be fulfilled by
431 * XXX a different package and still need this 431 * XXX a different package and still need this
432 * XXX one for a different pattern. 432 * XXX one for a different pattern.
433 */ 433 */
434 if (pkg_match(p->name, pkg->other_version) == 0) 434 if (pkg_match(p->name, pkg->other_version) == 0)
435 continue; 435 continue;
436 if (pkg_match(p->name, pkg->pkgname) == 1) 436 if (pkg_match(p->name, pkg->pkgname) == 1)
437 continue; /* Both match, ok. */ 437 continue; /* Both match, ok. */
438 warnx("Dependency of %s fulfilled by %s, but not by %s", 438 warnx("Dependency of %s fulfilled by %s, but not by %s",
439 iter, pkg->other_version, pkg->pkgname); 439 iter, pkg->other_version, pkg->pkgname);
440 if (!Force) 440 if (!Force)
441 status = -1; 441 status = -1;
442 break; 442 break;
443 } 443 }
444 free_plist(&plist);  444 free_plist(&plist);
445 } 445 }
446 446
447 fclose(f); 447 fclose(f);
448 448
449 return status; 449 return status;
450} 450}
451 451
452/* 452/*
453 * Read package build information from meta data. 453 * Read package build information from meta data.
454 */ 454 */
455static int 455static int
456read_buildinfo(struct pkg_task *pkg) 456read_buildinfo(struct pkg_task *pkg)
457{ 457{
458 const char *data, *eol, *next_line; 458 const char *data, *eol, *next_line;
459 459
460 data = pkg->meta_data.meta_build_info; 460 data = pkg->meta_data.meta_build_info;
461 461
462 for (; data != NULL && *data != '\0'; data = next_line) { 462 for (; data != NULL && *data != '\0'; data = next_line) {
463 if ((eol = strchr(data, '\n')) == NULL) { 463 if ((eol = strchr(data, '\n')) == NULL) {
464 eol = data + strlen(data); 464 eol = data + strlen(data);
465 next_line = eol; 465 next_line = eol;
466 } else 466 } else
467 next_line = eol + 1; 467 next_line = eol + 1;
468 468
469 if (strncmp(data, "OPSYS=", 6) == 0) 469 if (strncmp(data, "OPSYS=", 6) == 0)
470 pkg->buildinfo[BI_OPSYS] = dup_value(data, eol); 470 pkg->buildinfo[BI_OPSYS] = dup_value(data, eol);
471 else if (strncmp(data, "OS_VERSION=", 11) == 0) 471 else if (strncmp(data, "OS_VERSION=", 11) == 0)
472 pkg->buildinfo[BI_OS_VERSION] = dup_value(data, eol); 472 pkg->buildinfo[BI_OS_VERSION] = dup_value(data, eol);
473 else if (strncmp(data, "MACHINE_ARCH=", 13) == 0) 473 else if (strncmp(data, "MACHINE_ARCH=", 13) == 0)
474 pkg->buildinfo[BI_MACHINE_ARCH] = dup_value(data, eol); 474 pkg->buildinfo[BI_MACHINE_ARCH] = dup_value(data, eol);
475 else if (strncmp(data, "IGNORE_RECOMMENDED=", 19) == 0) 475 else if (strncmp(data, "IGNORE_RECOMMENDED=", 19) == 0)
476 pkg->buildinfo[BI_IGNORE_RECOMMENDED] = dup_value(data, 476 pkg->buildinfo[BI_IGNORE_RECOMMENDED] = dup_value(data,
477 eol); 477 eol);
478 else if (strncmp(data, "USE_ABI_DEPENDS=", 16) == 0) 478 else if (strncmp(data, "USE_ABI_DEPENDS=", 16) == 0)
479 pkg->buildinfo[BI_USE_ABI_DEPENDS] = dup_value(data, 479 pkg->buildinfo[BI_USE_ABI_DEPENDS] = dup_value(data,
480 eol); 480 eol);
481 } 481 }
482 if (pkg->buildinfo[BI_OPSYS] == NULL || 482 if (pkg->buildinfo[BI_OPSYS] == NULL ||
483 pkg->buildinfo[BI_OS_VERSION] == NULL || 483 pkg->buildinfo[BI_OS_VERSION] == NULL ||
484 pkg->buildinfo[BI_MACHINE_ARCH] == NULL) { 484 pkg->buildinfo[BI_MACHINE_ARCH] == NULL) {
485 warnx("Not all required build information are present."); 485 warnx("Not all required build information are present.");
486 return -1; 486 return -1;
487 } 487 }
488 488
489 if ((pkg->buildinfo[BI_USE_ABI_DEPENDS] != NULL && 489 if ((pkg->buildinfo[BI_USE_ABI_DEPENDS] != NULL &&
490 strcasecmp(pkg->buildinfo[BI_USE_ABI_DEPENDS], "YES") != 0) || 490 strcasecmp(pkg->buildinfo[BI_USE_ABI_DEPENDS], "YES") != 0) ||
491 (pkg->buildinfo[BI_IGNORE_RECOMMENDED] != NULL && 491 (pkg->buildinfo[BI_IGNORE_RECOMMENDED] != NULL &&
492 strcasecmp(pkg->buildinfo[BI_IGNORE_RECOMMENDED], "NO") != 0)) { 492 strcasecmp(pkg->buildinfo[BI_IGNORE_RECOMMENDED], "NO") != 0)) {
493 warnx("%s was built to ignore ABI dependencies", pkg->pkgname); 493 warnx("%s was built to ignore ABI dependencies", pkg->pkgname);
494 } 494 }
495 495
496 return 0; 496 return 0;
497} 497}
498 498
499/* 499/*
500 * Free buildinfo. 500 * Free buildinfo.
501 */ 501 */
502static void 502static void
503free_buildinfo(struct pkg_task *pkg) 503free_buildinfo(struct pkg_task *pkg)
504{ 504{
505 size_t i; 505 size_t i;
506 506
507 for (i = 0; i < BI_ENUM_COUNT; ++i) { 507 for (i = 0; i < BI_ENUM_COUNT; ++i) {
508 free(pkg->buildinfo[i]); 508 free(pkg->buildinfo[i]);
509 pkg->buildinfo[i] = NULL; 509 pkg->buildinfo[i] = NULL;
510 } 510 }
511} 511}
512 512
513/* 513/*
514 * Write meta data files to pkgdb after creating the directory. 514 * Write meta data files to pkgdb after creating the directory.
515 */ 515 */
516static int 516static int
517write_meta_data(struct pkg_task *pkg) 517write_meta_data(struct pkg_task *pkg)
518{ 518{
519 const struct pkg_meta_desc *descr; 519 const struct pkg_meta_desc *descr;
520 char *filename, **target; 520 char *filename, **target;
521 size_t len; 521 size_t len;
522 ssize_t ret; 522 ssize_t ret;
523 int fd; 523 int fd;
524 524
525 if (Fake) 525 if (Fake)
526 return 0; 526 return 0;
527 527
528 if (mkdir_p(pkg->install_logdir)) { 528 if (mkdir_p(pkg->install_logdir)) {
529 warn("Can't create pkgdb entry: %s", pkg->install_logdir); 529 warn("Can't create pkgdb entry: %s", pkg->install_logdir);
530 return -1; 530 return -1;
531 } 531 }
532 532
533 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) { 533 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
534 target = (char **)((char *)&pkg->meta_data + 534 target = (char **)((char *)&pkg->meta_data +
535 descr->entry_offset); 535 descr->entry_offset);
536 if (*target == NULL) 536 if (*target == NULL)
537 continue; 537 continue;
538 filename = xasprintf("%s/%s", pkg->install_logdir, 538 filename = xasprintf("%s/%s", pkg->install_logdir,
539 descr->entry_filename); 539 descr->entry_filename);
540 (void)unlink(filename); 540 (void)unlink(filename);
541 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, descr->perm); 541 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, descr->perm);
542 if (fd == -1) { 542 if (fd == -1) {
543 warn("Can't open meta data file: %s", filename); 543 warn("Can't open meta data file: %s", filename);
544 return -1; 544 return -1;
545 } 545 }
546 len = strlen(*target); 546 len = strlen(*target);
547 do { 547 do {
548 ret = write(fd, *target, len); 548 ret = write(fd, *target, len);
549 if (ret == -1) { 549 if (ret == -1) {
550 warn("Can't write meta data file: %s", 550 warn("Can't write meta data file: %s",
551 filename); 551 filename);
552 free(filename); 552 free(filename);
553 close(fd); 553 close(fd);
554 return -1; 554 return -1;
555 } 555 }
556 len -= ret; 556 len -= ret;
557 } while (ret > 0); 557 } while (ret > 0);
558 if (close(fd) == -1) { 558 if (close(fd) == -1) {
559 warn("Can't close meta data file: %s", filename); 559 warn("Can't close meta data file: %s", filename);
560 free(filename); 560 free(filename);
561 return -1; 561 return -1;
562 } 562 }
563 free(filename); 563 free(filename);
564 } 564 }
565 565
566 return 0; 566 return 0;
567} 567}
568 568
569/* 569/*
570 * Helper function for extract_files. 570 * Helper function for extract_files.
571 */ 571 */
572static int 572static int
573copy_data_to_disk(struct archive *reader, struct archive *writer, 573copy_data_to_disk(struct archive *reader, struct archive *writer,
574 const char *filename) 574 const char *filename)
575{ 575{
576 int r; 576 int r;
577 const void *buff; 577 const void *buff;
578 size_t size; 578 size_t size;
579 off_t offset; 579 off_t offset;
580 580
581 for (;;) { 581 for (;;) {
582 r = archive_read_data_block(reader, &buff, &size, &offset); 582 r = archive_read_data_block(reader, &buff, &size, &offset);
583 if (r == ARCHIVE_EOF) 583 if (r == ARCHIVE_EOF)
584 return 0; 584 return 0;
585 if (r != ARCHIVE_OK) { 585 if (r != ARCHIVE_OK) {
586 warnx("Read error for %s: %s", filename, 586 warnx("Read error for %s: %s", filename,
587 archive_error_string(reader)); 587 archive_error_string(reader));
588 return -1; 588 return -1;
589 } 589 }
590 r = archive_write_data_block(writer, buff, size, offset); 590 r = archive_write_data_block(writer, buff, size, offset);
591 if (r != ARCHIVE_OK) { 591 if (r != ARCHIVE_OK) {
592 warnx("Write error for %s: %s", filename, 592 warnx("Write error for %s: %s", filename,
593 archive_error_string(writer)); 593 archive_error_string(writer));
594 return -1; 594 return -1;
595 } 595 }
596 } 596 }
597} 597}
598 598
599/* 599/*
600 * Extract package. 600 * Extract package.
601 * Any misordered, missing or unlisted file in the package is an error. 601 * Any misordered, missing or unlisted file in the package is an error.
602 */ 602 */
603 603
604static const int extract_flags = /* ARCHIVE_EXTRACT_OWNER | */ 604static const int extract_flags = /* ARCHIVE_EXTRACT_OWNER | */
605 ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK | 605 ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK |
606 ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR; 606 ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR;
607 607
608static int 608static int
609extract_files(struct pkg_task *pkg) 609extract_files(struct pkg_task *pkg)
610{ 610{
611 char cmd[MaxPathSize]; 611 char cmd[MaxPathSize];
612 const char *owner, *group, *permissions; 612 const char *owner, *group, *permissions;
613 struct archive *writer; 613 struct archive *writer;
614 int r; 614 int r;
615 plist_t *p; 615 plist_t *p;
616 const char *last_file; 616 const char *last_file;
617 char *fullpath; 617 char *fullpath;
618 618
619 if (Fake) 619 if (Fake)
620 return 0; 620 return 0;
621 621
622 if (mkdir_p(pkg->install_prefix)) { 622 if (mkdir_p(pkg->install_prefix)) {
623 warn("Can't create prefix: %s", pkg->install_prefix); 623 warn("Can't create prefix: %s", pkg->install_prefix);
624 return -1; 624 return -1;
625 } 625 }
626 626
627 if (!NoRecord && !pkgdb_open(ReadWrite)) { 627 if (!NoRecord && !pkgdb_open(ReadWrite)) {
628 warn("Can't open pkgdb for writing"); 628 warn("Can't open pkgdb for writing");
629 return -1; 629 return -1;
630 } 630 }
631 631
632 if (chdir(pkg->install_prefix) == -1) { 632 if (chdir(pkg->install_prefix) == -1) {
633 warn("Can't change into prefix: %s", pkg->install_prefix); 633 warn("Can't change into prefix: %s", pkg->install_prefix);
634 return -1; 634 return -1;
635 } 635 }
636 636
637 writer = archive_write_disk_new(); 637 writer = archive_write_disk_new();
638 archive_write_disk_set_options(writer, extract_flags); 638 archive_write_disk_set_options(writer, extract_flags);
639 archive_write_disk_set_standard_lookup(writer); 639 archive_write_disk_set_standard_lookup(writer);
640 640
641 owner = NULL; 641 owner = NULL;
642 group = NULL; 642 group = NULL;
643 permissions = NULL; 643 permissions = NULL;
644 last_file = NULL; 644 last_file = NULL;
645 645
646 r = -1; 646 r = -1;
647 647
648 for (p = pkg->plist.head; p != NULL; p = p->next) { 648 for (p = pkg->plist.head; p != NULL; p = p->next) {
649 switch (p->type) { 649 switch (p->type) {
650 case PLIST_FILE: 650 case PLIST_FILE:
651 last_file = p->name; 651 last_file = p->name;
652 if (pkg->entry == NULL) { 652 if (pkg->entry == NULL) {
653 warnx("PLIST entry not in package (%s)", 653 warnx("PLIST entry not in package (%s)",
654 archive_entry_pathname(pkg->entry)); 654 archive_entry_pathname(pkg->entry));
655 goto out; 655 goto out;
656 } 656 }
657 if (strcmp(p->name, archive_entry_pathname(pkg->entry))) { 657 if (strcmp(p->name, archive_entry_pathname(pkg->entry))) {
658 warnx("PLIST entry and package don't match (%s vs %s)", 658 warnx("PLIST entry and package don't match (%s vs %s)",
659 p->name, archive_entry_pathname(pkg->entry)); 659 p->name, archive_entry_pathname(pkg->entry));
660 goto out; 660 goto out;
661 } 661 }
662 fullpath = xasprintf("%s/%s", pkg->prefix, p->name); 662 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
663 pkgdb_store(fullpath, pkg->pkgname); 663 pkgdb_store(fullpath, pkg->pkgname);
664 free(fullpath); 664 free(fullpath);
665 if (Verbose) 665 if (Verbose)
666 printf("%s", p->name); 666 printf("%s", p->name);
667 break; 667 break;
668 668
669 case PLIST_CMD: 669 case PLIST_CMD:
670 if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix, last_file)) 670 if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix, last_file))
671 return -1; 671 return -1;
672 printf("Executing '%s'\n", cmd); 672 printf("Executing '%s'\n", cmd);
673 if (!Fake && system(cmd)) 673 if (!Fake && system(cmd))
674 warnx("command '%s' failed", cmd); /* XXX bail out? */ 674 warnx("command '%s' failed", cmd); /* XXX bail out? */
675 continue; 675 continue;
676 676
677 case PLIST_CHMOD: 677 case PLIST_CHMOD:
678 permissions = p->name; 678 permissions = p->name;
679 continue; 679 continue;
680 680
681 case PLIST_CHOWN: 681 case PLIST_CHOWN:
682 owner = p->name; 682 owner = p->name;
683 continue; 683 continue;
684 684
685 case PLIST_CHGRP: 685 case PLIST_CHGRP:
686 group = p->name; 686 group = p->name;
687 continue; 687 continue;
688 688
689 case PLIST_IGNORE: 689 case PLIST_IGNORE:
690 p = p->next; 690 p = p->next;
691 continue; 691 continue;
692 692
693 default: 693 default:
694 continue; 694 continue;
695 } 695 }
696 696
697 r = archive_write_header(writer, pkg->entry); 697 r = archive_write_header(writer, pkg->entry);
698 if (r != ARCHIVE_OK) { 698 if (r != ARCHIVE_OK) {
699 warnx("Failed to write %s: %s", 699 warnx("Failed to write %s: %s",
700 archive_entry_pathname(pkg->entry), 700 archive_entry_pathname(pkg->entry),
701 archive_error_string(writer)); 701 archive_error_string(writer));
702 goto out; 702 goto out;
703 } 703 }
704 704
705 if (owner != NULL) 705 if (owner != NULL)
706 archive_entry_set_uname(pkg->entry, owner); 706 archive_entry_set_uname(pkg->entry, owner);
707 if (group != NULL) 707 if (group != NULL)
708 archive_entry_set_uname(pkg->entry, group); 708 archive_entry_set_uname(pkg->entry, group);
709 if (permissions != NULL) { 709 if (permissions != NULL) {
710 mode_t mode; 710 mode_t mode;
711 711
712 mode = archive_entry_mode(pkg->entry); 712 mode = archive_entry_mode(pkg->entry);
713 mode = getmode(setmode(permissions), mode); 713 mode = getmode(setmode(permissions), mode);
714 archive_entry_set_mode(pkg->entry, mode); 714 archive_entry_set_mode(pkg->entry, mode);
715 } 715 }
716 716
717 r = copy_data_to_disk(pkg->archive, writer, 717 r = copy_data_to_disk(pkg->archive, writer,
718 archive_entry_pathname(pkg->entry)); 718 archive_entry_pathname(pkg->entry));
719 if (r) 719 if (r)
720 goto out; 720 goto out;
721 if (Verbose) 721 if (Verbose)
722 printf("\n"); 722 printf("\n");
723 723
724 r = archive_read_next_header(pkg->archive, &pkg->entry); 724 r = archive_read_next_header(pkg->archive, &pkg->entry);
725 if (r == ARCHIVE_EOF) { 725 if (r == ARCHIVE_EOF) {
726 pkg->entry = NULL; 726 pkg->entry = NULL;
727 continue; 727 continue;
728 } 728 }
729 if (r != ARCHIVE_OK) { 729 if (r != ARCHIVE_OK) {
730 warnx("Failed to read from archive: %s", 730 warnx("Failed to read from archive: %s",
731 archive_error_string(pkg->archive)); 731 archive_error_string(pkg->archive));
732 goto out; 732 goto out;
733 } 733 }
734 } 734 }
735 735
736 if (pkg->entry != NULL) { 736 if (pkg->entry != NULL) {
737 warnx("Package contains entries not in PLIST: %s", 737 warnx("Package contains entries not in PLIST: %s",
738 archive_entry_pathname(pkg->entry)); 738 archive_entry_pathname(pkg->entry));
739 goto out; 739 goto out;
740 } 740 }
741 741
742 r = 0; 742 r = 0;
743 743
744out: 744out:
745 if (!NoRecord) 745 if (!NoRecord)
746 pkgdb_close(); 746 pkgdb_close();
747 archive_write_close(writer); 747 archive_write_close(writer);
748 archive_write_finish(writer); 748 archive_write_finish(writer);
749 749
750 return r; 750 return r;
751} 751}
752 752
753/* 753/*
754 * Register dependencies after sucessfully installing the package. 754 * Register dependencies after sucessfully installing the package.
755 */ 755 */
756static void 756static void
757pkg_register_depends(struct pkg_task *pkg) 757pkg_register_depends(struct pkg_task *pkg)
758{ 758{
759 int fd; 759 int fd;
760 size_t text_len, i; 760 size_t text_len, i;
761 char *required_by, *text; 761 char *required_by, *text;
762 762
763 if (Fake) 763 if (Fake)
764 return; 764 return;
765 765
766 if (pkg->other_version != NULL) 
767 return; /* XXX It's using the old dependencies. */ 
768 
769 text = xasprintf("%s\n", pkg->pkgname); 766 text = xasprintf("%s\n", pkg->pkgname);
770 text_len = strlen(text); 767 text_len = strlen(text);
771 768
772 for (i = 0; i < pkg->dep_length; ++i) { 769 for (i = 0; i < pkg->dep_length; ++i) {
773 required_by = pkgdb_pkg_file(pkg->dependencies[i], REQUIRED_BY_FNAME); 770 required_by = pkgdb_pkg_file(pkg->dependencies[i], REQUIRED_BY_FNAME);
774 771
775 fd = open(required_by, O_WRONLY | O_APPEND | O_CREAT, 0644); 772 fd = open(required_by, O_WRONLY | O_APPEND | O_CREAT, 0644);
776 if (fd == -1) { 773 if (fd == -1) {
777 warn("can't open dependency file '%s'," 774 warn("can't open dependency file '%s',"
778 "registration is incomplete!", required_by); 775 "registration is incomplete!", required_by);
779 } else if (write(fd, text, text_len) != text_len) { 776 } else if (write(fd, text, text_len) != text_len) {
780 warn("can't write to dependency file `%s'", required_by); 777 warn("can't write to dependency file `%s'", required_by);
781 close(fd); 778 close(fd);
782 } else if (close(fd) == -1) 779 } else if (close(fd) == -1)
783 warn("cannot close file %s", required_by); 780 warn("cannot close file %s", required_by);
784 781
785 free(required_by); 782 free(required_by);
786 } 783 }
787 784
788 free(text); 785 free(text);
789} 786}
790 787
791/* 788/*
792 * Reduce the result from uname(3) to a canonical form. 789 * Reduce the result from uname(3) to a canonical form.
793 */ 790 */
794static void 791static void
795normalise_platform(struct utsname *host_name) 792normalise_platform(struct utsname *host_name)
796{ 793{
797#ifdef NUMERIC_VERSION_ONLY 794#ifdef NUMERIC_VERSION_ONLY
798 size_t span; 795 size_t span;
799 796
800 span = strspn(host_name->release, "0123456789."); 797 span = strspn(host_name->release, "0123456789.");
801 host_name->release[span] = '\0'; 798 host_name->release[span] = '\0';
802#endif 799#endif
803} 800}
804 801
805/* 802/*
806 * Check build platform of the package against local host. 803 * Check build platform of the package against local host.
807 */ 804 */
808static int 805static int
809check_platform(struct pkg_task *pkg) 806check_platform(struct pkg_task *pkg)
810{ 807{
811 struct utsname host_uname; 808 struct utsname host_uname;
812 const char *effective_arch; 809 const char *effective_arch;
813 int fatal; 810 int fatal;
814 811
815 if (uname(&host_uname) < 0) { 812 if (uname(&host_uname) < 0) {
816 if (Force) { 813 if (Force) {
817 warnx("uname() failed, continuing."); 814 warnx("uname() failed, continuing.");
818 return 0; 815 return 0;
819 } else { 816 } else {
820 warnx("uname() failed, aborting."); 817 warnx("uname() failed, aborting.");
821 return -1; 818 return -1;
822 } 819 }
823 } 820 }
824 821
825 normalise_platform(&host_uname); 822 normalise_platform(&host_uname);
826 823
827 if (OverrideMachine != NULL) 824 if (OverrideMachine != NULL)
828 effective_arch = OverrideMachine; 825 effective_arch = OverrideMachine;
829 else 826 else
830 effective_arch = MACHINE_ARCH; 827 effective_arch = MACHINE_ARCH;
831 828
832 /* If either the OS or arch are different, bomb */ 829 /* If either the OS or arch are different, bomb */
833 if (strcmp(OPSYS_NAME, pkg->buildinfo[BI_OPSYS]) || 830 if (strcmp(OPSYS_NAME, pkg->buildinfo[BI_OPSYS]) ||
834 strcmp(effective_arch, pkg->buildinfo[BI_MACHINE_ARCH]) != 0) 831 strcmp(effective_arch, pkg->buildinfo[BI_MACHINE_ARCH]) != 0)
835 fatal = 1; 832 fatal = 1;
836 else 833 else
837 fatal = 0; 834 fatal = 0;
838 835
839 if (fatal || 836 if (fatal ||
840 strcmp(host_uname.release, pkg->buildinfo[BI_OS_VERSION]) != 0) { 837 strcmp(host_uname.release, pkg->buildinfo[BI_OS_VERSION]) != 0) {
841 warnx("Warning: package `%s' was built for a platform:", 838 warnx("Warning: package `%s' was built for a platform:",
842 pkg->pkgname); 839 pkg->pkgname);
843 warnx("%s/%s %s (pkg) vs. %s/%s %s (this host)", 840 warnx("%s/%s %s (pkg) vs. %s/%s %s (this host)",
844 pkg->buildinfo[BI_OPSYS], 841 pkg->buildinfo[BI_OPSYS],
845 pkg->buildinfo[BI_MACHINE_ARCH], 842 pkg->buildinfo[BI_MACHINE_ARCH],
846 pkg->buildinfo[BI_OS_VERSION], 843 pkg->buildinfo[BI_OS_VERSION],
847 OPSYS_NAME, 844 OPSYS_NAME,
848 effective_arch, 845 effective_arch,
849 host_uname.release); 846 host_uname.release);
850 if (!Force && fatal) 847 if (!Force && fatal)
851 return -1; 848 return -1;
852 } 849 }
853 return 0; 850 return 0;
854} 851}
855 852
856/* 853/*
857 * Run the install script. 854 * Run the install script.
858 */ 855 */
859static int 856static int
860run_install_script(struct pkg_task *pkg, const char *argument) 857run_install_script(struct pkg_task *pkg, const char *argument)
861{ 858{
862 int ret; 859 int ret;
863 char *filename; 860 char *filename;
864 861
865 if (pkg->meta_data.meta_install == NULL || NoInstall) 862 if (pkg->meta_data.meta_install == NULL || NoInstall)
866 return 0; 863 return 0;
867 864
868 if (Destdir != NULL) 865 if (Destdir != NULL)
869 setenv(PKG_DESTDIR_VNAME, Destdir, 1); 866 setenv(PKG_DESTDIR_VNAME, Destdir, 1);
870 setenv(PKG_PREFIX_VNAME, pkg->prefix, 1); 867 setenv(PKG_PREFIX_VNAME, pkg->prefix, 1);
871 setenv(PKG_METADATA_DIR_VNAME, pkg->logdir, 1); 868 setenv(PKG_METADATA_DIR_VNAME, pkg->logdir, 1);
872 setenv(PKG_REFCOUNT_DBDIR_VNAME, pkgdb_refcount_dir(), 1); 869 setenv(PKG_REFCOUNT_DBDIR_VNAME, pkgdb_refcount_dir(), 1);
873 870
874 if (Verbose) 871 if (Verbose)
875 printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname); 872 printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname);
876 if (Fake) 873 if (Fake)
877 return 0; 874 return 0;
878 875
879 filename = pkgdb_pkg_file(pkg->pkgname, INSTALL_FNAME); 876 filename = pkgdb_pkg_file(pkg->pkgname, INSTALL_FNAME);
880 877
881 ret = 0; 878 ret = 0;
882 errno = 0; 879 errno = 0;
883 if (fcexec(pkg->install_logdir, filename, pkg->pkgname, argument, 880 if (fcexec(pkg->install_logdir, filename, pkg->pkgname, argument,
884 (void *)NULL)) { 881 (void *)NULL)) {
885 if (errno != 0) 882 if (errno != 0)
886 warn("exec of install script failed"); 883 warn("exec of install script failed");
887 else 884 else
888 warnx("install script returned error status"); 885 warnx("install script returned error status");
889 ret = -1; 886 ret = -1;
890 } 887 }
891 free(filename); 888 free(filename);
892 889
893 return ret; 890 return ret;
894} 891}
895 892
896struct find_conflict_data { 893struct find_conflict_data {
897 const char *pkg; 894 const char *pkg;
898 const char *old_pkg; 895 const char *old_pkg;
899 const char *pattern; 896 const char *pattern;
900}; 897};
901 898
902static int 899static int
903check_explicit_conflict_iter(const char *cur_pkg, void *cookie) 900check_explicit_conflict_iter(const char *cur_pkg, void *cookie)
904{ 901{
905 struct find_conflict_data *data = cookie; 902 struct find_conflict_data *data = cookie;
906 903
907 if (data->old_pkg && strcmp(data->old_pkg, cur_pkg) == 0) 904 if (data->old_pkg && strcmp(data->old_pkg, cur_pkg) == 0)
908 return 0; 905 return 0;
909 906
910 warnx("Package `%s' conflicts with `%s', and `%s' is installed.", 907 warnx("Package `%s' conflicts with `%s', and `%s' is installed.",
911 data->pkg, data->pattern, cur_pkg); 908 data->pkg, data->pattern, cur_pkg);
912 909
913 return 1; 910 return 1;
914} 911}
915 912
916static int 913static int
917check_explicit_conflict(struct pkg_task *pkg) 914check_explicit_conflict(struct pkg_task *pkg)
918{ 915{
919 struct find_conflict_data data; 916 struct find_conflict_data data;
920 char *installed, *installed_pattern; 917 char *installed, *installed_pattern;
921 plist_t *p; 918 plist_t *p;
922 int status; 919 int status;
923 920
924 status = 0; 921 status = 0;
925 922
926 for (p = pkg->plist.head; p != NULL; p = p->next) { 923 for (p = pkg->plist.head; p != NULL; p = p->next) {
927 if (p->type == PLIST_IGNORE) { 924 if (p->type == PLIST_IGNORE) {
928 p = p->next; 925 p = p->next;
929 continue; 926 continue;
930 } 927 }
931 if (p->type != PLIST_PKGCFL) 928 if (p->type != PLIST_PKGCFL)
932 continue; 929 continue;
933 data.pkg = pkg->pkgname; 930 data.pkg = pkg->pkgname;
934 data.old_pkg = pkg->other_version; 931 data.old_pkg = pkg->other_version;
935 data.pattern = p->name; 932 data.pattern = p->name;
936 status |= match_installed_pkgs(p->name, 933 status |= match_installed_pkgs(p->name,
937 check_explicit_conflict_iter, &data); 934 check_explicit_conflict_iter, &data);
938 } 935 }
939 936
940 if (some_installed_package_conflicts_with(pkg->pkgname, 937 if (some_installed_package_conflicts_with(pkg->pkgname,
941 pkg->other_version, &installed, &installed_pattern)) { 938 pkg->other_version, &installed, &installed_pattern)) {
942 warnx("Installed package `%s' conflicts with `%s' when trying to install `%s'.", 939 warnx("Installed package `%s' conflicts with `%s' when trying to install `%s'.",
943 installed, installed_pattern, pkg->pkgname); 940 installed, installed_pattern, pkg->pkgname);
944 free(installed); 941 free(installed);
945 free(installed_pattern); 942 free(installed_pattern);
946 status |= -1; 943 status |= -1;
947 } 944 }
948 945
949 return status; 946 return status;
950} 947}
951 948
952static int 949static int
953check_implicit_conflict(struct pkg_task *pkg) 950check_implicit_conflict(struct pkg_task *pkg)
954{ 951{
955 plist_t *p; 952 plist_t *p;
956 char *fullpath, *existing; 953 char *fullpath, *existing;
957 int status; 954 int status;
958 955
959 if (!pkgdb_open(ReadOnly)) { 956 if (!pkgdb_open(ReadOnly)) {
960#if notyet /* XXX empty pkgdb without database? */ 957#if notyet /* XXX empty pkgdb without database? */
961 warn("Can't open pkgdb for reading"); 958 warn("Can't open pkgdb for reading");
962 return -1; 959 return -1;
963#else 960#else
964 return 0; 961 return 0;
965#endif 962#endif
966 } 963 }
967 964
968 status = 0; 965 status = 0;
969 966
970 for (p = pkg->plist.head; p != NULL; p = p->next) { 967 for (p = pkg->plist.head; p != NULL; p = p->next) {
971 if (p->type == PLIST_IGNORE) { 968 if (p->type == PLIST_IGNORE) {
972 p = p->next; 969 p = p->next;
973 continue; 970 continue;
974 } else if (p->type != PLIST_FILE) 971 } else if (p->type != PLIST_FILE)
975 continue; 972 continue;
976 973
977 fullpath = xasprintf("%s/%s", pkg->prefix, p->name); 974 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
978 existing = pkgdb_retrieve(fullpath); 975 existing = pkgdb_retrieve(fullpath);
979 free(fullpath); 976 free(fullpath);
980 if (existing == NULL) 977 if (existing == NULL)
981 continue; 978 continue;
982 if (pkg->other_version != NULL && 979 if (pkg->other_version != NULL &&
983 strcmp(pkg->other_version, existing) == 0) 980 strcmp(pkg->other_version, existing) == 0)
984 continue; 981 continue;
985 982
986 warnx("Conflicting PLIST with %s: %s", existing, p->name); 983 warnx("Conflicting PLIST with %s: %s", existing, p->name);
987 if (!Force) { 984 if (!Force) {
988 status = -1; 985 status = -1;
989 if (!Verbose) 986 if (!Verbose)
990 break; 987 break;
991 } 988 }
992 } 989 }
993 990
994 pkgdb_close(); 991 pkgdb_close();
995 return status; 992 return status;
996} 993}
997 994
998static int 995static int
999check_dependencies(struct pkg_task *pkg) 996check_dependencies(struct pkg_task *pkg)
1000{ 997{
1001 plist_t *p; 998 plist_t *p;
1002 char *best_installed; 999 char *best_installed;
1003 int status; 1000 int status;
1004 size_t i; 1001 size_t i;
1005 1002
1006 status = 0; 1003 status = 0;
1007 1004
1008 for (p = pkg->plist.head; p != NULL; p = p->next) { 1005 for (p = pkg->plist.head; p != NULL; p = p->next) {
1009 if (p->type == PLIST_IGNORE) { 1006 if (p->type == PLIST_IGNORE) {
1010 p = p->next; 1007 p = p->next;
1011 continue; 1008 continue;
1012 } else if (p->type != PLIST_PKGDEP) 1009 } else if (p->type != PLIST_PKGDEP)
1013 continue; 1010 continue;
1014 1011
1015 best_installed = find_best_matching_installed_pkg(p->name); 1012 best_installed = find_best_matching_installed_pkg(p->name);
1016 1013
1017 if (best_installed == NULL) { 1014 if (best_installed == NULL) {
1018 /* XXX check cyclic dependencies? */ 1015 /* XXX check cyclic dependencies? */
1019 if (Fake || NoRecord) { 1016 if (Fake || NoRecord) {
1020 if (!Force) { 1017 if (!Force) {
1021 warnx("Missing dependency %s\n", 1018 warnx("Missing dependency %s\n",
1022 p->name); 1019 p->name);
1023 status = -1; 1020 status = -1;
1024 break; 1021 break;
1025 } 1022 }
1026 warnx("Missing dependency %s, continuing", 1023 warnx("Missing dependency %s, continuing",
1027 p->name); 1024 p->name);
1028 continue; 1025 continue;
1029 } 1026 }
1030 if (pkg_do(p->name, 1, 0)) { 1027 if (pkg_do(p->name, 1, 0)) {
1031 warnx("Can't install dependency %s", p->name); 1028 warnx("Can't install dependency %s", p->name);
1032 status = -1; 1029 status = -1;
1033 break; 1030 break;
1034 } 1031 }
1035 best_installed = find_best_matching_installed_pkg(p->name); 1032 best_installed = find_best_matching_installed_pkg(p->name);
1036 if (best_installed == NULL && Force) { 1033 if (best_installed == NULL && Force) {
1037 warnx("Missing dependency %s ignored", p->name); 1034 warnx("Missing dependency %s ignored", p->name);
1038 continue; 1035 continue;
1039 } else if (best_installed == NULL) { 1036 } else if (best_installed == NULL) {
1040 warnx("Just installed dependency %s disappeared", p->name); 1037 warnx("Just installed dependency %s disappeared", p->name);
1041 status = -1; 1038 status = -1;
1042 break; 1039 break;
1043 } 1040 }
1044 } 1041 }
1045 for (i = 0; i < pkg->dep_length; ++i) { 1042 for (i = 0; i < pkg->dep_length; ++i) {
1046 if (strcmp(best_installed, pkg->dependencies[i]) == 0) 1043 if (strcmp(best_installed, pkg->dependencies[i]) == 0)
1047 break; 1044 break;
1048 } 1045 }
1049 if (i < pkg->dep_length) { 1046 if (i < pkg->dep_length) {
1050 /* Already used as dependency, so skip it. */ 1047 /* Already used as dependency, so skip it. */
1051 free(best_installed); 1048 free(best_installed);
1052 continue; 1049 continue;
1053 } 1050 }
1054 if (pkg->dep_length + 1 >= pkg->dep_allocated) { 1051 if (pkg->dep_length + 1 >= pkg->dep_allocated) {
1055 char **tmp; 1052 char **tmp;
1056 pkg->dep_allocated = 2 * pkg->dep_allocated + 1; 1053 pkg->dep_allocated = 2 * pkg->dep_allocated + 1;
1057 pkg->dependencies = xrealloc(pkg->dependencies, 1054 pkg->dependencies = xrealloc(pkg->dependencies,
1058 pkg->dep_allocated * sizeof(*tmp)); 1055 pkg->dep_allocated * sizeof(*tmp));
1059 } 1056 }
1060 pkg->dependencies[pkg->dep_length++] = best_installed; 1057 pkg->dependencies[pkg->dep_length++] = best_installed;
1061 } 1058 }
1062 1059
1063 return status; 1060 return status;
1064} 1061}
1065 1062
1066/* 1063/*
1067 * If this package uses pkg_views, register it in the default view. 1064 * If this package uses pkg_views, register it in the default view.
1068 */ 1065 */
1069static void 1066static void
1070pkg_register_views(struct pkg_task *pkg) 1067pkg_register_views(struct pkg_task *pkg)
1071{ 1068{
1072 if (Fake || NoView || pkg->meta_data.meta_views == NULL) 1069 if (Fake || NoView || pkg->meta_data.meta_views == NULL)
1073 return; 1070 return;
1074 1071
1075 if (Verbose) { 1072 if (Verbose) {
1076 printf("%s/pkg_view -d %s %s%s %s%s %sadd %s\n", 1073 printf("%s/pkg_view -d %s %s%s %s%s %sadd %s\n",
1077 BINDIR, _pkgdb_getPKGDB_DIR(), 1074 BINDIR, _pkgdb_getPKGDB_DIR(),
1078 View ? "-w " : "", View ? View : "", 1075 View ? "-w " : "", View ? View : "",
1079 Viewbase ? "-W " : "", Viewbase ? Viewbase : "", 1076 Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1080 Verbose ? "-v " : "", pkg->pkgname); 1077 Verbose ? "-v " : "", pkg->pkgname);
1081 } 1078 }
1082 1079
1083 fexec_skipempty(BINDIR "/pkg_view", "-d", _pkgdb_getPKGDB_DIR(), 1080 fexec_skipempty(BINDIR "/pkg_view", "-d", _pkgdb_getPKGDB_DIR(),
1084 View ? "-w " : "", View ? View : "", 1081 View ? "-w " : "", View ? View : "",
1085 Viewbase ? "-W " : "", Viewbase ? Viewbase : "", 1082 Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1086 Verbose ? "-v " : "", "add", pkg->pkgname, 1083 Verbose ? "-v " : "", "add", pkg->pkgname,
1087 (void *)NULL); 1084 (void *)NULL);
1088} 1085}
1089 1086
1090static int 1087static int
1091preserve_meta_data_file(struct pkg_task *pkg, const char *name) 1088preserve_meta_data_file(struct pkg_task *pkg, const char *name)
1092{ 1089{
1093 char *old_file, *new_file; 1090 char *old_file, *new_file;
1094 int rv; 1091 int rv;
1095 1092
1096 if (Fake) 1093 if (Fake)
1097 return 0; 1094 return 0;
1098 1095
1099 old_file = pkgdb_pkg_file(pkg->other_version, name); 1096 old_file = pkgdb_pkg_file(pkg->other_version, name);
1100 new_file = pkgdb_pkg_file(pkg->pkgname, name); 1097 new_file = pkgdb_pkg_file(pkg->pkgname, name);
1101 rv = 0; 1098 rv = 0;
1102 if (rename(old_file, new_file) == -1 && errno != ENOENT) { 1099 if (rename(old_file, new_file) == -1 && errno != ENOENT) {
1103 warn("Can't move %s from %s to %s", name, old_file, new_file); 1100 warn("Can't move %s from %s to %s", name, old_file, new_file);
1104 rv = -1;  1101 rv = -1;
1105 } 1102 }
1106 free(old_file); 1103 free(old_file);
1107 free(new_file); 1104 free(new_file);
1108 return rv; 1105 return rv;
1109} 1106}
1110 1107
1111static int 1108static int
1112start_replacing(struct pkg_task *pkg) 1109start_replacing(struct pkg_task *pkg)
1113{ 1110{
1114 if (preserve_meta_data_file(pkg, REQUIRED_BY_FNAME)) 1111 if (preserve_meta_data_file(pkg, REQUIRED_BY_FNAME))
1115 return -1; 1112 return -1;
1116 1113
1117 if (preserve_meta_data_file(pkg, PRESERVE_FNAME)) 1114 if (preserve_meta_data_file(pkg, PRESERVE_FNAME))
1118 return -1; 1115 return -1;
1119 1116
1120 if (pkg->meta_data.meta_installed_info == NULL && 1117 if (pkg->meta_data.meta_installed_info == NULL &&
1121 preserve_meta_data_file(pkg, INSTALLED_INFO_FNAME)) 1118 preserve_meta_data_file(pkg, INSTALLED_INFO_FNAME))
1122 return -1; 1119 return -1;
1123 1120
1124 if (Verbose || Fake) { 1121 if (Verbose || Fake) {
1125 printf("%s/pkg_delete -K %s -p %s%s%s '%s'\n", 1122 printf("%s/pkg_delete -K %s -p %s%s%s '%s'\n",
1126 BINDIR, _pkgdb_getPKGDB_DIR(), pkg->prefix, 1123 BINDIR, _pkgdb_getPKGDB_DIR(), pkg->prefix,
1127 Destdir ? " -P ": "", Destdir ? Destdir : "", 1124 Destdir ? " -P ": "", Destdir ? Destdir : "",
1128 pkg->other_version); 1125 pkg->other_version);
1129 } 1126 }
1130 if (!Fake) 1127 if (!Fake)
1131 fexec_skipempty(BINDIR "/pkg_delete", "-K", _pkgdb_getPKGDB_DIR(), 1128 fexec_skipempty(BINDIR "/pkg_delete", "-K", _pkgdb_getPKGDB_DIR(),
1132 "-p", pkg->prefix, 1129 "-p", pkg->prefix,
1133 Destdir ? "-P": "", Destdir ? Destdir : "", 1130 Destdir ? "-P": "", Destdir ? Destdir : "",
1134 pkg->other_version, NULL); 1131 pkg->other_version, NULL);
1135 1132
1136 /* XXX Check return value and do what? */ 1133 /* XXX Check return value and do what? */
1137 return 0; 1134 return 0;
1138} 1135}
1139 1136
1140static int check_input(const char *line, size_t len) 1137static int check_input(const char *line, size_t len)
1141{ 1138{
1142 if (line == NULL || len == 0) 1139 if (line == NULL || len == 0)
1143 return 1; 1140 return 1;
1144 switch (*line) { 1141 switch (*line) {
1145 case 'Y': 1142 case 'Y':
1146 case 'y': 1143 case 'y':
1147 case 'T': 1144 case 'T':
1148 case 't': 1145 case 't':
1149 case '1': 1146 case '1':
1150 return 0; 1147 return 0;
1151 default: 1148 default:
1152 return 1; 1149 return 1;
1153 } 1150 }
1154} 1151}
1155 1152
1156static int 1153static int
1157check_signature(struct pkg_task *pkg, int invalid_sig) 1154check_signature(struct pkg_task *pkg, int invalid_sig)
1158{ 1155{
1159 char *line; 1156 char *line;
1160 size_t len; 1157 size_t len;
1161 1158
1162 if (strcasecmp(verified_installation, "never") == 0) 1159 if (strcasecmp(verified_installation, "never") == 0)
1163 return 0; 1160 return 0;
1164 if (strcasecmp(verified_installation, "always") == 0) { 1161 if (strcasecmp(verified_installation, "always") == 0) {
1165 if (invalid_sig) 1162 if (invalid_sig)
1166 warnx("No valid signature found, rejected"); 1163 warnx("No valid signature found, rejected");
1167 return invalid_sig; 1164 return invalid_sig;
1168 } 1165 }
1169 if (strcasecmp(verified_installation, "trusted") == 0) { 1166 if (strcasecmp(verified_installation, "trusted") == 0) {
1170 if (!invalid_sig) 1167 if (!invalid_sig)
1171 return 0; 1168 return 0;
1172 fprintf(stderr, "No valid signature found for %s.\n", 1169 fprintf(stderr, "No valid signature found for %s.\n",
1173 pkg->pkgname); 1170 pkg->pkgname);
1174 fprintf(stderr, 1171 fprintf(stderr,
1175 "Do you want to proceed with the installation [y/n]?\n"); 1172 "Do you want to proceed with the installation [y/n]?\n");
1176 line = fgetln(stdin, &len); 1173 line = fgetln(stdin, &len);
1177 if (check_input(line, len)) { 1174 if (check_input(line, len)) {
1178 fprintf(stderr, "Cancelling installation\n"); 1175 fprintf(stderr, "Cancelling installation\n");
1179 return 1; 1176 return 1;
1180 } 1177 }
1181 return 0; 1178 return 0;
1182 } 1179 }
1183 if (strcasecmp(verified_installation, "interactive") == 0) { 1180 if (strcasecmp(verified_installation, "interactive") == 0) {
1184 fprintf(stderr, "Do you want to proceed with " 1181 fprintf(stderr, "Do you want to proceed with "
1185 "the installation of %s [y/n]?\n", pkg->pkgname); 1182 "the installation of %s [y/n]?\n", pkg->pkgname);
1186 line = fgetln(stdin, &len); 1183 line = fgetln(stdin, &len);
1187 if (check_input(line, len)) { 1184 if (check_input(line, len)) {
1188 fprintf(stderr, "Cancelling installation\n"); 1185 fprintf(stderr, "Cancelling installation\n");
1189 return 1; 1186 return 1;
1190 } 1187 }
1191 return 0; 1188 return 0;
1192 } 1189 }
1193 warnx("Unknown value of configuration variable VERIFIED_INSTALLATION"); 1190 warnx("Unknown value of configuration variable VERIFIED_INSTALLATION");
1194 return 1; 1191 return 1;
1195} 1192}
1196 1193
1197static int 1194static int
1198check_vulnerable(struct pkg_task *pkg) 1195check_vulnerable(struct pkg_task *pkg)
1199{ 1196{
1200 static struct pkg_vulnerabilities *pv; 1197 static struct pkg_vulnerabilities *pv;
1201 int require_check; 1198 int require_check;
1202 char *line; 1199 char *line;
1203 size_t len; 1200 size_t len;
1204 1201
1205 if (strcasecmp(check_vulnerabilities, "never") == 0) 1202 if (strcasecmp(check_vulnerabilities, "never") == 0)
1206 return 0; 1203 return 0;
1207 else if (strcasecmp(check_vulnerabilities, "always")) 1204 else if (strcasecmp(check_vulnerabilities, "always"))
1208 require_check = 1; 1205 require_check = 1;
1209 else if (strcasecmp(check_vulnerabilities, "interactive")) 1206 else if (strcasecmp(check_vulnerabilities, "interactive"))
1210 require_check = 0; 1207 require_check = 0;
1211 else { 1208 else {
1212 warnx("Unknown value of the configuration variable" 1209 warnx("Unknown value of the configuration variable"
1213 "CHECK_VULNERABILITIES"); 1210 "CHECK_VULNERABILITIES");
1214 return 1; 1211 return 1;
1215 } 1212 }
1216 1213
1217 if (pv == NULL) { 1214 if (pv == NULL) {
1218 pv = read_pkg_vulnerabilities(pkg_vulnerabilities_file, 1215 pv = read_pkg_vulnerabilities(pkg_vulnerabilities_file,
1219 require_check, 0); 1216 require_check, 0);
1220 if (pv == NULL) 1217 if (pv == NULL)
1221 return require_check; 1218 return require_check;
1222 } 1219 }
1223 1220
1224 if (!audit_package(pv, pkg->pkgname, NULL, 0, 2)) 1221 if (!audit_package(pv, pkg->pkgname, NULL, 0, 2))
1225 return 0; 1222 return 0;
1226 1223
1227 if (require_check) 1224 if (require_check)
1228 return 1; 1225 return 1;
1229 1226
1230 fprintf(stderr, "Do you want to proceed with the installation of %s" 1227 fprintf(stderr, "Do you want to proceed with the installation of %s"
1231 " [y/n]?\n", pkg->pkgname); 1228 " [y/n]?\n", pkg->pkgname);
1232 line = fgetln(stdin, &len); 1229 line = fgetln(stdin, &len);
1233 if (check_input(line, len)) { 1230 if (check_input(line, len)) {
1234 fprintf(stderr, "Cancelling installation\n"); 1231 fprintf(stderr, "Cancelling installation\n");
1235 return 1; 1232 return 1;
1236 } 1233 }
1237 return 0; 1234 return 0;
1238} 1235}
1239 1236
1240/* 1237/*
1241 * Install a single package. 1238 * Install a single package.
1242 */ 1239 */
1243static int 1240static int
1244pkg_do(const char *pkgpath, int mark_automatic, int top_level) 1241pkg_do(const char *pkgpath, int mark_automatic, int top_level)
1245{ 1242{
1246 int status, invalid_sig; 1243 int status, invalid_sig;
1247 struct pkg_task *pkg; 1244 struct pkg_task *pkg;
1248 1245
1249 pkg = xcalloc(1, sizeof(*pkg)); 1246 pkg = xcalloc(1, sizeof(*pkg));
1250 1247
1251 status = -1; 1248 status = -1;
1252 1249
1253 pkg->archive = find_archive(pkgpath, top_level); 1250 pkg->archive = find_archive(pkgpath, top_level);
1254 if (pkg->archive == NULL) { 1251 if (pkg->archive == NULL) {
1255 warnx("no pkg found for '%s', sorry.", pkgpath); 1252 warnx("no pkg found for '%s', sorry.", pkgpath);
1256 goto clean_find_archive; 1253 goto clean_find_archive;
1257 } 1254 }
1258 1255
1259 invalid_sig = pkg_verify_signature(&pkg->archive, &pkg->entry, 1256 invalid_sig = pkg_verify_signature(&pkg->archive, &pkg->entry,
1260 &pkg->pkgname); 1257 &pkg->pkgname);
1261 1258
1262 if (pkg->archive == NULL) 1259 if (pkg->archive == NULL)
1263 goto clean_memory; 1260 goto clean_memory;
1264 1261
1265 if (read_meta_data(pkg)) 1262 if (read_meta_data(pkg))
1266 goto clean_memory; 1263 goto clean_memory;
1267 1264
1268 /* Parse PLIST early, so that messages can use real package name. */ 1265 /* Parse PLIST early, so that messages can use real package name. */
1269 if (pkg_parse_plist(pkg)) 1266 if (pkg_parse_plist(pkg))
1270 goto clean_memory; 1267 goto clean_memory;
1271 1268
1272 if (check_signature(pkg, invalid_sig)) 1269 if (check_signature(pkg, invalid_sig))
1273 goto clean_memory; 1270 goto clean_memory;
1274 1271
1275 if (check_vulnerable(pkg)) 1272 if (check_vulnerable(pkg))
1276 goto clean_memory; 1273 goto clean_memory;
1277 1274
1278 if (pkg->meta_data.meta_mtree != NULL) 1275 if (pkg->meta_data.meta_mtree != NULL)
1279 warnx("mtree specification in pkg `%s' ignored", pkg->pkgname); 1276 warnx("mtree specification in pkg `%s' ignored", pkg->pkgname);
1280 1277
1281 if (pkg->meta_data.meta_views != NULL) { 1278 if (pkg->meta_data.meta_views != NULL) {
1282 pkg->logdir = xstrdup(pkg->prefix); 1279 pkg->logdir = xstrdup(pkg->prefix);
1283 _pkgdb_setPKGDB_DIR(dirname_of(pkg->logdir)); 1280 _pkgdb_setPKGDB_DIR(dirname_of(pkg->logdir));
1284 } else { 1281 } else {
1285 pkg->logdir = xasprintf("%s/%s", _pkgdb_getPKGDB_DIR(), 1282 pkg->logdir = xasprintf("%s/%s", _pkgdb_getPKGDB_DIR(),
1286 pkg->pkgname); 1283 pkg->pkgname);
1287 } 1284 }
1288 1285
1289 if (Destdir != NULL) { 1286 if (Destdir != NULL) {
1290 pkg->install_logdir = xasprintf("%s/%s", Destdir, pkg->logdir); 1287 pkg->install_logdir = xasprintf("%s/%s", Destdir, pkg->logdir);
1291 _pkgdb_setPKGDB_DIR(dirname_of(pkg->install_logdir)); 1288 _pkgdb_setPKGDB_DIR(dirname_of(pkg->install_logdir));
1292 } else 1289 } else
1293 pkg->install_logdir = xstrdup(pkg->logdir); 1290 pkg->install_logdir = xstrdup(pkg->logdir);
1294 1291
1295 if (NoRecord && !Fake) { 1292 if (NoRecord && !Fake) {
1296 const char *tmpdir; 1293 const char *tmpdir;
1297 1294
1298 tmpdir = getenv("TMPDIR"); 1295 tmpdir = getenv("TMPDIR");
1299 if (tmpdir == NULL) 1296 if (tmpdir == NULL)
1300 tmpdir = "/tmp"; 1297 tmpdir = "/tmp";
1301 1298
1302 free(pkg->install_logdir); 1299 free(pkg->install_logdir);
1303 pkg->install_logdir = xasprintf("%s/pkg_install.XXXXXX", tmpdir); 1300 pkg->install_logdir = xasprintf("%s/pkg_install.XXXXXX", tmpdir);
1304 /* XXX pkg_add -u... */ 1301 /* XXX pkg_add -u... */
1305 if (mkdtemp(pkg->install_logdir) == NULL) { 1302 if (mkdtemp(pkg->install_logdir) == NULL) {
1306 warn("mkdtemp failed"); 1303 warn("mkdtemp failed");
1307 goto clean_memory; 1304 goto clean_memory;
1308 } 1305 }
1309 } 1306 }
1310 1307
1311 if (check_already_installed(pkg) == 0) { 1308 if (check_already_installed(pkg) == 0) {
1312 status = 0; 1309 status = 0;
1313 goto clean_memory; 1310 goto clean_memory;
1314 } 1311 }
1315 1312
1316 if (read_buildinfo(pkg)) 1313 if (read_buildinfo(pkg))
1317 goto clean_memory; 1314 goto clean_memory;
1318 1315
1319 if (check_platform(pkg)) 1316 if (check_platform(pkg))
1320 goto clean_memory; 1317 goto clean_memory;
1321 1318
1322 if (check_other_installed(pkg)) 1319 if (check_other_installed(pkg))
1323 goto clean_memory;  1320 goto clean_memory;
1324 1321
1325 if (check_explicit_conflict(pkg)) 1322 if (check_explicit_conflict(pkg))
1326 goto clean_memory; 1323 goto clean_memory;
1327 1324
1328 if (check_implicit_conflict(pkg)) 1325 if (check_implicit_conflict(pkg))
1329 goto clean_memory; 1326 goto clean_memory;
1330 1327
1331 if (pkg->other_version != NULL) { 1328 if (pkg->other_version != NULL) {
1332 /* 1329 /*
1333 * Replacing an existing package. 1330 * Replacing an existing package.
1334 * Write meta-data, get rid of the old version, 1331 * Write meta-data, get rid of the old version,
1335 * install/update dependencies and finally extract. 1332 * install/update dependencies and finally extract.
1336 */ 1333 */
1337 if (write_meta_data(pkg)) 1334 if (write_meta_data(pkg))
1338 goto nuke_pkgdb; 1335 goto nuke_pkgdb;
1339 1336
1340 if (start_replacing(pkg)) 1337 if (start_replacing(pkg))
1341 goto nuke_pkgdb; 1338 goto nuke_pkgdb;
1342 1339
1343 if (check_dependencies(pkg)) 1340 if (check_dependencies(pkg))
1344 goto nuke_pkgdb; 1341 goto nuke_pkgdb;
1345 } else { 1342 } else {
1346 /* 1343 /*
1347 * Normal installation. 1344 * Normal installation.
1348 * Install/update dependencies first and 1345 * Install/update dependencies first and
1349 * write the current package to disk afterwards. 1346 * write the current package to disk afterwards.
1350 */  1347 */
1351 if (check_dependencies(pkg)) 1348 if (check_dependencies(pkg))
1352 goto clean_memory; 1349 goto clean_memory;
1353 1350
1354 if (write_meta_data(pkg)) 1351 if (write_meta_data(pkg))
1355 goto nuke_pkgdb; 1352 goto nuke_pkgdb;
1356 } 1353 }
1357 1354
1358 if (run_install_script(pkg, "PRE-INSTALL")) 1355 if (run_install_script(pkg, "PRE-INSTALL"))
1359 goto nuke_pkgdb; 1356 goto nuke_pkgdb;
1360 1357
1361 if (extract_files(pkg)) 1358 if (extract_files(pkg))
1362 goto nuke_pkg; 1359 goto nuke_pkg;
1363 1360
1364 if (run_install_script(pkg, "POST-INSTALL")) 1361 if (run_install_script(pkg, "POST-INSTALL"))
1365 goto nuke_pkgdb; 1362 goto nuke_pkgdb;
1366 1363
1367 /* XXX keep +INSTALL_INFO for updates? */ 1364 /* XXX keep +INSTALL_INFO for updates? */
1368 /* XXX keep +PRESERVE for updates? */ 1365 /* XXX keep +PRESERVE for updates? */
1369 if (mark_automatic) 1366 if (mark_automatic)
1370 mark_as_automatic_installed(pkg->pkgname, 1); 1367 mark_as_automatic_installed(pkg->pkgname, 1);
1371 1368
1372 pkg_register_depends(pkg); 1369 pkg_register_depends(pkg);
1373 1370
1374 if (Verbose) 1371 if (Verbose)
1375 printf("Package %s registered in %s\n", pkg->pkgname, pkg->install_logdir); 1372 printf("Package %s registered in %s\n", pkg->pkgname, pkg->install_logdir);
1376 1373
1377 if (pkg->meta_data.meta_display != NULL) 1374 if (pkg->meta_data.meta_display != NULL)
1378 fputs(pkg->meta_data.meta_display, stdout); 1375 fputs(pkg->meta_data.meta_display, stdout);
1379 1376
1380 pkg_register_views(pkg); 1377 pkg_register_views(pkg);
1381 1378
1382 status = 0; 1379 status = 0;
1383 goto clean_memory; 1380 goto clean_memory;
1384 1381
1385nuke_pkg: 1382nuke_pkg:
1386 if (!Fake) { 1383 if (!Fake) {
1387 if (pkg->other_version) { 1384 if (pkg->other_version) {
1388 warnx("Updating of %s to %s failed.", 1385 warnx("Updating of %s to %s failed.",
1389 pkg->other_version, pkg->pkgname); 1386 pkg->other_version, pkg->pkgname);
1390 warnx("Remember to run pkg_admin rebuild-tree after fixing this."); 1387 warnx("Remember to run pkg_admin rebuild-tree after fixing this.");
1391 } 1388 }
1392 delete_package(FALSE, FALSE, &pkg->plist, FALSE, Destdir); 1389 delete_package(FALSE, FALSE, &pkg->plist, FALSE, Destdir);
1393 } 1390 }
1394 1391
1395nuke_pkgdb: 1392nuke_pkgdb:
1396 if (!Fake) { 1393 if (!Fake) {
1397 if (recursive_remove(pkg->install_logdir, 1)) 1394 if (recursive_remove(pkg->install_logdir, 1))
1398 warn("Couldn't remove %s", pkg->install_logdir); 1395 warn("Couldn't remove %s", pkg->install_logdir);
1399 free(pkg->install_logdir); 1396 free(pkg->install_logdir);
1400 free(pkg->logdir); 1397 free(pkg->logdir);
1401 pkg->install_logdir = NULL; 1398 pkg->install_logdir = NULL;
1402 pkg->logdir = NULL; 1399 pkg->logdir = NULL;
1403 } 1400 }
1404 1401
1405clean_memory: 1402clean_memory:
1406 if (pkg->logdir != NULL && NoRecord && !Fake) { 1403 if (pkg->logdir != NULL && NoRecord && !Fake) {
1407 if (recursive_remove(pkg->install_logdir, 1)) 1404 if (recursive_remove(pkg->install_logdir, 1))
1408 warn("Couldn't remove %s", pkg->install_logdir); 1405 warn("Couldn't remove %s", pkg->install_logdir);
1409 } 1406 }
1410 free(pkg->install_prefix); 1407 free(pkg->install_prefix);
1411 free(pkg->install_logdir); 1408 free(pkg->install_logdir);
1412 free(pkg->logdir); 1409 free(pkg->logdir);
1413 free_buildinfo(pkg); 1410 free_buildinfo(pkg);
1414 free_plist(&pkg->plist); 1411 free_plist(&pkg->plist);
1415 free_meta_data(pkg); 1412 free_meta_data(pkg);
1416 if (pkg->archive) 1413 if (pkg->archive)
1417 archive_read_finish(pkg->archive); 1414 archive_read_finish(pkg->archive);
1418 free(pkg->other_version); 1415 free(pkg->other_version);
1419 free(pkg->pkgname); 1416 free(pkg->pkgname);
1420clean_find_archive: 1417clean_find_archive:
1421 free(pkg); 1418 free(pkg);
1422 return status; 1419 return status;
1423} 1420}
1424 1421
1425int 1422int
1426pkg_perform(lpkg_head_t *pkgs) 1423pkg_perform(lpkg_head_t *pkgs)
1427{ 1424{
1428 int errors = 0; 1425 int errors = 0;
1429 lpkg_t *lpp; 1426 lpkg_t *lpp;
1430 1427
1431 while ((lpp = TAILQ_FIRST(pkgs)) != NULL) { 1428 while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
1432 if (pkg_do(lpp->lp_name, Automatic, 1)) 1429 if (pkg_do(lpp->lp_name, Automatic, 1))
1433 ++errors; 1430 ++errors;
1434 TAILQ_REMOVE(pkgs, lpp, lp_link); 1431 TAILQ_REMOVE(pkgs, lpp, lp_link);
1435 free_lpkg(lpp); 1432 free_lpkg(lpp);
1436 } 1433 }
1437 1434
1438 return errors; 1435 return errors;
1439} 1436}

cvs diff -r1.120 -r1.121 pkgsrc/pkgtools/pkg_install/files/lib/version.h (switch to unified diff)

--- pkgsrc/pkgtools/pkg_install/files/lib/version.h 2009/03/26 14:32:39 1.120
+++ pkgsrc/pkgtools/pkg_install/files/lib/version.h 2009/04/06 14:34:15 1.121
@@ -1,32 +1,32 @@ @@ -1,32 +1,32 @@
1/* $NetBSD: version.h,v 1.120 2009/03/26 14:32:39 joerg Exp $ */ 1/* $NetBSD: version.h,v 1.121 2009/04/06 14:34:15 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Thomas Klausner. All rights reserved. 4 * Copyright (c) 2001 Thomas Klausner. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27#ifndef _INST_LIB_VERSION_H_ 27#ifndef _INST_LIB_VERSION_H_
28#define _INST_LIB_VERSION_H_ 28#define _INST_LIB_VERSION_H_
29 29
30#define PKGTOOLS_VERSION "20090326" 30#define PKGTOOLS_VERSION "20090406"
31 31
32#endif /* _INST_LIB_VERSION_H_ */ 32#endif /* _INST_LIB_VERSION_H_ */