]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.sbin/pkg_install/info/main.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.sbin / pkg_install / info / main.c
1 /*
2  *
3  * FreeBSD install - a package for the installation and maintainance
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     whead = malloc(sizeof(struct which_head));
72     if (whead == NULL)
73         err(2, NULL);
74     TAILQ_INIT(whead);
75
76     pkgs = start = argv;
77     if (argc == 1) {
78         MatchType = MATCH_ALL;
79         Flags = SHOW_INDEX;
80     }
81     else while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) {
82         switch(ch) {
83         case 'a':
84             MatchType = MATCH_ALL;
85             break;
86
87         case 'b':
88             UseBlkSz = TRUE;
89             break;
90
91         case 'v':
92             Verbose++;
93             /* Reasonable definition of 'everything' */
94             Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
95                 SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
96             break;
97
98         case 'E':
99             Flags |= SHOW_PKGNAME;
100             break;
101
102         case 'I':
103             Flags |= SHOW_INDEX;
104             break;
105
106         case 'p':
107             Flags |= SHOW_PREFIX;
108             break;
109
110         case 'c':
111             Flags |= SHOW_COMMENT;
112             break;
113
114         case 'd':
115             Flags |= SHOW_DESC;
116             break;
117
118         case 'D':
119             Flags |= SHOW_DISPLAY;
120             break;
121
122         case 'f':
123             Flags |= SHOW_PLIST;
124             break;
125
126         case 'g':
127             Flags |= SHOW_CKSUM;
128             break;
129
130         case 'G':
131             MatchType = MATCH_EXACT;
132             break;
133
134         case 'i':
135             Flags |= SHOW_INSTALL;
136             break;
137
138         case 'j':
139             Flags |= SHOW_REQUIRE;
140             break;
141
142         case 'k':
143             Flags |= SHOW_DEINSTALL;
144             break;
145
146         case 'K':
147             KeepPackage = TRUE;
148             break;
149
150         case 'r':
151             Flags |= SHOW_DEPEND;
152             break;
153
154         case 'R':
155             Flags |= SHOW_REQBY;
156             break;
157
158         case 'L':
159             Flags |= SHOW_FILES;
160             break;
161
162         case 'm':
163             Flags |= SHOW_MTREE;
164             break;
165
166         case 's':
167             Flags |= SHOW_SIZE;
168             break;
169
170         case 'o':
171             Flags |= SHOW_ORIGIN;
172             break;
173
174         case 'O':
175             LookUpOrigin = strdup(optarg);
176             if (LookUpOrigin == NULL)
177                 err(2, NULL);
178             break;
179
180         case 'V':
181             Flags |= SHOW_FMTREV;
182             break;
183
184         case 'l':
185             InfoPrefix = optarg;
186             break;
187
188         case 'q':
189             Quiet = TRUE;
190             break;
191
192         case 'Q':
193             Quiet = TRUE;
194             QUIET = TRUE;
195             break;
196
197         case 't':
198             strlcpy(PlayPen, optarg, sizeof(PlayPen));
199             break;
200
201         case 'x':
202             MatchType = MATCH_REGEX;
203             break;
204
205         case 'X':
206             MatchType = MATCH_EREGEX;
207             break;
208
209         case 'e':
210             CheckPkg = optarg;
211             break;
212
213         case 'W':
214             {
215                 struct which_entry *entp;
216
217                 entp = calloc(1, sizeof(struct which_entry));
218                 if (entp == NULL)
219                     err(2, NULL);
220                 
221                 strlcpy(entp->file, optarg, PATH_MAX);
222                 entp->skip = FALSE;
223                 TAILQ_INSERT_TAIL(whead, entp, next);
224                 break;
225             }
226
227         case 'P':
228             Flags = SHOW_PTREV;
229             break;
230
231         case 'h':
232         default:
233             usage();
234             break;
235         }
236     }
237
238     argc -= optind;
239     argv += optind;
240
241     if (Flags & SHOW_PTREV) {
242         if (!Quiet)
243             printf("Package tools revision: ");
244         printf("%d\n", PKG_INSTALL_VERSION);
245         exit(0);
246     }
247
248     /* Set some reasonable defaults */
249     if (!Flags)
250         Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY;
251
252     /* Get all the remaining package names, if any */
253     while (*argv) {
254         /* 
255          * Don't try to apply heuristics if arguments are regexs or if
256          * the argument refers to an existing file.
257          */
258         if (MatchType != MATCH_REGEX && MatchType != MATCH_EREGEX && !isfile(*argv) && !isURL(*argv))
259             while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) {
260                 *pkgs_split++ = '\0';
261                 /*
262                  * If character after the '/' is alphanumeric or shell
263                  * metachar, then we've found the package name.  Otherwise
264                  * we've come across a trailing '/' and need to continue our
265                  * quest.
266                  */
267                 if (isalnum(*pkgs_split) || ((MatchType == MATCH_GLOB) && \
268                     strpbrk(pkgs_split, "*?[]") != NULL)) {
269                     *argv = pkgs_split;
270                     break;
271                 }
272             }
273         *pkgs++ = *argv++;
274     }
275
276     /* If no packages, yelp */
277     if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg && 
278         TAILQ_EMPTY(whead) && LookUpOrigin == NULL)
279         warnx("missing package name(s)"), usage();
280     *pkgs = NULL;
281     return pkg_perform(start);
282 }
283
284 static void
285 usage(void)
286 {
287     fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
288         "usage: pkg_info [-bcdDEfgGiIjkKLmopPqQrRsvVxX] [-e package] [-l prefix]",
289         "                [-t template] -a | pkg-name ...",
290         "       pkg_info [-qQ] -W filename",
291         "       pkg_info [-qQ] -O origin",
292         "       pkg_info");
293     exit(1);
294 }