diff --git a/bin/xbps-bin.c b/bin/xbps-bin.c index 7d728f5682d..15ba7d12e55 100644 --- a/bin/xbps-bin.c +++ b/bin/xbps-bin.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -41,30 +42,28 @@ typedef struct repository_info { } repo_info_t; static bool sanitize_localpath(char *, const char *); -static prop_dictionary_t getrepolist_dict(void); +static prop_dictionary_t getrepolist_dict(const char *); static bool pkgindex_getinfo(prop_dictionary_t, repo_info_t *); static void usage(void); static void usage(void) { - printf("Usage: xbps-bin [action] [arguments]\n\n" + printf("Usage: xbps-bin [options] [action] [arguments]\n\n" " Available actions:\n" " install, list, repo-add, repo-list, repo-rm, search, show\n" - " Action arguments:\n" - " install\t[] []\n" - " list\n" - " repo-add\t[]\n" - " repo-list\t[none]\n" - " repo-rm\t[]\n" - " search\t[]\n" - " show\t[]\n" - " Environment:\n" - " XBPS_META_PATH\tPath to the xbps metadata directory\n" + " Actions with arguments:\n" + " install\t\n" + " repo-add\t\n" + " repo-rm\t\n" + " search\t\n" + " show\t\n" + " Options shared by all actions:\n" + " -r\t\t\n" "\n" " Examples:\n" " $ xbps-bin install klibc\n" - " $ xbps-bin install klibc /path/to/directory\n" + " $ xbps-bin -r /path/to/root install klibc\n" " $ xbps-bin list\n" " $ xbps-bin repo-add /path/to/directory\n" " $ xbps-bin repo-add http://www.location.org/xbps-repo\n" @@ -104,12 +103,14 @@ pkgindex_getinfo(prop_dictionary_t dict, repo_info_t *ri) } static prop_dictionary_t -getrepolist_dict(void) +getrepolist_dict(const char *root) { prop_dictionary_t dict; char plist[PATH_MAX]; - if (!xbps_append_full_path(plist, NULL, XBPS_REPOLIST)) + xbps_set_rootdir(root); + + if (!xbps_append_full_path(true, plist, NULL, XBPS_REPOLIST)) exit(1); dict = prop_dictionary_internalize_from_file(plist); @@ -169,22 +170,41 @@ main(int argc, char **argv) { prop_dictionary_t dict; repo_info_t *rinfo = NULL; - char dpkgidx[PATH_MAX], repolist[PATH_MAX]; - int rv = 0; + char dpkgidx[PATH_MAX], repolist[PATH_MAX], *root = NULL; + int c, rv = 0; - if (argc < 2) + while ((c = getopt(argc, argv, "r:")) != -1) { + switch (c) { + case 'r': + /* To specify the root directory */ + root = strdup(optarg); + if (root == NULL) + exit(ENOMEM); + xbps_set_rootdir(root); + break; + case '?': + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) usage(); - if (strcasecmp(argv[1], "repo-add") == 0) { + if (strcasecmp(argv[0], "repo-add") == 0) { /* Adds a new repository to the pool. */ - if (argc != 3) + if (argc != 2) usage(); - if (!sanitize_localpath(dpkgidx, argv[2])) + if (!sanitize_localpath(dpkgidx, argv[1])) exit(EINVAL); /* Temp buffer to verify pkgindex file. */ - if (!xbps_append_full_path(repolist, dpkgidx, XBPS_PKGINDEX)) + if (!xbps_append_full_path(false, repolist, dpkgidx, + XBPS_PKGINDEX)) exit(EINVAL); dict = prop_dictionary_internalize_from_file(repolist); @@ -222,22 +242,22 @@ main(int argc, char **argv) prop_object_release(dict); free(rinfo); - } else if (strcasecmp(argv[1], "repo-list") == 0) { + } else if (strcasecmp(argv[0], "repo-list") == 0) { /* Lists all repositories registered in pool. */ - if (argc != 2) + if (argc != 1) usage(); - dict = getrepolist_dict(); + dict = getrepolist_dict(root); (void)xbps_callback_array_iter_in_dict(dict, "repository-list", xbps_list_strings_in_array, NULL); prop_object_release(dict); - } else if (strcasecmp(argv[1], "repo-rm") == 0) { + } else if (strcasecmp(argv[0], "repo-rm") == 0) { /* Remove a repository from the pool. */ - if (argc != 3) + if (argc != 2) usage(); - if (!sanitize_localpath(dpkgidx, argv[2])) + if (!sanitize_localpath(dpkgidx, argv[1])) exit(EINVAL); if (!xbps_unregister_repository(dpkgidx)) { @@ -250,37 +270,37 @@ main(int argc, char **argv) exit(EINVAL); } - } else if (strcasecmp(argv[1], "search") == 0) { + } else if (strcasecmp(argv[0], "search") == 0) { /* Search for a package by looking at short_desc. */ - if (argc != 3) + if (argc != 2) usage(); - dict = getrepolist_dict(); + dict = getrepolist_dict(root); (void)xbps_callback_array_iter_in_dict(dict, - "repository-list", xbps_search_string_in_pkgs, argv[2]); + "repository-list", xbps_search_string_in_pkgs, argv[1]); prop_object_release(dict); - } else if (strcasecmp(argv[1], "show") == 0) { + } else if (strcasecmp(argv[0], "show") == 0) { /* Shows info about a binary package. */ - if (argc != 3) + if (argc != 2) usage(); - dict = getrepolist_dict(); + dict = getrepolist_dict(root); if (xbps_callback_array_iter_in_dict(dict, "repository-list", - xbps_show_pkg_info_from_repolist, argv[2]) != 0) { + xbps_show_pkg_info_from_repolist, argv[1]) != 0) { prop_object_release(dict); printf("ERROR: unable to locate package '%s'.\n", - argv[2]); + argv[1]); exit(EINVAL); } prop_object_release(dict); - } else if (strcasecmp(argv[1], "list") == 0) { + } else if (strcasecmp(argv[0], "list") == 0) { /* Lists packages currently registered in database. */ - if (argc != 2) + if (argc != 1) usage(); - if (!xbps_append_full_path(dpkgidx, NULL, XBPS_REGPKGDB)) + if (!xbps_append_full_path(true, dpkgidx, NULL, XBPS_REGPKGDB)) exit(EINVAL); dict = prop_dictionary_internalize_from_file(dpkgidx); @@ -296,21 +316,15 @@ main(int argc, char **argv) } prop_object_release(dict); - } else if (strcasecmp(argv[1], "install") == 0) { + } else if (strcasecmp(argv[0], "install") == 0) { /* Installs a binary package and required deps. */ - if (argc < 3 || argc > 4) + if (argc != 2) usage(); - if (argc == 3) { - /* Install into root directory by default. */ - rv = xbps_install_binary_pkg(argv[2], "/"); - } else { - /* install into specified directory. */ - rv = xbps_install_binary_pkg(argv[2], argv[3]); - } - + /* Install into root directory by default. */ + rv = xbps_install_binary_pkg(argv[1], root); if (rv) { - printf("ERROR: unable to install %s.\n", argv[2]); + printf("ERROR: unable to install %s.\n", argv[1]); exit(rv); } } else { diff --git a/bin/xbps-pkgdb.c b/bin/xbps-pkgdb.c index bb4297f5a0d..19b73897eeb 100644 --- a/bin/xbps-pkgdb.c +++ b/bin/xbps-pkgdb.c @@ -48,16 +48,17 @@ write_plist_file(prop_dictionary_t dict, const char *file) static void usage(void) { - printf("usage: xbps-pkgdb [args]\n\n" + printf("usage: xbps-pkgdb [options] [action] [args]\n\n" " Available actions:\n" " register, sanitize-plist, unregister, version\n" " Action arguments:\n" - " register\t[ ]\n" - " sanitize-plist\t[]\n" - " unregister\t[ ]\n" - " version\t[]\n" - " Environment:\n" - " XBPS_META_PATH\tPath to xbps metadata root directory\n\n" + " register\t\t \n" + " sanitize-plist\t\n" + " unregister\t\t \n" + " version\t\t\n" + " Options shared by all actions:\n" + " -r\t\t\t\n" + "\n" " Examples:\n" " $ xbps-pkgdb register pkgname 2.0 \"A short description\"\n" " $ xbps-pkgdb sanitize-plist /blah/foo.plist\n" @@ -71,14 +72,32 @@ main(int argc, char **argv) { prop_dictionary_t dbdict = NULL, pkgdict; const char *version; - char dbfile[PATH_MAX], *in_chroot_env; + char dbfile[PATH_MAX], *in_chroot_env, *root = NULL; bool in_chroot = false; - int rv = 0; + int c, rv = 0; - if (argc < 2) + while ((c = getopt(argc, argv, "r:")) != -1) { + switch (c) { + case 'r': + /* To specify the root directory */ + root = strdup(optarg); + if (root == NULL) + exit(ENOMEM); + xbps_set_rootdir(root); + break; + case '?': + default: + usage(); + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) usage(); - if (!xbps_append_full_path(dbfile, NULL, XBPS_REGPKGDB)) { + if (!xbps_append_full_path(true, dbfile, NULL, XBPS_REGPKGDB)) { printf("=> ERROR: couldn't find regpkdb file (%s)\n", strerror(errno)); exit(EINVAL); @@ -88,53 +107,53 @@ main(int argc, char **argv) if (in_chroot_env != NULL) in_chroot = true; - if (strcasecmp(argv[1], "register") == 0) { + if (strcasecmp(argv[0], "register") == 0) { /* Registers a package into the database */ - if (argc != 5) - usage(); - - rv = xbps_register_pkg(argv[2], argv[3], argv[4]); - if (rv == EEXIST) { - printf("%s=> %s-%s already registered.\n", - in_chroot ? "[chroot] " : "", argv[2], argv[3]); - } else if (rv != 0) { - printf("%s=> couldn't register %s-%s (%s).\n", - in_chroot ? "[chroot] " : "" , argv[2], argv[3], - strerror(rv)); - } else { - printf("%s=> %s-%s registered successfully.\n", - in_chroot ? "[chroot] " : "", argv[2], argv[3]); - } - - } else if (strcasecmp(argv[1], "unregister") == 0) { - /* Unregisters a package from the database */ if (argc != 4) usage(); - if (!xbps_remove_pkg_dict_from_file(argv[2], dbfile)) { + rv = xbps_register_pkg(argv[1], argv[2], argv[3]); + if (rv == EEXIST) { + printf("%s=> %s-%s already registered.\n", + in_chroot ? "[chroot] " : "", argv[1], argv[2]); + } else if (rv != 0) { + printf("%s=> couldn't register %s-%s (%s).\n", + in_chroot ? "[chroot] " : "" , argv[1], argv[2], + strerror(rv)); + } else { + printf("%s=> %s-%s registered successfully.\n", + in_chroot ? "[chroot] " : "", argv[1], argv[2]); + } + + } else if (strcasecmp(argv[0], "unregister") == 0) { + /* Unregisters a package from the database */ + if (argc != 3) + usage(); + + if (!xbps_remove_pkg_dict_from_file(argv[1], dbfile)) { if (errno == ENODEV) printf("=> ERROR: %s not registered " - "in database.\n", argv[2]); + "in database.\n", argv[1]); else printf("=> ERROR: couldn't unregister %s " - "from database (%s)\n", argv[2], + "from database (%s)\n", argv[1], strerror(errno)); exit(EINVAL); } printf("%s=> %s-%s unregistered successfully.\n", - in_chroot ? "[chroot] " : "", argv[2], argv[3]); + in_chroot ? "[chroot] " : "", argv[1], argv[2]); - } else if (strcasecmp(argv[1], "version") == 0) { + } else if (strcasecmp(argv[0], "version") == 0) { /* Prints version of an installed package */ - if (argc != 3) + if (argc != 2) usage(); dbdict = prop_dictionary_internalize_from_file(dbfile); if (dbdict == NULL) exit(1); - pkgdict = xbps_find_pkg_in_dict(dbdict, argv[2]); + pkgdict = xbps_find_pkg_in_dict(dbdict, argv[1]); if (pkgdict == NULL) exit(1); @@ -144,18 +163,18 @@ main(int argc, char **argv) printf("%s\n", version); - } else if (strcasecmp(argv[1], "sanitize-plist") == 0) { + } else if (strcasecmp(argv[0], "sanitize-plist") == 0) { /* Sanitize a plist file (indent the file properly) */ - if (argc != 3) + if (argc != 1) usage(); - dbdict = prop_dictionary_internalize_from_file(argv[2]); + dbdict = prop_dictionary_internalize_from_file(argv[1]); if (dbdict == NULL) { printf("=> ERROR: couldn't sanitize %s plist file " - "(%s)\n", argv[2], strerror(errno)); + "(%s)\n", argv[1], strerror(errno)); exit(1); } - write_plist_file(dbdict, argv[2]); + write_plist_file(dbdict, argv[1]); } else { usage(); diff --git a/bin/xbps-src.sh b/bin/xbps-src.sh index b4c78759fb9..a4ce3121f2a 100755 --- a/bin/xbps-src.sh +++ b/bin/xbps-src.sh @@ -110,8 +110,8 @@ set_defvars() [ ! -d "$val" ] && msg_error "cannot find $i, aborting." done - XBPS_REGPKGDB_CMD="env XBPS_META_PATH=$XBPS_META_PATH xbps-pkgdb" - XBPS_BIN_CMD="env XBPS_META_PATH=$XBPS_META_PATH xbps-bin" + XBPS_REGPKGDB_CMD="xbps-pkgdb -r $XBPS_MASTERDIR" + XBPS_BIN_CMD="xbps-bin -r $XBPS_MASTERDIR" } # diff --git a/include/plist.h b/include/plist.h index f5292387d96..925f4684641 100644 --- a/include/plist.h +++ b/include/plist.h @@ -152,7 +152,8 @@ int xbps_show_pkg_namedesc(prop_object_t, void *, bool *); int xbps_search_string_in_pkgs(prop_object_t, void *, bool *); /* Utils */ -bool xbps_append_full_path(char *, const char *, const char *); +void xbps_set_rootdir(const char *); +bool xbps_append_full_path(bool, char *, const char *, const char *); int xbps_check_is_installed_pkg(const char *); int xbps_cmpver_packages(const char *, const char *); int xbps_cmpver_versions(const char *, const char *); diff --git a/include/xbps_api.h b/include/xbps_api.h index c7b903f65f2..4c5f0ef8659 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -36,7 +36,7 @@ #include /* Default root PATH for xbps to store metadata info. */ -#define XBPS_META_PATH "/var/cache/xbps/" +#define XBPS_META_PATH "/var/cache/xbps" /* Filename for the repositories plist file. */ #define XBPS_REPOLIST "repositories.plist" diff --git a/lib/depends.c b/lib/depends.c index 299060fe94e..5ef4bbc61be 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -53,7 +53,7 @@ xbps_check_is_installed_pkg(const char *pkg) assert(pkg != NULL); - if (!xbps_append_full_path(plist, NULL, XBPS_REGPKGDB)) + if (!xbps_append_full_path(true, plist, NULL, XBPS_REGPKGDB)) return EINVAL; pkgname = xbps_get_pkg_name(pkg); @@ -207,7 +207,7 @@ xbps_install_pkg_deps(prop_dictionary_t pkg) assert(pkg != NULL); - if (!xbps_append_full_path(plist, NULL, XBPS_REPOLIST)) + if (!xbps_append_full_path(true, plist, NULL, XBPS_REPOLIST)) return EINVAL; repolistd = prop_dictionary_internalize_from_file(plist); @@ -229,7 +229,7 @@ xbps_install_pkg_deps(prop_dictionary_t pkg) */ while ((obj = prop_object_iterator_next(iter)) != NULL) { memset(plist, 0, sizeof(&plist)); - if (!xbps_append_full_path(plist, + if (!xbps_append_full_path(false, plist, prop_string_cstring_nocopy(obj), XBPS_PKGINDEX)) { xbps_clean_pkg_depslist(); prop_object_iterator_release(iter); diff --git a/lib/install.c b/lib/install.c index b4d31e8b25a..0d0bc2c7ede 100644 --- a/lib/install.c +++ b/lib/install.c @@ -45,7 +45,7 @@ xbps_install_binary_pkg_from_repolist(prop_object_t obj, void *arg, * Get the dictionary from a repository's index file. */ memset(plist, 0, sizeof(&plist)); - if (!xbps_append_full_path(plist, + if (!xbps_append_full_path(false, plist, prop_string_cstring_nocopy(obj), XBPS_PKGINDEX)) return EINVAL; @@ -125,7 +125,7 @@ xbps_install_binary_pkg(const char *pkgname, const char *destdir) * Get the dictionary with the list of registered * repositories. */ - if (!xbps_append_full_path(plist, NULL, XBPS_REPOLIST)) + if (!xbps_append_full_path(true, plist, NULL, XBPS_REPOLIST)) return EINVAL; repolistd = prop_dictionary_internalize_from_file(plist); @@ -170,7 +170,7 @@ xbps_register_pkg(const char *pkgname, const char *version, const char *desc) assert(version != NULL); assert(desc != NULL); - if (!xbps_append_full_path(plist, NULL, XBPS_REGPKGDB)) + if (!xbps_append_full_path(true, plist, NULL, XBPS_REGPKGDB)) return EINVAL; dict = prop_dictionary_internalize_from_file(plist); @@ -278,7 +278,7 @@ xbps_unpack_binary_pkg(prop_dictionary_t repo, prop_dictionary_t pkg, filename = prop_dictionary_get(pkg, "filename"); repoloc = prop_dictionary_get(repo, "location-local"); - if (!xbps_append_full_path(binfile, + if (!xbps_append_full_path(false, binfile, prop_string_cstring_nocopy(repoloc), prop_string_cstring_nocopy(filename))) return EINVAL; diff --git a/lib/plist.c b/lib/plist.c index b42ee1c5797..c453011af13 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -275,7 +275,7 @@ xbps_register_repository(const char *uri) assert(uri != NULL); - if (!xbps_append_full_path(plist, NULL, XBPS_REPOLIST)) { + if (!xbps_append_full_path(true, plist, NULL, XBPS_REPOLIST)) { errno = EINVAL; return false; } @@ -354,7 +354,7 @@ xbps_unregister_repository(const char *uri) assert(uri != NULL); - if (!xbps_append_full_path(plist, NULL, XBPS_REPOLIST)) { + if (!xbps_append_full_path(true, plist, NULL, XBPS_REPOLIST)) { errno = EINVAL; return false; } @@ -517,7 +517,7 @@ xbps_search_string_in_pkgs(prop_object_t obj, void *arg, bool *loop_done) repofile = prop_string_cstring_nocopy(obj); assert(repofile != NULL); - if (!xbps_append_full_path(plist, repofile, XBPS_PKGINDEX)) + if (!xbps_append_full_path(false, plist, repofile, XBPS_PKGINDEX)) return EINVAL; dict = prop_dictionary_internalize_from_file(plist); @@ -546,7 +546,7 @@ xbps_show_pkg_info_from_repolist(prop_object_t obj, void *arg, bool *loop_done) repofile = prop_string_cstring_nocopy(obj); /* Get string for pkg-index.plist with full path. */ - if (!xbps_append_full_path(plist, repofile, XBPS_PKGINDEX)) + if (!xbps_append_full_path(false, plist, repofile, XBPS_PKGINDEX)) return EINVAL; dict = prop_dictionary_internalize_from_file(plist); diff --git a/lib/util.c b/lib/util.c index 5051a332cb0..9527f4b5ce9 100644 --- a/lib/util.c +++ b/lib/util.c @@ -32,6 +32,8 @@ #include +static const char *rootdir; + const char * xbps_get_pkg_version(const char *pkg) { @@ -80,34 +82,40 @@ xbps_pkg_has_rundeps(prop_dictionary_t pkg) return false; } -bool -xbps_append_full_path(char *buf, const char *root, const char *plistf) +void +xbps_set_rootdir(const char *dir) { - const char *env, *tmp; - size_t len = 0; + assert(dir != NULL); + rootdir = dir; +} + +bool +xbps_append_full_path(bool use_rootdir, char *buf, const char *basedir, + const char *plistf) +{ + const char *env; assert(buf != NULL); assert(plistf != NULL); - if (root) - env = root; - else { - env = getenv("XBPS_META_PATH"); - if (env == NULL) - env = XBPS_META_PATH; - } + if (basedir) + env = basedir; + else + env = XBPS_META_PATH; - tmp = strncpy(buf, env, PATH_MAX - 1); - if (sizeof(*tmp) >= PATH_MAX) { - errno = ENOSPC; - return false; + if (rootdir && use_rootdir) { + if (snprintf(buf, PATH_MAX - 1, "%s/%s/%s", + rootdir, env, plistf) < 0) { + errno = ENOSPC; + return false; + } + } else { + if (snprintf(buf, PATH_MAX - 1, "%s/%s", + env, plistf) < 0) { + errno = ENOSPC; + return false; + } } - len = strlen(buf); - buf[len + 1] = '\0'; - if (buf[len - 2] != '/') - strncat(buf, "/", 1); - strncat(buf, plistf, sizeof(buf) - strlen(buf) - 1); - return true; }