socsvn commit: r253509 - in soc2013/mattbw/backend: . actions
mattbw at FreeBSD.org
mattbw at FreeBSD.org
Tue Jun 25 23:37:18 UTC 2013
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 at 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 at 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);
}
/**
More information about the svn-soc-all
mailing list