From: Michael Tremer Date: Tue, 9 Mar 2021 22:00:02 +0000 (+0000) Subject: dist: Add basic C implementation X-Git-Tag: 0.9.28~1285^2~586 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af41db7e7cca544513c645d8bbf7df9add0cfd39;p=pakfire.git dist: Add basic C implementation Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index d11b72c8e..c9dd32e02 100644 --- a/Makefile.am +++ b/Makefile.am @@ -264,6 +264,7 @@ libpakfire_la_SOURCES = \ src/libpakfire/arch.c \ src/libpakfire/archive.c \ src/libpakfire/db.c \ + src/libpakfire/dist.c \ src/libpakfire/errno.c \ src/libpakfire/execute.c \ src/libpakfire/file.c \ @@ -294,6 +295,7 @@ pkginclude_HEADERS += \ src/libpakfire/include/pakfire/archive.h \ src/libpakfire/include/pakfire/constants.h \ src/libpakfire/include/pakfire/db.h \ + src/libpakfire/include/pakfire/dist.h \ src/libpakfire/include/pakfire/errno.h \ src/libpakfire/include/pakfire/execute.h \ src/libpakfire/include/pakfire/file.h \ diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index db2e0761a..638f68c41 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -701,7 +702,29 @@ static PyObject* Pakfire_read_makefile(PakfireObject* self, PyObject* args) { return ret; } +static PyObject* Pakfire_dist(PakfireObject* self, PyObject* args) { + const char* path = NULL; + const char* target = NULL; + + if (!PyArg_ParseTuple(args, "s|z", &path, &target)) + return NULL; + + int r = pakfire_dist(self->pakfire, path, target); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + Py_RETURN_NONE; +} + static struct PyMethodDef Pakfire_methods[] = { + { + "dist", + (PyCFunction)Pakfire_dist, + METH_VARARGS, + NULL + }, { "execute", (PyCFunction)Pakfire_execute, diff --git a/src/libpakfire/dist.c b/src/libpakfire/dist.c new file mode 100644 index 000000000..328ed52b2 --- /dev/null +++ b/src/libpakfire/dist.c @@ -0,0 +1,128 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2021 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +PAKFIRE_EXPORT int pakfire_dist(Pakfire pakfire, const char* path, const char* target) { + PakfireParser makefile; + struct pakfire_parser_error* error = NULL; + + struct pakfire_packager* packager = NULL; + PakfirePackage pkg = NULL; + + char* filename = NULL; + char tempfile[PATH_MAX] = ""; + + // Open the target directory + DIR* d = opendir(target); + if (!d) + return 1; + + int dfd = dirfd(d); + + // Load makefile + int r = pakfire_read_makefile(&makefile, pakfire, path, &error); + if (r) { + if (error) + pakfire_parser_error_unref(error); + + return r; + } + + PakfireRepo repo = pakfire_repo_create(pakfire, "dummy"); + if (!repo) + goto ERROR; + + // Get the package object + r = pakfire_parser_create_package(makefile, &pkg, repo, NULL); + if (r) + goto ERROR; + + // Set architecture to source + pakfire_package_set_arch(pkg, "src"); + + // Create a packager + r = pakfire_packager_create(&packager, pkg); + if (r) + goto ERROR; + + // Add the makefile + r = pakfire_packager_add(packager, path); + if (r) + goto ERROR; + + snprintf(tempfile, PATH_MAX - 1, "%s/.pakfire-dist.XXXXXX", target); + + // Create a temporary result file + int fd = mkostemp(tempfile, O_CLOEXEC); + if (fd < 0) + goto ERROR; + + // Re-open as file handle + FILE* f = fdopen(fd, "w"); + + // Write the finished package + filename = pakfire_packager_finish(packager, f); + if (!filename) { + ERROR(pakfire, "pakfire_packager_finish() failed: %s\n", strerror(errno)); + goto ERROR; + } + + // Close the file + fclose(f); + + // Move the temporary file to destination + r = renameat(AT_FDCWD, tempfile, dfd, filename); + if (r) + goto ERROR; + +ERROR: + // Remove the temporary file + if (*tempfile) + unlink(tempfile); + + if (filename) + free(filename); + closedir(d); + + if (packager) + pakfire_packager_unref(packager); + if (pkg) + pakfire_package_unref(pkg); + if (repo) + pakfire_repo_unref(repo); + pakfire_parser_unref(makefile); + + return r; +} diff --git a/src/libpakfire/include/pakfire/dist.h b/src/libpakfire/include/pakfire/dist.h new file mode 100644 index 000000000..c0582ac00 --- /dev/null +++ b/src/libpakfire/include/pakfire/dist.h @@ -0,0 +1,28 @@ +/*############################################################################# +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2021 Pakfire development team # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +#############################################################################*/ + +#ifndef PAKFIRE_DIST_H +#define PAKFIRE_DIST_H + +#include + +int pakfire_dist(Pakfire pakfire, const char* path, const char* target); + +#endif /* PAKFIRE_DIST_H */ diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index cbac55353..99d05e9c3 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -91,6 +91,9 @@ global: pakfire_db_remove_package; pakfire_db_unref; + # dist + pakfire_dist; + # file pakfire_file_cmp; pakfire_file_create; diff --git a/src/pakfire/base.py b/src/pakfire/base.py index 02f191804..f9c495d57 100644 --- a/src/pakfire/base.py +++ b/src/pakfire/base.py @@ -149,11 +149,6 @@ class Pakfire(_pakfire.Pakfire): for repo in self.repos: repo.clean() - def dist(self, pkg, resultdir): - pkg = packages.Makefile(self, pkg) - - return pkg.dist(resultdir=resultdir) - class PakfireContext(object): """ diff --git a/src/pakfire/cli.py b/src/pakfire/cli.py index c887e2ff3..e9d75c929 100644 --- a/src/pakfire/cli.py +++ b/src/pakfire/cli.py @@ -518,7 +518,7 @@ class CliBuilder(Cli): p = self.pakfire(ns) for pkg in pkgs: - p.dist(pkg, resultdir=resultdir) + p.dist(pkg, resultdir) class CliClient(Cli):