Exemple #1
0
int
rc_depend(int argc, char **argv)
{
	RC_STRINGLIST *list;
	RC_STRINGLIST *types;
	RC_STRINGLIST *services;
	RC_STRINGLIST *depends;
	RC_STRING *s;
	RC_DEPTREE *deptree = NULL;
	int options = RC_DEP_TRACE, update = 0;
	bool first = true;
	char *runlevel = xstrdup(getenv("RC_RUNLEVEL"));
	int opt;
	char *token;

	types = rc_stringlist_new();
	while ((opt = getopt_long(argc, argv, getoptstring,
		    longopts, (int *) 0)) != -1)
	{
		switch (opt) {
		case 'a':
			options |= RC_DEP_START;
			break;
		case 'o':
			options |= RC_DEP_STOP;
			break;
		case 's':
			options |= RC_DEP_STRICT;
			break;
		case 't':
			while ((token = strsep(&optarg, ",")))
				rc_stringlist_add(types, token);
			break;
		case 'u':
			update = 1;
			break;
		case 'T':
			options &= RC_DEP_TRACE;
			break;

			case_RC_COMMON_GETOPT
			    }
	}

	if (!(deptree = _rc_deptree_load(update, NULL)))
		eerrorx("failed to load deptree");

	if (!runlevel)
		runlevel = rc_runlevel_get();

	services = rc_stringlist_new();
	while (optind < argc) {
		list = rc_stringlist_new();
		rc_stringlist_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_stringlist_add(services, argv[optind]);

		rc_stringlist_free(depends);
		rc_stringlist_free(list);
		optind++;
	}
	if (!TAILQ_FIRST(services)) {
		rc_stringlist_free(services);
		rc_stringlist_free(types);
		rc_deptree_free(deptree);
		free(runlevel);
		if (update)
			return EXIT_SUCCESS;
		eerrorx("no services specified");
	}

	/* If we don't have any types, then supply some defaults */
	if (!TAILQ_FIRST(types)) {
		rc_stringlist_add(types, "ineed");
		rc_stringlist_add(types, "iuse");
	}

	depends = rc_deptree_depends(deptree, types, services,
	    runlevel, options);

	if (TAILQ_FIRST(depends)) {
		TAILQ_FOREACH(s, depends, entries) {
			if (first)
				first = false;
			else
				printf (" ");
			printf ("%s", s->value);

		}
		printf ("\n");
	}

	rc_stringlist_free(types);
	rc_stringlist_free(services);
	rc_stringlist_free(depends);
	rc_deptree_free(deptree);
	free(runlevel);
	return EXIT_SUCCESS;
}
Exemple #2
0
static void
do_stop_services(RC_STRINGLIST *types_n, RC_STRINGLIST *start_services,
				 const RC_STRINGLIST *stop_services, const RC_DEPTREE *deptree,
				 const char *newlevel, bool parallel, bool going_down)
{
	pid_t pid;
	RC_STRING *service, *svc1, *svc2;
	RC_STRINGLIST *deporder, *tmplist, *kwords;
	RC_SERVICE state;
	RC_STRINGLIST *nostop;
	bool crashed, nstop;

	if (!types_n) {
		types_n = rc_stringlist_new();
		rc_stringlist_add(types_n, "needsme");
	}

	crashed = rc_conf_yesno("rc_crashed_stop");

	nostop = rc_stringlist_split(rc_conf_value("rc_nostop"), " ");
	TAILQ_FOREACH_REVERSE(service, stop_services, rc_stringlist, entries)
	{
		state = rc_service_state(service->value);
		if (state & RC_SERVICE_STOPPED || state & RC_SERVICE_FAILED)
			continue;

		/* Sometimes we don't ever want to stop a service. */
		if (rc_stringlist_find(nostop, service->value)) {
			rc_service_mark(service->value, RC_SERVICE_FAILED);
			continue;
		}
		kwords = rc_deptree_depend(deptree, service->value, "keyword");
		if (rc_stringlist_find(kwords, "-stop") ||
		    rc_stringlist_find(kwords, "nostop") ||
		    (going_down &&
			(rc_stringlist_find(kwords, "-shutdown") ||
			    rc_stringlist_find(kwords, "noshutdown"))))
			nstop = true;
		else
			nstop = false;
		rc_stringlist_free(kwords);
		if (nstop) {
			rc_service_mark(service->value, RC_SERVICE_FAILED);
			continue;
		}

		/* If the service has crashed, skip futher checks and just stop
		   it */
		if (crashed &&
		    rc_service_daemons_crashed(service->value))
			goto stop;

		/* If we're in the start list then don't bother stopping us */
		svc1 = rc_stringlist_find(start_services, service->value);
		if (svc1) {
			if (newlevel && strcmp(runlevel, newlevel) != 0) {
				/* So we're in the start list. But we should
				 * be stopped if we have a runlevel
				 * configuration file for either the current
				 * or next so we use the correct one. */
				if (!runlevel_config(service->value,runlevel) &&
				    !runlevel_config(service->value,newlevel))
					continue;
			}
			else
				continue;
		}

		/* We got this far. Last check is to see if any any service
		 * that going to be started depends on us */
		if (!svc1) {
			tmplist = rc_stringlist_new();
			rc_stringlist_add(tmplist, service->value);
			deporder = rc_deptree_depends(deptree, types_n,
			    tmplist, newlevel ? newlevel : runlevel,
			    RC_DEP_STRICT | RC_DEP_TRACE);
			rc_stringlist_free(tmplist);
			svc2 = NULL;
			TAILQ_FOREACH(svc1, deporder, entries) {
				svc2 = rc_stringlist_find(start_services,
				    svc1->value);
				if (svc2)
					break;
			}