mirror of
https://github.com/owntracks/recorder.git
synced 2026-08-27 16:57:21 +00:00
Support most config options in defaults file
This commit is contained in:
@@ -369,6 +369,33 @@ As mentioned earlier, data is stored in files, and these files are relative to `
|
||||
|
||||
You should definitely **not** modify or touch these files: they remain under the control of the _recorder_. You can of course, remove old `.rec` files if they consume too much space.
|
||||
|
||||
## Configuration file
|
||||
|
||||
The recorder attempts to read its startup configuration from a configuration file; the path to this is compiled into the Recorder (typically `/etc/defaults/ot-recorder`). The format of this file approximates that of a shell script with variables to be exported (the intention is so that it can be sourced by a shell script). Lines beginning with an octothorp (`#`) are ignored as are blank lines. Configuration settings proper are set as follows (note that some older versions of _libconfig_ require a trailing semicolon (`;`) on assignment:
|
||||
|
||||
```
|
||||
OTR_STORAGEDIR="/var/spool/owntracks/recorder/store"
|
||||
```
|
||||
|
||||
The following configuration settings may be applied (a `Y` in column `$` means an environment variable of the same name overrides a setting in the config file):
|
||||
|
||||
| Variable | $ | Default | Usage
|
||||
| --------------------- | :--- | :------------ | ---------------
|
||||
| `OTR_STORAGEDIR` | Y | compiled in | Pathname to the storage directory
|
||||
| `OTR_HOST` | Y | `localhost` | MQTT hostname/address to connect to
|
||||
| `OTR_PORT` | Y | `1883` | MQTT port number to connect to
|
||||
| `OTR_USER` | Y | | MQTT username
|
||||
| `OTR_PASS` | Y | | MQTT password
|
||||
| `OTR_QOS` | | `2` | MQTT QoS
|
||||
| `OTR_HTTPHOST` | | `localhost` | Address for the HTTP module to bind to
|
||||
| `OTR_HTTPPORT` | | `8083` | Port number of the HTTP module to bind to
|
||||
| `OTR_LUASCRIPT` | | | Path to the Lua script
|
||||
| `OTR_PRECISION` | | `7` | Reverse-geo precision
|
||||
| `OTR_GEOKEY` | | | API key for reverse-geo lookups
|
||||
| `OTR_TOPICS` | | | String containing a space-separated list of topics to subscribe to for MQTT (overrides command-line arguments)
|
||||
|
||||
Note that options passed to `ot-recorder` override both configuration file settings and environment variables.
|
||||
|
||||
|
||||
## Reverse Geo
|
||||
|
||||
@@ -625,7 +652,8 @@ After running `otr_hook()`, the _recorder_ attempts to invoke a Lua function for
|
||||
|
||||
You define a hooklet function only if you're interested in expressly triggering on a particular JSON element.
|
||||
|
||||
#### Environment
|
||||
|
||||
### Environment
|
||||
|
||||
The following environment variables control _ocat_'s behaviour:
|
||||
|
||||
|
||||
@@ -4,4 +4,69 @@
|
||||
# and its associated utilities to override compiled-in defaults.
|
||||
# *** In libconfig versions < 1.4 a trailing semicolon is mandatory
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Storage directory
|
||||
#
|
||||
|
||||
# OTR_STORAGEDIR = "/var/spool/owntracks/recorder/store"
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Address or hostname of the MQTT broker
|
||||
#
|
||||
|
||||
# OTR_HOST="localhost"
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Port number of the MQTT broker
|
||||
#
|
||||
|
||||
# OTR_PORT=1883
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Username for the MQTT connection
|
||||
#
|
||||
|
||||
# OTR_USER=""
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Password for the MQTT connection
|
||||
#
|
||||
|
||||
# OTR_PASS=""
|
||||
|
||||
# -----------------------------------------------------
|
||||
# QoS for MQTT connection
|
||||
#
|
||||
|
||||
# OTR_QOS=2
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Address for the HTTP module to bind to (default: localhost)
|
||||
#
|
||||
|
||||
# OTR_HTTPHOST="localhost"
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Port number for the HTTP module to bind to (default: 8083)
|
||||
#
|
||||
|
||||
# OTR_HTTPPORT=8083
|
||||
|
||||
# -----------------------------------------------------
|
||||
# API key for reverse-geo lookups
|
||||
#
|
||||
|
||||
# OTR_GEOKEY=""
|
||||
|
||||
# -----------------------------------------------------
|
||||
# Reverse geo precision
|
||||
#
|
||||
|
||||
# OTR_PRECISION=7
|
||||
|
||||
# -----------------------------------------------------
|
||||
# List of topics for MQTT to subscribe to, blank separated in a string
|
||||
#
|
||||
|
||||
# OTR_TOPICS="owntracks/+/+"
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ void get_defaults(char *filename, struct udata *ud)
|
||||
{
|
||||
config_t cfg, *cf;
|
||||
const char *value;
|
||||
int ival;
|
||||
|
||||
if (access(filename, R_OK) == -1)
|
||||
return;
|
||||
@@ -118,6 +119,71 @@ void get_defaults(char *filename, struct udata *ud)
|
||||
|
||||
if (config_lookup_string(cf, "OTR_STORAGEDIR", &value) != CONFIG_FALSE)
|
||||
strcpy(STORAGEDIR, value);
|
||||
#if WITH_MQTT
|
||||
if (config_lookup_string(cf, "OTR_HOST", &value) != CONFIG_FALSE) {
|
||||
if (ud->hostname) free(ud->hostname);
|
||||
ud->hostname = strdup(value);
|
||||
}
|
||||
if (config_lookup_int(cf, "OTR_PORT", &ival) != CONFIG_FALSE) {
|
||||
ud->port = ival;
|
||||
}
|
||||
if (config_lookup_string(cf, "OTR_USER", &value) != CONFIG_FALSE) {
|
||||
if (ud->username) free(ud->username);
|
||||
ud->username = strdup(value);
|
||||
}
|
||||
if (config_lookup_string(cf, "OTR_PASS", &value) != CONFIG_FALSE) {
|
||||
if (ud->password) free(ud->password);
|
||||
ud->password = strdup(value);
|
||||
}
|
||||
if (config_lookup_int(cf, "OTR_QOS", &ival) != CONFIG_FALSE) {
|
||||
ud->qos = ival;
|
||||
}
|
||||
|
||||
/* Topics is a blank-separated string of words; split and add to JSON array */
|
||||
if (config_lookup_string(cf, "OTR_TOPICS", &value) != CONFIG_FALSE) {
|
||||
char *parts[40];
|
||||
int np, n;
|
||||
if (ud->topics) json_delete(ud->topics);
|
||||
|
||||
if ((np = splitter((char *)value, " ", parts)) < 1) {
|
||||
olog(LOG_ERR, "Illegal value in OTR_TOPICS");
|
||||
exit(2);
|
||||
}
|
||||
ud->topics = json_mkarray();
|
||||
|
||||
for (n = 0; n < np; n++) {
|
||||
json_append_element(ud->topics, json_mkstring(parts[n]));
|
||||
}
|
||||
splitterfree(parts);
|
||||
}
|
||||
#endif /* WITH_MQTT */
|
||||
|
||||
if (config_lookup_string(cf, "OTR_GEOKEY", &value) != CONFIG_FALSE) {
|
||||
if (ud->geokey) free(ud->geokey);
|
||||
ud->geokey = strdup(value);
|
||||
}
|
||||
|
||||
if (config_lookup_int(cf, "OTR_PRECISION", &ival) != CONFIG_FALSE) {
|
||||
geohash_setprec(ival);
|
||||
printf("PREC=%d\n", geohash_prec());
|
||||
}
|
||||
|
||||
#if WITH_HTTP
|
||||
if (config_lookup_string(cf, "OTR_HTTPHOST", &value) != CONFIG_FALSE) {
|
||||
if (ud->http_host) free(ud->http_host);
|
||||
ud->http_host = strdup(value);
|
||||
}
|
||||
if (config_lookup_int(cf, "OTR_HTTPPORT", &ival) != CONFIG_FALSE) {
|
||||
ud->http_port = ival;
|
||||
}
|
||||
#endif /* WITH_HTTP */
|
||||
|
||||
#if WITH_LUA
|
||||
if (config_lookup_string(cf, "OTR_LUASCRIPT", &value) != CONFIG_FALSE) {
|
||||
if (ud->luascript) free(ud->luascript);
|
||||
ud->luascript = strdup(value);
|
||||
}
|
||||
#endif
|
||||
|
||||
config_destroy(cf);
|
||||
}
|
||||
|
||||
+50
-43
@@ -1112,33 +1112,31 @@ int main(int argc, char **argv)
|
||||
{
|
||||
#if WITH_MQTT
|
||||
struct mosquitto *mosq = NULL;
|
||||
char *username, *password, *cafile;
|
||||
char *hostname = strdup("localhost");
|
||||
int port = 1883;
|
||||
char *cafile;
|
||||
UT_string *clientid;
|
||||
int rc, i;
|
||||
struct utsname uts;
|
||||
#endif /* WITH_MQTT */
|
||||
char err[1024], *p;
|
||||
char *logfacility = "local0";
|
||||
#ifdef WITH_LUA
|
||||
char *luascript = NULL;
|
||||
#endif
|
||||
#if WITH_MQTT
|
||||
int loop_timeout = 1000;
|
||||
#endif
|
||||
int ch, initialize = FALSE;
|
||||
static struct udata udata, *ud = &udata;
|
||||
#ifdef WITH_HTTP
|
||||
int http_port = 8083;
|
||||
char *doc_root = DOCROOT;
|
||||
char *http_host = strdup("localhost");
|
||||
#endif
|
||||
char *progname = *argv;
|
||||
|
||||
#if WITH_MQTT
|
||||
udata.qos = DEFAULT_QOS;
|
||||
udata.pubprefix = NULL;
|
||||
udata.username = NULL;
|
||||
udata.password = NULL;
|
||||
udata.hostname = strdup("localhost");
|
||||
udata.port = 1883;
|
||||
udata.topics = NULL;
|
||||
#endif
|
||||
udata.ignoreretained = TRUE;
|
||||
udata.skipdemo = TRUE;
|
||||
@@ -1149,8 +1147,11 @@ int main(int argc, char **argv)
|
||||
udata.t2t = NULL; /* Topic to TID */
|
||||
#ifdef WITH_HTTP
|
||||
udata.mgserver = NULL;
|
||||
udata.http_host = strdup("localhost");
|
||||
udata.http_port = 8083;
|
||||
#endif
|
||||
#ifdef WITH_LUA
|
||||
udata.luascript = NULL;
|
||||
udata.luadata = NULL;
|
||||
udata.luadb = NULL;
|
||||
#endif /* WITH_LUA */
|
||||
@@ -1162,13 +1163,14 @@ int main(int argc, char **argv)
|
||||
|
||||
get_defaults(CONFIGFILE, &udata);
|
||||
|
||||
|
||||
#if WITH_MQTT
|
||||
if ((p = getenv("OTR_HOST")) != NULL) {
|
||||
hostname = strdup(p);
|
||||
ud->hostname = strdup(p);
|
||||
}
|
||||
|
||||
if ((p = getenv("OTR_PORT")) != NULL) {
|
||||
port = atoi(p);
|
||||
ud->port = atoi(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1177,6 +1179,9 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
#if WITH_MQTT
|
||||
ud->username = getenv("OTR_USER");
|
||||
ud->password = getenv("OTR_PASS");
|
||||
|
||||
utstring_new(clientid);
|
||||
utstring_printf(clientid, "ot-recorder");
|
||||
if (uname(&uts) == 0) {
|
||||
@@ -1228,6 +1233,7 @@ int main(int argc, char **argv)
|
||||
udata.debug = TRUE;
|
||||
break;
|
||||
case 12:
|
||||
if (udata.geokey) free(udata.geokey);
|
||||
udata.geokey = strdup(optarg);
|
||||
break;
|
||||
case 11:
|
||||
@@ -1245,7 +1251,8 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
#ifdef WITH_LUA
|
||||
case 7:
|
||||
luascript = strdup(optarg);
|
||||
if (ud->luascript) free(ud->luascript);
|
||||
ud->luascript = strdup(optarg);
|
||||
break;
|
||||
#endif
|
||||
#ifdef WITH_MQTT
|
||||
@@ -1267,11 +1274,11 @@ int main(int argc, char **argv)
|
||||
ud->ignoreretained = FALSE;
|
||||
break;
|
||||
case 'H':
|
||||
free(hostname);
|
||||
hostname = strdup(optarg);
|
||||
free(ud->hostname);
|
||||
ud->hostname = strdup(optarg);
|
||||
break;
|
||||
case 'p':
|
||||
port = atoi(optarg);
|
||||
ud->port = atoi(optarg);
|
||||
break;
|
||||
#endif /* WITH_MQTT */
|
||||
case 5:
|
||||
@@ -1282,14 +1289,14 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
#ifdef WITH_HTTP
|
||||
case 'A': /* API */
|
||||
http_port = atoi(optarg);
|
||||
ud->http_port = atoi(optarg);
|
||||
break;
|
||||
case 2: /* no short char */
|
||||
doc_root = strdup(optarg);
|
||||
break;
|
||||
case 3: /* no short char */
|
||||
free(http_host);
|
||||
http_host = strdup(optarg);
|
||||
free(ud->http_host);
|
||||
ud->http_host = strdup(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'D':
|
||||
@@ -1369,19 +1376,27 @@ int main(int argc, char **argv)
|
||||
argv += (optind);
|
||||
|
||||
#ifdef WITH_MQTT
|
||||
if (argc < 1) {
|
||||
if (ud->topics == NULL && argc < 1) { /* no topics set via config file */
|
||||
usage(progname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Push list of topics into the array so that we can (re)subscribe
|
||||
* in on_connect()
|
||||
*/
|
||||
|
||||
if (ud->topics == NULL) {
|
||||
ud->topics = json_mkarray();
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
json_append_element(ud->topics, json_mkstring(argv[i]));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MQTT
|
||||
username = getenv("OTR_USER");
|
||||
password = getenv("OTR_PASS");
|
||||
#endif /* WITH_MQTT */
|
||||
|
||||
#ifdef WITH_HTTP
|
||||
if (http_port) {
|
||||
if (ud->http_port) {
|
||||
if (!is_directory(doc_root)) {
|
||||
olog(LOG_ERR, "%s is not a directory", doc_root);
|
||||
exit(1);
|
||||
@@ -1423,9 +1438,9 @@ int main(int argc, char **argv)
|
||||
* If option for lua-script has not been given, ignore all hooks.
|
||||
*/
|
||||
|
||||
if (luascript) {
|
||||
if ((udata.luadata = hooks_init(ud, luascript)) == NULL) {
|
||||
olog(LOG_ERR, "Stopping because Lua load failed");
|
||||
if (ud->luascript) {
|
||||
if ((udata.luadata = hooks_init(ud, ud->luascript)) == NULL) {
|
||||
olog(LOG_ERR, "Stopping because loading of Lua script %s failed", ud->luascript);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
@@ -1451,14 +1466,6 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pushing list of topics into the array so that we can (re)subscribe on_connect()
|
||||
*/
|
||||
|
||||
ud->topics = json_mkarray();
|
||||
for (i = 0; i < argc; i++) {
|
||||
json_append_element(ud->topics, json_mkstring(argv[i]));
|
||||
}
|
||||
|
||||
mosquitto_reconnect_delay_set(mosq,
|
||||
2, /* delay */
|
||||
@@ -1469,8 +1476,8 @@ int main(int argc, char **argv)
|
||||
mosquitto_connect_callback_set(mosq, on_connect);
|
||||
mosquitto_disconnect_callback_set(mosq, on_disconnect);
|
||||
|
||||
if (username && password) {
|
||||
mosquitto_username_pw_set(mosq, username, password);
|
||||
if (ud->username && ud->password) {
|
||||
mosquitto_username_pw_set(mosq, ud->username, ud->password);
|
||||
}
|
||||
|
||||
cafile = getenv("OTR_CAFILE");
|
||||
@@ -1499,11 +1506,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
olog(LOG_INFO, "connecting to MQTT on %s:%d as clientID %s %s TLS",
|
||||
hostname, port,
|
||||
ud->hostname, ud->port,
|
||||
UB(clientid),
|
||||
(cafile) ? "with" : "without");
|
||||
|
||||
rc = mosquitto_connect(mosq, hostname, port, 60);
|
||||
rc = mosquitto_connect(mosq, ud->hostname, ud->port, 60);
|
||||
if (rc) {
|
||||
if (rc == MOSQ_ERR_ERRNO) {
|
||||
strerror_r(errno, err, 1024);
|
||||
@@ -1518,11 +1525,11 @@ int main(int argc, char **argv)
|
||||
#endif /* WITH_MQTT */
|
||||
|
||||
#ifdef WITH_HTTP
|
||||
if (http_port) {
|
||||
if (ud->http_port) {
|
||||
char address[BUFSIZ];
|
||||
const char *addressinfo;
|
||||
|
||||
sprintf(address, "%s:%d", http_host, http_port);
|
||||
sprintf(address, "%s:%d", ud->http_host, ud->http_port);
|
||||
|
||||
mg_set_option(udata.mgserver, "listening_port", address);
|
||||
// mg_set_option(udata.mgserver, "listening_port", "8090,ssl://8091:cert.pem");
|
||||
@@ -1583,6 +1590,7 @@ int main(int argc, char **argv)
|
||||
|
||||
#ifdef WITH_HTTP
|
||||
mg_destroy_server(&udata.mgserver);
|
||||
free(ud->http_host);
|
||||
#endif
|
||||
|
||||
#if WITH_LUA
|
||||
@@ -1596,9 +1604,8 @@ int main(int argc, char **argv)
|
||||
|
||||
mosquitto_destroy(mosq);
|
||||
mosquitto_lib_cleanup();
|
||||
free(hostname);
|
||||
free(ud->hostname);
|
||||
#endif
|
||||
free(http_host);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ struct udata {
|
||||
#if WITH_MQTT
|
||||
char *pubprefix; /* If not NULL (default), republish modified payload to <pubprefix>/topic */
|
||||
int qos; /* Subscribe QoS */
|
||||
char *hostname; /* MQTT broker */
|
||||
int port; /* MQTT port */
|
||||
char *username; /* MQTT user */
|
||||
char *password; /* MQTT password */
|
||||
#endif
|
||||
int skipdemo; /* True if _demo users are to be skipped */
|
||||
int revgeo; /* True (default) if we should do reverse Geo lookups */
|
||||
@@ -24,8 +28,11 @@ struct udata {
|
||||
struct gcache *t2t; /* topic to tid */
|
||||
#ifdef WITH_HTTP
|
||||
struct mg_server *mgserver; /* Mongoose */
|
||||
char *http_host; /* address of http bind */
|
||||
int http_port; /* port number for above */
|
||||
#endif
|
||||
#ifdef WITH_LUA
|
||||
char *luascript; /* Path to Lua script */
|
||||
struct luadata *luadata; /* Lua stuff */
|
||||
struct gcache *luadb; /* lmdb named database 'luadb' */
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user