summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/pacman/Makefile.am1
-rw-r--r--src/pacman/conf.c4
-rw-r--r--src/pacman/conf.h3
-rw-r--r--src/pacman/files.c84
-rw-r--r--src/pacman/pacman.c64
-rw-r--r--src/pacman/pacman.h2
-rw-r--r--src/pacman/util.c2
7 files changed, 158 insertions, 2 deletions
diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am
index dc127a2b..d3ae071e 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 ccf8183d..e1997435 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_dbext(handle, ".files");
+ }
+
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 d6feb7ac..84b5a253 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 00000000..18d4c914
--- /dev/null
+++ b/src/pacman/files.c
@@ -0,0 +1,84 @@
+/*
+ * files.c
+ *
+ * Copyright (c) 2015 Pacman Development Team <pacman-dev@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 764193e6..951d628c 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 ddf6e62a..e7d3aa64 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 46620240..dd6e218a 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;
}