diff options
author | sobomax <sobomax@FreeBSD.org> | 2002-05-14 21:42:37 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2002-05-14 21:42:37 +0000 |
commit | bac8396cc90f34d617b583831e7a5902146b56b9 (patch) | |
tree | d8b1633a3ddd015d49630a6bac619312b1306625 /usr.sbin/pkg_install/lib | |
parent | eb68e3aae2dbda29ad3463cd0ad85dcb6ce4158a (diff) | |
download | FreeBSD-src-bac8396cc90f34d617b583831e7a5902146b56b9.zip FreeBSD-src-bac8396cc90f34d617b583831e7a5902146b56b9.tar.gz |
- 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
Diffstat (limited to 'usr.sbin/pkg_install/lib')
-rw-r--r-- | usr.sbin/pkg_install/lib/deps.c | 15 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/lib.h | 2 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/match.c | 146 |
3 files changed, 139 insertions, 24 deletions
diff --git a/usr.sbin/pkg_install/lib/deps.c b/usr.sbin/pkg_install/lib/deps.c index cf366f0..4ebb2cf 100644 --- a/usr.sbin/pkg_install/lib/deps.c +++ b/usr.sbin/pkg_install/lib/deps.c @@ -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); diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h index 181c3a2..5a11712 100644 --- a/usr.sbin/pkg_install/lib/lib.h +++ b/usr.sbin/pkg_install/lib/lib.h @@ -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 **); diff --git a/usr.sbin/pkg_install/lib/match.c b/usr.sbin/pkg_install/lib/match.c index 5671406..fd96f3f 100644 --- a/usr.sbin/pkg_install/lib/match.c +++ b/usr.sbin/pkg_install/lib/match.c @@ -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; @@ -163,6 +154,101 @@ matchinstalled(match_t MatchType, char **patterns, int *retval) } /* + * 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 * engine reported an error (usually invalid syntax). @@ -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) { |