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