file: provide user name and group name lookups for stat listings master
authorPaul Donald <[email protected]>
Tue, 2 Dec 2025 23:34:52 +0000 (00:34 +0100)
committerRobert Marko <[email protected]>
Wed, 3 Dec 2025 21:48:31 +0000 (22:48 +0100)
This provides more user friendly information than numeric IDs.

Before this patch:

ubus call file list '{"path":"/proc"}'
...
{
"name": "kcore",
"type": "file",
"size": 140737471586304,
"mode": 33024,
"atime": 1764716086,
"mtime": 1764716086,
"ctime": 1764716086,
"inode": -268435271,
"uid": 0,
"gid": 0,
},
...

After this patch:

ubus call file list '{"path":"/proc"}'
...
{
"name": "kcore",
"type": "file",
"size": 140737471586304,
"mode": 33024,
"atime": 1764716086,
"mtime": 1764716086,
"ctime": 1764716086,
"inode": -268435271,
"uid": 0,
"gid": 0,
"user": "root",
"group": "root"
},
...

Tested on: OpenWrt SNAPSHOT r32139-1f879b8839 / 6.12.59
Signed-off-by: Paul Donald <[email protected]>
Link: https://github.com/openwrt/rpcd/pull/22
Signed-off-by: Robert Marko <[email protected]>
file.c

diff --git a/file.c b/file.c
index 591ab6bcfff327ebac3f59cfe889f7c8047a89cf..691249018af0322daf06689e2d7896e79da27b8b 100644 (file)
--- a/file.c
+++ b/file.c
@@ -19,6 +19,8 @@
 
 #define _GNU_SOURCE
 
+#include <pwd.h>
+#include <grp.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
@@ -470,6 +472,30 @@ rpc_file_md5(struct ubus_context *ctx, struct ubus_object *obj,
        return UBUS_STATUS_OK;
 }
 
+/* Add a string key only if value is non-NULL */
+static inline void
+blobmsg_add_string_safe(struct blob_buf *buf, const char *key, const char *val)
+{
+       if (val)
+               blobmsg_add_string(buf, key, val);
+}
+
+/* Look up username from UID */
+static const char *
+look_up_username(uid_t uid)
+{
+       struct passwd *pw = getpwuid(uid);
+       return pw ? pw->pw_name : NULL;
+}
+
+/* Look up group name from GID */
+static const char *
+look_up_groupname(gid_t gid)
+{
+       struct group *gr = getgrgid(gid);
+       return gr ? gr->gr_name : NULL;
+}
+
 static int
 _get_stat_type(struct stat *s)
 {
@@ -489,6 +515,9 @@ _get_stat_type(struct stat *s)
 static void
 _rpc_file_add_stat(struct stat *s)
 {
+       const char *user = look_up_username(s->st_uid);
+       const char *group = look_up_groupname(s->st_gid);
+
        blobmsg_add_string(&buf, "type", d_types[_get_stat_type(s)]);
        blobmsg_add_u64(&buf, "size",  s->st_size);
        blobmsg_add_u32(&buf, "mode",  s->st_mode);
@@ -498,6 +527,8 @@ _rpc_file_add_stat(struct stat *s)
        blobmsg_add_u32(&buf, "inode", s->st_ino);
        blobmsg_add_u32(&buf, "uid",   s->st_uid);
        blobmsg_add_u32(&buf, "gid",   s->st_gid);
+       blobmsg_add_string_safe(&buf, "user", user);
+       blobmsg_add_string_safe(&buf, "group", group);
 }
 
 static int