uint16_t service_usage_query_group (enum einit_usage_query task, const struct lmodule *module, const char *service) { uint16_t ret = 0; struct stree *ha; if (!service) return 0; emutex_lock (&service_usage_mutex); if (task & service_add_group_provider) { if (!module || !module->module) { emutex_unlock (&service_usage_mutex); return 0; } if (!service_usage || !(ha = streefind (service_usage, service, tree_find_first))) { struct service_usage_item nitem; memset (&nitem, 0, sizeof (struct service_usage_item)); nitem.provider = (struct lmodule **)setadd ((void **)nitem.provider, (void *)module, SET_NOALLOC); service_usage = streeadd (service_usage, service, &nitem, sizeof (struct service_usage_item), NULL); } else { struct service_usage_item *citem = (struct service_usage_item *)ha->value; if (citem) { if (!inset ((const void **)citem->provider, (void *)module, SET_NOALLOC)) { citem->provider = (struct lmodule **)setadd ((void **)citem->provider, (void *)module, SET_NOALLOC); } } } } if (task & service_set_group_providers) { if (!service_usage || !(ha = streefind (service_usage, service, tree_find_first))) { struct service_usage_item nitem; memset (&nitem, 0, sizeof (struct service_usage_item)); nitem.provider = (struct lmodule **)setdup ((const void **)module, SET_NOALLOC); service_usage = streeadd (service_usage, service, &nitem, sizeof (struct service_usage_item), NULL); } else { struct service_usage_item *citem = (struct service_usage_item *)ha->value; if (citem) { free (citem->provider); citem->provider = (struct lmodule **)setdup ((const void **)module, SET_NOALLOC); } } } emutex_unlock (&service_usage_mutex); return ret; }
void fbsplash_queue_comand (const char *command) { emutex_lock (&fbsplash_commandQ_mutex); fbsplash_commandQ = (char **)setadd ((void **)fbsplash_commandQ, command, SET_TYPE_STRING); emutex_unlock (&fbsplash_commandQ_mutex); pthread_cond_broadcast (&fbsplash_commandQ_cond); }
void *event_emit (struct einit_event *event, enum einit_event_emit_flags flags) { pthread_t **threads = NULL; if (!event || !event->type) return NULL; event_do_wakeup_calls (event->type); if (flags & einit_event_flag_spawn_thread) { struct einit_event *ev = evdup(event); if (!ev) return NULL; ethread_spawn_detached_run ((void *(*)(void *))event_subthread, (void *)ev); return NULL; } uint32_t subsystem = event->type & EVENT_SUBSYSTEM_MASK; /* initialise sequence id and timestamp of the event */ event->seqid = cseqid++; event->timestamp = time(NULL); struct event_function *cur = event_functions; while (cur) { if (((cur->type == subsystem) || (cur->type == einit_event_subsystem_any)) && cur->handler) { if (flags & einit_event_flag_spawn_thread_multi_wait) { pthread_t *threadid = emalloc (sizeof (pthread_t)); struct evt_wrapper_data *d = emalloc (sizeof (struct evt_wrapper_data)); d->event = evdup(event); d->handler = cur->handler; ethread_create (threadid, NULL, (void *(*)(void *))event_thread_wrapper, d); threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC); } else cur->handler (event); } cur = cur->next; } if (event->chain_type) { event->type = event->chain_type; event->chain_type = 0; event_emit (event, flags); } if ((flags & einit_event_flag_spawn_thread_multi_wait) && threads) { int i = 0; for (; threads[i]; i++) { pthread_join (*(threads[i]), NULL); free (threads[i]); } free (threads); } return NULL; }
void db_set_object_flag(Objid oid, db_object_flag f) { objects[oid]->flags |= (1 << f); if (f == FLAG_USER) { Var v; v.type = TYPE_OBJ; v.v.obj = oid; all_users = setadd(all_users, v); } }
pid_t *filter_processes_cwd (struct pc_conditional * cond, pid_t * ret, struct process_status ** stat) { uint32_t i = 0; if (stat && cond && cond->para) for (; stat[i]; i++) { if (stat[i]->cwd && strmatch ((char *)cond->para, stat[i]->cwd)) { uintptr_t tmp = (stat[i]->pid); ret = (pid_t *)setadd ((void **)ret, (void *)tmp, SET_NOALLOC); } } return ret; }
void linux_static_dev_hotplug_handle (char **v) { if (v && v[0]) { int i = 0; char **args = NULL; struct einit_event ev = evstaticinit(einit_hotplug_generic); if (strstr (v[0], "add@") == v[0]) { ev.type = einit_hotplug_add; } else if (strstr (v[0], "remove@") == v[0]) { ev.type = einit_hotplug_remove; } else if (strstr (v[0], "change@") == v[0]) { ev.type = einit_hotplug_change; } else if (strstr (v[0], "online@") == v[0]) { ev.type = einit_hotplug_online; } else if (strstr (v[0], "offline@") == v[0]) { ev.type = einit_hotplug_offline; } else if (strstr (v[0], "move@") == v[0]) { ev.type = einit_hotplug_move; } for (i = 1; v[i]; i++) { char *n = strchr (v[i], '='); if (n) { *n = 0; n++; args = (char **)setadd ((void **)args, v[i], SET_TYPE_STRING); args = (char **)setadd ((void **)args, n, SET_TYPE_STRING); } } ev.stringset = args; /* emit the event, waiting for it to be processed */ event_emit (&ev, einit_event_flag_broadcast); evstaticdestroy (ev); if (args) free (args); } }
/* Remove_Duplicates - from Access_Denied@LambdaMOO. */ static package bf_remove_duplicates(Var arglist, Byte next, void *vdata, Objid progr) { Var r; int i; r = new_list(0); for (i = 1; i <= arglist.v.list[1].v.list[0].v.num; i++) r = setadd(r, var_ref(arglist.v.list[1].v.list[i])); free_var(arglist); return make_var_pack(r); }
int linux_kernel_modules_load (char **modules) { if (!modules) return status_failed; pthread_t **threads = NULL; char *modprobe_command = cfg_getstring ("configuration-command-modprobe/with-env", 0); uint32_t i = 0; for (; modules[i]; i++) if (strcmp ("", modules[i])) { const char *tpldata[] = { "module", modules[i], NULL }; char *applied = apply_variables (modprobe_command, tpldata); if (applied) { notice (4, "loading kernel module: %s", modules[i]); if (modules[i+1]) { pthread_t *threadid = emalloc (sizeof (pthread_t)); if (ethread_create (threadid, NULL, (void *(*)(void *))linux_kernel_modules_load_exec, applied)) { linux_kernel_modules_load_exec (applied); } else { threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC); } } else { linux_kernel_modules_load_exec (applied); } } } free (modules); if (threads) { int i = 0; for (; threads[i]; i++) { pthread_join (*(threads[i]), NULL); free (threads[i]); } free (threads); } return status_ok; }
int main(int argc, char **argv, char **environ) { #else int main(int argc, char **argv) { #endif int i, ret = EXIT_SUCCESS; pid_t pid = getpid(), wpid = 0; char **ipccommands = NULL; int pthread_errno; FILE *commandpipe_in, *commandpipe_out; int commandpipe[2]; int debugsocket[2]; char need_recovery = 0; char debug = 0; int debugme_pipe = 0; char crash_threshold = 5; char *einit_crash_data = NULL; boottime = time(NULL); uname (&osinfo); config_configure(); // initialise subsystems ipc_configure(NULL); // is this the system's init-process? isinit = getpid() == 1; event_listen (einit_event_subsystem_core, core_einit_event_handler); event_listen (einit_event_subsystem_timer, core_timer_event_handler); if (argv) einit_argv = (char **)setdup ((const void **)argv, SET_TYPE_STRING); /* check command line arguments */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') switch (argv[i][1]) { case 'c': if ((++i) < argc) einit_default_startup_configuration_files[0] = argv[i]; else return print_usage_info (); break; case 'h': return print_usage_info (); break; case 'v': eputs("eINIT " EINIT_VERSION_LITERAL "\n", stdout); return 0; case 'L': eputs("eINIT " EINIT_VERSION_LITERAL "\nThis Program is Free Software, released under the terms of this (BSD) License:\n" "--------------------------------------------------------------------------------\n" "Copyright (c) 2006, 2007, Magnus Deininger\n" BSDLICENSE "\n", stdout); return 0; case '-': if (strmatch(argv[i], "--check-configuration") || strmatch(argv[i], "--checkup") || strmatch(argv[i], "--wtf")) { ipccommands = (char **)setadd ((void **)ipccommands, "examine configuration", SET_TYPE_STRING); } else if (strmatch(argv[i], "--help")) return print_usage_info (); else if (strmatch(argv[i], "--ipc-command") && argv[i+1]) ipccommands = (char **)setadd ((void **)ipccommands, (void *)argv[i+1], SET_TYPE_STRING); else if (strmatch(argv[i], "--override-init-check")) initoverride = 1; else if (strmatch(argv[i], "--sandbox")) { einit_default_startup_configuration_files[0] = "lib/einit/einit.xml"; coremode = einit_mode_sandbox; need_recovery = 1; } else if (strmatch(argv[i], "--metadaemon")) { coremode = einit_mode_metadaemon; } else if (strmatch(argv[i], "--bootstrap-modules")) { bootstrapmodulepath = argv[i+1]; } else if (strmatch(argv[i], "--debugme")) { debugme_pipe = parse_integer (argv[i+1]); i++; initoverride = 1; } else if (strmatch(argv[i], "--debug")) { debug = 1; } break; } } /* check environment */ if (environ) { uint32_t e = 0; for (e = 0; environ[e]; e++) { char *ed = estrdup (environ[e]); char *lp = strchr (ed, '='); *lp = 0; lp++; if (strmatch (ed, "softlevel")) { einit_startup_mode_switches = str2set (':', lp); } if (strmatch (ed, "mode")) { /* override default mode-switches with the ones in the environment variable mode= */ einit_startup_mode_switches = str2set (':', lp); } else if (strmatch (ed, "einit")) { /* override default configuration files and/or mode-switches with the ones in the variable einit= */ char **tmpstrset = str2set (',', lp); uint32_t rx = 0; for (rx = 0; tmpstrset[rx]; rx++) { char **atom = str2set (':', tmpstrset[rx]); if (strmatch (atom[0], "file")) { /* specify configuration files */ einit_startup_configuration_files = (char **)setdup ((const void **)atom, SET_TYPE_STRING); einit_startup_configuration_files = (char **)strsetdel (einit_startup_configuration_files, (void *)"file"); } else if (strmatch (atom[0], "mode")) { /* specify mode-switches */ einit_startup_mode_switches = (char **)setdup ((const void **)atom, SET_TYPE_STRING); einit_startup_mode_switches = (char **)strsetdel (einit_startup_mode_switches, (void *)"mode"); } else if (strmatch (atom[0], "stfu")) { einit_quietness = 3; } else if (strmatch (atom[0], "silent")) { einit_quietness = 2; } else if (strmatch (atom[0], "quiet")) { einit_quietness = 1; } free (atom); } free (tmpstrset); } free (ed); } einit_initial_environment = (char **)setdup ((const void **)environ, SET_TYPE_STRING); } if (!einit_startup_mode_switches) einit_startup_mode_switches = einit_default_startup_mode_switches; if (!einit_startup_configuration_files) einit_startup_configuration_files = einit_default_startup_configuration_files; respawn: pipe (commandpipe); fcntl (commandpipe[1], F_SETFD, FD_CLOEXEC); socketpair (AF_UNIX, SOCK_STREAM, 0, debugsocket); fcntl (debugsocket[0], F_SETFD, FD_CLOEXEC); fcntl (debugsocket[1], F_SETFD, FD_CLOEXEC); if (!debug) { fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC); commandpipe_in = fdopen (commandpipe[0], "r"); } commandpipe_out = fdopen (commandpipe[1], "w"); if (!initoverride && ((pid == 1) || ((coremode & einit_mode_sandbox) && !ipccommands))) { // if (pid == 1) { initoverride = 1; #if 0 #ifdef LINUX if ((einit_sub = syscall(__NR_clone, CLONE_PTRACE | SIGCHLD, 0, NULL, NULL, NULL)) < 0) { bitch (bitch_stdio, errno, "Could not fork()"); eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr); } #else #endif #endif if ((einit_sub = fork()) < 0) { bitch (bitch_stdio, errno, "Could not fork()"); eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr); } } if (einit_sub) { /* PID==1 part */ int rstatus; struct sigaction action; /* signal handlers */ action.sa_sigaction = einit_sigint; sigemptyset(&(action.sa_mask)); action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; if ( sigaction (SIGINT, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed."); /* ignore sigpipe */ action.sa_sigaction = (void (*)(int, siginfo_t *, void *))SIG_IGN; if ( sigaction (SIGPIPE, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed."); close (debugsocket[1]); if (einit_crash_data) { free (einit_crash_data); einit_crash_data = NULL; } while (1) { wpid = waitpid(-1, &rstatus, 0); /* this ought to wait for ANY process */ if (wpid == einit_sub) { // goto respawn; /* try to recover by re-booting */ if (!debug) if (commandpipe_in) fclose (commandpipe_in); if (commandpipe_out) fclose (commandpipe_out); if (WIFEXITED(rstatus) && (WEXITSTATUS(rstatus) != einit_exit_status_die_respawn)) { fprintf (stderr, "eINIT has quit properly.\n"); if (!(coremode & einit_mode_sandbox)) { if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_halt) { execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "h", NULL); } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_reboot) { execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "r", NULL); } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_kexec) { execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "k", NULL); } } exit (EXIT_SUCCESS); } int n = 5; fprintf (stderr, "The secondary eINIT process has died, waiting a while before respawning.\n"); if ((einit_crash_data = readfd (debugsocket[0]))) { fprintf (stderr, " > neat, received crash data\n"); } while ((n = sleep (n))); fprintf (stderr, "Respawning secondary eINIT process.\n"); if (crash_threshold) crash_threshold--; else debug = 1; need_recovery = 1; initoverride = 0; close (debugsocket[0]); goto respawn; } else { if (commandpipe_out) { if (WIFEXITED(rstatus)) { fprintf (commandpipe_out, "pid %i terminated\n\n", wpid); } else { fprintf (commandpipe_out, "pid %i died\n\n", wpid); } fflush (commandpipe_out); } } } } else { enable_core_dumps (); close (debugsocket[0]); sched_trace_target = debugsocket[1]; if (debug) { char **xargv = (char **)setdup ((const void **)argv, SET_TYPE_STRING); char tbuffer[BUFFERSIZE]; struct stat st; char have_valgrind = 0; char have_gdb = 0; fputs ("eINIT needs to be debugged, starting in debugger mode\n.", stderr); xargv = (char **)setadd ((void **)xargv, (void *)"--debugme", SET_TYPE_STRING); snprintf (tbuffer, BUFFERSIZE, "%i", commandpipe[0]); xargv = (char **)setadd ((void **)xargv, (void *)tbuffer, SET_TYPE_STRING); xargv = strsetdel (xargv, "--debug"); // don't keep the --debug flag if (!stat ("/usr/bin/valgrind", &st)) have_valgrind = 1; if (!stat ("/usr/bin/gdb", &st)) have_gdb = 1; if (have_valgrind) { char **nargv = NULL; uint32_t i = 1; #ifdef LINUX if (!(coremode & einit_mode_sandbox)) { mount ("proc", "/proc", "proc", 0, NULL); mount ("sys", "/sys", "sysfs", 0, NULL); system ("mount / -o remount,rw"); } #endif nargv = (char **)setadd ((void **)nargv, "/usr/bin/valgrind", SET_TYPE_STRING); nargv = (char **)setadd ((void **)nargv, "--log-file=/einit.valgrind", SET_TYPE_STRING); nargv = (char **)setadd ((void **)nargv, (coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", SET_TYPE_STRING); for (; xargv[i]; i++) { nargv = (char **)setadd ((void **)nargv, xargv[i], SET_TYPE_STRING); } execv ("/usr/bin/valgrind", nargv); } else { execv ((coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", xargv); } } if (debugme_pipe) { // commandpipe[0] fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC); commandpipe_in = fdopen (debugme_pipe, "r"); } /* actual system initialisation */ struct einit_event cev = evstaticinit(einit_core_update_configuration); if (ipccommands && (coremode != einit_mode_sandbox)) { coremode = einit_mode_ipconly; } eprintf (stderr, "eINIT " EINIT_VERSION_LITERAL ": Initialising: %s\n", osinfo.sysname); if ((pthread_errno = pthread_attr_init (&thread_attribute_detached))) { bitch(bitch_epthreads, pthread_errno, "pthread_attr_init() failed."); if (einit_initial_environment) free (einit_initial_environment); return -1; } else { if ((pthread_errno = pthread_attr_setdetachstate (&thread_attribute_detached, PTHREAD_CREATE_DETACHED))) { bitch(bitch_epthreads, pthread_errno, "pthread_attr_setdetachstate() failed."); } } if ((pthread_errno = pthread_key_create(&einit_function_macro_key, NULL))) { bitch(bitch_epthreads, pthread_errno, "pthread_key_create(einit_function_macro_key) failed."); if (einit_initial_environment) free (einit_initial_environment); return -1; } /* this should be a good place to initialise internal modules */ if (coremodules) { uint32_t cp = 0; eputs (" >> initialising in-core modules:", stderr); for (; coremodules[cp]; cp++) { struct lmodule *lmm; eprintf (stderr, " [%s]", (*coremodules[cp])->rid); lmm = mod_add(NULL, (*coremodules[cp])); lmm->source = estrdup("core"); } eputs (" OK\n", stderr); } /* emit events to read configuration files */ if (einit_startup_configuration_files) { uint32_t rx = 0; for (; einit_startup_configuration_files[rx]; rx++) { cev.string = einit_startup_configuration_files[rx]; event_emit (&cev, einit_event_flag_broadcast); } if (einit_startup_configuration_files != einit_default_startup_configuration_files) { free (einit_startup_configuration_files); } } cev.string = NULL; cev.type = einit_core_configuration_update; // make sure we keep updating until everything is sorted out while (cev.type == einit_core_configuration_update) { // notice (2, "stuff changed, updating configuration."); cev.type = einit_core_update_configuration; event_emit (&cev, einit_event_flag_broadcast); } evstaticdestroy(cev); if (ipccommands) { uint32_t rx = 0; for (; ipccommands[rx]; rx++) { ret = ipc_process (ipccommands[rx], stdout); } // if (gmode == EINIT_GMODE_SANDBOX) // cleanup (); free (ipccommands); if (einit_initial_environment) free (einit_initial_environment); return ret; } else if ((coremode == einit_mode_init) && !isinit && !initoverride) { eputs ("WARNING: eINIT is configured to run as init, but is not the init-process (pid=1) and the --override-init-check flag was not specified.\nexiting...\n\n", stderr); exit (EXIT_FAILURE); } else { /* actual init code */ uint32_t e = 0; nice (einit_core_niceness_increment); if (need_recovery) { notice (1, "need to recover from something..."); struct einit_event eml = evstaticinit(einit_core_recover); event_emit (&eml, einit_event_flag_broadcast); evstaticdestroy(eml); } if (einit_crash_data) { notice (1, "submitting crash data..."); struct einit_event eml = evstaticinit(einit_core_crash_data); eml.string = einit_crash_data; event_emit (&eml, einit_event_flag_broadcast); evstaticdestroy(eml); free (einit_crash_data); einit_crash_data = NULL; } { notice (3, "running early bootup code..."); struct einit_event eml = evstaticinit(einit_boot_early); event_emit (&eml, einit_event_flag_broadcast | einit_event_flag_spawn_thread_multi_wait); evstaticdestroy(eml); } notice (2, "scheduling startup switches.\n"); for (e = 0; einit_startup_mode_switches[e]; e++) { struct einit_event ee = evstaticinit(einit_core_switch_mode); ee.string = einit_startup_mode_switches[e]; event_emit (&ee, einit_event_flag_broadcast | einit_event_flag_spawn_thread | einit_event_flag_duplicate); evstaticdestroy(ee); } struct einit_event eml = evstaticinit(einit_core_main_loop_reached); eml.file = commandpipe_in; event_emit (&eml, einit_event_flag_broadcast); evstaticdestroy(eml); } if (einit_initial_environment) free (einit_initial_environment); return ret; } /* this should never be reached... */ if (einit_initial_environment) free (einit_initial_environment); return 0; }
uint16_t service_usage_query (enum einit_usage_query task, const struct lmodule *module, const char *service) { uint16_t ret = 0; struct stree *ha; char **t; uint32_t i; struct service_usage_item *item; if ((!module || !module->module) && !service) return 0; emutex_lock (&service_usage_mutex); if (task & service_not_in_use) { ret |= service_not_in_use; struct stree *ha = service_usage; /* a service is "in use" if * it's the provider for something, and * it's the only provider for that for that specific service, and * all of the users of that service use the */ while (ha) { if (((struct service_usage_item *)(ha->value))->users && (((struct service_usage_item *)(ha->value))->provider) && ((((struct service_usage_item *)(ha->value))->provider)[0]) && (!((((struct service_usage_item *)(ha->value))->provider)[1])) && inset ((const void **)(((struct service_usage_item *)(ha->value))->provider), module, -1)) { /* this one might be a culprit */ uint32_t i = 0, r = 0; for (; (((struct service_usage_item *)(ha->value))->users)[i]; i++) { if ((((struct service_usage_item *)(ha->value))->users)[i]->si && (((struct service_usage_item *)(ha->value))->users)[i]->si->requires) { if (inset ((const void **)((((struct service_usage_item *)(ha->value))->users)[i]->si->requires), ha->key, SET_TYPE_STRING)) { r++; } } } /* yep, really is in use */ if (i == r) { ret ^= service_not_in_use; break; } } ha = streenext (ha); } } else if (task & service_requirements_met) { ret |= service_requirements_met; if (module->si && (t = module->si->requires)) { for (i = 0; t[i]; i++) { if (!service_usage || !(ha = streefind (service_usage, t[i], tree_find_first)) || !((struct service_usage_item *)(ha->value))->provider) { ret ^= service_requirements_met; break; } } } } else if (task & service_update) { modules_last_change = time(NULL); if (module->status & status_enabled) { if (module->si && (t = module->si->requires)) { for (i = 0; t[i]; i++) { if (service_usage && (ha = streefind (service_usage, t[i], tree_find_first)) && (item = (struct service_usage_item *)ha->value)) { item->users = (struct lmodule **)setadd ((void **)item->users, (void *)module, SET_NOALLOC); } } } if (module->si && (t = module->si->provides)) { for (i = 0; t[i]; i++) { if (service_usage && (ha = streefind (service_usage, t[i], tree_find_first)) && (item = (struct service_usage_item *)ha->value)) { item->provider = (struct lmodule **)setadd ((void **)item->provider, (void *)module, SET_NOALLOC); } else { struct service_usage_item nitem; memset (&nitem, 0, sizeof (struct service_usage_item)); nitem.provider = (struct lmodule **)setadd ((void **)nitem.provider, (void *)module, SET_NOALLOC); service_usage = streeadd (service_usage, t[i], &nitem, sizeof (struct service_usage_item), NULL); } } } } /* more cleanup code */ ha = service_usage; while (ha) { item = (struct service_usage_item *)ha->value; if (!(module->status & status_enabled)) { item->provider = (struct lmodule **)setdel ((void **)item->provider, (void *)module); item->users = (struct lmodule **)setdel ((void **)item->users, (void *)module); } if (!item->provider && !item->users) { // service_usage = streedel (service_usage, ha); service_usage = streedel (ha); ha = service_usage; } else ha = streenext (ha); } } else if (task & service_is_required) { if (service_usage && (ha = streefind (service_usage, service, tree_find_first)) && (item = (struct service_usage_item *)ha->value) && (item->users)) ret |= service_is_required; } else if (task & service_is_provided) { if (service_usage && (ha = streefind (service_usage, service, tree_find_first)) && (item = (struct service_usage_item *)ha->value) && (item->provider)) ret |= service_is_provided; } emutex_unlock (&service_usage_mutex); return ret; }
int mod (enum einit_module_task task, struct lmodule *module, char *custom_command) { struct einit_event *fb; unsigned int ret; if (!module) return 0; /* wait if the module is already being processed in a different thread */ if (!(task & einit_module_ignore_mutex)) { if ((task & einit_module_suspend) || (task & einit_module_resume)) { if (pthread_mutex_trylock (&module->mutex)) return status_failed; } else emutex_lock (&module->mutex); } if (task & einit_module_suspend) { int retval = mod_suspend (module); if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); return retval; } if (task & einit_module_resume) { int retval = mod_resume (module); if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); return retval; } if (module->status & status_suspended) { if (!(mod_resume (module) == status_ok)) { if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); return status_failed; } } if (task & einit_module_custom) { if (!custom_command) { if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); return status_failed; } goto skipdependencies; } if (task & einit_module_ignore_dependencies) { notice (2, "module: skipping dependency-checks"); task ^= einit_module_ignore_dependencies; goto skipdependencies; } if (module->status & MOD_LOCKED) { // this means the module is locked. maybe we're shutting down just now. if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); if (task & einit_module_enable) return status_failed; else if (task & einit_module_disable) return status_ok; else return status_ok; } module->status |= status_working; /* check if the task requested has already been done (or if it can be done at all) */ if ((task & einit_module_enable) && (!module->enable || (module->status & status_enabled))) { wontload: module->status ^= status_working; if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); return status_idle; } if ((task & einit_module_disable) && (!module->disable || (module->status & status_disabled) || (module->status == status_idle))) goto wontload; if (task & einit_module_enable) { if (!service_usage_query(service_requirements_met, module, NULL)) goto wontload; } else if (task & einit_module_disable) { if (!service_usage_query(service_not_in_use, module, NULL)) goto wontload; } skipdependencies: /* inform everyone about what's going to happen */ { struct einit_event eem = evstaticinit (einit_core_module_update); modules_work_count++; eem.task = task; eem.status = status_working; eem.para = (void *)module; eem.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0]; event_emit (&eem, einit_event_flag_broadcast); evstaticdestroy (eem); /* same for services */ if (module->si && module->si->provides) { struct einit_event ees = evstaticinit (einit_core_service_update); ees.task = task; ees.status = status_working; ees.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0]; ees.set = (void **)module->si->provides; ees.para = (void *)module; event_emit (&ees, einit_event_flag_broadcast); evstaticdestroy (ees); } } /* actual loading bit */ { fb = evinit (einit_feedback_module_status); fb->para = (void *)module; fb->task = task | einit_module_feedback_show; fb->status = status_working; fb->flag = 0; fb->string = NULL; fb->stringset = (char **)setadd ((void **)NULL, (module->module && module->module->rid) ? module->module->rid : module->si->provides[0], SET_TYPE_STRING); fb->integer = module->fbseq+1; status_update (fb); if (task & einit_module_custom) { if (strmatch (custom_command, "zap")) { char zerror = module->status & status_failed ? 1 : 0; fb->string = "module ZAP'd."; module->status = status_idle; module->status = status_disabled; if (zerror) module->status |= status_failed; } else if (module->custom) { module->status = module->custom(module->param, custom_command, fb); } else { module->status = (module->status & (status_enabled | status_disabled)) | status_failed | status_command_not_implemented; } } else if (task & einit_module_enable) { ret = module->enable (module->param, fb); if (ret & status_ok) { module->status = status_ok | status_enabled; } else { module->status = status_failed | status_disabled; } } else if (task & einit_module_disable) { ret = module->disable (module->param, fb); if (ret & status_ok) { module->status = status_ok | status_disabled; } else { module->status = status_failed | status_enabled; } } fb->status = module->status; module->fbseq = fb->integer + 1; status_update (fb); // event_emit(fb, einit_event_flag_broadcast); // if (fb->task & einit_module_feedback_show) fb->task ^= einit_module_feedback_show; fb->string = NULL; /* module status update */ { struct einit_event eem = evstaticinit (einit_core_module_update); eem.task = task; eem.status = fb->status; eem.para = (void *)module; eem.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0]; event_emit (&eem, einit_event_flag_broadcast); evstaticdestroy (eem); /* service status update */ if (module->si && module->si->provides) { struct einit_event ees = evstaticinit (einit_core_service_update); ees.task = task; ees.status = fb->status; ees.string = (module->module && module->module->rid) ? module->module->rid : module->si->provides[0]; ees.set = (void **)module->si->provides; ees.para = (void *)module; event_emit (&ees, einit_event_flag_broadcast); evstaticdestroy (ees); } } free (fb->stringset); evdestroy (fb); service_usage_query(service_update, module, NULL); modules_work_count--; } if (!(task & einit_module_ignore_mutex)) emutex_unlock (&module->mutex); return module->status; }
void einit_feedback_visual_fbsplash_boot_event_handler(struct einit_event *ev) { /* preinit */ if ((ev->type == einit_boot_devices_available) && !(coremode & einit_mode_ipconly)) { if (einit_initial_environment) { /* check for kernel params */ uint32_t i = 0; char start_splash = 0, *ttypatch = NULL, *splashargs = NULL; for (; einit_initial_environment[i]; i++) { if (strstr (einit_initial_environment[i], "splash=") == einit_initial_environment[i]) { start_splash = 1; splashargs = einit_initial_environment[i]+7; if (!ttypatch) ttypatch = "tty1"; } else if ((strstr (einit_initial_environment[i], "console=") == einit_initial_environment[i]) || (strstr (einit_initial_environment[i], "einitty=") == einit_initial_environment[i])) { ttypatch = einit_initial_environment[i]+8; } } if (splashargs && *splashargs) { char *fbtheme = NULL/*, *fbmode = NULL*/; if (splashargs) { char **p = str2set (',', splashargs); if (p) { for (i = 0; p[i]; i++) { char *sep = strchr (p[i], ':'); if (sep) { *sep = 0; sep++; if (strmatch (p[i], "theme")) { fbtheme = estrdup (sep); } }/* else { fbmode = estrdup(p[i]); }*/ } free (p); } } if (fbtheme) { struct cfgnode *node = cfg_getnode ("configuration-feedback-visual-fbsplash-theme", NULL); if (node && node->arbattrs) { uint32_t u = 0; for (; node->arbattrs[u]; u+=2) { if (strmatch(node->arbattrs[u], "s")) { notice (4, "patching fbsplash theme to %s", fbtheme); node->arbattrs[u+1] = fbtheme; node->svalue = fbtheme; } } } } /* if (fbmode) { }*/ } else fbsplash_disabled = 1; if (ttypatch && *ttypatch) { struct cfgnode *node = cfg_getnode ("configuration-feedback-visual-std-io", NULL); /* patch console */ if (node && node->arbattrs) { uint32_t ri = 0; for (; node->arbattrs[ri]; ri+=2) { if (strmatch (node->arbattrs[ri], "stdio")) { char tx[BUFFERSIZE]; if (ttypatch[0] == '/') esprintf (tx, BUFFERSIZE, "%s", ttypatch); else esprintf (tx, BUFFERSIZE, "/dev/%s", ttypatch); notice (4, "patching stdio output to go to %s", tx); node->arbattrs[ri+1] = estrdup(tx); } else if (strmatch (node->arbattrs[ri], "activate-vt")) { notice (4, "removing activate-vt= instruction"); node->arbattrs = (char **)setdel ((void **)node->arbattrs, node->arbattrs[ri]); node->arbattrs = (char **)setdel ((void **)node->arbattrs, node->arbattrs[ri]); } } } } if (start_splash) { struct einit_event ee = evstaticinit(einit_core_change_service_status); ee.argv = (char **)setadd ((void **)ee.set, "splashd", SET_TYPE_STRING); ee.argv = (char **)setadd ((void **)ee.set, "enable", SET_TYPE_STRING); event_emit (&ee, einit_event_flag_broadcast); evstaticdestroy(ee); notice (4, "enabling feedack (fbsplash)"); einit_feedback_visual_fbsplash_enable(); } } } }
void *linux_static_dev_hotplug(void *ignored) { struct sockaddr_nl nls; int fd, pos = 0; char buffer[BUFFERSIZE]; redo: memset(&nls, 0, sizeof(struct sockaddr_nl)); nls.nl_family = AF_NETLINK; nls.nl_pid = getpid(); nls.nl_groups = -1; fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (fd == -1) goto done; if (bind(fd, (void *)&nls, sizeof(struct sockaddr_nl))) goto done; errno = 0; char **v = NULL; int newlength = NETLINK_BUFFER; if (setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &newlength, sizeof (int))) { perror ("setsockopt: can't increase buffer size"); } if (fcntl (fd, F_SETFD, FD_CLOEXEC)) { perror ("can't set close-on-exec flag"); } while (!errno || (errno == EAGAIN) || (errno == ESPIPE) || (errno == EINTR)) { int rp = read (fd, buffer + pos, BUFFERSIZE - pos); int i = 0; char last = rp < (BUFFERSIZE - pos); if ((rp == -1) && !(!errno || (errno == EAGAIN) || (errno == ESPIPE) || (errno == EINTR))) { perror ("static_dev/read"); continue; } pos += rp; buffer[rp] = 0; for (i = 0; (i < pos); i++) { if (((buffer[i] == 0)) && (i > 0)) { char lbuffer[BUFFERSIZE]; int offset = 0; for (offset = 0; (offset < i) && !buffer[offset]; offset++) { offset++; } memcpy (lbuffer, buffer + offset, i - offset +1); if ((strstr (lbuffer, "add@") == lbuffer) || (strstr (lbuffer, "remove@") == lbuffer) || (strstr (lbuffer, "change@") == lbuffer) || (strstr (lbuffer, "online@") == lbuffer) || (strstr (lbuffer, "offline@") == lbuffer) || (strstr (lbuffer, "move@") == lbuffer)) { if (v) { linux_static_dev_hotplug_handle(v); free (v); v = NULL; } } v = (char **)setadd ((void **)v, lbuffer, SET_TYPE_STRING); i++; memmove (buffer, buffer + offset + i, pos - i); pos -= i; i = -1; } } /* we got less than we requested, assume that was a last message */ if (last) { if (v) { linux_static_dev_hotplug_handle(v); free (v); v = NULL; } } errno = 0; } if (v) { linux_static_dev_hotplug_handle(v); free (v); v = NULL; } close (fd); if (errno) { perror ("static_dev"); } sleep (1); goto redo; done: notice (1, "hotplug thread exiting... respawning in 10 sec"); sleep (10); return linux_static_dev_hotplug (NULL); }
struct einit_cron_job *einit_cron_parse_attrs_to_cron_job (char **attributes) { if (!attributes) return NULL; struct einit_cron_job *cj = emalloc (sizeof (struct einit_cron_job)); uint32_t i = 0; memset (cj, 0, sizeof (struct einit_cron_job)); for (; attributes[i]; i+=2) { if (strmatch (attributes[i], "command")) { cj->command = estrdup(attributes[i+1]); } else if (strmatch (attributes[i], "id")) { cj->id = estrdup(attributes[i+1]); } else if (strmatch (attributes[i], "years") || strmatch (attributes[i], "year")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { uintptr_t num = parse_integer (x[j]); if (num) { cj->years = (uintptr_t *)setadd ((void **)cj->years, (void *)num, SET_NOALLOC); } } free (x); } else if (strmatch (attributes[i], "months") || strmatch (attributes[i], "month")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { uintptr_t num = parse_integer (x[j]); if (num) { cj->months = (uintptr_t *)setadd ((void **)cj->months, (void *)num, SET_NOALLOC); } } free (x); } else if (strmatch (attributes[i], "days") || strmatch (attributes[i], "day")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { uintptr_t num = parse_integer (x[j]); if (num) { cj->days = (uintptr_t *)setadd ((void **)cj->days, (void *)num, SET_NOALLOC); } } free (x); } else if (strmatch (attributes[i], "hours") || strmatch (attributes[i], "hour")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { uintptr_t num = parse_integer (x[j]); if (num) { cj->hours = (uintptr_t *)setadd ((void **)cj->hours, (void *)num, SET_NOALLOC); } } free (x); } else if (strmatch (attributes[i], "minutes") || strmatch (attributes[i], "minute")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { uintptr_t num = parse_integer (x[j]); if (num) { cj->minutes = (uintptr_t *)setadd ((void **)cj->minutes, (void *)num, SET_NOALLOC); } } free (x); } else if (strmatch (attributes[i], "seconds") || strmatch (attributes[i], "second")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { uintptr_t num = parse_integer (x[j]); if (num) { cj->seconds = (uintptr_t *)setadd ((void **)cj->seconds, (void *)num, SET_NOALLOC); } } free (x); } else if (strmatch (attributes[i], "weekdays") || strmatch (attributes[i], "weekday")) { char **x = str2set (':', attributes[i+1]); uint32_t j = 0; for (; x[j]; j++) { if (strmatch (x[j], "sunday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)0, SET_NOALLOC); } else if (strmatch (x[j], "monday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)1, SET_NOALLOC); } else if (strmatch (x[j], "tuesday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)2, SET_NOALLOC); } else if (strmatch (x[j], "wednesday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)3, SET_NOALLOC); } else if (strmatch (x[j], "thursday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)4, SET_NOALLOC); } else if (strmatch (x[j], "friday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)5, SET_NOALLOC); } else if (strmatch (x[j], "saturday")) { cj->weekdays = (uintptr_t *)setadd ((void **)cj->weekdays, (void *)6, SET_NOALLOC); } } free (x); } } return cj; }
char *linux_bootchart_update_ps (char *ps, char *uptime) { DIR *d; struct dirent *e; char **data = NULL; d = opendir ("/proc"); if (d != NULL) { while ((e = readdir (d))) { char *t, *u, *da = NULL; if (strmatch (e->d_name, ".") || strmatch (e->d_name, "..")) { continue; } if ((t = joinpath ("/proc/", e->d_name))) { if ((u = joinpath (t, "stat"))) { struct stat st; if (!stat (u, &st)) { da = readfile (u); } free (u); } /* if ((u = joinpath (t, "cmdline"))) { struct stat st; if (!stat (u, &st)) { char *ru = readfile (u); if (strstr (ru, )) { linux_bootchart_have_thread = 0; } } free (u); }*/ free (t); } if (da) { data = (char **)setadd ((void **)data, da, SET_TYPE_STRING); free (da); da = NULL; } } closedir(d); } if (data) { char *t = set2str ('\n', (const char **)data); if (t) { size_t len = strlen (uptime) + strlen (t) + 4 + (ps ? strlen (ps) : 0); char *tx = emalloc (len); if (ps) { esprintf (tx, len, "%s\n%s\n%s\n", ps, uptime, t); free (ps); } else { esprintf (tx, len, "%s\n%s\n", uptime, t); } free (t); ps = tx; } free (data); } return ps; }
Manager::Manager(int money, string name, int time, int add, int level): Employee(money, name, time, level) { setadd(add); }
int linux_kernel_modules_run (enum lkm_run_code code) { pthread_t **threads = NULL; if (code == lkm_pre_dev) { char dwait; char **modules = linux_kernel_modules_get_by_subsystem ("storage", &dwait); if (modules) { pthread_t *threadid = emalloc (sizeof (pthread_t)); if (ethread_create (threadid, NULL, (void *(*)(void *))linux_kernel_modules_load, modules)) { linux_kernel_modules_load (modules); } else { if (dwait) threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC); } } } else if (code == lkm_post_dev) { struct stree *linux_kernel_modules_nodes = cfg_prefix(MPREFIX); char have_generic = 0; char have_audio = 0; if (linux_kernel_modules_nodes) { struct stree *cur = linux_kernel_modules_nodes; while (cur) { char *subsystem = cur->key + sizeof (MPREFIX) -1; struct cfgnode *nod = cur->value; if (nod && nod->arbattrs) { size_t i; for (i = 0; nod->arbattrs[i]; i+=2) { if (strmatch (nod->arbattrs[i], "provide-service") && parse_boolean (nod->arbattrs[i+1])) { goto nextgroup; } } } if (strmatch (subsystem, "storage")) { } else { struct cfgnode *node = cur->value; if (strmatch (subsystem, "generic") || strmatch (subsystem, "arbitrary")) { have_generic = 1; } else if (strmatch (subsystem, "alsa") || strmatch (subsystem, "audio") || strmatch (subsystem, "sound")) { have_audio = 1; } if (node && node->svalue) { char **modules = str2set (':', node->svalue); if (modules) { pthread_t *threadid = emalloc (sizeof (pthread_t)); if (ethread_create (threadid, NULL, (void *(*)(void *))linux_kernel_modules_load, modules)) { linux_kernel_modules_load (modules); } else { if (!node->flag) threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC); } } } } nextgroup: cur = streenext (cur); } streefree (linux_kernel_modules_nodes); } if (!have_generic) { char dwait; char **modules = linux_kernel_modules_get_by_subsystem ("generic", &dwait); if (modules) { pthread_t *threadid = emalloc (sizeof (pthread_t)); if (ethread_create (threadid, NULL, (void *(*)(void *))linux_kernel_modules_load, modules)) { linux_kernel_modules_load (modules); } else { if (dwait) threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC); } } } if (!have_audio) { char dwait; char **modules = linux_kernel_modules_get_by_subsystem ("audio", &dwait); if (modules) { pthread_t *threadid = emalloc (sizeof (pthread_t)); if (ethread_create (threadid, NULL, (void *(*)(void *))linux_kernel_modules_load, modules)) { linux_kernel_modules_load (modules); } else { if (dwait) threads = (pthread_t **)setadd ((void **)threads, threadid, SET_NOALLOC); } } } } if (threads) { int i = 0; for (; threads[i]; i++) { pthread_join (*(threads[i]), NULL); free (threads[i]); } free (threads); } return status_ok; }