1 /*
2  * FreeBSD install - a package for the installation and maintainance
3  * of non-core utilities.
4  *
5  * Jordan K. Hubbard
6  * 18 July 1993
7  *
8  * This is the create module.
9  *
10  */
11 
12 #include <sys/cdefs.h>
13 __FBSDID("$FreeBSD: stable/9/usr.sbin/pkg_install/create/main.c 222035 2011-05-17 19:11:47Z flz $");
14 
15 #include <getopt.h>
16 #include <err.h>
17 
18 #include "lib.h"
19 #include "create.h"
20 
21 match_t	MatchType	= MATCH_GLOB;
22 char	*Prefix		= NULL;
23 char	*Comment        = NULL;
24 char	*Desc		= NULL;
25 char	*SrcDir		= NULL;
26 char	*BaseDir	= NULL;
27 char	*Display	= NULL;
28 char	*Install	= NULL;
29 char	*PostInstall	= NULL;
30 char	*DeInstall	= NULL;
31 char	*PostDeInstall	= NULL;
32 char	*Contents	= NULL;
33 char	*Require	= NULL;
34 char	*ExcludeFrom	= NULL;
35 char	*Mtree		= NULL;
36 char	*Pkgdeps	= NULL;
37 char	*Conflicts	= NULL;
38 char	*Origin		= NULL;
39 char	*InstalledPkg	= NULL;
40 char	PlayPen[FILENAME_MAX];
41 int	Dereference	= FALSE;
42 int	PlistOnly	= FALSE;
43 int	Recursive	= FALSE;
44 int	Regenerate	= TRUE;
45 int	Help		= FALSE;
46 enum zipper	Zipper  = BZIP2;
47 
48 
49 static void usage(void);
50 
51 static char opts[] = "EGYNnORhjJvxyzf:p:P:C:c:d:i:I:k:K:r:t:X:D:m:s:S:o:b:";
52 static struct option longopts[] = {
53 	{ "backup",	required_argument,	NULL,		'b' },
54 	{ "extended",	no_argument,		NULL,		'E' },
55 	{ "help",	no_argument,		&Help,		TRUE },
56 	{ "no",		no_argument,		NULL,		'N' },
57 	{ "no-glob",	no_argument,		NULL,		'G' },
58 	{ "origin",	required_argument,	NULL,		'o' },
59 	{ "plist-only",	no_argument,		NULL,		'O' },
60 	{ "prefix",	required_argument,	NULL,		'p' },
61 	{ "recursive",	no_argument,		NULL,		'R' },
62 	{ "regex",	no_argument,		NULL,		'x' },
63 	{ "template",	required_argument,	NULL,		't' },
64 	{ "verbose",	no_argument,		NULL,		'v' },
65 	{ "yes",	no_argument,		NULL,		'Y' },
66 	{ NULL,		0,			NULL,		0 },
67 };
68 
69 int
main(int argc,char ** argv)70 main(int argc, char **argv)
71 {
72     int ch;
73     char **pkgs, **start, *tmp;
74 
75     pkgs = start = argv;
76     while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1)
77 	switch(ch) {
78 	case 'v':
79 	    Verbose++;
80 	    break;
81 
82 	case 'x':
83 	    MatchType = MATCH_REGEX;
84 	    break;
85 
86 	case 'E':
87 	    MatchType = MATCH_EREGEX;
88 	    break;
89 
90 	case 'G':
91 	    MatchType = MATCH_EXACT;
92 	    break;
93 
94 	case 'N':
95 	    AutoAnswer = NO;
96 	    break;
97 
98 	case 'Y':
99 	    AutoAnswer = YES;
100 	    break;
101 
102 	case 'O':
103 	    PlistOnly = TRUE;
104 	    break;
105 
106 	case 'p':
107 	    Prefix = optarg;
108 	    break;
109 
110 	case 's':
111 	    SrcDir = optarg;
112 	    break;
113 
114 	case 'S':
115 	    BaseDir = optarg;
116 	    break;
117 
118 	case 'f':
119 	    Contents = optarg;
120 	    break;
121 
122 	case 'C':
123 	    Conflicts = optarg;
124 	    break;
125 
126 	case 'c':
127 	    Comment = optarg;
128 	    break;
129 
130 	case 'd':
131 	    Desc = optarg;
132 	    break;
133 
134 	case 'i':
135 	    Install = optarg;
136 	    break;
137 
138 	case 'I':
139 	    PostInstall = optarg;
140 	    break;
141 
142 	case 'k':
143 	    DeInstall = optarg;
144 	    break;
145 
146 	case 'K':
147 	    PostDeInstall = optarg;
148 	    break;
149 
150 	case 'r':
151 	    Require = optarg;
152 	    break;
153 
154 	case 't':
155 	    strlcpy(PlayPen, optarg, sizeof(PlayPen));
156 	    break;
157 
158 	case 'X':
159 	    ExcludeFrom = optarg;
160 	    break;
161 
162 	case 'h':
163 	    Dereference = TRUE;
164 	    break;
165 
166 	case 'D':
167 	    Display = optarg;
168 	    break;
169 
170 	case 'm':
171 	    Mtree = optarg;
172 	    break;
173 
174 	case 'P':
175 	    Pkgdeps = optarg;
176 	    break;
177 
178 	case 'o':
179 	    Origin = optarg;
180 	    break;
181 
182 	case 'y':
183 	case 'j':
184 	    Zipper = BZIP2;
185 	    break;
186 
187 	case 'z':
188 	    Zipper = GZIP;
189 	    break;
190 
191 	case 'J':
192 	    Zipper = XZ;
193 	    break;
194 
195 	case 'b':
196 	    InstalledPkg = optarg;
197 	    while ((tmp = strrchr(optarg, (int)'/')) != NULL) {
198 		*tmp++ = '\0';
199 		/*
200 		 * If character after the '/' is alphanumeric, then we've
201 		 * found the package name.  Otherwise we've come across
202 		 * a trailing '/' and need to continue our quest.
203 		 */
204 		if (isalpha(*tmp)) {
205 		    InstalledPkg = tmp;
206 		    break;
207 		}
208 	    }
209 	    break;
210 
211 	case 'R':
212 	    Recursive = TRUE;
213 	    break;
214 
215 	case 'n':
216 	    Regenerate = FALSE;
217 	    break;
218 
219 	case 0:
220 	    if (Help)
221 		usage();
222 	    break;
223 
224 	default:
225 	    usage();
226 	    break;
227 	}
228 
229     argc -= optind;
230     argv += optind;
231 
232     /* Get all the remaining package names, if any */
233     while (*argv)
234 	*pkgs++ = *argv++;
235 
236     /* If no packages, yelp */
237     if ((pkgs == start) && (InstalledPkg == NULL))
238 	warnx("missing package name"), usage();
239     *pkgs = NULL;
240     if ((start[0] != NULL) && (start[1] != NULL)) {
241 	warnx("only one package name allowed ('%s' extraneous)", start[1]);
242 	usage();
243     }
244     if (start[0] == NULL)
245 	start[0] = InstalledPkg;
246     if (!pkg_perform(start)) {
247 	if (Verbose)
248 	    warnx("package creation failed");
249 	return 1;
250     }
251     else
252 	return 0;
253 }
254 
255 static void
usage(void)256 usage(void)
257 {
258     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
259 "usage: pkg_create [-YNOhjnvyz] [-C conflicts] [-P pkgs] [-p prefix]",
260 "                  [-i iscript] [-I piscript] [-k dscript] [-K pdscript]",
261 "                  [-r rscript] [-s srcdir] [-S basedir]",
262 "                  [-t template] [-X excludefile]",
263 "                  [-D displayfile] [-m mtreefile] [-o originpath]",
264 "                  -c comment -d description -f packlist pkg-filename",
265 "       pkg_create [-EGYNRhnvxy] -b pkg-name [pkg-filename]");
266     exit(1);
267 }
268