-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17937 from benpicco/nanocoap_vfs
nanocoap_vfs: add nanocoap_vfs_get()
- Loading branch information
Showing
10 changed files
with
334 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (C) 2022 ML!PA Consulting GmbH | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup net_nanosock | ||
* @brief VFS NanoCoAP helper functions | ||
* | ||
* @{ | ||
* | ||
* @file | ||
* @brief VFS NanoCoAP helper functions | ||
* | ||
* @author Benjamin Valentin <[email protected]> | ||
*/ | ||
#ifndef NET_NANOCOAP_VFS_H | ||
#define NET_NANOCOAP_VFS_H | ||
|
||
#include "net/nanocoap_sock.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Downloads the resource behind @p url via blockwise | ||
* GET and stores it in the file @p dst. | ||
* | ||
* @param[in] url URL to the resource | ||
* @param[in] dst Path to the destination file | ||
* | ||
* @returns 0 on success | ||
* @returns <0 on error | ||
*/ | ||
int nanocoap_vfs_get_url(const char *url, const char *dst); | ||
|
||
/** | ||
* @brief Downloads the resource behind @p path via blockwise | ||
* GET and stores it in the file @p dst. | ||
* | ||
* @param[in] sock Connection to the server | ||
* @param[in] path Remote query path to the resource | ||
* @param[in] dst Local path to the destination file | ||
* | ||
* @returns 0 on success | ||
* @returns <0 on error | ||
*/ | ||
int nanocoap_vfs_get(nanocoap_sock_t *sock, const char *path, const char *dst); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* NET_NANOCOAP_VFS_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Copyright (C) 2022 ML!PA Consulting GmbH | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup net_nanocoap | ||
* @{ | ||
* | ||
* @file | ||
* @brief Nanocoap VFS helpers | ||
* | ||
* @author Benjamin Valentin <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <fcntl.h> | ||
#include "net/nanocoap_sock.h" | ||
#include "net/sock/util.h" | ||
#include "vfs.h" | ||
|
||
#define ENABLE_DEBUG 0 | ||
#include "debug.h" | ||
|
||
static int _2file(void *arg, size_t offset, uint8_t *buf, size_t len, int more) | ||
{ | ||
(void)more; | ||
int *fd = arg; | ||
|
||
vfs_lseek(*fd, offset, SEEK_SET); | ||
return vfs_write(*fd, buf, len); | ||
} | ||
|
||
static int _prepare_file(const char *dst, char *dst_tmp, size_t len) | ||
{ | ||
/* download to temp file, rename it later */ | ||
if (snprintf(dst_tmp, len, "%s.t", dst) > (int)len) { | ||
return -ENOBUFS; | ||
} | ||
|
||
return vfs_open(dst_tmp, O_CREAT | O_WRONLY | O_TRUNC, 0644); | ||
} | ||
|
||
static int _finalize_file(int fd, int res, const char *dst, const char *dst_tmp) | ||
{ | ||
vfs_close(fd); | ||
|
||
/* move file to it's final location */ | ||
if (res >= 0) { | ||
DEBUG("nanocoap: moving %s to %s\n", dst_tmp, dst); | ||
vfs_unlink(dst); | ||
res = vfs_rename(dst_tmp, dst); | ||
} | ||
|
||
vfs_unlink(dst_tmp); | ||
|
||
return res; | ||
} | ||
|
||
int nanocoap_vfs_get(nanocoap_sock_t *sock, const char *path, const char *dst) | ||
{ | ||
int fd, res; | ||
char dst_tmp[CONFIG_SOCK_URLPATH_MAXLEN]; | ||
|
||
DEBUG("nanocoap: downloading %s to %s\n", path, dst_tmp); | ||
|
||
fd = _prepare_file(dst, dst_tmp, sizeof(dst_tmp)); | ||
if (fd < 0) { | ||
return fd; | ||
} | ||
res = nanocoap_sock_get_blockwise(sock, path, CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT, | ||
_2file, &fd); | ||
return _finalize_file(fd, res, dst, dst_tmp); | ||
} | ||
|
||
int nanocoap_vfs_get_url(const char *url, const char *dst) | ||
{ | ||
int fd, res; | ||
char dst_tmp[CONFIG_SOCK_URLPATH_MAXLEN]; | ||
|
||
DEBUG("nanocoap: downloading %s to %s\n", url, dst_tmp); | ||
|
||
fd = _prepare_file(dst, dst_tmp, sizeof(dst_tmp)); | ||
if (fd < 0) { | ||
return fd; | ||
} | ||
res = nanocoap_get_blockwise_url(url, CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT, | ||
_2file, &fd); | ||
return _finalize_file(fd, res, dst, dst_tmp); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* Copyright (C) 2022 ML!PA Consulting GmbH | ||
* | ||
* This file is subject to the terms and conditions of the GNU Lesser | ||
* General Public License v2.1. See the file LICENSE in the top level | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @ingroup sys_shell_commands | ||
* @{ | ||
* | ||
* @file | ||
* @brief NanoCoAP commands that interact with the filesystem | ||
* | ||
* @author Benjamin Valentin <[email protected]> | ||
* | ||
* @} | ||
*/ | ||
|
||
#include <errno.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <inttypes.h> | ||
|
||
#include "vfs_default.h" | ||
#include "net/nanocoap_vfs.h" | ||
#include "net/nanocoap_sock.h" | ||
|
||
struct dir_list_ctx { | ||
char *buf; | ||
char *cur; | ||
char *end; | ||
}; | ||
|
||
static bool _is_dir(const char *url) | ||
{ | ||
int len = strlen(url); | ||
return url[len - 1] == '/'; | ||
} | ||
|
||
static int _print_cb(void *arg, size_t offset, uint8_t *buf, size_t len, int more) | ||
{ | ||
(void)arg; | ||
(void)offset; | ||
|
||
write(STDOUT_FILENO, buf, len); | ||
if (!more) { | ||
puts(""); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int _print_dir_cb(void *arg, size_t offset, uint8_t *buf, size_t len, int more) | ||
{ | ||
(void)offset; | ||
(void)more; | ||
|
||
struct dir_list_ctx *ctx = arg; | ||
|
||
char *end = (char *)buf + len; | ||
for (char *c = (char *)buf; c < end; ++c) { | ||
if (ctx->cur) { | ||
if (*c == '>' || ctx->cur == ctx->end) { | ||
*ctx->cur = 0; | ||
puts(ctx->buf); | ||
ctx->cur = NULL; | ||
} else { | ||
*ctx->cur++ = *c; | ||
} | ||
} else if (*c == '<') { | ||
ctx->cur = ctx->buf; | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int _print_dir(const char *url, char *buf, size_t len) | ||
{ | ||
struct dir_list_ctx ctx = { | ||
.buf = buf, | ||
.end = buf + len, | ||
}; | ||
return nanocoap_get_blockwise_url(url, CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT, | ||
_print_dir_cb, &ctx); | ||
} | ||
|
||
int _nanocoap_get_handler(int argc, char **argv) | ||
{ | ||
int res; | ||
char buffer[CONFIG_NANOCOAP_QS_MAX]; | ||
char *dst, *url = argv[1]; | ||
|
||
if (argc < 2) { | ||
printf("Usage: %s <url> [destination]\n", argv[0]); | ||
printf("Default destination: %s\n", VFS_DEFAULT_DATA); | ||
return -EINVAL; | ||
} | ||
|
||
if (_is_dir(url) && argc < 3) { | ||
res = _print_dir(url, buffer, sizeof(buffer)); | ||
if (res) { | ||
printf("Request failed: %s\n", strerror(-res)); | ||
} | ||
return res; | ||
} | ||
|
||
if (argc < 3) { | ||
dst = strrchr(url, '/'); | ||
if (dst == NULL) { | ||
printf("invalid url: '%s'\n", url); | ||
return -EINVAL; | ||
} | ||
if (snprintf(buffer, sizeof(buffer), "%s%s", | ||
VFS_DEFAULT_DATA, dst) >= (int)sizeof(buffer)) { | ||
printf("Output file path too long\n"); | ||
return -ENOBUFS; | ||
} | ||
dst = buffer; | ||
} else { | ||
dst = argv[2]; | ||
} | ||
|
||
/* alternatively write the file to stdout */ | ||
if (strcmp(dst, "-") == 0) { | ||
return nanocoap_get_blockwise_url(url, CONFIG_NANOCOAP_BLOCKSIZE_DEFAULT, | ||
_print_cb, NULL); | ||
} | ||
|
||
res = nanocoap_vfs_get_url(url, dst); | ||
if (res < 0) { | ||
printf("Download failed: %s\n", strerror(-res)); | ||
} else { | ||
printf("Saved as %s\n", dst); | ||
} | ||
return res; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters