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;
|
||||
}
|
||||
|
||||
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 *
|
||||
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("stat", rpc_file_stat, 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),
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue