/** * Create engine. * */ static engine_type* engine_create(void) { engine_type* engine; allocator_type* allocator = allocator_create(malloc, free); if (!allocator) { ods_log_error("[%s] unable to create engine: allocator_create() " "failed", engine_str); return NULL; } engine = (engine_type*) allocator_alloc(allocator, sizeof(engine_type)); if (!engine) { ods_log_error("[%s] unable to create engine: allocator_alloc() " "failed", engine_str); allocator_cleanup(allocator); return NULL; } engine->allocator = allocator; engine->config = NULL; engine->workers = NULL; engine->drudgers = NULL; engine->cmdhandler = NULL; engine->cmdhandler_done = 0; engine->dnshandler = NULL; engine->xfrhandler = NULL; engine->pid = -1; engine->uid = -1; engine->gid = -1; engine->daemonize = 0; engine->need_to_exit = 0; engine->need_to_reload = 0; lock_basic_init(&engine->signal_lock); lock_basic_set(&engine->signal_cond); lock_basic_lock(&engine->signal_lock); engine->signal = SIGNAL_INIT; lock_basic_unlock(&engine->signal_lock); engine->zonelist = zonelist_create(engine->allocator); if (!engine->zonelist) { engine_cleanup(engine); return NULL; } engine->taskq = schedule_create(engine->allocator); if (!engine->taskq) { engine_cleanup(engine); return NULL; } engine->signq = fifoq_create(engine->allocator); if (!engine->signq) { engine_cleanup(engine); return NULL; } return engine; }
void engine_cleanup(t_engine *engine) { t_link *link; t_process *process; if(engine->garbage->first) { int do_loop = 0; for(link = engine->garbage->first; link; link = link->next) { process = (t_process * ) link->data; if(process->done) { lst_link_delete_by_id(engine->processes, process->id.id); lst_link_delete_by_id(engine->garbage, process->id.id); process_free(process); do_loop = 1; break; } } if(do_loop) engine_cleanup(engine); } }
// Engine ---------------------------------------------------------------------- // ----------------------------------------------------------------------------- int engine_create(const int width, const int height, const int scale, const int fps) { engine = (struct Engine*)malloc(sizeof(struct Engine)); if (!engine_init(width, height, scale, fps)) { free(engine); return 1; } game_init(); // Main Loop, o'rly? int render_start = 0, render_diff = 0, render_wait = 0; int fps_count = 0, fps_time = 0; while (engine->running) { render_start = SDL_GetTicks(); engine_events(); if (key_pressed(SDLK_p)) { engine_pause(!engine->paused); } if (!engine->paused) { game_update(); } engine_clear_keys(); engine_clear_mouse(); game_render(engine->screen); SDL_Flip(engine->screen->bg); // Limit FPS render_diff = SDL_GetTicks() - render_start; if (render_diff > 0) { render_wait = engine->fps_wait - render_diff; if (render_wait > 0) { SDL_Delay(render_wait); } if (!engine->paused) { engine->time += SDL_GetTicks() - render_start; } } // Count FPS if (!engine->paused) { fps_count++; if (fps_count >= 10) { engine->fps_current = 1000 / ((engine->time - fps_time) / fps_count); fps_count = 0; fps_time = engine->time; } } } // Cleanup game_quit(); engine_cleanup(); return 0; }
/** * Create engine. * */ static engine_type* engine_create(void) { engine_type* engine; CHECKALLOC(engine = (engine_type*) malloc(sizeof(engine_type))); engine->config = NULL; engine->workers = NULL; engine->drudgers = NULL; engine->cmdhandler = NULL; engine->cmdhandler_done = 0; engine->dnshandler = NULL; engine->xfrhandler = NULL; engine->taskq = NULL; engine->signq = NULL; engine->pid = -1; engine->uid = -1; engine->gid = -1; engine->daemonize = 0; engine->need_to_exit = 0; engine->need_to_reload = 0; lock_basic_init(&engine->signal_lock); lock_basic_set(&engine->signal_cond); lock_basic_lock(&engine->signal_lock); engine->signal = SIGNAL_INIT; lock_basic_unlock(&engine->signal_lock); engine->zonelist = zonelist_create(); if (!engine->zonelist) { engine_cleanup(engine); return NULL; } engine->taskq = schedule_create(); if (!engine->taskq) { engine_cleanup(engine); return NULL; } engine->signq = fifoq_create(); if (!engine->signq) { engine_cleanup(engine); return NULL; } return engine; }
/** * Create engine. * */ static engine_type* engine_create(void) { engine_type* engine; allocator_type* allocator = allocator_create(malloc, free); if (!allocator) { return NULL; } engine = (engine_type*) allocator_alloc(allocator, sizeof(engine_type)); if (!engine) { allocator_cleanup(allocator); return NULL; } engine->allocator = allocator; engine->config = NULL; engine->workers = NULL; engine->drudgers = NULL; engine->cmdhandler = NULL; engine->cmdhandler_done = 0; engine->pid = -1; engine->uid = -1; engine->gid = -1; engine->daemonize = 0; engine->need_to_exit = 0; engine->need_to_reload = 0; engine->signal = SIGNAL_INIT; lock_basic_init(&engine->signal_lock); lock_basic_set(&engine->signal_cond); engine->taskq = schedule_create(engine->allocator); if (!engine->taskq) { engine_cleanup(engine); return NULL; } engine->signq = fifoq_create(engine->allocator); if (!engine->signq) { engine_cleanup(engine); return NULL; } return engine; }
/** * Stop engine. * */ void engine_stop(engine_type *engine) { ods_orm_shutdown(); ods_protobuf_shutdown(); if (engine && engine->config) { if (engine->config->pid_filename) { (void)unlink(engine->config->pid_filename); } if (engine->config->clisock_filename) { (void)unlink(engine->config->clisock_filename); } } engine_cleanup(engine); engine = NULL; ods_log_close(); xmlCleanupParser(); xmlCleanupGlobals(); xmlCleanupThreads(); }
void engine_crash(const char *reason) { printf("%s: %s\n", reason, SDL_GetError()); engine->running = false; engine_cleanup(); exit(1); }
/** * Start engine. * */ void engine_start(const char* cfgfile, int cmdline_verbosity, int daemonize, int info, int single_run) { engine_type* engine = NULL; int use_syslog = 0; ods_status zl_changed = ODS_STATUS_UNCHANGED; ods_status status = ODS_STATUS_OK; int close_hsm = 0; ods_log_assert(cfgfile); ods_log_init(NULL, use_syslog, cmdline_verbosity); ods_log_verbose("[%s] starting signer", engine_str); /* initialize */ xmlInitGlobals(); xmlInitParser(); xmlInitThreads(); engine = engine_create(); if (!engine) { ods_fatal_exit("[%s] create failed", engine_str); return; } engine->daemonize = daemonize; /* config */ engine->config = engine_config(engine->allocator, cfgfile, cmdline_verbosity); status = engine_config_check(engine->config); if (status != ODS_STATUS_OK) { ods_log_error("[%s] cfgfile %s has errors", engine_str, cfgfile); goto earlyexit; } if (info) { engine_config_print(stdout, engine->config); /* for debugging */ goto earlyexit; } /* check pidfile */ if (!util_check_pidfile(engine->config->pid_filename)) { exit(1); } /* open log */ ods_log_init(engine->config->log_filename, engine->config->use_syslog, engine->config->verbosity); /* setup */ tzset(); /* for portability */ status = engine_setup(engine); if (status != ODS_STATUS_OK) { ods_log_error("[%s] setup failed: %s", engine_str, ods_status2str(status)); engine->need_to_exit = 1; if (status != ODS_STATUS_WRITE_PIDFILE_ERR) { /* command handler had not yet been started */ engine->cmdhandler_done = 1; } } else { /* setup ok, mark hsm open */ close_hsm = 1; } /* run */ while (engine->need_to_exit == 0) { /* update zone list */ lock_basic_lock(&engine->zonelist->zl_lock); zl_changed = zonelist_update(engine->zonelist, engine->config->zonelist_filename); engine->zonelist->just_removed = 0; engine->zonelist->just_added = 0; engine->zonelist->just_updated = 0; lock_basic_unlock(&engine->zonelist->zl_lock); /* start/reload */ if (engine->need_to_reload) { ods_log_info("[%s] signer reloading", engine_str); engine->need_to_reload = 0; } else { ods_log_info("[%s] signer started", engine_str); zl_changed = engine_recover(engine); } if (zl_changed == ODS_STATUS_OK || zl_changed == ODS_STATUS_UNCHANGED) { engine_update_zones(engine, zl_changed); } engine_run(engine, single_run); } /* shutdown */ ods_log_info("[%s] signer shutdown", engine_str); if (close_hsm) { ods_log_verbose("[%s] close hsm", engine_str); hsm_close(); } if (!engine->cmdhandler_done) { engine_stop_xfrhandler(engine); engine_stop_dnshandler(engine); engine_stop_cmdhandler(engine); } earlyexit: if (engine && engine->config) { if (engine->config->pid_filename) { (void)unlink(engine->config->pid_filename); } if (engine->config->clisock_filename) { (void)unlink(engine->config->clisock_filename); } } tsig_handler_cleanup(); engine_cleanup(engine); engine = NULL; ods_log_close(); xmlCleanupParser(); xmlCleanupGlobals(); xmlCleanupThreads(); return; }
/** * Set up engine. * */ static ods_status engine_setup(engine_type* engine) { ods_status status = ODS_STATUS_OK; struct sigaction action; int result = 0; int sockets[2] = {0,0}; ods_log_debug("[%s] setup signer engine", engine_str); if (!engine || !engine->config) { return ODS_STATUS_ASSERT_ERR; } /* set edns */ edns_init(&engine->edns, EDNS_MAX_MESSAGE_LEN); /* create command handler (before chowning socket file) */ engine->cmdhandler = cmdhandler_create(engine->allocator, engine->config->clisock_filename); if (!engine->cmdhandler) { return ODS_STATUS_CMDHANDLER_ERR; } engine->dnshandler = dnshandler_create(engine->allocator, engine->config->interfaces); engine->xfrhandler = xfrhandler_create(engine->allocator); if (!engine->xfrhandler) { return ODS_STATUS_XFRHANDLER_ERR; } if (engine->dnshandler) { if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) { return ODS_STATUS_XFRHANDLER_ERR; } engine->xfrhandler->dnshandler.fd = sockets[0]; engine->dnshandler->xfrhandler.fd = sockets[1]; status = dnshandler_listen(engine->dnshandler); if (status != ODS_STATUS_OK) { ods_log_error("[%s] setup: unable to listen to sockets (%s)", engine_str, ods_status2str(status)); } } /* privdrop */ engine->uid = privuid(engine->config->username); engine->gid = privgid(engine->config->group); /* TODO: does piddir exists? */ /* remove the chown stuff: piddir? */ ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1); ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0); ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0); if (engine->config->log_filename && !engine->config->use_syslog) { ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0); } if (engine->config->working_dir && chdir(engine->config->working_dir) != 0) { ods_log_error("[%s] setup: unable to chdir to %s (%s)", engine_str, engine->config->working_dir, strerror(errno)); return ODS_STATUS_CHDIR_ERR; } if (engine_privdrop(engine) != ODS_STATUS_OK) { return ODS_STATUS_PRIVDROP_ERR; } /* daemonize */ if (engine->daemonize) { switch ((engine->pid = fork())) { case -1: /* error */ ods_log_error("[%s] setup: unable to fork daemon (%s)", engine_str, strerror(errno)); return ODS_STATUS_FORK_ERR; case 0: /* child */ break; default: /* parent */ engine_cleanup(engine); engine = NULL; xmlCleanupParser(); xmlCleanupGlobals(); xmlCleanupThreads(); exit(0); } if (setsid() == -1) { ods_log_error("[%s] setup: unable to setsid daemon (%s)", engine_str, strerror(errno)); return ODS_STATUS_SETSID_ERR; } } engine->pid = getpid(); ods_log_verbose("[%s] running as pid %lu", engine_str, (unsigned long) engine->pid); /* catch signals */ signal_set_engine(engine); action.sa_handler = signal_handler; sigfillset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGTERM, &action, NULL); sigaction(SIGHUP, &action, NULL); sigaction(SIGINT, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGUSR1, &action, NULL); sigaction(SIGALRM, &action, NULL); sigaction(SIGCHLD, &action, NULL); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); /* set up hsm */ /* LEAK */ result = lhsm_open(engine->config->cfg_filename); if (result != HSM_OK) { return ODS_STATUS_HSM_ERR; } /* create workers/drudgers */ engine_create_workers(engine); engine_create_drudgers(engine); /* start cmd/dns/xfr handlers */ engine_start_cmdhandler(engine); engine_start_dnshandler(engine); engine_start_xfrhandler(engine); tsig_handler_init(engine->allocator); /* write pidfile */ if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) { hsm_close(); return ODS_STATUS_WRITE_PIDFILE_ERR; } /* setup done */ return ODS_STATUS_OK; }
/** * Start engine. * */ int engine_start(const char* cfgfile, int cmdline_verbosity, int daemonize, int info, int single_run) { engine_type* engine = NULL; ods_status zl_changed = ODS_STATUS_UNCHANGED; ods_status status = ODS_STATUS_OK; engine = engine_create(); if (!engine) { ods_fatal_exit("[%s] create failed", engine_str); return 1; } engine->daemonize = daemonize; /* config */ engine->config = engine_config(cfgfile, cmdline_verbosity); status = engine_config_check(engine->config); if (status != ODS_STATUS_OK) { ods_log_error("[%s] cfgfile %s has errors", engine_str, cfgfile); goto earlyexit; } if (info) { engine_config_print(stdout, engine->config); /* for debugging */ goto earlyexit; } /* check pidfile */ if (!util_check_pidfile(engine->config->pid_filename)) { exit(1); } /* open log */ ods_log_init("ods-signerd", engine->config->use_syslog, engine->config->log_filename, engine->config->verbosity); /* setup */ status = engine_setup(engine); if (status != ODS_STATUS_OK) { ods_log_error("[%s] setup failed: %s", engine_str, ods_status2str(status)); if (status != ODS_STATUS_WRITE_PIDFILE_ERR) { /* command handler had not yet been started */ engine->cmdhandler_done = 1; } goto earlyexit; } /* run */ while (engine->need_to_exit == 0) { /* update zone list */ lock_basic_lock(&engine->zonelist->zl_lock); zl_changed = zonelist_update(engine->zonelist, engine->config->zonelist_filename); engine->zonelist->just_removed = 0; engine->zonelist->just_added = 0; engine->zonelist->just_updated = 0; lock_basic_unlock(&engine->zonelist->zl_lock); /* start/reload */ if (engine->need_to_reload) { ods_log_info("[%s] signer reloading", engine_str); fifoq_wipe(engine->signq); engine->need_to_reload = 0; } else { ods_log_info("[%s] signer started (version %s), pid %u", engine_str, PACKAGE_VERSION, engine->pid); if (hsm_open2(engine->config->repositories, hsm_check_pin) != HSM_OK) { char* error = hsm_get_error(NULL); if (error != NULL) { ods_log_error("[%s] %s", "hsm", error); free(error); } ods_log_error("[%s] opening hsm failed (for engine recover)", engine_str); break; } zl_changed = engine_recover(engine); hsm_close(); } if (zl_changed == ODS_STATUS_OK || zl_changed == ODS_STATUS_UNCHANGED) { engine_update_zones(engine, zl_changed); } if (hsm_open2(engine->config->repositories, hsm_check_pin) != HSM_OK) { char* error = hsm_get_error(NULL); if (error != NULL) { ods_log_error("[%s] %s", "hsm", error); free(error); } ods_log_error("[%s] opening hsm failed (for engine run)", engine_str); break; } engine_run(engine, single_run); hsm_close(); } /* shutdown */ ods_log_info("[%s] signer shutdown", engine_str); engine_stop_cmdhandler(engine); engine_stop_xfrhandler(engine); engine_stop_dnshandler(engine); earlyexit: if (engine && engine->config) { if (engine->config->pid_filename) { (void)unlink(engine->config->pid_filename); } if (engine->config->clisock_filename) { (void)unlink(engine->config->clisock_filename); } } tsig_handler_cleanup(); engine_cleanup(engine); engine = NULL; return 1; }
/** * Set up engine and return the setup status. * */ static ods_status engine_setup_and_return_status(engine_type* engine) { struct sigaction action; int result = 0; int fd; ods_log_debug("[%s] enforcer setup", engine_str); if (!engine || !engine->config) { return ODS_STATUS_ASSERT_ERR; } /* create command handler (before chowning socket file) */ engine->cmdhandler = cmdhandler_create(engine->allocator, engine->config->clisock_filename); if (!engine->cmdhandler) { ods_log_error("[%s] create command handler to %s failed", engine_str, engine->config->clisock_filename); return ODS_STATUS_CMDHANDLER_ERR; } /* privdrop */ engine->uid = privuid(engine->config->username); engine->gid = privgid(engine->config->group); /* TODO: does piddir exists? */ /* remove the chown stuff: piddir? */ ods_chown(engine->config->pid_filename, engine->uid, engine->gid, 1); ods_chown(engine->config->clisock_filename, engine->uid, engine->gid, 0); ods_chown(engine->config->working_dir, engine->uid, engine->gid, 0); if (engine->config->log_filename && !engine->config->use_syslog) { ods_chown(engine->config->log_filename, engine->uid, engine->gid, 0); } if (engine->config->working_dir && chdir(engine->config->working_dir) != 0) { ods_log_error("[%s] chdir to %s failed: %s", engine_str, engine->config->working_dir, strerror(errno)); return ODS_STATUS_CHDIR_ERR; } if (engine_privdrop(engine) != ODS_STATUS_OK) { ods_log_error("[%s] unable to drop privileges", engine_str); return ODS_STATUS_PRIVDROP_ERR; } /* daemonize */ if (engine->daemonize) { switch ((engine->pid = fork())) { case -1: /* error */ ods_log_error("[%s] unable to fork daemon: %s", engine_str, strerror(errno)); return ODS_STATUS_FORK_ERR; case 0: /* child */ if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { (void)dup2(fd, STDIN_FILENO); (void)dup2(fd, STDOUT_FILENO); (void)dup2(fd, STDERR_FILENO); if (fd > 2) (void)close(fd); } break; default: /* parent */ engine_cleanup(engine); engine = NULL; xmlCleanupParser(); xmlCleanupGlobals(); xmlCleanupThreads(); exit(0); } if (setsid() == -1) { ods_log_error("[%s] unable to setsid daemon (%s)", engine_str, strerror(errno)); return ODS_STATUS_SETSID_ERR; } } engine->pid = getpid(); ods_log_verbose("[%s] running as pid %lu", engine_str, (unsigned long) engine->pid); /* catch signals */ signal_set_engine(engine); action.sa_handler = signal_handler; sigfillset(&action.sa_mask); action.sa_flags = 0; sigaction(SIGHUP, &action, NULL); sigaction(SIGTERM, &action, NULL); /* set up hsm */ /* LEAK */ result = hsm_open(engine->config->cfg_filename, hsm_prompt_pin, NULL); if (result != HSM_OK) { ods_log_error("[%s] error initializing libhsm (errno %i)", engine_str, result); return ODS_STATUS_HSM_ERR; } /* create workers */ engine_create_workers(engine); engine_create_drudgers(engine); /* start command handler */ engine_start_cmdhandler(engine); /* write pidfile */ if (util_write_pidfile(engine->config->pid_filename, engine->pid) == -1) { hsm_close(); ods_log_error("[%s] unable to write pid file", engine_str); return ODS_STATUS_WRITE_PIDFILE_ERR; } return ODS_STATUS_OK; }