main.c revision 112579
1327Sjkh/*
2327Sjkh *
3327Sjkh * FreeBSD install - a package for the installation and maintainance
4327Sjkh * of non-core utilities.
5327Sjkh *
6327Sjkh * Redistribution and use in source and binary forms, with or without
7327Sjkh * modification, are permitted provided that the following conditions
8327Sjkh * are met:
9327Sjkh * 1. Redistributions of source code must retain the above copyright
10327Sjkh *    notice, this list of conditions and the following disclaimer.
11327Sjkh * 2. Redistributions in binary form must reproduce the above copyright
12327Sjkh *    notice, this list of conditions and the following disclaimer in the
13327Sjkh *    documentation and/or other materials provided with the distribution.
14327Sjkh *
15327Sjkh * Jordan K. Hubbard
16327Sjkh * 18 July 1993
17327Sjkh *
1831997Shoek * This is the info module.
19327Sjkh *
20327Sjkh */
21327Sjkh
22327Sjkh#include <sys/cdefs.h>
23327Sjkh__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/info/main.c 112579 2003-03-25 01:22:42Z mdodd $");
2474699Ssobomax
25327Sjkh#include "lib.h"
2655567Sphantom#include "info.h"
2755567Sphantom#include <err.h>
2855567Sphantom
2955567Sphantomstatic char Options[] = "abcdDe:fgGhiIkl:LmoO:pPqQrRst:vVW:x";
30327Sjkh
3184750Ssobomaxint	Flags		= 0;
3255567Sphantommatch_t	MatchType	= MATCH_GLOB;
33327SjkhBoolean Quiet		= FALSE;
3472174SsobomaxBoolean QUIET		= FALSE;
35411SjkhBoolean UseBlkSz	= FALSE;
3684745Ssobomaxchar *InfoPrefix	= (char *)(uintptr_t)"";
3711780Sjkhchar PlayPen[FILENAME_MAX];
38392Sjkhchar *CheckPkg		= NULL;
3974699Ssobomaxchar *LookUpOrigin	= NULL;
40327Sjkhstruct which_head *whead;
4130221Scharnier
4230221Scharnierstatic void usage __P((void));
43327Sjkh
44327Sjkhint
45327Sjkhmain(int argc, char **argv)
46327Sjkh{
47327Sjkh    int ch;
4856001Sdan    char **pkgs, **start;
49327Sjkh    char *pkgs_split;
5074699Ssobomax
5174699Ssobomax    whead = malloc(sizeof(struct which_head));
5274699Ssobomax    if (whead == NULL)
5374699Ssobomax	err(2, NULL);
5474699Ssobomax    TAILQ_INIT(whead);
55327Sjkh
5646105Sjkh    pkgs = start = argv;
5772174Ssobomax    if (argc == 1) {
5846105Sjkh	MatchType = MATCH_ALL;
5946105Sjkh	Flags = SHOW_INDEX;
6046105Sjkh    }
61327Sjkh    else while ((ch = getopt(argc, argv, Options)) != -1) {
62327Sjkh	switch(ch) {
6372174Ssobomax	case 'a':
64327Sjkh	    MatchType = MATCH_ALL;
65327Sjkh	    break;
66327Sjkh
67327Sjkh	case 'b':
68327Sjkh	    UseBlkSz = TRUE;
69327Sjkh	    break;
704996Sjkh
71327Sjkh	case 'v':
72327Sjkh	    Verbose = TRUE;
73327Sjkh	    /* Reasonable definition of 'everything' */
74327Sjkh	    Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
75327Sjkh		SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
76327Sjkh	    break;
77327Sjkh
78327Sjkh	case 'I':
79327Sjkh	    Flags |= SHOW_INDEX;
80327Sjkh	    break;
81327Sjkh
82327Sjkh	case 'p':
83327Sjkh	    Flags |= SHOW_PREFIX;
84327Sjkh	    break;
85327Sjkh
86327Sjkh	case 'c':
87327Sjkh	    Flags |= SHOW_COMMENT;
88327Sjkh	    break;
894996Sjkh
904996Sjkh	case 'd':
914996Sjkh	    Flags |= SHOW_DESC;
924996Sjkh	    break;
93327Sjkh
94327Sjkh	case 'D':
95327Sjkh	    Flags |= SHOW_DISPLAY;
96327Sjkh	    break;
9771965Sjkh
9871965Sjkh	case 'f':
9971965Sjkh	    Flags |= SHOW_PLIST;
10071965Sjkh	    break;
10172174Ssobomax
10272174Ssobomax	case 'g':
10372174Ssobomax	    Flags |= SHOW_CKSUM;
10472174Ssobomax	    break;
105327Sjkh
106327Sjkh	case 'G':
107327Sjkh	    MatchType = MATCH_EXACT;
108327Sjkh	    break;
109327Sjkh
110327Sjkh	case 'i':
111327Sjkh	    Flags |= SHOW_INSTALL;
112327Sjkh	    break;
113327Sjkh
114327Sjkh	case 'k':
115327Sjkh	    Flags |= SHOW_DEINSTALL;
116327Sjkh	    break;
1174996Sjkh
1184996Sjkh	case 'r':
1194996Sjkh	    Flags |= SHOW_REQUIRE;
1204996Sjkh	    break;
121411Sjkh
122411Sjkh	case 'R':
123411Sjkh	    Flags |= SHOW_REQBY;
124411Sjkh	    break;
1254996Sjkh
1264996Sjkh	case 'L':
1274996Sjkh	    Flags |= SHOW_FILES;
1284996Sjkh	    break;
12972174Ssobomax
13072174Ssobomax	case 'm':
13172174Ssobomax	    Flags |= SHOW_MTREE;
13262775Ssobomax	    break;
13367454Ssobomax
13467454Ssobomax	case 's':
13567454Ssobomax	    Flags |= SHOW_SIZE;
13667454Ssobomax	    break;
13784750Ssobomax
13884750Ssobomax	case 'o':
13984750Ssobomax	    Flags |= SHOW_ORIGIN;
14084750Ssobomax	    break;
141379Sjkh
142379Sjkh	case 'O':
143379Sjkh	    LookUpOrigin = strdup(optarg);
144379Sjkh	    if (LookUpOrigin == NULL)
145411Sjkh		err(2, NULL);
146411Sjkh	    break;
147411Sjkh
148411Sjkh	case 'V':
149383Sjkh	    Flags |= SHOW_FMTREV;
15085019Ssobomax	    break;
151383Sjkh
152383Sjkh	case 'l':
15372174Ssobomax	    InfoPrefix = optarg;
15472174Ssobomax	    break;
15572174Ssobomax
15672174Ssobomax	case 'q':
157392Sjkh	    Quiet = TRUE;
158392Sjkh	    break;
159392Sjkh
160392Sjkh	case 'Q':
16174699Ssobomax	    Quiet = TRUE;
16274699Ssobomax	    QUIET = TRUE;
16374699Ssobomax	    break;
16474699Ssobomax
16574699Ssobomax	case 't':
16674699Ssobomax	    strlcpy(PlayPen, optarg, sizeof(PlayPen));
16774699Ssobomax	    break;
16874699Ssobomax
16974699Ssobomax	case 'x':
17074699Ssobomax	    MatchType = MATCH_REGEX;
17174699Ssobomax	    break;
17274699Ssobomax
17374699Ssobomax	case 'e':
17474699Ssobomax	    CheckPkg = optarg;
175327Sjkh	    break;
176327Sjkh
177327Sjkh	case 'W':
17830221Scharnier	    {
179327Sjkh		struct which_entry *entp;
180327Sjkh
18146105Sjkh		entp = calloc(1, sizeof(struct which_entry));
182327Sjkh		if (entp == NULL)
1838857Srgrimes		    err(2, NULL);
184327Sjkh
185327Sjkh		strlcpy(entp->file, optarg, PATH_MAX);
186327Sjkh		entp->skip = FALSE;
187327Sjkh		TAILQ_INSERT_TAIL(whead, entp, next);
1884996Sjkh		break;
189327Sjkh	    }
190327Sjkh
19160563Ssteve	case 'P':
19272174Ssobomax	    Flags = SHOW_PTREV;
19372174Ssobomax	    break;
19472174Ssobomax
19572174Ssobomax	case 'h':
19672174Ssobomax	case '?':
19772174Ssobomax	default:
19872174Ssobomax	    usage();
19972174Ssobomax	    break;
20072174Ssobomax	}
20172174Ssobomax    }
20272174Ssobomax
20372174Ssobomax    argc -= optind;
20472174Ssobomax    argv += optind;
20572174Ssobomax
20672174Ssobomax    if (Flags & SHOW_PTREV) {
20760563Ssteve	if (!Quiet)
20860563Ssteve	    printf("Package tools revision: ");
20956001Sdan	printf("%d\n", PKG_INSTALL_VERSION);
210327Sjkh	exit(0);
211327Sjkh    }
21274699Ssobomax
21374699Ssobomax    /* Set some reasonable defaults */
21430221Scharnier    if (!Flags)
215327Sjkh	Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY;
216327Sjkh
217327Sjkh    /* Get all the remaining package names, if any */
218327Sjkh    while (*argv) {
21930221Scharnier	/*
22030221Scharnier	 * Don't try to apply heuristics if arguments are regexs or if
221327Sjkh	 * the argument refers to an existing file.
22230221Scharnier	 */
22384750Ssobomax	if (MatchType != MATCH_REGEX && !isfile(*argv))
22474699Ssobomax	    while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) {
22530221Scharnier		*pkgs_split++ = '\0';
226327Sjkh		/*
227327Sjkh		 * If character after the '/' is alphanumeric or shell
228		 * metachar, then we've found the package name.  Otherwise
229		 * we've come across a trailing '/' and need to continue our
230		 * quest.
231		 */
232		if (isalpha(*pkgs_split) || ((MatchType == MATCH_GLOB) && \
233		    strpbrk(pkgs_split, "*?[]") != NULL)) {
234		    *argv = pkgs_split;
235		    break;
236		}
237	    }
238	*pkgs++ = *argv++;
239    }
240
241    /* If no packages, yelp */
242    if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg &&
243	TAILQ_EMPTY(whead) && LookUpOrigin == NULL)
244	warnx("missing package name(s)"), usage();
245    *pkgs = NULL;
246    return pkg_perform(start);
247}
248
249static void
250usage()
251{
252    fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
253	"usage: pkg_info [-cdDfGiIkLmopqrRsvVx] [-e package] [-l prefix]",
254	"                [-t template] [pkg-name ...]",
255	"       pkg_info [-q] -W filename",
256	"       pkg_info [-q] -O origin",
257	"       pkg_info -a [flags]");
258    exit(1);
259}
260