Skip to content

Commit 7549a62

Browse files
author
Joakim Nohlgård
committed
shell: Add vfs command
usage: vfs r /path/to/file nbytes offset Only reading is currently supported
1 parent d71140f commit 7549a62

3 files changed

Lines changed: 180 additions & 4 deletions

File tree

sys/shell/commands/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ endif
6969
ifneq (,$(filter ccn-lite-utils,$(USEMODULE)))
7070
SRC += sc_ccnl.c
7171
endif
72+
ifneq (,$(filter vfs,$(USEMODULE)))
73+
SRC += sc_vfs.c
74+
endif
7275

7376
# TODO
7477
# Conditional building not possible at the moment due to

sys/shell/commands/sc_vfs.c

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*
2+
* Copyright (C) 2016 Eistec AB
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @ingroup sys_shell_commands
11+
* @{
12+
*
13+
* @file
14+
* @brief Shell commands for the VFS module
15+
*
16+
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
17+
*
18+
* @}
19+
*/
20+
21+
#ifdef BOARD_MULLE
22+
#include <stdint.h>
23+
#include <inttypes.h>
24+
#include <stdlib.h>
25+
#include <stdio.h>
26+
#include <string.h>
27+
#include <ctype.h>
28+
#include <errno.h>
29+
#include <unistd.h>
30+
#include <fcntl.h>
31+
32+
#include "vfs.h"
33+
34+
static void _usage(char **argv)
35+
{
36+
printf("%s <r|w> <path> [bytes] [offset]\n", argv[0]);
37+
puts("r: Read [bytes] bytes at [offset] in file <path>");
38+
}
39+
40+
/* Macro used by _errno_string to expand errno labels to string and print it */
41+
#define _case_snprintf_errno_name(x) \
42+
case x: \
43+
res = snprintf(buf, buflen, #x); \
44+
break
45+
46+
static int _errno_string(int err, char *buf, size_t buflen)
47+
{
48+
int len = 0;
49+
int res;
50+
if (err < 0) {
51+
res = snprintf(buf, buflen, "-");
52+
if (res < 0) {
53+
return res;
54+
}
55+
if (res <= buflen) {
56+
buf += res;
57+
buflen -= res;
58+
}
59+
len += res;
60+
err = -err;
61+
}
62+
switch (err) {
63+
_case_snprintf_errno_name(EACCES);
64+
_case_snprintf_errno_name(ENOENT);
65+
_case_snprintf_errno_name(EINVAL);
66+
_case_snprintf_errno_name(EFAULT);
67+
_case_snprintf_errno_name(EROFS);
68+
_case_snprintf_errno_name(EIO);
69+
70+
default:
71+
res = snprintf(buf, buflen, "%d", err);
72+
break;
73+
}
74+
if (res < 0) {
75+
return res;
76+
}
77+
len += res;
78+
return len;
79+
}
80+
#undef _case_snprintf_errno_name
81+
82+
int _vfs_handler(int argc, char **argv)
83+
{
84+
printf("vfs: %d, %p\n", argc, (void *)argv);
85+
if (argc < 3) {
86+
_usage(argv);
87+
return 1;
88+
}
89+
if (strcmp(argv[1], "r") != 0) {
90+
printf("Only read is currently supported");
91+
return 2;
92+
}
93+
uint8_t buf[16];
94+
size_t nbytes = sizeof(buf);
95+
off_t offset = 0;
96+
char *path = argv[2];
97+
if (argc > 3) {
98+
nbytes = atoi(argv[3]);
99+
}
100+
if (argc > 4) {
101+
offset = atoi(argv[4]);
102+
}
103+
104+
vfs_normalize_path(path, path, strlen(path));
105+
106+
int fd = vfs_open(path, O_RDONLY, 0);
107+
if (fd < 0) {
108+
_errno_string(fd, (char *)buf, sizeof(buf));
109+
printf("Error opening file \"%s\": %s\n", path, buf);
110+
return 3;
111+
}
112+
113+
int res;
114+
res = vfs_lseek(fd, offset, SEEK_SET);
115+
if (res < 0) {
116+
_errno_string(fd, (char *)buf, sizeof(buf));
117+
printf("Seek error: %s\n", buf);
118+
vfs_close(fd);
119+
return 4;
120+
}
121+
122+
while (nbytes > 0) {
123+
size_t line_len = (nbytes < sizeof(buf) ? nbytes : sizeof(buf));
124+
res = vfs_read(fd, buf, line_len);
125+
if (res < 0) {
126+
_errno_string(fd, (char *)buf, sizeof(buf));
127+
printf("Read error: %s\n", buf);
128+
vfs_close(fd);
129+
return 5;
130+
}
131+
else if (res > line_len) {
132+
printf("BUFFER OVERRUN! %d > %lu\n", res, (unsigned long)line_len);
133+
vfs_close(fd);
134+
return 6;
135+
}
136+
else if (res == 0) {
137+
/* EOF */
138+
printf("-- EOF --\n");
139+
break;
140+
}
141+
printf("%08lx:", (unsigned long)offset);
142+
for (size_t k = 0; k < res; ++k) {
143+
if ((k % 2) == 0) {
144+
putchar(' ');
145+
}
146+
printf("%02x", buf[k]);
147+
}
148+
putchar(' ');
149+
putchar(' ');
150+
for (size_t k = 0; k < res; ++k) {
151+
if (isprint(buf[k])) {
152+
putchar(buf[k]);
153+
}
154+
else {
155+
putchar('.');
156+
}
157+
}
158+
puts("");
159+
offset += res;
160+
nbytes -= res;
161+
}
162+
163+
vfs_close(fd);
164+
return 0;
165+
}
166+
#endif

sys/shell/commands/shell_commands.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ extern int _ccnl_interest(int argc, char **argv);
129129
extern int _ccnl_fib(int argc, char **argv);
130130
#endif
131131

132+
#ifdef MODULE_VFS
133+
extern int _vfs_handler(int argc, char **argv);
134+
#endif
135+
132136
const shell_command_t _shell_command_list[] = {
133137
{"reboot", "Reboot the node", _reboot_handler},
134138
#ifdef MODULE_CONFIG
@@ -209,10 +213,13 @@ const shell_command_t _shell_command_list[] = {
209213
{"saul", "interact with sensors and actuators using SAUL", _saul },
210214
#endif
211215
#ifdef MODULE_CCN_LITE_UTILS
212-
{ "ccnl_open", "opens an interface or socket", _ccnl_open},
213-
{ "ccnl_int", "sends an interest", _ccnl_interest},
214-
{ "ccnl_cont", "create content and populated it", _ccnl_content},
215-
{ "ccnl_fib", "shows or modifies the CCN-Lite FIB", _ccnl_fib},
216+
{"ccnl_open", "opens an interface or socket", _ccnl_open},
217+
{"ccnl_int", "sends an interest", _ccnl_interest},
218+
{"ccnl_cont", "create content and populated it", _ccnl_content},
219+
{"ccnl_fib", "shows or modifies the CCN-Lite FIB", _ccnl_fib},
220+
#endif
221+
#ifdef MODULE_VFS
222+
{"vfs", "read files", _vfs_handler},
216223
#endif
217224
{NULL, NULL, NULL}
218225
};

0 commit comments

Comments
 (0)