xref: /netbsd-src/external/bsd/pkg_install/dist/info/main.c (revision 2d48ac808c43ea6701ba8f33cfc3645685301f79)
1 /*	$NetBSD: main.c,v 1.1.1.6 2009/08/06 16:55:25 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: main.c,v 1.1.1.6 2009/08/06 16:55:25 joerg Exp $");
11 
12 /*
13  *
14  * FreeBSD install - a package for the installation and maintainance
15  * of non-core utilities.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  *
26  * Jordan K. Hubbard
27  * 18 July 1993
28  *
29  * This is the add module.
30  *
31  */
32 
33 #if HAVE_SYS_IOCTL_H
34 #include <sys/ioctl.h>
35 #endif
36 
37 #if HAVE_TERMIOS_H
38 #include <termios.h>
39 #endif
40 #if HAVE_ERR_H
41 #include <err.h>
42 #endif
43 
44 #include "lib.h"
45 #include "info.h"
46 
47 static const char Options[] = ".aBbcDde:E:fFhIiK:kLl:mNnpQ:qrRsSuvVX";
48 
49 int     Flags = 0;
50 enum which Which = WHICH_LIST;
51 Boolean File2Pkg = FALSE;
52 Boolean Quiet = FALSE;
53 const char   *InfoPrefix = "";
54 const char   *BuildInfoVariable = "";
55 size_t  termwidth = 0;
56 lpkg_head_t pkgs;
57 
58 static void
59 usage(void)
60 {
61 	fprintf(stderr, "%s\n%s\n%s\n%s\n",
62 	    "usage: pkg_info [-BbcDdFfhIikLmNnpqrRSsVvX] [-e package] [-E package]",
63 	    "                [-K pkg_dbdir] [-l prefix] pkg-name ...",
64 	    "       pkg_info [-a | -u] [flags]",
65 	    "       pkg_info [-Q variable] pkg-name ...");
66 	exit(1);
67 }
68 
69 int
70 main(int argc, char **argv)
71 {
72 	char *CheckPkg = NULL;
73 	char *BestCheckPkg = NULL;
74 	lpkg_t *lpp;
75 	int     ch;
76 	int	rc;
77 
78 	setprogname(argv[0]);
79 	while ((ch = getopt(argc, argv, Options)) != -1)
80 		switch (ch) {
81 		case '.':	/* for backward compatibility */
82 			break;
83 
84 		case 'a':
85 			Which = WHICH_ALL;
86 			break;
87 
88 		case 'B':
89 			Flags |= SHOW_BUILD_INFO;
90 			break;
91 
92 		case 'b':
93 			Flags |= SHOW_BUILD_VERSION;
94 			break;
95 
96 		case 'c':
97 			Flags |= SHOW_COMMENT;
98 			break;
99 
100 		case 'D':
101 			Flags |= SHOW_DISPLAY;
102 			break;
103 
104 		case 'd':
105 			Flags |= SHOW_DESC;
106 			break;
107 
108 		case 'E':
109 			BestCheckPkg = optarg;
110 			break;
111 
112 		case 'e':
113 			CheckPkg = optarg;
114 			break;
115 
116 		case 'f':
117 			Flags |= SHOW_PLIST;
118 			break;
119 
120 		case 'F':
121 			File2Pkg = 1;
122 			break;
123 
124 		case 'I':
125 			Flags |= SHOW_INDEX;
126 			break;
127 
128 		case 'i':
129 			Flags |= SHOW_INSTALL;
130 			break;
131 
132 		case 'K':
133 			_pkgdb_setPKGDB_DIR(optarg);
134 			break;
135 
136 		case 'k':
137 			Flags |= SHOW_DEINSTALL;
138 			break;
139 
140 		case 'L':
141 			Flags |= SHOW_FILES;
142 			break;
143 
144 		case 'l':
145 			InfoPrefix = optarg;
146 			break;
147 
148 		case 'm':
149 			Flags |= SHOW_MTREE;
150 			break;
151 
152 		case 'N':
153 			Flags |= SHOW_BLD_DEPENDS;
154 			break;
155 
156 		case 'n':
157 			Flags |= SHOW_DEPENDS;
158 			break;
159 
160 		case 'p':
161 			Flags |= SHOW_PREFIX;
162 			break;
163 
164 		case 'Q':
165 			Flags |= SHOW_BI_VAR;
166 			BuildInfoVariable = optarg;
167 			break;
168 
169 		case 'q':
170 			Quiet = TRUE;
171 			break;
172 
173 		case 'r':
174 			Flags |= SHOW_FULL_REQBY;
175 			break;
176 
177 		case 'R':
178 			Flags |= SHOW_REQBY;
179 			break;
180 
181 		case 's':
182 			Flags |= SHOW_PKG_SIZE;
183 			break;
184 
185 		case 'S':
186 			Flags |= SHOW_ALL_SIZE;
187 			break;
188 
189 		case 'u':
190 			Which = WHICH_USER;
191 			break;
192 
193 		case 'v':
194 			Verbose = TRUE;
195 			/* Reasonable definition of 'everything' */
196 			Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
197 			    SHOW_DEINSTALL | SHOW_DISPLAY | SHOW_MTREE |
198 			    SHOW_REQBY | SHOW_BLD_DEPENDS | SHOW_DEPENDS | SHOW_PKG_SIZE | SHOW_ALL_SIZE;
199 			break;
200 
201 		case 'V':
202 			show_version();
203 			/* NOTREACHED */
204 
205 		case 'X':
206 			Flags |= SHOW_SUMMARY;
207 			break;
208 
209 		case 'h':
210 		case '?':
211 		default:
212 			usage();
213 			/* NOTREACHED */
214 		}
215 
216 	argc -= optind;
217 	argv += optind;
218 
219 	if (argc == 0 && !Flags && !CheckPkg) {
220 		/* No argument or relevant flags specified - assume -I */
221 		Flags = SHOW_INDEX;
222 		/* assume -a if neither -u nor -a is given */
223 		if (Which == WHICH_LIST)
224 			Which = WHICH_ALL;
225 	}
226 
227 	if (CheckPkg != NULL && BestCheckPkg != NULL) {
228 		warnx("-E and -e are mutally exlusive");
229 		usage();
230 	}
231 
232 	if (argc != 0 && CheckPkg != NULL) {
233 		warnx("can't give any additional arguments to -e");
234 		usage();
235 	}
236 
237 	if (argc != 0 && BestCheckPkg != NULL) {
238 		warnx("can't give any additional arguments to -E");
239 		usage();
240 	}
241 
242 	if (argc != 0 && Which != WHICH_LIST) {
243 		warnx("can't use both -a/-u and package name");
244 		usage();
245 	}
246 
247 	/* Set some reasonable defaults */
248 	if (!Flags)
249 		Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY
250 			| SHOW_DEPENDS | SHOW_DISPLAY;
251 
252 	/* -Fe /filename -> change CheckPkg to real packagename */
253 	if (CheckPkg) {
254 		if (File2Pkg) {
255 			char   *s;
256 
257 			if (!pkgdb_open(ReadOnly))
258 				err(EXIT_FAILURE, "cannot open pkgdb");
259 
260 			s = pkgdb_retrieve(CheckPkg);
261 
262 			if (s == NULL)
263 				errx(EXIT_FAILURE, "No matching pkg for %s.", CheckPkg);
264 			CheckPkg = xstrdup(s);
265 
266 			pkgdb_close();
267 		}
268 		return CheckForPkg(CheckPkg);
269 	}
270 
271 	if (BestCheckPkg)
272 		return CheckForBestPkg(BestCheckPkg);
273 
274 	TAILQ_INIT(&pkgs);
275 
276 	/* Get all the remaining package names, if any */
277 	if (File2Pkg && Which == WHICH_LIST)
278 		if (!pkgdb_open(ReadOnly)) {
279 			err(EXIT_FAILURE, "cannot open pkgdb");
280 		}
281 	while (*argv) {
282 		/* pkgdb: if -F flag given, don't add pkgnames to the "pkgs"
283 		 * queue but rather resolve the given filenames to pkgnames
284 		 * using pkgdb_retrieve, then add them. */
285 		if (File2Pkg) {
286 			char   *s;
287 
288 			s = pkgdb_retrieve(*argv);
289 
290 			if (s) {
291 				lpp = alloc_lpkg(s);
292 				TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
293 			} else
294 				errx(EXIT_FAILURE, "No matching pkg for %s.", *argv);
295 		} else {
296 			if (ispkgpattern(*argv)) {
297 				switch (add_installed_pkgs_by_pattern(*argv, &pkgs)) {
298 				case 0:
299 					errx(EXIT_FAILURE, "No matching pkg for %s.", *argv);
300 				case -1:
301 					errx(EXIT_FAILURE, "Error during search in pkgdb for %s", *argv);
302 				}
303 			} else {
304 				const char   *dbdir;
305 
306 				dbdir = _pkgdb_getPKGDB_DIR();
307 				if (**argv == '/' && strncmp(*argv, dbdir, strlen(dbdir)) == 0) {
308 					*argv += strlen(dbdir) + 1;
309 					if ((*argv)[strlen(*argv) - 1] == '/') {
310 						(*argv)[strlen(*argv) - 1] = 0;
311 					}
312 				}
313 				lpp = alloc_lpkg(*argv);
314 				TAILQ_INSERT_TAIL(&pkgs, lpp, lp_link);
315 			}
316 		}
317 		argv++;
318 	}
319 
320 	if (File2Pkg)
321 		pkgdb_close();
322 
323 	/* If no packages, yelp */
324 	if (TAILQ_FIRST(&pkgs) == NULL && Which == WHICH_LIST && !CheckPkg)
325 		warnx("missing package name(s)"), usage();
326 
327 	if (isatty(STDOUT_FILENO)) {
328 		const char *p;
329 		struct winsize win;
330 
331 		if ((p = getenv("COLUMNS")) != NULL)
332 			termwidth = atoi(p);
333 		else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 &&
334 		    win.ws_col > 0)
335 			termwidth = win.ws_col;
336 	}
337 
338 	rc = pkg_perform(&pkgs);
339 	exit(rc);
340 	/* NOTREACHED */
341 }
342