diff --git a/README.md b/README.md index b546ca7..6f5ba63 100644 --- a/README.md +++ b/README.md @@ -300,6 +300,7 @@ We took a number of decisions for the design of the recorder and its utilities: As mentioned earlier, data is stored in files, and these files are relative to `STORAGEDIR` (compiled into the programs or specified as an option). In particular, the following directory structure can exist, whereby directories are created as needed by the _recorder_: * `cards/`, optional, contains user cards which are published when either you or one of your trackers on Hosted adds a new device. This card is then stored here and used with, e.g., `ocat --last` to show a user's name and optional avatar. +* `config/`, optional, contains the JSON of a [device configuration](http://owntracks.org/booklet/features/remoteconfig/) (`.otrc`) which was requested remotely via a [dump command](http://owntracks.org/booklet/tech/json/#_typecmd). Note that this will contain sensitive data. * `ghash/`, unless disabled, reverse Geo data is collected into an LMDB database located in this directory. * `last/` contains the last location published by devices. E.g. Jane's last publish from her iPhone would be in `last/jjolie/iphone/jjolie-iphone.json`. The JSON payload contained therein is enhanced with the fields `user`, `device`, `topic`, and `ghash`. * `monitor` a file which contains a timestamp and the last received topic (see Monitoring below). diff --git a/recorder.c b/recorder.c index 56360f5..b1595fa 100644 --- a/recorder.c +++ b/recorder.c @@ -322,6 +322,34 @@ static void putrec(struct udata *ud, time_t now, UT_string *reltopic, UT_string } } +/* + * Payload contains JSON string with a configuration obtained + * via cmd `dump' to the device. Store it. + */ + +void config_dump(struct udata *ud, UT_string *username, UT_string *device, char *payloadstring) +{ + static UT_string *ts = NULL; + + utstring_renew(ts); + + utstring_printf(ts, "%s/%s/%s/%s", + STORAGEDIR, + "config", + UB(username), + UB(device)); + if (mkpath(UB(ts)) < 0) { + olog(LOG_ERR, "Cannot mkdir %s: %m", UB(ts)); + return; + } + + utstring_printf(ts, "/%s-%s.otrc", UB(username), UB(device)); + if (ud->verbose) { + printf("Received configuration dump, storing at %s\n", UB(ts)); + } + safewrite(UB(ts), payloadstring); +} + /* * Payload contains JSON string with an array of waypoints. Dump * these into a single file. @@ -480,6 +508,7 @@ void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_m else if (!strcmp(j->string_, "transition")) _type = T_TRANSITION; 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_DUMP; } } @@ -500,6 +529,9 @@ void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_m case T_WAYPOINTS: waypoints_dump(ud, username, device, m->payload); goto cleanup; + case T_DUMP: + config_dump(ud, username, device, m->payload); + goto cleanup; case T_WAYPOINT: case T_TRANSITION: case T_LOCATION: diff --git a/storage.c b/storage.c index d36f06d..9d7da47 100644 --- a/storage.c +++ b/storage.c @@ -1059,6 +1059,15 @@ JsonNode *kill_datastore(char *user, char *device) olog(LOG_NOTICE, "removed %s", UB(path)); } + /* Remove config (.otrc) */ + utstring_renew(path); + utstring_printf(path, "%s/config/%s-%s.otrc", STORAGEDIR, user, device); + if (remove(UB(path)) == 0) { + olog(LOG_NOTICE, "removed %s", UB(path)); + json_append_member(obj, "otrc", json_mkstring(UB(path))); + } + + /* Remove waypoint files and containing directories */ utstring_renew(path); utstring_printf(path, "%s/waypoints/%s/%s/*.json", STORAGEDIR, user, device); diff --git a/storage.h b/storage.h index 3c3a269..c22d9ea 100644 --- a/storage.h +++ b/storage.h @@ -33,6 +33,7 @@ typedef enum { T_TRANSITION, T_WAYPOINT, T_WAYPOINTS, + T_DUMP, } payload_type; JsonNode *lister(char *username, char *device, time_t s_lo, time_t s_hi, int reverse);