static void cleanup(void) { #ifdef DEBUG_MEMORY RC_PID *p1 = LIST_FIRST(&service_pids); RC_PID *p2; #endif if (!rc_in_logger && !rc_in_plugin && applet && (strcmp(applet, "rc") == 0 || strcmp(applet, "openrc") == 0)) { if (hook_out) rc_plugin_run(hook_out, runlevel); rc_plugin_unload(); if (termios_orig) { tcsetattr(STDIN_FILENO, TCSANOW, termios_orig); free(termios_orig); } /* Clean runlevel start, stop markers */ rmdir(RC_STARTING); rmdir(RC_STOPPING); clean_failed(); rc_logger_close(); } #ifdef DEBUG_MEMORY while (p1) { p2 = LIST_NEXT(p1, entries); free(p1); p1 = p2; } rc_stringlist_free(hotplugged_services); rc_stringlist_free(stop_services); rc_stringlist_free(start_services); rc_stringlist_free(types_n); rc_stringlist_free(types_nua); rc_deptree_free(deptree); free(runlevel); #endif }
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; }