depinfo and deptype are now internal use only. rc-depend cuddles up to getopt.

This commit is contained in:
Roy Marples 2007-10-04 13:38:47 +00:00
parent 422ac82ef9
commit 379b66936c
5 changed files with 110 additions and 76 deletions

View File

@ -149,7 +149,7 @@ rc_depinfo_t *rc_deptree_load (void)
} }
librc_hidden_def(rc_deptree_load) 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; rc_depinfo_t *di;
@ -162,9 +162,8 @@ rc_depinfo_t *rc_deptree_depinfo (rc_depinfo_t *deptree, const char *service)
return (NULL); 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; rc_deptype_t *dt;
@ -177,7 +176,6 @@ rc_deptype_t *rc_deptree_deptype (rc_depinfo_t *depinfo, const char *type)
return (NULL); return (NULL);
} }
librc_hidden_def(rc_deptree_deptype)
static bool valid_service (const char *runlevel, const char *service) 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)) if (rc_service_exists (depinfo->service))
return (NULL); return (NULL);
dt = rc_deptree_deptype (depinfo, "providedby"); dt = get_deptype (depinfo, "providedby");
if (! dt) if (! dt)
return (NULL); return (NULL);
@ -379,7 +377,7 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
STRLIST_FOREACH (types, item, i) STRLIST_FOREACH (types, item, i)
{ {
if ((dt = rc_deptree_deptype (depinfo, item))) if ((dt = get_deptype (depinfo, item)))
{ {
STRLIST_FOREACH (dt->services, service, j) STRLIST_FOREACH (dt->services, service, j)
{ {
@ -389,12 +387,12 @@ static void visit_service (rc_depinfo_t *deptree, char **types,
continue; continue;
} }
di = rc_deptree_depinfo (deptree, service); di = get_depinfo (deptree, service);
if ((provides = get_provided (deptree, di, runlevel, options))) if ((provides = get_provided (deptree, di, runlevel, options)))
{ {
STRLIST_FOREACH (provides, lp, k) STRLIST_FOREACH (provides, lp, k)
{ {
di = rc_deptree_depinfo (deptree, lp); di = get_depinfo (deptree, lp);
if (di && (strcmp (item, "ineed") == 0 || if (di && (strcmp (item, "ineed") == 0 ||
strcmp (item, "needsme") == 0 || strcmp (item, "needsme") == 0 ||
valid_service (runlevel, di->service))) 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 */ /* Now visit the stuff we provide for */
if (options & RC_DEP_TRACE && if (options & RC_DEP_TRACE &&
(dt = rc_deptree_deptype (depinfo, "iprovide"))) (dt = get_deptype (depinfo, "iprovide")))
{ {
STRLIST_FOREACH (dt->services, service, i) 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))) if ((provides = get_provided (deptree, di, runlevel, options)))
{ {
STRLIST_FOREACH (provides, lp, j) 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 */ are also the service calling us or we are provided by something */
svcname = getenv("SVCNAME"); svcname = getenv("SVCNAME");
if (! svcname || strcmp (svcname, depinfo->service) != 0) 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); rc_strlist_add (&sorted->list, depinfo->service);
} }
@ -452,7 +450,7 @@ char **rc_deptree_depends (rc_depinfo_t *deptree,
char *service; char *service;
int i; int i;
if (! deptree || ! types || ! services) if (! deptree || ! services)
return (NULL); return (NULL);
memset (&sorted, 0, sizeof (struct lhead)); memset (&sorted, 0, sizeof (struct lhead));
@ -464,8 +462,13 @@ char **rc_deptree_depends (rc_depinfo_t *deptree,
STRLIST_FOREACH (services, service, i) STRLIST_FOREACH (services, service, i)
{ {
di = rc_deptree_depinfo (deptree, service); if (! (di = get_depinfo (deptree, service))) {
visit_service (deptree, types, &sorted, &visited, di, runlevel, options); errno = ENOENT;
continue;
}
if (types)
visit_service (deptree, types, &sorted, &visited,
di, runlevel, options);
} }
rc_strlist_free (visited.list); 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 4 scans that depinfo object and puts in backlinks
Phase 5 saves the depinfo object to disk Phase 5 saves the depinfo object to disk
*/ */
int rc_deptree_update (void) bool rc_deptree_update (void)
{ {
char *depends; char *depends;
char *service; char *service;
char *type; char *type;
char *depend; char *depend;
char **config = NULL; char **config = NULL;
int retval = 0; int retval = true;
FILE *fp; FILE *fp;
rc_depinfo_t *deptree; rc_depinfo_t *deptree;
rc_depinfo_t *depinfo; rc_depinfo_t *depinfo;
@ -680,7 +683,7 @@ int rc_deptree_update (void)
/* Phase 1 */ /* Phase 1 */
if (! (fp = popen (GENDEP, "r"))) if (! (fp = popen (GENDEP, "r")))
return (-1); return (false);
deptree = rc_xmalloc (sizeof (rc_depinfo_t)); deptree = rc_xmalloc (sizeof (rc_depinfo_t));
memset (deptree, 0, 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 */ /* Phase 3 - add our providors to the tree */
for (depinfo = deptree; depinfo; depinfo = depinfo->next) 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) STRLIST_FOREACH (deptype->services, service, i)
{ {
for (di = deptree; di; di = di->next) for (di = deptree; di; di = di->next)
@ -803,13 +806,13 @@ int rc_deptree_update (void)
{ {
for (i = 0; deppairs[i].depend; i++) for (i = 0; deppairs[i].depend; i++)
{ {
deptype = rc_deptree_deptype (depinfo, deppairs[i].depend); deptype = get_deptype (depinfo, deppairs[i].depend);
if (! deptype) if (! deptype)
continue; continue;
STRLIST_FOREACH (deptype->services, service, j) STRLIST_FOREACH (deptype->services, service, j)
{ {
di = rc_deptree_depinfo (deptree, service); di = get_depinfo (deptree, service);
if (! di) if (! di)
{ {
if (strcmp (deptype->type, "ineed") == 0) if (strcmp (deptype->type, "ineed") == 0)
@ -817,7 +820,7 @@ int rc_deptree_update (void)
fprintf (stderr, fprintf (stderr,
"Service `%s' needs non existant service `%s'", "Service `%s' needs non existant service `%s'",
depinfo->service, service); depinfo->service, service);
retval = -1; retval = false;
} }
continue; continue;
} }
@ -884,8 +887,10 @@ int rc_deptree_update (void)
i++; i++;
} }
fclose (fp); fclose (fp);
} else } else {
fprintf (stderr, "fopen `%s': %s", RC_DEPTREE, strerror (errno)); fprintf (stderr, "fopen `%s': %s\n", RC_DEPTREE, strerror (errno));
retval = false;
}
/* Save our external config files to disk */ /* Save our external config files to disk */
if (config) { if (config) {
@ -893,8 +898,10 @@ int rc_deptree_update (void)
STRLIST_FOREACH (config, service, i) STRLIST_FOREACH (config, service, i)
fprintf (fp, "%s\n", service); fprintf (fp, "%s\n", service);
fclose (fp); fclose (fp);
} else } else {
fprintf (stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror (errno)); fprintf (stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror (errno));
retval = false;
}
rc_strlist_free (config); rc_strlist_free (config);
} }

View File

@ -55,8 +55,6 @@ librc_hidden_proto(rc_config_list)
librc_hidden_proto(rc_config_load) librc_hidden_proto(rc_config_load)
librc_hidden_proto(rc_config_value) librc_hidden_proto(rc_config_value)
librc_hidden_proto(rc_deptree_depends) 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_free)
librc_hidden_proto(rc_deptree_load) librc_hidden_proto(rc_deptree_load)
librc_hidden_proto(rc_deptree_order_services) librc_hidden_proto(rc_deptree_order_services)

View File

@ -5,9 +5,13 @@
Released under the GPLv2 Released under the GPLv2
*/ */
#define APPLET "rc-depend"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <getopt.h>
#include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -31,56 +35,97 @@ rc_depinfo_t *_rc_deptree_load (void) {
return (rc_deptree_load ()); 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) int rc_depend (int argc, char **argv)
{ {
char **types = NULL; char **types = NULL;
char **services = NULL; char **services = NULL;
char **depends = NULL; char **depends = NULL;
char **list;
rc_depinfo_t *deptree = NULL; rc_depinfo_t *deptree = NULL;
rc_depinfo_t *di;
char *service; char *service;
int options = RC_DEP_TRACE; int options = RC_DEP_TRACE;
bool first = true; bool first = true;
int i; int i;
bool update = false; bool update = false;
char *runlevel = getenv ("RC_SOFTLEVEL"); 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) if (! runlevel)
runlevel = rc_runlevel_get (); runlevel = rc_runlevel_get ();
for (i = 1; i < argc; i++) { if (! (deptree = _rc_deptree_load ()))
if (strcmp (argv[i], "--update") == 0) { eerrorx ("failed to load deptree");
if (! update) {
ebegin ("Caching service dependencies");
update = (rc_deptree_update () == 0);
eend (update ? 0 : -1, "Failed to update the dependency tree");
}
continue;
}
if (strcmp (argv[i], "--strict") == 0) { while (optind < argc) {
options |= RC_DEP_STRICT; list = NULL;
continue; 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) { rc_strlist_free (depends);
options &= RC_DEP_TRACE; rc_strlist_free (list);
continue; optind++;
}
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]);
}
} }
if (! services) { if (! services) {
@ -117,6 +162,5 @@ int rc_depend (int argc, char **argv)
rc_strlist_free (services); rc_strlist_free (services);
rc_strlist_free (depends); rc_strlist_free (depends);
rc_deptree_free (deptree); rc_deptree_free (deptree);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
} }

View File

@ -254,15 +254,14 @@ pid_t *rc_find_pids (const char *exec, const char *cmd,
#ifndef _IN_LIBRC #ifndef _IN_LIBRC
/* Handles to internal structures */ /* Handles to internal structures */
typedef void *rc_deptype_t;
typedef void *rc_depinfo_t; typedef void *rc_depinfo_t;
#endif #endif
/*! Update the cached dependency tree if it's older than any init script, /*! Update the cached dependency tree if it's older than any init script,
* its configuration file or an external configuration file the init script * its configuration file or an external configuration file the init script
* has specified. * has specified.
* @return 0 if successful, otherwise -1 */ * @return true if successful, otherwise false */
int rc_deptree_update (void); bool rc_deptree_update (void);
/*! Check if the cached dependency tree is older than any init script, /*! Check if the cached dependency tree is older than any init script,
* its configuration file or an external configuration file the 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 */ * @return pointer to the dependency tree */
rc_depinfo_t *rc_deptree_load (void); 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 **rc_deptree_depends (rc_depinfo_t *deptree, char **types,
char **services, const char *runlevel, int options); char **services, const char *runlevel, int options);

View File

@ -4,8 +4,6 @@ global:
rc_config_load; rc_config_load;
rc_config_value; rc_config_value;
rc_deptree_depends; rc_deptree_depends;
rc_deptree_depinfo;
rc_deptree_deptype;
rc_deptree_free; rc_deptree_free;
rc_deptree_load; rc_deptree_load;
rc_deptree_order_services; rc_deptree_order_services;