file: add remove operation
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
604db20aa6
commit
345363bf47
1 changed files with 88 additions and 6 deletions
82
file.c
82
file.c
|
@ -577,6 +577,87 @@ rpc_file_stat(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rpc_file_remove_recursive(const char *path);
|
||||||
|
|
||||||
|
static int
|
||||||
|
rpc_file_remove_recursive(const char *path)
|
||||||
|
{
|
||||||
|
DIR *fd;
|
||||||
|
int err = 0;
|
||||||
|
struct stat s;
|
||||||
|
struct dirent *e;
|
||||||
|
char *entrypath;
|
||||||
|
|
||||||
|
if ((fd = opendir(path)) == NULL)
|
||||||
|
return rpc_errno_status();
|
||||||
|
|
||||||
|
for (e = readdir(fd); e != NULL && err == 0; e = readdir(fd))
|
||||||
|
{
|
||||||
|
if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (asprintf(&entrypath, "%s/%s", path, e->d_name) >= 0)
|
||||||
|
{
|
||||||
|
if (!lstat(entrypath, &s))
|
||||||
|
{
|
||||||
|
if (S_ISDIR(s.st_mode))
|
||||||
|
err = rpc_file_remove_recursive(entrypath);
|
||||||
|
else if (unlink(entrypath))
|
||||||
|
err = rpc_errno_status();
|
||||||
|
}
|
||||||
|
|
||||||
|
free(entrypath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = UBUS_STATUS_UNKNOWN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(fd);
|
||||||
|
|
||||||
|
if (!err && rmdir(path))
|
||||||
|
return rpc_errno_status();
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rpc_file_remove(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
|
struct ubus_request_data *req, const char *method,
|
||||||
|
struct blob_attr *msg)
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
struct blob_attr *tb[__RPC_F_R_MAX];
|
||||||
|
char *path = NULL;
|
||||||
|
|
||||||
|
blobmsg_parse(rpc_file_r_policy, __RPC_F_R_MAX, tb,
|
||||||
|
blob_data(msg), blob_len(msg));
|
||||||
|
|
||||||
|
if (!tb[RPC_F_RW_PATH])
|
||||||
|
return UBUS_STATUS_INVALID_ARGUMENT;
|
||||||
|
|
||||||
|
path = rpc_canonicalize_path(blobmsg_get_string(tb[RPC_F_RW_PATH]));
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
return UBUS_STATUS_UNKNOWN_ERROR;
|
||||||
|
|
||||||
|
if (!rpc_file_write_access(tb[RPC_F_R_SESSION], path))
|
||||||
|
return UBUS_STATUS_PERMISSION_DENIED;
|
||||||
|
|
||||||
|
if (lstat(path, &s))
|
||||||
|
return rpc_errno_status();
|
||||||
|
|
||||||
|
if (S_ISDIR(s.st_mode))
|
||||||
|
return rpc_file_remove_recursive(path);
|
||||||
|
|
||||||
|
if (unlink(path))
|
||||||
|
return rpc_errno_status();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
rpc_file_exec_lookup(const char *cmd)
|
rpc_file_exec_lookup(const char *cmd)
|
||||||
{
|
{
|
||||||
|
@ -906,6 +987,7 @@ rpc_file_api_init(const struct rpc_daemon_ops *o, struct ubus_context *ctx)
|
||||||
UBUS_METHOD("list", rpc_file_list, rpc_file_r_policy),
|
UBUS_METHOD("list", rpc_file_list, rpc_file_r_policy),
|
||||||
UBUS_METHOD("stat", rpc_file_stat, rpc_file_r_policy),
|
UBUS_METHOD("stat", rpc_file_stat, rpc_file_r_policy),
|
||||||
UBUS_METHOD("md5", rpc_file_md5, rpc_file_r_policy),
|
UBUS_METHOD("md5", rpc_file_md5, rpc_file_r_policy),
|
||||||
|
UBUS_METHOD("remove", rpc_file_remove, rpc_file_r_policy),
|
||||||
UBUS_METHOD("exec", rpc_file_exec, rpc_exec_policy),
|
UBUS_METHOD("exec", rpc_file_exec, rpc_exec_policy),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue