Select Git revision
options.c 9.57 KiB
/* xaaws - xAAL web interface
* Part of the 'xaaws' software
* (c) 2019 Christophe Lohr <christophe.lohr@imt-atlantique.fr>
*
* 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/>.
*/
#include "options.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <json-c/json.h>
#include <uuid/uuid.h>
#include <errno.h>
#include <xaal.h>
/* Parse cmdline */
void parse_cmdline(int argc, char **argv, options_t *opts) {
int opt;
bool arg_error = false;
while ( (opt = getopt(argc, argv, "a:p:h:s:u:c:idl:L:U:G:V:P:I:R:")) != -1) {
switch (opt) {
case 'a':
opts->addr = optarg;
break;
case 'p':
opts->port = optarg;
break;
case 'h':
opts->hops = atoi(optarg);
break;
case 's':
opts->passphrase = optarg;
break;
case 'u':
if ( uuid_parse(optarg, *(opts->uuid)) == -1 ) {
fprintf(stderr, "Warning: invalid uuid '%s'\n", optarg);
uuid_clear(*(opts->uuid));
}
break;
case 'c':
opts->conffile = optarg;
break;
case 'i':
opts->immutable = true;
break;
case 'd':
opts->daemon = true;
break;
case 'l':
opts->logfile = optarg;
break;
case 'L':
opts->lockfile = optarg;
break;
case 'U':
opts->uid = atoi(optarg);
break;
case 'G':
opts->gid = atoi(optarg);
break;
case 'V':
opts->verbose = atoi(optarg);
break;
case 'P':
opts->http_port = optarg;
break;
case 'I':
opts->http_iface = optarg;
break;
case 'R':
opts->resource_path = optarg;
break;
case 'B':
opts->dbfile = optarg;
break;
default: /* '?' */
arg_error = true;
}
}
if (optind < argc) {
fprintf(stderr, "Unknown argument %s\n", argv[optind]);
arg_error = true;
}
if (arg_error) {
fprintf(stderr, "Usage: %s [-a <addr>] [-p <port>] [-h <hops>] [-s <secret>]\n"
" [-c <conffile>] [-i] [-d] [-l <logfile>] [-L <lockfile>]\n"
" [-U <uid>] [-G <gid>] [-V <bitfield verbose flags>]\n"
" [-P <http port>] [-I <iface>] [-R <resource path>]\n"
" -a <addr> multicast IPv4 or IPv6 address of the xAAL bus\n"
" -p <port> UDP port of the xAAL bus\n"
" -s <secret> Secret passphrase\n"
" -h <hops> Hops limit for multicast packets\n"
" -u <uuid> xAAL address of the device; random by default\n"
" -c <conffile> Filename of the configuration file (json format)\n"
" Use 'xaaws.conf' by default\n"
" -i Immutable config file (do not re-write it)\n"
" -d Start as a daemon\n"
" -l <logfile> Filename to write errors; stderr by default\n"
" -L <lockfile> Filename to write pid and use as a lock\n"
" -U <uid> User id\n"
" -G <gid> Group id\n"
" -V <verbose> Number; Bitfield verbosity flags (see libwesockets.h)\n"
" -I <iface> Network interface to bind to\n"
" -R <path> Path to web resources (default ./web)\n"
" -B <db-file> Internal database file name\n"
, argv[0]);
exit(EXIT_FAILURE);
}
}
/* Read a config file (json format) */
void read_config(options_t *opts) {
json_object *jconf, *jaddr, *jport, *jhops, *jpassphrase, *juuid,
*jconffile, *jimmutable, *jlogfile, *jlockfile,
*juid, *jgid, *jverbose, *jhttpport, *jhttpiface,
*jresourcepath, *jdb, *jdaemon;
/* read file */
jconf = json_object_from_file(opts->conffile);
if (json_object_is_type(jconf, json_type_null)) {
fprintf(stderr, "Could not parse config file %s\n", opts->conffile);
return;
}
/* parse bus addr */
if (json_object_object_get_ex(jconf, "addr", &jaddr)
&& json_object_is_type(jaddr, json_type_string))
opts->addr = strdup(json_object_get_string(jaddr));
/* parse bus port */
if (json_object_object_get_ex(jconf, "port", &jport)
&& json_object_is_type(jport, json_type_string))
opts->port = strdup(json_object_get_string(jport));
/* parse bus hops */
if (json_object_object_get_ex(jconf, "hops", &jhops)
&& json_object_is_type(jhops, json_type_int))
opts->hops = json_object_get_int(jhops);
/* parse passphrase */
if (json_object_object_get_ex(jconf, "passphrase", &jpassphrase)
&& json_object_is_type(jpassphrase, json_type_string))
opts->passphrase = strdup(json_object_get_string(jpassphrase));
/* parse me xAAL address (uuid) */
if (json_object_object_get_ex(jconf, "uuid", &juuid)
&& json_object_is_type(juuid, json_type_string))
if ( uuid_parse(json_object_get_string(juuid), *(opts->uuid)) == -1 )
uuid_clear(*(opts->uuid));
/* parse config file name */
if (json_object_object_get_ex(jconf, "conffile", &jconffile)
&& json_object_is_type(jconffile, json_type_string))
opts->conffile = strdup(json_object_get_string(jconffile));
/* parse immutable flag */
if (json_object_object_get_ex(jconf, "immutable", &jimmutable)
&& json_object_is_type(jimmutable, json_type_boolean))
opts->immutable = json_object_get_boolean(jimmutable);
/* parse daemon flag */
if (json_object_object_get_ex(jconf, "daemon", &jdaemon)
&& json_object_is_type(jdaemon, json_type_boolean))
opts->daemon = json_object_get_boolean(jdaemon);
/* parse log file name */
if (json_object_object_get_ex(jconf, "logfile", &jlogfile)
&& json_object_is_type(jlogfile, json_type_string))
opts->logfile = strdup(json_object_get_string(jlogfile));
/* parse lock file name */
if (json_object_object_get_ex(jconf, "lockfile", &jlockfile)
&& json_object_is_type(jlockfile, json_type_string))
opts->lockfile = strdup(json_object_get_string(jlockfile));
/* parse user id */
if (json_object_object_get_ex(jconf, "uid", &juid)
&& json_object_is_type(juid, json_type_int))
opts->uid = json_object_get_int(juid);
/* parse group id */
if (json_object_object_get_ex(jconf, "gid", &jgid)
&& json_object_is_type(jgid, json_type_int))
opts->gid = json_object_get_int(jgid);
/* parse verbose */
if (json_object_object_get_ex(jconf, "verbose", &jverbose)
&& json_object_is_type(jverbose, json_type_int))
opts->verbose = json_object_get_int(jverbose);
/* parse http_port */
if (json_object_object_get_ex(jconf, "http_port", &jhttpport)
&& json_object_is_type(jhttpport, json_type_string))
opts->http_port = strdup(json_object_get_string(jhttpport));
/* parse http_iface */
if (json_object_object_get_ex(jconf, "http_iface", &jhttpiface)
&& json_object_is_type(jhttpiface, json_type_string))
opts->http_iface = strdup(json_object_get_string(jhttpiface));
/* parse resource_path */
if (json_object_object_get_ex(jconf, "resource_path", &jresourcepath)
&& json_object_is_type(jresourcepath, json_type_string))
opts->resource_path = strdup(json_object_get_string(jresourcepath));
/* parse db file name */
if (json_object_object_get_ex(jconf, "db", &jdb)
&& json_object_is_type(jdb, json_type_string))
opts->dbfile = strdup(json_object_get_string(jdb));
json_object_put(jconf);
}
/* Init the path of schemas cache */
void init_schemas_path(options_t *opts, const char *cache) {
opts->schemas = malloc( strlen(opts->resource_path) + strlen(cache) + 2);
sprintf(opts->schemas, "%s/%s", opts->resource_path, cache);
}
/* Re-write config file (json format) */
void write_config(options_t *opts) {
json_object *jconf;
char uuid[37];
if (opts->immutable)
return;
jconf = json_object_new_object();
json_object_object_add(jconf, "addr", json_object_new_string(opts->addr));
json_object_object_add(jconf, "port", json_object_new_string(opts->port));
json_object_object_add(jconf, "hops", json_object_new_int(opts->hops));
json_object_object_add(jconf, "passphrase", json_object_new_string(opts->passphrase));
uuid_unparse(*(opts->uuid), uuid);
json_object_object_add(jconf, "uuid", json_object_new_string(uuid));
json_object_object_add(jconf, "conffile", json_object_new_string(opts->conffile));
json_object_object_add(jconf, "immutable", json_object_new_boolean(opts->immutable));
json_object_object_add(jconf, "daemon", json_object_new_boolean(opts->daemon));
if (opts->logfile)
json_object_object_add(jconf, "logfile", json_object_new_string(opts->logfile));
if (opts->lockfile)
json_object_object_add(jconf, "lockfile", json_object_new_string(opts->lockfile));
json_object_object_add(jconf, "uid", json_object_new_int(opts->uid));
json_object_object_add(jconf, "gid", json_object_new_int(opts->gid));
json_object_object_add(jconf, "verbose", json_object_new_int(opts->verbose));
json_object_object_add(jconf, "http_port", json_object_new_string(opts->http_port));
if (opts->http_iface)
json_object_object_add(jconf, "http_iface", json_object_new_string(opts->http_iface));
json_object_object_add(jconf, "resource_path", json_object_new_string(opts->resource_path));
json_object_object_add(jconf, "db", json_object_new_string(opts->dbfile));
if (json_object_to_file_ext(opts->conffile, jconf, JSON_C_TO_STRING_PRETTY
| JSON_C_TO_STRING_SPACED) == -1)
fprintf(xAAL_error_log, "Writing config file: %s\n", strerror(errno));
json_object_put(jconf);
}