2 * luci-rpcd - LuCI UBUS RPC server
4 * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 static struct blob_buf buf
;
35 static const struct blobmsg_policy file_policy
[__RPC_F_MAX
] = {
36 [RPC_F_PATH
] = { .name
= "path", .type
= BLOBMSG_TYPE_STRING
},
37 [RPC_F_DATA
] = { .name
= "data", .type
= BLOBMSG_TYPE_STRING
},
40 static const char *d_types
[] = {
43 [DT_DIR
] = "directory",
48 [DT_UNKNOWN
] = "unknown",
53 rpc_errno_status(void)
58 return UBUS_STATUS_PERMISSION_DENIED
;
61 return UBUS_STATUS_INVALID_ARGUMENT
;
64 return UBUS_STATUS_NOT_FOUND
;
67 return UBUS_STATUS_INVALID_ARGUMENT
;
70 return UBUS_STATUS_UNKNOWN_ERROR
;
74 static struct blob_attr
**
75 rpc_check_path(struct blob_attr
*msg
, char **path
, struct stat
*s
)
77 static struct blob_attr
*tb
[__RPC_F_MAX
];
79 blobmsg_parse(file_policy
, __RPC_F_MAX
, tb
, blob_data(msg
), blob_len(msg
));
87 *path
= blobmsg_data(tb
[RPC_F_PATH
]);
96 rpc_handle_read(struct ubus_context
*ctx
, struct ubus_object
*obj
,
97 struct ubus_request_data
*req
, const char *method
,
98 struct blob_attr
*msg
)
102 char buffer
[RPC_FILE_MAX_SIZE
];
105 if (!rpc_check_path(msg
, &path
, &s
))
106 return rpc_errno_status();
108 if (s
.st_size
>= RPC_FILE_MAX_SIZE
)
109 return UBUS_STATUS_NOT_SUPPORTED
;
111 if ((fd
= open(path
, O_RDONLY
)) < 0)
112 return rpc_errno_status();
114 if ((rlen
= read(fd
, buffer
, RPC_FILE_MAX_SIZE
-1)) > 0)
120 return UBUS_STATUS_NO_DATA
;
122 blob_buf_init(&buf
, 0);
123 blobmsg_add_string(&buf
, "data", buffer
);
124 ubus_send_reply(ctx
, req
, buf
.head
);
130 rpc_handle_write(struct ubus_context
*ctx
, struct ubus_object
*obj
,
131 struct ubus_request_data
*req
, const char *method
,
132 struct blob_attr
*msg
)
137 struct blob_attr
**tb
;
139 if (!(tb
= rpc_check_path(msg
, &path
, &s
)))
140 return rpc_errno_status();
143 return UBUS_STATUS_INVALID_ARGUMENT
;
145 if ((fd
= open(path
, O_WRONLY
)) < 0)
146 return rpc_errno_status();
148 rv
= write(fd
, blobmsg_data(tb
[RPC_F_DATA
]), blobmsg_data_len(tb
[RPC_F_DATA
]));
153 return UBUS_STATUS_NO_DATA
;
159 rpc_handle_list(struct ubus_context
*ctx
, struct ubus_object
*obj
,
160 struct ubus_request_data
*req
, const char *method
,
161 struct blob_attr
*msg
)
169 if (!rpc_check_path(msg
, &path
, &s
))
170 return rpc_errno_status();
172 if ((fd
= opendir(path
)) == NULL
)
173 return rpc_errno_status();
175 blob_buf_init(&buf
, 0);
176 c
= blobmsg_open_array(&buf
, "entries");
178 while ((e
= readdir(fd
)) != NULL
)
180 if (!strcmp(e
->d_name
, ".") || !strcmp(e
->d_name
, ".."))
183 d
= blobmsg_open_table(&buf
, NULL
);
184 blobmsg_add_string(&buf
, "name", e
->d_name
);
185 blobmsg_add_string(&buf
, "type", d_types
[e
->d_type
]);
186 blobmsg_close_table(&buf
, d
);
189 blobmsg_close_array(&buf
, c
);
190 ubus_send_reply(ctx
, req
, buf
.head
);
196 rpc_handle_stat(struct ubus_context
*ctx
, struct ubus_object
*obj
,
197 struct ubus_request_data
*req
, const char *method
,
198 struct blob_attr
*msg
)
204 if (!rpc_check_path(msg
, &path
, &s
))
205 return rpc_errno_status();
207 blob_buf_init(&buf
, 0);
209 type
= S_ISREG(s
.st_mode
) ? DT_REG
:
210 S_ISDIR(s
.st_mode
) ? DT_DIR
:
211 S_ISCHR(s
.st_mode
) ? DT_CHR
:
212 S_ISBLK(s
.st_mode
) ? DT_BLK
:
213 S_ISFIFO(s
.st_mode
) ? DT_FIFO
:
214 S_ISLNK(s
.st_mode
) ? DT_LNK
:
215 S_ISSOCK(s
.st_mode
) ? DT_SOCK
:
218 blobmsg_add_string(&buf
, "path", path
);
219 blobmsg_add_string(&buf
, "type", d_types
[type
]);
220 blobmsg_add_u32(&buf
, "size", s
.st_size
);
221 blobmsg_add_u32(&buf
, "mode", s
.st_mode
);
222 blobmsg_add_u32(&buf
, "atime", s
.st_atime
);
223 blobmsg_add_u32(&buf
, "mtime", s
.st_mtime
);
224 blobmsg_add_u32(&buf
, "ctime", s
.st_ctime
);
225 blobmsg_add_u32(&buf
, "inode", s
.st_ino
);
226 blobmsg_add_u32(&buf
, "uid", s
.st_uid
);
227 blobmsg_add_u32(&buf
, "gid", s
.st_gid
);
229 ubus_send_reply(ctx
, req
, buf
.head
);
235 int rpc_file_api_init(struct ubus_context
*ctx
)
237 static const struct ubus_method file_methods
[] = {
238 UBUS_METHOD("read", rpc_handle_read
, file_policy
),
239 UBUS_METHOD("write", rpc_handle_write
, file_policy
),
240 UBUS_METHOD("list", rpc_handle_list
, file_policy
),
241 UBUS_METHOD("stat", rpc_handle_stat
, file_policy
),
244 static struct ubus_object_type file_type
=
245 UBUS_OBJECT_TYPE("luci-rpc-file", file_methods
);
247 static struct ubus_object obj
= {
250 .methods
= file_methods
,
251 .n_methods
= ARRAY_SIZE(file_methods
),
254 return ubus_add_object(ctx
, &obj
);