Add ability to query installed packages based on origin.
This commit is contained in:
parent
9e861cfaa4
commit
76c0ee0ef2
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user