SUBDIRS = . po
+LIBPAKFIRE_CURRENT=0
+LIBPAKFIRE_REVISION=0
+LIBPAKFIRE_AGE=0
+
libexecdir = $(libdir)/pakfire
pythondir = $(pyexecdir)
lib_LTLIBRARIES =
libexec_PROGRAMS =
pkgpyexec_LTLIBRARIES =
+pkginclude_HEADERS =
DISTCHECK_CONFIGURE_FLAGS = \
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
# ------------------------------------------------------------------------------
+lib_LTLIBRARIES += \
+ libpakfire.la
+
+libpakfire_la_SOURCES = \
+ src/libpakfire/archive.c \
+ src/libpakfire/cache.c \
+ src/libpakfire/errno.c \
+ src/libpakfire/file.c \
+ src/libpakfire/filter.c \
+ src/libpakfire/package.c \
+ src/libpakfire/packagelist.c \
+ src/libpakfire/pool.c \
+ src/libpakfire/relation.c \
+ src/libpakfire/relationlist.c \
+ src/libpakfire/repo.c \
+ src/libpakfire/repocache.c \
+ src/libpakfire/request.c \
+ src/libpakfire/selector.c \
+ src/libpakfire/solver.c \
+ src/libpakfire/step.c \
+ src/libpakfire/transaction.c \
+ src/libpakfire/util.c
+
+pkginclude_HEADERS += \
+ src/libpakfire/include/pakfire/archive.h \
+ src/libpakfire/include/pakfire/cache.h \
+ src/libpakfire/include/pakfire/constants.h \
+ src/libpakfire/include/pakfire/errno.h \
+ src/libpakfire/include/pakfire/file.h \
+ src/libpakfire/include/pakfire/filter.h \
+ src/libpakfire/include/pakfire/i18n.h \
+ src/libpakfire/include/pakfire/package.h \
+ src/libpakfire/include/pakfire/packagecache.h \
+ src/libpakfire/include/pakfire/packagelist.h \
+ src/libpakfire/include/pakfire/pool.h \
+ src/libpakfire/include/pakfire/relation.h \
+ src/libpakfire/include/pakfire/relationlist.h \
+ src/libpakfire/include/pakfire/repo.h \
+ src/libpakfire/include/pakfire/repocache.h \
+ src/libpakfire/include/pakfire/request.h \
+ src/libpakfire/include/pakfire/selector.h \
+ src/libpakfire/include/pakfire/solver.h \
+ src/libpakfire/include/pakfire/step.h \
+ src/libpakfire/include/pakfire/transaction.h \
+ src/libpakfire/include/pakfire/types.h \
+ src/libpakfire/include/pakfire/util.h
+
+libpakfire_la_CFLAGS = \
+ $(AM_CFLAGS)
+
+libpakfire_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -I$(top_srcdir)/src/libpakfire/include \
+ -include $(top_builddir)/config.h \
+ -DPAKFIRE_PRIVATE
+
+libpakfire_la_LDFLAGS = \
+ $(AM_LDFLAGS) \
+ -version-info $(LIBPAKFIRE_CURRENT):$(LIBPAKFIRE_REVISION):$(LIBPAKFIRE_AGE) \
+ -Wl,--version-script=$(top_srcdir)/src/libpakfire/libpakfire.sym
+
+libpakfire_la_LIBADD = \
+ $(ARCHIVE_LIBS) \
+ $(SOLV_LIBS)
+
+EXTRA_DIST += \
+ src/libpakfire/libpakfire.sym
+
+# ------------------------------------------------------------------------------
+
lib_LTLIBRARIES += \
libpakfire_preload.la
# Python
AM_PATH_PYTHON([3.4])
+AC_C_CONST
+AC_CHECK_LIB([m], [round])
+
+AC_CHECK_HEADERS([ \
+ assert.h \
+ math.h \
+ stdlib.h \
+ string.h \
+ sys/stat.h \
+ unistd.h
+])
+
+AC_CHECK_FUNCS([ \
+ assert \
+ strcmp \
+ strdup
+])
+
save_LIBS="$LIBS"
# libdl
AC_SUBST(SOLV_LIBS)
LIBS="$save_LIBS"
+PKG_CHECK_MODULES([ARCHIVE], [libarchive])
PKG_CHECK_MODULES([PYTHON_DEVEL], [python-${PYTHON_VERSION}])
PKG_CHECK_MODULES([LZMA], [liblzma])
+src/libpakfire/package.c
+
src/_pakfire/problem.c
src/_pakfire/solution.c
src/pakfire/base.py
src/pakfire/builder.py
src/pakfire/cli.py
+src/pakfire/client.py
src/pakfire/compress.py
src/pakfire/config.py
src/pakfire/daemon.py
src/pakfire/downloader.py
src/pakfire/errors.py
+src/pakfire/http.py
src/pakfire/i18n.py
src/pakfire/keyring.py
src/pakfire/packages/base.py
src/pakfire/shell.py
src/pakfire/system.py
src/pakfire/transaction.py
+src/pakfire/ui/progressbar.py
src/pakfire/util.py
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+// libarchive
+#include <archive.h>
+#include <archive_entry.h>
+
+#include <pakfire/archive.h>
+#include <pakfire/errno.h>
+#include <pakfire/file.h>
+#include <pakfire/util.h>
+
+static void configure_archive(struct archive* a) {
+ archive_read_support_filter_all(a);
+ archive_read_support_format_all(a);
+}
+
+static int archive_open(PakfireArchive archive, struct archive** a) {
+ *a = archive_read_new();
+ configure_archive(*a);
+
+ if (archive_read_open_filename(*a, archive->path, PAKFIRE_ARCHIVE_BLOCKSIZE) == ARCHIVE_OK) {
+ return 0;
+ }
+
+ archive_read_free(*a);
+ *a = NULL;
+
+ return -1;
+}
+
+static void archive_close(struct archive* a) {
+ archive_read_close(a);
+ archive_read_free(a);
+}
+
+static int archive_read(struct archive* a, void** data, size_t* data_size) {
+ *data = NULL;
+ *data_size = 0;
+
+ for (;;) {
+ *data = pakfire_realloc(*data, *data_size + PAKFIRE_ARCHIVE_BLOCKSIZE);
+
+ ssize_t size = archive_read_data(a, *data + *data_size,
+ PAKFIRE_ARCHIVE_BLOCKSIZE);
+
+ if (size == 0)
+ break;
+
+ if (size < 0) {
+ pakfire_free(*data);
+ *data = NULL;
+
+ return 1;
+ }
+
+ *data_size += size;
+ }
+
+ return 0;
+}
+
+static int find_archive_entry(struct archive_entry** entry, struct archive* a, const char* filename) {
+ int r;
+
+ while ((r = archive_read_next_header(a, entry)) == ARCHIVE_OK) {
+ const char* entry_name = archive_entry_pathname(*entry);
+
+ if (strcmp(entry_name, filename) == 0) {
+ return 0;
+ }
+ }
+
+ *entry = NULL;
+ return 1;
+}
+
+static ssize_t payload_archive_read(struct archive* a, void* client_data, const void** buf) {
+ struct payload_archive_data* data = client_data;
+ *buf = data->buffer;
+
+ return archive_read_data(data->archive, data->buffer, sizeof(data->buffer));
+}
+
+static int payload_archive_close(struct archive* a, void* client_data) {
+ struct payload_archive_data* data = client_data;
+
+ pakfire_free(data);
+
+ return ARCHIVE_OK;
+}
+
+static int payload_archive_open(struct archive** a, struct archive* source_archive) {
+ *a = archive_read_new();
+ configure_archive(*a);
+
+ struct payload_archive_data* data = pakfire_calloc(1, sizeof(*data));
+ data->archive = source_archive;
+
+ archive_read_set_callback_data(*a, data);
+ archive_read_set_read_callback(*a, payload_archive_read);
+ archive_read_set_close_callback(*a, payload_archive_close);
+
+ return archive_read_open1(*a);
+}
+
+PakfireArchive pakfire_archive_create() {
+ PakfireArchive archive = pakfire_calloc(1, sizeof(*archive));
+ if (archive) {
+ archive->format = -1;
+ }
+
+ return archive;
+}
+
+void pakfire_archive_free(PakfireArchive archive) {
+ if (archive->path)
+ pakfire_free(archive->path);
+
+ pakfire_free(archive);
+}
+
+static int pakfire_archive_parse_entry_format(PakfireArchive archive,
+ struct archive* a, struct archive_entry* e) {
+ char format[PAKFIRE_ARCHIVE_FORMAT_SIZE + 1];
+ format[PAKFIRE_ARCHIVE_FORMAT_SIZE] = '\0';
+
+ archive_read_data(a, &format, PAKFIRE_ARCHIVE_FORMAT_SIZE);
+ archive->format = atoi(format);
+
+ return (archive->format < 0);
+}
+
+static int pakfire_archive_parse_entry_metadata(PakfireArchive archive,
+ struct archive* a, struct archive_entry* e) {
+ void* data;
+ size_t data_size;
+
+ int r = archive_read(a, &data, &data_size);
+ if (r) {
+ return 1;
+ }
+
+ #warning actually parse this
+
+ pakfire_free(data);
+
+ return 0;
+}
+
+static int pakfire_archive_parse_entry_filelist(PakfireArchive archive,
+ struct archive* a, struct archive_entry* e) {
+ char* data;
+ size_t data_size;
+
+ int r = archive_read(a, (void**)&data, &data_size);
+ if (r) {
+ return 1;
+ }
+
+ // Terminate string.
+ data[data_size] = '\0';
+
+ if (data_size > 0) {
+ archive->filelist = pakfire_file_parse_from_file(data, archive->format);
+ }
+
+ pakfire_free(data);
+
+ return 0;
+}
+
+static int pakfire_archive_read_metadata(PakfireArchive archive, struct archive* a) {
+ int ret;
+
+ struct archive_entry* entry;
+ while ((ret = archive_read_next_header(a, &entry)) == ARCHIVE_OK) {
+ const char* entry_name = archive_entry_pathname(entry);
+
+ /* The first file in a pakfire package file must be
+ * the pakfire-format file, so we know with what version of
+ * the package format we are dealing with.
+ */
+ if (archive->format < 0) {
+ if (strcmp(PAKFIRE_ARCHIVE_FN_FORMAT, entry_name) == 0) {
+ ret = pakfire_archive_parse_entry_format(archive, a, entry);
+ if (ret)
+ return PAKFIRE_E_PKG_INVALID;
+
+ } else {
+ return PAKFIRE_E_PKG_INVALID;
+ }
+
+ // If the format is set, we can go on...
+ } else {
+ // Parse the metadata
+ if (strcmp(PAKFIRE_ARCHIVE_FN_METADATA, entry_name) == 0) {
+ ret = pakfire_archive_parse_entry_metadata(archive, a, entry);
+ if (ret)
+ return PAKFIRE_E_PKG_INVALID;
+
+ // Parse the filelist
+ } else if (strcmp(PAKFIRE_ARCHIVE_FN_FILELIST, entry_name) == 0) {
+ ret = pakfire_archive_parse_entry_filelist(archive, a, entry);
+ if (ret)
+ return PAKFIRE_E_PKG_INVALID;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int archive_copy_data(struct archive* in, struct archive* out) {
+ int r;
+ const void* buff;
+
+ size_t size;
+ off_t offset;
+
+ for (;;) {
+ r = archive_read_data_block(in, &buff, &size, &offset);
+ if (r == ARCHIVE_EOF)
+ break;
+
+ if (r != ARCHIVE_OK)
+ return r;
+
+ r = archive_write_data_block(out, buff, size, offset);
+ if (r != ARCHIVE_OK)
+ return r;
+ }
+
+ return 0;
+}
+
+static int archive_extract(struct archive* a, const char* prefix) {
+ struct archive_entry* entry;
+ int r;
+
+ // Unpack to the root filesystem if no prefix is given.
+ if (!prefix)
+ prefix = "/";
+
+ struct archive* ext = archive_write_disk_new();
+
+ // Set flags for extracting contents.
+ int flags = 0;
+ flags |= ARCHIVE_EXTRACT_ACL;
+ flags |= ARCHIVE_EXTRACT_FFLAGS;
+ flags |= ARCHIVE_EXTRACT_OWNER;
+ flags |= ARCHIVE_EXTRACT_PERM;
+ flags |= ARCHIVE_EXTRACT_SPARSE;
+ flags |= ARCHIVE_EXTRACT_TIME;
+ flags |= ARCHIVE_EXTRACT_UNLINK;
+ flags |= ARCHIVE_EXTRACT_XATTR;
+
+ archive_write_disk_set_options(ext, flags);
+ archive_write_disk_set_standard_lookup(ext);
+
+ char* pathname = NULL;
+ for (;;) {
+ r = archive_read_next_header(a, &entry);
+
+ // Reached the end of the archive.
+ if (r == ARCHIVE_EOF)
+ break;
+
+ // Prepend the prefix to the path the file is extracted to.
+ if (prefix) {
+ const char* archive_pathname = archive_entry_pathname(entry);
+ pathname = pakfire_path_join(prefix, archive_pathname);
+
+ archive_entry_set_pathname(entry, pathname);
+ }
+
+ r = archive_write_header(ext, entry);
+ if (r != ARCHIVE_OK)
+ goto out;
+
+ size_t size = archive_entry_size(entry);
+ if (size > 0) {
+ r = archive_copy_data(a, ext);
+
+ if (r != ARCHIVE_OK)
+ goto out;
+ }
+
+#warning need to handle extended attributes
+#if 0
+ const char* name;
+ const void* data;
+ size_t size;
+
+ while (archive_entry_xattr_next(entry, &name, &data, &size) == ARCHIVE_OK) {
+ printf("name=%s\n", name);
+ }
+#endif
+
+ r = archive_write_finish_entry(ext);
+
+ pakfire_free(pathname);
+ }
+
+out:
+ archive_write_close(ext);
+ archive_write_free(ext);
+
+ return r;
+}
+
+
+PakfireArchive pakfire_archive_open(const char* path) {
+ PakfireArchive archive = pakfire_archive_create();
+ archive->path = pakfire_strdup(path);
+
+ // Open the archive file for reading.
+ struct archive* a;
+ int r = archive_open(archive, &a);
+ if (r) {
+ pakfire_errno = r;
+ goto error;
+ }
+
+ // Parse all entries in the archive.
+ r = pakfire_archive_read_metadata(archive, a);
+ if (r) {
+ pakfire_errno = r;
+ return NULL;
+ }
+
+ return archive;
+
+error:
+ if (a)
+ archive_read_free(a);
+
+ pakfire_archive_free(archive);
+
+ return NULL;
+}
+
+static struct archive* archive_open_payload(struct archive* a) {
+ struct archive_entry* entry;
+ int r;
+
+ r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_PAYLOAD);
+ if (r) {
+ pakfire_errno = r;
+ return NULL;
+ }
+
+ struct archive* payload_archive;
+ r = payload_archive_open(&payload_archive, a);
+ if (r) {
+ pakfire_errno = r;
+ return NULL;
+ }
+
+ return payload_archive;
+}
+
+int pakfire_archive_read(PakfireArchive archive, const char* filename,
+ void** data, size_t* data_size, int flags) {
+ struct archive* a;
+ struct archive* pa = NULL;
+ struct archive_entry* entry;
+
+ int r = archive_open(archive, &a);
+ if (r) {
+ pakfire_errno = r;
+ goto out;
+ }
+
+ int use_payload = (flags & PAKFIRE_ARCHIVE_USE_PAYLOAD);
+
+ if (use_payload) {
+ pa = archive_open_payload(a);
+
+ // Strip leading / from filenames, because the payload does
+ // not have leading slashes.
+ if (*filename == '/')
+ filename++;
+ }
+
+ r = find_archive_entry(&entry, use_payload ? pa : a, filename);
+ if (r) {
+ goto out;
+ }
+
+ r = archive_read(use_payload ? pa : a, data, data_size);
+
+out:
+ if (pa)
+ archive_close(pa);
+
+ archive_close(a);
+
+ return r;
+}
+
+int pakfire_archive_extract(PakfireArchive archive, const char* prefix, int flags) {
+ struct archive* a;
+ struct archive* pa = NULL;
+
+ int r = archive_open(archive, &a);
+ if (r) {
+ pakfire_errno = r;
+ return 1;
+ }
+
+ int use_payload = (flags & PAKFIRE_ARCHIVE_USE_PAYLOAD);
+
+ if (use_payload)
+ pa = archive_open_payload(a);
+
+ r = archive_extract(use_payload ? pa : a, prefix);
+
+ if (pa)
+ archive_close(pa);
+
+ archive_close(a);
+
+ return r;
+}
+
+const char* pakfire_archive_get_path(PakfireArchive archive) {
+ return archive->path;
+}
+
+unsigned int pakfire_archive_get_format(PakfireArchive archive) {
+ return archive->format;
+}
+
+PakfireFile pakfire_archive_get_filelist(PakfireArchive archive) {
+ return archive->filelist;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+#include <errno.h>
+#include <libgen.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <pakfire/cache.h>
+#include <pakfire/constants.h>
+#include <pakfire/package.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireCache pakfire_cache_create(PakfirePool pool, const char* path) {
+ PakfireCache cache = pakfire_calloc(1, sizeof(*cache));
+
+ cache->pool = pool;
+ cache->path = pakfire_strdup(path);
+
+ return cache;
+}
+
+void pakfire_cache_free(PakfireCache cache) {
+ pakfire_free(cache->path);
+ pakfire_free(cache);
+}
+
+const char* pakfire_cache_get_path(PakfireCache cache) {
+ return cache->path;
+}
+
+char* pakfire_cache_get_full_path(PakfireCache cache, const char* path) {
+ const char* cache_path = pakfire_cache_get_path(cache);
+
+ return pakfire_path_join(cache_path, path);
+}
+
+static int pakfire_cache_stat(PakfireCache cache, const char* filename, struct stat* buf) {
+ char* cache_filename = pakfire_cache_get_full_path(cache, filename);
+
+ int r = stat(cache_filename, buf);
+ pakfire_free(cache_filename);
+
+ return r;
+}
+
+int pakfire_cache_has_file(PakfireCache cache, const char* filename) {
+ struct stat buf;
+ int r = pakfire_cache_stat(cache, filename, &buf);
+
+ // Just check if stat() was sucessful.
+ return (r == 0);
+}
+
+char* pakfire_cache_get_package_path(PakfireCache cache, PakfirePackage pkg) {
+ char buffer[STRING_SIZE] = "";
+
+ const char* filename = pakfire_package_get_filename(pkg);
+ const char* checksum = pakfire_package_get_checksum(pkg);
+
+ if (strlen(checksum) < 3)
+ return NULL;
+
+ snprintf(buffer, sizeof(buffer), "%c%c/%s/%s", checksum[0], checksum[1],
+ checksum + 2, filename);
+
+ return pakfire_strdup(buffer);
+}
+
+int pakfire_cache_has_package(PakfireCache cache, PakfirePackage pkg) {
+ char* filename = pakfire_cache_get_package_path(cache, pkg);
+
+ int r = pakfire_cache_has_file(cache, filename);
+ pakfire_free(filename);
+
+ return r;
+}
+
+int pakfire_cache_age(PakfireCache cache, const char* filename) {
+ struct stat buf;
+ int r = pakfire_cache_stat(cache, filename, &buf);
+
+ if (r == 0) {
+ // Get timestamp.
+ time_t now = time(NULL);
+
+ // Calculate the difference since the file has been created and now.
+ time_t age = now - buf.st_ctime;
+
+ return (int)age;
+ }
+
+ return -1;
+}
+
+static int pakfire_cache_mkdir(PakfireCache cache, const char* path, mode_t mode) {
+ int r = 0;
+
+ if ((strcmp(path, "/") == 0) || (strcmp(path, ".") == 0)) {
+ return 0;
+ }
+
+ // If parent does not exists, we try to create it.
+ char* parent_path = pakfire_dirname(path);
+ r = access(parent_path, F_OK);
+ if (r) {
+ r = pakfire_cache_mkdir(cache, parent_path, mode);
+ }
+ pakfire_free(parent_path);
+
+ if (!r) {
+ // Finally, create the directory we want.
+ r = mkdir(path, mode);
+
+ if (r) {
+ switch (errno) {
+ // If the directory already exists, this is fine.
+ case EEXIST:
+ r = 0;
+ break;
+ }
+ }
+ }
+
+ return r;
+}
+
+FILE* pakfire_cache_open(PakfireCache cache, const char* filename, const char* flags) {
+ assert(filename);
+
+ char* cache_filename = pakfire_cache_get_full_path(cache, filename);
+
+ char* cache_dirname = pakfire_dirname(cache_filename);
+ pakfire_cache_mkdir(cache, cache_dirname, S_IRUSR|S_IWUSR|S_IXUSR);
+
+ FILE* fp = fopen(cache_filename, flags);
+
+ pakfire_free(cache_filename);
+ pakfire_free(cache_dirname);
+
+ return fp;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include "errno.h"
+
+__thread int pakfire_errno = 0;
+
+int pakfire_get_errno(void) {
+ return pakfire_errno;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <tar.h>
+#include <time.h>
+
+#include <pakfire/constants.h>
+#include <pakfire/file.h>
+#include <pakfire/util.h>
+
+PakfireFile pakfire_file_create() {
+ PakfireFile file = pakfire_calloc(1, sizeof(*file));
+ if (file) {
+ file->name = NULL;
+
+ file->prev = NULL;
+ file->next = NULL;
+ }
+
+ return file;
+}
+
+void pakfire_file_free(PakfireFile file) {
+ if (file->name)
+ pakfire_free(file->name);
+
+ if (file->user)
+ pakfire_free(file->user);
+ if (file->group)
+ pakfire_free(file->group);
+
+ // Update pointers in the previous and next element in the list.
+ if (file->next)
+ file->next->prev = NULL;
+ if (file->prev)
+ file->prev->next = NULL;
+
+ pakfire_free(file);
+}
+
+void pakfire_file_free_all(PakfireFile file) {
+ file = pakfire_file_get_first(file);
+
+ while (file) {
+ PakfireFile next = file->next;
+ pakfire_file_free(file);
+
+ file = next;
+ }
+}
+
+int pakfire_file_cmp(PakfireFile file1, PakfireFile file2) {
+ const char* name1 = pakfire_file_get_name(file1);
+ const char* name2 = pakfire_file_get_name(file2);
+
+ return strcmp(name1, name2);
+}
+
+void pakfire_file_swap(PakfireFile file1, PakfireFile file2) {
+ PakfireFile file_prev = file1->prev;
+ PakfireFile file_next = file2->next;
+
+ if (file_prev)
+ file_prev->next = file2;
+ file2->prev = file_prev;
+
+ if (file_next)
+ file_next->prev = file1;
+ file1->next = file_next;
+
+ file2->next = file1;
+ file1->prev = file2;
+}
+
+PakfireFile pakfire_file_sort(PakfireFile head) {
+ unsigned int count = pakfire_file_count(head);
+
+ for (unsigned int i = 0; i < count; i++) {
+ PakfireFile file = head;
+ PakfireFile next = pakfire_file_get_next(file);
+
+ while (next) {
+ if (pakfire_file_cmp(file, next) > 0) {
+ if (head == file)
+ head = next;
+
+ pakfire_file_swap(file, next);
+ }
+
+ file = next;
+ next = pakfire_file_get_next(file);
+ }
+ }
+
+ return head;
+}
+
+PakfireFile pakfire_file_get_prev(PakfireFile file) {
+ return file->prev;
+}
+
+PakfireFile pakfire_file_get_next(PakfireFile file) {
+ return file->next;
+}
+
+PakfireFile pakfire_file_get_first(PakfireFile file) {
+ if (file->prev)
+ return pakfire_file_get_first(file->prev);
+
+ return file;
+}
+
+PakfireFile pakfire_file_get_last(PakfireFile file) {
+ if (file->next)
+ return pakfire_file_get_last(file->next);
+
+ return file;
+}
+
+static PakfireFile __pakfire_file_append(PakfireFile file, PakfireFile appended_file) {
+ // Get the last file in the queue.
+ file = pakfire_file_get_last(file);
+
+ // Set the links.
+ file->next = appended_file;
+ appended_file->prev = file;
+
+ return appended_file;
+}
+
+PakfireFile pakfire_file_append(PakfireFile file) {
+ // Create a new file object.
+ PakfireFile appended_file = pakfire_file_create();
+
+ return __pakfire_file_append(file, appended_file);
+}
+
+unsigned int pakfire_file_count(PakfireFile file) {
+ unsigned int counter = 0;
+
+ while (file) {
+ file = pakfire_file_get_next(file);
+ ++counter;
+ }
+
+ return counter;
+}
+
+static char pakfire_file_sprintf_type(PakfireFile file) {
+ if (pakfire_file_is_dir(file))
+ return 'd';
+
+ if (pakfire_file_is_symlink(file))
+ return 'l';
+
+ if (pakfire_file_is_char(file))
+ return 'c';
+
+ return '-';
+}
+
+static char* pakfire_file_format_perms(PakfireFile file) {
+ char buffer[11];
+
+ mode_t mode = pakfire_file_get_mode(file);
+
+ buffer[0] = pakfire_file_sprintf_type(file);
+ buffer[1] = (S_IRUSR & mode) ? 'r' : '-';
+ buffer[2] = (S_IWUSR & mode) ? 'w' : '-';
+ buffer[3] = (S_IXUSR & mode) ? 'x' : '-';
+ buffer[4] = (S_IRGRP & mode) ? 'r' : '-';
+ buffer[5] = (S_IWGRP & mode) ? 'w' : '-';
+ buffer[6] = (S_IXGRP & mode) ? 'x' : '-';
+ buffer[7] = (S_IROTH & mode) ? 'r' : '-';
+ buffer[8] = (S_IWOTH & mode) ? 'w' : '-';
+ buffer[9] = (S_IXOTH & mode) ? 'x' : '-';
+ buffer[10] = '\0';
+
+ #warning TODO SUID bits, etc...
+
+ return pakfire_strdup(buffer);
+}
+
+static char* pakfire_file_format_mtime(PakfireFile file) {
+ struct tm* timer = gmtime((time_t *)&file->time);
+
+ char buffer[STRING_SIZE];
+ strftime(buffer, sizeof(buffer), "%d %b %Y %T", timer);
+
+ return pakfire_strdup(buffer);
+}
+
+void pakfire_file_sprintf(PakfireFile file, char* str, size_t len) {
+ const char* name = pakfire_file_get_name(file);
+ ssize_t size = pakfire_file_get_size(file);
+
+ const char* user = pakfire_file_get_user(file);
+ const char* group = pakfire_file_get_group(file);
+
+ char* perms = pakfire_file_format_perms(file);
+ char* mtime = pakfire_file_format_mtime(file);
+
+ snprintf(str, len, "%s %-8s %-8s %8d %s %s", perms, user, group,
+ (int)size, mtime, name);
+
+ pakfire_free(perms);
+ pakfire_free(mtime);
+}
+
+const char* pakfire_file_get_name(PakfireFile file) {
+ return file->name;
+}
+
+void pakfire_file_set_name(PakfireFile file, const char* name) {
+ if (file->name)
+ pakfire_free(file->name);
+
+ if (*name == '/') {
+ file->name = pakfire_strdup(name);
+ } else {
+ asprintf(&file->name, "/%s", name);
+ }
+}
+
+char pakfire_file_get_type(PakfireFile file) {
+ return file->type;
+}
+
+void pakfire_file_set_type(PakfireFile file, char type) {
+ file->type = type;
+}
+
+int pakfire_file_is_file(PakfireFile file) {
+ return (file->type == REGTYPE) || (file->type == AREGTYPE);
+}
+
+int pakfire_file_is_link(PakfireFile file) {
+ return (file->type == LNKTYPE);
+}
+
+int pakfire_file_is_symlink(PakfireFile file) {
+ return (file->type == SYMTYPE);
+}
+
+int pakfire_file_is_char(PakfireFile file) {
+ return (file->type == CHRTYPE);
+}
+
+int pakfire_file_is_block(PakfireFile file) {
+ return (file->type == BLKTYPE);
+}
+
+int pakfire_file_is_dir(PakfireFile file) {
+ return (file->type == DIRTYPE);
+}
+
+ssize_t pakfire_file_get_size(PakfireFile file) {
+ return file->size;
+}
+
+void pakfire_file_set_size(PakfireFile file, ssize_t size) {
+ file->size = size;
+}
+
+const char* pakfire_file_get_user(PakfireFile file) {
+ return file->user;
+}
+
+void pakfire_file_set_user(PakfireFile file, const char* user) {
+ file->user = pakfire_strdup(user);
+}
+
+const char* pakfire_file_get_group(PakfireFile file) {
+ return file->group;
+}
+
+void pakfire_file_set_group(PakfireFile file, const char* group) {
+ file->group = pakfire_strdup(group);
+}
+
+mode_t pakfire_file_get_mode(PakfireFile file) {
+ return file->mode;
+}
+
+void pakfire_file_set_mode(PakfireFile file, mode_t mode) {
+ file->mode = mode;
+}
+
+time_t pakfire_file_get_time(PakfireFile file) {
+ return file->time;
+}
+
+void pakfire_file_set_time(PakfireFile file, time_t time) {
+ file->time = time;
+}
+
+const char* pakfire_file_get_chksum(PakfireFile file) {
+ return file->chksum;
+}
+
+void pakfire_file_set_chksum(PakfireFile file, const char* chksum) {
+ file->chksum = pakfire_strdup(chksum);
+}
+
+static PakfireFile pakfire_file_parse_line(char* line, unsigned int format) {
+ unsigned int i = 0;
+
+ PakfireFile file = pakfire_file_create();
+ ssize_t size;
+ mode_t mode;
+ time_t time;
+
+ unsigned int bytes_read = 0;
+
+ char* word = strtok(line, " ");
+ while (word) {
+ if (format >= 4) {
+ switch (i) {
+ // type
+ case 0:
+ pakfire_file_set_type(file, *word);
+ break;
+
+ // size
+ case 1:
+ size = atoi(word);
+ pakfire_file_set_size(file, size);
+ break;
+
+ // user
+ case 2:
+ pakfire_file_set_user(file, word);
+ break;
+
+ // group
+ case 3:
+ pakfire_file_set_group(file, word);
+ break;
+
+ // mode
+ case 4:
+ mode = atoi(word);
+ pakfire_file_set_mode(file, mode);
+ break;
+
+ // time
+ case 5:
+ time = atoi(word);
+ pakfire_file_set_time(file, time);
+ break;
+
+ // checksum
+ case 6:
+ pakfire_file_set_chksum(file, word);
+ break;
+
+ // name
+ #warning handle filenames with spaces
+ case 8:
+ pakfire_file_set_name(file, line + bytes_read);
+ break;
+ }
+
+ } else if (format >= 3) {
+ switch (i) {
+ // name
+ case 0:
+ pakfire_file_set_name(file, word);
+ break;
+
+ // type
+ case 1:
+ pakfire_file_set_type(file, *word);
+ break;
+
+ // size
+ case 2:
+ size = atoi(word);
+ pakfire_file_set_size(file, size);
+ break;
+
+ // user
+ case 3:
+ pakfire_file_set_user(file, word);
+ break;
+
+ // group
+ case 4:
+ pakfire_file_set_group(file, word);
+ break;
+
+ // mode
+ case 5:
+ mode = atoi(word);
+ pakfire_file_set_mode(file, mode);
+ break;
+
+ // time
+ case 6:
+ time = atoi(word);
+ pakfire_file_set_time(file, time);
+ break;
+
+ // checksum
+ case 7:
+ pakfire_file_set_chksum(file, word);
+ break;
+ }
+ }
+
+ // Count the bytes of the line that have been processed so far
+ // (Skip all padding spaces)
+ bytes_read += strlen(word) + 1;
+ while (*(line + bytes_read) == ' ')
+ bytes_read += 1;
+
+ word = strtok(NULL, " ");
+ ++i;
+ }
+
+ return file;
+}
+
+PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format) {
+ PakfireFile head = NULL;
+
+ char* plist = (char *)list;
+ char line[32 * 1024];
+
+ for (;;) {
+ line[0] = '\0';
+
+ pakfire_sgets(line, sizeof(line), &plist);
+ pakfire_remove_trailing_newline(line);
+
+ if (*line == '\0')
+ break;
+
+ PakfireFile file = pakfire_file_parse_line(line, format);
+
+ if (!file)
+ continue;
+
+ if (head)
+ file = __pakfire_file_append(head, file);
+ else
+ head = file;
+ }
+
+ return head;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <pakfire/file.h>
+#include <pakfire/filelist.h>
+#include <pakfire/util.h>
+
+PakfireFilelist pakfire_filelist_create(PakfirePackage pkg) {
+ PakfireFilelist list = pakfire_calloc(1, sizeof(*list));
+ if (list) {
+ list->pkg = pkg;
+
+ list->first = NULL;
+ list->last = NULL;
+ }
+
+ return list;
+}
+
+void pakfire_filelist_free(PakfireFilelist list) {
+ pakfire_filelist_remove_all();
+ pakfire_free(list);
+}
+
+static void pakfire_filelist_remove_first(PakfireFilelist list) {
+ if (!list->first)
+ return;
+
+ PakfireFile file = list->first;
+
+ list->first = file->next;
+ list->first->prev = NULL;
+
+ pakfire_file_free(file);
+}
+
+void pakfire_filelist_remove_all(PakfireFilelist list) {
+ while (list->first) {
+ pakfire_filelist_remove_first(list);
+ }
+}
+
+void pakfire_filelist_append(PakfireFilelist list, PakfireFile file) {
+ if (list->first && list->last) {
+ list->last->next = file;
+ list->last = file;
+ } else {
+ list->first = file;
+ list->last = file;
+ }
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <pakfire/filter.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireFilter pakfire_filter_create(void) {
+ PakfireFilter filter = pakfire_calloc(1, sizeof(*filter));
+
+ return filter;
+}
+
+void pakfire_filter_free(PakfireFilter filter) {
+ pakfire_free(filter->match);
+ pakfire_free(filter);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_ARCHIVE_H
+#define PAKFIRE_ARCHIVE_H
+
+#include <archive.h>
+
+#include <pakfire/types.h>
+
+PakfireArchive pakfire_archive_create();
+void pakfire_archive_free(PakfireArchive archive);
+
+PakfireArchive pakfire_archive_open(const char* path);
+
+int pakfire_archive_read(PakfireArchive archive, const char* filename,
+ void** data, size_t* data_size, int flags);
+int pakfire_archive_extract(PakfireArchive archive, const char* prefix, int flags);
+
+const char* pakfire_archive_get_path(PakfireArchive archive);
+
+unsigned int pakfire_archive_get_format(PakfireArchive archive);
+
+PakfireFile pakfire_archive_get_filelist(PakfireArchive archive);
+
+enum pakfire_archive_flags {
+ PAKFIRE_ARCHIVE_USE_PAYLOAD = 1 << 0,
+};
+
+#define PAKFIRE_ARCHIVE_FN_FILELIST "filelist"
+#define PAKFIRE_ARCHIVE_FN_FORMAT "pakfire-format"
+#define PAKFIRE_ARCHIVE_FN_METADATA "info"
+#define PAKFIRE_ARCHIVE_FN_PAYLOAD "data.img"
+
+#ifdef PAKFIRE_PRIVATE
+
+#define PAKFIRE_ARCHIVE_BLOCKSIZE 10240
+#define PAKFIRE_ARCHIVE_FORMAT_SIZE 5
+
+struct _PakfireArchive {
+ char* path;
+
+ // metadata
+ int format;
+
+ PakfireFile filelist;
+};
+
+struct payload_archive_data {
+ struct archive* archive;
+ char buffer[PAKFIRE_ARCHIVE_BLOCKSIZE];
+};
+
+#endif
+
+#endif /* PAKFIRE_ARCHIVE_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_CACHE_H
+#define PAKFIRE_CACHE_H
+
+#include <stdio.h>
+
+#include <pakfire/types.h>
+
+PakfireCache pakfire_cache_create(PakfirePool pool, const char* path);
+void pakfire_cache_free(PakfireCache cache);
+
+const char* pakfire_cache_get_path(PakfireCache cache);
+char* pakfire_cache_get_full_path(PakfireCache cache, const char* path);
+
+int pakfire_cache_has_file(PakfireCache cache, const char* filename);
+char* pakfire_cache_get_package_path(PakfireCache cache, PakfirePackage pkg);
+int pakfire_cache_has_package(PakfireCache cache, PakfirePackage pkg);
+int pakfire_cache_age(PakfireCache cache, const char* filename);
+
+FILE* pakfire_cache_open(PakfireCache cache, const char* filename, const char* flags);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireCache {
+ PakfirePool pool;
+ char* path;
+};
+
+#endif
+
+#endif /* PAKFIRE_CACHE_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_CONSTANTS_H
+#define PAKFIRE_CONSTANTS_H
+
+#define STRING_SIZE 1024
+
+#define PAKFIRE_REPO_SYSTEM_NAME "@system"
+
+#endif /* PAKFIRE_CONSTANTS_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_ERRNO_H
+#define PAKFIRE_ERRNO_H
+
+enum _pakfire_errors {
+ PAKFIRE_E_FAILED = 1, // general runtime error
+ PAKFIRE_E_OP, // client programming error
+ PAKFIRE_E_LIBSOLV, // error propagated from libsolv
+ PAKFIRE_E_IO, // I/O error
+ PAKFIRE_E_ARCH,
+ PAKFIRE_E_SELECTOR,
+ PAKFIRE_E_PKG_INVALID, // when a package is not in the pakfire format
+ PAKFIRE_E_EOF,
+};
+
+extern __thread int pakfire_errno;
+
+int pakfire_get_errno(void);
+
+#endif /* PAKFIRE_ERRNO_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_FILE_H
+#define PAKFIRE_FILE_H
+
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <pakfire/types.h>
+
+PakfireFile pakfire_file_create();
+void pakfire_file_free(PakfireFile file);
+void pakfire_file_free_all(PakfireFile file);
+
+int pakfire_file_cmp(PakfireFile file1, PakfireFile file2);
+void pakfire_file_swap(PakfireFile file1, PakfireFile file2);
+PakfireFile pakfire_file_sort(PakfireFile head);
+
+PakfireFile pakfire_file_get_prev(PakfireFile file);
+PakfireFile pakfire_file_get_next(PakfireFile file);
+PakfireFile pakfire_file_get_first(PakfireFile file);
+PakfireFile pakfire_file_get_last(PakfireFile file);
+
+PakfireFile pakfire_file_append(PakfireFile file);
+
+unsigned int pakfire_file_count(PakfireFile file);
+
+void pakfire_file_sprintf(PakfireFile file, char* str, size_t len);
+
+const char* pakfire_file_get_name(PakfireFile file);
+void pakfire_file_set_name(PakfireFile file, const char* name);
+
+char pakfire_file_get_type(PakfireFile file);
+void pakfire_file_set_type(PakfireFile file, char type);
+
+int pakfire_file_is_file(PakfireFile file);
+int pakfire_file_is_link(PakfireFile file);
+int pakfire_file_is_symlink(PakfireFile file);
+int pakfire_file_is_char(PakfireFile file);
+int pakfire_file_is_block(PakfireFile file);
+int pakfire_file_is_dir(PakfireFile file);
+
+ssize_t pakfire_file_get_size(PakfireFile file);
+void pakfire_file_set_size(PakfireFile file, ssize_t size);
+
+const char* pakfire_file_get_user(PakfireFile file);
+void pakfire_file_set_user(PakfireFile file, const char* user);
+
+const char* pakfire_file_get_group(PakfireFile file);
+void pakfire_file_set_group(PakfireFile file, const char* group);
+
+mode_t pakfire_file_get_mode(PakfireFile file);
+void pakfire_file_set_mode(PakfireFile file, mode_t mode);
+
+time_t pakfire_file_get_time(PakfireFile file);
+void pakfire_file_set_time(PakfireFile file, time_t time);
+
+const char* pakfire_file_get_chksum(PakfireFile file);
+void pakfire_file_set_chksum(PakfireFile file, const char* chksum);
+
+PakfireFile pakfire_file_parse_from_file(const char* list, unsigned int format);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireFile {
+ char* name;
+ char type;
+ ssize_t size;
+
+ char* user;
+ char* group;
+
+ mode_t mode;
+ time_t time;
+
+ char* chksum;
+
+ #warning TODO capabilities, config, data
+ // capabilities
+ //int is_configfile;
+ //int is_datafile;
+
+ PakfireFile prev;
+ PakfireFile next;
+};
+
+#endif
+
+#endif /* PAKFIRE_FILE_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2014 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_FILELIST_H
+#define PAKFIRE_FILELIST_H
+
+#include <pakfire/types.h>
+
+PakfireFilelist pakfire_filelist_create(PakfirePackage pkg);
+void pakfire_filelist_free(PakfireFilelist list);
+
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireFilelist {
+ PakfirePackage pkg;
+
+ PakfireFile first;
+ PakfireFile last;
+};
+
+#endif
+
+#endif /* PAKFIRE_FILELIST_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_FILTER_H
+#define PAKFIRE_FILTER_H
+
+#include <pakfire/types.h>
+
+PakfireFilter pakfire_filter_create(void);
+void pakfire_filter_free(PakfireFilter filter);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireFilter {
+ int cmp_type;
+ int keyname;
+ char* match;
+};
+
+#endif
+
+#endif /* PAKFIRE_FILTER_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_I18N_H
+#define PAKFIRE_I18N_H
+
+#include <libintl.h>
+
+#define PAKFIRE_TEXTDOMAIN "pakfire"
+
+#define _(x) dgettext(PAKFIRE_TEXTDOMAIN, x)
+
+#endif /* PAKFIRE_I18N_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_PACKAGE_H
+#define PAKFIRE_PACKAGE_H
+
+#include <solv/pooltypes.h>
+
+#include <pakfire/relation.h>
+#include <pakfire/relationlist.h>
+#include <pakfire/pool.h>
+#include <pakfire/types.h>
+
+PakfirePackage pakfire_package_create(PakfirePool pool, Id id);
+PakfirePackage pakfire_package_create2(PakfirePool pool, PakfireRepo repo, const char* name, const char* evr, const char* arch);
+void pakfire_package_free(PakfirePackage pkg);
+
+int pakfire_package_identical(PakfirePackage pkg1, PakfirePackage pkg2);
+int pakfire_package_cmp(PakfirePackage pkg1, PakfirePackage pkg2);
+int pakfire_package_evr_cmp(PakfirePackage pkg1, PakfirePackage pkg2);
+
+Id pakfire_package_id(PakfirePackage pkg);
+
+char* pakfire_package_get_nevra(PakfirePackage pkg);
+const char* pakfire_package_get_name(PakfirePackage pkg);
+void pakfire_package_set_name(PakfirePackage pkg, const char* name);
+const char* pakfire_package_get_evr(PakfirePackage pkg);
+void pakfire_package_set_evr(PakfirePackage pkg, const char* evr);
+unsigned long pakfire_package_get_epoch(PakfirePackage pkg);
+const char* pakfire_package_get_version(PakfirePackage pkg);
+const char* pakfire_package_get_release(PakfirePackage pkg);
+const char* pakfire_package_get_arch(PakfirePackage pkg);
+void pakfire_package_set_arch(PakfirePackage pkg, const char* arch);
+
+const char* pakfire_package_get_uuid(PakfirePackage pkg);
+void pakfire_package_set_uuid(PakfirePackage pkg, const char* uuid);
+const char* pakfire_package_get_checksum(PakfirePackage pkg);
+void pakfire_package_set_checksum(PakfirePackage pkg, const char* checksum);
+const char* pakfire_package_get_summary(PakfirePackage pkg);
+void pakfire_package_set_summary(PakfirePackage pkg, const char* summary);
+const char* pakfire_package_get_description(PakfirePackage pkg);
+void pakfire_package_set_description(PakfirePackage pkg, const char* description);
+const char* pakfire_package_get_license(PakfirePackage pkg);
+void pakfire_package_set_license(PakfirePackage pkg, const char* license);
+const char* pakfire_package_get_url(PakfirePackage pkg);
+void pakfire_package_set_url(PakfirePackage pkg, const char* url);
+const char** pakfire_package_get_groups(PakfirePackage pkg);
+void pakfire_package_set_groups(PakfirePackage pkg, const char** grouplist);
+const char* pakfire_package_get_vendor(PakfirePackage pkg);
+void pakfire_package_set_vendor(PakfirePackage pkg, const char* vendor);
+const char* pakfire_package_get_maintainer(PakfirePackage pkg);
+void pakfire_package_set_maintainer(PakfirePackage pkg, const char* maintainer);
+const char* pakfire_package_get_filename(PakfirePackage pkg);
+void pakfire_package_set_filename(PakfirePackage pkg, const char* filename);
+int pakfire_package_is_installed(PakfirePackage pkg);
+unsigned long long pakfire_package_get_downloadsize(PakfirePackage pkg);
+void pakfire_package_set_downloadsize(PakfirePackage pkg, unsigned long long downloadsize);
+unsigned long long pakfire_package_get_installsize(PakfirePackage pkg);
+void pakfire_package_set_installsize(PakfirePackage pkg, unsigned long long installsize);
+unsigned long long pakfire_package_get_size(PakfirePackage pkg);
+const char* pakfire_package_get_buildhost(PakfirePackage pkg);
+void pakfire_package_set_buildhost(PakfirePackage pkg, const char* buildhost);
+unsigned long long pakfire_package_get_buildtime(PakfirePackage pkg);
+void pakfire_package_set_buildtime(PakfirePackage pkg, unsigned long long buildtime);
+unsigned long long pakfire_package_get_installtime(PakfirePackage pkg);
+
+PakfireRelationList pakfire_package_get_provides(PakfirePackage pkg);
+void pakfire_package_set_provides(PakfirePackage pkg, PakfireRelationList relationlist);
+void pakfire_package_add_provides(PakfirePackage pkg, PakfireRelation relation);
+PakfireRelationList pakfire_package_get_requires(PakfirePackage pkg);
+void pakfire_package_set_requires(PakfirePackage pkg, PakfireRelationList relationlist);
+void pakfire_package_add_requires(PakfirePackage pkg, PakfireRelation relation);
+PakfireRelationList pakfire_package_get_conflicts(PakfirePackage pkg);
+void pakfire_package_set_conflicts(PakfirePackage pkg, PakfireRelationList relationlist);
+void pakfire_package_add_conflicts(PakfirePackage pkg, PakfireRelation relation);
+PakfireRelationList pakfire_package_get_obsoletes(PakfirePackage pkg);
+void pakfire_package_set_obsoletes(PakfirePackage pkg, PakfireRelationList relationlist);
+void pakfire_package_add_obsoletes(PakfirePackage pkg, PakfireRelation relation);
+PakfireRelationList pakfire_package_get_recommends(PakfirePackage pkg);
+void pakfire_package_set_recommends(PakfirePackage pkg, PakfireRelationList relationlist);
+void pakfire_package_add_recommends(PakfirePackage pkg, PakfireRelation relation);
+PakfireRelationList pakfire_package_get_suggests(PakfirePackage pkg);
+void pakfire_package_set_suggests(PakfirePackage pkg, PakfireRelationList relationlist);
+void pakfire_package_add_suggests(PakfirePackage pkg, PakfireRelation relation);
+
+PakfireRepo pakfire_package_get_repo(PakfirePackage pkg);
+void pakfire_package_set_repo(PakfirePackage pkg, PakfireRepo repo);
+
+char* pakfire_package_get_location(PakfirePackage pkg);
+
+char* pakfire_package_dump(PakfirePackage pkg, int flags);
+
+int pakfire_package_is_cached(PakfirePackage pkg);
+char* pakfire_package_get_cache_path(PakfirePackage pkg);
+char* pakfire_package_get_cache_full_path(PakfirePackage pkg);
+
+PakfireFile pakfire_package_get_filelist(PakfirePackage pkg);
+PakfireFile pakfire_package_filelist_append(PakfirePackage pkg, const char* filename);
+#if 0
+PakfireFile pakfire_package_filelist_append(PakfirePackage pkg);
+#endif
+void pakfire_package_filelist_remove(PakfirePackage pkg);
+
+enum pakfire_package_keynames {
+ PAKFIRE_PKG,
+ PAKFIRE_PKG_ALL,
+ PAKFIRE_PKG_ARCH,
+ PAKFIRE_PKG_CONFLICTS,
+ PAKFIRE_PKG_DESCRIPTION,
+ PAKFIRE_PKG_EPOCH,
+ PAKFIRE_PKG_EVR,
+ PAKFIRE_PKG_FILE,
+ PAKFIRE_PKG_NAME,
+ PAKFIRE_PKG_OBSOLETES,
+ PAKFIRE_PKG_PROVIDES,
+ PAKFIRE_PKG_RELEASE,
+ PAKFIRE_PKG_REPONAME,
+ PAKFIRE_PKG_REQUIRES,
+ PAKFIRE_PKG_SOURCERPM,
+ PAKFIRE_PKG_SUMMARY,
+ PAKFIRE_PKG_URL,
+ PAKFIRE_PKG_VERSION,
+ PAKFIRE_PKG_LOCATION
+};
+
+enum pakfire_package_dump_flags {
+ PAKFIRE_PKG_DUMP_FILELIST = 1 << 0,
+ PAKFIRE_PKG_DUMP_LONG = 1 << 1,
+};
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfirePackage {
+ PakfirePool pool;
+ Id id;
+ int nrefs;
+ PakfireFile filelist;
+};
+
+static inline PakfirePool pakfire_package_pool(PakfirePackage pkg) {
+ return pkg->pool;
+}
+
+static inline Pool* pakfire_package_solv_pool(PakfirePackage pkg) {
+ return pakfire_package_pool(pkg)->pool;
+}
+
+#endif
+
+#endif /* PAKFIRE_PACKAGE_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_PACKAGECACHE_H
+#define PAKFIRE_PACKAGECACHE_H
+
+#include <pakfire/types.h>
+
+PakfirePackageCache pakfire_packagecache_create(PakfirePool pool, const char* path);
+void pakfire_packagecache_free(PakfirePackageCache cache);
+
+const char* pakfire_packagecache_get_path(PakfirePackageCache cache);
+
+int pakfire_packagecache_has_package(PakfirePackageCache cache, PakfirePackage pkg);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfirePackageCache {
+ PakfirePool pool;
+};
+
+#endif
+
+#endif /* PAKFIRE_PACKAGECACHE_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_PACKAGELIST_H
+#define PAKFIRE_PACKAGELIST_H
+
+#include <solv/queue.h>
+
+#include <pakfire/types.h>
+
+PakfirePackageList pakfire_packagelist_create(void);
+void pakfire_packagelist_free(PakfirePackageList list);
+
+int pakfire_packagelist_count(PakfirePackageList list);
+int pakfire_packagelist_has(PakfirePackageList list, PakfirePackage pkg);
+PakfirePackage pakfire_packagelist_get(PakfirePackageList list, int index);
+
+void pakfire_packagelist_push(PakfirePackageList list, PakfirePackage pkg);
+void pakfire_packagelist_push_if_not_exists(PakfirePackageList list, PakfirePackage pkg);
+
+#define FOR_PACKAGELIST(pkg, list, i) \
+ for (i = 0; (pkg = pakfire_packagelist_get(list, i)) != NULL; i++)
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfirePackageList {
+ PakfirePackage* elements;
+ int count;
+};
+
+PakfirePackageList pakfire_packagelist_from_queue(PakfirePool _pool, Queue* q);
+
+#endif
+
+#endif /* PAKFIRE_PACKAGELIST_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_POOL_H
+#define PAKFIRE_POOL_H
+
+#include <solv/pool.h>
+
+#include <pakfire/types.h>
+
+PakfirePool pakfire_pool_create(const char* arch);
+void pakfire_pool_free(PakfirePool pool);
+
+int pakfire_pool_version_compare(PakfirePool pool, const char* evr1, const char* evr2);
+int pakfire_pool_count(PakfirePool pool);
+
+PakfireRepo pakfire_pool_get_installed_repo(PakfirePool pool);
+void pakfire_pool_set_installed_repo(PakfirePool pool, PakfireRepo repo);
+
+const char** pakfire_pool_get_installonly(PakfirePool pool);
+void pakfire_pool_set_installonly(PakfirePool pool, const char** installonly);
+
+const char* pakfire_pool_get_cache_path(PakfirePool pool);
+void pakfire_pool_set_cache_path(PakfirePool pool, const char* path);
+PakfireCache pakfire_pool_get_cache(PakfirePool pool);
+
+PakfirePackageList pakfire_pool_whatprovides(PakfirePool pool, const char* provides, int flags);
+PakfirePackageList pakfire_pool_search(PakfirePool pool, const char* what, int flags);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfirePool {
+ Pool* pool;
+ int provides_ready;
+ Queue installonly;
+
+ PakfireCache cache;
+};
+
+void pakfire_pool_make_provides_ready(PakfirePool pool);
+char* pakfire_pool_tmpdup(Pool* pool, const char* s);
+
+#endif
+
+#endif /* PAKFIRE_POOL_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_RELATION_H
+#define PAKFIRE_RELATION_H
+
+#include <solv/pool.h>
+#include <solv/pooltypes.h>
+#include <solv/queue.h>
+
+#include <pakfire/pool.h>
+#include <pakfire/types.h>
+
+PakfireRelation pakfire_relation_create(PakfirePool pool, const char* name, int cmp_type, const char* evr);
+PakfireRelation pakfire_relation_create_from_id(PakfirePool pool, Id id);
+void pakfire_relation_free(PakfireRelation relation);
+
+Id pakfire_relation_id(PakfireRelation relation);
+char* pakfire_relation_str(PakfireRelation relation);
+
+PakfirePackageList pakfire_relation_providers(PakfireRelation relation);
+
+int pakfire_relation2queue(const PakfireRelation relation, Queue* queue, int solver_action);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireRelation {
+ PakfirePool pool;
+ Id id;
+};
+
+static inline PakfirePool pakfire_relation_pool(PakfireRelation relation) {
+ return relation->pool;
+}
+
+static inline Pool* pakfire_relation_solv_pool(PakfireRelation relation) {
+ return pakfire_relation_pool(relation)->pool;
+}
+
+#endif
+
+#endif /* PAKFIRE_RELATION_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_RELATIONLIST_H
+#define PAKFIRE_RELATIONLIST_H
+
+#include <solv/queue.h>
+
+#include <pakfire/pool.h>
+#include <pakfire/relation.h>
+#include <pakfire/types.h>
+
+PakfireRelationList pakfire_relationlist_create(PakfirePool pool);
+void pakfire_relationlist_free(PakfireRelationList reldeplist);
+
+void pakfire_relationlist_add(PakfireRelationList relationlist, PakfireRelation relation);
+int pakfire_relationlist_count(PakfireRelationList relationlist);
+
+PakfireRelation pakfire_relationlist_get_clone(PakfireRelationList relationlist, int index);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireRelationList {
+ PakfirePool pool;
+ Queue queue;
+};
+
+PakfireRelationList pakfire_relationlist_from_queue(PakfirePool pool, Queue q);
+void pakfire_relationlist_clone_to_queue(PakfireRelationList relationlist, Queue* q);
+
+#endif
+
+#endif /* PAKFIRE_RELATIONLIST_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_REPO_H
+#define PAKFIRE_REPO_H
+
+#include <solv/repo.h>
+
+#include <pakfire/types.h>
+
+PakfireRepo pakfire_repo_create(PakfirePool pool, const char* name);
+PakfireRepo pakfire_repo_create_from_repo(PakfirePool pool, Repo* r);
+void pakfire_repo_free(PakfireRepo pkg);
+
+PakfirePool pakfire_repo_pool(PakfireRepo repo);
+
+int pakfire_repo_identical(PakfireRepo repo1, PakfireRepo repo2);
+int pakfire_repo_cmp(PakfireRepo repo1, PakfireRepo repo2);
+int pakfire_repo_count(PakfireRepo repo);
+
+void pakfire_repo_internalize(PakfireRepo repo);
+
+const char* pakfire_repo_get_name(PakfireRepo repo);
+void pakfire_repo_set_name(PakfireRepo repo, const char* name);
+
+int pakfire_repo_get_enabled(PakfireRepo repo);
+void pakfire_repo_set_enabled(PakfireRepo repo, int enabled);
+
+int pakfire_repo_get_priority(PakfireRepo repo);
+void pakfire_repo_set_priority(PakfireRepo repo, int priority);
+
+int pakfire_repo_is_installed_repo(PakfireRepo repo);
+
+int pakfire_repo_read_solv(PakfireRepo repo, const char* filename, int flags);
+int pakfire_repo_read_solv_fp(PakfireRepo repo, FILE *f, int flags);
+
+int pakfire_repo_write_solv(PakfireRepo repo, const char* filename, int flags);
+int pakfire_repo_write_solv_fp(PakfireRepo repo, FILE *f, int flags);
+
+PakfireRepoCache pakfire_repo_get_cache(PakfireRepo repo);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireRepo {
+ PakfirePool pool;
+ Repo* repo;
+ PakfireRepoCache cache;
+ int nrefs;
+
+ Repodata* filelist;
+};
+
+PakfirePackage pakfire_repo_add_package(PakfireRepo repo);
+
+static inline Pool* pakfire_repo_solv_pool(PakfireRepo repo) {
+ return pakfire_repo_pool(repo)->pool;
+}
+
+static inline Repo* pakfire_repo_get_solv_repo(PakfireRepo repo) {
+ return repo->repo;
+}
+
+#endif
+
+#endif /* PAKFIRE_REPO_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_REPOCACHE_H
+#define PAKFIRE_REPOCACHE_H
+
+#include <stdio.h>
+
+#include <pakfire/types.h>
+
+PakfireRepoCache pakfire_repocache_create(PakfireRepo repo);
+void pakfire_repocache_free(PakfireRepoCache repo_cache);
+
+char* pakfire_repocache_get_cache_path(PakfireRepoCache repo_cache, const char* path);
+char* pakfire_repocache_get_full_path(PakfireRepoCache repo_cache, const char* path);
+
+int pakfire_repocache_has_file(PakfireRepoCache repo_cache, const char* filename);
+int pakfire_repocache_age(PakfireRepoCache repo_cache, const char* filename);
+
+FILE* pakfire_repocache_open(PakfireRepoCache repo_cache, const char* filename, const char* flags);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireRepoCache {
+ PakfireRepo repo;
+ char* prefix;
+};
+
+inline PakfirePool pakfire_repocache_pool(PakfireRepoCache repo_cache) {
+ return pakfire_repo_pool(repo_cache->repo);
+}
+
+inline PakfireCache pakfire_repocache_cache(PakfireRepoCache repo_cache) {
+ PakfirePool pool = pakfire_repocache_pool(repo_cache);
+
+ return pakfire_pool_get_cache(pool);
+}
+
+#endif
+
+#endif /* PAKFIRE_REPOCACHE_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_REQUEST_H
+#define PAKFIRE_REQUEST_H
+
+#include <solv/queue.h>
+#include <solv/solver.h>
+#include <solv/transaction.h>
+
+#include <pakfire/types.h>
+
+enum _pakfire_request_op_flags {
+ PAKFIRE_CHECK_INSTALLED = 1 << 0,
+ PAKFIRE_CLEAN_DEPS = 1 << 1,
+};
+
+enum _pakfire_solver_flags {
+ PAKFIRE_SOLVER_ALLOW_UNINSTALL = 1 << 0,
+ PAKFIRE_SOLVER_FORCE_BEST = 1 << 1,
+};
+
+PakfireRequest pakfire_request_create(PakfirePool pool);
+void pakfire_request_free(PakfireRequest request);
+
+PakfirePool pakfire_request_pool(PakfireRequest request);
+
+int pakfire_request_solve(PakfireRequest request, int flags);
+PakfireTransaction pakfire_request_get_transaction(PakfireRequest request);
+
+int pakfire_request_install(PakfireRequest request, PakfirePackage package);
+int pakfire_request_install_relation(PakfireRequest request, PakfireRelation relation);
+int pakfire_request_install_selector(PakfireRequest request, PakfireSelector selector);
+
+int pakfire_request_erase(PakfireRequest request, PakfirePackage package, int flags);
+int pakfire_request_erase_relation(PakfireRequest request, PakfireRelation relation, int flags);
+int pakfire_request_erase_selector(PakfireRequest request, PakfireSelector selector, int flags);
+
+int pakfire_request_upgrade(PakfireRequest request, PakfirePackage package);
+int pakfire_request_upgrade_relation(PakfireRequest request, PakfireRelation relation);
+int pakfire_request_upgrade_selector(PakfireRequest request, PakfireSelector selector);
+
+int pakfire_request_upgrade_all(PakfireRequest request);
+int pakfire_request_distupgrade(PakfireRequest request);
+
+int pakfire_request_lock(PakfireRequest request, PakfirePackage package);
+int pakfire_request_lock_relation(PakfireRequest request, PakfireRelation relation);
+int pakfire_request_lock_selector(PakfireRequest request, PakfireSelector selector);
+
+int pakfire_request_verify(PakfireRequest request);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireRequest {
+ PakfirePool pool;
+ Queue queue;
+ Solver* solver;
+ Transaction* transaction;
+};
+
+#endif
+
+#endif /* PAKFIRE_REQUEST_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_SELECTOR_H
+#define PAKFIRE_SELECTOR_H
+
+#include <solv/pool.h>
+#include <solv/queue.h>
+
+#include <pakfire/filter.h>
+#include <pakfire/packagelist.h>
+#include <pakfire/pool.h>
+
+PakfireSelector pakfire_selector_create(PakfirePool pool);
+void pakfire_selector_free(PakfireSelector selector);
+
+int pakfire_selector_set(PakfireSelector selector, int keyname, int cmp_type, const char* match);
+
+PakfirePackageList pakfire_selector_providers(PakfireSelector selector);
+
+int pakfire_selector2queue(const PakfireSelector selector, Queue* queue, int solver_action);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireSelector {
+ PakfirePool pool;
+ PakfireFilter f_name;
+ PakfireFilter f_provides;
+ PakfireFilter f_evr;
+ PakfireFilter f_arch;
+};
+
+static inline PakfirePool pakfire_selector_pool(PakfireSelector selector) {
+ return selector->pool;
+}
+
+static inline Pool* pakfire_selector_solv_pool(PakfireSelector selector) {
+ return pakfire_selector_pool(selector)->pool;
+}
+
+#endif
+
+#endif /* PAKFIRE_SELECTOR_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_SOLVER_H
+#define PAKFIRE_SOLVER_H
+
+#endif /* PAKFIRE_SOLVER_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_STEP_H
+#define PAKFIRE_STEP_H
+
+#include <solv/pooltypes.h>
+
+#include <pakfire/types.h>
+
+PakfireStep pakfire_step_create(PakfireTransaction transaction, Id id);
+void pakfire_step_free(PakfireStep step);
+
+PakfirePackage pakfire_step_get_package(PakfireStep step);
+int pakfire_step_get_type(PakfireStep step);
+const char* pakfire_step_get_type_string(PakfireStep step);
+
+unsigned long long pakfire_step_get_downloadsize(PakfireStep step);
+long pakfire_step_get_installsizechange(PakfireStep step);
+
+int pakfire_step_needs_download(PakfireStep step);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireStep {
+ PakfirePool pool;
+ PakfireTransaction transaction;
+ Id id;
+};
+
+static inline PakfirePool pakfire_step_pool(PakfireStep step) {
+ return step->pool;
+}
+
+#endif
+
+#endif /* PAKFIRE_STEP_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_TRANSACTION_H
+#define PAKFIRE_TRANSACTION_H
+
+#include <solv/transaction.h>
+
+#include <pakfire/types.h>
+
+PakfireTransaction pakfire_transaction_create(PakfirePool pool, Transaction* trans);
+void pakfire_transaction_free(PakfireTransaction transaction);
+
+int pakfire_transaction_count(PakfireTransaction transaction);
+
+int pakfire_transaction_installsizechange(PakfireTransaction transaction);
+
+PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int index);
+PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transaction, int type);
+
+#ifdef PAKFIRE_PRIVATE
+
+struct _PakfireTransaction {
+ PakfirePool pool;
+ Transaction* transaction;
+};
+
+static inline PakfirePool pakfire_transaction_pool(PakfireTransaction transaction) {
+ return transaction->pool;
+}
+
+#endif
+
+#endif /* PAKFIRE_TRANSACTION_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_TYPES_H
+#define PAKFIRE_TYPES_H
+
+typedef struct _PakfireArchive* PakfireArchive;
+typedef struct _PakfireCache* PakfireCache;
+typedef struct _PakfireFile* PakfireFile;
+typedef struct _PakfireFilter* PakfireFilter;
+typedef struct _PakfirePackage* PakfirePackage;
+typedef struct _PakfirePackageCache* PakfirePackageCache;
+typedef struct _PakfirePackageList* PakfirePackageList;
+typedef struct _PakfirePool* PakfirePool;
+typedef struct _PakfireRelation* PakfireRelation;
+typedef struct _PakfireRelationList* PakfireRelationList;
+typedef struct _PakfireRepo* PakfireRepo;
+typedef struct _PakfireRepoCache* PakfireRepoCache;
+typedef struct _PakfireRequest* PakfireRequest;
+typedef struct _PakfireSelector* PakfireSelector;
+typedef struct _PakfireStep* PakfireStep;
+typedef struct _PakfireTransaction* PakfireTransaction;
+
+enum _pakfire_comparison_types {
+ PAKFIRE_ICASE = 1 << 0,
+ PAKFIRE_NOT = 1 << 1,
+ PAKFIRE_NAME_ONLY = 1 << 2,
+ PAKFIRE_SUBSTRING = 1 << 3,
+
+ PAKFIRE_EQ = 1 << 8,
+ PAKFIRE_LT = 1 << 9,
+ PAKFIRE_LE = PAKFIRE_EQ|PAKFIRE_LT,
+ PAKFIRE_GT = 1 << 10,
+ PAKFIRE_GE = PAKFIRE_EQ|PAKFIRE_GT,
+ PAKFIRE_NEQ = PAKFIRE_EQ|PAKFIRE_NOT,
+
+ PAKFIRE_SUBSTR = 1 << 11,
+ PAKFIRE_GLOB = 1 << 12,
+};
+
+#define PAKFIRE_SOLVABLE_FILEMARKER "solvable:filemarker"
+
+#endif /* PAKFIRE_TYPES_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_UTIL_H
+#define PAKFIRE_UTIL_H
+
+#include <stddef.h>
+
+void pakfire_oom(size_t num, size_t len);
+
+void* pakfire_malloc(size_t len);
+void* pakfire_calloc(size_t num, size_t len);
+void* pakfire_realloc(void* ptr, size_t size);
+
+void* pakfire_free(void* mem);
+
+char* pakfire_strdup(const char* s);
+
+char* pakfire_format_size(double size);
+
+char* pakfire_path_join(const char* first, const char* second);
+
+char* pakfire_basename(const char* path);
+char* pakfire_dirname(const char* path);
+
+char* pakfire_sgets(char* str, int num, char** input);
+char* pakfire_remove_trailing_newline(char* str);
+
+#endif /* PAKFIRE_UTIL_H */
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+LIBPAKFIRE_0 {
+global:
+ # archive
+ pakfire_archive_create;
+ pakfire_archive_extract;
+ pakfire_archive_free;
+ pakfire_archive_get_filelist;
+ pakfire_archive_get_format;
+ pakfire_archive_get_path;
+ pakfire_archive_open;
+ pakfire_archive_read;
+
+ # file
+ pakfire_file_append;
+ pakfire_file_cmp;
+ pakfire_file_count;
+ pakfire_file_create;
+ pakfire_file_free;
+ pakfire_file_free_all;
+ pakfire_file_get_first;
+ pakfire_file_get_group;
+ pakfire_file_get_last;
+ pakfire_file_get_mode;
+ pakfire_file_get_name;
+ pakfire_file_get_next;
+ pakfire_file_get_prev;
+ pakfire_file_get_time;
+ pakfire_file_get_user;
+ pakfire_file_is_file;
+ pakfire_file_is_link;
+ pakfire_file_is_symlink;
+ pakfire_file_is_char;
+ pakfire_file_is_block;
+ pakfire_file_is_dir;
+ pakfire_file_set_group;
+ pakfire_file_set_mode;
+ pakfire_file_set_name;
+ pakfire_file_set_time;
+ pakfire_file_set_user;
+ pakfire_file_sprintf;
+ pakfire_file_sort;
+ pakfire_file_swap;
+
+ # package
+ pakfire_package_add_conflicts;
+ pakfire_package_add_obsoletes;
+ pakfire_package_add_provides;
+ pakfire_package_add_recommends;
+ pakfire_package_add_requires;
+ pakfire_package_add_suggests;
+ pakfire_package_cmp;
+ pakfire_package_create;
+ pakfire_package_create2;
+ pakfire_package_dump;
+ pakfire_package_filelist_append;
+ pakfire_package_filelist_remove;
+ pakfire_package_free;
+ pakfire_package_get_arch;
+ pakfire_package_get_buildhost;
+ pakfire_package_get_buildtime;
+ pakfire_package_get_cache_path;
+ pakfire_package_get_cache_full_path;
+ pakfire_package_get_checksum;
+ pakfire_package_get_conflicts;
+ pakfire_package_get_description;
+ pakfire_package_get_downloadsize;
+ pakfire_package_get_epoch;
+ pakfire_package_get_evr;
+ pakfire_package_get_filelist;
+ pakfire_package_get_filename;
+ pakfire_package_get_groups;
+ pakfire_package_get_license;
+ pakfire_package_get_location;
+ pakfire_package_get_installsize;
+ pakfire_package_get_installtime;
+ pakfire_package_get_maintainer;
+ pakfire_package_get_name;
+ pakfire_package_get_nevra;
+ pakfire_package_get_obsoletes;
+ pakfire_package_get_provides;
+ pakfire_package_get_recommends;
+ pakfire_package_get_release;
+ pakfire_package_get_repo;
+ pakfire_package_get_requires;
+ pakfire_package_get_size;
+ pakfire_package_get_suggests;
+ pakfire_package_get_summary;
+ pakfire_package_get_url;
+ pakfire_package_get_uuid;
+ pakfire_package_get_vendor;
+ pakfire_package_get_version;
+ pakfire_package_id;
+ pakfire_package_is_installed;
+ pakfire_package_set_arch;
+ pakfire_package_set_buildhost;
+ pakfire_package_set_buildtime;
+ pakfire_package_set_checksum;
+ pakfire_package_set_conflicts;
+ pakfire_package_set_description;
+ pakfire_package_set_downloadsize;
+ pakfire_package_set_evr;
+ pakfire_package_set_filename;
+ pakfire_package_set_groups;
+ pakfire_package_set_installsize;
+ pakfire_package_set_license;
+ pakfire_package_set_maintainer;
+ pakfire_package_set_name;
+ pakfire_package_set_obsoletes;
+ pakfire_package_set_provides;
+ pakfire_package_set_recommends;
+ pakfire_package_set_repo;
+ pakfire_package_set_requires;
+ pakfire_package_set_suggests;
+ pakfire_package_set_summary;
+ pakfire_package_set_url;
+ pakfire_package_set_uuid;
+ pakfire_package_set_vendor;
+
+ # packagelist
+ pakfire_packagelist_count;
+ pakfire_packagelist_create;
+ pakfire_packagelist_free;
+ pakfire_packagelist_get;
+ pakfire_packagelist_has;
+ pakfire_packagelist_push;
+ pakfire_packagelist_push_if_not_exists;
+
+ # pool
+ pakfire_pool_count;
+ pakfire_pool_create;
+ pakfire_pool_free;
+ pakfire_pool_get_cache_path;
+ pakfire_pool_get_installed_repo;
+ pakfire_pool_get_installonly;
+ pakfire_pool_search;
+ pakfire_pool_set_cache_path;
+ pakfire_pool_set_installed_repo;
+ pakfire_pool_set_installonly;
+ pakfire_pool_version_compare;
+ pakfire_pool_whatprovides;
+
+ # repo
+ pakfire_repo_cmp;
+ pakfire_repo_count;
+ pakfire_repo_create;
+ pakfire_repo_free;
+ pakfire_repo_get_cache;
+ pakfire_repo_get_name;
+ pakfire_repo_get_enabled;
+ pakfire_repo_get_priority;
+ pakfire_repo_identical;
+ pakfire_repo_internalize;
+ pakfire_repo_is_installed_repo;
+ pakfire_repo_pool;
+ pakfire_repo_read_solv;
+ pakfire_repo_read_solv_fp;
+ pakfire_repo_set_enabled;
+ pakfire_repo_set_name;
+ pakfire_repo_set_priority;
+ pakfire_repo_write_solv;
+ pakfire_repo_write_solv_fp;
+
+ # repocache
+ pakfire_repocache_age;
+ pakfire_repocache_create;
+ pakfire_repocache_free;
+ pakfire_repocache_get_cache_path;
+ pakfire_repocache_get_full_path;
+ pakfire_repocache_has_file;
+ pakfire_repocache_open;
+
+ # relation
+ pakfire_relation_create;
+ pakfire_relation_create_from_id;
+ pakfire_relation_free;
+ pakfire_relation_id;
+ pakfire_relation_providers;
+ pakfire_relation_str;
+
+ # relationlist
+ pakfire_relationlist_add;
+ pakfire_relationlist_count;
+ pakfire_relationlist_create;
+ pakfire_relationlist_free;
+ pakfire_relationlist_get_clone;
+
+ # request
+ pakfire_request_create;
+ pakfire_request_distupgrade;
+ pakfire_request_free;
+ pakfire_request_erase;
+ pakfire_request_erase_relation;
+ pakfire_request_erase_selector;
+ pakfire_request_get_transaction;
+ pakfire_request_install;
+ pakfire_request_install_relation;
+ pakfire_request_install_selector;
+ pakfire_request_lock;
+ pakfire_request_lock_relation;
+ pakfire_request_lock_selector;
+ pakfire_request_pool;
+ pakfire_request_solve;
+ pakfire_request_upgrade;
+ pakfire_request_upgrade_all;
+ pakfire_request_upgrade_relation;
+ pakfire_request_upgrade_selector;
+ pakfire_request_verify;
+
+ # selector
+ pakfire_selector_create;
+ pakfire_selector_free;
+ pakfire_selector_providers;
+ pakfire_selector_set;
+
+ # step
+ pakfire_step_create;
+ pakfire_step_free;
+ pakfire_step_get_downloadsize;
+ pakfire_step_get_installsizechange;
+ pakfire_step_get_package;
+ pakfire_step_get_type;
+ pakfire_step_get_type_string;
+ pakfire_step_needs_download;
+
+ # transaction
+ pakfire_transaction_create;
+ pakfire_transaction_free;
+ pakfire_transaction_get_packages;
+ pakfire_transaction_get_step;
+ pakfire_transaction_installsizechange;
+
+ # util
+ pakfire_free;
+ pakfire_get_errno;
+
+local:
+ *;
+};
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <solv/evr.h>
+#include <solv/pool.h>
+#include <solv/pooltypes.h>
+#include <solv/repo.h>
+#include <solv/solvable.h>
+
+#include <pakfire/cache.h>
+#include <pakfire/constants.h>
+#include <pakfire/file.h>
+#include <pakfire/i18n.h>
+#include <pakfire/package.h>
+#include <pakfire/packagecache.h>
+#include <pakfire/pool.h>
+#include <pakfire/relation.h>
+#include <pakfire/relationlist.h>
+#include <pakfire/repo.h>
+#include <pakfire/repocache.h>
+#include <pakfire/util.h>
+
+static void pakfire_package_add_self_provides(PakfirePool pool, PakfirePackage pkg, const char* name, const char* evr) {
+#if 1
+ PakfireRelation relation = pakfire_relation_create(pool, name, PAKFIRE_EQ, evr);
+
+ pakfire_package_add_provides(pkg, relation);
+
+ pakfire_relation_free(relation);
+#else
+ Id iname = pool_str2id(pool->pool, name, 1);
+ Id ievr = pool_str2id(pool->pool, evr, 1);
+
+ Id rel = pool_rel2id(pool->pool, iname, ievr, REL_EQ, 1);
+
+ Solvable* s = get_solvable(pkg);
+
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+
+ s->provides = repo_addid_dep(repo->repo, s->provides, rel, 0);
+#endif
+}
+
+PakfirePackage pakfire_package_create(PakfirePool pool, Id id) {
+ PakfirePackage pkg = pakfire_calloc(1, sizeof(*pkg));
+
+ if (pkg) {
+ pkg->pool = pool;
+ pkg->id = id;
+
+ // Initialize reference counter
+ pkg->nrefs = 1;
+ }
+
+ return pkg;
+}
+
+PakfirePackage pakfire_package_create2(PakfirePool pool, PakfireRepo repo, const char* name, const char* evr, const char* arch) {
+ PakfirePackage pkg = pakfire_repo_add_package(repo);
+
+ pakfire_package_set_name(pkg, name);
+ pakfire_package_set_evr(pkg, evr);
+ pakfire_package_set_arch(pkg, arch);
+
+ pakfire_package_add_self_provides(pool, pkg, name, evr);
+
+ return pkg;
+}
+
+void pakfire_package_free(PakfirePackage pkg) {
+ if (--pkg->nrefs > 0)
+ return;
+
+ pakfire_package_filelist_remove(pkg);
+ pakfire_free(pkg);
+}
+
+static Solvable* get_solvable(PakfirePackage pkg) {
+ PakfirePool pool = pakfire_package_pool(pkg);
+
+ return pool_id2solvable(pool->pool, pkg->id);
+}
+
+static Repo* pakfire_package_solv_repo(PakfirePackage pkg) {
+ Solvable* s = get_solvable(pkg);
+
+ return s->repo;
+}
+
+static Id pakfire_package_get_handle(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ return s - pool->solvables;
+}
+
+int pakfire_package_identical(PakfirePackage pkg1, PakfirePackage pkg2) {
+ return pkg1->id == pkg2->id;
+}
+
+int pakfire_package_cmp(PakfirePackage pkg1, PakfirePackage pkg2) {
+ Pool* pool = pakfire_package_solv_pool(pkg1);
+
+ Solvable* s1 = get_solvable(pkg1);
+ Solvable* s2 = get_solvable(pkg2);
+
+ // Check names
+ const char* str1 = pool_id2str(pool, s1->name);
+ const char* str2 = pool_id2str(pool, s2->name);
+
+ int ret = strcmp(str1, str2);
+ if (ret)
+ return ret;
+
+ // Check the version string
+ ret = pakfire_package_evr_cmp(pkg1, pkg2);
+ if (ret)
+ return ret;
+
+ // Check repositories
+ PakfireRepo repo1 = pakfire_package_get_repo(pkg1);
+ PakfireRepo repo2 = pakfire_package_get_repo(pkg2);
+
+ if (repo1 && repo2) {
+ ret = pakfire_repo_cmp(repo1, repo2);
+
+ pakfire_repo_free(repo1);
+ pakfire_repo_free(repo2);
+
+ if (ret)
+ return ret;
+ }
+
+ // Check package architectures
+ str1 = pool_id2str(pool, s1->arch);
+ str2 = pool_id2str(pool, s2->arch);
+
+ return strcmp(str1, str2);
+}
+
+int pakfire_package_evr_cmp(PakfirePackage pkg1, PakfirePackage pkg2) {
+ Pool* pool = pakfire_package_solv_pool(pkg1);
+
+ Solvable* s1 = get_solvable(pkg1);
+ Solvable* s2 = get_solvable(pkg2);
+
+ return pool_evrcmp(pool, s1->evr, s2->evr, EVRCMP_COMPARE);
+}
+
+Id pakfire_package_id(PakfirePackage pkg) {
+ return pkg->id;
+}
+
+char* pakfire_package_get_nevra(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ const char* nevra = pool_solvable2str(pool, s);
+
+ return pakfire_strdup(nevra);
+}
+
+const char* pakfire_package_get_name(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ return pool_id2str(pool, s->name);
+}
+
+void pakfire_package_set_name(PakfirePackage pkg, const char* name) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ s->name = pool_str2id(pool, name, 1);
+}
+
+const char* pakfire_package_get_evr(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ return pool_id2str(pool, s->evr);
+}
+
+void pakfire_package_set_evr(PakfirePackage pkg, const char* evr) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ s->evr = pool_str2id(pool, evr, 1);
+}
+
+static void split_evr(Pool* pool, const char* evr_c, char** epoch, char** version, char** release) {
+ char* evr = pakfire_pool_tmpdup(pool, evr_c);
+ char *e, *v, *r;
+
+ for (e = evr + 1; *e != ':' && *e != '-'; ++e)
+ ;
+
+ if (*e == '-') {
+ *e = '\0';
+ v = evr;
+ r = e + 1;
+ e = NULL;
+ } else { /* *e == ':' */
+ *e = '\0';
+ v = e + 1;
+ e = evr;
+ for (r = v + 1; *r != '-'; ++r)
+ ;
+ *r = '\0';
+ r++;
+ }
+
+ *epoch = e;
+ *version = v;
+ *release = r;
+}
+
+unsigned long pakfire_package_get_epoch(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ char *e, *v, *r, *endptr;
+
+ unsigned long epoch = 0;
+
+ split_evr(pool, pakfire_package_get_evr(pkg), &e, &v, &r);
+
+ if (e) {
+ long int converted = strtol(e, &endptr, 10);
+ assert(converted > 0);
+ assert(*endptr == '\0');
+ epoch = converted;
+ }
+
+ return epoch;
+}
+
+const char* pakfire_package_get_version(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ char *e, *v, *r;
+
+ split_evr(pool, pakfire_package_get_evr(pkg), &e, &v, &r);
+ return pakfire_strdup(v);
+}
+
+const char* pakfire_package_get_release(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ char *e, *v, *r;
+
+ split_evr(pool, pakfire_package_get_evr(pkg), &e, &v, &r);
+ return pakfire_strdup(r);
+}
+
+const char* pakfire_package_get_arch(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ return pool_id2str(pool, s->arch);
+}
+
+void pakfire_package_set_arch(PakfirePackage pkg, const char* arch) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ s->arch = pool_str2id(pool, arch, 1);
+}
+
+static void pakfire_package_internalize_repo(PakfirePackage pkg) {
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+ if (repo) {
+ pakfire_repo_internalize(repo);
+ pakfire_repo_free(repo);
+ }
+}
+
+static const char* pakfire_package_get_string(PakfirePackage pkg, int key) {
+ pakfire_package_internalize_repo(pkg);
+
+ Solvable* s = get_solvable(pkg);
+ const char* str = solvable_lookup_str(s, key);
+
+ if (!str)
+ return NULL;
+
+ if (strlen(str) == 0)
+ return NULL;
+
+ return str;
+}
+
+static void pakfire_package_set_string(PakfirePackage pkg, int key, const char* value) {
+ Solvable* s = get_solvable(pkg);
+
+ if (!value)
+ value = "";
+
+ solvable_set_str(s, key, value);
+}
+
+const char* pakfire_package_get_uuid(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_PKGID);
+}
+
+void pakfire_package_set_uuid(PakfirePackage pkg, const char* uuid) {
+ pakfire_package_set_string(pkg, SOLVABLE_PKGID, uuid);
+}
+
+const char* pakfire_package_get_checksum(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_CHECKSUM);
+}
+
+void pakfire_package_set_checksum(PakfirePackage pkg, const char* checksum) {
+ pakfire_package_set_string(pkg, SOLVABLE_CHECKSUM, checksum);
+}
+
+const char* pakfire_package_get_summary(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_SUMMARY);
+}
+
+void pakfire_package_set_summary(PakfirePackage pkg, const char* summary) {
+ pakfire_package_set_string(pkg, SOLVABLE_SUMMARY, summary);
+}
+
+const char* pakfire_package_get_description(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_DESCRIPTION);
+}
+
+void pakfire_package_set_description(PakfirePackage pkg, const char* description) {
+ pakfire_package_set_string(pkg, SOLVABLE_DESCRIPTION, description);
+}
+
+const char* pakfire_package_get_license(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_LICENSE);
+}
+
+void pakfire_package_set_license(PakfirePackage pkg, const char* license) {
+ pakfire_package_set_string(pkg, SOLVABLE_LICENSE, license);
+}
+
+const char* pakfire_package_get_url(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_URL);
+}
+
+void pakfire_package_set_url(PakfirePackage pkg, const char* url) {
+ pakfire_package_set_string(pkg, SOLVABLE_URL, url);
+}
+
+#warning the groups functions need to be refactored
+
+const char** pakfire_package_get_groups(PakfirePackage pkg) {
+ const char* groups = pakfire_package_get_string(pkg, SOLVABLE_GROUP);
+
+ const char** grouplist = NULL;
+ char* group = strtok((char *)groups, " ");
+
+ int i = 0;
+ while (group != NULL) {
+ grouplist = realloc(grouplist, sizeof(char *) * ++i);
+ assert(grouplist);
+ grouplist[i - 1] = group;
+
+ group = strtok(NULL, " ");
+ }
+ grouplist[i] = NULL;
+
+ return grouplist;
+}
+
+void pakfire_package_set_groups(PakfirePackage pkg, const char** grouplist) {
+ char groups[2048] = "";
+
+ if (grouplist) {
+ const char* group;
+ while ((group = *grouplist++) != NULL) {
+ if (groups[0])
+ strcat(groups, " ");
+
+ strcat(groups, group);
+ }
+ groups[sizeof(groups) - 1] = '\0';
+ } else
+ groups[0] = '\0';
+
+ pakfire_package_set_string(pkg, SOLVABLE_GROUP, (const char *)&groups);
+}
+
+const char* pakfire_package_get_vendor(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_VENDOR);
+}
+
+void pakfire_package_set_vendor(PakfirePackage pkg, const char* vendor) {
+ pakfire_package_set_string(pkg, SOLVABLE_VENDOR, vendor);
+}
+
+const char* pakfire_package_get_maintainer(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_PACKAGER);
+}
+
+void pakfire_package_set_maintainer(PakfirePackage pkg, const char* maintainer) {
+ pakfire_package_set_string(pkg, SOLVABLE_PACKAGER, maintainer);
+}
+
+const char* pakfire_package_get_filename(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_MEDIAFILE);
+}
+
+void pakfire_package_set_filename(PakfirePackage pkg, const char* filename) {
+ pakfire_package_set_string(pkg, SOLVABLE_MEDIAFILE, filename);
+}
+
+int pakfire_package_is_installed(PakfirePackage pkg) {
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Solvable* s = get_solvable(pkg);
+
+ return pool->installed == s->repo;
+}
+
+static unsigned long long pakfire_package_get_num(PakfirePackage pkg, Id type) {
+ pakfire_package_internalize_repo(pkg);
+
+ Solvable* s = get_solvable(pkg);
+ return solvable_lookup_num(s, type, 0);
+}
+
+static void pakfire_package_set_num(PakfirePackage pkg, Id type, unsigned long long value) {
+ Solvable* s = get_solvable(pkg);
+
+ solvable_set_num(s, type, value);
+}
+
+unsigned long long pakfire_package_get_downloadsize(PakfirePackage pkg) {
+ return pakfire_package_get_num(pkg, SOLVABLE_DOWNLOADSIZE);
+}
+
+void pakfire_package_set_downloadsize(PakfirePackage pkg, unsigned long long downloadsize) {
+ return pakfire_package_set_num(pkg, SOLVABLE_DOWNLOADSIZE, downloadsize);
+}
+
+unsigned long long pakfire_package_get_installsize(PakfirePackage pkg) {
+ return pakfire_package_get_num(pkg, SOLVABLE_INSTALLSIZE);
+}
+
+void pakfire_package_set_installsize(PakfirePackage pkg, unsigned long long installsize) {
+ return pakfire_package_set_num(pkg, SOLVABLE_INSTALLSIZE, installsize);
+}
+
+unsigned long long pakfire_package_get_size(PakfirePackage pkg) {
+ if (pakfire_package_is_installed(pkg))
+ return pakfire_package_get_installsize(pkg);
+
+ return pakfire_package_get_downloadsize(pkg);
+}
+
+const char* pakfire_package_get_buildhost(PakfirePackage pkg) {
+ return pakfire_package_get_string(pkg, SOLVABLE_BUILDHOST);
+}
+
+void pakfire_package_set_buildhost(PakfirePackage pkg, const char* buildhost) {
+ pakfire_package_set_string(pkg, SOLVABLE_BUILDHOST, buildhost);
+}
+
+unsigned long long pakfire_package_get_buildtime(PakfirePackage pkg) {
+ return pakfire_package_get_num(pkg, SOLVABLE_BUILDTIME);
+}
+
+void pakfire_package_set_buildtime(PakfirePackage pkg, unsigned long long buildtime) {
+ pakfire_package_set_num(pkg, SOLVABLE_BUILDTIME, buildtime);
+}
+
+unsigned long long pakfire_package_get_installtime(PakfirePackage pkg) {
+ return pakfire_package_get_num(pkg, SOLVABLE_INSTALLTIME);
+}
+
+static PakfireRelationList pakfire_package_get_relationlist(PakfirePackage pkg, Id type) {
+ Queue q;
+ queue_init(&q);
+
+ Solvable* s = get_solvable(pkg);
+ solvable_lookup_idarray(s, type, &q);
+
+ PakfirePool pool = pakfire_package_pool(pkg);
+ PakfireRelationList relationlist = pakfire_relationlist_from_queue(pool, q);
+
+ queue_free(&q);
+
+ return relationlist;
+}
+
+static void pakfire_package_set_relationlist(PakfirePackage pkg, Id type, PakfireRelationList relationlist) {
+#if 0
+ // This implemention should be the fastest, but unfortunately does not work.
+ Queue q;
+ pakfire_relationlist_clone_to_queue(relationlist, &q);
+
+ Solvable* s = get_solvable(pkg);
+ solvable_set_idarray(s, type, &q);
+
+ queue_free(&q);
+#endif
+
+ Solvable* s = get_solvable(pkg);
+ solvable_unset(s, type);
+
+ int count = pakfire_relationlist_count(relationlist);
+ for (int i = 0; i < count; i++) {
+ PakfireRelation relation = pakfire_relationlist_get_clone(relationlist, i);
+ solvable_add_idarray(s, type, relation->id);
+
+ pakfire_relation_free(relation);
+ }
+}
+
+static void pakfire_package_add_relation(PakfirePackage pkg, Id type, PakfireRelation relation) {
+ Solvable* s = get_solvable(pkg);
+
+ solvable_add_idarray(s, type, relation->id);
+}
+
+PakfireRelationList pakfire_package_get_provides(PakfirePackage pkg) {
+ return pakfire_package_get_relationlist(pkg, SOLVABLE_PROVIDES);
+}
+
+void pakfire_package_set_provides(PakfirePackage pkg, PakfireRelationList relationlist) {
+ pakfire_package_set_relationlist(pkg, SOLVABLE_PROVIDES, relationlist);
+}
+
+void pakfire_package_add_provides(PakfirePackage pkg, PakfireRelation relation) {
+ pakfire_package_add_relation(pkg, SOLVABLE_PROVIDES, relation);
+}
+
+PakfireRelationList pakfire_package_get_prerequires(PakfirePackage pkg) {
+ #warning TODO
+ return NULL;
+}
+
+PakfireRelationList pakfire_package_get_requires(PakfirePackage pkg) {
+ return pakfire_package_get_relationlist(pkg, SOLVABLE_REQUIRES);
+}
+
+void pakfire_package_set_requires(PakfirePackage pkg, PakfireRelationList relationlist) {
+ pakfire_package_set_relationlist(pkg, SOLVABLE_REQUIRES, relationlist);
+}
+
+void pakfire_package_add_requires(PakfirePackage pkg, PakfireRelation relation) {
+ pakfire_package_add_relation(pkg, SOLVABLE_REQUIRES, relation);
+}
+
+PakfireRelationList pakfire_package_get_conflicts(PakfirePackage pkg) {
+ return pakfire_package_get_relationlist(pkg, SOLVABLE_CONFLICTS);
+}
+
+void pakfire_package_set_conflicts(PakfirePackage pkg, PakfireRelationList relationlist) {
+ pakfire_package_set_relationlist(pkg, SOLVABLE_CONFLICTS, relationlist);
+}
+
+void pakfire_package_add_conflicts(PakfirePackage pkg, PakfireRelation relation) {
+ pakfire_package_add_relation(pkg, SOLVABLE_CONFLICTS, relation);
+}
+
+PakfireRelationList pakfire_package_get_obsoletes(PakfirePackage pkg) {
+ return pakfire_package_get_relationlist(pkg, SOLVABLE_OBSOLETES);
+}
+
+void pakfire_package_set_obsoletes(PakfirePackage pkg, PakfireRelationList relationlist) {
+ pakfire_package_set_relationlist(pkg, SOLVABLE_OBSOLETES, relationlist);
+}
+
+void pakfire_package_add_obsoletes(PakfirePackage pkg, PakfireRelation relation) {
+ pakfire_package_add_relation(pkg, SOLVABLE_OBSOLETES, relation);
+}
+
+PakfireRelationList pakfire_package_get_recommends(PakfirePackage pkg) {
+ return pakfire_package_get_relationlist(pkg, SOLVABLE_RECOMMENDS);
+}
+
+void pakfire_package_set_recommends(PakfirePackage pkg, PakfireRelationList relationlist) {
+ pakfire_package_set_relationlist(pkg, SOLVABLE_RECOMMENDS, relationlist);
+}
+
+void pakfire_package_add_recommends(PakfirePackage pkg, PakfireRelation relation) {
+ pakfire_package_add_relation(pkg, SOLVABLE_RECOMMENDS, relation);
+}
+
+PakfireRelationList pakfire_package_get_suggests(PakfirePackage pkg) {
+ return pakfire_package_get_relationlist(pkg, SOLVABLE_SUGGESTS);
+}
+
+void pakfire_package_set_suggests(PakfirePackage pkg, PakfireRelationList relationlist) {
+ pakfire_package_set_relationlist(pkg, SOLVABLE_SUGGESTS, relationlist);
+}
+
+void pakfire_package_add_suggests(PakfirePackage pkg, PakfireRelation relation) {
+ pakfire_package_add_relation(pkg, SOLVABLE_SUGGESTS, relation);
+}
+
+PakfireRepo pakfire_package_get_repo(PakfirePackage pkg) {
+ Solvable* s = get_solvable(pkg);
+
+ return pakfire_repo_create_from_repo(pkg->pool, s->repo);
+}
+
+void pakfire_package_set_repo(PakfirePackage pkg, PakfireRepo repo) {
+ Solvable* s = get_solvable(pkg);
+
+ s->repo = pakfire_repo_get_solv_repo(repo);
+}
+
+char* pakfire_package_get_location(PakfirePackage pkg) {
+ pakfire_package_internalize_repo(pkg);
+
+ Solvable* s = get_solvable(pkg);
+
+ const char* location = solvable_get_location(s, NULL);
+ return pakfire_strdup(location);
+}
+
+static void pakfire_package_dump_add_line(char** str, const char* key, const char* val) {
+ if (val)
+ asprintf(str, "%s%-15s: %s\n", *str, key ? key : "", val);
+}
+
+static void pakfire_package_dump_add_lines(char** str, const char* key, const char* val) {
+ const char* string = val;
+
+ while (*string) {
+ char line[STRING_SIZE];
+ int counter = 0;
+
+ while (*string) {
+ if (*string == '\n') {
+ string++;
+ break;
+ }
+
+ line[counter++] = *string++;
+ }
+ line[counter] = '\0';
+
+ if (*line) {
+ pakfire_package_dump_add_line(str, key, line);
+ key = NULL;
+ }
+ }
+}
+
+static void pakfire_package_dump_add_line_date(char** str, const char* key, unsigned long long date) {
+ // Convert from integer to tm struct.
+ struct tm* timer = gmtime((time_t *)&date);
+
+ char val[STRING_SIZE];
+ strftime(val, STRING_SIZE, "%a, %d %b %Y %T %z", timer);
+
+ pakfire_package_dump_add_line(str, key, val);
+}
+
+static void pakfire_package_dump_add_line_relations(char** str, const char* key, PakfireRelationList deps) {
+ int count = pakfire_relationlist_count(deps);
+ for (int i = 0; i < count; i++) {
+ PakfireRelation relation = pakfire_relationlist_get_clone(deps, i);
+
+ if (relation) {
+ char* dep = pakfire_relation_str(relation);
+ pakfire_relation_free(relation);
+
+ // Stop here and don't list any files.
+ if (strcmp(PAKFIRE_SOLVABLE_FILEMARKER, dep) == 0)
+ break;
+
+ if (dep) {
+ pakfire_package_dump_add_line(str, (i == 0) ? key : "", dep);
+ pakfire_free(dep);
+ }
+ }
+ }
+}
+
+static void pakfire_package_dump_add_line_size(char** str, const char* key, unsigned long long size) {
+ char* val = pakfire_format_size(size);
+
+ if (val) {
+ pakfire_package_dump_add_line(str, key, val);
+ pakfire_free(val);
+ }
+}
+
+char* pakfire_package_dump(PakfirePackage pkg, int flags) {
+ char* string = "";
+
+ // Name
+ const char* name = pakfire_package_get_name(pkg);
+ pakfire_package_dump_add_line(&string, _("Name"), name);
+
+ // Version
+ const char* version = pakfire_package_get_version(pkg);
+ pakfire_package_dump_add_line(&string, _("Version"), version);
+
+ // Release
+ const char* release = pakfire_package_get_release(pkg);
+ pakfire_package_dump_add_line(&string, _("Release"), release);
+
+ // Size
+ unsigned long long size = pakfire_package_get_size(pkg);
+ pakfire_package_dump_add_line_size(&string, _("Size"), size);
+
+ // Installed size
+ if (pakfire_package_is_installed(pkg)) {
+ unsigned long long installsize = pakfire_package_get_installsize(pkg);
+ pakfire_package_dump_add_line_size(&string, _("Installed size"), installsize);
+
+ // Downloadsize
+ } else {
+ unsigned long long downloadsize = pakfire_package_get_downloadsize(pkg);
+ pakfire_package_dump_add_line_size(&string, _("Download size"), downloadsize);
+ }
+
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+ if (repo) {
+ const char* repo_name = pakfire_repo_get_name(repo);
+ pakfire_package_dump_add_line(&string, _("Repo"), repo_name);
+
+ pakfire_repo_free(repo);
+ }
+
+ // Summary
+ const char* summary = pakfire_package_get_summary(pkg);
+ pakfire_package_dump_add_line(&string, _("Summary"), summary);
+
+ // Description
+ const char* description = pakfire_package_get_description(pkg);
+ pakfire_package_dump_add_lines(&string, _("Description"), description);
+
+ // Groups
+ #warning TODO groups
+
+ // URL
+ const char* url = pakfire_package_get_url(pkg);
+ pakfire_package_dump_add_line(&string, _("URL"), url);
+
+ // License
+ const char* license = pakfire_package_get_license(pkg);
+ pakfire_package_dump_add_line(&string, _("License"), license);
+
+ if (flags & PAKFIRE_PKG_DUMP_LONG) {
+ // Maintainer
+ const char* maintainer = pakfire_package_get_maintainer(pkg);
+ pakfire_package_dump_add_line(&string, _("Maintainer"), maintainer);
+
+ // Vendor
+ const char* vendor = pakfire_package_get_vendor(pkg);
+ pakfire_package_dump_add_line(&string, _("Vendor"), vendor);
+
+ // UUID
+ const char* uuid = pakfire_package_get_uuid(pkg);
+ pakfire_package_dump_add_line(&string, _("UUID"), uuid);
+
+ // Build time
+ unsigned long long buildtime = pakfire_package_get_buildtime(pkg);
+ pakfire_package_dump_add_line_date(&string, _("Build date"), buildtime);
+
+ // Build host
+ const char* buildhost = pakfire_package_get_buildhost(pkg);
+ pakfire_package_dump_add_line(&string, _("Build host"), buildhost);
+
+ PakfireRelationList provides = pakfire_package_get_provides(pkg);
+ if (provides) {
+ pakfire_package_dump_add_line_relations(&string, _("Provides"), provides);
+ pakfire_relationlist_free(provides);
+ }
+
+ PakfireRelationList requires = pakfire_package_get_requires(pkg);
+ if (requires) {
+ pakfire_package_dump_add_line_relations(&string, _("Requires"), requires);
+ pakfire_relationlist_free(requires);
+ }
+
+ PakfireRelationList conflicts = pakfire_package_get_conflicts(pkg);
+ if (conflicts) {
+ pakfire_package_dump_add_line_relations(&string, _("Conflicts"), conflicts);
+ pakfire_relationlist_free(conflicts);
+ }
+
+ PakfireRelationList obsoletes = pakfire_package_get_obsoletes(pkg);
+ if (obsoletes) {
+ pakfire_package_dump_add_line_relations(&string, _("Obsoletes"), obsoletes);
+ pakfire_relationlist_free(obsoletes);
+ }
+
+ PakfireRelationList recommends = pakfire_package_get_recommends(pkg);
+ if (recommends) {
+ pakfire_package_dump_add_line_relations(&string, _("Recommends"), recommends);
+ pakfire_relationlist_free(recommends);
+ }
+
+ PakfireRelationList suggests = pakfire_package_get_suggests(pkg);
+ if (suggests) {
+ pakfire_package_dump_add_line_relations(&string, _("Suggests"), suggests);
+ pakfire_relationlist_free(suggests);
+ }
+ }
+
+ if (flags & PAKFIRE_PKG_DUMP_FILELIST) {
+ PakfireFile file = pakfire_package_get_filelist(pkg);
+
+ char* prefix = _("Filelist");
+ while (file) {
+ const char* name = pakfire_file_get_name(file);
+ pakfire_package_dump_add_line(&string, prefix, name);
+
+ file = pakfire_file_get_next(file);
+
+ // Only prefix the first line.
+ prefix = NULL;
+ }
+ }
+
+ return string;
+}
+
+int pakfire_package_is_cached(PakfirePackage pkg) {
+ PakfireCache cache = pakfire_pool_get_cache(pkg->pool);
+ if (!cache)
+ return 1;
+
+ return pakfire_cache_has_package(cache, pkg);
+}
+
+char* pakfire_package_get_cache_path(PakfirePackage pkg) {
+ PakfireCache cache = pakfire_pool_get_cache(pkg->pool);
+ if (!cache)
+ return NULL;
+
+ return pakfire_cache_get_package_path(cache, pkg);
+}
+
+char* pakfire_package_get_cache_full_path(PakfirePackage pkg) {
+ char* cache_path = NULL;
+
+ char* pkg_cache_path = pakfire_package_get_cache_path(pkg);
+ if (!pkg_cache_path)
+ return NULL;
+
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+ if (!repo)
+ goto out;
+
+ PakfireRepoCache repo_cache = pakfire_repo_get_cache(repo);
+ if (!repo_cache) {
+ goto out;
+ }
+
+ cache_path = pakfire_repocache_get_full_path(repo_cache, pkg_cache_path);
+
+out:
+ if (repo)
+ pakfire_repo_free(repo);
+
+ return cache_path;
+}
+
+static PakfireFile pakfire_package_fetch_legacy_filelist(PakfirePackage pkg) {
+ pakfire_package_internalize_repo(pkg);
+
+ PakfireFile file = NULL;
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+ Solvable* s = get_solvable(pkg);
+ Pool* p = pakfire_package_solv_pool(pkg);
+ Repo* r = pakfire_repo_get_solv_repo(repo);
+
+ int found_marker = 0;
+
+ Id id, *ids;
+ ids = r->idarraydata + s->provides;
+ while((id = *ids++) != 0) {
+ const char* filename = pool_dep2str(p, id);
+
+ if (found_marker) {
+ if (file) {
+ file = pakfire_file_append(file);
+ } else {
+ file = pakfire_file_create();
+ }
+
+ pakfire_file_set_name(file, filename);
+ continue;
+ }
+
+ if (strcmp(filename, PAKFIRE_SOLVABLE_FILEMARKER) == 0)
+ ++found_marker;
+ }
+
+ if (file) {
+ file = pakfire_file_get_first(file);
+
+ // Sort the output
+ file = pakfire_file_sort(file);
+ }
+
+ return file;
+}
+
+static PakfireFile pakfire_package_fetch_filelist(PakfirePackage pkg) {
+ pakfire_package_internalize_repo(pkg);
+
+ PakfireFile file = NULL;
+ Pool* pool = pakfire_package_solv_pool(pkg);
+ Repo* repo = pakfire_package_solv_repo(pkg);
+ Id handle = pakfire_package_get_handle(pkg);
+
+ Dataiterator di;
+ dataiterator_init(&di, pool, repo, handle,
+ SOLVABLE_FILELIST, NULL, SEARCH_FILES | SEARCH_COMPLETE_FILELIST);
+ while (dataiterator_step(&di)) {
+ if (file) {
+ file = pakfire_file_append(file);
+ } else {
+ file = pakfire_file_create();
+ }
+
+ pakfire_file_set_name(file, di.kv.str);
+ }
+ dataiterator_free(&di);
+
+ if (file) {
+ file = pakfire_file_get_first(file);
+
+ // Sort the result.
+ file = pakfire_file_sort(file);
+ }
+
+ // If the file list is empty, we fall back to read files
+ // in the older format.
+ if (!file)
+ file = pakfire_package_fetch_legacy_filelist(pkg);
+
+ return file;
+}
+
+PakfireFile pakfire_package_get_filelist(PakfirePackage pkg) {
+ if (!pkg->filelist) {
+ pkg->filelist = pakfire_package_fetch_filelist(pkg);
+ }
+
+ return pkg->filelist;
+}
+
+PakfireFile pakfire_package_filelist_append(PakfirePackage pkg, const char* filename) {
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+
+ Id handle = pakfire_package_get_handle(pkg);
+
+ char* dirname = pakfire_dirname(filename);
+ char* basename = pakfire_basename(filename);
+
+ Id did = repodata_str2dir(repo->filelist, dirname, 1);
+ if (!did)
+ did = repodata_str2dir(repo->filelist, "/", 1);
+
+ repodata_add_dirstr(repo->filelist, handle,
+ SOLVABLE_FILELIST, did, basename);
+
+ return NULL;
+}
+
+#if 0
+PakfireFile pakfire_package_filelist_append(PakfirePackage pkg) {
+ if (pkg->filelist) {
+ return pakfire_file_append(pkg->filelist);
+ }
+
+ PakfireFile file = pakfire_file_create();
+ pkg->filelist = file;
+
+ return file;
+}
+#endif
+
+void pakfire_package_filelist_remove(PakfirePackage pkg) {
+ if (pkg->filelist)
+ pakfire_file_free_all(pkg->filelist);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <sys/stat.h>
+
+#include <pakfire/constants.h>
+#include <pakfire/package.h>
+#include <pakfire/packagecache.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfirePackageCache pakfire_packagecache_create(PakfirePool pool, const char* path) {
+ PakfirePackageCache cache = pakfire_calloc(1, sizeof(*cache));
+
+ cache->pool = pool;
+ cache->path = pakfire_strdup(path);
+
+ return cache;
+}
+
+void pakfire_packagecache_free(PakfirePackageCache cache) {
+ pakfire_free(cache->path);
+ pakfire_free(cache);
+}
+
+const char* pakfire_packagecache_get_path(PakfirePackageCache cache) {
+ return cache->path;
+}
+
+char* pakfire_packagecache_get_package_path(PakfirePackageCache cache, PakfirePackage pkg) {
+ char buffer[STRING_SIZE] = "";
+
+ const char* filename = pakfire_package_get_filename(pkg);
+ const char* checksum = pakfire_package_get_checksum(pkg);
+
+ if (strlen(checksum) < 3)
+ return NULL;
+
+ snprintf(buffer, sizeof(buffer), "%s/%c%c/%s/%s", cache->path,
+ checksum[0], checksum[1], checksum + 2, filename);
+
+ return pakfire_strdup(buffer);
+}
+
+int pakfire_packagecache_has_package(PakfirePackageCache cache, PakfirePackage pkg) {
+ char* filename = pakfire_packagecache_get_package_path(cache, pkg);
+
+ // Check if stat() is successful.
+ struct stat buf;
+ int r = stat(filename, &buf);
+
+ pakfire_free(filename);
+ return (r == 0);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <solv/pool.h>
+#include <solv/pooltypes.h>
+#include <solv/solver.h>
+#include <solv/util.h>
+
+#include <pakfire/package.h>
+#include <pakfire/packagelist.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+#define BLOCK_SIZE 31
+
+PakfirePackageList pakfire_packagelist_create(void) {
+ PakfirePackageList list = pakfire_calloc(1, sizeof(*list));
+
+ return list;
+}
+
+void pakfire_packagelist_free(PakfirePackageList list) {
+ for (int i = 0; i < list->count; i++) {
+ PakfirePackage pkg = list->elements[i];
+ pakfire_package_free(pkg);
+ }
+
+ pakfire_free(list->elements);
+ pakfire_free(list);
+}
+
+int pakfire_packagelist_count(PakfirePackageList list) {
+ return list->count;
+}
+
+PakfirePackage pakfire_packagelist_get(PakfirePackageList list, int index) {
+ if (index < list->count)
+ return list->elements[index];
+
+ return NULL;
+}
+
+int pakfire_packagelist_has(PakfirePackageList list, PakfirePackage pkg) {
+ for (int i = 0; i < list->count; i++) {
+ PakfirePackage _pkg = list->elements[i];
+
+ if (pakfire_package_identical(pkg, _pkg))
+ return 1;
+ }
+
+ return 0;
+}
+
+void pakfire_packagelist_push(PakfirePackageList list, PakfirePackage pkg) {
+ list->elements = solv_extend(list->elements, list->count, 1, sizeof(pkg), BLOCK_SIZE);
+ list->elements[list->count++] = pkg;
+}
+
+void pakfire_packagelist_push_if_not_exists(PakfirePackageList list, PakfirePackage pkg) {
+ if (pakfire_packagelist_has(list, pkg))
+ return;
+
+ pakfire_packagelist_push(list, pkg);
+}
+
+PakfirePackageList pakfire_packagelist_from_queue(PakfirePool _pool, Queue* q) {
+ PakfirePackageList list = pakfire_packagelist_create();
+
+ Pool* pool = _pool->pool;
+ Id p, pp;
+ for (int i = 0; i < q->count; i += 2) {
+ FOR_JOB_SELECT(p, pp, q->elements[i], q->elements[i + 1]) {
+ PakfirePackage pkg = pakfire_package_create(_pool, p);
+ pakfire_packagelist_push(list, pkg);
+ }
+ }
+
+ return list;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+
+#include <solv/evr.h>
+#include <solv/pool.h>
+#include <solv/poolarch.h>
+#include <solv/queue.h>
+#include <solv/repo.h>
+
+#include <pakfire/cache.h>
+#include <pakfire/package.h>
+#include <pakfire/packagelist.h>
+#include <pakfire/pool.h>
+#include <pakfire/repo.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfirePool pakfire_pool_create(const char* arch) {
+ PakfirePool pool = pakfire_calloc(1, sizeof(*pool));
+ pool->pool = pool_create();
+
+ queue_init(&pool->installonly);
+
+ // Set architecture
+ pool_setarch(pool->pool, arch);
+
+ return pool;
+}
+
+static void pakfire_pool_free_repos(Pool* pool) {
+ Repo* repo;
+ int i;
+
+ FOR_REPOS(i, repo) {
+ PakfireRepo r = repo->appdata;
+ if (r == NULL)
+ continue;
+
+ pakfire_repo_free(r);
+ }
+}
+
+void pakfire_pool_free(PakfirePool pool) {
+ pakfire_pool_free_repos(pool->pool);
+
+ queue_free(&pool->installonly);
+
+ pool_free(pool->pool);
+ pakfire_free(pool);
+}
+
+int pakfire_pool_version_compare(PakfirePool pool, const char* evr1, const char* evr2) {
+ return pool_evrcmp_str(pool->pool, evr1, evr2, EVRCMP_COMPARE);
+}
+
+int pakfire_pool_count(PakfirePool pool) {
+ int cnt = 0;
+
+ for (int i = 2; i < pool->pool->nsolvables; i++) {
+ Solvable* s = pool->pool->solvables + i;
+ if (s->repo)
+ cnt++;
+ }
+
+ return cnt;
+}
+
+void pakfire_pool_make_provides_ready(PakfirePool pool) {
+ if (!pool->provides_ready) {
+ pool_addfileprovides(pool->pool);
+ pool_createwhatprovides(pool->pool);
+ pool->provides_ready = 1;
+ }
+}
+
+PakfireRepo pakfire_pool_get_installed_repo(PakfirePool pool) {
+ Pool* p = pool->pool;
+
+ if (!p->installed)
+ return NULL;
+
+ return pakfire_repo_create_from_repo(pool, p->installed);
+}
+
+void pakfire_pool_set_installed_repo(PakfirePool pool, PakfireRepo repo) {
+ if (!repo) {
+ pool_set_installed(pool->pool, NULL);
+ return;
+ }
+
+ assert(pool == repo->pool);
+ pool_set_installed(pool->pool, repo->repo);
+}
+
+const char** pakfire_pool_get_installonly(PakfirePool pool) {
+ Queue q;
+ queue_init_clone(&q, &pool->installonly);
+
+ const char** installonly = pakfire_malloc(sizeof(const char*) * (q.count + 1));
+
+ int i = 0;
+ while (q.count) {
+ installonly[i++] = pool_id2str(pool->pool, queue_shift(&q));
+ }
+ installonly[i] = NULL;
+
+ queue_free(&q);
+
+ return installonly;
+}
+
+void pakfire_pool_set_installonly(PakfirePool pool, const char** installonly) {
+ queue_empty(&pool->installonly);
+
+ if (installonly == NULL)
+ return;
+
+ const char* name;
+ while ((name = *installonly++) != NULL)
+ queue_pushunique(&pool->installonly, pool_str2id(pool->pool, name, 1));
+}
+
+const char* pakfire_pool_get_cache_path(PakfirePool pool) {
+ if (!pool->cache)
+ return NULL;
+
+ return pakfire_cache_get_path(pool->cache);
+}
+
+void pakfire_pool_set_cache_path(PakfirePool pool, const char* path) {
+ if (pool->cache)
+ pakfire_cache_free(pool->cache);
+
+ pool->cache = pakfire_cache_create(pool, path);
+}
+
+PakfireCache pakfire_pool_get_cache(PakfirePool pool) {
+ return pool->cache;
+}
+
+static PakfirePackageList pakfire_pool_dataiterator(PakfirePool pool, const char* what, int key, int flags) {
+ PakfirePackageList list = pakfire_packagelist_create();
+ pakfire_pool_make_provides_ready(pool);
+
+ int di_flags = 0;
+ if (flags & PAKFIRE_SUBSTRING)
+ di_flags |= SEARCH_SUBSTRING;
+ else
+ di_flags |= SEARCH_STRING;
+
+ if (flags & PAKFIRE_ICASE)
+ di_flags |= SEARCH_NOCASE;
+ if (flags & PAKFIRE_GLOB)
+ di_flags |= SEARCH_GLOB;
+
+ Dataiterator di;
+ dataiterator_init(&di, pool->pool, 0, 0, key, what, di_flags);
+ while (dataiterator_step(&di)) {
+ PakfirePackage pkg = pakfire_package_create(pool, di.solvid);
+ pakfire_packagelist_push_if_not_exists(list, pkg);
+ }
+ dataiterator_free(&di);
+
+ return list;
+}
+
+static PakfirePackageList pakfire_pool_search_name(PakfirePool _pool, const char* name, int flags) {
+ if (!flags) {
+ PakfirePackageList list = pakfire_packagelist_create();
+ pakfire_pool_make_provides_ready(_pool);
+
+ Pool* pool = _pool->pool;
+ Id id = pool_str2id(pool, name, 0);
+ if (id == 0)
+ return list;
+
+ Id p, pp;
+ FOR_PROVIDES(p, pp, id) {
+ Solvable* s = pool_id2solvable(pool, p);
+
+ if (s->name == id) {
+ PakfirePackage pkg = pakfire_package_create(_pool, p);
+ pakfire_packagelist_push_if_not_exists(list, pkg);
+ }
+ }
+
+ return list;
+ }
+
+ return pakfire_pool_dataiterator(_pool, name, SOLVABLE_NAME, flags);
+}
+
+static PakfirePackageList pakfire_pool_search_provides(PakfirePool _pool, const char* provides, int flags) {
+ if (!flags) {
+ PakfirePackageList list = pakfire_packagelist_create();
+ pakfire_pool_make_provides_ready(_pool);
+
+ Pool* pool = _pool->pool;
+ Id id = pool_str2id(pool, provides, 0);
+ if (id == 0)
+ return list;
+
+ Id p, pp;
+ FOR_PROVIDES(p, pp, id) {
+ PakfirePackage pkg = pakfire_package_create(_pool, p);
+ pakfire_packagelist_push_if_not_exists(list, pkg);
+ }
+
+ return list;
+ }
+
+ return pakfire_pool_dataiterator(_pool, provides, SOLVABLE_PROVIDES, flags);
+}
+
+PakfirePackageList pakfire_pool_whatprovides(PakfirePool pool, const char* what, int flags) {
+ assert((flags & ~(PAKFIRE_ICASE|PAKFIRE_NAME_ONLY|PAKFIRE_GLOB)) == 0);
+
+ if (flags & PAKFIRE_NAME_ONLY) {
+ flags &= ~PAKFIRE_NAME_ONLY;
+
+ return pakfire_pool_search_name(pool, what, flags);
+ } else {
+ return pakfire_pool_search_provides(pool, what, flags);
+ }
+}
+
+PakfirePackageList pakfire_pool_search(PakfirePool pool, const char* what, int flags) {
+ return pakfire_pool_dataiterator(pool, what, 0, PAKFIRE_SUBSTRING);
+}
+
+char* pakfire_pool_tmpdup(Pool* pool, const char* s) {
+ char* dup = pool_alloctmpspace(pool, strlen(s) + 1);
+
+ return strcpy(dup, s);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+
+#include <solv/pooltypes.h>
+#include <solv/queue.h>
+#include <solv/solver.h>
+
+#include <pakfire/packagelist.h>
+#include <pakfire/pool.h>
+#include <pakfire/relation.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+static int cmptype2relflags(int type) {
+ int flags = 0;
+
+ if (type & PAKFIRE_EQ)
+ flags |= REL_EQ;
+ if (type & PAKFIRE_LT)
+ flags |= REL_LT;
+ if (type & PAKFIRE_GT)
+ flags |= REL_GT;
+
+ return flags;
+}
+
+PakfireRelation pakfire_relation_create(PakfirePool pool, const char* name, int cmp_type, const char* evr) {
+ Pool* p = pool->pool;
+
+ Id id = pool_str2id(p, name, 1);
+
+ if (id == STRID_NULL || id == STRID_EMPTY)
+ return NULL;
+
+ if (evr) {
+ assert(cmp_type);
+
+ Id ievr = pool_str2id(p, evr, 1);
+ int flags = cmptype2relflags(cmp_type);
+ id = pool_rel2id(p, id, ievr, flags, 1);
+ }
+
+ return pakfire_relation_create_from_id(pool, id);
+}
+
+PakfireRelation pakfire_relation_create_from_id(PakfirePool pool, Id id) {
+ PakfireRelation relation = pakfire_calloc(1, sizeof(*relation));
+
+ relation->pool = pool;
+ relation->id = id;
+
+ return relation;
+}
+
+void pakfire_relation_free(PakfireRelation relation) {
+ pakfire_free(relation);
+}
+
+Id pakfire_relation_id(PakfireRelation relation) {
+ return relation->id;
+}
+
+char* pakfire_relation_str(PakfireRelation relation) {
+ Pool* pool = pakfire_relation_solv_pool(relation);
+
+ const char* str = pool_dep2str(pool, relation->id);
+
+ return pakfire_strdup(str);
+}
+
+int pakfire_relation2queue(const PakfireRelation relation, Queue* queue, int solver_action) {
+ queue_push2(queue, SOLVER_SOLVABLE_PROVIDES|solver_action, relation->id);
+
+ return 0;
+}
+
+PakfirePackageList pakfire_relation_providers(PakfireRelation relation) {
+ Queue q;
+ queue_init(&q);
+
+ pakfire_relation2queue(relation, &q, 0);
+
+ PakfirePackageList list = pakfire_packagelist_from_queue(relation->pool, &q);
+
+ queue_free(&q);
+
+ return list;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <solv/pooltypes.h>
+#include <solv/queue.h>
+
+#include <pakfire/pool.h>
+#include <pakfire/relation.h>
+#include <pakfire/relationlist.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireRelationList pakfire_relationlist_create(PakfirePool pool) {
+ PakfireRelationList relationlist = pakfire_calloc(1, sizeof(*relationlist));
+ if (relationlist) {
+ relationlist->pool = pool;
+ queue_init(&relationlist->queue);
+ }
+
+ return relationlist;
+}
+
+void pakfire_relationlist_free(PakfireRelationList relationlist) {
+ queue_free(&relationlist->queue);
+ pakfire_free(relationlist);
+}
+
+void pakfire_relationlist_add(PakfireRelationList relationlist, PakfireRelation relation) {
+ queue_push(&relationlist->queue, relation->id);
+}
+
+int pakfire_relationlist_count(PakfireRelationList relationlist) {
+ return relationlist->queue.count;
+}
+
+PakfireRelationList pakfire_relationlist_from_queue(PakfirePool pool, Queue q) {
+ PakfireRelationList relationlist = pakfire_calloc(1, sizeof(*relationlist));
+ if (relationlist) {
+ relationlist->pool = pool;
+ queue_init_clone(&relationlist->queue, &q);
+ }
+
+ return relationlist;
+}
+
+PakfireRelation pakfire_relationlist_get_clone(PakfireRelationList relationlist, int index) {
+ Id id = relationlist->queue.elements[index];
+
+ return pakfire_relation_create_from_id(relationlist->pool, id);
+}
+
+void pakfire_relationlist_clone_to_queue(PakfireRelationList relationlist, Queue* q) {
+ queue_init_clone(q, &relationlist->queue);
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <string.h>
+
+#include <solv/repo.h>
+#include <solv/repo_solv.h>
+#include <solv/repo_write.h>
+
+#include <pakfire/constants.h>
+#include <pakfire/errno.h>
+#include <pakfire/package.h>
+#include <pakfire/pool.h>
+#include <pakfire/repo.h>
+#include <pakfire/repocache.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+static Repo* get_repo_by_name(Pool* pool, const char* name) {
+ Repo* repo;
+ int i;
+
+ FOR_REPOS(i, repo) {
+ if (strcmp(repo->name, name) == 0)
+ return repo;
+ }
+
+ return NULL;
+}
+
+static PakfireRepo get_pakfire_repo_by_name(PakfirePool pool, const char* name) {
+ Repo* repo = get_repo_by_name(pool->pool, name);
+
+ if (repo)
+ return repo->appdata;
+
+ return NULL;
+}
+
+PakfireRepo pakfire_repo_create(PakfirePool pool, const char* name) {
+ PakfireRepo repo = get_pakfire_repo_by_name(pool, name);
+ if (repo) {
+ repo->nrefs++;
+ return repo;
+ }
+
+ Repo* r = get_repo_by_name(pool->pool, name);
+ if (!r)
+ r = repo_create(pool->pool, name);
+
+ return pakfire_repo_create_from_repo(pool, r);
+}
+
+PakfireRepo pakfire_repo_create_from_repo(PakfirePool pool, Repo* r) {
+ PakfireRepo repo;
+
+ if (r->appdata) {
+ repo = r->appdata;
+ repo->nrefs++;
+
+ } else {
+ repo = pakfire_calloc(1, sizeof(*repo));
+ if (repo) {
+ repo->pool = pool;
+
+ repo->repo = r;
+ repo->cache = pakfire_repocache_create(repo);
+ repo->repo->appdata = repo;
+
+ repo->filelist = repo_add_repodata(r, REPO_EXTEND_SOLVABLES|REPO_LOCALPOOL|REPO_NO_INTERNALIZE|REPO_NO_LOCATION);
+
+ // Initialize reference counter
+ repo->nrefs = 1;
+ }
+ }
+
+ return repo;
+}
+
+void pakfire_repo_free(PakfireRepo repo) {
+ if (--repo->nrefs > 0)
+ return;
+
+ if (repo->repo)
+ repo->repo->appdata = NULL;
+
+ // Free repodata.
+ repodata_free(repo->filelist);
+
+ pakfire_free(repo);
+
+ if (repo->cache)
+ pakfire_repocache_free(repo->cache);
+}
+
+PakfirePool pakfire_repo_pool(PakfireRepo repo) {
+ return repo->pool;
+}
+
+int pakfire_repo_identical(PakfireRepo repo1, PakfireRepo repo2) {
+ Repo* r1 = repo1->repo;
+ Repo* r2 = repo2->repo;
+
+ return strcmp(r1->name, r2->name);
+}
+
+int pakfire_repo_cmp(PakfireRepo repo1, PakfireRepo repo2) {
+ Repo* r1 = repo1->repo;
+ Repo* r2 = repo2->repo;
+
+ if (r1->priority > r2->priority)
+ return 1;
+
+ else if (r1->priority < r2->priority)
+ return -1;
+
+ return strcmp(r1->name, r2->name);
+}
+
+int pakfire_repo_count(PakfireRepo repo) {
+ Pool* pool = pakfire_repo_solv_pool(repo);
+ int cnt = 0;
+
+ for (int i = 2; i < pool->nsolvables; i++) {
+ Solvable* s = pool->solvables + i;
+ if (s->repo && s->repo == repo->repo)
+ cnt++;
+ }
+
+ return cnt;
+}
+
+void pakfire_repo_internalize(PakfireRepo repo) {
+ repo_internalize(repo->repo);
+}
+
+const char* pakfire_repo_get_name(PakfireRepo repo) {
+ return repo->repo->name;
+}
+
+void pakfire_repo_set_name(PakfireRepo repo, const char* name) {
+ repo->repo->name = pakfire_strdup(name);
+}
+
+int pakfire_repo_get_enabled(PakfireRepo repo) {
+ return !repo->repo->disabled;
+}
+
+void pakfire_repo_set_enabled(PakfireRepo repo, int enabled) {
+ repo->repo->disabled = !enabled;
+
+ PakfirePool pool = pakfire_repo_pool(repo);
+ pool->provides_ready = 0;
+}
+
+int pakfire_repo_get_priority(PakfireRepo repo) {
+ return repo->repo->priority;
+}
+
+void pakfire_repo_set_priority(PakfireRepo repo, int priority) {
+ repo->repo->priority = priority;
+}
+
+int pakfire_repo_is_installed_repo(PakfireRepo repo) {
+ PakfirePool pool = pakfire_repo_pool(repo);
+
+ PakfireRepo installed_repo = pakfire_pool_get_installed_repo(pool);
+
+ return pakfire_repo_identical(repo, installed_repo);
+}
+
+int pakfire_repo_read_solv(PakfireRepo repo, const char* filename, int flags) {
+ FILE* f = fopen(filename, "rb");
+ if (!f) {
+ return PAKFIRE_E_IO;
+ }
+
+ int ret = pakfire_repo_read_solv_fp(repo, f, flags);
+ fclose(f);
+
+ return ret;
+}
+
+int pakfire_repo_read_solv_fp(PakfireRepo repo, FILE *f, int flags) {
+ int ret = repo_add_solv(repo->repo, f, flags);
+
+ repo->pool->provides_ready = 0;
+
+ return ret;
+}
+
+int pakfire_repo_write_solv(PakfireRepo repo, const char* filename, int flags) {
+ FILE* f = fopen(filename, "wb");
+ if (!f) {
+ return PAKFIRE_E_IO;
+ }
+
+ int ret = pakfire_repo_write_solv_fp(repo, f, flags);
+ fclose(f);
+
+ return ret;
+}
+
+int pakfire_repo_write_solv_fp(PakfireRepo repo, FILE *f, int flags) {
+ pakfire_repo_internalize(repo);
+
+ return repo_write(repo->repo, f);
+}
+
+PakfirePackage pakfire_repo_add_package(PakfireRepo repo) {
+ Id id = repo_add_solvable(repo->repo);
+
+ return pakfire_package_create(repo->pool, id);
+}
+
+PakfireRepoCache pakfire_repo_get_cache(PakfireRepo repo) {
+ return repo->cache;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <stdio.h>
+#include <sys/stat.h>
+
+#include <pakfire/cache.h>
+#include <pakfire/constants.h>
+#include <pakfire/package.h>
+#include <pakfire/repo.h>
+#include <pakfire/repocache.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+static char* pakfire_repocache_prefix(PakfireRepoCache repo_cache) {
+ const char* repo_name = pakfire_repo_get_name(repo_cache->repo);
+
+ char buffer[STRING_SIZE] = "";
+ snprintf(buffer, sizeof(buffer), "repodata/%s", repo_name);
+
+ return pakfire_strdup(buffer);
+}
+
+PakfireRepoCache pakfire_repocache_create(PakfireRepo repo) {
+ PakfireRepoCache repo_cache = pakfire_calloc(1, sizeof(*repo_cache));
+
+ repo_cache->repo = repo;
+ repo_cache->prefix = pakfire_repocache_prefix(repo_cache);
+
+ return repo_cache;
+}
+
+void pakfire_repocache_free(PakfireRepoCache repo_cache) {
+ pakfire_free(repo_cache->prefix);
+ pakfire_free(repo_cache);
+}
+
+char* pakfire_repocache_get_cache_path(PakfireRepoCache repo_cache, const char* path) {
+ return pakfire_path_join(repo_cache->prefix, path);
+}
+
+char* pakfire_repocache_get_full_path(PakfireRepoCache repo_cache, const char* path) {
+ char* cache_path = pakfire_repocache_get_cache_path(repo_cache, path);
+
+ PakfireCache cache = pakfire_repocache_cache(repo_cache);
+ char* full_path = pakfire_cache_get_full_path(cache, cache_path);
+
+ pakfire_free(cache_path);
+
+ return full_path;
+}
+
+int pakfire_repocache_has_file(PakfireRepoCache repo_cache, const char* filename) {
+ char* cache_filename = pakfire_repocache_get_cache_path(repo_cache, filename);
+
+ PakfireCache cache = pakfire_repocache_cache(repo_cache);
+ int r = pakfire_cache_has_file(cache, cache_filename);
+
+ pakfire_free(cache_filename);
+ return r;
+}
+
+int pakfire_repocache_age(PakfireRepoCache repo_cache, const char* filename) {
+ char* cache_filename = pakfire_repocache_get_cache_path(repo_cache, filename);
+
+ PakfireCache cache = pakfire_repocache_cache(repo_cache);
+ int age = pakfire_cache_age(cache, cache_filename);
+ pakfire_free(cache_filename);
+
+ return age;
+}
+
+FILE* pakfire_repocache_open(PakfireRepoCache repo_cache, const char* filename, const char* flags) {
+ char* cache_filename = pakfire_repocache_get_cache_path(repo_cache, filename);
+
+ PakfireCache cache = pakfire_repocache_cache(repo_cache);
+ FILE* fp = pakfire_cache_open(cache, cache_filename, flags);
+ pakfire_free(cache_filename);
+
+ return fp;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <solv/queue.h>
+#include <solv/solver.h>
+#include <solv/transaction.h>
+
+#ifdef DEBUG
+# include <solv/solverdebug.h>
+#endif
+
+#include <pakfire/package.h>
+#include <pakfire/request.h>
+#include <pakfire/selector.h>
+#include <pakfire/transaction.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireRequest pakfire_request_create(PakfirePool pool) {
+ PakfireRequest request = pakfire_calloc(1, sizeof(*request));
+ request->pool = pool;
+
+ queue_init(&request->queue);
+
+ return request;
+}
+
+void pakfire_request_free(PakfireRequest request) {
+ if (request->transaction)
+ transaction_free(request->transaction);
+
+ if (request->solver)
+ solver_free(request->solver);
+
+ queue_free(&request->queue);
+
+ pakfire_free(request);
+}
+
+PakfirePool pakfire_request_pool(PakfireRequest request) {
+ return request->pool;
+}
+
+static void init_solver(PakfireRequest request, int flags) {
+ PakfirePool pool = pakfire_request_pool(request);
+
+ Solver* solver = solver_create(pool->pool);
+
+ /* Free older solver */
+ if (request->solver) {
+ solver_free(request->solver);
+ request->solver = NULL;
+ }
+
+ request->solver = solver;
+
+ if (flags & PAKFIRE_SOLVER_ALLOW_UNINSTALL)
+ solver_set_flag(solver, SOLVER_FLAG_ALLOW_UNINSTALL, 1);
+
+ /* no vendor locking */
+ solver_set_flag(solver, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
+
+ /* no arch change for forcebest */
+ solver_set_flag(solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
+}
+
+static int solve(PakfireRequest request, Queue* queue) {
+ /* Remove any previous transactions */
+ if (request->transaction) {
+ transaction_free(request->transaction);
+ request->transaction = NULL;
+ }
+
+ pakfire_pool_make_provides_ready(request->pool);
+
+ if (solver_solve(request->solver, queue)) {
+#ifdef DEBUG
+ solver_printallsolutions(request->solver);
+#endif
+
+ return 1;
+ }
+
+ /* If the solving process was successful, we get the transaction
+ * from the solver. */
+ request->transaction = solver_create_transaction(request->solver);
+ transaction_order(request->transaction, 0);
+
+ return 0;
+}
+
+int pakfire_request_solve(PakfireRequest request, int flags) {
+ init_solver(request, flags);
+
+ Queue queue;
+ queue_init_clone(&queue, &request->queue);
+
+ /* Apply forcebest */
+ if (flags & PAKFIRE_SOLVER_FORCE_BEST) {
+ for (int i = 0; i < queue.count; i += 2) {
+ queue.elements[i] |= SOLVER_FORCEBEST;
+ }
+ }
+
+ /* turn off implicit obsoletes for installonly packages */
+ PakfirePool pool = request->pool;
+ for (int i = 0; i < pool->installonly.count; i++)
+ queue_push2(&queue, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_PROVIDES,
+ pool->installonly.elements[i]);
+
+ // XXX EXCLUDES
+
+ int ret = solve(request, &queue);
+
+ queue_free(&queue);
+
+ return ret;
+}
+
+PakfireTransaction pakfire_request_get_transaction(PakfireRequest request) {
+ if (!request->transaction)
+ return NULL;
+
+ return pakfire_transaction_create(request->pool, request->transaction);
+}
+
+int pakfire_request_install(PakfireRequest request, PakfirePackage package) {
+ queue_push2(&request->queue, SOLVER_SOLVABLE|SOLVER_INSTALL, pakfire_package_id(package));
+
+ return 0;
+}
+
+int pakfire_request_install_relation(PakfireRequest request, PakfireRelation relation) {
+ return pakfire_relation2queue(relation, &request->queue, SOLVER_INSTALL);
+}
+
+int pakfire_request_install_selector(PakfireRequest request, PakfireSelector selector) {
+ return pakfire_selector2queue(selector, &request->queue, SOLVER_INSTALL);
+}
+
+static int erase_flags(int flags) {
+ int additional = 0;
+
+ if (flags & PAKFIRE_CLEAN_DEPS)
+ additional |= SOLVER_CLEANDEPS;
+
+ return additional;
+}
+
+int pakfire_request_erase(PakfireRequest request, PakfirePackage package, int flags) {
+ int additional = erase_flags(flags);
+ queue_push2(&request->queue, SOLVER_SOLVABLE|SOLVER_ERASE|additional, pakfire_package_id(package));
+
+ return 0;
+}
+
+int pakfire_request_erase_relation(PakfireRequest request, PakfireRelation relation, int flags) {
+ int additional = erase_flags(flags);
+
+ return pakfire_relation2queue(relation, &request->queue, SOLVER_ERASE|additional);
+}
+
+int pakfire_request_erase_selector(PakfireRequest request, PakfireSelector selector, int flags) {
+ int additional = erase_flags(flags);
+
+ return pakfire_selector2queue(selector, &request->queue, SOLVER_ERASE|additional);
+}
+
+int pakfire_request_upgrade(PakfireRequest request, PakfirePackage package) {
+ return pakfire_request_install(request, package);
+}
+
+int pakfire_request_upgrade_relation(PakfireRequest request, PakfireRelation relation) {
+ return pakfire_relation2queue(relation, &request->queue, SOLVER_UPDATE);
+}
+
+int pakfire_request_upgrade_selector(PakfireRequest request, PakfireSelector selector) {
+ return pakfire_selector2queue(selector, &request->queue, SOLVER_UPDATE);
+}
+
+int pakfire_request_upgrade_all(PakfireRequest request) {
+ queue_push2(&request->queue, SOLVER_UPDATE|SOLVER_SOLVABLE_ALL, 0);
+
+ return 0;
+}
+
+int pakfire_request_distupgrade(PakfireRequest request) {
+ queue_push2(&request->queue, SOLVER_DISTUPGRADE|SOLVER_SOLVABLE_ALL, 0);
+
+ return 0;
+}
+
+int pakfire_request_lock(PakfireRequest request, PakfirePackage package) {
+ queue_push2(&request->queue, SOLVER_SOLVABLE|SOLVER_LOCK, pakfire_package_id(package));
+
+ return 0;
+}
+
+int pakfire_request_lock_relation(PakfireRequest request, PakfireRelation relation) {
+ return pakfire_relation2queue(relation, &request->queue, SOLVER_LOCK);
+}
+
+int pakfire_request_lock_selector(PakfireRequest request, PakfireSelector selector) {
+ return pakfire_selector2queue(selector, &request->queue, SOLVER_LOCK);
+}
+
+int pakfire_request_verify(PakfireRequest request) {
+ queue_push2(&request->queue, SOLVER_VERIFY|SOLVER_SOLVABLE_ALL, 0);
+
+ return 0;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <assert.h>
+
+#include <solv/pool.h>
+#include <solv/queue.h>
+#include <solv/solver.h>
+
+#include <pakfire/errno.h>
+#include <pakfire/filter.h>
+#include <pakfire/package.h>
+#include <pakfire/packagelist.h>
+#include <pakfire/pool.h>
+#include <pakfire/selector.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireSelector pakfire_selector_create(PakfirePool pool) {
+ PakfireSelector selector = pakfire_calloc(1, sizeof(*selector));
+ selector->pool = pool;
+
+ selector->f_arch = NULL;
+ selector->f_name = NULL;
+ selector->f_evr = NULL;
+ selector->f_provides = NULL;
+
+ return selector;
+}
+
+void pakfire_selector_free(PakfireSelector selector) {
+ pakfire_free(selector);
+}
+
+static int pakfire_selector_valid_setting(int keyname, int cmp_type) {
+ switch (keyname) {
+ case PAKFIRE_PKG_ARCH:
+ case PAKFIRE_PKG_EVR:
+ case PAKFIRE_PKG_VERSION:
+ case PAKFIRE_PKG_PROVIDES:
+ return cmp_type == PAKFIRE_EQ;
+
+ case PAKFIRE_PKG_NAME:
+ return (cmp_type == PAKFIRE_EQ || cmp_type == PAKFIRE_GLOB);
+
+ default:
+ return 0;
+ }
+}
+
+static void pakfire_selector_replace_filter(PakfireFilter* filter, int keyname, int cmp_type, const char* match) {
+ if (*filter)
+ pakfire_filter_free(*filter);
+
+ PakfireFilter f = pakfire_filter_create();
+
+ f->keyname = keyname;
+ f->cmp_type = cmp_type;
+ f->match = pakfire_strdup(match);
+
+ *filter = f;
+}
+
+int pakfire_selector_set(PakfireSelector selector, int keyname, int cmp_type, const char* match) {
+ if (!pakfire_selector_valid_setting(keyname, cmp_type))
+ return PAKFIRE_E_SELECTOR;
+
+ PakfireFilter* filter = NULL;
+
+ switch (keyname) {
+ case PAKFIRE_PKG_ARCH:
+ filter = &selector->f_arch;
+ break;
+
+ case PAKFIRE_PKG_EVR:
+ case PAKFIRE_PKG_VERSION:
+ filter = &selector->f_evr;
+ break;
+
+ case PAKFIRE_PKG_NAME:
+ if (selector->f_provides)
+ return PAKFIRE_E_SELECTOR;
+
+ filter = &selector->f_name;
+ break;
+
+ case PAKFIRE_PKG_PROVIDES:
+ if (selector->f_name)
+ return PAKFIRE_E_SELECTOR;
+
+ filter = &selector->f_provides;
+ break;
+
+ default:
+ return PAKFIRE_E_SELECTOR;
+ }
+
+ assert(filter);
+
+ pakfire_selector_replace_filter(filter, keyname, cmp_type, match);
+
+ return 0;
+}
+
+PakfirePackageList pakfire_selector_providers(PakfireSelector selector) {
+ Queue q;
+ queue_init(&q);
+
+ pakfire_selector2queue(selector, &q, 0);
+
+ PakfirePackageList list = pakfire_packagelist_from_queue(selector->pool, &q);
+
+ queue_free(&q);
+
+ return list;
+}
+
+static int queue_has(Queue* queue, Id what, Id id) {
+ for (int i = 0; i < queue->count; i += 2) {
+ if (queue->elements[i] == what && queue->elements[i + 1] == id)
+ return 1;
+ }
+
+ return 0;
+}
+
+static Id str2archid(Pool* pool, const char* arch) {
+ // originally from libsolv/examples/solv.c:str2archid()
+
+ if (!*arch)
+ return 0;
+
+ Id id = pool_str2id(pool, arch, 0);
+ if (id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
+ return id;
+
+ if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
+ return 0;
+
+ return id;
+}
+
+static int filter_arch2queue(PakfirePool pool, const PakfireFilter f, Queue* queue) {
+ if (f == NULL)
+ return 0;
+
+ assert(f->cmp_type == PAKFIRE_EQ);
+
+ Id archid = str2archid(pool->pool, f->match);
+ if (archid == 0)
+ return PAKFIRE_E_ARCH;
+
+ for (int i = 0; i < queue->count; i += 2) {
+ assert((queue->elements[i] & SOLVER_SELECTMASK) == SOLVER_SOLVABLE_NAME);
+
+ Id dep = queue->elements[i + 1];
+ queue->elements[i + 1] = pool_rel2id(pool->pool, dep, archid, REL_ARCH, 1);
+ queue->elements[i] |= SOLVER_SETARCH;
+ }
+
+ return 0;
+}
+
+static int filter_evr2queue(PakfirePool pool, const PakfireFilter f, Queue* queue) {
+ if (f == NULL)
+ return 0;
+
+ assert(f->cmp_type == PAKFIRE_EQ);
+
+ Id evr = pool_str2id(pool->pool, f->match, 1);
+
+ for (int i = 0; i < queue->count; i += 2) {
+ assert((queue->elements[i] & SOLVER_SELECTMASK) == SOLVER_SOLVABLE_NAME);
+
+ Id dep = queue->elements[i + 1];
+ queue->elements[i + 1] = pool_rel2id(pool->pool, dep, evr, REL_EQ, 1);
+ queue->elements[i] |= PAKFIRE_PKG_VERSION ? SOLVER_SETEV : SOLVER_SETEVR;
+ }
+
+ return 0;
+}
+
+static int filter_name2queue(PakfirePool pool, const PakfireFilter f, Queue* queue) {
+ if (f == NULL)
+ return 0;
+
+ const char* name = f->match;
+ Id id;
+ Dataiterator di;
+
+ switch (f->cmp_type) {
+ case PAKFIRE_EQ:
+ id = pool_str2id(pool->pool, name, 0);
+ if (id)
+ queue_push2(queue, SOLVER_SOLVABLE_NAME, id);
+ break;
+
+ case PAKFIRE_GLOB:
+ dataiterator_init(&di, pool->pool, 0, 0, SOLVABLE_NAME, name, SEARCH_GLOB);
+
+ while (dataiterator_step(&di)) {
+ assert(di.idp);
+ Id id = *di.idp;
+
+ if (queue_has(queue, SOLVABLE_NAME, id))
+ continue;
+
+ queue_push2(queue, SOLVER_SOLVABLE_NAME, id);
+ }
+
+ dataiterator_free(&di);
+ break;
+
+ default:
+ assert(0);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int filter_provides2queue(PakfirePool pool, const PakfireFilter f, Queue* queue) {
+ if (f == NULL)
+ return 0;
+
+ Id id;
+
+ switch (f->cmp_type) {
+ case PAKFIRE_EQ:
+ id = pool_str2id(pool->pool, f->match, 0);
+ if (id)
+ queue_push2(queue, SOLVER_SOLVABLE_PROVIDES, id);
+ break;
+
+ default:
+ assert(0);
+ return 1;
+ }
+
+ return 0;
+}
+
+int pakfire_selector2queue(const PakfireSelector selector, Queue* queue, int solver_action) {
+ PakfirePool pool = selector->pool;
+ int ret = 0;
+
+ Queue queue_selector;
+ queue_init(&queue_selector);
+
+ if (selector->f_name == NULL && selector->f_provides == NULL) {
+ // no name or provides in the selector is an erro
+ ret = PAKFIRE_E_SELECTOR;
+ goto finish;
+ }
+
+ pakfire_pool_make_provides_ready(pool);
+
+ ret = filter_name2queue(pool, selector->f_name, &queue_selector);
+ if (ret)
+ goto finish;
+
+ ret = filter_provides2queue(pool, selector->f_provides, &queue_selector);
+ if (ret)
+ goto finish;
+
+ ret = filter_arch2queue(pool, selector->f_arch, &queue_selector);
+ if (ret)
+ goto finish;
+
+ ret = filter_evr2queue(pool, selector->f_evr, &queue_selector);
+ if (ret)
+ goto finish;
+
+ for (int i = 0; i < queue_selector.count; i += 2) {
+ queue_push2(queue,
+ queue_selector.elements[i] | solver_action,
+ queue_selector.elements[i + 1]
+ );
+ }
+
+finish:
+ if (ret)
+ pakfire_errno = ret;
+
+ queue_free(&queue_selector);
+
+ return ret;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <stdbool.h>
+
+#include <solv/pooltypes.h>
+#include <solv/transaction.h>
+
+#include <pakfire/cache.h>
+#include <pakfire/constants.h>
+#include <pakfire/package.h>
+#include <pakfire/repo.h>
+#include <pakfire/step.h>
+#include <pakfire/transaction.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireStep pakfire_step_create(PakfireTransaction transaction, Id id) {
+ PakfireStep step = pakfire_calloc(1, sizeof(*step));
+
+ step->pool = pakfire_transaction_pool(transaction);
+ step->transaction = transaction;
+ step->id = id;
+
+ return step;
+}
+
+void pakfire_step_free(PakfireStep step) {
+ pakfire_free(step);
+}
+
+PakfirePackage pakfire_step_get_package(PakfireStep step) {
+ return pakfire_package_create(step->pool, step->id);
+}
+
+int pakfire_step_get_type(PakfireStep step) {
+ Transaction* trans = step->transaction->transaction;
+
+ return transaction_type(trans, step->id,
+ SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_CHANGE_IS_REINSTALL);
+}
+
+const char* pakfire_step_get_type_string(PakfireStep step) {
+ const char *type;
+
+ switch(pakfire_step_get_type(step)) {
+ case SOLVER_TRANSACTION_IGNORE:
+ type = "ignore";
+ break;
+
+ case SOLVER_TRANSACTION_ERASE:
+ type = "erase";
+ break;
+
+ case SOLVER_TRANSACTION_REINSTALLED:
+ type = "reinstalled";
+ break;
+
+ case SOLVER_TRANSACTION_DOWNGRADED:
+ type = "downgraded";
+ break;
+
+ case SOLVER_TRANSACTION_CHANGED:
+ type = "changed";
+ break;
+
+ case SOLVER_TRANSACTION_UPGRADED:
+ type = "upgraded";
+ break;
+
+ case SOLVER_TRANSACTION_OBSOLETED:
+ type = "obsoleted";
+ break;
+
+ case SOLVER_TRANSACTION_INSTALL:
+ type = "install";
+ break;
+
+ case SOLVER_TRANSACTION_REINSTALL:
+ type = "reinstall";
+ break;
+
+ case SOLVER_TRANSACTION_DOWNGRADE:
+ type = "downgrade";
+ break;
+
+ case SOLVER_TRANSACTION_CHANGE:
+ type = "change";
+ break;
+
+ case SOLVER_TRANSACTION_UPGRADE:
+ type = "upgrade";
+ break;
+
+ case SOLVER_TRANSACTION_OBSOLETES:
+ type = "obsoletes";
+ break;
+
+ case SOLVER_TRANSACTION_MULTIINSTALL:
+ type = "multiinstall";
+ break;
+
+ case SOLVER_TRANSACTION_MULTIREINSTALL:
+ type = "multireinstall";
+ break;
+
+ default:
+ type = NULL;
+ break;
+ }
+
+ return type;
+}
+
+static int pakfire_step_get_downloadtype(PakfireStep step) {
+ int type = pakfire_step_get_type(step);
+ switch (type) {
+ case SOLVER_TRANSACTION_DOWNGRADE:
+ //case SOLVER_TRANSACTION_IGNORE:
+ case SOLVER_TRANSACTION_INSTALL:
+ case SOLVER_TRANSACTION_MULTIINSTALL:
+ case SOLVER_TRANSACTION_MULTIREINSTALL:
+ case SOLVER_TRANSACTION_REINSTALL:
+ case SOLVER_TRANSACTION_UPGRADE:
+ return 1;
+ }
+
+ return 0;
+}
+
+unsigned long long pakfire_step_get_downloadsize(PakfireStep step) {
+ PakfirePackage pkg = NULL;
+ int downloadsize = 0;
+
+ if (pakfire_step_get_downloadtype(step)) {
+ pkg = pakfire_step_get_package(step);
+ downloadsize = pakfire_package_get_downloadsize(pkg);
+ }
+
+ if (pkg)
+ pakfire_package_free(pkg);
+
+ return downloadsize;
+}
+
+long pakfire_step_get_installsizechange(PakfireStep step) {
+ PakfirePackage pkg = pakfire_step_get_package(step);
+ int installsize = pakfire_package_get_installsize(pkg);
+
+ int type = pakfire_step_get_type(step);
+ switch (type) {
+ case SOLVER_TRANSACTION_IGNORE:
+ case SOLVER_TRANSACTION_ERASE:
+ installsize *= -1;
+ break;
+ }
+
+ pakfire_package_free(pkg);
+
+ return installsize;
+}
+
+int pakfire_step_needs_download(PakfireStep step) {
+ PakfirePackage pkg = NULL;
+ int ret = true;
+
+ if (!pakfire_step_get_downloadtype(step))
+ return false;
+
+ /* Get the package object. */
+ pkg = pakfire_step_get_package(step);
+
+ PakfireRepo repo = pakfire_package_get_repo(pkg);
+ if (pakfire_repo_is_installed_repo(repo)) {
+ ret = false;
+ goto finish;
+ }
+
+ PakfireCache cache = pakfire_pool_get_cache(step->pool);
+ if (!cache)
+ goto finish;
+
+ // Return false if package is in cache.
+ ret = !pakfire_cache_has_package(cache, pkg);
+
+finish:
+ if (pkg)
+ pakfire_package_free(pkg);
+
+ return ret;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <solv/transaction.h>
+
+#include <pakfire/package.h>
+#include <pakfire/packagelist.h>
+#include <pakfire/step.h>
+#include <pakfire/transaction.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+PakfireTransaction pakfire_transaction_create(PakfirePool pool, Transaction* trans) {
+ PakfireTransaction transaction = pakfire_calloc(1, sizeof(*transaction));
+ transaction->pool = pool;
+
+ // Clone the transaction, so we get independent from what ever called this.
+ if (trans) {
+ transaction->transaction = transaction_create_clone(trans);
+ transaction_order(transaction->transaction, 0);
+ } else {
+ transaction->transaction = transaction_create(trans->pool);
+ }
+
+ return transaction;
+}
+
+void pakfire_transaction_free(PakfireTransaction transaction) {
+ transaction_free(transaction->transaction);
+ pakfire_free(transaction);
+}
+
+int pakfire_transaction_count(PakfireTransaction transaction) {
+ return transaction->transaction->steps.count;
+}
+
+int pakfire_transaction_installsizechange(PakfireTransaction transaction) {
+ int sizechange = transaction_calc_installsizechange(transaction->transaction);
+ printf("SIZECHANGE %d\n", sizechange);
+
+ // Convert from kbytes to bytes
+ return sizechange * 1024;
+}
+
+PakfireStep pakfire_transaction_get_step(PakfireTransaction transaction, int index) {
+ Transaction* trans = transaction->transaction;
+
+ if (index >= trans->steps.count)
+ return NULL;
+
+ return pakfire_step_create(transaction, trans->steps.elements[index]);
+}
+
+PakfirePackageList pakfire_transaction_get_packages(PakfireTransaction transaction, int type) {
+ PakfirePool pool = pakfire_transaction_pool(transaction);
+ Transaction* trans = transaction->transaction;
+
+ PakfirePackageList packagelist = pakfire_packagelist_create();
+
+ for (int i = 0; i < trans->steps.count; i++) {
+ Id p = trans->steps.elements[i];
+ Id t = transaction_type(trans, p,
+ SOLVER_TRANSACTION_SHOW_ACTIVE|SOLVER_TRANSACTION_CHANGE_IS_REINSTALL);
+
+ if (t == type) {
+ PakfirePackage package = pakfire_package_create(pool, p);
+ pakfire_packagelist_push(packagelist, package);
+ }
+ }
+
+ return packagelist;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2013 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 <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <libgen.h>
+#include <math.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pakfire/constants.h>
+
+void pakfire_oom(size_t num, size_t len) {
+ if (num)
+ fprintf(stderr, "Out of memory allocating %zu*%zu bytes!\n", num, len);
+ else
+ fprintf(stderr, "Out of memory allocating %zu bytes!\n", len);
+
+ abort();
+ exit(1);
+}
+
+void* pakfire_malloc(size_t len) {
+ void* r = malloc(len ? len : 1);
+ if (!r)
+ pakfire_oom(0, len);
+
+ return r;
+}
+
+void* pakfire_calloc(size_t num, size_t len) {
+ void* r;
+
+ if (num == 0 || len == 0)
+ r = malloc(1);
+ else
+ r = calloc(num, len);
+
+ if (!r)
+ pakfire_oom(num, len);
+
+ return r;
+}
+
+void* pakfire_realloc(void* ptr, size_t size) {
+ ptr = realloc(ptr, size);
+ if (!ptr)
+ pakfire_oom(0, size);
+
+ return ptr;
+}
+
+void* pakfire_free(void* mem) {
+ if (mem)
+ free(mem);
+
+ return 0;
+}
+
+char* pakfire_strdup(const char* s) {
+ if (!s)
+ return 0;
+
+ char* r = strdup(s);
+ if (!r)
+ pakfire_oom(0, strlen(s));
+
+ return r;
+}
+
+char* pakfire_format_size(double size) {
+ char string[STRING_SIZE];
+ const char* units[] = {" ", "k", "M", "G", "T", NULL};
+ const char** unit = units;
+
+ while (*(unit + 1) && size >= 1024.0) {
+ size /= 1024.0;
+ unit++;
+ }
+
+ snprintf(string, STRING_SIZE, "%.0f%s", round(size), *unit);
+
+ return pakfire_strdup(string);
+}
+
+char* pakfire_path_join(const char* first, const char* second) {
+ char* buffer;
+
+ if (!second)
+ return pakfire_strdup(first);
+
+ if (*second == '/')
+ return pakfire_strdup(second);
+
+ asprintf(&buffer, "%s/%s", first, second);
+
+ return buffer;
+}
+
+char* pakfire_basename(const char* path) {
+ char* name = pakfire_strdup(path);
+
+ return basename(name);
+}
+
+char* pakfire_dirname(const char* path) {
+ char* parent = pakfire_strdup(path);
+
+ return dirname(parent);
+}
+
+char* pakfire_sgets(char* str, int num, char** input) {
+ char* next = *input;
+ int numread = 0;
+
+ while (numread + 1 < num && *next) {
+ int isnewline = (*next == '\n');
+
+ *str++ = *next++;
+ numread++;
+
+ if (isnewline)
+ break;
+ }
+
+ // Terminate string
+ *str = '\0';
+
+ *input = next;
+
+ return str;
+}
+
+char* pakfire_remove_trailing_newline(char* str) {
+ ssize_t pos = strlen(str) - 1;
+
+ if (str[pos] == '\n')
+ str[pos] = '\0';
+
+ return str;
+}