From: Michael Tremer Date: Sun, 21 Mar 2021 13:09:20 +0000 (+0000) Subject: pakfire: Make passing path optional X-Git-Tag: 0.9.28~1285^2~500 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e75d1e3c2ff4a9df3587d5e65a933921417e5e35;p=pakfire.git pakfire: Make passing path optional This will automatically allocate a directory which will be used to create a temporary pakfire environment Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index 34f8f8593..13b83a24c 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -53,7 +53,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { const char* arch = NULL; int offline = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|zp", kwlist, &path, &arch, &offline)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzp", kwlist, &path, &arch, &offline)) return -1; // Create a new Pakfire instance @@ -65,12 +65,6 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { PyErr_SetString(PyExc_ValueError, "Invalid architecture or path"); break; - // path does not exist - case ENOENT: - PyErr_Format(PyExc_FileNotFoundError, - "%s does not exist or is not a directory", path); - break; - // Anything else default: PyErr_SetFromErrno(PyExc_OSError); diff --git a/src/libpakfire/include/pakfire/util.h b/src/libpakfire/include/pakfire/util.h index d63f47cc5..531032d14 100644 --- a/src/libpakfire/include/pakfire/util.h +++ b/src/libpakfire/include/pakfire/util.h @@ -67,6 +67,8 @@ time_t pakfire_path_age(const char* path); char* pakfire_hexlify(const char* digest, const size_t length); FILE* pakfire_mktemp(char* path); +char* pakfire_mkdtemp(char* path); +int pakfire_rmtree(const char* path, int flags); // JSON Stuff diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 5c27032ce..9f15401a0 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include @@ -68,6 +67,8 @@ struct _Pakfire { int activated; int nrefs; + + int destroy_on_free; }; static int log_priority(const char* priority) { @@ -137,6 +138,12 @@ ERROR: static void pakfire_free(Pakfire pakfire) { DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire); + if (pakfire->destroy_on_free) { + DEBUG(pakfire, "Destroying %s\n", pakfire->path); + + pakfire_rmtree(pakfire->path, 0); + } + pakfire_repo_free_all(pakfire); if (pakfire->pool) @@ -167,7 +174,8 @@ static int pakfire_safety_checks(Pakfire pakfire) { } PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char* arch) { - int r; + char tempdir[PATH_MAX] = PAKFIRE_PRIVATE_DIR "/tmp/XXXXXX"; + int r = 1; // Default to the native architecture if (!arch) @@ -180,17 +188,11 @@ PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char } // Path must be absolute - if (!pakfire_string_startswith(path, "/")) { + if (path && !pakfire_string_startswith(path, "/")) { errno = EINVAL; return 1; } - // Check if path exists - if (!pakfire_path_isdir(path)) { - errno = ENOENT; - return 1; - } - // Check if we are running as root uid_t uid = getuid(); if (uid != 0) { @@ -204,6 +206,16 @@ PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char p->nrefs = 1; + // Generate a random path if none is set + if (!path) { + path = pakfire_mkdtemp(tempdir); + if (!path) + goto ERROR; + + // Destroy everything when done + p->destroy_on_free = 1; + } + // Set path snprintf(p->path, sizeof(p->path) - 1, "%s", path); @@ -709,23 +721,13 @@ int pakfire_make_cache_path(Pakfire pakfire, char* path, size_t length, return 0; } -static int _unlink(const char* path, const struct stat* stat, int typeflag, struct FTW* ftwbuf) { - return remove(path); -} - PAKFIRE_EXPORT int pakfire_cache_destroy(Pakfire pakfire, const char* path) { char cache_path[PATH_MAX]; pakfire_make_cache_path(pakfire, cache_path, sizeof(cache_path) - 1, "%s", path); // Completely delete the tree of files - int r = nftw(cache_path, _unlink, 64, FTW_DEPTH|FTW_PHYS); - - // It is okay if the path doesn't exist - if (r < 0 && errno == ENOENT) - r = 0; - - return r; + return pakfire_rmtree(cache_path, 0); } PAKFIRE_EXPORT pakfire_log_function_t pakfire_log_get_function(Pakfire pakfire) { diff --git a/src/libpakfire/util.c b/src/libpakfire/util.c index 28f5dad52..ec6ea4879 100644 --- a/src/libpakfire/util.c +++ b/src/libpakfire/util.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -561,6 +562,28 @@ FILE* pakfire_mktemp(char* path) { return fdopen(fd, "w+"); } +char* pakfire_mkdtemp(char* path) { + int r = pakfire_mkparentdir(path); + if (r) + return NULL; + + return mkdtemp(path); +} + +static int _unlink(const char* path, const struct stat* stat, int typeflag, struct FTW* ftwbuf) { + return remove(path); +} + +int pakfire_rmtree(const char* path, int flags) { + int r = nftw(path, _unlink, 64, flags|FTW_DEPTH|FTW_PHYS); + + // Ignore if path didn't exist + if (r < 0 && errno == ENOENT) + r = 0; + + return r; +} + // JSON Stuff static struct json_object* pakfire_json_parse(Pakfire pakfire, FILE* f) { diff --git a/src/pakfire/cli.py b/src/pakfire/cli.py index fa469bd72..ef7163ca8 100644 --- a/src/pakfire/cli.py +++ b/src/pakfire/cli.py @@ -44,6 +44,8 @@ from .constants import * from .i18n import _ class Cli(object): + default_path = "/" + def __init__(self): self.ui = ui.cli.CliUI() @@ -188,7 +190,10 @@ class Cli(object): help=_("Run pakfire in offline mode.")) def pakfire(self, ns): - p = base.Pakfire(path=ns.root, offline=ns.offline) + p = base.Pakfire( + path=ns.root if "root" in ns else self.default_path, + offline=ns.offline, + ) # Disable repositories. for repo_name in ns.disable_repo: @@ -381,6 +386,8 @@ class Cli(object): class CliBuilder(Cli): + default_path = None + def parse_cli(self): parser = argparse.ArgumentParser( description = _("Pakfire builder command line interface"),