main.c revision 85019
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 "lib.h"
23#include "info.h"
24#include <err.h>
25
26#ifndef lint
27static const char rcsid[] =
28  "$FreeBSD: head/usr.sbin/pkg_install/info/main.c 85019 2001-10-16 03:04:15Z sobomax $";
29#endif
30
31static char Options[] = "acdDe:fgGhiIkl:LmopqrRst:vVW:x";
32
33int	Flags		= 0;
34match_t	MatchType	= MATCH_GLOB;
35Boolean Quiet		= FALSE;
36char *InfoPrefix	= (char *)(uintptr_t)"";
37char PlayPen[FILENAME_MAX];
38char *CheckPkg		= NULL;
39struct which_head *whead;
40
41static void usage __P((void));
42
43int
44main(int argc, char **argv)
45{
46    int ch;
47    char **pkgs, **start;
48    char *pkgs_split;
49
50    whead = malloc(sizeof(struct which_head));
51    if (whead == NULL)
52	err(2, NULL);
53    TAILQ_INIT(whead);
54
55    pkgs = start = argv;
56    if (argc == 1) {
57	MatchType = MATCH_ALL;
58	Flags = SHOW_INDEX;
59    }
60    else while ((ch = getopt(argc, argv, Options)) != -1) {
61	switch(ch) {
62	case 'a':
63	    MatchType = MATCH_ALL;
64	    break;
65
66	case 'v':
67	    Verbose = TRUE;
68	    /* Reasonable definition of 'everything' */
69	    Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
70		SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
71	    break;
72
73	case 'I':
74	    Flags |= SHOW_INDEX;
75	    break;
76
77	case 'p':
78	    Flags |= SHOW_PREFIX;
79	    break;
80
81	case 'c':
82	    Flags |= SHOW_COMMENT;
83	    break;
84
85	case 'd':
86	    Flags |= SHOW_DESC;
87	    break;
88
89	case 'D':
90	    Flags |= SHOW_DISPLAY;
91	    break;
92
93	case 'f':
94	    Flags |= SHOW_PLIST;
95	    break;
96
97	case 'g':
98	    Flags |= SHOW_CKSUM;
99	    break;
100
101	case 'G':
102	    MatchType = MATCH_EXACT;
103	    break;
104
105	case 'i':
106	    Flags |= SHOW_INSTALL;
107	    break;
108
109	case 'k':
110	    Flags |= SHOW_DEINSTALL;
111	    break;
112
113	case 'r':
114	    Flags |= SHOW_REQUIRE;
115	    break;
116
117	case 'R':
118	    Flags |= SHOW_REQBY;
119	    break;
120
121	case 'L':
122	    Flags |= SHOW_FILES;
123	    break;
124
125	case 'm':
126	    Flags |= SHOW_MTREE;
127	    break;
128
129	case 's':
130	    Flags |= SHOW_SIZE;
131	    break;
132
133	case 'o':
134	    Flags |= SHOW_ORIGIN;
135	    break;
136
137	case 'V':
138	    Flags |= SHOW_FMTREV;
139	    break;
140
141	case 'l':
142	    InfoPrefix = optarg;
143	    break;
144
145	case 'q':
146	    Quiet = TRUE;
147	    break;
148
149	case 't':
150	    strlcpy(PlayPen, optarg, sizeof(PlayPen));
151	    break;
152
153	case 'x':
154	    MatchType = MATCH_REGEX;
155	    break;
156
157	case 'e':
158	    CheckPkg = optarg;
159	    break;
160
161	case 'W':
162	    {
163		struct which_entry *entp;
164
165		entp = calloc(1, sizeof(struct which_entry));
166		if (entp == NULL)
167		    err(2, NULL);
168
169		strlcpy(entp->file, optarg, PATH_MAX);
170		entp->skip = FALSE;
171		TAILQ_INSERT_TAIL(whead, entp, next);
172		break;
173	    }
174
175	case 'h':
176	case '?':
177	default:
178	    usage();
179	    break;
180	}
181    }
182
183    argc -= optind;
184    argv += optind;
185
186    /* Set some reasonable defaults */
187    if (!Flags)
188	Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY;
189
190    /* Get all the remaining package names, if any */
191    while (*argv) {
192	/* Don't try to apply heuristics if arguments are regexs */
193	if (MatchType != MATCH_REGEX)
194	    while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) {
195		*pkgs_split++ = '\0';
196		/*
197		 * If character after the '/' is alphanumeric or shell
198		 * metachar, then we've found the package name.  Otherwise
199		 * we've come across a trailing '/' and need to continue our
200		 * quest.
201		 */
202		if (isalpha(*pkgs_split) || ((MatchType == MATCH_GLOB) && \
203		    strpbrk(pkgs_split, "*?[]") != NULL)) {
204		    *argv = pkgs_split;
205		    break;
206		}
207	    }
208	*pkgs++ = *argv++;
209    }
210
211    /* If no packages, yelp */
212    if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg &&
213	TAILQ_EMPTY(whead))
214	warnx("missing package name(s)"), usage();
215    *pkgs = NULL;
216    return pkg_perform(start);
217}
218
219static void
220usage()
221{
222    fprintf(stderr, "%s\n%s\n%s\n",
223	"usage: pkg_info [-cdDfGiIkLmopqrRsvVx] [-e package] [-l prefix]",
224	"                [-t template] [-W filename] [pkg-name ...]",
225	"       pkg_info -a [flags]");
226    exit(1);
227}
228