*/
#define _GNU_SOURCE
-#define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
-#include <uuid/uuid.h>
-
#include "verbose.h"
#include "afb-config.h"
#include "afb-hook.h"
#if !defined(BINDING_INSTALL_DIR)
#error "you should define BINDING_INSTALL_DIR"
#endif
-
-#define AFB_VERSION "0.6"
+#if !defined(AFB_VERSION)
+#error "you should define AFB_VERSION"
+#endif
// default
#define DEFLT_CNTX_TIMEOUT 3600 // default Client Connection
#define DEFLT_CACHE_TIMEOUT 100000 // default Static File Chache
// [Client Side Cache
// 100000~=1day]
-#define DEFLT_AUTH_TOKEN NULL // expect for debug should == NULL
#define CTX_NBCLIENTS 10 // allow a default of 10 authenticated
// clients
#define SET_BACKGROUND 2
#define SET_FORGROUND 3
-#define SET_TCP_PORT 5
#define SET_ROOT_DIR 6
#define SET_ROOT_BASE 7
#define SET_ROOT_API 8
#define SET_LDPATH 13
#define SET_APITIMEOUT 14
#define SET_CNTXTIMEOUT 15
-
+#define SET_WEAK_LDPATH 16
+#define NO_LDPATH 17
#define SET_MODE 18
#define SET_TRACEEVT 'E'
#define SET_EXEC 'e'
#define DISPLAY_HELP 'h'
+#if defined(WITH_MONITORING_OPTION)
+#define SET_MONITORING 'M'
+#endif
+#define SET_NAME 'n'
+#define SET_TCP_PORT 'p'
#define SET_QUIET 'q'
#define SET_RNDTOKEN 'r'
#define SET_TRACESVC 'S'
#define SET_VERBOSE 'v'
#define SET_WORK_DIR 'w'
-#define SHORTOPTS "c:D:E:ehqrT:t:u:Vvw:"
+const char shortopts[] =
+ "c:D:E:ehn:p:qrT:t:u:Vvw:"
+#if defined(WITH_MONITORING_OPTION)
+ "M"
+#endif
+;
// Command line structure hold cli --command + help text
typedef struct {
{SET_FORGROUND, 0, "foreground", "Get all in foreground mode"},
{SET_BACKGROUND, 0, "daemon", "Get all in background mode"},
+ {SET_NAME, 1, "name", "Set the visible name"},
+
{SET_TCP_PORT, 1, "port", "HTTP listening TCP port [default 1234]"},
{SET_ROOT_HTTP, 1, "roothttp", "HTTP Root Directory [default no root http (files not served but apis still available)]"},
{SET_ROOT_BASE, 1, "rootbase", "Angular Base Root URL [default /opa]"},
{SET_LDPATH, 1, "ldpaths", "Load bindings from dir1:dir2:... [default = " BINDING_INSTALL_DIR "]"},
{SO_BINDING, 1, "binding", "Load the binding of path"},
+ {SET_WEAK_LDPATH, 1, "weak-ldpaths","Same as --ldpaths but ignore errors"},
+ {NO_LDPATH, 0, "no-ldpaths", "Discard default ldpaths loading"},
{SET_AUTH_TOKEN, 1, "token", "Initial Secret [default=no-session, --token= for session without authentication]"},
- {SET_RNDTOKEN, 0, "random-token","Creates a random token"},
+ {SET_RNDTOKEN, 0, "random-token","Enforce a random token"},
{DISPLAY_VERSION, 0, "version", "Display version and copyright"},
{DISPLAY_HELP, 0, "help", "Display this help"},
{SET_NO_HTTPD, 0, "no-httpd", "Forbids HTTP service"},
{SET_EXEC, 0, "exec", "Execute the remaining arguments"},
+#if defined(WITH_MONITORING_OPTION)
+ {SET_MONITORING, 0, "monitoring", "enable HTTP monitoring at <ROOT>/monitoring/"},
+#endif
{0, 0, NULL, NULL}
/* *INDENT-ON* */
};
+--------------------------------------------------------- */
static void printVersion(FILE * file)
{
- fprintf(file, "\n----------------------------------------- \n");
- fprintf(file, " AFB [Application Framework Binder] version=%s |\n",
- AFB_VERSION);
- fprintf(file, " \n");
- fprintf(file,
- " Copyright (C) 2015, 2016, 2017 \"IoT.bzh\" [fulup -at- iot.bzh]\n");
- fprintf(file, " AFB comes with ABSOLUTELY NO WARRANTY.\n");
- fprintf(file, " Licence Apache 2\n\n");
+ static const char version[] =
+ "\n"
+ " AFB [Application Framework Binder] version="AFB_VERSION"\n"
+ "\n"
+ " Copyright (C) 2015, 2016, 2017 \"IoT.bzh\"\n"
+ " AFB comes with ABSOLUTELY NO WARRANTY.\n"
+ " Licence Apache 2\n"
+ "\n";
+
+ fprintf(file, "%s", version);
}
/*----------------------------------------------------------
}
-/*----------------------------------------------------------
- | adds a string to the list
- +--------------------------------------------------------- */
-static char *random_token()
-{
- static char uuidstr[37];
- uuid_t uuid;
- uuid_generate_random(uuid);
- uuid_unparse(uuid, uuidstr);
- return uuidstr;
-}
-
/*----------------------------------------------------------
| adds a string to the list
+--------------------------------------------------------- */
| helpers for argument scanning
+--------------------------------------------------------- */
-static const char *optname(int optc)
+static const char *name_of_option(int optc)
{
AFB_options *o = cliOptions;
while (o->name && o->val != optc)
return o->name ? : "<unknown-option-name>";
}
-static char *argvalstr(int optc)
+static const char *current_argument(int optc)
{
if (optarg == 0) {
ERROR("option [--%s] needs a value i.e. --%s=xxx",
- optname(optc), optname(optc));
+ name_of_option(optc), name_of_option(optc));
exit(1);
}
return optarg;
}
+static char *argvalstr(int optc)
+{
+ char *result = strdup(current_argument(optc));
+ if (result == NULL) {
+ ERROR("can't alloc memory");
+ exit(1);
+ }
+ return result;
+}
+
static int argvalenum(int optc, struct enumdesc *desc)
{
int i;
size_t len;
- char *list, *name = argvalstr(optc);
+ char *list;
+ const char *name = current_argument(optc);
i = 0;
while(desc[i].name && strcmp(desc[i].name, name))
list = malloc(len + i + i);
if (!i || !list)
ERROR("option [--%s] bad value (found %s)",
- optname(optc), name);
+ name_of_option(optc), name);
else {
i = 0;
strcpy(list, desc[i].name ? : "");
while(desc[++i].name)
strcat(strcat(list, ", "), desc[i].name);
ERROR("option [--%s] bad value, only accepts values %s (found %s)",
- optname(optc), list, name);
+ name_of_option(optc), list, name);
}
free(list);
exit(1);
static int argvalint(int optc, int mini, int maxi, int base)
{
- char *beg, *end;
+ const char *beg, *end;
long int val;
- beg = argvalstr(optc);
- val = strtol(beg, &end, base);
+ beg = current_argument(optc);
+ val = strtol(beg, (char**)&end, base);
if (*end || end == beg) {
ERROR("option [--%s] requires a valid integer (found %s)",
- optname(optc), beg);
+ name_of_option(optc), beg);
exit(1);
}
if (val < (long int)mini || val > (long int)maxi) {
ERROR("option [--%s] value out of bounds (not %d<=%ld<=%d)",
- optname(optc), mini, val, maxi);
+ name_of_option(optc), mini, val, maxi);
exit(1);
}
return (int)val;
static void noarg(int optc)
{
if (optarg != 0) {
- ERROR("option [--%s] need no value (found %s)", optname(optc), optarg);
+ ERROR("option [--%s] need no value (found %s)", name_of_option(optc), optarg);
+ exit(1);
+ }
+}
+
+static char **make_exec(char **argv)
+{
+ char **result, *iter;
+ size_t length;
+ int i;
+
+ length = 0;
+ for (i = 0 ; argv[i] ; i++)
+ length += strlen(argv[i]) + 1;
+
+ result = malloc(length + ((unsigned)(i + 1)) * sizeof *result);
+ if (result == NULL) {
+ ERROR("can't alloc memory");
exit(1);
}
+
+ iter = (char*)&result[i+1];
+ for (i = 0 ; argv[i] ; i++) {
+ result[i] = iter;
+ iter = stpcpy(iter, argv[i]) + 1;
+ }
+ result[i] = NULL;
+ return result;
}
/*---------------------------------------------------------
}
// get all options from command line
- while ((optc = getopt_long(argc, argv, SHORTOPTS, gnuOptions, NULL)) != EOF) {
+ while ((optc = getopt_long(argc, argv, shortopts, gnuOptions, NULL)) != EOF) {
switch (optc) {
case SET_VERBOSE:
verbosity++;
list_add(&config->ldpaths, argvalstr(optc));
break;
+ case SET_WEAK_LDPATH:
+ list_add(&config->weak_ldpaths, argvalstr(optc));
+ break;
+
+ case NO_LDPATH:
+ noarg(optc);
+ config->no_ldpaths = 1;
+ break;
+
case ADD_CALL:
list_add(&config->calls, argvalstr(optc));
break;
case SET_SESSION_DIR:
/* config->sessiondir = argvalstr(optc); */
- WARNING("Obsolete otpion %s ignored", optname(optc));
+ WARNING("Obsolete option %s ignored", name_of_option(optc));
break;
case SET_UPLOAD_DIR:
config->background = 1;
break;
+ case SET_NAME:
+ config->name = argvalstr(optc);
+ break;
+
case SET_MODE:
config->mode = argvalenum(optc, mode_desc);
break;
break;
case SET_EXEC:
- config->exec = &argv[optind];
- optind = argc;
+ config->exec = make_exec(&argv[optind]);
+ optind = argc; /* stop option scanning */
break;
case SET_RNDTOKEN:
- config->token = random_token();
+ config->random_token = 1;
break;
+#if defined(WITH_MONITORING_OPTION)
+ case SET_MONITORING:
+ config->monitoring = 1;
+ break;
+#endif
+
case DISPLAY_VERSION:
noarg(optc);
printVersion(stdout);
free(gnuOptions);
}
-// load config from disk and merge with CLI option
-static void config_set_default(struct afb_config *config)
+static void fulfill_config(struct afb_config *config)
{
// default HTTP port
if (config->httpdPort == 0)
config->apiTimeout = DEFLT_API_TIMEOUT;
// default AUTH_TOKEN
- if (config->token == NULL)
- config->token = DEFLT_AUTH_TOKEN;
+ if (config->random_token)
+ config->token = NULL;
// cache timeout default one hour
if (config->cacheTimeout == 0)
if (config->rootapi == NULL)
config->rootapi = "/api";
- if (config->ldpaths == NULL)
+ if (config->ldpaths == NULL && config->weak_ldpaths == NULL && !config->no_ldpaths)
list_add(&config->ldpaths, BINDING_INSTALL_DIR);
+#if defined(WITH_MONITORING_OPTION)
+ if (config->monitoring)
+ list_add(&config->aliases, strdup("/monitoring:"BINDING_INSTALL_DIR"/monitoring"));
+#endif
+
// if no config dir create a default path from uploaddir
if (config->console == NULL) {
config->console = malloc(512);
S(workdir)
S(uploaddir)
S(token)
+ S(name)
L(aliases)
L(dbus_clients)
L(ws_servers)
L(so_bindings)
L(ldpaths)
+ L(weak_ldpaths)
L(calls)
V(exec)
D(httpdPort)
- B(background)
D(cacheTimeout)
D(apiTimeout)
D(cntxTimeout)
D(nbSessionMax)
+
E(mode,mode_desc)
E(tracereq,tracereq_desc)
E(traceditf,traceditf_desc)
+ E(tracesvc,tracesvc_desc)
+ E(traceevt,traceevt_desc)
+
+ B(no_ldpaths)
B(noHttpd)
+ B(background)
+ B(monitoring)
+ B(random_token)
P("---END-OF-CONFIG---\n");
#undef V
result = calloc(1, sizeof *result);
parse_arguments(argc, argv, result);
- config_set_default(result);
+ fulfill_config(result);
if (verbosity >= 3)
afb_config_dump(result);
return result;