perform.c revision 1.1.1.2 1 /* $NetBSD: perform.c,v 1.1.1.2 2009/02/02 20:44:03 joerg Exp $ */
2
3 #if HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 #include <nbcompat.h>
7 #if HAVE_SYS_CDEFS_H
8 #include <sys/cdefs.h>
9 #endif
10 __RCSID("$NetBSD: perform.c,v 1.1.1.2 2009/02/02 20:44:03 joerg Exp $");
11
12 /*
13 * FreeBSD install - a package for the installation and maintainance
14 * of non-core utilities.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * Jordan K. Hubbard
26 * 18 July 1993
27 *
28 * This is the main body of the create module.
29 *
30 */
31
32 #include "lib.h"
33 #include "create.h"
34
35 #if HAVE_ERR_H
36 #include <err.h>
37 #endif
38 #if HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 static void
43 sanity_check(void)
44 {
45 if (!Comment)
46 errx(2, "required package comment string is missing (-c comment)");
47 if (!Desc)
48 errx(2, "required package description string is missing (-d desc)");
49 if (!Contents)
50 errx(2, "required package contents list is missing (-f [-]file)");
51 }
52
53 static void
54 register_depends(package_t *plist, char *deps, int build_only)
55 {
56 char *cp;
57
58 if (Verbose && !PlistOnly) {
59 if (build_only)
60 printf("Registering build depends:");
61 else
62 printf("Registering depends:");
63 }
64 while (deps) {
65 cp = strsep(&deps, " \t\n");
66 if (*cp) {
67 char *best_installed;
68 best_installed = find_best_matching_installed_pkg(cp);
69 if (best_installed != NULL) {
70 add_plist(plist, PLIST_BLDDEP, best_installed);
71 if (Verbose && !PlistOnly && build_only)
72 printf(" %s", cp);
73 } else
74 warnx("No matching package installed for %s", cp);
75 free(best_installed);
76 if (!build_only) {
77 add_plist(plist, PLIST_PKGDEP, cp);
78 if (Verbose && !PlistOnly)
79 printf(" %s", cp);
80 }
81 }
82 }
83 if (Verbose && !PlistOnly)
84 printf(".\n");
85 }
86
87 /*
88 * Expect "fname" to point at a file, and read it into
89 * the buffer returned.
90 */
91 static char *
92 fileGetContents(char *fname)
93 {
94 char *contents;
95 struct stat sb;
96 int fd;
97
98 if (stat(fname, &sb) == FAIL) {
99 cleanup(0);
100 errx(2, "can't stat '%s'", fname);
101 }
102
103 contents = xmalloc((size_t) (sb.st_size) + 1);
104 fd = open(fname, O_RDONLY, 0);
105 if (fd == FAIL) {
106 cleanup(0);
107 errx(2, "unable to open '%s' for reading", fname);
108 }
109 if (read(fd, contents, (size_t) sb.st_size) != (size_t) sb.st_size) {
110 cleanup(0);
111 errx(2, "short read on '%s' - did not get %lld bytes",
112 fname, (long long) sb.st_size);
113 }
114 close(fd);
115 contents[(size_t) sb.st_size] = '\0';
116 return contents;
117 }
118
119 /*
120 * Get a string parameter as a file spec or as a "contents follow -" spec
121 */
122 static void
123 get_dash_string(char **s)
124 {
125 if (**s == '-')
126 *s = xstrdup(*s + 1);
127 else
128 *s = fileGetContents(*s);
129 }
130
131 int
132 pkg_perform(const char *pkg)
133 {
134 char *cp;
135 FILE *pkg_in;
136 package_t plist;
137 const char *full_pkg, *suffix;
138 char *allocated_pkg;
139 int retval;
140
141 /* Break the package name into base and desired suffix (if any) */
142 if ((cp = strrchr(pkg, '.')) != NULL) {
143 allocated_pkg = xmalloc(cp - pkg + 1);
144 memcpy(allocated_pkg, pkg, cp - pkg);
145 allocated_pkg[cp - pkg] = '\0';
146 suffix = cp + 1;
147 full_pkg = pkg;
148 pkg = allocated_pkg;
149 } else {
150 allocated_pkg = NULL;
151 full_pkg = pkg;
152 suffix = "tgz";
153 }
154
155 /* Preliminary setup */
156 sanity_check();
157 if (Verbose && !PlistOnly)
158 printf("Creating package %s\n", pkg);
159 get_dash_string(&Comment);
160 get_dash_string(&Desc);
161 if (IS_STDIN(Contents))
162 pkg_in = stdin;
163 else {
164 pkg_in = fopen(Contents, "r");
165 if (!pkg_in)
166 errx(2, "unable to open contents file '%s' for input", Contents);
167 }
168
169 plist.head = plist.tail = NULL;
170
171 /* If a SrcDir override is set, add it now */
172 if (SrcDir) {
173 if (Verbose && !PlistOnly)
174 printf("Using SrcDir value of %s\n", (realprefix) ? realprefix : SrcDir);
175 add_plist(&plist, PLIST_SRC, SrcDir);
176 }
177
178 /* Stick the dependencies, if any, at the top */
179 if (Pkgdeps)
180 register_depends(&plist, Pkgdeps, 0);
181
182 /*
183 * Put the build dependencies after the dependencies.
184 * This works due to the evaluation order in pkg_add.
185 */
186 if (BuildPkgdeps)
187 register_depends(&plist, BuildPkgdeps, 1);
188
189 /* Put the conflicts directly after the dependencies, if any */
190 if (Pkgcfl) {
191 if (Verbose && !PlistOnly)
192 printf("Registering conflicts:");
193 while (Pkgcfl) {
194 cp = strsep(&Pkgcfl, " \t\n");
195 if (*cp) {
196 add_plist(&plist, PLIST_PKGCFL, cp);
197 if (Verbose && !PlistOnly)
198 printf(" %s", cp);
199 }
200 }
201 if (Verbose && !PlistOnly)
202 printf(".\n");
203 }
204
205 /* Slurp in the packing list */
206 append_plist(&plist, pkg_in);
207
208 if (pkg_in != stdin)
209 fclose(pkg_in);
210
211 /* Prefix should override the packing list */
212 if (Prefix) {
213 delete_plist(&plist, FALSE, PLIST_CWD, NULL);
214 add_plist_top(&plist, PLIST_CWD, Prefix);
215 }
216 /*
217 * Run down the list and see if we've named it, if not stick in a name
218 * at the top.
219 */
220 if (find_plist(&plist, PLIST_NAME) == NULL) {
221 add_plist_top(&plist, PLIST_NAME, basename_of(pkg));
222 }
223
224 /* Make first "real contents" pass over it */
225 check_list(&plist, basename_of(pkg));
226
227 /*
228 * We're just here for to dump out a revised plist for the FreeBSD ports
229 * hack. It's not a real create in progress.
230 */
231 if (PlistOnly) {
232 write_plist(&plist, stdout, realprefix);
233 retval = TRUE;
234 } else {
235 #ifdef BOOTSTRAP
236 warnx("Package building is not supported in bootstrap mode");
237 retval = FALSE;
238 #else
239 retval = pkg_build(pkg, full_pkg, suffix, &plist);
240 #endif
241 }
242
243 /* Cleanup */
244 free(Comment);
245 free(Desc);
246 free_plist(&plist);
247
248 free(allocated_pkg);
249
250 return retval;
251 }
252