diff options
author | 2005-06-07 04:37:32 +0000 | |
---|---|---|
committer | 2005-06-07 04:37:32 +0000 | |
commit | 8c71dad3850587154075822d8f42ff29d9c2d0fd (patch) | |
tree | f8ea2e77f590199fdf38c5e52cfe105130fc2cac /q.c | |
parent | add some whitespace to help make readable (diff) | |
download | portage-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.c | 344 |
1 files changed, 6 insertions, 338 deletions
@@ -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); -} |