aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorFabian Groffen <grobian@gentoo.org>2019-03-27 11:53:58 +0100
committerFabian Groffen <grobian@gentoo.org>2019-03-27 11:53:58 +0100
commitd0a8d231167adddb80a73849d3bc70edbfda3507 (patch)
tree387e1ffea50f8da37063ce5be638fe35f7397712 /main.c
parentlibq: split out cache-related funcs from main/qsearch (diff)
downloadportage-utils-d0a8d231167adddb80a73849d3bc70edbfda3507.tar.gz
portage-utils-d0a8d231167adddb80a73849d3bc70edbfda3507.tar.bz2
portage-utils-d0a8d231167adddb80a73849d3bc70edbfda3507.zip
build: compile applets as separate objects
Instead of including everything from a single file, compile each applet separately. This standardises things somewhat, and allows for parallel compilation. Signed-off-by: Fabian Groffen <grobian@gentoo.org>
Diffstat (limited to 'main.c')
-rw-r--r--main.c604
1 files changed, 30 insertions, 574 deletions
diff --git a/main.c b/main.c
index 01d358a..1da04fe 100644
--- a/main.c
+++ b/main.c
@@ -8,9 +8,19 @@
*/
#include "main.h"
+#include "applets.h"
+
+#include <iniparser.h>
+#include <xalloc.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <limits.h>
+
#include "atom.h"
#include "basename.h"
#include "busybox.h"
+#include "cache.h"
#include "colors.h"
#include "copy_file.h"
#include "eat_file.h"
@@ -32,34 +42,6 @@
#include "xregex.h"
#include "xsystem.h"
-#include <iniparser.h>
-#include <xalloc.h>
-#include <assert.h>
-#include <ctype.h>
-#include <sys/time.h>
-#include <limits.h>
-
-#if defined(__sun) && defined(__SVR4)
-/* workaround non-const defined name in option struct, such that we
- * don't get a zillion of warnings */
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-struct option {
- const char *name;
- int has_arg;
- int *flag;
- int val;
-};
-extern int getopt_long(int, char * const *, const char *,
- const struct option *, int *);
-#else
-# include <getopt.h>
-#endif
-
-/* prototypes and such */
-static int lookup_applet_idx(const char *);
-
/* variables to control runtime behavior */
char *module_name = NULL;
char *modpath = NULL;
@@ -67,29 +49,26 @@ int verbose = 0;
int quiet = 0;
int portcachedir_type = 0;
char pretend = 0;
-static int reinitialize = 0;
-static int reinitialize_metacache = 0;
-static char *portlogdir;
+char *portroot;
+char *config_protect;
+char *config_protect_mask;
+char *portvdb;
+char *portlogdir;
+char *pkg_install_mask;
+char *binhost;
+char *pkgdir;
+char *port_tmpdir;
+char *features;
+char *install_mask;
+DECLARE_ARRAY(overlays);
+
static char *main_overlay;
static char *portarch;
-static char *portvdb;
static char *portedb;
const char portcachedir_pms[] = "metadata/cache";
const char portcachedir_md5[] = "metadata/md5-cache";
-static char *portroot;
static char *eprefix;
-static char *config_protect, *config_protect_mask;
-
-static char *pkgdir;
-static char *port_tmpdir;
-
-static char *binhost;
-static char *features;
static char *accept_license;
-static char *install_mask;
-static char *pkg_install_mask;
-
-const char err_noapplet[] = "Sorry this applet was disabled at compile time";
/* helper functions for showing errors */
const char *argv0;
@@ -108,9 +87,7 @@ init_coredumps(void)
}
#endif
-static DECLARE_ARRAY(overlays);
-
-static void
+void
no_colors(void)
{
BOLD = NORM = BLUE = DKBLUE = CYAN = GREEN = DKGREEN = \
@@ -118,7 +95,7 @@ no_colors(void)
setenv("NOCOLOR", "true", 1);
}
-static void
+void
setup_quiet(void)
{
/* "e" for FD_CLOEXEC */
@@ -127,38 +104,8 @@ setup_quiet(void)
++quiet;
}
-/* include common applet defs */
-#include "applets.h"
-
-/* Common usage for all applets */
-#define COMMON_FLAGS "vqChV"
-#define COMMON_LONG_OPTS \
- {"root", a_argument, NULL, 0x1}, \
- {"verbose", no_argument, NULL, 'v'}, \
- {"quiet", no_argument, NULL, 'q'}, \
- {"nocolor", no_argument, NULL, 'C'}, \
- {"help", no_argument, NULL, 'h'}, \
- {"version", no_argument, NULL, 'V'}, \
- {NULL, no_argument, NULL, 0x0}
-#define COMMON_OPTS_HELP \
- "Set the ROOT env var", \
- "Make a lot of noise", \
- "Tighter output; suppress warnings", \
- "Don't output color", \
- "Print this help and exit", \
- "Print version and exit", \
- NULL
-#define COMMON_GETOPTS_CASES(applet) \
- case 0x1: portroot = optarg; break; \
- case 'v': ++verbose; break; \
- case 'q': setup_quiet(); break; \
- case 'V': version_barf(); break; \
- case 'h': applet ## _usage(EXIT_SUCCESS); break; \
- case 'C': no_colors(); break; \
- default: applet ## _usage(EXIT_FAILURE); break;
-
/* display usage and exit */
-static void
+void
usage(int status, const char *flags, struct option const opts[],
const char * const help[], const char *desc, int blabber)
{
@@ -226,7 +173,7 @@ usage(int status, const char *flags, struct option const opts[],
exit(status);
}
-static void
+void
version_barf(void)
{
const char *vcsid = "";
@@ -250,39 +197,7 @@ version_barf(void)
exit(EXIT_SUCCESS);
}
-static bool
-prompt(const char *p)
-{
- printf("%s? [Y/n] ", p);
- fflush(stdout);
- switch (getc(stdin)) {
- case '\n':
- case 'y':
- case 'Y':
- return true;
- default:
- return false;
- }
-}
-
-int
-rematch(const char *re, const char *match, int cflags)
-{
- regex_t preg;
- int ret;
-
- if ((match == NULL) || (re == NULL))
- return EXIT_FAILURE;
-
- if (wregcomp(&preg, re, cflags))
- return EXIT_FAILURE;
- ret = regexec(&preg, match, 0, NULL, 0);
- regfree(&preg);
-
- return ret;
-}
-
-static void
+void
freeargv(int argc, char **argv)
{
while (argc--)
@@ -290,7 +205,7 @@ freeargv(int argc, char **argv)
free(argv);
}
-static void
+void
makeargv(const char *string, int *argc, char ***argv)
{
int curc = 2;
@@ -320,96 +235,6 @@ makeargv(const char *string, int *argc, char ***argv)
free(q);
}
-/*
- * Parse a line of CONTENTS file and provide access to the individual fields
- */
-typedef enum {
- CONTENTS_DIR, CONTENTS_OBJ, CONTENTS_SYM
-} contents_type;
-typedef struct {
- contents_type type;
- char *_data;
- char *name;
- char *sym_target;
- char *digest;
- char *mtime_str;
- long mtime;
-} contents_entry;
-
-static contents_entry *
-contents_parse_line(char *line)
-{
- static contents_entry e;
- char *p;
-
- if (!line || !*line || *line == '\n')
- return NULL;
-
- /* chop trailing newline */
- if ((p = strrchr(line, '\n')) != NULL)
- *p = '\0';
-
- /* ferringb wants to break portage/vdb by using tabs vs spaces
- * so filenames can have lame ass spaces in them..
- * (I smell Windows near by)
- * Anyway we just convert that crap to a space so we can still
- * parse quickly */
- p = line;
- while ((p = strchr(p, '\t')) != NULL)
- *p = ' ';
-
- memset(&e, 0x00, sizeof(e));
- e._data = line;
-
- if (!strncmp(e._data, "obj ", 4))
- e.type = CONTENTS_OBJ;
- else if (!strncmp(e._data, "dir ", 4))
- e.type = CONTENTS_DIR;
- else if (!strncmp(e._data, "sym ", 4))
- e.type = CONTENTS_SYM;
- else
- return NULL;
-
- e.name = e._data + 4;
-
- switch (e.type) {
- /* dir /bin */
- case CONTENTS_DIR:
- break;
-
- /* obj /bin/bash 62ed51c8b23866777552643ec57614b0 1120707577 */
- case CONTENTS_OBJ:
- if ((e.mtime_str = strrchr(e.name, ' ')) == NULL)
- return NULL;
- *e.mtime_str++ = '\0';
- if ((e.digest = strrchr(e.name, ' ')) == NULL)
- return NULL;
- *e.digest++ = '\0';
- break;
-
- /* sym /bin/sh -> bash 1120707577 */
- case CONTENTS_SYM:
- if ((e.mtime_str = strrchr(e.name, ' ')) == NULL)
- return NULL;
- *e.mtime_str++ = '\0';
- if ((e.sym_target = strstr(e.name, " -> ")) == NULL)
- return NULL;
- *e.sym_target = '\0';
- e.sym_target += 4;
- break;
- }
-
- if (e.mtime_str) {
- e.mtime = strtol(e.mtime_str, NULL, 10);
- if (e.mtime == LONG_MAX) {
- e.mtime = 0;
- e.mtime_str = NULL;
- }
- }
-
- return &e;
-}
-
/* Handle a single file in the repos.conf format. */
static void
read_one_repos_conf(const char *repos_conf)
@@ -958,22 +783,7 @@ initialize_portage_env(void)
color_remap();
}
-enum {
- CACHE_EBUILD = 1,
- CACHE_METADATA = 2,
- CACHE_METADATA_PMS = 10,
- CACHE_METADATA_MD5 = 11,
-};
-
-static int
-filter_hidden(const struct dirent *dentry)
-{
- if (dentry->d_name[0] == '.')
- return 0;
- return 1;
-}
-
-static const char *
+const char *
initialize_flat(const char *overlay, int cache_type, bool force)
{
struct dirent **category, **pn, **eb;
@@ -1109,357 +919,6 @@ ret:
return cache_file;
}
-static void
-reinitialize_as_needed(void)
-{
- size_t n;
- const char *overlay, *ret = ret;
-
- if (reinitialize)
- array_for_each(overlays, n, overlay) {
- ret = initialize_flat(overlay, CACHE_EBUILD, true);
- if (USE_CLEANUP)
- free((void *)ret);
- }
-
- if (reinitialize_metacache)
- array_for_each(overlays, n, overlay) {
- ret = initialize_flat(overlay, CACHE_METADATA, true);
- if (USE_CLEANUP)
- free((void *)ret);
- }
-}
-
-typedef struct {
- char *_data;
- char *DEPEND; /* line 1 */
- char *RDEPEND;
- char *SLOT;
- char *SRC_URI;
- char *RESTRICT; /* line 5 */
- char *HOMEPAGE;
- char *LICENSE;
- char *DESCRIPTION;
- char *KEYWORDS;
- char *INHERITED; /* line 10 */
- char *IUSE;
- char *CDEPEND;
- char *PDEPEND;
- char *PROVIDE; /* line 14 */
- char *EAPI;
- char *PROPERTIES;
- depend_atom *atom;
- /* These are MD5-Cache only */
- char *DEFINED_PHASES;
- char *REQUIRED_USE;
- char *_eclasses_;
- char *_md5_;
-} portage_cache;
-
-static void cache_free(portage_cache *cache);
-static portage_cache *cache_read_file_pms(const char *file);
-static portage_cache *cache_read_file_md5(const char *file);
-
-static portage_cache *
-cache_read_file(const char *file)
-{
- if (portcachedir_type == CACHE_METADATA_MD5)
- return(cache_read_file_md5(file));
- else if (portcachedir_type == CACHE_METADATA_PMS)
- return(cache_read_file_pms(file));
- warn("Unknown metadata cache type!");
- return NULL;
-}
-
-static portage_cache *
-cache_read_file_pms(const char *file)
-{
- struct stat s;
- char *ptr;
- FILE *f;
- portage_cache *ret = NULL;
- size_t len;
-
- if ((f = fopen(file, "r")) == NULL)
- goto err;
-
- if (fstat(fileno(f), &s) != 0)
- goto err;
- len = sizeof(*ret) + s.st_size + 1;
- ret = xzalloc(len);
- ptr = (char*)ret;
- ret->_data = ptr + sizeof(*ret);
- if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size)
- goto err;
-
- ret->atom = atom_explode(file);
- ret->DEPEND = ret->_data;
-#define next_line(curr, next) \
- if ((ptr = strchr(ret->curr, '\n')) == NULL) { \
- warn("Invalid cache file '%s'", file); \
- goto err; \
- } \
- ret->next = ptr+1; \
- *ptr = '\0';
- next_line(DEPEND, RDEPEND)
- next_line(RDEPEND, SLOT)
- next_line(SLOT, SRC_URI)
- next_line(SRC_URI, RESTRICT)
- next_line(RESTRICT, HOMEPAGE)
- next_line(HOMEPAGE, LICENSE)
- next_line(LICENSE, DESCRIPTION)
- next_line(DESCRIPTION, KEYWORDS)
- next_line(KEYWORDS, INHERITED)
- next_line(INHERITED, IUSE)
- next_line(IUSE, CDEPEND)
- next_line(CDEPEND, PDEPEND)
- next_line(PDEPEND, PROVIDE)
- next_line(PROVIDE, EAPI)
- next_line(EAPI, PROPERTIES)
-#undef next_line
- ptr = strchr(ptr+1, '\n');
- if (ptr == NULL) {
- warn("Invalid cache file '%s' - could not find end of cache data", file);
- goto err;
- }
- *ptr = '\0';
-
- fclose(f);
-
- return ret;
-
-err:
- if (f) fclose(f);
- if (ret) cache_free(ret);
- return NULL;
-}
-
-static portage_cache *
-cache_read_file_md5(const char *file)
-{
- struct stat s;
- char *ptr, *endptr;
- FILE *f;
- portage_cache *ret = NULL;
- size_t len;
-
- if ((f = fopen(file, "r")) == NULL)
- goto err;
-
- if (fstat(fileno(f), &s) != 0)
- goto err;
- len = sizeof(*ret) + s.st_size + 1;
- ret = xzalloc(len);
- ptr = (char*)ret;
- ret->_data = ptr + sizeof(*ret);
- if ((off_t)fread(ret->_data, 1, s.st_size, f) != s.st_size)
- goto err;
-
- ret->atom = atom_explode(file);
-
- /* We have a block of key=value\n data.
- * KEY=VALUE\n
- * Where KEY does NOT contain:
- * \0 \n =
- * And VALUE does NOT contain:
- * \0 \n
- * */
-#define assign_var_cmp(keyname, cmpkey) \
- if (strncmp(keyptr, cmpkey, strlen(cmpkey)) == 0) { \
- ret->keyname = valptr; \
- continue; \
- }
-#define assign_var(keyname) \
- assign_var_cmp(keyname, #keyname);
-
- ptr = ret->_data;
- endptr = strchr(ptr, '\0');
- if (endptr == NULL) {
- warn("Invalid cache file '%s' - could not find end of cache data", file);
- goto err;
- }
-
- while (ptr != NULL && ptr != endptr) {
- char *keyptr;
- char *valptr;
- keyptr = ptr;
- valptr = strchr(ptr, '=');
- if (valptr == NULL) {
- warn("Invalid cache file '%s' val", file);
- goto err;
- }
- *valptr = '\0';
- valptr++;
- ptr = strchr(valptr, '\n');
- if (ptr == NULL) {
- warn("Invalid cache file '%s' key", file);
- goto err;
- }
- *ptr = '\0';
- ptr++;
-
- assign_var(CDEPEND);
- assign_var(DEPEND);
- assign_var(DESCRIPTION);
- assign_var(EAPI);
- assign_var(HOMEPAGE);
- assign_var(INHERITED);
- assign_var(IUSE);
- assign_var(KEYWORDS);
- assign_var(LICENSE);
- assign_var(PDEPEND);
- assign_var(PROPERTIES);
- assign_var(PROVIDE);
- assign_var(RDEPEND);
- assign_var(RESTRICT);
- assign_var(SLOT);
- assign_var(SRC_URI);
- assign_var(DEFINED_PHASES);
- assign_var(REQUIRED_USE);
- assign_var(_eclasses_);
- assign_var(_md5_);
- warn("Cache file '%s' with unknown key %s", file, keyptr);
- }
-#undef assign_var
-#undef assign_var_cmp
-
- fclose(f);
-
- return ret;
-
-err:
- if (f) fclose(f);
- if (ret) cache_free(ret);
- return NULL;
-}
-
-#ifdef EBUG
-static void
-cache_dump(portage_cache *cache)
-{
- if (!cache)
- errf("Cache is empty !");
-
- printf("DEPEND : %s\n", cache->DEPEND);
- printf("RDEPEND : %s\n", cache->RDEPEND);
- printf("SLOT : %s\n", cache->SLOT);
- printf("SRC_URI : %s\n", cache->SRC_URI);
- printf("RESTRICT : %s\n", cache->RESTRICT);
- printf("HOMEPAGE : %s\n", cache->HOMEPAGE);
- printf("LICENSE : %s\n", cache->LICENSE);
- printf("DESCRIPTION: %s\n", cache->DESCRIPTION);
- printf("KEYWORDS : %s\n", cache->KEYWORDS);
- printf("INHERITED : %s\n", cache->INHERITED);
- printf("IUSE : %s\n", cache->IUSE);
- printf("CDEPEND : %s\n", cache->CDEPEND);
- printf("PDEPEND : %s\n", cache->PDEPEND);
- printf("PROVIDE : %s\n", cache->PROVIDE);
- printf("EAPI : %s\n", cache->EAPI);
- printf("PROPERTIES : %s\n", cache->PROPERTIES);
- if (!cache->atom) return;
- printf("CATEGORY : %s\n", cache->atom->CATEGORY);
- printf("PN : %s\n", cache->atom->PN);
- printf("PV : %s\n", cache->atom->PV);
- printf("PVR : %s\n", cache->atom->PVR);
-}
-#endif
-
-static void
-cache_free(portage_cache *cache)
-{
- if (!cache)
- errf("Cache is empty !");
- atom_implode(cache->atom);
- free(cache);
-}
-
-static char *
-atom_to_pvr(depend_atom *atom) {
- return (atom->PR_int == 0 ? atom->P : atom->PVR );
-}
-
-/* TODO: Merge this into libq/vdb.c somehow. */
-static set *
-get_vdb_atoms(int fullcpv)
-{
- q_vdb_ctx *ctx;
-
- int cfd, j;
- int dfd, i;
-
- char buf[_Q_PATH_MAX];
- char slot[_Q_PATH_MAX];
- char *slotp = slot;
- size_t slot_len;
-
- struct dirent **cat;
- struct dirent **pf;
-
- depend_atom *atom = NULL;
- set *cpf = NULL;
-
- ctx = q_vdb_open(portroot, portvdb);
- if (!ctx)
- return NULL;
-
- /* scan the cat first */
- cfd = scandirat(ctx->vdb_fd, ".", &cat, q_vdb_filter_cat, alphasort);
- if (cfd < 0)
- goto fuckit;
-
- for (j = 0; j < cfd; j++) {
- dfd = scandirat(ctx->vdb_fd, cat[j]->d_name,
- &pf, q_vdb_filter_pkg, alphasort);
- if (dfd < 0)
- continue;
- for (i = 0; i < dfd; i++) {
- int blen = snprintf(buf, sizeof(buf), "%s/%s/SLOT",
- cat[j]->d_name, pf[i]->d_name);
- if (blen < 0 || (size_t)blen >= sizeof(buf)) {
- warnf("unable to parse long package: %s/%s",
- cat[j]->d_name, pf[i]->d_name);
- continue;
- }
-
- /* Chop the SLOT for the atom parsing. */
- buf[blen - 5] = '\0';
- if ((atom = atom_explode(buf)) == NULL)
- continue;
- /* Restore the SLOT. */
- buf[blen - 5] = '/';
-
- slot_len = sizeof(slot);
- eat_file_at(ctx->vdb_fd, buf, &slotp, &slot_len);
- rmspace(slot);
-
- if (fullcpv) {
- if (atom->PR_int)
- snprintf(buf, sizeof(buf), "%s/%s-%s-r%i",
- atom->CATEGORY, atom->PN, atom->PV, atom->PR_int);
- else
- snprintf(buf, sizeof(buf), "%s/%s-%s",
- atom->CATEGORY, atom->PN, atom->PV);
- } else {
- snprintf(buf, sizeof(buf), "%s/%s", atom->CATEGORY, atom->PN);
- }
- atom_implode(atom);
- cpf = add_set(buf, cpf);
- }
- scandir_free(pf, dfd);
- }
- scandir_free(cat, cfd);
-
- fuckit:
- q_vdb_close(ctx);
- return cpf;
-}
-
-static void
-cleanup(void)
-{
- reinitialize_as_needed();
-}
-
int main(int argc, char **argv)
{
struct stat st;
@@ -1478,9 +937,6 @@ int main(int argc, char **argv)
no_colors();
initialize_portage_env();
- atexit(cleanup);
optind = 0;
return q_main(argc, argv);
}
-
-#include "include_applets.h"