Add ability to query installed packages based on origin.

This commit is contained in:
Maxim Sobolev 2002-05-04 14:49:49 +00:00
parent 9e861cfaa4
commit 76c0ee0ef2
7 changed files with 99 additions and 11 deletions

View File

@ -63,6 +63,7 @@ extern Boolean Quiet;
extern char *InfoPrefix;
extern char PlayPen[];
extern char *CheckPkg;
extern char *LookUpOrigin;
extern match_t MatchType;
extern struct which_head *whead;

View File

@ -26,7 +26,7 @@ __FBSDID("$FreeBSD$");
#include "info.h"
#include <err.h>
static char Options[] = "acdDe:fgGhiIkl:LmopqrRst:vVW:x";
static char Options[] = "acdDe:fgGhiIkl:LmoO:pqrRst:vVW:x";
int Flags = 0;
match_t MatchType = MATCH_GLOB;
@ -34,6 +34,7 @@ Boolean Quiet = FALSE;
char *InfoPrefix = (char *)(uintptr_t)"";
char PlayPen[FILENAME_MAX];
char *CheckPkg = NULL;
char *LookUpOrigin = NULL;
struct which_head *whead;
static void usage __P((void));
@ -132,6 +133,12 @@ main(int argc, char **argv)
Flags |= SHOW_ORIGIN;
break;
case 'O':
LookUpOrigin = strdup(optarg);
if (LookUpOrigin == NULL)
err(2, NULL);
break;
case 'V':
Flags |= SHOW_FMTREV;
break;
@ -211,7 +218,7 @@ main(int argc, char **argv)
/* If no packages, yelp */
if (pkgs == start && MatchType != MATCH_ALL && !CheckPkg &&
TAILQ_EMPTY(whead))
TAILQ_EMPTY(whead) && LookUpOrigin == NULL)
warnx("missing package name(s)"), usage();
*pkgs = NULL;
return pkg_perform(start);

View File

@ -30,6 +30,7 @@ static int pkg_do(char *);
static int find_pkg(const char *, struct which_head *);
static int cmp_path(const char *, const char *, const char *);
static char *abspath(const char *);
static int find_pkgs_by_origin(const char *, const char *);
int
pkg_perform(char **pkgs)
@ -52,6 +53,8 @@ pkg_perform(char **pkgs)
/* Not reached */
} else if (!TAILQ_EMPTY(whead)) {
return find_pkg(tmp, whead);
} else if (LookUpOrigin != NULL) {
return find_pkgs_by_origin(tmp, LookUpOrigin);
}
if (MatchType != MATCH_EXACT) {
@ -412,3 +415,61 @@ find_pkg(const char *db_dir, struct which_head *which_list)
free(which_list);
return 0;
}
/*
* Look through package dbs in db_dir and find which
* packages have the given origin. Don't use read_plist()
* because this increases time necessary for lookup by 40
* times, as we don't really have to parse all plist to
* get origin.
*/
static int
find_pkgs_by_origin(const char *db_dir, const char *origin)
{
char **installed;
int errcode, i;
installed = matchinstalled(MATCH_ALL, NULL, &errcode);
if (installed == NULL)
return errcode;
if (!Quiet)
printf("The following installed package(s) has %s origin:\n", origin);
for (i = 0; installed[i] != NULL; i++) {
FILE *fp;
char *cp, tmp[PATH_MAX];
int cmd;
snprintf(tmp, PATH_MAX, "%s/%s/%s", db_dir, installed[i],
CONTENTS_FNAME);
fp = fopen(tmp, "r");
if (fp == NULL) {
warn("%s", tmp);
return 1;
}
cmd = -1;
while (fgets(tmp, sizeof(tmp), fp)) {
int len = strlen(tmp);
while (len && isspace(tmp[len - 1]))
tmp[--len] = '\0';
if (!len)
continue;
cp = tmp;
if (tmp[0] != CMD_CHAR)
continue;
cmd = plist_cmd(tmp + 1, &cp);
if (cmd == PLIST_ORIGIN) {
if (strcmp(origin, cp) == 0)
puts(installed[i]);
break;
}
}
if (cmd != PLIST_ORIGIN)
warnx("package %s has no origin recorded", installed[i]);
fclose(fp);
}
return 0;
}

View File

@ -30,6 +30,7 @@
.Op Fl l Ar prefix
.Op Fl t Ar template
.Op Fl W Ar filename
.Op Fl O Ar origin
.Op Ar pkg-name ...
.Nm
.Fl a
@ -114,6 +115,10 @@ current directory, and does not have an absolute path, then the
.Ev PATH
is searched using
.Xr which 1 .
.It Fl O
For the specified
.Ar origin
argument list all packages having this origin.
.It Fl x
Treat the
.Ar pkg-name

View File

@ -312,21 +312,17 @@ show_cksum(const char *title, Package *plist)
void
show_origin(const char *title, Package *plist)
{
PackingList p;
if (!Quiet)
printf("%s%s", InfoPrefix, title);
for (p = plist->head; p != NULL; p = p->next)
if (p->type == PLIST_COMMENT && !strncmp(p->name, "ORIGIN:", 7)) {
printf("%s\n", p->name + 7);
break;
}
printf("%s\n", plist->origin != NULL ? plist->origin : "");
}
/* Show revision number of the packing list */
void
show_fmtrev(const char *title, Package *plist)
{
if (!Quiet)
printf("%s%s", InfoPrefix, title);
printf("%d.%d\n", plist->fmtver_maj, plist->fmtver_mnr);

View File

@ -91,7 +91,7 @@ enum _plist_t {
PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, PLIST_IGNORE,
PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY,
PLIST_PKGDEP, PLIST_MTREE, PLIST_DIR_RM, PLIST_IGNORE_INST,
PLIST_OPTION
PLIST_OPTION, PLIST_ORIGIN
};
typedef enum _plist_t plist_t;
@ -113,6 +113,8 @@ typedef struct _plist *PackingList;
struct _pack {
struct _plist *head, *tail;
char *name;
char *origin;
int fmtver_maj, fmtver_mnr;
};
typedef struct _pack Package;

View File

@ -42,6 +42,18 @@ add_plist(Package *p, plist_t type, const char *arg)
p->tail->next = tmp;
p->tail = tmp;
}
switch (type) {
case PLIST_NAME:
p->name = tmp->name;
break;
case PLIST_ORIGIN:
p->origin = tmp->name;
break;
default:
break;
}
}
void
@ -210,9 +222,13 @@ plist_cmd(const char *s, char **arg)
return PLIST_CHOWN;
else if (!strcmp(cmd, "group"))
return PLIST_CHGRP;
else if (!strcmp(cmd, "comment"))
else if (!strcmp(cmd, "comment")) {
if (!strncmp(*arg, "ORIGIN:", 7)) {
*arg += 7;
return PLIST_ORIGIN;
}
return PLIST_COMMENT;
else if (!strcmp(cmd, "ignore"))
} else if (!strcmp(cmd, "ignore"))
return PLIST_IGNORE;
else if (!strcmp(cmd, "ignore_inst"))
return PLIST_IGNORE_INST;