/* * Copyright (c) 2002 Packet Design, LLC. * All rights reserved. * * Subject to the following obligations and disclaimer of warranty, * use and redistribution of this software, in source or object code * forms, with or without modifications are expressly permitted by * Packet Design; provided, however, that: * * (i) Any and all reproductions of the source or object code * must include the copyright notice above and the following * disclaimer of warranties; and * (ii) No rights are granted, in any manner or form, to use * Packet Design trademarks, including the mark "PACKET DESIGN" * on advertising, endorsements, or otherwise except as such * appears in the above copyright notice or in the software. * * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, * OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, * RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * Author: Archie Cobbs */ #include "lws_global.h" #include "lws_config.h" /* * Internal functions */ /* SSL typed_mem(3) wrappers */ static void *ssl_malloc(size_t size); static void *ssl_realloc(void *mem, size_t size); static void ssl_free(void *mem); static void usage(void) __dead2; /* * Global variables */ pid_t pid; int debug_level = 0; struct pevent_ctx *lws_event_ctx; int main(int argc, char **argv) { const char *dir = PREFIX "/etc/lws"; int no_fork = 0; sigset_t sigs; void *config; int sig; int ch; /* Parse command line */ while ((ch = getopt(argc, argv, "Dd:")) != -1) { switch (ch) { case 'D': no_fork = 1; debug_level++; break; case 'd': dir = optarg; break; default: usage(); break; } } argc -= optind; argv += optind; switch (argc) { default: usage(); break; case 0: break; } /* Change directory */ if (chdir(dir) == -1) err(1, "%s", dir); /* Make OpenSSL use our malloc/free wrappers */ CRYPTO_set_mem_functions(ssl_malloc, ssl_realloc, ssl_free); CRYPTO_set_locked_mem_functions(ssl_malloc, ssl_free); /* Enable typed memory */ if (debug_level > 0 && typed_mem_enable() == -1) err(1, "typed_mem_enable"); #ifndef __linux__ /* Seed random number generator */ srandomdev(); #endif /* Block SIGPIPE */ (void)signal(SIGPIPE, SIG_IGN); /* Enable debug logging and malloc() if desired */ if (debug_level > 0) { alog_set_debug(0, 1); setenv("MALLOC_OPTIONS", "AJ", 1); } /* Get a new event context */ if ((lws_event_ctx = pevent_ctx_create("pevent_ctx", NULL)) == NULL) err(1, "pevent_ctx_create"); /* Fork into the background, but stay in same directory */ if (!no_fork && daemon(1, debug_level > 0) == -1) err(1, "daemon"); pid = getpid(); /* Load in configuration */ if (lws_config_init(lws_event_ctx, CONFIG_FILE) == -1) err(1, "failed to get configuration"); loop: /* Wait for interrupt */ sigemptyset(&sigs); sigaddset(&sigs, SIGINT); sigaddset(&sigs, SIGTERM); sigaddset(&sigs, SIGHUP); sigaddset(&sigs, SIGUSR1); if (sigprocmask(SIG_BLOCK, &sigs, NULL) == -1) err(1, "sigprocmask"); if (sigwait(&sigs, &sig) == -1) err(1, "sigwait"); /* If SIGHUP, just reload config */ if (sig == SIGHUP) { alog(LOG_NOTICE, "rec'd signal %s, %s", sys_signame[sig], "reloading configuration"); app_config_reload(lws_config_ctx); goto loop; } alog(LOG_NOTICE, "rec'd signal %s, %s", sys_signame[sig], sig == SIGUSR1 ? "restarting" : "shutting down"); /* Shut down */ if (app_config_set(lws_config_ctx, NULL, 0, NULL, 0) == -1) err(1, "app_config_set"); while ((config = app_config_get(lws_config_ctx, 0)) != NULL) { app_config_free(lws_config_ctx, &config); usleep(10000); } /* If restarting, start back up */ if (sig == SIGUSR1) { app_config_reload(lws_config_ctx); goto loop; } /* Shut down app_config stuff */ app_config_uninit(&lws_config_ctx); /* Destroy event context */ pevent_ctx_destroy(&lws_event_ctx); usleep(10000); /* Show memory usage */ if (debug_level > 0) { printf("\nUnfreed memory:\n\n"); typed_mem_dump(stdout); } /* Done */ return (0); } static void usage(void) { (void)fprintf(stderr, "Usage: lws [-D] [-d directory]\n"); exit(1); } /*********************************************************************** SSL MEMORY WRAPPERS ***********************************************************************/ static void *ssl_malloc(size_t size) { return (MALLOC("OpenSSL", size)); } static void *ssl_realloc(void *mem, size_t size) { return (REALLOC("OpenSSL", mem, size)); } static void ssl_free(void *mem) { return (FREE("OpenSSL", mem)); }