]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.sbin/pkg_install/info/main.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.sbin / pkg_install / info / main.c
1 /*
2  *
3  * FreeBSD install - a package for the installation and maintenance
4  * of non-core utilities.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * Jordan K. Hubbard
16  * 18 July 1993
17  *
18  * This is the info module.
19  *
20  */
21
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
24
25 #include <getopt.h>
26 #include <err.h>
27
28 #include "lib.h"
29 #include "info.h"
30
31 int     Flags           = 0;
32 match_t MatchType       = MATCH_GLOB;
33 Boolean QUIET           = FALSE;
34 Boolean UseBlkSz        = FALSE;
35 char *InfoPrefix        = (char *)(uintptr_t)"";
36 char PlayPen[FILENAME_MAX];
37 char *CheckPkg          = NULL;
38 char *LookUpOrigin      = NULL;
39 Boolean KeepPackage     = FALSE;
40 struct which_head *whead;
41
42 static void usage(void);
43
44 static char opts[] = "abcdDe:EfgGhiIjkKl:LmoO:pPqQrRst:vVW:xX";
45 static struct option longopts[] = {
46         { "all",        no_argument,            NULL,           'a' },
47         { "blocksize",  no_argument,            NULL,           'b' },
48         { "exist",      required_argument,      NULL,           'X' },
49         { "exists",     required_argument,      NULL,           'X' },
50         { "extended",   no_argument,            NULL,           'e' },
51         { "help",       no_argument,            NULL,           'h' },
52         { "keep",       no_argument,            NULL,           'K' },
53         { "no-glob",    no_argument,            NULL,           'G' },
54         { "origin",     required_argument,      NULL,           'O' },
55         { "quiet",      no_argument,            NULL,           'q' },
56         { "regex",      no_argument,            NULL,           'x' },
57         { "template",   required_argument,      NULL,           't' },
58         { "verbose",    no_argument,            NULL,           'v' },
59         { "version",    no_argument,            NULL,           'P' },
60         { "which",      required_argument,      NULL,           'W' },
61         { NULL,         0,                      NULL,           0 }
62 };
63
64 int
65 main(int argc, char **argv)
66 {
67     int ch;
68     char **pkgs, **start;
69     char *pkgs_split;
70
71     warnpkgng();
72     whead = malloc(sizeof(struct which_head));
73     if (whead == NULL)
74         err(2, NULL);
75     TAILQ_INIT(whead);
76
77     pkgs = start = argv;
78     if (argc == 1) {
79         MatchType = MATCH_ALL;
80         Flags = SHOW_INDEX;
81     }
82     else while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) {
83         switch(ch) {
84         case 'a':
85             MatchType = MATCH_ALL;
86             break;
87
88         case 'b':
89             UseBlkSz = TRUE;
90             break;
91
92         case 'v':
93             Verbose++;
94             /* Reasonable definition of 'everything' */
95             Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
96                 SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
97             break;
98
99         case 'E':
100             Flags |= SHOW_PKGNAME;
101             break;
102
103         case 'I':
104             Flags |= SHOW_INDEX;
105             break;
106
107         case 'p':
108             Flags |= SHOW_PREFIX;
109             break;
110
111         case 'c':
112             Flags |= SHOW_COMMENT;
113             break;
114
115         case 'd':
116             Flags |= SHOW_DESC;
117             break;
118
119         case 'D':
120             Flags |= SHOW_DISPLAY;
121             break;
122
123         case 'f':
124             Flags |= SHOW_PLIST;
125             break;
126
127         case 'g':
128             Flags |= SHOW_CKSUM;
129             break;
130
131         case 'G':
132             MatchType = MATCH_EXACT;
133             break;
134
135         case 'i':
136             Flags |= SHOW_INSTALL;
137             break;
138
139         case 'j':
140             Flags |= SHOW_REQUIRE;
141             break;
142
143         case 'k':
144             Flags |= SHOW_DEINSTALL;
145             break;
146
147         case 'K':
148             KeepPackage = TRUE;
149             break;
150
151         case 'r':
152             Flags |= SHOW_DEPEND;
153             break;
154
155         case 'R':
156             Flags |= SHOW_REQBY;
157             break;
158
159         case 'L':
160             Flags |= SHOW_FILES;
161             break;
162
163         case 'm':
164             Flags |= SHOW_MTREE;
165             break;
166
167         case 's':
168             Flags |= SHOW_SIZE;
169             break;
170
171         case 'o':
172             Flags |= SHOW_ORIGIN;
173             break;
174
175         case 'O':
176             LookUpOrigin = strdup(optarg);
177             if (LookUpOrigin == NULL)
178                 err(2, NULL);
179             break;
180
181         case 'V':
182             Flags |= SHOW_FMTREV;
183             break;
184
185         case 'l':
186             InfoPrefix = optarg;
187             break;
188
189         case 'q':
190             Quiet = TRUE;
191             break;
192
193         case 'Q':
194             Quiet = TRUE;
195             QUIET = TRUE;
196             break;
197
198         case 't':
199             strlcpy(PlayPen, optarg, sizeof(PlayPen));
200             break;
201
202         case 'x':
203             MatchType = MATCH_REGEX;
204             break;
205
206         case 'X':
207             MatchType = MATCH_EREGEX;
208             break;
209
210         case 'e':
211             CheckPkg = optarg;
212             break;
213
214         case 'W':
215             {
216                 struct which_entry *entp;
217
218                 entp = calloc(1, sizeof(struct which_entry));
219                 if (entp == NULL)
220                     err(2, NULL);
221                 
222                 strlcpy(entp->file, optarg, PATH_MAX);
223                 entp->skip = FALSE;
224                 TAILQ_INSERT_TAIL(whead, entp, next);
225                 break;
226             }
227
228         case 'P':
229             Flags = SHOW_PTREV;
230             break;
231
232         case 'h':
233         default:
234             usage();
235             break;
236         }
237     }
238
239     argc -= optind;
240     argv += optind;
241
242     if (Flags & SHOW_PTREV) {
243         if (!Quiet)
244             printf("Package tools revision: ");
245         printf("%d\n", PKG_INSTALL_VERSION);
246         exit(0);
247     }
248
249     /* Set some reasonable defaults */
250     if (!Flags)
251         Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY;
252
253     /* Get all the remaining package names, if any */
254     while (*argv) {
255         /* 
256          * Don't try to apply heuristics if arguments are regexs or if
257          * the argument refers to an existing file.
258          */
259         if (MatchType != MATCH_REGEX && MatchType != MATCH_EREGEX && !isfile(*argv) && !isURL(*argv))
260             while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) {
261                 *pkgs_split++ = '\0';
262                 /*
263                  * If character after the '/' is alphanumeric or shell
264                  * metachar, then we've found the package name.  Otherwise
265                  * we've come across a trailing '/' and need to continue our
266                  * quest.
267                  */
268                 if (isalnum(*pkgs_split) || ((MatchType == MATCH_GLOB) && \
269                     strpbrk(pkgs_split, "*?[]") != NULL)) {
270                     *argv = pkgs_split;
271                     break;
272                 }
273             }
274         *pkgs++ = *argv++;
275     }
276
277     /* If no packages, yelp */
278     if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg && 
279         TAILQ_EMPTY(whead) && LookUpOrigin == NULL)
280         warnx("missing package name(s)"), usage();
281     *pkgs = NULL;
282     return pkg_perform(start);
283 }
284
285 static void
286 usage(void)
287 {
288     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
289         "usage: pkg_info [-bcdDEfgGiIjkKLmopPqQrRsvVxX] [-e package] [-l prefix]",
290         "                [-t template] -a | pkg-name ...",
291         "       pkg_info [-qQ] -W filename",
292         "       pkg_info [-qQ] -O origin",
293         "       pkg_info");
294     exit(1);
295 }