[pacman-dev] [PATCH 08/13] Prototype pacman files database operations

Allan McRae allan at archlinux.org
Sat Jun 20 07:42:21 UTC 2015


Add the -F/--files operations, -s/--sync support and nd provide dummy
functions for -s/--search, -l/-list and -o/--owns.

Signed-off-by: Allan McRae <allan at archlinux.org>
---
 src/pacman/Makefile.am |  1 +
 src/pacman/conf.c      |  4 +++
 src/pacman/conf.h      |  3 +-
 src/pacman/files.c     | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/pacman/pacman.c    | 64 +++++++++++++++++++++++++++++++++++++-
 src/pacman/pacman.h    |  2 ++
 src/pacman/util.c      |  2 ++
 7 files changed, 158 insertions(+), 2 deletions(-)
 create mode 100644 src/pacman/files.c

diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am
index dc127a2..d3ae071 100644
--- a/src/pacman/Makefile.am
+++ b/src/pacman/Makefile.am
@@ -32,6 +32,7 @@ pacman_SOURCES = \
 	conf.h conf.c \
 	database.c \
 	deptest.c \
+	files.c \
 	ini.h ini.c \
 	package.h package.c \
 	pacman.h pacman.c \
diff --git a/src/pacman/conf.c b/src/pacman/conf.c
index ccf8183..83ec950 100644
--- a/src/pacman/conf.c
+++ b/src/pacman/conf.c
@@ -729,6 +729,10 @@ static int setup_libalpm(void)
 	alpm_option_set_questioncb(handle, cb_question);
 	alpm_option_set_progresscb(handle, cb_progress);
 
+	if(config->op == PM_OP_FILES) {
+		alpm_option_set_files(handle, 1);
+	}
+
 	config->logfile = config->logfile ? config->logfile : strdup(LOGFILE);
 	ret = alpm_option_set_logfile(handle, config->logfile);
 	if(ret != 0) {
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index d6feb7a..84b5a25 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -138,7 +138,8 @@ enum {
 	PM_OP_QUERY,
 	PM_OP_SYNC,
 	PM_OP_DEPTEST,
-	PM_OP_DATABASE
+	PM_OP_DATABASE,
+	PM_OP_FILES
 };
 
 /* Long Operations */
diff --git a/src/pacman/files.c b/src/pacman/files.c
new file mode 100644
index 0000000..18d4c91
--- /dev/null
+++ b/src/pacman/files.c
@@ -0,0 +1,84 @@
+/*
+ *  files.c
+ *
+ *  Copyright (c) 2015 Pacman Development Team <pacman-dev at archlinux.org>
+ *
+ *  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 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 <alpm.h>
+#include <alpm_list.h>
+
+/* pacman */
+#include "pacman.h"
+#include "util.h"
+#include "conf.h"
+
+
+static int files_fileowner(alpm_list_t __attribute__((unused)) *syncs, alpm_list_t __attribute__((unused)) *targets) {
+	return 0;
+}
+
+static int files_search(alpm_list_t __attribute__((unused)) *syncs, alpm_list_t __attribute__((unused)) *targets) {
+	return 0;
+}
+
+static int files_list(alpm_list_t __attribute__((unused)) *syncs, alpm_list_t __attribute__((unused)) *targets) {
+	return 0;
+}
+
+
+int pacman_files(alpm_list_t *targets)
+{
+	alpm_list_t *files_dbs = NULL;
+
+	if(check_syncdbs(1, 0)) {
+		return 1;
+	}
+
+	files_dbs = alpm_get_syncdbs(config->handle);
+
+	if(config->op_s_sync) {
+		/* grab a fresh package list */
+		colon_printf(_("Synchronizing package databases...\n"));
+		alpm_logaction(config->handle, PACMAN_CALLER_PREFIX,
+				"synchronizing package lists\n");
+		if(!sync_syncdbs(config->op_s_sync, files_dbs)) {
+			return 1;
+		}
+	}
+
+	if(targets == NULL && (config->op_s_search || config->op_q_owns)) {
+		pm_printf(ALPM_LOG_ERROR, _("no targets specified (use -h for help)\n"));
+		return 1;
+	}
+
+	/* determine the owner of a file */
+	if(config->op_q_owns) {
+		return files_fileowner(files_dbs, targets);
+	}
+
+	/* search for a file */
+	if(config->op_s_search) {
+		return files_search(files_dbs, targets);
+	}
+
+	/* get a listing of files in sync DBs */
+	if(config->op_q_list) {
+		return files_list(files_dbs, targets);
+	}
+
+
+	return 0;
+}
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 764193e..951d628 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -110,6 +110,7 @@ static void usage(int op, const char * const myname)
 		printf("    %s {-h --help}\n", myname);
 		printf("    %s {-V --version}\n", myname);
 		printf("    %s {-D --database} <%s> <%s>\n", myname, str_opt, str_pkg);
+		printf("    %s {-F --files}    [%s] [%s]\n", myname, str_opt, str_pkg);
 		printf("    %s {-Q --query}    [%s] [%s]\n", myname, str_opt, str_pkg);
 		printf("    %s {-R --remove}   [%s] <%s>\n", myname, str_opt, str_pkg);
 		printf("    %s {-S --sync}     [%s] [%s]\n", myname, str_opt, str_pkg);
@@ -173,6 +174,12 @@ static void usage(int op, const char * const myname)
 		} else if(op == PM_OP_DEPTEST) {
 			printf("%s:  %s {-T --deptest} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg);
 			printf("%s:\n", str_opt);
+		} else if(op == PM_OP_FILES) {
+			addlist(_("  -l, --list           list the files owned by the queried package\n"));
+			addlist(_("  -o, --owns <file>    query the package that owns <file>\n"));
+			addlist(_("  -s, --search <regex> search package file names for matching strings\n"));
+			addlist(_("  -y, --refresh        download fresh package databases from the server\n"
+			          "                       (-yy to force a refresh even if up to date)\n"));
 		}
 		switch(op) {
 			case PM_OP_SYNC:
@@ -363,6 +370,9 @@ static int parsearg_op(int opt, int dryrun)
 		case 'D':
 			if(dryrun) break;
 			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_DATABASE); break;
+		case 'F':
+			if(dryrun) break;
+			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_FILES); break;
 		case 'Q':
 			if(dryrun) break;
 			config->op = (config->op != PM_OP_MAIN ? 0 : PM_OP_QUERY); break;
@@ -755,6 +765,48 @@ static void checkargs_upgrade(void)
 			"--asdeps", "--asexplicit");
 }
 
+static int parsearg_files(int opt)
+{
+	if(parsearg_trans(opt) == 0) {
+		return 0;
+	}
+	switch(opt) {
+		case OP_OWNS:
+		case 'o':
+			config->op_q_owns = 1;
+			break;
+		case OP_LIST:
+		case 'l':
+			config->op_q_list = 1;
+			break;
+		case OP_SEARCH:
+		case 's':
+			config->op_s_search = 1;
+			break;
+		case OP_REFRESH:
+		case 'y':
+			(config->op_s_sync)++;
+			break;
+		case OP_QUIET:
+		case 'q':
+			config->quiet = 1;
+			break;
+		default:
+			return 1;
+	}
+	return 0;
+}
+
+static void checkargs_files(void)
+{
+	if(config->op_q_owns) {
+		invalid_opt(config->op_q_list, "--owns", "--list");
+		invalid_opt(config->op_q_search, "--owns", "--search");
+	} else if(config->op_q_list) {
+		invalid_opt(config->op_q_search, "--list", "--search");
+	}
+}
+
 static int parsearg_sync(int opt)
 {
 	if(parsearg_upgrade(opt) == 0) {
@@ -847,10 +899,11 @@ static int parseargs(int argc, char *argv[])
 	int opt;
 	int option_index = 0;
 	int result;
-	const char *optstring = "DQRSTUVb:cdefghiklmnopqr:stuvwy";
+	const char *optstring = "DFQRSTUVb:cdefghiklmnopqr:stuvwy";
 	static const struct option opts[] =
 	{
 		{"database",   no_argument,       0, 'D'},
+		{"files",      no_argument,       0, 'F'},
 		{"query",      no_argument,       0, 'Q'},
 		{"remove",     no_argument,       0, 'R'},
 		{"sync",       no_argument,       0, 'S'},
@@ -964,6 +1017,9 @@ static int parseargs(int argc, char *argv[])
 			case PM_OP_UPGRADE:
 				result = parsearg_upgrade(opt);
 				break;
+			case PM_OP_FILES:
+				result = parsearg_files(opt);
+				break;
 			case PM_OP_DEPTEST:
 			default:
 				result = 1;
@@ -1012,6 +1068,9 @@ static int parseargs(int argc, char *argv[])
 		case PM_OP_UPGRADE:
 			checkargs_upgrade();
 			break;
+		case PM_OP_FILES:
+			checkargs_files();
+			break;
 		default:
 			break;
 	}
@@ -1238,6 +1297,9 @@ int main(int argc, char *argv[])
 		case PM_OP_DEPTEST:
 			ret = pacman_deptest(pm_targets);
 			break;
+		case PM_OP_FILES:
+			ret = pacman_files(pm_targets);
+			break;
 		default:
 			pm_printf(ALPM_LOG_ERROR, _("no operation specified (use -h for help)\n"));
 			ret = EXIT_FAILURE;
diff --git a/src/pacman/pacman.h b/src/pacman/pacman.h
index ddf6e62..e7d3aa6 100644
--- a/src/pacman/pacman.h
+++ b/src/pacman/pacman.h
@@ -28,6 +28,8 @@
 int pacman_database(alpm_list_t *targets);
 /* deptest.c */
 int pacman_deptest(alpm_list_t *targets);
+/* files.c */
+int pacman_files(alpm_list_t *files);
 /* query.c */
 int pacman_query(alpm_list_t *targets);
 /* remove.c */
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 4662024..dd6e218 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -113,6 +113,8 @@ int needs_root(void)
 			return (config->op_s_clean || config->op_s_sync ||
 					(!config->group && !config->op_s_info && !config->op_q_list &&
 					 !config->op_s_search && !config->print));
+		case PM_OP_FILES:
+			return config->op_s_sync;
 		default:
 			return 0;
 	}
-- 
2.4.4


More information about the pacman-dev mailing list