summaryrefslogtreecommitdiffstats
path: root/src/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config.c')
-rw-r--r--src/config.c335
1 files changed, 335 insertions, 0 deletions
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 00000000..893b3a5f
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2015 "IoT.bzh"
+ * Author "Fulup Ar Foll"
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ References:
+ https://www.gnu.org/software/libmicrohttpd/manual/html_node/index.html#Top
+ http://www-01.ibm.com/support/knowledgecenter/SSB23S_1.1.0.9/com.ibm.ztpf-ztpfdf.doc_put.09/gtpc2/cpp_vsprintf.html?cp=SSB23S_1.1.0.9%2F0-3-8-1-0-16-8
+
+*/
+
+
+#include "../include/local-def.h"
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+#define AFB_CONFIG_JTYPE "AFB_config"
+
+PUBLIC char *ERROR_LABEL[]=ERROR_LABEL_DEF;
+
+PUBLIC int verbose;
+STATIC AFB_ErrorT AFB_Error [AFB_SUCCESS+1];
+STATIC json_object *AFBJsonType;
+
+/* ------------------------------------------------------------------------------
+ * Get localtime and return in a string
+ * ------------------------------------------------------------------------------ */
+
+PUBLIC char * configTime (void) {
+ static char reqTime [26];
+ time_t tt;
+ struct tm *rt;
+
+ /* Get actual Date and Time */
+ time (&tt);
+ rt = localtime (&tt);
+
+ strftime (reqTime, sizeof (reqTime), "(%d-%b %H:%M)",rt);
+
+ // return pointer on static data
+ return (reqTime);
+}
+
+// load config from disk and merge with CLI option
+PUBLIC AFB_ERROR configLoadFile (AFB_session * session, AFB_config *cliconfig) {
+ static char cacheTimeout [10];
+ int fd;
+ json_object * AFBConfig, *value;
+
+ // fix config redirect message
+ session->config->html5.msg = "Angular/HTML5 redirect";
+ session->config->html5.len = strlen(session->config->html5.msg);
+
+ // default HTTP port
+ if (cliconfig->httpdPort == 0) session->config->httpdPort=1234;
+ else session->config->httpdPort=cliconfig->httpdPort;
+
+ // cache timeout default one hour
+ if (cliconfig->cacheTimeout == 0) session->config->cacheTimeout=3600;
+ else session->config->cacheTimeout=cliconfig->cacheTimeout;
+
+ if (cliconfig->rootdir == NULL) {
+ session->config->rootdir = getenv("AFBDIR");
+ if (session->config->rootdir == NULL) {
+ session->config->rootdir = malloc (512);
+ strncpy (session->config->rootdir, getenv("HOME"),512);
+ strncat (session->config->rootdir, "/.AFB",512);
+ }
+ // if directory does not exist createit
+ mkdir (session->config->rootdir, O_RDWR | S_IRWXU | S_IRGRP);
+ } else {
+ session->config->rootdir = cliconfig->rootdir;
+ }
+
+ // if no Angular/HTML5 rootbase let's try '/' as default
+ if (cliconfig->rootbase == NULL) {
+ session->config->rootbase = "/";
+ } else {
+ session->config->console= cliconfig->console;
+ }
+
+ // if no rootapi use '/api'
+ if (cliconfig->rootbase == NULL) {
+ session->config->rootbase = "/api";
+ } else {
+ session->config->console= cliconfig->console;
+ }
+
+
+
+ // if no session dir create a default path from rootdir
+ if (cliconfig->sessiondir == NULL) {
+ session->config->sessiondir = malloc (512);
+ strncpy (session->config->sessiondir, session->config->rootdir, 512);
+ strncat (session->config->sessiondir, "/sessions",512);
+ } else {
+ session->config->sessiondir = cliconfig->sessiondir;
+ }
+
+ // if no config dir create a default path from sessiondir
+ if (cliconfig->configfile == NULL) {
+ session->config->configfile = malloc (512);
+ strncpy (session->config->configfile, session->config->sessiondir, 512);
+ strncat (session->config->configfile, "/AFB-config.json",512);
+ } else {
+ session->config->configfile = cliconfig->configfile;
+ }
+
+ // if no config dir create a default path from sessiondir
+ if (cliconfig->pidfile == NULL) {
+ session->config->pidfile = malloc (512);
+ strncpy (session->config->pidfile, session->config->sessiondir, 512);
+ strncat (session->config->pidfile, "/AFB-process.pid",512);
+ } else {
+ session->config->pidfile= cliconfig->pidfile;
+ }
+
+ // if no config dir create a default path from sessiondir
+ if (cliconfig->console == NULL) {
+ session->config->console = malloc (512);
+ strncpy (session->config->console, session->config->sessiondir, 512);
+ strncat (session->config->console, "/AFB-console.out",512);
+ } else {
+ session->config->console= cliconfig->console;
+ }
+
+ // just upload json object and return without any further processing
+ if((fd = open(session->config->configfile, O_RDONLY)) < 0) {
+ if (verbose) fprintf (stderr, "AFB:notice: config at %s: %s\n", session->config->configfile, strerror(errno));
+ return AFB_EMPTY;
+ }
+
+ // openjson from FD is not public API we need to reopen it !!!
+ close(fd);
+ AFBConfig = json_object_from_file (session->config->configfile);
+
+ // check it is an AFB_config
+ if (json_object_object_get_ex (AFBConfig, "jtype", &value)) {
+ if (strcmp (AFB_CONFIG_JTYPE, json_object_get_string (value))) {
+ fprintf (stderr,"AFB: Error file [%s] is not a valid [%s] type\n ", session->config->configfile, AFB_CONFIG_JTYPE);
+ return AFB_FAIL;
+ }
+ }
+
+ if (!cliconfig->rootdir && json_object_object_get_ex (AFBConfig, "rootdir", &value)) {
+ session->config->rootdir = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->rootbase && json_object_object_get_ex (AFBConfig, "rootbase", &value)) {
+ session->config->rootbase = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->rootapi && json_object_object_get_ex (AFBConfig, "rootapi", &value)) {
+ session->config->rootapi = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->smack && json_object_object_get_ex (AFBConfig, "smack", &value)) {
+ session->config->smack = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->plugins && json_object_object_get_ex (AFBConfig, "plugins", &value)) {
+ session->config->plugins = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->sessiondir && json_object_object_get_ex (AFBConfig, "sessiondir", &value)) {
+ session->config->sessiondir = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->pidfile && json_object_object_get_ex (AFBConfig, "pidfile", &value)) {
+ session->config->pidfile = strdup (json_object_get_string (value));
+ }
+
+ if (!cliconfig->httpdPort && json_object_object_get_ex (AFBConfig, "httpdPort", &value)) {
+ session->config->httpdPort = json_object_get_int (value);
+ }
+
+ if (!cliconfig->setuid && json_object_object_get_ex (AFBConfig, "setuid", &value)) {
+ session->config->setuid = json_object_get_int (value);
+ }
+
+ if (!cliconfig->localhostOnly && json_object_object_get_ex (AFBConfig, "localhostonly", &value)) {
+ session->config->localhostOnly = json_object_get_int (value);
+ }
+
+ if (!cliconfig->cacheTimeout && json_object_object_get_ex (AFBConfig, "cachetimeout", &value)) {
+ session->config->cacheTimeout = json_object_get_int (value);
+ }
+ // cacheTimeout is an interger but HTTPd wants it as a string
+ snprintf (cacheTimeout, sizeof (cacheTimeout),"%d", session->config->cacheTimeout);
+ session->cacheTimeout = cacheTimeout; // httpd uses cacheTimeout string version
+ json_object_put (AFBConfig); // decrease reference count to free the json object
+
+ return AFB_SUCCESS;
+}
+
+// Save the config on disk
+PUBLIC void configStoreFile (AFB_session * session) {
+ json_object * AFBConfig;
+ time_t rawtime;
+ struct tm * timeinfo;
+ int err;
+
+ AFBConfig = json_object_new_object();
+
+ // add a timestamp and store session on disk
+ time ( &rawtime ); timeinfo = localtime ( &rawtime );
+ // A copy of the string is made and the memory is managed by the json_object
+ json_object_object_add (AFBConfig, "jtype" , json_object_new_string (AFB_CONFIG_JTYPE));
+ json_object_object_add (AFBConfig, "timestamp" , json_object_new_string (asctime (timeinfo)));
+ json_object_object_add (AFBConfig, "rootdir" , json_object_new_string (session->config->rootdir));
+ json_object_object_add (AFBConfig, "rootapi" , json_object_new_string (session->config->rootapi));
+ json_object_object_add (AFBConfig, "rootbase" , json_object_new_string (session->config->rootbase));
+ json_object_object_add (AFBConfig, "smack" , json_object_new_string (session->config->smack));
+ json_object_object_add (AFBConfig, "plugins" , json_object_new_string (session->config->plugins));
+ json_object_object_add (AFBConfig, "sessiondir" , json_object_new_string (session->config->sessiondir));
+ json_object_object_add (AFBConfig, "pidfile" , json_object_new_string (session->config->pidfile));
+ json_object_object_add (AFBConfig, "httpdPort" , json_object_new_int (session->config->httpdPort));
+ json_object_object_add (AFBConfig, "setuid" , json_object_new_int (session->config->setuid));
+ json_object_object_add (AFBConfig, "localhostonly" , json_object_new_int (session->config->localhostOnly));
+ json_object_object_add (AFBConfig, "cachetimeout" , json_object_new_int (session->config->cacheTimeout));
+
+ err = json_object_to_file (session->config->configfile, AFBConfig);
+ json_object_put (AFBConfig); // decrease reference count to free the json object
+ if (err < 0) {
+ fprintf(stderr, "AFB: Fail to save config on disk [%s]\n ", session->config->configfile);
+ }
+}
+
+
+PUBLIC AFB_session *configInit () {
+
+ AFB_session *session;
+ AFB_config *config;
+ int idx, verbosesav;
+
+
+ session = malloc (sizeof (AFB_session));
+ memset (session,0, sizeof (AFB_session));
+
+ // create config handle
+ config = malloc (sizeof (AFB_config));
+ memset (config,0, sizeof (AFB_config));
+
+ // stack config handle into session
+ session->config = config;
+
+ AFBJsonType = json_object_new_string ("AFB_message");
+
+ // initialise JSON constant messages and increase reference count to make them permanent
+ verbosesav = verbose;
+ verbose = 0; // run initialisation in silent mode
+
+
+
+ for (idx = 0; idx <= AFB_SUCCESS; idx++) {
+ AFB_Error[idx].level = idx;
+ AFB_Error[idx].label = ERROR_LABEL [idx];
+ AFB_Error[idx].json = jsonNewMessage (idx, NULL);
+ }
+ verbose = verbosesav;
+
+ return (session);
+}
+
+
+// get JSON object from error level and increase its reference count
+PUBLIC json_object *jsonNewStatus (AFB_ERROR level) {
+
+ json_object *target = AFB_Error[level].json;
+ json_object_get (target);
+
+ return (target);
+}
+
+// get AFB object type with adequate usage count
+PUBLIC json_object *jsonNewjtype (void) {
+ json_object_get (AFBJsonType); // increase reference count
+ return (AFBJsonType);
+}
+
+// build an ERROR message and return it as a valid json object
+PUBLIC json_object *jsonNewMessage (AFB_ERROR level, char* format, ...) {
+ static int count = 0;
+ json_object * AFBResponse;
+ va_list args;
+ char message [512];
+
+ // format message
+ if (format != NULL) {
+ va_start(args, format);
+ vsnprintf (message, sizeof (message), format, args);
+ va_end(args);
+ }
+
+ AFBResponse = json_object_new_object();
+ json_object_object_add (AFBResponse, "jtype", jsonNewjtype ());
+ json_object_object_add (AFBResponse, "status" , json_object_new_string (ERROR_LABEL[level]));
+ if (format != NULL) {
+ json_object_object_add (AFBResponse, "info" , json_object_new_string (message));
+ }
+ if (verbose) {
+ fprintf (stderr, "AFB:%-6s [%3d]: ", AFB_Error [level].label, count++);
+ if (format != NULL) {
+ fprintf (stderr, "%s", message);
+ } else {
+ fprintf (stderr, "No Message");
+ }
+ fprintf (stderr, "\n");
+ }
+
+ return (AFBResponse);
+}
+
+// Dump a message on stderr
+PUBLIC void jsonDumpObject (json_object * jObject) {
+
+ if (verbose) {
+ fprintf (stderr, "AFB:dump [%s]\n", json_object_to_json_string(jObject));
+ }
+}
+