rc: add option to get info for a single script in list method

Add option to get info for a single script in list method.

To get info of a particular script pass the name arg to the list method.

If the script doesn't exist an empty table is returned.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
Christian Marangi 2023-01-31 15:45:18 +01:00
parent 632b4fc898
commit d97883005f
No known key found for this signature in database
GPG key ID: AC001D09ADBFEAD7

15
rc.c
View file

@ -21,11 +21,13 @@
#define RC_LIST_EXEC_TIMEOUT_MS 3000 #define RC_LIST_EXEC_TIMEOUT_MS 3000
enum { enum {
RC_LIST_NAME,
RC_LIST_SKIP_RUNNING_CHECK, RC_LIST_SKIP_RUNNING_CHECK,
__RC_LIST_MAX __RC_LIST_MAX
}; };
static const struct blobmsg_policy rc_list_policy[] = { static const struct blobmsg_policy rc_list_policy[] = {
[RC_LIST_NAME] = { "name", BLOBMSG_TYPE_STRING },
[RC_LIST_SKIP_RUNNING_CHECK] = { "skip_running_check", BLOBMSG_TYPE_BOOL }, [RC_LIST_SKIP_RUNNING_CHECK] = { "skip_running_check", BLOBMSG_TYPE_BOOL },
}; };
@ -48,6 +50,7 @@ struct rc_list_context {
struct blob_buf *buf; struct blob_buf *buf;
DIR *dir; DIR *dir;
bool skip_running_check; bool skip_running_check;
const char *req_name;
/* Info about currently processed init.d entry */ /* Info about currently processed init.d entry */
struct { struct {
@ -181,7 +184,12 @@ static void rc_list_readdir(struct rc_list_context *c)
FILE *fp; FILE *fp;
e = readdir(c->dir); e = readdir(c->dir);
if (!e) { /*
* If scanning for a specific script and entry.d_name is set
* we can assume we found a matching one in the previous
* iteration since entry.d_name is set only if a match is found.
*/
if (!e || (c->req_name && c->entry.d_name)) {
closedir(c->dir); closedir(c->dir);
ubus_send_reply(c->ctx, &c->req, c->buf->head); ubus_send_reply(c->ctx, &c->req, c->buf->head);
ubus_complete_deferred_request(c->ctx, &c->req, UBUS_STATUS_OK); ubus_complete_deferred_request(c->ctx, &c->req, UBUS_STATUS_OK);
@ -191,6 +199,9 @@ static void rc_list_readdir(struct rc_list_context *c)
if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, ".."))
goto next; goto next;
if (c->req_name && strcmp(e->d_name, c->req_name))
goto next;
memset(&c->entry, 0, sizeof(c->entry)); memset(&c->entry, 0, sizeof(c->entry));
c->entry.start = -1; c->entry.start = -1;
c->entry.stop = -1; c->entry.stop = -1;
@ -271,6 +282,8 @@ static int rc_list(struct ubus_context *ctx, struct ubus_object *obj,
} }
if (tb[RC_LIST_SKIP_RUNNING_CHECK]) if (tb[RC_LIST_SKIP_RUNNING_CHECK])
c->skip_running_check = blobmsg_get_bool(tb[RC_LIST_SKIP_RUNNING_CHECK]); c->skip_running_check = blobmsg_get_bool(tb[RC_LIST_SKIP_RUNNING_CHECK]);
if (tb[RC_LIST_NAME])
c->req_name = blobmsg_get_string(tb[RC_LIST_NAME]);
ubus_defer_request(ctx, req, &c->req); ubus_defer_request(ctx, req, &c->req);