- Make use of DEPOROGINs (if there are any) when installing package;
- fix few bogosities here and there; - move some common routines into the library. MFC after: 2 weeks
This commit is contained in:
parent
a2642c4d67
commit
dd3a3dfc3b
@ -230,24 +230,39 @@ pkg_do(char *pkg)
|
||||
}
|
||||
|
||||
setenv(PKG_PREFIX_VNAME, (p = find_plist(&Plist, PLIST_CWD)) ? p->name : ".", 1);
|
||||
/* Protect against old packages with bogus @name fields */
|
||||
(const char *)PkgName = (p = find_plist(&Plist, PLIST_NAME)) ? p->name : "anonymous";
|
||||
/* Protect against old packages with bogus @name and origin fields */
|
||||
if (Plist.name == NULL)
|
||||
Plist.name = "anonymous";
|
||||
if (Plist.origin == NULL)
|
||||
Plist.origin = "anonymous/anonymous";
|
||||
|
||||
/* See if we're already registered */
|
||||
sprintf(LogDir, "%s/%s", LOG_DIR, PkgName);
|
||||
if (isdir(LogDir) && !Force) {
|
||||
warnx("package '%s' already recorded as installed", PkgName);
|
||||
/*
|
||||
* See if we're already registered either with the same name (the same
|
||||
* version) or some other version with the same origin.
|
||||
*/
|
||||
if ((isinstalledpkg(Plist.name) ||
|
||||
matchbyorigin(Plist.origin, NULL) != NULL) && !Force) {
|
||||
warnx("package '%s' or its older version already installed",
|
||||
Plist.name);
|
||||
code = 1;
|
||||
goto success; /* close enough for government work */
|
||||
}
|
||||
|
||||
/* Now check the packing list for dependencies */
|
||||
for (p = Plist.head; p ; p = p->next) {
|
||||
char *deporigin;
|
||||
|
||||
if (p->type != PLIST_PKGDEP)
|
||||
continue;
|
||||
if (Verbose)
|
||||
printf("Package '%s' depends on '%s'.\n", PkgName, p->name);
|
||||
if (vsystem("pkg_info -e %s", p->name)) {
|
||||
deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL;
|
||||
if (Verbose) {
|
||||
printf("Package '%s' depends on '%s'", Plist.name, p->name);
|
||||
if (deporigin != NULL)
|
||||
printf(" with '%s' origin", deporigin);
|
||||
printf(".\n");
|
||||
}
|
||||
if (!isinstalledpkg(p->name) &&
|
||||
!(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) {
|
||||
char path[FILENAME_MAX], *cp = NULL;
|
||||
|
||||
if (!Fake) {
|
||||
@ -316,8 +331,8 @@ pkg_do(char *pkg)
|
||||
if (fexists(REQUIRE_FNAME)) {
|
||||
vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */
|
||||
if (Verbose)
|
||||
printf("Running requirements file first for %s..\n", PkgName);
|
||||
if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, PkgName)) {
|
||||
printf("Running requirements file first for %s..\n", Plist.name);
|
||||
if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, Plist.name)) {
|
||||
warnx("package %s fails requirements %s", pkg_fullname,
|
||||
Force ? "installing anyway" : "- not installed");
|
||||
if (!Force) {
|
||||
@ -349,8 +364,8 @@ pkg_do(char *pkg)
|
||||
if (!NoInstall && fexists(pre_script)) {
|
||||
vsystem("chmod +x %s", pre_script); /* make sure */
|
||||
if (Verbose)
|
||||
printf("Running pre-install for %s..\n", PkgName);
|
||||
if (!Fake && vsystem("./%s %s %s", pre_script, PkgName, pre_arg)) {
|
||||
printf("Running pre-install for %s..\n", Plist.name);
|
||||
if (!Fake && vsystem("./%s %s %s", pre_script, Plist.name, pre_arg)) {
|
||||
warnx("install script returned error status");
|
||||
unlink(pre_script);
|
||||
code = 1;
|
||||
@ -364,7 +379,7 @@ pkg_do(char *pkg)
|
||||
|
||||
if (!Fake && fexists(MTREE_FNAME)) {
|
||||
if (Verbose)
|
||||
printf("Running mtree for %s..\n", PkgName);
|
||||
printf("Running mtree for %s..\n", Plist.name);
|
||||
p = find_plist(&Plist, PLIST_CWD);
|
||||
if (Verbose)
|
||||
printf("mtree -U -f %s -d -e -p %s >%s\n", MTREE_FNAME, p ? p->name : "/", _PATH_DEVNULL);
|
||||
@ -378,8 +393,8 @@ pkg_do(char *pkg)
|
||||
if (!NoInstall && fexists(post_script)) {
|
||||
vsystem("chmod +x %s", post_script); /* make sure */
|
||||
if (Verbose)
|
||||
printf("Running post-install for %s..\n", PkgName);
|
||||
if (!Fake && vsystem("./%s %s %s", post_script, PkgName, post_arg)) {
|
||||
printf("Running post-install for %s..\n", Plist.name);
|
||||
if (!Fake && vsystem("./%s %s %s", post_script, Plist.name, post_arg)) {
|
||||
warnx("install script returned error status");
|
||||
unlink(post_script);
|
||||
code = 1;
|
||||
@ -394,12 +409,7 @@ pkg_do(char *pkg)
|
||||
|
||||
if (getuid() != 0)
|
||||
warnx("not running as root - trying to record install anyway");
|
||||
if (!PkgName) {
|
||||
warnx("no package name! can't record package, sorry");
|
||||
code = 1;
|
||||
goto success; /* well, partial anyway */
|
||||
}
|
||||
sprintf(LogDir, "%s/%s", LOG_DIR, PkgName);
|
||||
sprintf(LogDir, "%s/%s", LOG_DIR, Plist.name);
|
||||
zapLogDir = 1;
|
||||
if (Verbose)
|
||||
printf("Attempting to record package into %s..\n", LogDir);
|
||||
@ -438,24 +448,46 @@ pkg_do(char *pkg)
|
||||
write_plist(&Plist, contfile);
|
||||
fclose(contfile);
|
||||
for (p = Plist.head; p ; p = p->next) {
|
||||
char *deporigin, **depnames;
|
||||
int i;
|
||||
|
||||
if (p->type != PLIST_PKGDEP)
|
||||
continue;
|
||||
if (Verbose)
|
||||
printf("Attempting to record dependency on package '%s'\n", p->name);
|
||||
sprintf(contents, "%s/%s/%s", LOG_DIR, basename(p->name),
|
||||
REQUIRED_BY_FNAME);
|
||||
contfile = fopen(contents, "a");
|
||||
if (!contfile)
|
||||
warnx("can't open dependency file '%s'!\n"
|
||||
"dependency registration is incomplete", contents);
|
||||
else {
|
||||
fprintf(contfile, "%s\n", PkgName);
|
||||
if (fclose(contfile) == EOF)
|
||||
warnx("cannot properly close file %s", contents);
|
||||
deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name :
|
||||
NULL;
|
||||
if (Verbose) {
|
||||
printf("Trying to record dependency on package '%s'", p->name);
|
||||
if (deporigin != NULL)
|
||||
printf(" with '%s' origin", deporigin);
|
||||
printf(".\n");
|
||||
}
|
||||
|
||||
depnames = (deporigin != NULL) ? matchbyorigin(deporigin, NULL) :
|
||||
NULL;
|
||||
if (depnames == NULL) {
|
||||
depnames = alloca(sizeof(*depnames) * 2);
|
||||
depnames[0] = p->name;
|
||||
depnames[1] = NULL;
|
||||
}
|
||||
for (i = 0; depnames[i] != NULL; i++) {
|
||||
sprintf(contents, "%s/%s/%s", LOG_DIR, depnames[i],
|
||||
REQUIRED_BY_FNAME);
|
||||
if (strcmp(p->name, depnames[i]) != 0)
|
||||
warnx("warning: package '%s' requires '%s', but '%s' "
|
||||
"is installed", Plist.name, p->name, depnames[i]);
|
||||
contfile = fopen(contents, "a");
|
||||
if (!contfile)
|
||||
warnx("can't open dependency file '%s'!\n"
|
||||
"dependency registration is incomplete", contents);
|
||||
else {
|
||||
fprintf(contfile, "%s\n", Plist.name);
|
||||
if (fclose(contfile) == EOF)
|
||||
warnx("cannot properly close file %s", contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Verbose)
|
||||
printf("Package %s registered in %s\n", PkgName, LogDir);
|
||||
printf("Package %s registered in %s\n", Plist.name, LogDir);
|
||||
}
|
||||
|
||||
if ((p = find_plist(&Plist, PLIST_DISPLAY)) != NULL) {
|
||||
|
@ -41,12 +41,15 @@ check_list(const char *home, Package *pkg)
|
||||
case PLIST_CWD:
|
||||
where = p->name;
|
||||
break;
|
||||
|
||||
case PLIST_IGNORE:
|
||||
p = p->next;
|
||||
break;
|
||||
|
||||
case PLIST_SRC:
|
||||
there = p->name;
|
||||
break;
|
||||
|
||||
case PLIST_FILE:
|
||||
cp = NULL;
|
||||
sprintf(name, "%s/%s", there ? there : where, p->name);
|
||||
|
@ -27,7 +27,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static int pkg_do(char *);
|
||||
static void sanity_check(char *);
|
||||
static void undepend(PackingList, char *);
|
||||
static void undepend(char *, char *);
|
||||
static char LogDir[FILENAME_MAX];
|
||||
|
||||
|
||||
@ -46,8 +46,18 @@ pkg_perform(char **pkgs)
|
||||
return 1;
|
||||
/* Not reached */
|
||||
|
||||
if (matched != NULL)
|
||||
pkgs = matched;
|
||||
/*
|
||||
* Copy matched[] into pkgs[], because we'll need to use
|
||||
* matchinstalled() later on.
|
||||
*/
|
||||
if (matched != NULL) {
|
||||
pkgs = NULL;
|
||||
for (i = 0; matched[i] != NULL; i++) {
|
||||
pkgs = realloc(pkgs, sizeof(*pkgs) * (i + 2));
|
||||
pkgs[i] = strdup(matched[i]);
|
||||
}
|
||||
pkgs[i] = NULL;
|
||||
}
|
||||
else switch (MatchType) {
|
||||
case MATCH_GLOB:
|
||||
break;
|
||||
@ -111,9 +121,9 @@ static int
|
||||
pkg_do(char *pkg)
|
||||
{
|
||||
FILE *cfile;
|
||||
char home[FILENAME_MAX];
|
||||
char *deporigin, **depnames, home[FILENAME_MAX];
|
||||
PackingList p;
|
||||
int len;
|
||||
int i, len;
|
||||
/* support for separate pre/post install scripts */
|
||||
int new_m = 0;
|
||||
char pre_script[FILENAME_MAX] = DEINSTALL_FNAME;
|
||||
@ -131,9 +141,7 @@ pkg_do(char *pkg)
|
||||
if (Plist.head)
|
||||
free_plist(&Plist);
|
||||
|
||||
sprintf(LogDir, "%s/%s", LOG_DIR, pkg);
|
||||
|
||||
if (!fexists(LogDir)) {
|
||||
if (!isinstalledpkg(pkg)) {
|
||||
warnx("no such package '%s' installed", pkg);
|
||||
return 1;
|
||||
}
|
||||
@ -143,6 +151,8 @@ pkg_do(char *pkg)
|
||||
errx(2, "%s: unable to get current working directory!", __func__);
|
||||
}
|
||||
|
||||
sprintf(LogDir, "%s/%s", LOG_DIR, pkg);
|
||||
|
||||
if (chdir(LogDir) == FAIL) {
|
||||
warnx("unable to change directory to %s! deinstall failed", LogDir);
|
||||
return 1;
|
||||
@ -288,10 +298,25 @@ pkg_do(char *pkg)
|
||||
for (p = Plist.head; p ; p = p->next) {
|
||||
if (p->type != PLIST_PKGDEP)
|
||||
continue;
|
||||
if (Verbose)
|
||||
printf("Attempting to remove dependency on package '%s'\n", p->name);
|
||||
if (!Fake)
|
||||
undepend(p, pkg);
|
||||
deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name :
|
||||
NULL;
|
||||
if (Verbose) {
|
||||
printf("Trying to remove dependency on package '%s'", p->name);
|
||||
if (deporigin != NULL)
|
||||
printf(" with '%s' origin", deporigin);
|
||||
printf(".\n");
|
||||
}
|
||||
if (!Fake) {
|
||||
depnames = (deporigin != NULL) ? matchbyorigin(deporigin, NULL) :
|
||||
NULL;
|
||||
if (depnames == NULL) {
|
||||
depnames = alloca(sizeof(*depnames) * 2);
|
||||
depnames[0] = p->name;
|
||||
depnames[1] = NULL;
|
||||
}
|
||||
for (i = 0; depnames[i] != NULL; i++)
|
||||
undepend(depnames[i], pkg);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -314,7 +339,7 @@ cleanup(int sig)
|
||||
}
|
||||
|
||||
static void
|
||||
undepend(PackingList p, char *pkgname)
|
||||
undepend(char *p, char *pkgname)
|
||||
{
|
||||
char fname[FILENAME_MAX], ftmp[FILENAME_MAX];
|
||||
FILE *fpwr;
|
||||
@ -323,10 +348,9 @@ undepend(PackingList p, char *pkgname)
|
||||
struct reqr_by_head *rb_list;
|
||||
|
||||
|
||||
if (requiredby(p->name, &rb_list, Verbose, FALSE) <= 0)
|
||||
if (requiredby(p, &rb_list, Verbose, FALSE) <= 0)
|
||||
return;
|
||||
snprintf(fname, sizeof(fname), "%s/%s/%s", LOG_DIR, p->name,
|
||||
REQUIRED_BY_FNAME);
|
||||
snprintf(fname, sizeof(fname), "%s/%s/%s", LOG_DIR, p, REQUIRED_BY_FNAME);
|
||||
snprintf(ftmp, sizeof(ftmp), "%s.XXXXXX", fname);
|
||||
s = mkstemp(ftmp);
|
||||
if (s == -1) {
|
||||
|
@ -27,34 +27,28 @@ __FBSDID("$FreeBSD$");
|
||||
#include <signal.h>
|
||||
|
||||
static int pkg_do(char *);
|
||||
static int find_pkg(const char *, struct which_head *);
|
||||
static int find_pkg(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 *);
|
||||
static int find_pkgs_by_origin(const char *);
|
||||
|
||||
int
|
||||
pkg_perform(char **pkgs)
|
||||
{
|
||||
char **matched;
|
||||
const char *tmp;
|
||||
int err_cnt = 0;
|
||||
int i, errcode;
|
||||
|
||||
signal(SIGINT, cleanup);
|
||||
|
||||
tmp = LOG_DIR;
|
||||
|
||||
/* Overriding action? */
|
||||
if (CheckPkg) {
|
||||
char buf[FILENAME_MAX];
|
||||
|
||||
snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg);
|
||||
return abs(access(buf, R_OK));
|
||||
return isinstalledpkg(CheckPkg) == TRUE ? 0 : 1;
|
||||
/* Not reached */
|
||||
} else if (!TAILQ_EMPTY(whead)) {
|
||||
return find_pkg(tmp, whead);
|
||||
return find_pkg(whead);
|
||||
} else if (LookUpOrigin != NULL) {
|
||||
return find_pkgs_by_origin(tmp, LookUpOrigin);
|
||||
return find_pkgs_by_origin(LookUpOrigin);
|
||||
}
|
||||
|
||||
if (MatchType != MATCH_EXACT) {
|
||||
@ -145,11 +139,11 @@ pkg_do(char *pkg)
|
||||
}
|
||||
/* It's not an ininstalled package, try and find it among the installed */
|
||||
else {
|
||||
sprintf(log_dir, "%s/%s", LOG_DIR, pkg);
|
||||
if (!fexists(log_dir)) {
|
||||
if (!isinstalledpkg(pkg)) {
|
||||
warnx("can't find package '%s' installed or in a file!", pkg);
|
||||
return 1;
|
||||
}
|
||||
sprintf(log_dir, "%s/%s", LOG_DIR, pkg);
|
||||
if (chdir(log_dir) == FAIL) {
|
||||
warnx("can't change directory to '%s'!", log_dir);
|
||||
return 1;
|
||||
@ -316,11 +310,11 @@ cmp_path(const char *target, const char *current, const char *cwd)
|
||||
}
|
||||
|
||||
/*
|
||||
* Look through package dbs in db_dir and find which
|
||||
* Look through package dbs in LOG_DIR and find which
|
||||
* packages installed the files in which_list.
|
||||
*/
|
||||
static int
|
||||
find_pkg(const char *db_dir, struct which_head *which_list)
|
||||
find_pkg(struct which_head *which_list)
|
||||
{
|
||||
char **installed;
|
||||
int errcode, i;
|
||||
@ -365,7 +359,7 @@ find_pkg(const char *db_dir, struct which_head *which_list)
|
||||
char *cwd = NULL;
|
||||
char tmp[PATH_MAX];
|
||||
|
||||
snprintf(tmp, PATH_MAX, "%s/%s/%s", db_dir, installed[i],
|
||||
snprintf(tmp, PATH_MAX, "%s/%s/%s", LOG_DIR, installed[i],
|
||||
CONTENTS_FNAME);
|
||||
fp = fopen(tmp, "r");
|
||||
if (fp == NULL) {
|
||||
@ -417,65 +411,27 @@ find_pkg(const char *db_dir, struct which_head *which_list)
|
||||
}
|
||||
|
||||
/*
|
||||
* Look through package dbs in db_dir and find which
|
||||
* Look through package dbs in LOG_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)
|
||||
find_pkgs_by_origin(const char *origin)
|
||||
{
|
||||
char **installed;
|
||||
char **matched;
|
||||
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", db_dir, installed[i]);
|
||||
/*
|
||||
* SPECIAL CASE: ignore empty dirs, since we can can see them
|
||||
* during port installation.
|
||||
*/
|
||||
if (isemptydir(tmp))
|
||||
continue;
|
||||
snprintf(tmp, PATH_MAX, "%s/%s", tmp, CONTENTS_FNAME);
|
||||
fp = fopen(tmp, "r");
|
||||
if (fp == NULL) {
|
||||
warn("%s", tmp);
|
||||
return 1;
|
||||
}
|
||||
matched = matchbyorigin(origin, &errcode);
|
||||
if (matched == NULL)
|
||||
return errcode;
|
||||
|
||||
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);
|
||||
}
|
||||
for (i = 0; matched[i] != NULL; i++)
|
||||
puts(matched[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -84,7 +84,6 @@ int
|
||||
chkifdepends(const char *pkgname1, const char *pkgname2)
|
||||
{
|
||||
char *cp1, *cp2;
|
||||
char pkgdir[FILENAME_MAX];
|
||||
int errcode;
|
||||
struct reqr_by_entry *rb_entry;
|
||||
struct reqr_by_head *rb_list;
|
||||
@ -98,8 +97,7 @@ chkifdepends(const char *pkgname1, const char *pkgname2)
|
||||
|
||||
errcode = 0;
|
||||
/* Check that pkgname2 is actually installed */
|
||||
snprintf(pkgdir, sizeof(pkgdir), "%s/%s", LOG_DIR, pkgname2);
|
||||
if (!isdir(pkgdir))
|
||||
if (!isinstalledpkg(pkgname2))
|
||||
goto exit;
|
||||
|
||||
errcode = requiredby(pkgname2, &rb_list, FALSE, TRUE);
|
||||
@ -142,7 +140,7 @@ int
|
||||
requiredby(const char *pkgname, struct reqr_by_head **list, Boolean strict, Boolean filter)
|
||||
{
|
||||
FILE *fp;
|
||||
char fbuf[FILENAME_MAX], fname[FILENAME_MAX], pkgdir[FILENAME_MAX];
|
||||
char fbuf[FILENAME_MAX], fname[FILENAME_MAX];
|
||||
int retval;
|
||||
struct reqr_by_entry *rb_entry;
|
||||
static struct reqr_by_head rb_list = STAILQ_HEAD_INITIALIZER(rb_list);
|
||||
@ -155,14 +153,14 @@ requiredby(const char *pkgname, struct reqr_by_head **list, Boolean strict, Bool
|
||||
free(rb_entry);
|
||||
}
|
||||
|
||||
snprintf(fname, sizeof(fname), "%s/%s", LOG_DIR, pkgname);
|
||||
if (!isdir(fname)) {
|
||||
if (!isinstalledpkg(pkgname)) {
|
||||
if (strict == TRUE)
|
||||
warnx("no such package '%s' installed", pkgname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(fname, sizeof(fname), "%s/%s", fname, REQUIRED_BY_FNAME);
|
||||
snprintf(fname, sizeof(fname), "%s/%s/%s", LOG_DIR, pkgname,
|
||||
REQUIRED_BY_FNAME);
|
||||
fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
/* Probably pkgname doesn't have any packages that depend on it */
|
||||
@ -175,8 +173,7 @@ requiredby(const char *pkgname, struct reqr_by_head **list, Boolean strict, Bool
|
||||
while (fgets(fbuf, sizeof(fbuf), fp) != NULL) {
|
||||
if (fbuf[strlen(fbuf) - 1] == '\n')
|
||||
fbuf[strlen(fbuf) - 1] = '\0';
|
||||
snprintf(pkgdir, sizeof(pkgdir), "%s/%s", LOG_DIR, fbuf);
|
||||
if (filter == TRUE && !isdir(pkgdir)) {
|
||||
if (filter == TRUE && !isinstalledpkg(fbuf)) {
|
||||
if (strict == TRUE)
|
||||
warnx("package '%s' is recorded in the '%s' but isn't "
|
||||
"actually installed", fbuf, fname);
|
||||
|
@ -193,6 +193,8 @@ int pkg_perform(char **);
|
||||
|
||||
/* Query installed packages */
|
||||
char **matchinstalled(match_t, char **, int *);
|
||||
char **matchbyorigin(const char *, int *);
|
||||
int isinstalledpkg(const char *name);
|
||||
|
||||
/* Dependencies */
|
||||
int sortdeps(char **);
|
||||
|
@ -38,6 +38,7 @@ struct store {
|
||||
};
|
||||
|
||||
static int rex_match(const char *, const char *);
|
||||
struct store *storecreate(struct store *);
|
||||
static int storeappend(struct store *, const char *);
|
||||
static int fname_cmp(const FTSENT **, const FTSENT **);
|
||||
|
||||
@ -63,22 +64,12 @@ matchinstalled(match_t MatchType, char **patterns, int *retval)
|
||||
FTSENT *f;
|
||||
Boolean *lmatched;
|
||||
|
||||
store = storecreate(store);
|
||||
if (store == NULL) {
|
||||
store = malloc(sizeof *store);
|
||||
if (store == NULL) {
|
||||
warnx("%s(): malloc() failed", __func__);
|
||||
if (retval != NULL)
|
||||
*retval = 1;
|
||||
return NULL;
|
||||
}
|
||||
store->currlen = 0;
|
||||
store->store = NULL;
|
||||
} else
|
||||
if (store->store != NULL)
|
||||
/* Free previously allocated memory */
|
||||
for (i = 0; store->store[i] != NULL; i++)
|
||||
free(store->store[i]);
|
||||
store->used = 0;
|
||||
if (retval != NULL)
|
||||
*retval = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retval != NULL)
|
||||
*retval = 0;
|
||||
@ -162,6 +153,101 @@ matchinstalled(match_t MatchType, char **patterns, int *retval)
|
||||
return store->store;
|
||||
}
|
||||
|
||||
/*
|
||||
* Synopsis is similar to matchinstalled(), but use origin
|
||||
* as a key for matching packages.
|
||||
*/
|
||||
char **
|
||||
matchbyorigin(const char *origin, int *retval)
|
||||
{
|
||||
char **installed;
|
||||
int i;
|
||||
static struct store *store = NULL;
|
||||
|
||||
store = storecreate(store);
|
||||
if (store == NULL) {
|
||||
if (retval != NULL)
|
||||
*retval = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (retval != NULL)
|
||||
*retval = 0;
|
||||
|
||||
installed = matchinstalled(MATCH_ALL, NULL, retval);
|
||||
if (installed == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; installed[i] != NULL; i++) {
|
||||
FILE *fp;
|
||||
char *cp, tmp[PATH_MAX];
|
||||
int cmd;
|
||||
|
||||
snprintf(tmp, PATH_MAX, "%s/%s", LOG_DIR, installed[i]);
|
||||
/*
|
||||
* SPECIAL CASE: ignore empty dirs, since we can can see them
|
||||
* during port installation.
|
||||
*/
|
||||
if (isemptydir(tmp))
|
||||
continue;
|
||||
snprintf(tmp, PATH_MAX, "%s/%s", tmp, CONTENTS_FNAME);
|
||||
fp = fopen(tmp, "r");
|
||||
if (fp == NULL) {
|
||||
warn("%s", tmp);
|
||||
if (retval != NULL)
|
||||
*retval = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
storeappend(store, installed[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cmd != PLIST_ORIGIN)
|
||||
warnx("package %s has no origin recorded", installed[i]);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (store->used == 0)
|
||||
return NULL;
|
||||
else
|
||||
return store->store;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if the specified package is installed,
|
||||
* or FALSE otherwise.
|
||||
*/
|
||||
int
|
||||
isinstalledpkg(const char *name)
|
||||
{
|
||||
char buf[FILENAME_MAX];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", LOG_DIR, name);
|
||||
if (!isdir(buf) || access(buf, R_OK) == FAIL)
|
||||
return FALSE;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", buf, CONTENTS_FNAME);
|
||||
if (!isfile(buf) || access(buf, R_OK) == FAIL)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if specified pkgname matches RE pattern.
|
||||
* Otherwise returns 0 if doesn't match or -1 if RE
|
||||
@ -194,6 +280,36 @@ rex_match(const char *pattern, const char *pkgname)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an empty store, optionally deallocating
|
||||
* any previously allocated space if store != NULL.
|
||||
*/
|
||||
struct store *
|
||||
storecreate(struct store *store)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (store == NULL) {
|
||||
store = malloc(sizeof *store);
|
||||
if (store == NULL) {
|
||||
warnx("%s(): malloc() failed", __func__);
|
||||
return NULL;
|
||||
}
|
||||
store->currlen = 0;
|
||||
store->store = NULL;
|
||||
} else
|
||||
if (store->store != NULL)
|
||||
/* Free previously allocated memory */
|
||||
for (i = 0; store->store[i] != NULL; i++)
|
||||
free(store->store[i]);
|
||||
store->used = 0;
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append specified element to the provided store.
|
||||
*/
|
||||
static int
|
||||
storeappend(struct store *store, const char *item)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user