- char* programName = argv [0];
- int optionIndex = 0;
- int optc, ind;
- int nbcmd;
- struct option *gnuOptions;
- AFB_config cliconfig; // temp structure to store CLI option before file config upload
-
- // ------------- Build session handler & init config -------
- memset(&cliconfig,0,sizeof(cliconfig));
- memset(&aliasdir ,0,sizeof(aliasdir));
- cliconfig.aliasdir = aliasdir;
-
- // ------------------ Process Command Line -----------------------
-
- // if no argument print help and return
- if (argc < 2) {
- printHelp(programName);
- exit(1);
- }
-
- // build GNU getopt info from cliOptions
- nbcmd = sizeof (cliOptions) / sizeof (AFB_options);
- gnuOptions = malloc (sizeof (*gnuOptions) * (unsigned)nbcmd);
- for (ind=0; ind < nbcmd;ind++) {
- gnuOptions [ind].name = cliOptions[ind].name;
- gnuOptions [ind].has_arg = cliOptions[ind].has_arg;
- gnuOptions [ind].flag = 0;
- gnuOptions [ind].val = cliOptions[ind].val;
- }
-
- // get all options from command line
- while ((optc = getopt_long (argc, argv, "vsp?", gnuOptions, &optionIndex))
- != EOF)
- {
- switch (optc)
- {
- case SET_VERBOSE:
- verbose = 1;
- break;
-
- case SET_TCP_PORT:
- if (optarg == 0) goto needValueForOption;
- if (!sscanf (optarg, "%d", &cliconfig.httpdPort)) goto notAnInteger;
- break;
-
- case SET_APITIMEOUT:
- if (optarg == 0) goto needValueForOption;
- if (!sscanf (optarg, "%d", &cliconfig.apiTimeout)) goto notAnInteger;
- break;
-
- case SET_CNTXTIMEOUT:
- if (optarg == 0) goto needValueForOption;
- if (!sscanf (optarg, "%d", &cliconfig.cntxTimeout)) goto notAnInteger;
- break;
-
- case SET_ROOT_DIR:
- if (optarg == 0) goto needValueForOption;
- cliconfig.rootdir = optarg;
- if (verbose) fprintf(stderr, "Forcing Rootdir=%s\n",cliconfig.rootdir);
- break;
-
- case SET_ROOT_BASE:
- if (optarg == 0) goto needValueForOption;
- cliconfig.rootbase = optarg;
- if (verbose) fprintf(stderr, "Forcing Rootbase=%s\n",cliconfig.rootbase);
- break;
-
- case SET_ROOT_API:
- if (optarg == 0) goto needValueForOption;
- cliconfig.rootapi = optarg;
- if (verbose) fprintf(stderr, "Forcing Rootapi=%s\n",cliconfig.rootapi);
- break;
-
- case SET_ROOT_ALIAS:
- if (optarg == 0) goto needValueForOption;
- if (aliascount < MAX_ALIAS) {
- aliasdir[aliascount].url = strsep(&optarg,":");
- if (optarg == NULL) {
- fprintf(stderr, "missing ':' in alias %s, ignored\n", aliasdir[aliascount].url);
- } else {
- aliasdir[aliascount].path = optarg;
- aliasdir[aliascount].len = strlen(aliasdir[aliascount].url);
- if (verbose) fprintf(stderr, "Alias url=%s path=%s\n", aliasdir[aliascount].url, aliasdir[aliascount].path);
- aliascount++;
- }
- } else {
- fprintf(stderr, "Too many aliases [max:%d] %s ignored\n", MAX_ALIAS, optarg);
- }
- break;
-
- case SET_AUTH_TOKEN:
- if (optarg == 0) goto needValueForOption;
- cliconfig.token = optarg;
- break;
-
- case SET_LDPATH:
- if (optarg == 0) goto needValueForOption;
- cliconfig.ldpaths = optarg;
- break;
-
- case SET_PID_FILE:
- if (optarg == 0) goto needValueForOption;
- cliconfig.pidfile = optarg;
- break;
-
- case SET_SESSION_DIR:
- if (optarg == 0) goto needValueForOption;
- cliconfig.sessiondir = optarg;
- break;
-
- case SET_CONFIG_FILE:
- if (optarg == 0) goto needValueForOption;
- cliconfig.configfile = optarg;
- break;
-
- case SET_CACHE_TO:
- if (optarg == 0) goto needValueForOption;
- if (!sscanf (optarg, "%d", &cliconfig.cacheTimeout)) goto notAnInteger;
- break;
-
- case SET_CONFIG_EXIT:
- if (optarg != 0) goto noValueForOption;
- session->configsave = 1;
- session->forceexit = 1;
- break;
-
- case SET_CONFIG_SAVE:
- if (optarg != 0) goto noValueForOption;
- session->configsave = 1;
- break;
-
- case SET_USERID:
- if (optarg == 0) goto needValueForOption;
- cliconfig.setuid = optarg;
- break;
-
- case SET_FAKE_MOD:
- if (optarg != 0) goto noValueForOption;
- session->fakemod = 1;
- break;
-
- case SET_FORGROUND:
- if (optarg != 0) goto noValueForOption;
- session->foreground = 1;
- break;
-
- case SET_BACKGROUND:
- if (optarg != 0) goto noValueForOption;
- session->background = 1;
- break;
-
- case KILL_PREV_REST:
- if (optarg != 0) goto noValueForOption;
- session->killPrevious = 1;
- break;
-
- case KILL_PREV_EXIT:
- if (optarg != 0) goto noValueForOption;
- session->killPrevious = 2;
- break;
-
- case SET_MODE:
- if (optarg == 0) goto needValueForOption;
- if (!strcmp(optarg, "local")) cliconfig.mode = AFB_MODE_LOCAL;
- else if (!strcmp(optarg, "remote")) cliconfig.mode = AFB_MODE_REMOTE;
- else if (!strcmp(optarg, "global")) cliconfig.mode = AFB_MODE_GLOBAL;
- else goto badMode;
- break;
-
- case SET_READYFD:
- if (optarg == 0) goto needValueForOption;
- if (!sscanf (optarg, "%u", &session->readyfd)) goto notAnInteger;
- break;
-
- case DISPLAY_VERSION:
- if (optarg != 0) goto noValueForOption;
- printVersion();
- exit(0);
-
- case DISPLAY_HELP:
- default:
- printHelp(programName);
- exit(0);
- }
- }
- free(gnuOptions);
-
- // if exist merge config file with CLI arguments
- configLoadFile (session, &cliconfig);
- return;
-
-
-needValueForOption:
- fprintf (stderr,"\nERR:AFB-daemon option [--%s] need a value i.e. --%s=xxx\n\n"
- ,gnuOptions[optionIndex].name, gnuOptions[optionIndex].name);
- exit (1);
-
-notAnInteger:
- fprintf (stderr,"\nERR:AFB-daemon option [--%s] requirer an interger i.e. --%s=9\n\n"
- ,gnuOptions[optionIndex].name, gnuOptions[optionIndex].name);
- exit (1);
-
-noValueForOption:
- fprintf (stderr,"\nERR:AFB-daemon option [--%s] don't take value\n\n"
- ,gnuOptions[optionIndex].name);
- exit (1);
-
-badMode:
- fprintf (stderr,"\nERR:AFB-daemon option [--%s] only accepts local, global or remote.\n\n"
- ,gnuOptions[optionIndex].name);
- exit (1);
+ struct sigaction siga;
+ char port[20];
+ const char *token;
+ int rc;
+
+ /* check whether a command is to execute or not */
+ if (!main_config->exec || !main_config->exec[0])
+ return 0;
+
+ if (SELF_PGROUP)
+ setpgid(0, 0);
+
+ /* install signal handler */
+ memset(&siga, 0, sizeof siga);
+ siga.sa_sigaction = on_sigchld;
+ siga.sa_flags = SA_SIGINFO;
+ sigaction(SIGCHLD, &siga, NULL);
+
+ /* fork now */
+ childpid = fork();
+ if (childpid)
+ return 0;
+
+ /* compute the string for port */
+ if (main_config->httpdPort)
+ rc = snprintf(port, sizeof port, "%d", main_config->httpdPort);
+ else
+ rc = snprintf(port, sizeof port, "%cp", SUBST_CHAR);
+ if (rc < 0 || rc >= (int)(sizeof port)) {
+ ERROR("port->txt failed");
+ }
+ else {
+ /* instanciate arguments and environment */
+ token = afb_session_initial_token();
+ if (instanciate_command_args(port, token) >= 0
+ && instanciate_environ(port, token) >= 0) {
+ /* run */
+ if (!SELF_PGROUP)
+ setpgid(0, 0);
+ execv(main_config->exec[0], main_config->exec);
+ ERROR("can't launch %s: %m", main_config->exec[0]);
+ }
+ }
+ exit(1);
+ return -1;