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