static void send_last(struct mg_connection *conn) { struct udata *ud = (struct udata *)conn->server_param; JsonNode *user_array, *o, *one; char *u = NULL, *d = NULL; u = field(conn, "user"); d = field(conn, "device"); if ((user_array = last_users(u, d)) != NULL) { if (u) free(u); if (d) free(d); json_foreach(one, user_array) { JsonNode *f; o = json_mkobject(); json_append_member(o, "_type", json_mkstring("location")); if ((f = json_find_member(one, "lat")) != NULL) json_copy_element_to_object(o, "lat", f); if ((f = json_find_member(one, "lon")) != NULL) json_copy_element_to_object(o, "lon", f); if ((f = json_find_member(one, "tst")) != NULL) json_copy_element_to_object(o, "tst", f); if ((f = json_find_member(one, "tid")) != NULL) json_copy_element_to_object(o, "tid", f); if ((f = json_find_member(one, "addr")) != NULL) json_copy_element_to_object(o, "addr", f); if ((f = json_find_member(one, "topic")) != NULL) json_copy_element_to_object(o, "topic", f); http_ws_push_json(ud->mgserver, o); json_delete(o); } json_delete(user_array); }
static int candidate_line(char *line, void *param) { long counter = 0L; JsonNode *j, *o; struct jparam *jarg = (struct jparam*)param; char *bp; JsonNode *obj = jarg->obj; JsonNode *locs = jarg->locs; int limit = jarg->limit; time_t s_lo = jarg->s_lo; time_t s_hi = jarg->s_hi; JsonNode *fields = jarg->fields; output_type otype = jarg->otype; if (obj == NULL || obj->tag != JSON_OBJECT) return (-1); if (locs == NULL || locs->tag != JSON_ARRAY) return (-1); if (limit == 0) { /* Reading forwards; account for time */ char *p; struct tm tmline; time_t secs; if ((p = strptime(line, "%Y-%m-%dT%H:%M:%SZ", &tmline)) == NULL) { fprintf(stderr, "no strptime on %s", line); return (0); } secs = mktime(&tmline); if (secs <= s_lo || secs >= s_hi) { return (0); } if (otype == RAW) { printf("%s\n", line); return (0); } else if (otype == RAWPAYLOAD) { char *bp; if ((bp = strchr(line, '{')) != NULL) { printf("%s\n", bp); } } } if (limit > 0 && otype == RAW) { printf("%s\n", line); return (1); /* make it 'count' or tac() will not decrement line counter and continue until EOF */ } /* Do we have location line? */ if ((bp = strstr(line, "Z\t* ")) == NULL) { /* Not a location line */ return (0); } if ((bp = strrchr(bp, '\t')) == NULL) { return (0); } /* Initialize our counter to what the JSON obj currently has */ if ((j = json_find_member(obj, "count")) != NULL) { counter = j->number_; json_delete(j); } // fprintf(stderr, "-->[%s]\n", line); if ((o = line_to_location(line)) != NULL) { if (fields) { /* Create a new object, copying members we're interested in into it */ JsonNode *f, *node; JsonNode *newo = json_mkobject(); json_foreach(f, fields) { char *key = f->string_; if ((node = json_find_member(o, key)) != NULL) { json_copy_element_to_object(newo, key, node); } } json_delete(o); o = newo; } json_append_element(locs, o); ++counter; }
JsonNode *last_users(char *in_user, char *in_device, JsonNode *fields) { JsonNode *obj = json_mkobject(); JsonNode *un, *dn, *userlist = json_mkarray(); char path[BUFSIZ], user[BUFSIZ], device[BUFSIZ]; snprintf(path, BUFSIZ, "%s/last", STORAGEDIR); // fprintf(stderr, "last_users(%s, %s)\n", (in_user) ? in_user : "******", // (in_device) ? in_device : "<nil>"); if (user_device_list(path, 0, obj) == 1) { json_delete(userlist); return (obj); } /* Loop through users, devices */ json_foreach(un, obj) { if (un->tag != JSON_ARRAY) continue; strcpy(user, un->key); json_foreach(dn, un) { if (dn->tag == JSON_STRING) { strcpy(device, dn->string_); } else if (dn->tag == JSON_NUMBER) { /* all digits? */ sprintf(device, "%.lf", dn->number_); } if (!in_user && !in_device) { append_device_details(userlist, user, device); } else if (in_user && !in_device) { if (strcmp(user, in_user) == 0) { append_device_details(userlist, user, device); } } else if (in_user && in_device) { if (strcmp(user, in_user) == 0 && strcmp(device, in_device) == 0) { append_device_details(userlist, user, device); } } } } json_delete(obj); /* * userlist now is an array of user objects. If fields were * specified, re-create that array with object which have * only the requested fields. It's a shame we have to re-do * this here, but I can't think of an alternative way at * the moment. */ if (fields) { JsonNode *new_userlist = json_mkarray(), *user; json_foreach(user, userlist) { JsonNode *o = json_mkobject(), *f, *j; json_foreach(f, fields) { char *field_name = f->string_; if ((j = json_find_member(user, field_name)) != NULL) { json_copy_element_to_object(o, field_name, j); } } json_append_element(new_userlist, o); }