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