JsonNode *last_users(char *in_user, char *in_device) { 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) 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); return (userlist); }
static int user_device_list(char *name, int level, JsonNode *obj) { DIR *dirp; struct dirent *dp; char path[BUFSIZ]; JsonNode *devlist; int rc = 0; struct stat sb; if ((dirp = opendir(name)) == NULL) { perror(name); return (1); } while ((dp = readdir(dirp)) != NULL) { if (*dp->d_name != '.') { sprintf(path, "%s/%s", name, dp->d_name); if (stat(path, &sb) != 0) { continue; } if (!S_ISDIR(sb.st_mode)) continue; if (level == 0) { devlist = json_mkarray(); json_append_member(obj, dp->d_name, devlist); rc = user_device_list(path, level + 1, devlist); } else if (level == 1) { json_append_element(obj, json_mkstring(dp->d_name)); } } } closedir(dirp); return (rc); }
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); }