diff --git a/src/librc-depend.c b/src/librc-depend.c index 37f5d9ea..150edb16 100644 --- a/src/librc-depend.c +++ b/src/librc-depend.c @@ -149,7 +149,7 @@ rc_depinfo_t *rc_deptree_load (void) } librc_hidden_def(rc_deptree_load) -rc_depinfo_t *rc_deptree_depinfo (rc_depinfo_t *deptree, const char *service) +static rc_depinfo_t *get_depinfo (rc_depinfo_t *deptree, const char *service) { rc_depinfo_t *di; @@ -162,9 +162,8 @@ rc_depinfo_t *rc_deptree_depinfo (rc_depinfo_t *deptree, const char *service) return (NULL); } -librc_hidden_def(rc_deptree_depinfo) -rc_deptype_t *rc_deptree_deptype (rc_depinfo_t *depinfo, const char *type) +static rc_deptype_t *get_deptype (rc_depinfo_t *depinfo, const char *type) { rc_deptype_t *dt; @@ -177,7 +176,6 @@ rc_deptype_t *rc_deptree_deptype (rc_depinfo_t *depinfo, const char *type) return (NULL); } -librc_hidden_def(rc_deptree_deptype) static bool valid_service (const char *runlevel, const char *service) { @@ -260,7 +258,7 @@ static char **get_provided (rc_depinfo_t *deptree, rc_depinfo_t *depinfo, if (rc_service_exists (depinfo->service)) return (NULL); - dt = rc_deptree_deptype (depinfo, "providedby"); + dt = get_deptype (depinfo, "providedby"); if (! dt) return (NULL); @@ -379,7 +377,7 @@ static void visit_service (rc_depinfo_t *deptree, char **types, STRLIST_FOREACH (types, item, i) { - if ((dt = rc_deptree_deptype (depinfo, item))) + if ((dt = get_deptype (depinfo, item))) { STRLIST_FOREACH (dt->services, service, j) { @@ -389,12 +387,12 @@ static void visit_service (rc_depinfo_t *deptree, char **types, continue; } - di = rc_deptree_depinfo (deptree, service); + di = get_depinfo (deptree, service); if ((provides = get_provided (deptree, di, runlevel, options))) { STRLIST_FOREACH (provides, lp, k) { - di = rc_deptree_depinfo (deptree, lp); + di = get_depinfo (deptree, lp); if (di && (strcmp (item, "ineed") == 0 || strcmp (item, "needsme") == 0 || valid_service (runlevel, di->service))) @@ -415,11 +413,11 @@ static void visit_service (rc_depinfo_t *deptree, char **types, /* Now visit the stuff we provide for */ if (options & RC_DEP_TRACE && - (dt = rc_deptree_deptype (depinfo, "iprovide"))) + (dt = get_deptype (depinfo, "iprovide"))) { STRLIST_FOREACH (dt->services, service, i) { - if ((di = rc_deptree_depinfo (deptree, service))) + if ((di = get_depinfo (deptree, service))) if ((provides = get_provided (deptree, di, runlevel, options))) { STRLIST_FOREACH (provides, lp, j) @@ -438,7 +436,7 @@ static void visit_service (rc_depinfo_t *deptree, char **types, are also the service calling us or we are provided by something */ svcname = getenv("SVCNAME"); if (! svcname || strcmp (svcname, depinfo->service) != 0) - if (! rc_deptree_deptype (depinfo, "providedby")) + if (! get_deptype (depinfo, "providedby")) rc_strlist_add (&sorted->list, depinfo->service); } @@ -452,7 +450,7 @@ char **rc_deptree_depends (rc_depinfo_t *deptree, char *service; int i; - if (! deptree || ! types || ! services) + if (! deptree || ! services) return (NULL); memset (&sorted, 0, sizeof (struct lhead)); @@ -464,8 +462,13 @@ char **rc_deptree_depends (rc_depinfo_t *deptree, STRLIST_FOREACH (services, service, i) { - di = rc_deptree_depinfo (deptree, service); - visit_service (deptree, types, &sorted, &visited, di, runlevel, options); + if (! (di = get_depinfo (deptree, service))) { + errno = ENOENT; + continue; + } + if (types) + visit_service (deptree, types, &sorted, &visited, + di, runlevel, options); } rc_strlist_free (visited.list); @@ -650,14 +653,14 @@ librc_hidden_def(rc_deptree_update_needed) Phase 4 scans that depinfo object and puts in backlinks Phase 5 saves the depinfo object to disk */ -int rc_deptree_update (void) +bool rc_deptree_update (void) { char *depends; char *service; char *type; char *depend; char **config = NULL; - int retval = 0; + int retval = true; FILE *fp; rc_depinfo_t *deptree; rc_depinfo_t *depinfo; @@ -680,7 +683,7 @@ int rc_deptree_update (void) /* Phase 1 */ if (! (fp = popen (GENDEP, "r"))) - return (-1); + return (false); deptree = rc_xmalloc (sizeof (rc_depinfo_t)); memset (deptree, 0, sizeof (rc_depinfo_t)); @@ -779,7 +782,7 @@ int rc_deptree_update (void) /* Phase 3 - add our providors to the tree */ for (depinfo = deptree; depinfo; depinfo = depinfo->next) { - if ((deptype = rc_deptree_deptype (depinfo, "iprovide"))) + if ((deptype = get_deptype (depinfo, "iprovide"))) STRLIST_FOREACH (deptype->services, service, i) { for (di = deptree; di; di = di->next) @@ -803,13 +806,13 @@ int rc_deptree_update (void) { for (i = 0; deppairs[i].depend; i++) { - deptype = rc_deptree_deptype (depinfo, deppairs[i].depend); + deptype = get_deptype (depinfo, deppairs[i].depend); if (! deptype) continue; STRLIST_FOREACH (deptype->services, service, j) { - di = rc_deptree_depinfo (deptree, service); + di = get_depinfo (deptree, service); if (! di) { if (strcmp (deptype->type, "ineed") == 0) @@ -817,7 +820,7 @@ int rc_deptree_update (void) fprintf (stderr, "Service `%s' needs non existant service `%s'", depinfo->service, service); - retval = -1; + retval = false; } continue; } @@ -884,8 +887,10 @@ int rc_deptree_update (void) i++; } fclose (fp); - } else - fprintf (stderr, "fopen `%s': %s", RC_DEPTREE, strerror (errno)); + } else { + fprintf (stderr, "fopen `%s': %s\n", RC_DEPTREE, strerror (errno)); + retval = false; + } /* Save our external config files to disk */ if (config) { @@ -893,8 +898,10 @@ int rc_deptree_update (void) STRLIST_FOREACH (config, service, i) fprintf (fp, "%s\n", service); fclose (fp); - } else + } else { fprintf (stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror (errno)); + retval = false; + } rc_strlist_free (config); } diff --git a/src/librc.h b/src/librc.h index 28f2e49d..efed97f2 100644 --- a/src/librc.h +++ b/src/librc.h @@ -55,8 +55,6 @@ librc_hidden_proto(rc_config_list) librc_hidden_proto(rc_config_load) librc_hidden_proto(rc_config_value) librc_hidden_proto(rc_deptree_depends) -librc_hidden_proto(rc_deptree_depinfo) -librc_hidden_proto(rc_deptree_deptype) librc_hidden_proto(rc_deptree_free) librc_hidden_proto(rc_deptree_load) librc_hidden_proto(rc_deptree_order_services) diff --git a/src/rc-depend.c b/src/rc-depend.c index 5129e9b6..b86e17db 100644 --- a/src/rc-depend.c +++ b/src/rc-depend.c @@ -5,9 +5,13 @@ Released under the GPLv2 */ +#define APPLET "rc-depend" + #include #include +#include +#include #include #include #include @@ -31,56 +35,97 @@ rc_depinfo_t *_rc_deptree_load (void) { return (rc_deptree_load ()); } +static char *applet = NULL; + +#include "_usage.h" +#define getoptstring "t:suT" getoptstring_COMMON +static struct option longopts[] = { + { "type", 0, NULL, 't'}, + { "notrace", 0, NULL, 'T'}, + { "strict", 0, NULL, 's'}, + { "update", 0, NULL, 'u'}, + longopts_COMMON + { NULL, 0, NULL, 0} +}; +static const char * const longopts_help[] = { + "Type(s) of dependency to list", + "Don't trace service dependencies", + "Only use what is in the runlevels", + "Force an update of the dependency tree", + longopts_help_COMMON +}; +#include "_usage.c" + int rc_depend (int argc, char **argv) { char **types = NULL; char **services = NULL; char **depends = NULL; + char **list; rc_depinfo_t *deptree = NULL; - rc_depinfo_t *di; char *service; int options = RC_DEP_TRACE; bool first = true; int i; bool update = false; char *runlevel = getenv ("RC_SOFTLEVEL"); + int opt; + char *token; + + applet = argv[0]; + + while ((opt = getopt_long (argc, argv, getoptstring, + longopts, (int *) 0)) != -1) + { + switch (opt) { + case 's': + options |= RC_DEP_STRICT; + break; + case 't': + while ((token = strsep (&optarg, ","))) + rc_strlist_addu (&types, token); + break; + case 'u': + update = true; + break; + case 'T': + options &= RC_DEP_TRACE; + break; + case '?': + einfo ("hello"); + + case_RC_COMMON_GETOPT + } + } + + if (update) { + bool u = false; + ebegin ("Caching service dependencies"); + u = rc_deptree_update (); + eend (u ? 0 : -1, "%s: %s", applet, strerror (errno)); + if (! u) + eerrorx ("Failed to update the dependency tree"); + } if (! runlevel) runlevel = rc_runlevel_get (); - for (i = 1; i < argc; i++) { - if (strcmp (argv[i], "--update") == 0) { - if (! update) { - ebegin ("Caching service dependencies"); - update = (rc_deptree_update () == 0); - eend (update ? 0 : -1, "Failed to update the dependency tree"); - } - continue; - } + if (! (deptree = _rc_deptree_load ())) + eerrorx ("failed to load deptree"); - if (strcmp (argv[i], "--strict") == 0) { - options |= RC_DEP_STRICT; - continue; - } + while (optind < argc) { + list = NULL; + rc_strlist_add (&list, argv[optind]); + errno = 0; + depends = rc_deptree_depends (deptree, NULL, list, runlevel, 0); + if (! depends && errno == ENOENT) + eerror ("no dependency info for service `%s'", argv[optind]); + else + rc_strlist_add (&services, argv[optind]); - if (strcmp (argv[i], "--notrace") == 0) { - options &= RC_DEP_TRACE; - continue; - } - - if (argv[i][0] == '-') { - argv[i]++; - rc_strlist_add (&types, argv[i]); - } else { - if ((deptree = _rc_deptree_load ()) == NULL) - eerrorx ("failed to load deptree"); - - di = rc_deptree_depinfo (deptree, argv[i]); - if (! di) - eerror ("no dependency info for service `%s'", argv[i]); - else - rc_strlist_add (&services, argv[i]); - } + rc_strlist_free (depends); + rc_strlist_free (list); + optind++; } if (! services) { @@ -117,6 +162,5 @@ int rc_depend (int argc, char **argv) rc_strlist_free (services); rc_strlist_free (depends); rc_deptree_free (deptree); - return (EXIT_SUCCESS); } diff --git a/src/rc.h b/src/rc.h index 7d1fce0a..6f8b7f56 100644 --- a/src/rc.h +++ b/src/rc.h @@ -254,15 +254,14 @@ pid_t *rc_find_pids (const char *exec, const char *cmd, #ifndef _IN_LIBRC /* Handles to internal structures */ -typedef void *rc_deptype_t; typedef void *rc_depinfo_t; #endif /*! Update the cached dependency tree if it's older than any init script, * its configuration file or an external configuration file the init script * has specified. - * @return 0 if successful, otherwise -1 */ -int rc_deptree_update (void); + * @return true if successful, otherwise false */ +bool rc_deptree_update (void); /*! Check if the cached dependency tree is older than any init script, * its configuration file or an external configuration file the init script @@ -275,18 +274,6 @@ bool rc_deptree_update_needed (void); * @return pointer to the dependency tree */ rc_depinfo_t *rc_deptree_load (void); -/*! Get a services depedency information from a loaded tree - * @param deptree to search - * @param service to find - * @return service dependency information */ -rc_depinfo_t *rc_deptree_depinfo (rc_depinfo_t *deptree, const char *service); - -/*! Get a depenency type from the service dependency information - * @param depinfo service dependency to search - * @param type to find - * @return service dependency type information */ -rc_deptype_t *rc_deptree_deptype (rc_depinfo_t *depinfo, const char *type); - char **rc_deptree_depends (rc_depinfo_t *deptree, char **types, char **services, const char *runlevel, int options); diff --git a/src/rc.map b/src/rc.map index 633714ea..917f40c5 100644 --- a/src/rc.map +++ b/src/rc.map @@ -4,8 +4,6 @@ global: rc_config_load; rc_config_value; rc_deptree_depends; - rc_deptree_depinfo; - rc_deptree_deptype; rc_deptree_free; rc_deptree_load; rc_deptree_order_services;