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

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

ファイルを追加、更新。

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
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内
198 表示 */
199void print_ls(char *path_p, char *pattern_p, BYTE list_option)
200{
201 FRESULT res;
202 FILINFO fno;
203 DIR dir;
204 char *fn; /* This function assumes non-Unicode configuration */
205
206 if ((pattern_p != NULL) && (pattern_p[0] == '\0'))
207 pattern_p = NULL;
208
209 char *path_backup = NULL;
210 path_backup = ff_memalloc(LFN_BUF_SIZE);
211 if (path_backup == NULL) {
212 ntstdio_printf(&ntstdio, "ff_memalloc err.\n");
213 return;
214 }
215
216#if _USE_LFN
217 char *lfn = NULL;
218 lfn = ff_memalloc(LFN_BUF_SIZE);
219 if (lfn == NULL) {
220 ntstdio_printf(&ntstdio, "ff_memalloc err.\n");
221 ff_memfree(path_backup);
222 return;
223 }
224 fno.lfname = lfn;
225 fno.lfsize = LFN_BUF_SIZE;
226#endif
227
228 if ((path_p != NULL) && (pattern_p == NULL)) {
229 if ((res = f_opendir(&dir, path_p)) != FR_OK)
230 put_rc("f_opendir", res);
231 res = f_readdir(&dir, &fno);
232 }
233 else {
234 res = f_findfirst(&dir, &fno, path_p, pattern_p);
235 }
236
237 while ((res == FR_OK) && (fno.fname[0] != 0)) {
238 if (pattern_p != NULL && (fno.fattrib & AM_DIR) && ((fno.fname[0] == '.') ? (pattern_p[0] == '.') : 1)) {/* DIR とパターンマッチしている場合は DIR 内
239部を ls する */
240#if _USE_LFN
241 fn = *fno.lfname ? fno.lfname : fno.fname;
242#else
243 fn = fno->fname;
244#endif
245 if ((res = f_getcwd(path_backup, LFN_BUF_SIZE)) != FR_OK) {
246 put_rc("f_getcwd", res);
247 }
248
249 if ((res = f_chdrive(path_p)) != RES_OK) {
250 put_rc("f_chdrive", res);
251 }
252
253 if ((res = f_chdir(path_p)) != RES_OK) {
254 put_rc("f_chdir", res);
255 }
256
257 ntstdio_printf(&ntstdio, "\n%s/%s:\n", path_p, fn);
258
259 print_ls(fn, NULL, list_option);
260
261 ntstdio_printf(&ntstdio, "\n");
262
263 if ((res = f_chdrive(path_backup)) != RES_OK) {
264 put_rc("f_chdrive", res);
265 }
266
267 if ((res = f_chdir(path_backup)) != RES_OK) {
268 put_rc("f_chdir", res);
269 }
270 }
271 else {
272 print_one_list(&fno, list_option);
273 }
274
275 if (pattern_p == NULL)
276 res = f_readdir(&dir, &fno); /* all */
277 else
278 res = f_findnext(&dir, &fno); /* pattern matching */
279 }
280
281 f_closedir(&dir);
282
283 if (lfn != NULL) ff_memfree(lfn);
284 if (path_backup != NULL) ff_memfree(path_backup);
285}
286
287int usrcmd_ls(int argc, char **argv)
288{
289 char *pattern_p = NULL, *basename_p = NULL, *dirname_p = NULL;
290 char default_pattern[_MAX_LFN] = "";
291 int i;
292 BYTE list_option = 0;
293
294 for (i = 1; i < argc; i++) {
295 if (argv[i][0] == '-') {
296 if (argv[i][1] == 'a') {
297 list_option |= LS_ALL;
298 }
299 else if (argv[i][1] == 'l') {
300 list_option |= LS_LONG;
301 }
302 continue;
303 }
304 if (argv[i][0] != '\0') { /* pattern matching ? */
305 pattern_p = &argv[i][0];
306 break;
307 }
308 }
309
310 if (pattern_p != NULL)
311 strlcpy(default_pattern, pattern_p, sizeof(default_pattern));
312 basename_p = basename(pattern_p);
313 dirname_p = dirname(default_pattern);
314 if (((dirname_p[0] == '/') && (basename_p[0] == '/')) ||
315 (!strncmp(dirname_p, ".", strlen(dirname_p)) && !strncmp(basename_p, ".", strlen(basename_p))))
316 {
317 basename_p = NULL;
318 }
319 print_ls(dirname_p, basename_p, list_option);
320
321 return 0;
322}
323
324int usrcmd_cp(int argc, char **argv)
325{
326 char *src_str_p = NULL, *dst_str_p = NULL;
327 unsigned char i;
328 FRESULT res;
329 FILINFO fno;
330 FIL src_fp, dst_fp;
331 size_t read_size, write_size;
332 char *lfn = NULL, *local_buff = NULL, *dst_mod_str_p = NULL;
333 char *src_basename_p;
334
335 if (argc < 2)
336 return 0;
337
338 /* 引数チェック */
339 for (i = 1; i < argc; i++) {
340 if (argv[i][0] == '-')
341 continue;
342 if (argv[i][0] != '\0') {
343 if (src_str_p == NULL)
344 src_str_p = &argv[i][0];
345 else {
346 dst_str_p = &argv[i][0];
347 break;
348 }
349 }
350 }
351 if ((src_str_p == NULL) || (dst_str_p == NULL))
352 return 0;
353
354#if _USE_LFN
355 /* LFN buffer alloc */
356 lfn = ff_memalloc(LFN_BUF_SIZE);
357 if (lfn == NULL) {
358 ntstdio_printf(&ntstdio, "alloc err.\n");
359 goto cp_end;
360 }
361 fno.lfname = lfn;
362 fno.lfsize = LFN_BUF_SIZE;
363#endif
364
365 /* copy buffer alloc */
366 local_buff = ff_memalloc(64);
367 if (local_buff == NULL) {
368 ntstdio_printf(&ntstdio, "alloc err.\n");
369 goto cp_end;
370 }
371
372 /*************/
373 /* src check */
374 /*************/
375 res = f_stat(src_str_p, &fno);
376 if (res != FR_OK) {
377 if (res == FR_NO_FILE)
378 ntstdio_printf(&ntstdio, "src no file.\n", res);
379 else
380 ntstdio_printf(&ntstdio, "src stat err(%d).\n", res);
381 goto cp_end;
382 }
383 if (fno.fattrib & AM_DIR) { /* src is dir */
384 /*******************************************************/ /* from dir */ /* 未実装
385 */
386 }
387 else { /* src is file */
388 res = f_open(&src_fp, src_str_p, (FA_OPEN_EXISTING | FA_READ));
389 if (res != FR_OK) {
390 ntstdio_printf(&ntstdio, "src open err(%d).\n", res);
391 goto cp_end;
392 }
393 }
394
395 /*************/
396 /* dst check */
397 /*************/
398 res = f_stat(dst_str_p, &fno);
399 if (res != FR_NO_FILE) {
400 if (res == FR_OK) {
401 if (fno.fattrib & AM_DIR) { /* dst is dir */
402 src_basename_p = basename(src_str_p);
403 dst_mod_str_p = ff_memalloc(LFN_BUF_SIZE);
404 if (dst_mod_str_p == NULL) {
405 ntstdio_printf(&ntstdio, "alloc err.\n");
406 goto cp_end;
407 }
408 ntstdio_snprintf(dst_mod_str_p, LFN_BUF_SIZE, "%s/%s\0", dst_str_p, src_basename_p);
409 dst_str_p = dst_mod_str_p;
410 }
411 else {
412 ntstdio_printf(&ntstdio, "dst file exists.\n");
413 goto cp_end_1;
414 }
415 }
416 else {
417 ntstdio_printf(&ntstdio, "src stat err(%d).\n", res);
418 goto cp_end_1;
419 }
420 }
421 res = f_open(&dst_fp, dst_str_p, (FA_CREATE_NEW | FA_WRITE));
422 if (res != FR_OK) {
423 ntstdio_printf(&ntstdio, "dst open err(%d).\n", res);
424 goto cp_end_1;
425 }
426
427 /********/
428 /* copy */
429 /********/
430 do {
431 /* read from src */
432 res = f_read(&src_fp, local_buff, sizeof(local_buff), &read_size);
433 if (res != FR_OK) {
434 ntstdio_printf(&ntstdio, "src read err(%d).\n", res);
435 goto cp_end_2;
436 }
437
438 /* write to dst */
439 res = f_write(&dst_fp, local_buff, read_size, &write_size);
440 if (res != FR_OK) {
441 ntstdio_printf(&ntstdio, "dst write err(%d).\n", res);
442 goto cp_end_2;
443 }
444 if (read_size != write_size) {
445 ntstdio_printf(&ntstdio, "dst write err(disk full).\n", res);
446 goto cp_end_2;
447 }
448 } while (read_size == sizeof(local_buff));
449
450cp_end_2:
451 f_close(&dst_fp);
452cp_end_1:
453 f_close(&src_fp);
454cp_end:
455 if(dst_mod_str_p != NULL) ff_memfree(dst_mod_str_p);
456 if(local_buff != NULL) ff_memfree(local_buff);
457 if(lfn != NULL) ff_memfree(lfn);
458
459 return 0;
460}
461
462int usrcmd_rm(int argc, char **argv)
463{
464 FRESULT res;
465
466 if (argc == 2) {
467 if ((res = f_unlink(argv[1])) != FR_OK) {
468 put_rc("f_unlink", res);
469 return 0;
470 }
471 }
472
473 return 0;
474}
475
476int usrcmd_mv(int argc, char **argv)
477{
478 FRESULT res;
479
480 if (argc == 3) {
481 if ((res = f_rename(argv[1], argv[2])) != FR_OK) {
482 put_rc("f_rename", res);
483 return 0;
484 }
485 }
486
487 return 0;
488}
489
490int usrcmd_mkdir(int argc, char **argv)
491{
492 FRESULT res;
493
494 if (argc == 2) {
495 if ((res = f_mkdir(argv[1])) != FR_OK) {
496 put_rc("f_mkdir", res);
497 return 0;
498 }
499 }
500
501 return 0;
502}
503
504int usrcmd_hexdump(int argc, char **argv)
505{
506 FRESULT res;
507 FIL fsrc;
508 unsigned char data[16 + 1];
509 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")];
510 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)];
511
512 if (argc != 2) {
513 ntstdio_printf(&ntstdio, "hexdump file\n");
514 }
515
516 if ((res = f_open(&fsrc, argv[1], FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
517 put_rc("f_open", res);
518 return 0;
519 }
520
521 for (int i = 0; i < fsrc.fsize; i += 16) {
522 ascii[0] = '\0';
523 line[0] = '\0';
524 char *pos = line;
525 int rst = sizeof(line);
526 int len = ntstdio_snprintf(pos, rst, "%08X: ", i);
527 pos += len;
528 rst -= len;
529
530 UINT br = 0;
531 if ((res = f_read(&fsrc, data, 16, &br)) != FR_OK) {
532 put_rc("f_read", res);
533 f_close(&fsrc);
534 return 0;
535 }
536 data[16] = '\0';
537
538 char *apos = ascii;
539 int arst = sizeof(ascii);
540 for (int j = 0; j < br; j++) {
541 unsigned char c = data[j];
542 if (j != 7)
543 len = ntstdio_snprintf(pos, rst, "%02X ", c);
544 else
545 len = ntstdio_snprintf(pos, rst, "%02X-", c);
546 pos += len;
547 rst -= len;
548
549 if (c < 0x20) {
550 len = ntstdio_snprintf(apos, arst , "\x1B[31m%c\x1B[0m", c + 0x40);
551 }
552 else if (c == 0xFF) {
553 len = ntstdio_snprintf(apos, arst, "\x1B[32m%c\x1B[0m", 'E');
554 }
555 else {
556 len = ntstdio_snprintf(apos, arst, "%c", c);
557 }
558 apos += len;
559 arst -= len;
560 }
561
562 for (int j = br; j < 16; j++) {
563 if (j != 7)
564 len = ntstdio_snprintf(pos, rst, " ");
565 else
566 len = ntstdio_snprintf(pos, rst, " -");
567 pos += len;
568 rst -= len;
569 }
570
571 len = ntstdio_snprintf(pos, rst, ": %s\n", ascii);
572 pos += len;
573 rst -= len;
574
575 ntstdio_printf(&ntstdio, line);
576 }
577
578 f_close(&fsrc);
579 return 0;
580}
581
582int usrcmd_info(int argc, char **argv)
583{
584 if (argc != 2) {
585 ntstdio_printf(&ntstdio, "info sys\n");
586 ntstdio_printf(&ntstdio, "info ver\n");
587 return 0;
588 }
589 if (strcmp(argv[1], "sys") == 0) {
590 ntstdio_printf(&ntstdio, "GR-PEACH Monitor\n");
591 return 0;
592 }
593 if (strcmp(argv[1], "ver") == 0) {
594 int mj, mn, bd;
595 ntshell_version(&mj, &mn, &bd);
596 ntstdio_printf(&ntstdio, "Version %d.%d.%d\n", mj, mn, bd);
597 return 0;
598 }
599 ntstdio_printf(&ntstdio, "Unknown sub command found\n");
600 return -1;
601}
602
603int usrcmd_exit(int argc, char **argv)
604{
605 ntshell_exit = 1;
606
607 return 0;
608}
Note: See TracBrowser for help on using the repository browser.