Date: Tue, 25 Jun 2013 23:37:18 GMT From: mattbw@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r253509 - in soc2013/mattbw/backend: . actions Message-ID: <201306252337.r5PNbIZ0076528@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mattbw Date: Tue Jun 25 23:37:18 2013 New Revision: 253509 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=253509 Log: implemented GetFiles; may not throw the correct error message at the moment for non-installed files. Added: soc2013/mattbw/backend/actions/get-files.c soc2013/mattbw/backend/actions/get-files.h Modified: soc2013/mattbw/backend/Makefile soc2013/mattbw/backend/actions/get-details.c soc2013/mattbw/backend/db.c soc2013/mattbw/backend/db.h soc2013/mattbw/backend/iterate.c soc2013/mattbw/backend/pk-backend-pkgng.c Modified: soc2013/mattbw/backend/Makefile ============================================================================== --- soc2013/mattbw/backend/Makefile Tue Jun 25 22:46:52 2013 (r253508) +++ soc2013/mattbw/backend/Makefile Tue Jun 25 23:37:18 2013 (r253509) @@ -3,7 +3,7 @@ LIB= pk_backend_pkgng SHLIB_MAJOR= 1 SRCS= pk-backend-pkgng.c groups.c db.c licenses.c iterate.c -SRCS+= actions/get-details.c +SRCS+= actions/get-details.c actions/get-files.c LIBDIR= /usr/local/lib/packagekit-backend Modified: soc2013/mattbw/backend/actions/get-details.c ============================================================================== --- soc2013/mattbw/backend/actions/get-details.c Tue Jun 25 22:46:52 2013 (r253508) +++ soc2013/mattbw/backend/actions/get-details.c Tue Jun 25 23:37:18 2013 (r253509) @@ -18,11 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <string.h> #include <glib.h> #include "../pk-backend.h" #include "pkg.h" +#include "../db.h" /* db_query_from_id */ #include "../groups.h" /* group_from_origin */ #include "../iterate.h" /* Package iteration */ #include "../licenses.h" /* license_from_pkg */ @@ -30,17 +30,7 @@ #include "get-details.h" /* get_details_thread prototype */ static const int LOAD_FLAGS = PKG_LOAD_BASIC | PKG_LOAD_LICENSES; - -/* TODO: move out of get-details? */ -const char *null_if_empty(const char *in); - -static gboolean -get_details_query(const gchar *name, - const gchar *version, - const gchar *arch, - const gchar *reponame, - PkBackend *backend, - struct pkgdb *db); +static void get_details_emit(struct pkg *pkg, const gchar *id, PkBackend *backend); static gboolean get_details_for(gchar *package_id, PkBackend *backend, @@ -60,9 +50,7 @@ * Emits the given package's details. To be used as an iterating function. */ static void -emit_get_details(struct pkg *pkg, - const gchar *id, - PkBackend *backend) +get_details_emit(struct pkg *pkg, const gchar *id, PkBackend *backend) { const char *description; const char *origin; @@ -86,118 +74,11 @@ } /* - * Looks the split PackageID up in the package databases. - * - * Usually, a remote query will be done on the repository named by "reponame". - * If reponame is NULL, a remote check will be done against all repostories. - * If it is "installed", a local check will be done. (This is in keeping - * with the special meaning of the "installed" repository in PackageIDs). + * Look up and emit package details for the given PackageID, if it can be + * found. */ -static gboolean -get_details_query(const gchar *name, - const gchar *version, - const gchar *arch, - const gchar *reponame, - PkBackend *backend, - struct pkgdb *db) -{ - struct pkgdb_it *it; - gboolean success; - - success = FALSE; - - /* Are we doing a local query? */ - if (g_strcmp0(reponame, "installed") == 0) - it = pkgdb_query(db, name, MATCH_EXACT); - else - it = pkgdb_rquery(db, name, MATCH_EXACT, reponame); - if (it) - success = iterate_id_matches(it, - backend, - name, - version, - arch, - reponame, - LOAD_FLAGS, - emit_get_details); - return success; -} - -/* - * If the input pointer points to a string that is empty, return the null - * pointer; else pass through the pointer unmolested. - * - * This does NOT free anything! - */ -const char * -null_if_empty(const char *in) -{ - return (in != NULL && strlen(in) == 0) ? NULL : in; -} - gboolean get_details_for(gchar *package_id, PkBackend *backend, struct pkgdb *db) { - gchar **parts; - gboolean success; - - success = FALSE; - - parts = pk_package_id_split(package_id); - if (parts == NULL) - pk_backend_error_code(backend, - PK_ERROR_ENUM_PACKAGE_ID_INVALID, - "invalid package id"); - else { - /* Parts of the package ID */ - const gchar *name; - const gchar *version; - const gchar *arch; - const gchar *data; - - /* - * Make really really REALLY sure that the PackageID fields - * either have sensible data in them, or are NULL. - */ - name = null_if_empty(parts[PK_PACKAGE_ID_NAME]); - version = null_if_empty(parts[PK_PACKAGE_ID_VERSION]); - arch = null_if_empty(parts[PK_PACKAGE_ID_ARCH]); - data = null_if_empty(parts[PK_PACKAGE_ID_DATA]); - - /* - * If the PackageID has a repository specified (even if it's - * "installed" i.e. currently installed package), running - * "get_details_query" directly should handle remote/local - * queries properly. - * - * If there is no repository specified, however (data is NULL), - * we may need to check both the local and (all) remote - * repositories, in that order. (TODO: local packages?) - */ - if (data == NULL) { - /* Try local database first. */ - success = get_details_query(name, - version, - arch, - "installed", - backend, - db); - if (success == FALSE) - success = get_details_query(name, version, NULL, data, backend, db); - } else - success = get_details_query(name, version, arch, data, backend, db); - /* - * Assume any error is due to not finding packages. At time - * of writing this is true, but may change. - */ - if (success == FALSE) - pk_backend_error_code(backend, - PK_ERROR_ENUM_PACKAGE_NOT_FOUND, - "package not found"); - g_strfreev(parts); - } - - return success; + return db_query_with_id(package_id, backend, db, LOAD_FLAGS, get_details_emit); } - - Added: soc2013/mattbw/backend/actions/get-files.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/mattbw/backend/actions/get-files.c Tue Jun 25 23:37:18 2013 (r253509) @@ -0,0 +1,102 @@ +/*- + * Copyright (C) 2013 Matt Windsor <mattbw@FreeBSD.org> + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 files. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <glib.h> +#include "../pk-backend.h" +#include "pkg.h" + +#include "../db.h" /* db_query_from_id */ +#include "../groups.h" /* group_from_origin */ +#include "../iterate.h" /* Package iteration */ +#include "../licenses.h" /* license_from_pkg */ + +#include "get-files.h" /* get_files_thread prototype */ + +static const int FILE_NAME_STEP = 10; +static const int LOAD_FLAGS = PKG_LOAD_BASIC | PKG_LOAD_FILES; + +static void get_files_emit(struct pkg *pkg, const gchar *id, PkBackend *backend); +static gboolean +get_files_for(gchar *package_id, + PkBackend *backend, + struct pkgdb *db); + +/* + * The thread that performs a GetDetails operation. Should be invoked by the + * pk_backend_get_files hook. + */ +gboolean +get_files_thread(PkBackend *backend) +{ + return iterate_ids(backend, get_files_for); +} + +/* + * Emits the given package's files. To be used as an iterating function. + */ +static void +get_files_emit(struct pkg *pkg, const gchar *id, PkBackend *backend) +{ + struct pkg_file *file; + int err; + + gchar **filenames; + gchar *joined_filenames; + gint capacity; + gint i; + + i = 0; + file = NULL; + /* Start off with a small array to hold the file names, + * and expand it if needs be. + */ + capacity = FILE_NAME_STEP; + filenames = g_new(gchar *, capacity); + do { + err = pkg_files(pkg, &file); + if (err == EPKG_OK) { + /* Out of capacity (leaving a NULL)? Expand the array. */ + if (i >= (capacity - 1)) { + capacity += FILE_NAME_STEP; + filenames = g_renew(gchar *, filenames, capacity); + } + + filenames[i] = g_strdup(pkg_file_path(file)); + i++; + } + } while (err == EPKG_OK); + filenames[i] = NULL; + + joined_filenames = g_strjoinv(";", filenames); + g_strfreev(filenames); + + pk_backend_files(backend, id, joined_filenames); + g_free(joined_filenames); +} + +/* + * Look up and emit package files for the given PackageID, if it can be + * found. + */ +gboolean +get_files_for(gchar *package_id, PkBackend *backend, struct pkgdb *db) +{ + return db_query_with_id(package_id, backend, db, LOAD_FLAGS, get_files_emit); +} Added: soc2013/mattbw/backend/actions/get-files.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2013/mattbw/backend/actions/get-files.h Tue Jun 25 23:37:18 2013 (r253509) @@ -0,0 +1,29 @@ +/*- + * Copyright (C) 2013 Matt Windsor <mattbw@FreeBSD.org> + * + * Licensed under the GNU General Public License Version 2 + * + * 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 2 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 files. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _PKGNG_BACKEND_GET_FILES_H_ +#define _PKGNG_BACKEND_GET_FILES_H_ + +#include <glib.h> /* gboolean */ +#include "../pk-backend.h" /* PkBackend */ + +gboolean get_files_thread(PkBackend *backend); + +#endif /* !_PKGNG_BACKEND_GET_FILES_H_ */ Modified: soc2013/mattbw/backend/db.c ============================================================================== --- soc2013/mattbw/backend/db.c Tue Jun 25 22:46:52 2013 (r253508) +++ soc2013/mattbw/backend/db.c Tue Jun 25 23:37:18 2013 (r253509) @@ -19,11 +19,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include <string.h> #include <glib.h> #include "pk-backend.h" #include "pkg.h" #include "db.h" /* prototypes */ +#include "iterate.h" /* pkg_func_ptr */ + +static const char *null_if_empty(const char *in); + +static gboolean +db_query_split(const gchar *name, + const gchar *version, + const gchar *arch, + const gchar *reponame, + PkBackend *backend, + struct pkgdb *db, + int load_flags, + pkg_func_ptr emitter); /* * Opens a pkgdb ready for remote operations. This will always return TRUE if @@ -57,3 +71,131 @@ return success; } + +/* + * Performs a package database query against a PackageID, and then hands the + * matching results to an emitter function. + * + * The exact type of query depends on the repository given. + */ +gboolean +db_query_with_id(const gchar *package_id, + PkBackend *backend, + struct pkgdb *db, + int load_flags, + pkg_func_ptr emitter) +{ + gchar **parts; + gboolean success; + + success = FALSE; + + parts = pk_package_id_split(package_id); + if (parts == NULL) + pk_backend_error_code(backend, + PK_ERROR_ENUM_PACKAGE_ID_INVALID, + "invalid package id"); + else { + /* Parts of the package ID */ + const gchar *name; + const gchar *version; + const gchar *arch; + const gchar *data; + + /* + * Make really really REALLY sure that the PackageID fields + * either have sensible data in them, or are NULL. + */ + name = null_if_empty(parts[PK_PACKAGE_ID_NAME]); + version = null_if_empty(parts[PK_PACKAGE_ID_VERSION]); + arch = null_if_empty(parts[PK_PACKAGE_ID_ARCH]); + data = null_if_empty(parts[PK_PACKAGE_ID_DATA]); + + /* + * If the PackageID has a repository specified (even if it's + * "installed" i.e. currently installed package), running + * "get_details_query" directly should handle remote/local + * queries properly. + * + * If there is no repository specified, however (data is NULL), + * we may need to check both the local and (all) remote + * repositories, in that order. (TODO: local packages?) + */ + if (data == NULL) + /* Try local database first. */ + success = db_query_split(name, + version, + arch, + "installed", + backend, + db, + load_flags, + emitter); + if (success == FALSE) + success = db_query_split(name, version, arch, data, + backend, db, load_flags, emitter); + /* + * Assume any error is due to not finding packages. At time + * of writing this is true, but may change. + */ + if (success == FALSE) + pk_backend_error_code(backend, + PK_ERROR_ENUM_PACKAGE_NOT_FOUND, + "package not found"); + g_strfreev(parts); + } + + return success; +} + +/* + * Looks the split PackageID up in the package databases. + * + * Usually, a remote query will be done on the repository named by "reponame". + * If reponame is NULL, a remote check will be done against all repostories. + * If it is "installed", a local check will be done. (This is in keeping + * with the special meaning of the "installed" repository in PackageIDs). + */ +static gboolean +db_query_split(const gchar *name, + const gchar *version, + const gchar *arch, + const gchar *reponame, + PkBackend *backend, + struct pkgdb *db, + int load_flags, + pkg_func_ptr emitter) +{ + struct pkgdb_it *it; + gboolean success; + + success = FALSE; + + /* Are we doing a local query? */ + if (g_strcmp0(reponame, "installed") == 0) + it = pkgdb_query(db, name, MATCH_EXACT); + else + it = pkgdb_rquery(db, name, MATCH_EXACT, reponame); + if (it) + success = iterate_id_matches(it, + backend, + name, + version, + arch, + reponame, + load_flags, + emitter); + return success; +} + +/* + * If the input pointer points to a string that is empty, return the null + * pointer; else pass through the pointer unmolested. + * + * This does NOT free anything! + */ +static const char * +null_if_empty(const char *in) +{ + return (in != NULL && strlen(in) == 0) ? NULL : in; +} Modified: soc2013/mattbw/backend/db.h ============================================================================== --- soc2013/mattbw/backend/db.h Tue Jun 25 22:46:52 2013 (r253508) +++ soc2013/mattbw/backend/db.h Tue Jun 25 23:37:18 2013 (r253509) @@ -26,6 +26,14 @@ #include "pk-backend.h" /* PkBackend */ #include "pkg.h" /* struct pkgdb */ +#include "iterate.h" /* pk_func_ptr */ + gboolean open_remote_db(struct pkgdb **db, PkBackend *backend); +gboolean +db_query_with_id(const gchar *package_id, + PkBackend *backend, + struct pkgdb *db, + int load_flags, + pkg_func_ptr emitter); #endif /* !_PKGNG_BACKEND_DETAILS_H_ */ Modified: soc2013/mattbw/backend/iterate.c ============================================================================== --- soc2013/mattbw/backend/iterate.c Tue Jun 25 22:46:52 2013 (r253508) +++ soc2013/mattbw/backend/iterate.c Tue Jun 25 23:37:18 2013 (r253509) @@ -25,7 +25,7 @@ #include "iterate.h" /* Prototypes */ -#include "db.h" /* open_remote_db */ +#include "db.h" /* open_remote_db */ static gboolean try_id_match(struct pkg *pkg, const gchar *name, const gchar *version, const @@ -53,7 +53,19 @@ pkg = NULL; match_id = NULL; do { - err = pkgdb_it_next(iterator, &pkg, fetch_flags); + /* + * Stop pkg from catching fire if we try to load files from + * non-installed packages. + */ + if ((fetch_flags & PKG_LOAD_FILES) && g_strcmp0(data, + "installed") != 0) { + pk_backend_error_code(backend, + PK_ERROR_ENUM_CANNOT_GET_FILELIST, + "Cannot get files for non-installed package." + ); + err = EPKG_FATAL; + } else + err = pkgdb_it_next(iterator, &pkg, fetch_flags); if (err == EPKG_OK && try_id_match(pkg, name, @@ -133,11 +145,12 @@ return result; } -/* Iterates over a set of PackageIDs provided for this job with a function. - * +/* + * Iterates over a set of PackageIDs provided for this job with a function. + * * This provides each iterating function call with an open database connection * and updates the percentage after each iteration. - * + * * It also *finishes* the backend job. */ gboolean Modified: soc2013/mattbw/backend/pk-backend-pkgng.c ============================================================================== --- soc2013/mattbw/backend/pk-backend-pkgng.c Tue Jun 25 22:46:52 2013 (r253508) +++ soc2013/mattbw/backend/pk-backend-pkgng.c Tue Jun 25 23:37:18 2013 (r253509) @@ -31,6 +31,7 @@ #include "pkg.h" #include "groups.h" /* available_groups */ +#include "actions/get-files.h" /* get_files_thread */ #include "actions/get-details.h"/* get_details_thread */ #define INTENTIONALLY_IGNORE(x) (void)(x) @@ -218,25 +219,13 @@ void pk_backend_get_files(PkBackend *backend, gchar **package_ids) { - guint i; - guint len; - const gchar *package_id; + INTENTIONALLY_IGNORE(package_ids); /* can be retrieved from + * backend */ pk_backend_set_status(backend, PK_STATUS_ENUM_QUERY); + pk_backend_set_percentage(backend, PK_BACKEND_PERCENTAGE_INVALID); - len = g_strv_length(package_ids); - for (i = 0; i < len; i++) { - package_id = package_ids[i]; - if (g_strcmp0(package_id, "powertop;1.8-1.fc8;i386;fedora") == 0) - pk_backend_files(backend, package_id, "/usr/share/man/man1/boo;/usr/bin/xchat-gnome"); - else if (g_strcmp0(package_id, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed") == 0) - pk_backend_files(backend, package_id, "/usr/share/man/man1;/usr/share/man/man1/gnome-power-manager.1.gz;/usr/lib/firefox-3.5.7/firefox"); - else if (g_strcmp0(package_id, "gtkhtml2;2.19.1-4.fc8;i386;fedora") == 0) - pk_backend_files(backend, package_id, "/usr/share/man/man1;/usr/bin/ck-xinit-session;/lib/libselinux.so.1"); - else - pk_backend_files(backend, package_id, "/usr/share/gnome-power-manager;/usr/bin/ck-xinit-session"); - } - pk_backend_finished(backend); + pk_backend_thread_create(backend, get_files_thread); } /**
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306252337.r5PNbIZ0076528>