mirror of
https://github.com/owntracks/recorder.git
synced 2026-02-13 20:49:51 +00:00
experimental SHARES
This commit is contained in:
5
Makefile
5
Makefile
@@ -53,6 +53,11 @@ ifeq ($(WITH_HTTP),yes)
|
||||
OTR_EXTRA_OBJS += mongoose.o http.o
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_SHARES),yes)
|
||||
CFLAGS += -DWITH_SHARES
|
||||
OTR_EXTRA_OBJS +=
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_GREENWICH),yes)
|
||||
CFLAGS += -DWITH_GREENWICH=1
|
||||
endif
|
||||
|
||||
10
README.md
10
README.md
@@ -284,6 +284,7 @@ The following configuration settings may be applied (a `Y` in column `$` means a
|
||||
| `OTR_CLIENTID` | | hostname+pid | MQTT ClientID (override with -i)
|
||||
| `OTR_HTTPHOST` | Y | `localhost` | Address for the HTTP module to bind to
|
||||
| `OTR_HTTPPORT` | Y | `8083` | Port number of the HTTP module to bind to
|
||||
| `OTR_HTTPPREFIX` | Y | | Prefix of URL of this Recorder (e.g. `https://example.com/recorder/`
|
||||
| `OTR_HTTPLOGDIR` | | | Directory in which to store access.log. Override with --http-logdir
|
||||
| `OTR_LUASCRIPT` | | | Path to the Lua script
|
||||
| `OTR_PRECISION` | | `7` | Reverse-geo precision
|
||||
@@ -334,7 +335,7 @@ server {
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# OwnTracks Recorder Views
|
||||
# OwnTracks Recorder Views (requires /view, /static, /utils)
|
||||
location /owntracks/view/ {
|
||||
proxy_buffering off; # Chrome
|
||||
proxy_pass http://127.0.0.1:8083/view/;
|
||||
@@ -350,6 +351,13 @@ server {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
location /o/utils/ {
|
||||
proxy_pass http://127.0.0.1:8083/utils/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# HTTP Mode
|
||||
location /owntracks/pub {
|
||||
|
||||
@@ -39,6 +39,9 @@ WITH_MQTT ?= yes
|
||||
# Do you want recorder's built-in HTTP REST API?
|
||||
WITH_HTTP ?= yes
|
||||
|
||||
# Do you want recorder support for shared views? Requires WITH_HTTP
|
||||
WITH_SHARES ?= no
|
||||
|
||||
# Do you have Lua libraries installed and want the Lua hook integration?
|
||||
WITH_LUA ?= no
|
||||
|
||||
|
||||
15
http.c
15
http.c
@@ -618,7 +618,7 @@ static int dopublish(struct mg_connection *conn, const char *uri)
|
||||
char *enc;
|
||||
#endif
|
||||
static UT_string *topic = NULL, *userdevice = NULL;
|
||||
JsonNode *jarray;
|
||||
JsonNode *jarray, *jnode = NULL;
|
||||
#if WITH_LUA
|
||||
JsonNode *htobj;
|
||||
#endif
|
||||
@@ -643,11 +643,20 @@ static int dopublish(struct mg_connection *conn, const char *uri)
|
||||
|
||||
debug(ud, "HTTPPUB clen=%zu, topic=%s", conn->content_len, UB(topic));
|
||||
|
||||
handle_message(ud, UB(topic), payload, conn->content_len, 0, TRUE, FALSE);
|
||||
handle_message(ud, UB(topic), payload, conn->content_len, 0, TRUE, FALSE, &jnode);
|
||||
|
||||
|
||||
jarray = populate_friends(conn, u, d);
|
||||
extra_http_json(jarray, u, d);
|
||||
|
||||
if (jnode != NULL) {
|
||||
/*
|
||||
* Response data for share/shares is available; add it to
|
||||
* the outgoing JSON which will be returned to the HTTP
|
||||
* client.
|
||||
*/
|
||||
json_append_element(jarray, jnode);
|
||||
}
|
||||
#if WITH_LUA
|
||||
if ((htobj = hooks_http(ud, u, d, payload)) != NULL) {
|
||||
json_append_element(jarray, htobj);
|
||||
@@ -1565,7 +1574,7 @@ int ev_handler(struct mg_connection *conn, enum mg_event ev)
|
||||
|
||||
if ((js = json_stringify(obj, NULL)) != NULL) {
|
||||
fprintf(stderr, "Traccar: %s\n", js);
|
||||
handle_message(ud, UB(topic), js, strlen(js), 0, TRUE, FALSE);
|
||||
handle_message(ud, UB(topic), js, strlen(js), 0, TRUE, FALSE, NULL);
|
||||
free(js);
|
||||
}
|
||||
|
||||
|
||||
6
misc.c
6
misc.c
@@ -213,6 +213,12 @@ void get_defaults(char *filename, struct udata *ud)
|
||||
if (config_lookup_int(cf, "OTR_HTTPPORT", &ival) != CONFIG_FALSE) {
|
||||
ud->http_port = ival;
|
||||
}
|
||||
#ifdef WITH_SHARES
|
||||
if (config_lookup_string(cf, "OTR_HTTPPREFIX", &value) != CONFIG_FALSE) {
|
||||
if (ud->http_prefix) free(ud->http_prefix);
|
||||
ud->http_prefix = (value) ? strdup(value) : NULL;
|
||||
}
|
||||
# endif /* WITH_SHARES */
|
||||
if (config_lookup_string(cf, "OTR_HTTPLOGDIR", &value) != CONFIG_FALSE) {
|
||||
if (ud->http_logdir) free(ud->http_logdir);
|
||||
ud->http_logdir = (value) ? strdup(value) : NULL;
|
||||
|
||||
269
recorder.c
269
recorder.c
@@ -54,6 +54,7 @@
|
||||
# include <sodium.h>
|
||||
#endif
|
||||
#include "version.h"
|
||||
#include <dirent.h>
|
||||
|
||||
|
||||
#define SSL_VERIFY_PEER (1)
|
||||
@@ -135,6 +136,17 @@ int do_info(void *userdata, UT_string *username, UT_string *device, JsonNode *js
|
||||
}
|
||||
|
||||
#ifdef WITH_MQTT
|
||||
void publish(struct udata *userdata, char *topic, char *payload)
|
||||
{
|
||||
struct udata *ud = (struct udata *)userdata;
|
||||
int qos = 2;
|
||||
|
||||
// FIXME: what about HTTP ??
|
||||
|
||||
mosquitto_publish(ud->mosq, NULL, topic, strlen(payload), payload, qos, false);
|
||||
|
||||
}
|
||||
|
||||
void republish(struct mosquitto *mosq, struct udata *userdata, char *username, char *topic, double lat, double lon, char *cc, char *addr, long tst, char *t)
|
||||
{
|
||||
struct udata *ud = (struct udata *)userdata;
|
||||
@@ -374,6 +386,206 @@ void waypoints_dump(struct udata *ud, UT_string *username, UT_string *device, ch
|
||||
free(js);
|
||||
}
|
||||
|
||||
#ifdef WITH_SHARES
|
||||
static char *elem(JsonNode *json, char *e)
|
||||
{
|
||||
JsonNode *j;
|
||||
char *val = "-";
|
||||
|
||||
if ((j = json_find_member(json, e)) != NULL) {
|
||||
if (j->tag == JSON_STRING) {
|
||||
val = j->string_;
|
||||
}
|
||||
}
|
||||
return (val);
|
||||
}
|
||||
# endif /* WITH_SHARES */
|
||||
|
||||
#ifdef WITH_SHARES
|
||||
void do_request(struct udata *ud, UT_string *username, UT_string *device, char *payloadstring, bool httpmode, JsonNode **jnode)
|
||||
{
|
||||
JsonNode *json = json_decode(payloadstring), *j, *r, *resp;
|
||||
char *request_type = NULL, *js;
|
||||
static UT_string *url, *fulltopic;
|
||||
static int virgin = 1;
|
||||
static regex_t regex;
|
||||
int cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;
|
||||
|
||||
if (json == NULL)
|
||||
return;
|
||||
|
||||
utstring_renew(url);
|
||||
utstring_renew(fulltopic);
|
||||
|
||||
utstring_printf(fulltopic, "owntracks/%s/%s/cmd", UB(username), UB(device));
|
||||
|
||||
// 3d9d97d4-a27e-4cd1-842f-6bf51c18a5c2.json
|
||||
#define UUID_RE "^([[:alnum:]]{8})-([[:alnum:]]{4})-([[:alnum:]]{4})-([[:alnum:]]{4})-([[:alnum:]]{12})\\.json"
|
||||
|
||||
if (virgin) {
|
||||
virgin = !virgin;
|
||||
if (regcomp(®ex, UUID_RE, cflags)) {
|
||||
olog(LOG_ERR, "Cannot compile UUID RE");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((j = json_find_member(json, "request")) != NULL) {
|
||||
request_type = j->string_;
|
||||
}
|
||||
|
||||
if (strcmp(request_type, "share") == 0) {
|
||||
FILE *fp;
|
||||
char path[BUFSIZ];
|
||||
|
||||
if ((r = json_find_member(json, "share")) == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *uuid = uuid4();
|
||||
|
||||
utstring_printf(url, "%s/view/%s", ud->http_prefix, uuid);
|
||||
|
||||
JsonNode *o = json_mkobject();
|
||||
json_append_member(o, "page", json_mkstring("leafletmap.html"));
|
||||
json_append_member(o, "user", json_mkstring(UB(username)));
|
||||
json_append_member(o, "device", json_mkstring(UB(device)));
|
||||
json_append_member(o, "label", json_mkstring(elem(r, "label")));
|
||||
json_append_member(o, "zoom", json_mknumber(6));
|
||||
json_append_member(o, "from", json_mkstring(elem(r, "from")));
|
||||
json_append_member(o, "to", json_mkstring(elem(r, "to")));
|
||||
json_append_member(o, "uuid", json_mkstring(uuid));
|
||||
json_append_member(o, "url", json_mkstring(UB(url)));
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s.json", ud->viewsdir, uuid);
|
||||
|
||||
olog(LOG_DEBUG, "New share %s for %s/%s", uuid, UB(username), UB(device));
|
||||
|
||||
if ((fp = fopen(path, "w")) != NULL) {
|
||||
char *js = json_stringify(o, " ");
|
||||
fprintf(fp, "%s\n", js);
|
||||
free(js);
|
||||
fclose(fp);
|
||||
} else {
|
||||
olog(LOG_ERR, "Can't create at share %s: %m", path);
|
||||
json_delete(o);
|
||||
return;
|
||||
}
|
||||
|
||||
json_delete(o);
|
||||
|
||||
resp = json_mkobject();
|
||||
json_append_member(resp, "_type", json_mkstring("cmd"));
|
||||
json_append_member(resp, "action", json_mkstring("response"));
|
||||
json_append_member(resp, "request", json_mkstring("share"));
|
||||
json_append_member(resp, "status", json_mknumber(200));
|
||||
|
||||
JsonNode *nshare = json_mkobject();
|
||||
json_copy_to_object(nshare, r, false);
|
||||
json_append_member(nshare, "uuid", json_mkstring(uuid));
|
||||
json_append_member(nshare, "url", json_mkstring(UB(url)));
|
||||
|
||||
json_append_member(resp, "share", nshare);
|
||||
|
||||
if (httpmode) {
|
||||
*jnode = resp; // caller will delete `resp'
|
||||
return;
|
||||
}
|
||||
|
||||
if ((js = json_stringify(resp, " ")) != NULL) {
|
||||
publish(ud, UB(fulltopic), js);
|
||||
free(js);
|
||||
}
|
||||
json_delete(resp);
|
||||
|
||||
} else if (strcmp(request_type, "shares") == 0) {
|
||||
|
||||
//FILE *fp;
|
||||
JsonNode *arr, *o;
|
||||
char path[BUFSIZ];
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
int nomatch, nshare = 0;
|
||||
|
||||
resp = json_mkobject();
|
||||
json_append_member(resp, "_type", json_mkstring("cmd"));
|
||||
json_append_member(resp, "action", json_mkstring("response"));
|
||||
json_append_member(resp, "request", json_mkstring("shares"));
|
||||
|
||||
arr = json_mkarray();
|
||||
|
||||
if ((dirp = opendir(ud->viewsdir)) != NULL) {
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
char *fn = dp->d_name;
|
||||
|
||||
if (dp->d_type != DT_REG)
|
||||
continue;
|
||||
|
||||
nomatch = regexec(®ex, fn, 0, NULL, 0);
|
||||
if (nomatch)
|
||||
continue;
|
||||
|
||||
o = json_mkobject();
|
||||
snprintf(path, sizeof(path), "%s/%s", ud->viewsdir, fn);
|
||||
if (json_copy_from_file(o, path) == false) {
|
||||
olog(LOG_ERR, "Can't copy JSON from %s", path);
|
||||
json_delete(o);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(elem(o, "user"), UB(username)) != 0 ||
|
||||
strcmp(elem(o, "device"), UB(device)) != 0) {
|
||||
olog(LOG_DEBUG, "Skipping %s: owner mismatch", path);
|
||||
json_delete(o);
|
||||
continue;
|
||||
}
|
||||
|
||||
json_append_element(arr, o);
|
||||
++nshare;
|
||||
}
|
||||
closedir(dirp);
|
||||
} else {
|
||||
perror(ud->viewsdir);
|
||||
}
|
||||
|
||||
json_append_member(resp, "shares", arr);
|
||||
json_append_member(resp, "nshares", json_mknumber(nshare));
|
||||
|
||||
olog(LOG_DEBUG, "Returning nshares=%d for %s/%s", nshare, UB(username), UB(device));
|
||||
|
||||
if (httpmode) {
|
||||
*jnode = resp; // caller will delete `resp'
|
||||
return;
|
||||
}
|
||||
|
||||
if ((js = json_stringify(resp, " ")) != NULL) {
|
||||
publish(ud, UB(fulltopic), js);
|
||||
free(js);
|
||||
}
|
||||
|
||||
json_delete(resp);
|
||||
|
||||
} else if (strcmp(request_type, "unshare") == 0) {
|
||||
JsonNode *r;
|
||||
char path[BUFSIZ];
|
||||
|
||||
if ((r = json_find_member(json, "uuid")) == NULL) {
|
||||
fprintf(stderr, "No uuid in unshare request\n");
|
||||
return;
|
||||
}
|
||||
|
||||
olog(LOG_DEBUG, "Unshare %s for %s/%s", r->string_, UB(username), UB(device));
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s.json", ud->viewsdir, r->string_);
|
||||
if (access(path, R_OK) < 0) {
|
||||
olog(LOG_ERR, "Can't find share %s: %m", r->string_);
|
||||
}
|
||||
if (remove(path) != 0) {
|
||||
olog(LOG_ERR, "Can't delete share %s: %m", r->string_);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_SHARES */
|
||||
|
||||
#ifdef WITH_GREENWICH
|
||||
|
||||
/*
|
||||
@@ -512,7 +724,13 @@ unsigned char *decrypt(struct udata *ud, char *topic, char *p64, char *username,
|
||||
}
|
||||
#endif /* ENCRYPT */
|
||||
|
||||
void handle_message(void *userdata, char *topic, char *payload, size_t payloadlen, int retain, int httpmode, int was_encrypted)
|
||||
/*
|
||||
* if `jnode' will be set to a JsonNode object with results added to the
|
||||
* outgoing HTTP payload; the caller (in http.c) will delete the object
|
||||
* when it returns the payload to the client.
|
||||
*/
|
||||
|
||||
void handle_message(void *userdata, char *topic, char *payload, size_t payloadlen, int retain, int httpmode, int was_encrypted, JsonNode **jnode)
|
||||
{
|
||||
JsonNode *json, *j, *geo = NULL;
|
||||
char *tid = NULL, *t = NULL, *p;
|
||||
@@ -676,6 +894,9 @@ void handle_message(void *userdata, char *topic, char *payload, size_t payloadle
|
||||
else if (!strcmp(j->string_, "waypoint")) _type = T_WAYPOINT;
|
||||
else if (!strcmp(j->string_, "waypoints")) _type = T_WAYPOINTS;
|
||||
else if (!strcmp(j->string_, "dump")) _type = T_CONFIG;
|
||||
#ifdef WITH_SHARES
|
||||
else if (!strcmp(j->string_, "request")) _type = T_REQUEST;
|
||||
#endif /* WITH_SHARES */
|
||||
#if WITH_ENCRYPT
|
||||
else if (!strcmp(j->string_, "encrypted")) _type = T_ENCRYPTED;
|
||||
#endif /* WITH_ENCRYPT */
|
||||
@@ -744,7 +965,7 @@ void handle_message(void *userdata, char *topic, char *payload, size_t payloadle
|
||||
|
||||
cleartext = (char *)decrypt(ud, topic, j->string_, UB(username), UB(device));
|
||||
if (cleartext != NULL) {
|
||||
handle_message(ud, topic, cleartext, strlen(cleartext), retain, httpmode, TRUE);
|
||||
handle_message(ud, topic, cleartext, strlen(cleartext), retain, httpmode, TRUE, NULL);
|
||||
free(cleartext);
|
||||
}
|
||||
if (_typestr) free(_typestr);
|
||||
@@ -757,6 +978,12 @@ void handle_message(void *userdata, char *topic, char *payload, size_t payloadle
|
||||
return;
|
||||
break;
|
||||
#endif /* WITH_ENCRYPT */
|
||||
#ifdef WITH_SHARES
|
||||
case T_REQUEST:
|
||||
do_request(ud, username, device, payload, httpmode, jnode);
|
||||
goto cleanup;
|
||||
break;
|
||||
#endif /* WITH_SHARES */
|
||||
default:
|
||||
if (r_ok) {
|
||||
putrec(ud, now, reltopic, username, device, bindump(payload, payloadlen));
|
||||
@@ -882,9 +1109,9 @@ void handle_message(void *userdata, char *topic, char *payload, size_t payloadle
|
||||
#endif /* WITH_LUA */
|
||||
if ((geo = gcache_json_get(ud->gc, UB(ghash))) != NULL) {
|
||||
/* Habemus cached data */
|
||||
|
||||
|
||||
cached = TRUE;
|
||||
|
||||
|
||||
if ((j = json_find_member(geo, "cc")) != NULL) {
|
||||
utstring_printf(cc, "%s", j->string_);
|
||||
}
|
||||
@@ -898,10 +1125,10 @@ void handle_message(void *userdata, char *topic, char *payload, size_t payloadle
|
||||
} else {
|
||||
/* We didn't obtain reverse Geo, maybe because of over
|
||||
* quota; make a note of the missing geohash */
|
||||
|
||||
|
||||
char gfile[BUFSIZ];
|
||||
FILE *fp;
|
||||
|
||||
|
||||
snprintf(gfile, BUFSIZ, "%s/ghash/missing", STORAGEDIR);
|
||||
if ((fp = fopen(gfile, "a")) != NULL) {
|
||||
fprintf(fp, "%s %lf %lf\n", UB(ghash), lat, lon);
|
||||
@@ -1076,7 +1303,7 @@ void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_m
|
||||
{
|
||||
struct udata *ud = (struct udata *)userdata;
|
||||
|
||||
handle_message(ud, m->topic, m->payload, m->payloadlen, m->retain, FALSE, FALSE);
|
||||
handle_message(ud, m->topic, m->payload, m->payloadlen, m->retain, FALSE, FALSE, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1198,6 +1425,9 @@ int main(int argc, char **argv)
|
||||
#endif /* WITH_MQTT */
|
||||
#if WITH_HTTP
|
||||
UT_string *uviewsdir;
|
||||
# if WITH_SHARES
|
||||
UT_string *uhttp_prefix;
|
||||
# endif /* WITH_SHARES */
|
||||
#endif /* WITH_HTTP */
|
||||
char err[1024], *p;
|
||||
char *logfacility = "local0";
|
||||
@@ -1243,10 +1473,19 @@ int main(int argc, char **argv)
|
||||
udata.http_logdir = NULL;
|
||||
udata.browser_apikey = NULL;
|
||||
udata.viewsdir = NULL;
|
||||
#ifdef WITH_SHARES
|
||||
udata.http_prefix = NULL;
|
||||
# endif /* WITH_SHARES */
|
||||
|
||||
utstring_new(uviewsdir);
|
||||
utstring_printf(uviewsdir, "%s/views", DOCROOT);
|
||||
udata.viewsdir = strdup(UB(uviewsdir));
|
||||
|
||||
#ifdef WITH_SHARES
|
||||
utstring_new(uhttp_prefix);
|
||||
utstring_printf(uhttp_prefix, "%s", "http://localhost:8083");
|
||||
udata.http_prefix = strdup(UB(uhttp_prefix));
|
||||
# endif /* WITH_SHARES */
|
||||
#endif
|
||||
#ifdef WITH_LUA
|
||||
udata.luascript = NULL;
|
||||
@@ -1343,6 +1582,12 @@ int main(int argc, char **argv)
|
||||
if ((p = getenv("OTR_HTTPPORT")) != NULL) {
|
||||
ud->http_port = atoi(p);
|
||||
}
|
||||
|
||||
#ifdef WITH_SHARES
|
||||
if ((p = getenv("OTR_HTTPPREFIX")) != NULL) {
|
||||
udata.http_prefix = strdup(p);
|
||||
}
|
||||
# endif /* WITH_SHARES */
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
@@ -1773,11 +2018,16 @@ int main(int argc, char **argv)
|
||||
// mg_set_option(udata.mgserver, "cgi_pattern", "**.cgi");
|
||||
|
||||
addressinfo = mg_get_option(udata.mgserver, "listening_port");
|
||||
olog(LOG_INFO, "HTTP listener started on %s", addressinfo);
|
||||
olog(LOG_INFO, "HTTP listener started on %s, %s browser-apikey",
|
||||
addressinfo,
|
||||
ud->browser_apikey ? "with" : "without");
|
||||
if (addressinfo == NULL || *addressinfo == 0) {
|
||||
olog(LOG_ERR, "HTTP port is in use. Exiting.");
|
||||
exit(2);
|
||||
}
|
||||
#ifdef WITH_SHARES
|
||||
olog(LOG_INFO, "HTTP prefix is %s", ud->http_prefix);
|
||||
# endif /* WITH_SHARES */
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -1830,6 +2080,9 @@ int main(int argc, char **argv)
|
||||
free(ud->http_host);
|
||||
free(ud->browser_apikey);
|
||||
free(ud->viewsdir);
|
||||
# ifdef WITH_SHARES
|
||||
free(ud->http_prefix);
|
||||
# endif /* WITH_SHARES */
|
||||
if (ud->http_logdir) free(ud->http_logdir);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _RECORDER_H_INCL_
|
||||
# define _RECORDER_H_INCL_
|
||||
# include "json.h"
|
||||
|
||||
void handle_message(void *userdata, char *topic, char *payload, size_t payloadlen, int retain, int httpmode, int was_encrypted);
|
||||
void handle_message(void *userdata, char *topic, char *payload, size_t payloadlen, int retain, int httpmode, int was_encrypted, JsonNode **jnode);
|
||||
|
||||
#endif /* _RECORDER_H_INCL_ */
|
||||
|
||||
@@ -36,6 +36,9 @@ typedef enum {
|
||||
#if WITH_ENCRYPT
|
||||
T_ENCRYPTED,
|
||||
#endif
|
||||
#ifdef WITH_SHARES
|
||||
T_REQUEST,
|
||||
#endif
|
||||
} payload_type;
|
||||
|
||||
JsonNode *lister(char *username, char *device, time_t s_lo, time_t s_hi, int reverse);
|
||||
|
||||
3
udata.h
3
udata.h
@@ -42,6 +42,9 @@ struct udata {
|
||||
char *http_logdir; /* full path to http access log */
|
||||
char *browser_apikey; /* Google maps browser API key */
|
||||
char *viewsdir; /* path to views directory */
|
||||
# ifdef WITH_SHARES
|
||||
char *http_prefix; /* prefix URL to this Recorder */
|
||||
# endif /* SHARES */
|
||||
#endif
|
||||
#ifdef WITH_LUA
|
||||
char *luascript; /* Path to Lua script */
|
||||
|
||||
16
util.c
16
util.c
@@ -32,6 +32,9 @@
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
#ifdef WITH_SHARES
|
||||
# include <uuid/uuid.h>
|
||||
#endif
|
||||
#include "udata.h"
|
||||
|
||||
#ifndef LINESIZE
|
||||
@@ -627,3 +630,16 @@ double number(JsonNode *j, char *element)
|
||||
|
||||
return (NAN);
|
||||
}
|
||||
|
||||
#ifdef WITH_SHARES
|
||||
char *uuid4()
|
||||
{
|
||||
static char uustr[37];
|
||||
uuid_t uu;
|
||||
|
||||
uuid_generate(uu);
|
||||
uuid_unparse_lower(uu, uustr);
|
||||
|
||||
return (uustr);
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user