Gentoo Archives: gentoo-commits

From: "Mike Frysinger (vapier)" <vapier@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-projects commit in portage-utils: .depend main.c qmerge.c
Date: Wed, 23 Feb 2011 22:59:07
Message-Id: 20110223225852.142BE20054@flycatcher.gentoo.org
1 vapier 11/02/23 22:58:52
2
3 Modified: .depend main.c qmerge.c
4 Log:
5 rewrite merge code to take care of file updates ourself rather than shelling out
6
7 Revision Changes Path
8 1.41 portage-utils/.depend
9
10 file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/.depend?rev=1.41&view=markup
11 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/.depend?rev=1.41&content-type=text/plain
12 diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/.depend?r1=1.40&r2=1.41
13
14 Index: .depend
15 ===================================================================
16 RCS file: /var/cvsroot/gentoo-projects/portage-utils/.depend,v
17 retrieving revision 1.40
18 retrieving revision 1.41
19 diff -u -r1.40 -r1.41
20 --- .depend 23 Feb 2011 08:59:45 -0000 1.40
21 +++ .depend 23 Feb 2011 22:58:51 -0000 1.41
22 @@ -1,9 +1,9 @@
23 main.o: main.c main.h libq/libq.c libq/busybox.h libq/i18n.h libq/libq.h \
24 libq/colors.c libq/xmalloc.c libq/xstrdup.c libq/xasprintf.c \
25 libq/hash_fd.c libq/md5_sha1_sum.c libq/human_readable.c libq/rmspace.c \
26 - libq/which.c libq/compat.c libq/safe_io.c libq/xchdir.c libq/xgetcwd.c \
27 - libq/xmkdir.c libq/xreadlink.c libq/xsystem.c libq/atom_explode.c \
28 - libq/atom_compare.c libq/basename.c libq/vdb_get_next_dir.c \
29 - libq/virtuals.c applets.h include_applets.h q.c qcheck.c qdepends.c \
30 - qfile.c qlist.c qlop.c qsearch.c qsize.c qtbz2.c quse.c qxpak.c qpkg.c \
31 - qgrep.c qatom.c qmerge.c qcache.c qglsa.c
32 + libq/which.c libq/compat.c libq/copy_file.c libq/safe_io.c libq/xchdir.c \
33 + libq/xgetcwd.c libq/xmkdir.c libq/xreadlink.c libq/xsystem.c \
34 + libq/atom_explode.c libq/atom_compare.c libq/basename.c \
35 + libq/vdb_get_next_dir.c libq/virtuals.c applets.h include_applets.h q.c \
36 + qcheck.c qdepends.c qfile.c qlist.c qlop.c qsearch.c qsize.c qtbz2.c \
37 + quse.c qxpak.c qpkg.c qgrep.c qatom.c qmerge.c qcache.c qglsa.c
38
39
40
41 1.185 portage-utils/main.c
42
43 file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/main.c?rev=1.185&view=markup
44 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/main.c?rev=1.185&content-type=text/plain
45 diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/main.c?r1=1.184&r2=1.185
46
47 Index: main.c
48 ===================================================================
49 RCS file: /var/cvsroot/gentoo-projects/portage-utils/main.c,v
50 retrieving revision 1.184
51 retrieving revision 1.185
52 diff -u -r1.184 -r1.185
53 --- main.c 23 Feb 2011 08:59:45 -0000 1.184
54 +++ main.c 23 Feb 2011 22:58:51 -0000 1.185
55 @@ -1,7 +1,7 @@
56 /*
57 * Copyright 2005-2008 Gentoo Foundation
58 * Distributed under the terms of the GNU General Public License v2
59 - * $Header: /var/cvsroot/gentoo-projects/portage-utils/main.c,v 1.184 2011/02/23 08:59:45 vapier Exp $
60 + * $Header: /var/cvsroot/gentoo-projects/portage-utils/main.c,v 1.185 2011/02/23 22:58:51 vapier Exp $
61 *
62 * Copyright 2005-2008 Ned Ludd - <solar@g.o>
63 * Copyright 2005-2008 Mike Frysinger - <vapier@g.o>
64 @@ -344,16 +344,14 @@
65 return NULL;
66 }
67
68 -void freeargv(int, char **);
69 -void freeargv(int argc, char **argv)
70 +static void freeargv(int argc, char **argv)
71 {
72 while (argc--)
73 free(argv[argc]);
74 free(argv);
75 }
76
77 -void makeargv(char *string, int *argc, char ***argv);
78 -void makeargv(char *string, int *argc, char ***argv)
79 +static void makeargv(const char *string, int *argc, char ***argv)
80 {
81 int curc = 2;
82 char *q, *p, *str;
83
84
85
86 1.103 portage-utils/qmerge.c
87
88 file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qmerge.c?rev=1.103&view=markup
89 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qmerge.c?rev=1.103&content-type=text/plain
90 diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qmerge.c?r1=1.102&r2=1.103
91
92 Index: qmerge.c
93 ===================================================================
94 RCS file: /var/cvsroot/gentoo-projects/portage-utils/qmerge.c,v
95 retrieving revision 1.102
96 retrieving revision 1.103
97 diff -u -r1.102 -r1.103
98 --- qmerge.c 23 Feb 2011 08:59:45 -0000 1.102
99 +++ qmerge.c 23 Feb 2011 22:58:51 -0000 1.103
100 @@ -1,7 +1,7 @@
101 /*
102 * Copyright 2005-2010 Gentoo Foundation
103 * Distributed under the terms of the GNU General Public License v2
104 - * $Header: /var/cvsroot/gentoo-projects/portage-utils/qmerge.c,v 1.102 2011/02/23 08:59:45 vapier Exp $
105 + * $Header: /var/cvsroot/gentoo-projects/portage-utils/qmerge.c,v 1.103 2011/02/23 22:58:51 vapier Exp $
106 *
107 * Copyright 2005-2010 Ned Ludd - <solar@g.o>
108 * Copyright 2005-2010 Mike Frysinger - <vapier@g.o>
109 @@ -55,7 +55,7 @@
110 COMMON_OPTS_HELP
111 };
112
113 -static const char qmerge_rcsid[] = "$Id: qmerge.c,v 1.102 2011/02/23 08:59:45 vapier Exp $";
114 +static const char qmerge_rcsid[] = "$Id: qmerge.c,v 1.103 2011/02/23 22:58:51 vapier Exp $";
115 #define qmerge_usage(ret) usage(ret, QMERGE_FLAGS, qmerge_long_opts, qmerge_opts_help, lookup_applet_idx("qmerge"))
116
117 char search_pkgs = 0;
118 @@ -420,6 +420,254 @@
119 free(script);
120 }
121
122 +/* Copy one tree (the single package) to another tree (ROOT) */
123 +static int merge_tree_at(int fd_src, const char *src, int fd_dst, const char *dst,
124 + FILE *contents, char **cpathp, int iargc, char **iargv,
125 + int cp_argc, char **cp_argv, int cpm_argc, char **cpm_argv)
126 +{
127 + int i, ret, subfd_src, subfd_dst;
128 + DIR *dir;
129 + struct dirent *de;
130 + struct stat st;
131 + char *cpath;
132 + size_t clen, nlen, mnlen;
133 +
134 + ret = -1;
135 +
136 + /* Get handles to these subdirs */
137 + subfd_src = openat(fd_src, src, O_RDONLY|O_CLOEXEC);
138 + if (subfd_src < 0)
139 + return ret;
140 + subfd_dst = openat(fd_dst, dst, O_RDONLY|O_CLOEXEC);
141 + if (subfd_dst < 0) {
142 + close(subfd_src);
143 + return ret;
144 + }
145 +
146 + dir = fdopendir(subfd_src);
147 + if (!dir)
148 + goto done;
149 +
150 + cpath = *cpathp;
151 + clen = strlen(cpath);
152 + cpath[clen] = '/';
153 + nlen = mnlen = 0;
154 +
155 + while ((de = readdir(dir)) != NULL) {
156 + const char *name = de->d_name;
157 +
158 + if (!strcmp(name, ".") || !strcmp(name, ".."))
159 + continue;
160 +
161 + /* Build up the full path for this entry */
162 + nlen = strlen(name);
163 + if (mnlen < nlen) {
164 + cpath = *cpathp = realloc(*cpathp, nlen + clen + 2);
165 + mnlen = nlen;
166 + }
167 + strcpy(cpath + clen + 1, name);
168 +
169 + /* Check INSTALL_MASK */
170 + for (i = 1; i < iargc; ++i) {
171 + if (fnmatch(iargv[i], cpath, 0) == 0) {
172 + unlinkat(subfd_src, name, 0);
173 + unlinkat(subfd_dst, name, 0);
174 + continue;
175 + }
176 + }
177 +
178 + /* Find out what the source path is */
179 + if (fstatat(subfd_src, name, &st, AT_SYMLINK_NOFOLLOW)) {
180 + warnp("could not read %s", cpath);
181 + continue;
182 + }
183 +
184 + /* Migrate a directory */
185 + if (S_ISDIR(st.st_mode)) {
186 + if (mkdirat(subfd_dst, name, st.st_mode)) {
187 + if (errno != EEXIST) {
188 + warnp("could not read %s", cpath);
189 + continue;
190 + }
191 +
192 + /* XXX: update times of dir ? */
193 + }
194 +
195 + /* syntax: dir dirname */
196 + fprintf(contents, "dir %s\n", cpath);
197 + qprintf("%s>>>%s %s%s%s/\n", GREEN, NORM, DKBLUE, cpath, NORM);
198 +
199 + /* Copy all of these contents */
200 + merge_tree_at(subfd_src, name, subfd_dst, name, contents, cpathp,
201 + iargc, iargv, cp_argc, cp_argv, cpm_argc, cpm_argv);
202 + }
203 +
204 + /* Migrate a file */
205 + else if (S_ISREG(st.st_mode)) {
206 + struct timespec times[2];
207 + int fd_srcf, fd_dstf;
208 + unsigned char *hash;
209 + const char *tmpname, *dname;
210 +
211 + /* syntax: obj filename hash mtime */
212 + hash = hash_file_at(subfd_src, name, HASH_MD5);
213 + fprintf(contents, "obj %s %s %lu\n", cpath, hash, (unsigned long)st.st_mtime);
214 +
215 + /* Check CONFIG_PROTECT */
216 + if (config_protected(cpath, cp_argc, cp_argv, cpm_argc, cpm_argv)) {
217 + /* ._cfg####_ */
218 + char *num;
219 + dname = num = alloca(nlen + 10 + 1);
220 + *num++ = '.';
221 + *num++ = '_';
222 + *num++ = 'c';
223 + *num++ = 'f';
224 + *num++ = 'g';
225 + strcpy(num + 5, name);
226 + for (i = 0; i < 10000; ++i) {
227 + sprintf(num, "%04i", i);
228 + num[4] = '_';
229 + if (faccessat(subfd_dst, dname, F_OK, AT_SYMLINK_NOFOLLOW))
230 + break;
231 + }
232 + qprintf("%s>>>%s %s (%s)\n", GREEN, NORM, cpath, dname);
233 + } else {
234 + dname = name;
235 + qprintf("%s>>>%s %s\n", GREEN, NORM, cpath);
236 + }
237 +
238 + /* First try fast path -- src/dst are same device */
239 + if (renameat(subfd_src, dname, subfd_dst, name))
240 + ;
241 +
242 + /* Fall back to slow path -- manual read/write */
243 + fd_srcf = openat(subfd_src, name, O_RDONLY|O_CLOEXEC);
244 + if (fd_srcf < 0) {
245 + warnp("could not read %s", cpath);
246 + continue;
247 + }
248 +
249 + /* Do not write the file in place ...
250 + * will fail with files that are in use.
251 + * XXX: Should we make this random ?
252 + */
253 + tmpname = ".qmerge.update";
254 + fd_dstf = openat(subfd_dst, tmpname, O_WRONLY|O_CLOEXEC|O_CREAT|O_TRUNC, st.st_mode);
255 + if (fd_dstf < 0) {
256 + warnp("could not write %s", cpath);
257 + close(fd_srcf);
258 + continue;
259 + }
260 +
261 + /* Make sure owner/mode is sane before we write out data */
262 + if (fchown(fd_dstf, st.st_uid, st.st_gid)) {
263 + warnp("could not set ownership %s", cpath);
264 + continue;
265 + }
266 + if (fchmod(fd_dstf, st.st_mode)) {
267 + warnp("could not set permission %s", cpath);
268 + continue;
269 + }
270 +
271 + /* Do the actual data copy */
272 + if (copy_file_fd(fd_srcf, fd_dstf)) {
273 + warnp("could not write %s", cpath);
274 + if (ftruncate(fd_dstf, 0))
275 + /* don't care */;
276 + close(fd_srcf);
277 + close(fd_dstf);
278 + continue;
279 + }
280 +
281 + /* Preserve the file times */
282 + times[0] = st.st_mtim;
283 + times[1] = st.st_mtim;
284 + futimens(fd_dstf, times);
285 +
286 + close(fd_srcf);
287 + close(fd_dstf);
288 +
289 + /* Move the new tmp dst file to the right place */
290 + if (renameat(subfd_dst, tmpname, subfd_dst, dname)) {
291 + warnp("could not rename %s to %s", tmpname, cpath);
292 + continue;
293 + }
294 + }
295 +
296 + /* Migrate a symlink */
297 + else if (S_ISLNK(st.st_mode)) {
298 + size_t len = st.st_size;
299 + char *sym = alloca(len + 1);
300 +
301 + /* Find out what we're pointing to */
302 + if (readlinkat(subfd_src, name, sym, len) == -1) {
303 + warnp("could not read link %s", cpath);
304 + continue;
305 + }
306 + sym[len] = '\0';
307 +
308 + /* syntax: sym src -> dst mtime */
309 + fprintf(contents, "sym %s -> %s %lu\n", cpath, sym, (unsigned long)st.st_mtime);
310 + qprintf("%s>>>%s %s%s -> %s%s\n", GREEN, NORM, CYAN, cpath, sym, NORM);
311 +
312 + /* Make it in the dest tree */
313 + if (symlinkat(sym, subfd_dst, name)) {
314 + /* If the symlink exists, unlink it and try again */
315 + if (errno != EEXIST ||
316 + unlinkat(subfd_dst, name, 0) ||
317 + symlinkat(sym, subfd_dst, name)) {
318 + warnp("could not create link %s to %s", cpath, sym);
319 + continue;
320 + }
321 + }
322 +
323 + struct timespec times[2];
324 + times[0] = st.st_mtim;
325 + times[1] = st.st_mtim;
326 + utimensat(subfd_dst, name, times, AT_SYMLINK_NOFOLLOW);
327 + }
328 +
329 + /* WTF is this !? */
330 + else {
331 + warnp("unknown file type %s", cpath);
332 + continue;
333 + }
334 + }
335 +
336 + done:
337 + close(subfd_src);
338 + close(subfd_dst);
339 +
340 + return ret;
341 +}
342 +
343 +/* Copy one tree (the single package) to another tree (ROOT) */
344 +static int merge_tree(const char *src, const char *dst, FILE *contents,
345 + int iargc, char **iargv)
346 +{
347 + int ret;
348 + int cp_argc, cpm_argc;
349 + char **cp_argv, **cpm_argv;
350 + char *cpath;
351 +
352 + /* XXX: be nice to pull this out of the current func
353 + * so we don't keep reparsing the same env var
354 + * when unmerging multiple packages.
355 + */
356 + makeargv(config_protect, &cp_argc, &cp_argv);
357 + makeargv(config_protect_mask, &cpm_argc, &cpm_argv);
358 +
359 + cpath = xstrdup("");
360 + ret = merge_tree_at(AT_FDCWD, src, AT_FDCWD, dst, contents, &cpath,
361 + iargc, iargv, cp_argc, cp_argv, cpm_argc, cpm_argv);
362 + free(cpath);
363 +
364 + freeargv(cp_argc, cp_argv);
365 + freeargv(cpm_argc, cpm_argv);
366 +
367 + return ret;
368 +}
369 +
370 /* oh shit getting into pkg mgt here. FIXME: write a real dep resolver. */
371 void pkg_merge(int level, depend_atom *atom, struct pkg_t *pkg)
372 {
373 @@ -428,18 +676,17 @@
374 char tarball[255];
375 char *p;
376 int i;
377 - char **ARGV = NULL;
378 - int ARGC = 0;
379 + char **ARGV;
380 + int ARGC;
381 const char *saved_argv0 = argv0;
382 int ret, saved_optind = optind;
383 - struct stat st, lst;
384 + struct stat st;
385 char c;
386 - char **iargv = NULL;
387 - int iargc = 0;
388 + char **iargv;
389 + int iargc;
390
391 - if (!install) return;
392 - if (!pkg) return;
393 - if (!atom) return;
394 + if (!install || !pkg || !atom)
395 + return;
396
397 if (!pkg->PF[0] || !pkg->CATEGORY) {
398 if (verbose) warn("CPF is really NULL at level %d", level);
399 @@ -538,7 +785,6 @@
400 }
401 }
402 freeargv(ARGC, ARGV);
403 - ARGC = 0; ARGV = NULL;
404 }
405 if (pretend)
406 return;
407 @@ -552,6 +798,9 @@
408 /* Doesn't actually remove $PWD, just everything under it */
409 rm_rf(".");
410
411 + /* XXX: maybe some day we should have this step operate on the
412 + * tarball directly rather than unpacking it first. */
413 +
414 /* split the tbz and xpak data */
415 snprintf(tarball, sizeof(tarball), "%s.tbz2", pkg->PF);
416 snprintf(buf, sizeof(buf), "%s/%s/%s", pkgdir, pkg->CATEGORY, tarball);
417 @@ -562,17 +811,17 @@
418 mkdir("image", 0755);
419
420 /* unpack the tarball using our internal qxpak */
421 - ARGV = xmalloc(sizeof(char *));
422 - ARGV[0] = (char *) "qtbz2";
423 - ARGV[1] = (char *) "-s";
424 + ARGC = 3;
425 + ARGV = xmalloc(sizeof(*ARGV) * ARGC);
426 + ARGV[0] = (char *)"qtbz2";
427 + ARGV[1] = (char *)"-s";
428 ARGV[2] = tarball;
429 argv0 = ARGV[0];
430 optind = 0;
431 - assert((ret = qtbz2_main(3, ARGV)) == 0);
432 + assert(qtbz2_main(ARGC, ARGV) == 0);
433 argv0 = saved_argv0;
434 optind = saved_optind;
435 free(ARGV);
436 - ARGV = NULL;
437
438 /* list and extract vdb files from the xpak */
439 snprintf(buf, sizeof(buf), "qxpak -d %s/%s/vdb -x %s.xpak `qxpak -l %s.xpak`",
440 @@ -590,7 +839,6 @@
441 /* Unmerge the other versions */
442 p = best_version(atom->CATEGORY, atom->PN);
443 if (*p) {
444 - ARGC = 0; ARGV = NULL;
445 makeargv(p, &ARGC, &ARGV);
446 for (i = 1; i < ARGC; i++) {
447 char pf[126];
448 @@ -621,7 +869,6 @@
449 qprintf("%s+++%s %s %s %s\n", GREEN, NORM, buf, booga[ret], ARGV[i]);
450 }
451 freeargv(ARGC, ARGV);
452 - ARGC = 0; ARGV = NULL;
453 }
454
455 xchdir("image");
456 @@ -629,9 +876,10 @@
457 eat_file("../vdb/DEFINED_PHASES", phases, sizeof(phases));
458 pkg_run_func("../vdb", phases, "pkg_preinst");
459
460 - if (stat("./", &st) == -1)
461 + if (stat(".", &st) == -1)
462 err("Cant stat pwd");
463
464 + /* Initialize INSTALL_MASK and common stuff */
465 makeargv(install_mask, &iargc, &iargv);
466 install_mask_pwd(iargc, iargv, st);
467
468 @@ -642,149 +890,14 @@
469 /* we dont care about the return code */
470 rmdir("./usr/share");
471
472 - if ((fp = popen(BUSYBOX" find .", "r")) == NULL)
473 - errf("come on wtf no find?");
474 -
475 if ((contents = fopen("../vdb/CONTENTS", "w")) == NULL)
476 errf("come on wtf?");
477
478 - makeargv(config_protect, &ARGC, &ARGV);
479 -
480 - while (fgets(buf, sizeof(buf), fp) != NULL) {
481 - char line[BUFSIZ];
482 - int protected = 0;
483 - char matched = 0;
484 - char dest[_Q_PATH_MAX];
485 -
486 - if ((p = strrchr(buf, '\n')) != NULL)
487 - *p = 0;
488 -
489 - if (buf[0] != '.')
490 - continue;
491 -
492 - if ((strcmp(buf, ".") == 0) || (strcmp(buf, "..") == 0))
493 - continue;
494 -
495 - for (i = 1; i < iargc; i++) {
496 - int fn;
497 - if ((fn = fnmatch(iargv[i], buf, 0)) == 0)
498 - matched = 1;
499 - }
500 - if (matched) {
501 - unlink(buf);
502 - continue;
503 - }
504 - /* use lstats for symlinks */
505 - lstat(buf, &st);
506 -
507 - line[0] = 0;
508 -
509 - snprintf(dest, sizeof(dest), "%s%s", portroot, &buf[1]);
510 -
511 - /* portage has code that handes fifo's but it looks unused */
512 -
513 - if (S_ISCHR(st.st_mode) ||
514 - S_ISBLK(st.st_mode)); /* block or character device */
515 - if (S_ISFIFO(st.st_mode)); /* FIFO (named pipe) */
516 - if (S_ISSOCK(st.st_mode)); /* socket? (Not in POSIX.1-1996.) */
517 -
518 - /* syntax: dir dirname */
519 - if (S_ISDIR(st.st_mode)) {
520 - mkdir(dest, st.st_mode);
521 - assert(chown(dest, st.st_uid, st.st_gid) == 0);
522 - snprintf(line, sizeof(line), "dir %s", &buf[1]);
523 - }
524 -
525 - /* syntax: obj filename hash mtime */
526 - if (S_ISREG(st.st_mode)) { /* regular file */
527 - struct timeval tv;
528 - unsigned char *hash;
529 -
530 - hash = hash_file(buf, HASH_MD5);
531 -
532 - snprintf(line, sizeof(line), "obj %s %s %lu", &buf[1], hash, st.st_mtime);
533 - /* /etc /usr/kde/2/share/config /usr/kde/3/share/config /var/qmail/control */
534 -
535 - protected = config_protected(&buf[1], ARGC, ARGV, 0, NULL);
536 - if (protected) {
537 - unsigned char *target_hash = hash_file(dest, HASH_MD5);
538 - if (memcmp(target_hash, hash, 16) != 0) {
539 - char newbuf[sizeof(buf)];
540 - qprintf("%s***%s %s\n", BRYELLOW, NORM, &buf[1]);
541 - if (verbose) {
542 - snprintf(newbuf, sizeof(newbuf), "diff -u %s %s", buf, dest);
543 - xsystem(newbuf);
544 - }
545 - continue;
546 - }
547 - }
548 - if (lstat(dest, &lst) != -1) {
549 - if (S_ISLNK(lst.st_mode)) {
550 - warn("%s exists and is a symlink and we are going to overwrite it with a file", dest);
551 - unlink_q(dest);
552 - }
553 - }
554 - if (interactive_rename(buf, dest, pkg) != 0)
555 - continue;
556 -
557 - assert(chmod(dest, st.st_mode) == 0);
558 - assert(chown(dest, st.st_uid, st.st_gid) == 0);
559 -
560 - tv.tv_sec = st.st_mtime;
561 - tv.tv_usec = 0;
562 - /* utime(&buf[1], &tv); */
563 - }
564 -
565 - /* symlinks are unfinished */
566 - /* syntax: sym src -> dst */
567 - if (S_ISLNK(st.st_mode)) { /* (Not in POSIX.1-1996.) */
568 - /*
569 - save pwd
570 - get the dirname of the symlink from buf1
571 - chdir to it's dirname unless it's a dir itself
572 - symlink src dest
573 - report any errors along the way
574 - */
575 - char path[sizeof(buf)];
576 - char pwd[sizeof(buf)];
577 - char tmp[sizeof(buf)];
578 -
579 - memset(&path, 0, sizeof(path));
580 -
581 - assert(strlen(dest));
582 - xreadlink(buf, path, sizeof(path) - 1);
583 - assert(strlen(path));;
584 -
585 - snprintf(line, sizeof(line), "sym %s -> %s%s%lu", &buf[1], path, " ", st.st_mtime);
586 - /* snprintf(line, sizeof(line), "sym %s -> %s", &buf[1], path); */
587 - /* we better have one byte here to play with */
588 - strcpy(tmp, &buf[1]);
589 - if (tmp[0] != '/') errf("sym does not start with /");
590 -
591 - xgetcwd(pwd, sizeof(pwd));
592 - xchdir(dirname(tmp)); /* tmp gets eatten up now by the dirname call */
593 - if (lstat(path, &lst) != -1)
594 - unlink_q(dest);
595 - /* if (path[0] != '/')
596 - puts("path does not start with /");
597 - */
598 - if (symlink(path, dest))
599 - if (errno != EEXIST)
600 - warnp("symlink failed %s -> %s", path, &buf[1]);
601 - xchdir(pwd);
602 - }
603 - /* Save the line to the contents file */
604 - if (*line) fprintf(contents, "%s\n", line);
605 - }
606 -
607 - freeargv(ARGC, ARGV); /* config_protect */
608 - freeargv(iargc, iargv); /* install_mask */
609 -
610 - iargv = 0;
611 - iargv = NULL;
612 + merge_tree(".", portroot, contents, iargc, iargv);
613
614 fclose(contents);
615 - pclose(fp);
616 +
617 + freeargv(iargc, iargv);
618
619 xchdir(port_tmpdir);
620 xchdir(pkg->PF);
621 @@ -792,17 +905,17 @@
622 /* run postinst */
623 pkg_run_func("./vdb", phases, "pkg_postinst");
624
625 + /* FIXME */ /* move unmerging to around here ? */
626 + /* not perfect when a version is already installed */
627 snprintf(buf, sizeof(buf), "%s/var/db/pkg/%s/", portroot, pkg->CATEGORY);
628 if (access(buf, R_OK|W_OK|X_OK) != 0)
629 mkdir_p(buf, 0755);
630 strncat(buf, pkg->PF, sizeof(buf)-strlen(buf)-1);
631 -
632 - /* FIXME */ /* move unmerging to around here ? */
633 - /* not perfect when a version is already installed */
634 if (access(buf, X_OK) == 0) {
635 /* we need to compare CONTENTS in it and remove any file not provided by our CONTENTS */
636 rm_rf(buf);
637 }
638 +
639 if ((fp = fopen("vdb/COUNTER", "w")) != NULL) {
640 fputs("0", fp);
641 fclose(fp);