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); |