Annotation of pkgsrc/pkgtools/pkg_install/files/create/perform.c, Revision 1.2
1.2 ! jschauma 1: /* $NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $ */
1.1 schmonz 2:
3: #if 0
4: #include <sys/cdefs.h>
5: #ifndef lint
6: #if 0
7: static const char *rcsid = "from FreeBSD Id: perform.c,v 1.38 1997/10/13 15:03:51 jkh Exp";
8: #else
1.2 ! jschauma 9: __RCSID("$NetBSD: perform.c,v 1.1.1.1 2002/12/20 18:14:10 schmonz Exp $");
1.1 schmonz 10: #endif
11: #endif
12: #endif
13:
14: /*
15: * FreeBSD install - a package for the installation and maintainance
16: * of non-core utilities.
17: *
18: * Redistribution and use in source and binary forms, with or without
19: * modification, are permitted provided that the following conditions
20: * are met:
21: * 1. Redistributions of source code must retain the above copyright
22: * notice, this list of conditions and the following disclaimer.
23: * 2. Redistributions in binary form must reproduce the above copyright
24: * notice, this list of conditions and the following disclaimer in the
25: * documentation and/or other materials provided with the distribution.
26: *
27: * Jordan K. Hubbard
28: * 18 July 1993
29: *
30: * This is the main body of the create module.
31: *
32: */
33:
34: #include "lib.h"
35: #include "create.h"
36:
37: #ifdef HAVE_ERR_H
38: #include <err.h>
39: #endif
40:
41: #include <signal.h>
42:
43: #ifdef HAVE_SYS_WAIT_H
44: #include <sys/wait.h>
45: #endif
46:
47: #include <unistd.h>
48:
49: static char *Home;
50:
51: static void
52: make_dist(const char *home, const char *pkg, const char *suffix, const package_t *plist)
53: {
54: char tball[FILENAME_MAX];
55: const plist_t *p;
56: int ret;
57: char *args[50]; /* Much more than enough. */
58: int nargs = 1;
59: int pipefds[2];
60: FILE *totar;
61: pid_t pid;
62:
63: if ((args[0] = strrchr(TAR_FULLPATHNAME, '/')) == NULL)
64: args[0] = TAR_FULLPATHNAME;
65: else
66: args[0]++;
67:
68: if (*pkg == '/')
69: (void) snprintf(tball, sizeof(tball), "%s.%s", pkg, suffix);
70: else
71: (void) snprintf(tball, sizeof(tball), "%s/%s.%s", home, pkg, suffix);
72:
73: args[nargs++] = "-c";
74: args[nargs++] = "-f";
75: args[nargs++] = tball;
76: if (strstr(suffix, "bz")) {
77: args[nargs++] = "--use-compress-program";
78: args[nargs++] = "bzip2";
79: } else if (strchr(suffix, 'z'))/* Compress/gzip? */
80: args[nargs++] = "-z";
81: if (Dereference)
82: args[nargs++] = "-h";
83: if (ExcludeFrom) {
84: args[nargs++] = "-X";
85: args[nargs++] = ExcludeFrom;
86: }
87: args[nargs++] = "-T"; /* Take filenames from file instead of args. */
88: args[nargs++] = "-"; /* Use stdin for the file. */
89: args[nargs] = NULL;
90:
91: if (Verbose)
92: printf("Creating gzip'd binary package in '%s'\n", tball);
93:
94: /* Set up a pipe for passing the filenames, and fork off a tar process. */
95: if (pipe(pipefds) == -1) {
96: cleanup(0);
97: errx(2, "cannot create pipe");
98: }
99: if ((pid = fork()) == -1) {
100: cleanup(0);
101: errx(2, "cannot fork process for %s", TAR_FULLPATHNAME);
102: }
103: if (pid == 0) { /* The child */
104: dup2(pipefds[0], 0);
105: close(pipefds[0]);
106: close(pipefds[1]);
107: execvp(TAR_FULLPATHNAME, args);
108: cleanup(0);
109: errx(2, "failed to execute %s command", TAR_FULLPATHNAME);
110: }
111:
112: /* Meanwhile, back in the parent process ... */
113: close(pipefds[0]);
114: if ((totar = fdopen(pipefds[1], "w")) == NULL) {
115: cleanup(0);
116: errx(2, "fdopen failed");
117: }
118:
119: fprintf(totar, "%s\n", CONTENTS_FNAME);
120: fprintf(totar, "%s\n", COMMENT_FNAME);
121: fprintf(totar, "%s\n", DESC_FNAME);
122:
123: if (Install) {
124: fprintf(totar, "%s\n", INSTALL_FNAME);
125: }
126: if (DeInstall) {
127: fprintf(totar, "%s\n", DEINSTALL_FNAME);
128: }
129: if (Require) {
130: fprintf(totar, "%s\n", REQUIRE_FNAME);
131: }
132: if (Display) {
133: fprintf(totar, "%s\n", DISPLAY_FNAME);
134: }
135: if (Mtree) {
136: fprintf(totar, "%s\n", MTREE_FNAME);
137: }
138: if (BuildVersion) {
139: (void) fprintf(totar, "%s\n", BUILD_VERSION_FNAME);
140: }
141: if (BuildInfo) {
142: (void) fprintf(totar, "%s\n", BUILD_INFO_FNAME);
143: }
144: if (SizePkg) {
145: (void) fprintf(totar, "%s\n", SIZE_PKG_FNAME);
146: }
147: if (SizeAll) {
148: (void) fprintf(totar, "%s\n", SIZE_ALL_FNAME);
149: }
1.2 ! jschauma 150: if (Preserve) {
! 151: (void) fprintf(totar, "%s\n", PRESERVE_FNAME);
! 152: }
1.1 schmonz 153:
154: for (p = plist->head; p; p = p->next) {
155: if (p->type == PLIST_FILE) {
156: fprintf(totar, "%s\n", p->name);
157: } else if (p->type == PLIST_CWD || p->type == PLIST_SRC) {
158:
159: /* XXX let PLIST_SRC override PLIST_CWD */
160: if (p->type == PLIST_CWD && p->next != NULL &&
161: p->next->type == PLIST_SRC) {
162: continue;
163: }
164:
165: fprintf(totar, "-C\n%s\n", p->name);
166: } else if (p->type == PLIST_IGNORE) {
167: p = p->next;
168: }
169: }
170:
171: fclose(totar);
172: wait(&ret);
173: /* assume either signal or bad exit is enough for us */
174: if (ret) {
175: cleanup(0);
176: errx(2, "%s command failed with code %d", TAR_FULLPATHNAME, ret);
177: }
178: }
179:
180: static void
181: sanity_check(void)
182: {
183: if (!Comment) {
184: cleanup(0);
185: errx(2, "required package comment string is missing (-c comment)");
186: }
187: if (!Desc) {
188: cleanup(0);
189: errx(2, "required package description string is missing (-d desc)");
190: }
191: if (!Contents) {
192: cleanup(0);
193: errx(2, "required package contents list is missing (-f [-]file)");
194: }
195: }
196:
197:
198: /*
199: * Clean up those things that would otherwise hang around
200: */
201: void
202: cleanup(int sig)
203: {
204: static int alreadyCleaning;
205: void (*oldint) (int);
206: void (*oldhup) (int);
207: oldint = signal(SIGINT, SIG_IGN);
208: oldhup = signal(SIGHUP, SIG_IGN);
209:
210: if (!alreadyCleaning) {
211: alreadyCleaning = 1;
212: if (sig)
213: printf("Signal %d received, cleaning up.\n", sig);
214: leave_playpen(Home);
215: if (sig)
216: exit(1);
217: }
218: signal(SIGINT, oldint);
219: signal(SIGHUP, oldhup);
220: }
221:
222: int
223: pkg_perform(lpkg_head_t *pkgs)
224: {
225: const char *pkg;
226: char *cp;
227: FILE *pkg_in, *fp;
228: package_t plist;
229: char *suffix; /* What we tack on to the end of the finished package */
230: lpkg_t *lpp;
231: char installed[FILENAME_MAX];
232:
233: lpp = TAILQ_FIRST(pkgs);
234: pkg = lpp->lp_name; /* Only one arg to create */
235:
236: /* Preliminary setup */
237: sanity_check();
238: if (Verbose && !PlistOnly)
239: printf("Creating package %s\n", pkg);
240: get_dash_string(&Comment);
241: get_dash_string(&Desc);
242: if (IS_STDIN(Contents))
243: pkg_in = stdin;
244: else {
245: pkg_in = fopen(Contents, "r");
246: if (!pkg_in) {
247: cleanup(0);
248: errx(2, "unable to open contents file '%s' for input", Contents);
249: }
250: }
251: plist.head = plist.tail = NULL;
252:
253: /* Break the package name into base and desired suffix (if any) */
254: if ((cp = strrchr(pkg, '.')) != NULL) {
255: suffix = cp + 1;
256: *cp = '\0';
257: } else
258: suffix = "tgz";
259:
260: /* If a SrcDir override is set, add it now */
261: if (SrcDir) {
262: if (Verbose && !PlistOnly)
263: printf("Using SrcDir value of %s\n", (realprefix) ? realprefix : SrcDir);
264: add_plist(&plist, PLIST_SRC, SrcDir);
265: }
266:
267: /* Stick the dependencies, if any, at the top */
268: if (Pkgdeps) {
269: if (Verbose && !PlistOnly)
270: printf("Registering depends:");
271: while (Pkgdeps) {
272: cp = strsep(&Pkgdeps, " \t\n");
273: if (*cp) {
274: if (findmatchingname(_pkgdb_getPKGDB_DIR(), cp, note_whats_installed, installed) > 0) {
275: add_plist(&plist, PLIST_BLDDEP, installed);
276: }
277: add_plist(&plist, PLIST_PKGDEP, cp);
278: if (Verbose && !PlistOnly)
279: printf(" %s", cp);
280: }
281: }
282: if (Verbose && !PlistOnly)
283: printf(".\n");
284: }
285:
286: /* Put the conflicts directly after the dependencies, if any */
287: if (Pkgcfl) {
288: if (Verbose && !PlistOnly)
289: printf("Registering conflicts:");
290: while (Pkgcfl) {
291: cp = strsep(&Pkgcfl, " \t\n");
292: if (*cp) {
293: add_plist(&plist, PLIST_PKGCFL, cp);
294: if (Verbose && !PlistOnly)
295: printf(" %s", cp);
296: }
297: }
298: if (Verbose && !PlistOnly)
299: printf(".\n");
300: }
301:
302: /* Slurp in the packing list */
303: read_plist(&plist, pkg_in);
304:
305: if (pkg_in != stdin)
306: fclose(pkg_in);
307:
308: /* Prefix should override the packing list */
309: if (Prefix) {
310: delete_plist(&plist, FALSE, PLIST_CWD, NULL);
311: add_plist_top(&plist, PLIST_CWD, Prefix);
312: }
313: /*
314: * Run down the list and see if we've named it, if not stick in a name
315: * at the top.
316: */
317: if (find_plist(&plist, PLIST_NAME) == NULL) {
318: add_plist_top(&plist, PLIST_NAME, basename_of(pkg));
319: }
320:
321: /*
322: * We're just here for to dump out a revised plist for the FreeBSD ports
323: * hack. It's not a real create in progress.
324: */
325: if (PlistOnly) {
326: check_list(Home, &plist, basename_of(pkg));
327: write_plist(&plist, stdout, realprefix);
328: exit(0);
329: }
330:
331: /* Make a directory to stomp around in */
332: Home = make_playpen(PlayPen, PlayPenSize, 0);
333: signal(SIGINT, cleanup);
334: signal(SIGHUP, cleanup);
335:
336: /* Make first "real contents" pass over it */
337: check_list(Home, &plist, basename_of(pkg));
338: (void) umask(022); /* make sure gen'ed directories, files
339: * don't have group or other write bits. */
340:
341: /* Now put the release specific items in */
342: add_plist(&plist, PLIST_CWD, ".");
343: write_file(COMMENT_FNAME, Comment);
344: add_plist(&plist, PLIST_IGNORE, NULL);
345: add_plist(&plist, PLIST_FILE, COMMENT_FNAME);
346: write_file(DESC_FNAME, Desc);
347: add_plist(&plist, PLIST_IGNORE, NULL);
348: add_plist(&plist, PLIST_FILE, DESC_FNAME);
349:
350: if (Install) {
351: copy_file(Home, Install, INSTALL_FNAME);
352: add_plist(&plist, PLIST_IGNORE, NULL);
353: add_plist(&plist, PLIST_FILE, INSTALL_FNAME);
354: }
355: if (DeInstall) {
356: copy_file(Home, DeInstall, DEINSTALL_FNAME);
357: add_plist(&plist, PLIST_IGNORE, NULL);
358: add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME);
359: }
360: if (Require) {
361: copy_file(Home, Require, REQUIRE_FNAME);
362: add_plist(&plist, PLIST_IGNORE, NULL);
363: add_plist(&plist, PLIST_FILE, REQUIRE_FNAME);
364: }
365: if (Display) {
366: copy_file(Home, Display, DISPLAY_FNAME);
367: add_plist(&plist, PLIST_IGNORE, NULL);
368: add_plist(&plist, PLIST_FILE, DISPLAY_FNAME);
369: add_plist(&plist, PLIST_DISPLAY, DISPLAY_FNAME);
370: }
371: if (Mtree) {
372: copy_file(Home, Mtree, MTREE_FNAME);
373: add_plist(&plist, PLIST_IGNORE, NULL);
374: add_plist(&plist, PLIST_FILE, MTREE_FNAME);
375: add_plist(&plist, PLIST_MTREE, MTREE_FNAME);
376: }
377: if (BuildVersion) {
378: copy_file(Home, BuildVersion, BUILD_VERSION_FNAME);
379: add_plist(&plist, PLIST_IGNORE, NULL);
380: add_plist(&plist, PLIST_FILE, BUILD_VERSION_FNAME);
381: }
382: if (BuildInfo) {
383: copy_file(Home, BuildInfo, BUILD_INFO_FNAME);
384: add_plist(&plist, PLIST_IGNORE, NULL);
385: add_plist(&plist, PLIST_FILE, BUILD_INFO_FNAME);
386: }
387: if (SizePkg) {
388: copy_file(Home, SizePkg, SIZE_PKG_FNAME);
389: add_plist(&plist, PLIST_IGNORE, NULL);
390: add_plist(&plist, PLIST_FILE, SIZE_PKG_FNAME);
391: }
392: if (SizeAll) {
393: copy_file(Home, SizeAll, SIZE_ALL_FNAME);
394: add_plist(&plist, PLIST_IGNORE, NULL);
395: add_plist(&plist, PLIST_FILE, SIZE_ALL_FNAME);
1.2 ! jschauma 396: }
! 397: if (Preserve) {
! 398: copy_file(Home, Preserve, PRESERVE_FNAME);
! 399: add_plist(&plist, PLIST_IGNORE, NULL);
! 400: add_plist(&plist, PLIST_FILE, PRESERVE_FNAME);
1.1 schmonz 401: }
402:
403: /* Finally, write out the packing list */
404: fp = fopen(CONTENTS_FNAME, "w");
405: if (!fp) {
406: cleanup(0);
407: errx(2, "can't open file %s for writing", CONTENTS_FNAME);
408: }
409: write_plist(&plist, fp, realprefix);
410: if (fclose(fp)) {
411: cleanup(0);
412: errx(2, "error while closing %s", CONTENTS_FNAME);
413: }
414:
415: /* And stick it into a tar ball */
416: make_dist(Home, pkg, suffix, &plist);
417:
418: /* Cleanup */
419: free(Comment);
420: free(Desc);
421: free_plist(&plist);
422: leave_playpen(Home);
423:
424: return TRUE; /* Success */
425: }
CVSweb <webmaster@jp.NetBSD.org>