X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=rc.c;h=3d192f17a587115b81eeb3b5604d4322cdb5ead7;hb=HEAD;hp=35b47e9cd5c415d5bbfa408cbef71e647700f792;hpb=5577db9208e179e18cfe2e5e8376d58fd9111140;p=project%2Frpcd.git diff --git a/rc.c b/rc.c index 35b47e9..3d192f1 100644 --- a/rc.c +++ b/rc.c @@ -20,6 +20,17 @@ #define RC_LIST_EXEC_TIMEOUT_MS 3000 +enum { + RC_LIST_NAME, + RC_LIST_SKIP_RUNNING_CHECK, + __RC_LIST_MAX +}; + +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 }, +}; + enum { RC_INIT_NAME, RC_INIT_ACTION, @@ -38,6 +49,8 @@ struct rc_list_context { struct ubus_request_data req; struct blob_buf *buf; DIR *dir; + bool skip_running_check; + const char *req_name; /* Info about currently processed init.d entry */ struct { @@ -82,7 +95,7 @@ static void rc_list_add_table(struct rc_list_context *c) if (c->entry.stop >= 0) blobmsg_add_u16(c->buf, "stop", c->entry.stop); blobmsg_add_u8(c->buf, "enabled", c->entry.enabled); - if (c->entry.use_procd) + if (!c->skip_running_check && c->entry.use_procd) blobmsg_add_u8(c->buf, "running", c->entry.running); blobmsg_close_table(c->buf, e); @@ -114,6 +127,9 @@ static int rc_list_exec(struct rc_list_context *c, const char *action, uloop_pro case -1: return -errno; case 0: + if (c->skip_running_check) + exit(-EFAULT); + if (!c->entry.use_procd) exit(-EOPNOTSUPP); @@ -168,7 +184,12 @@ static void rc_list_readdir(struct rc_list_context *c) FILE *fp; 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); ubus_send_reply(c->ctx, &c->req, c->buf->head); ubus_complete_deferred_request(c->ctx, &c->req, UBUS_STATUS_OK); @@ -178,6 +199,9 @@ static void rc_list_readdir(struct rc_list_context *c) if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) goto next; + if (c->req_name && strcmp(e->d_name, c->req_name)) + goto next; + memset(&c->entry, 0, sizeof(c->entry)); c->entry.start = -1; c->entry.stop = -1; @@ -197,7 +221,8 @@ static void rc_list_readdir(struct rc_list_context *c) int count = 0; beginning = true; - while ((c->entry.start < 0 || c->entry.stop < 0 || !c->entry.use_procd) && + while ((c->entry.start < 0 || c->entry.stop < 0 || + (!c->skip_running_check && !c->entry.use_procd)) && count <= 10 && fgets(line, sizeof(line), fp)) { if (beginning) { if (!strncmp(line, "START=", 6)) { @@ -236,9 +261,12 @@ static int rc_list(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { + struct blob_attr *tb[__RC_LIST_MAX]; static struct blob_buf buf; struct rc_list_context *c; + blobmsg_parse(rc_list_policy, __RC_LIST_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg)); + blob_buf_init(&buf, 0); c = calloc(1, sizeof(*c)); @@ -252,6 +280,10 @@ static int rc_list(struct ubus_context *ctx, struct ubus_object *obj, free(c); return UBUS_STATUS_UNKNOWN_ERROR; } + if (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); @@ -359,7 +391,7 @@ static int rc_init(struct ubus_context *ctx, struct ubus_object *obj, int rpc_rc_api_init(struct ubus_context *ctx) { static const struct ubus_method rc_methods[] = { - UBUS_METHOD_NOARG("list", rc_list), + UBUS_METHOD("list", rc_list, rc_list_policy), UBUS_METHOD("init", rc_init, rc_init_policy), };