aboutsummaryrefslogtreecommitdiff
path: root/q.c
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2005-06-07 04:37:32 +0000
committerMike Frysinger <vapier@gentoo.org>2005-06-07 04:37:32 +0000
commit8c71dad3850587154075822d8f42ff29d9c2d0fd (patch)
treef8ea2e77f590199fdf38c5e52cfe105130fc2cac /q.c
parentadd some whitespace to help make readable (diff)
downloadportage-utils-8c71dad3850587154075822d8f42ff29d9c2d0fd.tar.gz
portage-utils-8c71dad3850587154075822d8f42ff29d9c2d0fd.tar.bz2
portage-utils-8c71dad3850587154075822d8f42ff29d9c2d0fd.zip
fork q into its own applet ... hopefully this will help readability
Diffstat (limited to 'q.c')
-rw-r--r--q.c344
1 files changed, 6 insertions, 338 deletions
diff --git a/q.c b/q.c
index 8b682fd6..35ed6204 100644
--- a/q.c
+++ b/q.c
@@ -1,10 +1,10 @@
/*
* Copyright 2005 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/q.c,v 1.10 2005/06/07 02:17:24 solar Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/q.c,v 1.11 2005/06/07 04:37:32 vapier Exp $
*
- * 2005 Ned Ludd - <solar@gentoo.org>
- * 2005 Mike Frysinger - <vapier@gentoo.org>
+ * 2005 Ned Ludd - <solar@gentoo.org>
+ * 2005 Mike Frysinger - <vapier@gentoo.org>
*
********************************************************************
* This program is free software; you can redistribute it and/or
@@ -24,327 +24,7 @@
*
*/
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <getopt.h>
-#include <regex.h>
-#include <errno.h>
-#include <libgen.h>
-#include <limits.h>
-
-typedef int (*APPLET)(int, char **);
-
-APPLET lookup_applet(char *);
-
-int rematch(char *, char *, int);
-char *rmspace(char *);
-void qfile(char *, char *);
-
-char *initialize_portdir(void);
-void initialize_ebuild_flat(void);
-void reinitialize_ebuild_flat(void);
-void reinitialize_as_needed(void);
-
-/* applet prototypes */
-int q_main(int, char **);
-int qsearch_main(int, char **);
-int quse_main(int, char **);
-int qlist_main(int, char **);
-int qfile_main(int, char **);
-
-/* helper functions for showing errors */
-static char *argv0;
-#define warn(fmt, args...) \
- fprintf(stderr, "%s: " fmt "\n", argv0, ## args)
-#define warnf(fmt, args...) warn("%s(): " fmt, __FUNCTION__, ## args)
-#define err(fmt, args...) \
- do { \
- warn(fmt, ## args); \
- exit(EXIT_FAILURE); \
- } while (0)
-#ifdef EBUG
-# define DBG(fmt, args...) warnf(fmt, ## args)
-#else
-# define DBG(fmt, args...)
-#endif
-
-static const char *rcsid = "$Id: q.c,v 1.10 2005/06/07 02:17:24 solar Exp $";
-
-static char color = 1;
-static char exact = 0;
-static int found = 0;
-static char reinitialize = 0;
-
-static char portdir[_POSIX_PATH_MAX] = "/usr/portage";
-
-/* applets we support */
-struct applet_t {
- const char *name;
- /* int *func; */
- APPLET func;
- const char *opts;
-} applets[] = {
- /* q must always be the first applet */
- {"q", (APPLET)q_main, "<applet> <args>"},
- {"qfile", (APPLET)qfile_main, "<filename>"},
- {"qlist", (APPLET)qlist_main, "<pkgname>"},
- {"qsearch", (APPLET)qsearch_main, "<regex>"},
- {"quse", (APPLET)quse_main, "<useflag>"},
- {NULL, (APPLET)NULL, NULL}
-};
-#define Q_IDX 0
-#define QFILE_IDX 1
-#define QLIST_IDX 2
-#define QSEARCH_IDX 3
-#define QUSE_IDX 4
-
-/* Common options for all applets */
-#define COMMON_FLAGS "hV"
-#define a_argument required_argument
-#define COMMON_LONG_OPTS \
- {"help", no_argument, NULL, 'h'}, \
- {"version", no_argument, NULL, 'V'}, \
- {NULL, no_argument, NULL, 0x0}
-#define COMMON_OPTS_HELP \
- "Print this help and exit", \
- "Print version and exit", \
- NULL
-
-/* display usage and exit */
-static void usage(int status, const char *flags, struct option const opts[],
- const char *help[], int applets_blabber)
-{
- unsigned long i;
- if (applets_blabber == 0) {
- printf("Usage: q <applet> [arguments]...\n"
- " or: <applet> [arguments]...\n\n");
- printf("Currently defined applets:\n");
- for (i = 0; applets[i].name; ++i)
- printf(" - %s %s\n", applets[i].name, applets[i].opts);
- } else {
- printf("Usage: %s %s\n", applets[applets_blabber].name, applets[applets_blabber].opts);
- }
-
- printf("\nOptions: [%s]\n", flags);
- for (i = 0; opts[i].name; ++i)
- if (opts[i].has_arg == no_argument)
- printf(" -%c, --%-13s* %s\n", opts[i].val,
- opts[i].name, help[i]);
- else
- printf(" -%c, --%-6s <arg> * %s\n", opts[i].val,
- opts[i].name, help[i]);
- exit(status);
-}
-static void version_barf(void)
-{
- printf("%s compiled %s\n%s\n"
- "%s written for Gentoo by <solar and vapier @ gentoo.org>\n",
- __FILE__, __DATE__, rcsid, argv0);
- exit(EXIT_SUCCESS);
-}
-
-APPLET lookup_applet(char *applet)
-{
- unsigned int i;
- for (i = 0; applets[i].name; ++i) {
- if ((strcmp(applets[i].name, applet)) == 0) {
- DBG("found applet %s at %p", applets[i].name, applets[i].func);
- return applets[i].func;
- }
- }
- /* No applet found? Search by shortname then... */
- if ((strlen(applet)) - 1 > 0) {
- DBG("Looking up applet (%s) by short name", applet);
- for (i = 1; applets[i].name; ++i) {
- if ((strcmp(applets[i].name + 1, applet)) == 0) {
- DBG("found applet by short name %s", applets[i].name);
- return applets[i].func;
- }
- }
- }
- /* still nothing? .. add short opts -q/-l etc.. */
- warn("Unknown applet '%s'", applet);
- return 0;
-}
-
-int rematch(char *regex, char *match, int cflags)
-{
- regex_t preg;
- int ret;
-
- ret = regcomp(&preg, regex, cflags);
- if (ret) {
- char err[256];
- if (regerror(ret, &preg, err, sizeof(err)))
- warnf("regcomp failed: %s", err);
- else
- warnf("regcomp failed");
- return EXIT_FAILURE;
- }
- ret = regexec(&preg, match, 0, NULL, 0);
- regfree(&preg);
-
- return ret;
-}
-
-char *rmspace(char *s)
-{
- register char *p;
- /* wipe end of string */
- for (p = s + strlen(s) - 1; ((isspace(*p)) && (p >= s)); p--);
- if (p != s + strlen(s) - 1)
- *(p + 1) = 0;
- for (p = s; ((isspace(*p)) && (*p)); p++);
- if (p != s)
- strcpy(s, p);
- return (char *) s;
-}
-
-char *initialize_portdir(void)
-{
- FILE *fp;
- char buf[_POSIX_PATH_MAX + 8];
- char *p = getenv("PORTDIR");
- size_t i;
-
- if (p) {
- if (strlen(p) < sizeof(portdir)) {
- strncpy(portdir, p, sizeof(portdir));
- return portdir;
- }
- }
- if ((fp = fopen("/etc/make.conf", "r")) != NULL) {
- while ((fgets(buf, sizeof(buf), fp)) != NULL) {
- if (*buf != 'P')
- continue;
- if (strncmp(buf, "PORTDIR=", 8) != 0)
- continue;
- /* Sorry don't understand bash variables. */
- if ((strchr(buf, '$')) != NULL)
- continue;
-
- for (i = 8; i < strlen(buf); i++)
- if ((buf[i] == '"') || (buf[i] == '\''))
- buf[i] = ' ';
-
- rmspace(&buf[8]);
- strncpy(portdir, buf + 8, sizeof(portdir));
- }
- fclose(fp);
- }
- return portdir;
-}
-
-#include "qfile.c"
-#include "qlist.c"
-#include "qsearch.c"
-#include "quse.c"
-
-void initialize_ebuild_flat(void)
-{
- DIR *dir[3];
- struct dirent *dentry[3];
- FILE *fp;
- time_t start;
-
- if ((chdir(portdir)) != 0) {
- warn("Error: unable chdir to what I think is your PORTDIR '%s' : %s",
- portdir, strerror(errno));
- return;
- }
-
- /* assuming --sync is used with --delete this will get recreated after every merged */
- if (access(".ebuild.x", W_OK) == 0)
- return;
-
- warn("Updating ebuild cache ... ");
-
- unlink(".ebuild.x");
- if (errno != ENOENT) {
- warnf("Error: unlinking %s/%s : %s", portdir,
- ".ebuild.x", strerror(errno));
- return;
- }
-
- if ((fp = fopen(".ebuild.x", "w")) == NULL) {
- warnf("Error opening %s/.ebuild.x %s", portdir,
- strerror(errno));
- return;
- }
-
- start = time(0);
- if ((dir[0] = opendir(".")) == NULL)
- return;
-
- while ((dentry[0] = readdir(dir[0]))) {
- struct stat st;
- stat(dentry[0]->d_name, &st);
-
- if (*dentry[0]->d_name == '.')
- continue;
-
- if (!(S_ISDIR(st.st_mode)))
- continue;
-
- if ((strchr(dentry[0]->d_name, '-')) == NULL)
- continue;
-
- if ((dir[1] = opendir(dentry[0]->d_name)) == NULL)
- continue;
-
- while ((dentry[1] = readdir(dir[1]))) {
- char de[_POSIX_PATH_MAX];
- if (*dentry[1]->d_name == '.')
- continue;
-
- snprintf(de, sizeof(de), "%s/%s", dentry[0]->d_name,
- dentry[1]->d_name);
-
- stat(de, &st);
- if (!(S_ISDIR(st.st_mode)))
- continue;
-
- if ((dir[2] = opendir(de)) == NULL)
- continue;
-
- while ((dentry[2] = readdir(dir[2]))) {
- char *p;
- if (*dentry[2]->d_name == '.')
- continue;
- if ((p = rindex(dentry[2]->d_name, '.')) != NULL)
- if (strcmp(p, ".ebuild") == 0) {
- fprintf(fp, "%s/%s/%s\n", dentry[0]->d_name,
- dentry[1]->d_name, dentry[2]->d_name);
- }
- }
- closedir(dir[2]);
- }
- closedir(dir[1]);
- }
- closedir(dir[0]);
- fclose(fp);
- warn("Finished in %lu seconds", time(0) - start);
-}
-
-void reinitialize_ebuild_flat(void)
-{
- if ((chdir(portdir)) != 0) {
- warn("Error: unable chdir to what I think is your PORTDIR '%s' : %s",
- portdir, strerror(errno));
- return;
- }
- unlink(".ebuild.x");
- initialize_ebuild_flat();
-}
#define Q_FLAGS "i" COMMON_FLAGS
static struct option const q_long_opts[] = {
@@ -355,7 +35,9 @@ static const char *q_opts_help[] = {
"Install symlinks for applets",
COMMON_OPTS_HELP
};
-#define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, Q_IDX)
+#define q_usage(ret) usage(ret, Q_FLAGS, q_long_opts, q_opts_help, APPLET_Q)
+
+
int q_main(int argc, char **argv)
{
@@ -412,17 +94,3 @@ int q_main(int argc, char **argv)
return (func)(argc - 1, ++argv);
}
-
-void reinitialize_as_needed(void)
-{
- if (reinitialize)
- reinitialize_ebuild_flat();
-}
-
-int main(int argc, char **argv)
-{
- argv0 = argv[0];
- initialize_portdir();
- atexit(reinitialize_as_needed);
- return q_main(argc, argv);
-}