main.c revision 96030
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
2293520Sobrien#include <sys/cdefs.h>
2393520Sobrien__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/info/main.c 96030 2002-05-04 14:49:49Z sobomax $");
2493520Sobrien
25327Sjkh#include "lib.h"
26327Sjkh#include "info.h"
2774699Ssobomax#include <err.h>
28327Sjkh
2996030Ssobomaxstatic char Options[] = "acdDe:fgGhiIkl:LmoO:pqrRst:vVW:x";
3055567Sphantom
31327Sjkhint	Flags		= 0;
3272174Ssobomaxmatch_t	MatchType	= MATCH_GLOB;
33411SjkhBoolean Quiet		= FALSE;
3484745Ssobomaxchar *InfoPrefix	= (char *)(uintptr_t)"";
3511780Sjkhchar PlayPen[FILENAME_MAX];
36392Sjkhchar *CheckPkg		= NULL;
3796030Ssobomaxchar *LookUpOrigin	= NULL;
3874699Ssobomaxstruct which_head *whead;
39327Sjkh
4030221Scharnierstatic void usage __P((void));
4130221Scharnier
42327Sjkhint
43327Sjkhmain(int argc, char **argv)
44327Sjkh{
45327Sjkh    int ch;
46327Sjkh    char **pkgs, **start;
4756001Sdan    char *pkgs_split;
48327Sjkh
4974699Ssobomax    whead = malloc(sizeof(struct which_head));
5074699Ssobomax    if (whead == NULL)
5174699Ssobomax	err(2, NULL);
5274699Ssobomax    TAILQ_INIT(whead);
5374699Ssobomax
54327Sjkh    pkgs = start = argv;
5546105Sjkh    if (argc == 1) {
5672174Ssobomax	MatchType = MATCH_ALL;
5746105Sjkh	Flags = SHOW_INDEX;
5846105Sjkh    }
5946105Sjkh    else while ((ch = getopt(argc, argv, Options)) != -1) {
60327Sjkh	switch(ch) {
61327Sjkh	case 'a':
6272174Ssobomax	    MatchType = MATCH_ALL;
63327Sjkh	    break;
64327Sjkh
65327Sjkh	case 'v':
66327Sjkh	    Verbose = TRUE;
67327Sjkh	    /* Reasonable definition of 'everything' */
68327Sjkh	    Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
694996Sjkh		SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE;
70327Sjkh	    break;
71327Sjkh
72327Sjkh	case 'I':
73327Sjkh	    Flags |= SHOW_INDEX;
74327Sjkh	    break;
75327Sjkh
76327Sjkh	case 'p':
77327Sjkh	    Flags |= SHOW_PREFIX;
78327Sjkh	    break;
79327Sjkh
80327Sjkh	case 'c':
81327Sjkh	    Flags |= SHOW_COMMENT;
82327Sjkh	    break;
83327Sjkh
84327Sjkh	case 'd':
85327Sjkh	    Flags |= SHOW_DESC;
86327Sjkh	    break;
87327Sjkh
884996Sjkh	case 'D':
894996Sjkh	    Flags |= SHOW_DISPLAY;
904996Sjkh	    break;
914996Sjkh
92327Sjkh	case 'f':
93327Sjkh	    Flags |= SHOW_PLIST;
94327Sjkh	    break;
95327Sjkh
9671965Sjkh	case 'g':
9771965Sjkh	    Flags |= SHOW_CKSUM;
9871965Sjkh	    break;
9971965Sjkh
10072174Ssobomax	case 'G':
10172174Ssobomax	    MatchType = MATCH_EXACT;
10272174Ssobomax	    break;
10372174Ssobomax
104327Sjkh	case 'i':
105327Sjkh	    Flags |= SHOW_INSTALL;
106327Sjkh	    break;
107327Sjkh
108327Sjkh	case 'k':
109327Sjkh	    Flags |= SHOW_DEINSTALL;
110327Sjkh	    break;
111327Sjkh
112327Sjkh	case 'r':
113327Sjkh	    Flags |= SHOW_REQUIRE;
114327Sjkh	    break;
115327Sjkh
1164996Sjkh	case 'R':
1174996Sjkh	    Flags |= SHOW_REQBY;
1184996Sjkh	    break;
1194996Sjkh
120411Sjkh	case 'L':
121411Sjkh	    Flags |= SHOW_FILES;
122411Sjkh	    break;
123411Sjkh
1244996Sjkh	case 'm':
1254996Sjkh	    Flags |= SHOW_MTREE;
1264996Sjkh	    break;
1274996Sjkh
12872174Ssobomax	case 's':
12972174Ssobomax	    Flags |= SHOW_SIZE;
13072174Ssobomax	    break;
13162775Ssobomax
13267454Ssobomax	case 'o':
13367454Ssobomax	    Flags |= SHOW_ORIGIN;
13467454Ssobomax	    break;
13567454Ssobomax
13696030Ssobomax	case 'O':
13796030Ssobomax	    LookUpOrigin = strdup(optarg);
13896030Ssobomax	    if (LookUpOrigin == NULL)
13996030Ssobomax		err(2, NULL);
14096030Ssobomax	    break;
14196030Ssobomax
14284750Ssobomax	case 'V':
14384750Ssobomax	    Flags |= SHOW_FMTREV;
14484750Ssobomax	    break;
14584750Ssobomax
146379Sjkh	case 'l':
147379Sjkh	    InfoPrefix = optarg;
148379Sjkh	    break;
149379Sjkh
150411Sjkh	case 'q':
151411Sjkh	    Quiet = TRUE;
152411Sjkh	    break;
153411Sjkh
154383Sjkh	case 't':
15585019Ssobomax	    strlcpy(PlayPen, optarg, sizeof(PlayPen));
156383Sjkh	    break;
157383Sjkh
15872174Ssobomax	case 'x':
15972174Ssobomax	    MatchType = MATCH_REGEX;
16072174Ssobomax	    break;
16172174Ssobomax
162392Sjkh	case 'e':
163392Sjkh	    CheckPkg = optarg;
164392Sjkh	    break;
165392Sjkh
16674699Ssobomax	case 'W':
16774699Ssobomax	    {
16874699Ssobomax		struct which_entry *entp;
16974699Ssobomax
17074699Ssobomax		entp = calloc(1, sizeof(struct which_entry));
17174699Ssobomax		if (entp == NULL)
17274699Ssobomax		    err(2, NULL);
17374699Ssobomax
17474699Ssobomax		strlcpy(entp->file, optarg, PATH_MAX);
17574699Ssobomax		entp->skip = FALSE;
17674699Ssobomax		TAILQ_INSERT_TAIL(whead, entp, next);
17774699Ssobomax		break;
17874699Ssobomax	    }
17974699Ssobomax
180327Sjkh	case 'h':
181327Sjkh	case '?':
182327Sjkh	default:
18330221Scharnier	    usage();
184327Sjkh	    break;
185327Sjkh	}
18646105Sjkh    }
187327Sjkh
1888857Srgrimes    argc -= optind;
189327Sjkh    argv += optind;
190327Sjkh
191327Sjkh    /* Set some reasonable defaults */
192327Sjkh    if (!Flags)
1934996Sjkh	Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY;
194327Sjkh
195327Sjkh    /* Get all the remaining package names, if any */
19660563Ssteve    while (*argv) {
19795934Ssobomax	/*
19895934Ssobomax	 * Don't try to apply heuristics if arguments are regexs or if
19995934Ssobomax	 * the argument refers to an existing file.
20095934Ssobomax	 */
20195934Ssobomax	if (MatchType != MATCH_REGEX && !isfile(*argv))
20272174Ssobomax	    while ((pkgs_split = strrchr(*argv, (int)'/')) != NULL) {
20372174Ssobomax		*pkgs_split++ = '\0';
20472174Ssobomax		/*
20572174Ssobomax		 * If character after the '/' is alphanumeric or shell
20672174Ssobomax		 * metachar, then we've found the package name.  Otherwise
20772174Ssobomax		 * we've come across a trailing '/' and need to continue our
20872174Ssobomax		 * quest.
20972174Ssobomax		 */
21072174Ssobomax		if (isalpha(*pkgs_split) || ((MatchType == MATCH_GLOB) && \
21172174Ssobomax		    strpbrk(pkgs_split, "*?[]") != NULL)) {
21272174Ssobomax		    *argv = pkgs_split;
21372174Ssobomax		    break;
21472174Ssobomax		}
21560563Ssteve	    }
21660563Ssteve	*pkgs++ = *argv++;
21756001Sdan    }
218327Sjkh
219327Sjkh    /* If no packages, yelp */
22074699Ssobomax    if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg &&
22196030Ssobomax	TAILQ_EMPTY(whead) && LookUpOrigin == NULL)
22230221Scharnier	warnx("missing package name(s)"), usage();
223327Sjkh    *pkgs = NULL;
224327Sjkh    return pkg_perform(start);
225327Sjkh}
226327Sjkh
22730221Scharnierstatic void
22830221Scharnierusage()
229327Sjkh{
23030221Scharnier    fprintf(stderr, "%s\n%s\n%s\n",
23184750Ssobomax	"usage: pkg_info [-cdDfGiIkLmopqrRsvVx] [-e package] [-l prefix]",
23274699Ssobomax	"                [-t template] [-W filename] [pkg-name ...]",
23330221Scharnier	"       pkg_info -a [flags]");
234327Sjkh    exit(1);
235327Sjkh}
236