+/*----------------------------------------------------------
+ | closeSession
+ | try to close everything before leaving
+ +--------------------------------------------------------- */
+static void closeSession (int status, void *data) {
+ /* struct afb_config *config = data; */
+}
+
+/*----------------------------------------------------------
+ | timeout signalQuit
+ +--------------------------------------------------------- */
+void signalQuit (int signum)
+{
+ fprintf(stderr, "Terminating signal received %s\n", strsignal(signum));
+ exit(1);
+}
+
+
+/*----------------------------------------------------------
+ | Error signals
+ |
+ +--------------------------------------------------------- */
+__thread sigjmp_buf *error_handler;
+static void signalError(int signum)
+{
+ sigset_t sigset;
+
+ // unlock signal to allow a new signal to come
+ if (error_handler != NULL) {
+ sigemptyset(&sigset);
+ sigaddset(&sigset, signum);
+ sigprocmask(SIG_UNBLOCK, &sigset, 0);
+ longjmp(*error_handler, signum);
+ }
+ if (signum == SIGALRM)
+ return;
+ fprintf(stderr, "Unmonitored signal received %s\n", strsignal(signum));
+ exit(2);
+}
+
+static void install_error_handlers()
+{
+ int i, signals[] = { SIGALRM, SIGSEGV, SIGFPE, 0 };
+
+ for (i = 0; signals[i] != 0; i++) {
+ if (signal(signals[i], signalError) == SIG_ERR) {
+ fprintf(stderr, "Signal handler error\n");
+ exit(1);
+ }
+ }
+}
+
+/*----------------------------------------------------------
+ | daemonize
+ | set the process in background
+ +--------------------------------------------------------- */
+static void daemonize(struct afb_config *config)
+{
+ int consoleFD;
+ int pid;
+
+ // open /dev/console to redirect output messAFBes
+ consoleFD = open(config->console, O_WRONLY | O_APPEND | O_CREAT , 0640);
+ if (consoleFD < 0) {
+ fprintf (stderr,"\nERR: AFB-daemon cannot open /dev/console (use --foreground)\n\n");
+ exit (1);
+ }
+
+ // fork process when running background mode
+ pid = fork ();
+
+ // if fail nothing much to do
+ if (pid == -1) {
+ fprintf (stderr,"\nERR: AFB-daemon Failed to fork son process\n\n");
+ exit (1);
+ }
+
+ // if in father process, just leave
+ if (pid != 0) _exit (0);
+
+ // son process get all data in standalone mode
+ fprintf (stderr, "\nAFB: background mode [pid:%d console:%s]\n", getpid(),config->console);
+
+ // redirect default I/O on console
+ close (2); dup(consoleFD); // redirect stderr
+ close (1); dup(consoleFD); // redirect stdout
+ close (0); // no need for stdin
+ close (consoleFD);
+
+#if 0
+ setsid(); // allow father process to fully exit
+ sleep (2); // allow main to leave and release port
+#endif
+
+ fprintf (stderr, "----------------------------\n");
+ fprintf (stderr, "INF: main background pid=%d\n", getpid());
+ fflush (stderr);
+}
+
+/*---------------------------------------------------------
+ | http server
+ | Handles the HTTP server
+ +--------------------------------------------------------- */
+static int init_http_server(struct afb_hsrv *hsrv, struct afb_config * config)
+{
+ int idx;
+
+ if (!afb_hsrv_add_handler(hsrv, config->rootapi, afb_hswitch_websocket_switch, NULL, 20))
+ return 0;
+
+ if (!afb_hsrv_add_handler(hsrv, config->rootapi, afb_hswitch_apis, NULL, 10))
+ return 0;
+
+ for (idx = 0; idx < config->aliascount; idx++)
+ if (!afb_hsrv_add_alias (hsrv, config->aliasdir[idx].url, config->aliasdir[idx].path, 0))
+ return 0;
+
+ if (!afb_hsrv_add_alias(hsrv, "", config->rootdir, -10))
+ return 0;
+
+ if (!afb_hsrv_add_handler(hsrv, config->rootbase, afb_hswitch_one_page_api_redirect, NULL, -20))
+ return 0;
+
+ return 1;
+}
+
+static struct afb_hsrv *start_http_server(struct afb_config * config)
+{
+ int rc;
+ struct afb_hsrv *hsrv;
+
+ if (afb_hreq_init_download_path("/tmp")) { /* TODO: sessiondir? */
+ fprintf(stderr, "unable to set the tmp directory\n");
+ return NULL;
+ }
+
+ hsrv = afb_hsrv_create();
+ if (hsrv == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ return NULL;
+ }
+
+ if (!afb_hsrv_set_cache_timeout(hsrv, config->cacheTimeout)
+ || !init_http_server(hsrv, config)) {
+ fprintf (stderr, "Error: initialisation of httpd failed");
+ afb_hsrv_put(hsrv);
+ return NULL;
+ }
+
+ if (verbosity) {
+ fprintf (stderr, "AFB:notice Waiting port=%d rootdir=%s\n", config->httpdPort, config->rootdir);
+ fprintf (stderr, "AFB:notice Browser URL= http:/*localhost:%d\n", config->httpdPort);
+ }
+
+ rc = afb_hsrv_start(hsrv, (uint16_t) config->httpdPort, 15);
+ if (!rc) {
+ fprintf (stderr, "Error: starting of httpd failed");
+ afb_hsrv_put(hsrv);
+ return NULL;
+ }
+
+ return hsrv;
+}
+
+