source: EcnlProtoTool/trunk/ntshell/ntshell/usrcmd.c@ 321

Last change on this file since 321 was 321, checked in by coas-nagasima, 7 years ago

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 14.0 KB
Line 
1/**
2 * @file usrcmd.c
3 * @author CuBeatSystems
4 * @author Shinichiro Nakamura
5 * @copyright
6 * ===============================================================
7 * Natural Tiny Shell (NT-Shell) Version 0.3.1
8 * ===============================================================
9 * Copyright (c) 2010-2016 Shinichiro Nakamura
10 *
11 * Permission is hereby granted, free of charge, to any person
12 * obtaining a copy of this software and associated documentation
13 * files (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use,
15 * copy, modify, merge, publish, distribute, sublicense, and/or
16 * sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following
18 * conditions:
19 *
20 * The above copyright notice and this permission notice shall be
21 * included in all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 * OTHER DEALINGS IN THE SOFTWARE.
31 */
32
33#include <kernel.h>
34#include <t_syslog.h>
35#include <t_stdlib.h>
36#include <sil.h>
37#include <stdlib.h>
38#include <string.h>
39#include <stdio.h>
40#include <setjmp.h>
41#include "syssvc/syslog.h"
42#include "kernel_cfg.h"
43#include "main.h"
44#include "rza1.h"
45#include "ffarch.h"
46#include "ff.h"
47#include "usrcmd.h"
48#include "ntstdio.h"
49#include "ntshell.h"
50
51extern ntstdio_t ntstdio;
52extern int ntshell_exit;
53
54int shell_kill(int pid, int sig)
55{
56 asm("bkpt #0");
57 return -1;
58}
59
60int shell_gettimeofday(struct timeval *tv, void *tzvp)
61{
62 SYSTIM time;
63 if (!tv) return 0;
64 get_tim(&time);
65 tv->tv_sec = time / 1000000;
66 tv->tv_usec = time - (tv->tv_sec * 1000000);
67 return 0;
68}
69
70void put_rc(const char *func, FRESULT rc)
71{
72 const char *p =
73 "OK\0DISK_ERR\0INT_ERR\0NOT_READY\0NO_FILE\0NO_PATH\0INVALID_NAME\0"
74 "DENIED\0EXIST\0INVALID_OBJECT\0WRITE_PROTECTED\0INVALID_DRIVE\0"
75 "NOT_ENABLED\0NO_FILE_SYSTEM\0MKFS_ABORTED\0TIMEOUT\0LOCKED\0"
76 "NOT_ENOUGH_CORE\0TOO_MANY_OPEN_FILES\0";
77 FRESULT i;
78
79 for (i = 0; i != rc && *p; i++) {
80 while (*p++);
81 }
82 ntstdio_printf(&ntstdio, "%s() =>%u FR_%s\n", func, (UINT)rc, p);
83}
84
85void put_drc(const char *func, DRESULT rc)
86{
87 const char *p =
88 "Successful\0R/W Error\0Write Protected\0Not Ready\0Invalid Parameter\0";
89 DRESULT i;
90
91 for (i = 0; i != rc && *p; i++) {
92 while (*p++);
93 }
94 ntstdio_printf(&ntstdio, "%s() =>%u %s\n", func, (UINT)rc, p);
95}
96
97char *basename(char *s)
98{
99 size_t i, j;
100 if (!s || !*s) return ".";
101 i = strlen(s) - 1;
102 for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
103 for (; i&&s[i] == '/'; i--) s[i] = 0;
104 for (; i&&s[i - 1] != '/'; i--);
105 return s + i;
106}
107
108char *dirname(char *_s)
109{
110 char *s = _s;
111 size_t i, j;
112 if (!s || !*s) return ".";
113 i = strlen(s) - 1;
114 for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
115 for (; s[i] == '/'; i--) if (!i) return (s == _s) ? "/" : _s;
116 for (; s[i] != '/'; i--) if (!i) return (s == _s) ? "." : _s;
117 for (; s[i] == '/'; i--) if (!i) if (s == _s) return "/"; else break;
118 s[i + 1] = 0;
119 return _s;
120}
121
122int usrcmd_cd(int argc, char **argv)
123{
124 FRESULT res;
125
126 if (argc == 2) {
127 if ((res = f_chdir(argv[1])) != FR_OK) {
128 put_rc("f_chdir", res);
129 return 0;
130 }
131 if ((res = f_chdrive(argv[1]) != FR_OK)) {
132 put_rc("f_chdrive", res);
133 return 0;
134 }
135 }
136
137 char path[256];
138 if ((res = f_getcwd(path, sizeof(path))) != FR_OK) {
139 put_rc("f_getcwd", res);
140 return 0;
141 }
142
143 strlcat(path, "\n", sizeof(path));
144 ntstdio_printf(&ntstdio, path);
145
146 return 0;
147}
148
149#define LS_ALL 0x01
150#define LS_LONG 0x02
151/* lsコマンド 1行表示 */
152void print_one_list(FILINFO *fno, BYTE list_option)
153{
154 char *fn;
155
156#if _USE_LFN
157 fn = *fno->lfname ? fno->lfname : fno->fname;
158#else
159 fn = fno->fname;
160#endif
161 if (!(list_option & LS_ALL)) {
162 if ((fno->fattrib & AM_HID) || (fn[0] == '.'))
163 return;
164 }
165
166 if (list_option & LS_LONG) {
167 ntstdio_printf(&ntstdio, "%c%c%c%c%c %04d/%02d/%02d %02d:%02d:%02d ",
168 (fno->fattrib & AM_DIR) ? 'd' : '-',
169 (fno->fattrib & AM_RDO) ? 'r' : '-',
170 (fno->fattrib & AM_HID) ? 'h' : '-',
171 (fno->fattrib & AM_SYS) ? 's' : '-',
172 (fno->fattrib & AM_ARC) ? 'a' : '-',
173 ((fno->fdate & 0xFE00) >> 9) + 1980,
174 ((fno->fdate & 0x01E0) >> 5),
175 ( fno->fdate & 0x001F),
176 ((fno->ftime & 0xF800) >> 11),
177 ((fno->ftime & 0x07E0) >> 5),
178 ( fno->ftime & 0x001F));
179
180 if (fno->fattrib & AM_DIR) { /* It is a directory */
181 ntstdio_printf(&ntstdio, "%10S ", " ");
182 }
183 else {
184 ntstdio_printf(&ntstdio, "%10d ", fno->fsize);
185 }
186 }
187
188 if (fno->fattrib & AM_DIR) { /* It is a directory */
189 ntstdio_printf(&ntstdio, "\x1B[32m%s\x1B[0m\n", fn);
190 }
191 else {
192 ntstdio_printf(&ntstdio, "%s\n", fn);
193 }
194}
195
196#define LFN_BUF_SIZE (_MAX_LFN + 1)
197/* lsコマンド dir内 表示 */
198void print_ls(char *path_p, char *pattern_p, BYTE list_option)
199{
200 FRESULT res;
201 FILINFO fno;
202 DIR dir;
203 char *fn; /* This function assumes non-Unicode configuration */
204
205 if ((pattern_p != NULL) && (pattern_p[0] == '\0'))
206 pattern_p = NULL;
207
208 char *path_backup = NULL;
209 path_backup = ff_memalloc(LFN_BUF_SIZE);
210 if (path_backup == NULL) {
211 ntstdio_printf(&ntstdio, "ff_memalloc err.\n");
212 return;
213 }
214
215#if _USE_LFN
216 char *lfn = NULL;
217 lfn = ff_memalloc(LFN_BUF_SIZE);
218 if (lfn == NULL) {
219 ntstdio_printf(&ntstdio, "ff_memalloc err.\n");
220 ff_memfree(path_backup);
221 return;
222 }
223 fno.lfname = lfn;
224 fno.lfsize = LFN_BUF_SIZE;
225#endif
226
227 if ((path_p != NULL) && (pattern_p == NULL)) {
228 if ((res = f_opendir(&dir, path_p)) != FR_OK)
229 put_rc("f_opendir", res);
230 res = f_readdir(&dir, &fno);
231 }
232 else {
233 res = f_findfirst(&dir, &fno, path_p, pattern_p);
234 }
235
236 while ((res == FR_OK) && (fno.fname[0] != 0)) {
237 if (pattern_p != NULL && (fno.fattrib & AM_DIR) && ((fno.fname[0] == '.') ? (pattern_p[0] == '.') : 1)) {/* DIR とパターンマッチしている場合は DIR 内部を ls する */
238#if _USE_LFN
239 fn = *fno.lfname ? fno.lfname : fno.fname;
240#else
241 fn = fno->fname;
242#endif
243 if ((res = f_getcwd(path_backup, LFN_BUF_SIZE)) != FR_OK) {
244 put_rc("f_getcwd", res);
245 }
246
247 if ((res = f_chdrive(path_p)) != RES_OK) {
248 put_rc("f_chdrive", res);
249 }
250
251 if ((res = f_chdir(path_p)) != RES_OK) {
252 put_rc("f_chdir", res);
253 }
254
255 ntstdio_printf(&ntstdio, "\n%s/%s:\n", path_p, fn);
256
257 print_ls(fn, NULL, list_option);
258
259 ntstdio_printf(&ntstdio, "\n");
260
261 if ((res = f_chdrive(path_backup)) != RES_OK) {
262 put_rc("f_chdrive", res);
263 }
264
265 if ((res = f_chdir(path_backup)) != RES_OK) {
266 put_rc("f_chdir", res);
267 }
268 }
269 else {
270 print_one_list(&fno, list_option);
271 }
272
273 if (pattern_p == NULL)
274 res = f_readdir(&dir, &fno); /* all */
275 else
276 res = f_findnext(&dir, &fno); /* pattern matching */
277 }
278
279 f_closedir(&dir);
280
281 if (lfn != NULL) ff_memfree(lfn);
282 if (path_backup != NULL) ff_memfree(path_backup);
283}
284
285int usrcmd_ls(int argc, char **argv)
286{
287 char *pattern_p = NULL, *basename_p = NULL, *dirname_p = NULL;
288 char default_pattern[_MAX_LFN] = "";
289 int i;
290 BYTE list_option = 0;
291
292 for (i = 1; i < argc; i++) {
293 if (argv[i][0] == '-') {
294 if (argv[i][1] == 'a') {
295 list_option |= LS_ALL;
296 }
297 else if (argv[i][1] == 'l') {
298 list_option |= LS_LONG;
299 }
300 continue;
301 }
302 if (argv[i][0] != '\0') { /* pattern matching ? */
303 pattern_p = &argv[i][0];
304 break;
305 }
306 }
307
308 if (pattern_p != NULL)
309 strlcpy(default_pattern, pattern_p, sizeof(default_pattern));
310 basename_p = basename(pattern_p);
311 dirname_p = dirname(default_pattern);
312 if (((dirname_p[0] == '/') && (basename_p[0] == '/')) ||
313 (!strncmp(dirname_p, ".", strlen(dirname_p)) && !strncmp(basename_p, ".", strlen(basename_p))))
314 {
315 basename_p = NULL;
316 }
317 print_ls(dirname_p, basename_p, list_option);
318
319 return 0;
320}
321
322int usrcmd_cp(int argc, char **argv)
323{
324 char *src_str_p = NULL, *dst_str_p = NULL;
325 unsigned char i;
326 FRESULT res;
327 FILINFO fno;
328 FIL src_fp, dst_fp;
329 size_t read_size, write_size;
330 char *lfn = NULL, *local_buff = NULL, *dst_mod_str_p = NULL;
331 char *src_basename_p;
332
333 if (argc < 2)
334 return 0;
335
336 /* 引数チェック */
337 for (i = 1; i < argc; i++) {
338 if (argv[i][0] == '-')
339 continue;
340 if (argv[i][0] != '\0') {
341 if (src_str_p == NULL)
342 src_str_p = &argv[i][0];
343 else {
344 dst_str_p = &argv[i][0];
345 break;
346 }
347 }
348 }
349 if ((src_str_p == NULL) || (dst_str_p == NULL))
350 return 0;
351
352#if _USE_LFN
353 /* LFN buffer alloc */
354 lfn = ff_memalloc(LFN_BUF_SIZE);
355 if (lfn == NULL) {
356 ntstdio_printf(&ntstdio, "alloc err.\n");
357 goto cp_end;
358 }
359 fno.lfname = lfn;
360 fno.lfsize = LFN_BUF_SIZE;
361#endif
362
363 /* copy buffer alloc */
364 local_buff = ff_memalloc(64);
365 if (local_buff == NULL) {
366 ntstdio_printf(&ntstdio, "alloc err.\n");
367 goto cp_end;
368 }
369
370 /*************/
371 /* src check */
372 /*************/
373 res = f_stat(src_str_p, &fno);
374 if (res != FR_OK) {
375 if (res == FR_NO_FILE)
376 ntstdio_printf(&ntstdio, "src no file.\n", res);
377 else
378 ntstdio_printf(&ntstdio, "src stat err(%d).\n", res);
379 goto cp_end;
380 }
381 if (fno.fattrib & AM_DIR) { /* src is dir */
382 /*******************************************************/ /* from dir */ /* 未実装 */
383 }
384 else { /* src is file */
385 res = f_open(&src_fp, src_str_p, (FA_OPEN_EXISTING | FA_READ));
386 if (res != FR_OK) {
387 ntstdio_printf(&ntstdio, "src open err(%d).\n", res);
388 goto cp_end;
389 }
390 }
391
392 /*************/
393 /* dst check */
394 /*************/
395 res = f_stat(dst_str_p, &fno);
396 if (res != FR_NO_FILE) {
397 if (res == FR_OK) {
398 if (fno.fattrib & AM_DIR) { /* dst is dir */
399 src_basename_p = basename(src_str_p);
400 dst_mod_str_p = ff_memalloc(LFN_BUF_SIZE);
401 if (dst_mod_str_p == NULL) {
402 ntstdio_printf(&ntstdio, "alloc err.\n");
403 goto cp_end;
404 }
405 ntstdio_snprintf(dst_mod_str_p, LFN_BUF_SIZE, "%s/%s\0", dst_str_p, src_basename_p);
406 dst_str_p = dst_mod_str_p;
407 }
408 else {
409 ntstdio_printf(&ntstdio, "dst file exists.\n");
410 goto cp_end_1;
411 }
412 }
413 else {
414 ntstdio_printf(&ntstdio, "src stat err(%d).\n", res);
415 goto cp_end_1;
416 }
417 }
418 res = f_open(&dst_fp, dst_str_p, (FA_CREATE_NEW | FA_WRITE));
419 if (res != FR_OK) {
420 ntstdio_printf(&ntstdio, "dst open err(%d).\n", res);
421 goto cp_end_1;
422 }
423
424 /********/
425 /* copy */
426 /********/
427 do {
428 /* read from src */
429 res = f_read(&src_fp, local_buff, sizeof(local_buff), &read_size);
430 if (res != FR_OK) {
431 ntstdio_printf(&ntstdio, "src read err(%d).\n", res);
432 goto cp_end_2;
433 }
434
435 /* write to dst */
436 res = f_write(&dst_fp, local_buff, read_size, &write_size);
437 if (res != FR_OK) {
438 ntstdio_printf(&ntstdio, "dst write err(%d).\n", res);
439 goto cp_end_2;
440 }
441 if (read_size != write_size) {
442 ntstdio_printf(&ntstdio, "dst write err(disk full).\n", res);
443 goto cp_end_2;
444 }
445 } while (read_size == sizeof(local_buff));
446
447cp_end_2:
448 f_close(&dst_fp);
449cp_end_1:
450 f_close(&src_fp);
451cp_end:
452 if(dst_mod_str_p != NULL) ff_memfree(dst_mod_str_p);
453 if(local_buff != NULL) ff_memfree(local_buff);
454 if(lfn != NULL) ff_memfree(lfn);
455
456 return 0;
457}
458
459int usrcmd_rm(int argc, char **argv)
460{
461 FRESULT res;
462
463 if (argc == 2) {
464 if ((res = f_unlink(argv[1])) != FR_OK) {
465 put_rc("f_unlink", res);
466 return 0;
467 }
468 }
469
470 return 0;
471}
472
473int usrcmd_mv(int argc, char **argv)
474{
475 FRESULT res;
476
477 if (argc == 3) {
478 if ((res = f_rename(argv[1], argv[2])) != FR_OK) {
479 put_rc("f_rename", res);
480 return 0;
481 }
482 }
483
484 return 0;
485}
486
487int usrcmd_mkdir(int argc, char **argv)
488{
489 FRESULT res;
490
491 if (argc == 2) {
492 if ((res = f_mkdir(argv[1])) != FR_OK) {
493 put_rc("f_mkdir", res);
494 return 0;
495 }
496 }
497
498 return 0;
499}
500
501int usrcmd_hexdump(int argc, char **argv)
502{
503 FRESULT res;
504 FIL fsrc;
505 unsigned char data[16 + 1];
506 unsigned char ascii[sizeof("\x1B[31m0\x1B[0m\x1B[31m1\x1B[0m\x1B[31m2\x1B[0m\x1B[31m3\x1B[0m\x1B[31m4\x1B[0m\x1B[31m5\x1B[0m\x1B[31m6\x1B[0m\x1B[31m7\x1B[0m\x1B[31m8\x1B[0m\x1B[31m9\x1B[0m\x1B[31ma\x1B[0m\x1B[31mb\x1B[0m\x1B[31mc\x1B[0m\x1B[31md\x1B[0m\x1B[31me\x1B[0m\x1B[31mf\x1B[0m")];
507 char line[sizeof("00000000: 00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 00 : \n") + sizeof(ascii)];
508
509 if (argc != 2) {
510 ntstdio_printf(&ntstdio, "hexdump file\n");
511 }
512
513 if ((res = f_open(&fsrc, argv[1], FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
514 put_rc("f_open", res);
515 return 0;
516 }
517
518 for (int i = 0; i < fsrc.fsize; i += 16) {
519 ascii[0] = '\0';
520 line[0] = '\0';
521 char *pos = line;
522 int rst = sizeof(line);
523 int len = ntstdio_snprintf(pos, rst, "%08X: ", i);
524 pos += len;
525 rst -= len;
526
527 UINT br = 0;
528 if ((res = f_read(&fsrc, data, 16, &br)) != FR_OK) {
529 put_rc("f_read", res);
530 f_close(&fsrc);
531 return 0;
532 }
533 data[16] = '\0';
534
535 char *apos = ascii;
536 int arst = sizeof(ascii);
537 for (int j = 0; j < br; j++) {
538 unsigned char c = data[j];
539 if (j != 7)
540 len = ntstdio_snprintf(pos, rst, "%02X ", c);
541 else
542 len = ntstdio_snprintf(pos, rst, "%02X-", c);
543 pos += len;
544 rst -= len;
545
546 if (c < 0x20) {
547 len = ntstdio_snprintf(apos, arst , "\x1B[31m%c\x1B[0m", c + 0x40);
548 }
549 else if (c == 0xFF) {
550 len = ntstdio_snprintf(apos, arst, "\x1B[32m%c\x1B[0m", 'E');
551 }
552 else {
553 len = ntstdio_snprintf(apos, arst, "%c", c);
554 }
555 apos += len;
556 arst -= len;
557 }
558
559 for (int j = br; j < 16; j++) {
560 if (j != 7)
561 len = ntstdio_snprintf(pos, rst, " ");
562 else
563 len = ntstdio_snprintf(pos, rst, " -");
564 pos += len;
565 rst -= len;
566 }
567
568 len = ntstdio_snprintf(pos, rst, ": %s\n", ascii);
569 pos += len;
570 rst -= len;
571
572 ntstdio_printf(&ntstdio, line);
573 }
574
575 f_close(&fsrc);
576 return 0;
577}
578
579int usrcmd_info(int argc, char **argv)
580{
581 if (argc != 2) {
582 ntstdio_printf(&ntstdio, "info sys\n");
583 ntstdio_printf(&ntstdio, "info ver\n");
584 return 0;
585 }
586 if (strcmp(argv[1], "sys") == 0) {
587 ntstdio_printf(&ntstdio, "GR-PEACH Monitor\n");
588 return 0;
589 }
590 if (strcmp(argv[1], "ver") == 0) {
591 int mj, mn, bd;
592 ntshell_version(&mj, &mn, &bd);
593 ntstdio_printf(&ntstdio, "Version %d.%d.%d\n", mj, mn, bd);
594 return 0;
595 }
596 ntstdio_printf(&ntstdio, "Unknown sub command found\n");
597 return -1;
598}
599
600int usrcmd_exit(int argc, char **argv)
601{
602 ntshell_exit = 1;
603
604 return 0;
605}
Note: See TracBrowser for help on using the repository browser.