X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fmain-afb-daemon.c;h=e9472d50b7e549013c1e2ed069eaf147d396b8bb;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=a85ffc0a6af69cec2249951511e7969bb5b2fba3;hpb=2ba7c200c6c4844b63f8f707a6f04017661f16ca;p=src%2Fapp-framework-binder.git diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c index a85ffc0a..e9472d50 100644 --- a/src/main-afb-daemon.c +++ b/src/main-afb-daemon.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2019 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author "Fulup Ar Foll" * Author José Bollo * @@ -298,7 +298,7 @@ static int init_alias(void *closure, const char *spec) *path++ = 0; INFO("Alias for url=%s to path=%s", spec, path); return afb_hsrv_add_alias(hsrv, spec, afb_common_rootdir_get_fd(), path, - 0, 0); + 0, 1); } static int init_http_server(struct afb_hsrv *hsrv) @@ -340,14 +340,25 @@ static int init_http_server(struct afb_hsrv *hsrv) return 1; } +static int add_interface(void *closure, const char *value) +{ + struct afb_hsrv *hsrv = closure; + int rc; + + rc = afb_hsrv_add_interface(hsrv, value); + return rc > 0; +} + static struct afb_hsrv *start_http_server() { int rc; - const char *uploaddir, *rootdir; + const char *uploaddir, *rootdir, *errs; struct afb_hsrv *hsrv; int cache_timeout, http_port; + struct json_object *junk; - rc = wrap_json_unpack(main_config, "{ss ss si si}", + http_port = -1; + rc = wrap_json_unpack(main_config, "{ss ss si s?i}", "uploaddir", &uploaddir, "rootdir", &rootdir, "cache-eol", &cache_timeout, @@ -358,8 +369,13 @@ static struct afb_hsrv *start_http_server() } if (afb_hreq_init_download_path(uploaddir)) { - ERROR("unable to set the upload directory %s", uploaddir); - return NULL; + static const char fallback_uploaddir[] = "/tmp"; + WARNING("unable to set the upload directory %s", uploaddir); + if (afb_hreq_init_download_path(fallback_uploaddir)) { + ERROR("unable to fallback to upload directory %s", fallback_uploaddir); + return NULL; + } + uploaddir = fallback_uploaddir; } hsrv = afb_hsrv_create(); @@ -375,9 +391,6 @@ static struct afb_hsrv *start_http_server() return NULL; } - NOTICE("Waiting port=%d rootdir=%s", http_port, rootdir); - NOTICE("Browser URL= http://localhost:%d", http_port); - rc = afb_hsrv_start(hsrv, 15); if (!rc) { ERROR("starting of httpd failed"); @@ -385,9 +398,27 @@ static struct afb_hsrv *start_http_server() return NULL; } - rc = afb_hsrv_add_interface_tcp(hsrv, DEFAULT_BINDER_INTERFACE, (uint16_t) http_port); - if (!rc) { - ERROR("setting interface failed"); + NOTICE("Serving rootdir=%s uploaddir=%s", rootdir, uploaddir); + + /* check if port is set */ + if (http_port < 0) { + /* not set, check existing interfaces */ + if (!json_object_object_get_ex(main_config, "interface", &junk)) { + ERROR("No port and no interface "); + } + } else { + rc = afb_hsrv_add_interface_tcp(hsrv, DEFAULT_BINDER_INTERFACE, (uint16_t) http_port); + if (!rc) { + ERROR("setting interface failed"); + afb_hsrv_put(hsrv); + return NULL; + } + NOTICE("Browser URL= http://localhost:%d", http_port); + } + + errs = run_for_config_array_opt("interface", add_interface, hsrv); + if (errs) { + ERROR("setting interface %s failed", errs); afb_hsrv_put(hsrv); return NULL; } @@ -399,15 +430,25 @@ static struct afb_hsrv *start_http_server() | execute_command +--------------------------------------------------------- */ -static void wait_child_and_exit() +static void exit_at_end() +{ + exit(0); +} + +static void wait_child(int signum, void* arg) { + pid_t pid = (pid_t)(intptr_t)arg; pid_t pidchld = childpid; - childpid = 0; - if (!SELF_PGROUP) - killpg(pidchld, SIGKILL); - waitpid(pidchld, NULL, 0); - exit(0); + if (pidchld == pid) { + childpid = 0; + if (!SELF_PGROUP) + killpg(pidchld, SIGKILL); + waitpid(pidchld, NULL, 0); + jobs_exit(exit_at_end); + } else { + waitpid(pid, NULL, 0); + } } static void on_sigchld(int signum, siginfo_t *info, void *uctx) @@ -417,7 +458,7 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctx) case CLD_EXITED: case CLD_KILLED: case CLD_DUMPED: - jobs_exit(wait_child_and_exit); + jobs_queue_lazy(0, 0, wait_child, (void*)(intptr_t)info->si_pid); default: break; } @@ -433,9 +474,9 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctx) #define SUBST_CHAR '@' #define SUBST_STR "@" -static char *instanciate_string(const char *arg, const char *port, const char *token) +static char *instanciate_string(char *arg, const char *port, const char *token) { - char *resu, *it, *wr; + char *resu, *it, *wr, c; int chg, dif; /* get the changes */ @@ -443,18 +484,24 @@ static char *instanciate_string(const char *arg, const char *port, const char *t dif = 0; it = strchrnul(arg, SUBST_CHAR); while (*it) { - switch(*++it) { - case 'p': chg++; dif += (int)strlen(port) - 2; break; - case 't': chg++; dif += (int)strlen(token) - 2; break; - case SUBST_CHAR: it++; chg++; dif--; break; - default: break; + c = *++it; + if (c == 'p' && port) { + chg++; + dif += (int)strlen(port) - 2; + } else if (c == 't' && token) { + chg++; + dif += (int)strlen(token) - 2; + } else if (c == SUBST_CHAR) { + it++; + chg++; + dif--; } it = strchrnul(it, SUBST_CHAR); } /* return arg when no change */ if (!chg) - return strdup(arg); + return arg; /* allocates the result */ resu = malloc((it - arg) + dif + 1); @@ -470,11 +517,15 @@ static char *instanciate_string(const char *arg, const char *port, const char *t wr = mempcpy(wr, arg, it - arg); if (!*it) break; - switch(*++it) { - case 'p': wr = stpcpy(wr, port); break; - case 't': wr = stpcpy(wr, token); break; - default: *wr++ = SUBST_CHAR; /*@fallthrough@*/ - case SUBST_CHAR: *wr++ = *it; + c = *++it; + if (c == 'p' && port) + wr = stpcpy(wr, port); + else if (c == 't' && token) + wr = stpcpy(wr, token); + else { + if (c != SUBST_CHAR) + *wr++ = SUBST_CHAR; + *wr++ = *it; } arg = ++it; } @@ -502,7 +553,7 @@ static int instanciate_environ(const char *port, const char *token) static char **instanciate_command_args(struct json_object *exec, const char *port, const char *token) { char **result; - char *repl; + char *repl, *item; int i, n; /* allocates the result */ @@ -515,10 +566,9 @@ static char **instanciate_command_args(struct json_object *exec, const char *por /* instanciate the arguments */ for (i = 0 ; i < n ; i++) { - repl = instanciate_string(json_object_get_string(json_object_array_get_idx(exec, i)), port, token); + item = (char*)json_object_get_string(json_object_array_get_idx(exec, i)); + repl = instanciate_string(item, port, token); if (!repl) { - while(i) - free(result[--i]); free(result); return NULL; } @@ -530,12 +580,10 @@ static char **instanciate_command_args(struct json_object *exec, const char *por static int execute_command() { - struct json_object *exec, *oport; + struct json_object *exec, *oport, *otok; struct sigaction siga; - char port[20]; - const char *token; + const char *token, *port; char **args; - int rc; /* check whether a command is to execute or not */ if (!json_object_object_get_ex(main_config, "exec", &exec)) @@ -557,23 +605,21 @@ static int execute_command() /* compute the string for port */ if (json_object_object_get_ex(main_config, "port", &oport)) - rc = snprintf(port, sizeof port, "%s", json_object_get_string(oport)); + port = json_object_get_string(oport); else - rc = snprintf(port, sizeof port, "%cp", SUBST_CHAR); - if (rc < 0 || rc >= (int)(sizeof port)) { - ERROR("port->txt failed"); - } - else { - /* instantiate arguments and environment */ - token = afb_session_initial_token(); - args = instanciate_command_args(exec, port, token); - if (args && instanciate_environ(port, token) >= 0) { - /* run */ - if (!SELF_PGROUP) - setpgid(0, 0); - execv(args[0], args); - ERROR("can't launch %s: %m", args[0]); - } + port = 0; + /* instantiate arguments and environment */ + if (json_object_object_get_ex(main_config, "token", &otok)) + token = json_object_get_string(otok); + else + token = 0; + args = instanciate_command_args(exec, port, token); + if (args && instanciate_environ(port, token) >= 0) { + /* run */ + if (!SELF_PGROUP) + setpgid(0, 0); + execv(args[0], args); + ERROR("can't launch %s: %m", args[0]); } exit(1); return -1; @@ -645,8 +691,7 @@ static void startup_call_current(struct startup_req *sreq) json = strchr(verb, ':'); if (json) { afb_xreq_init(&sreq->xreq, &startup_xreq_itf); - afb_context_init(&sreq->xreq.context, sreq->session, NULL); - sreq->xreq.context.validated = 1; + afb_context_init_validated(&sreq->xreq.context, sreq->session, NULL, NULL); sreq->api = strndup(api, verb - api); sreq->verb = strndup(verb + 1, json - verb - 1); sreq->xreq.request.called_api = sreq->api; @@ -716,12 +761,6 @@ static void start(int signum, void *arg) "ss ss s?s" "si si si" "s?b s?i s?s" -#if WITH_AFB_HOOK -#if !defined(REMOVE_LEGACY_TRACE) - "s?s s?s" -#endif - "s?s s?s s?s s?s s?s" -#endif "s?o" "}", @@ -737,7 +776,21 @@ static void start(int signum, void *arg) "port", &http_port, "rootapi", &rootapi, + "set", &settings + ); + if (rc < 0) { + ERROR("Unable to get start config"); + exit(1); + } + #if WITH_AFB_HOOK + rc = wrap_json_unpack(main_config, "{" +#if !defined(REMOVE_LEGACY_TRACE) + "s?s s?s" +#endif + "s?s s?s s?s s?s s?s" + "}", + #if !defined(REMOVE_LEGACY_TRACE) "tracesvc", &tracesvc, "traceditf", &traceditf, @@ -746,17 +799,16 @@ static void start(int signum, void *arg) "traceapi", &traceapi, "traceevt", &traceevt, "traceses", &traceses, - "traceglob", &traceglob, -#endif - "set", &settings + "traceglob", &traceglob ); if (rc < 0) { - ERROR("Unable to get start config"); + ERROR("Unable to get hook config"); exit(1); } +#endif /* initialize session handling */ - if (afb_session_init(max_session_count, session_timeout, token)) { + if (afb_session_init(max_session_count, session_timeout)) { ERROR("initialisation of session manager failed"); goto error; } @@ -779,16 +831,12 @@ static void start(int signum, void *arg) /* setup HTTP */ if (!no_httpd) { - if (http_port < 0) { - ERROR("no port is defined"); - goto error; - } if (http_port == 0) { ERROR("random port is not implemented"); goto error; } - if (addenv_int("AFB_PORT", http_port) - || addenv("AFB_TOKEN", afb_session_initial_token())) { + if ((http_port > 0 && addenv_int("AFB_PORT", http_port)) + || (token && addenv("AFB_TOKEN", token))) { ERROR("can't set HTTP environment"); goto error; } @@ -835,9 +883,11 @@ static void start(int signum, void *arg) /* load bindings and apis */ afb_debug("start-load"); +#if WITH_DYNAMIC_BINDING apiset_start_list("binding", afb_api_so_add_binding, "the binding"); apiset_start_list("ldpaths", afb_api_so_add_pathset_fails, "the binding path set"); apiset_start_list("weak-ldpaths", afb_api_so_add_pathset_nofails, "the weak binding path set"); +#endif apiset_start_list("auto-api", afb_autoset_add_any, "the automatic api path set"); #if WITH_DBUS_TRANSPARENCY apiset_start_list("dbus-client", afb_api_dbus_add_client, "the afb-dbus client"); @@ -879,7 +929,7 @@ static void start(int signum, void *arg) /* run the command */ afb_debug("start-exec"); - if (execute_command() < 0) + if (execute_command(http_port, token) < 0) goto error; /* ready */ @@ -933,7 +983,7 @@ int main(int argc, char *argv[]) afb_debug("main-start"); /* enter job processing */ - jobs_start(3, 0, 50, start, NULL); + jobs_start(3, 0, 100, start, NULL); WARNING("hoops returned from jobs_enter! [report bug]"); return 1; }