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

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

NTShellタスクを更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 19.8 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 "shellif.h"
34#include <kernel.h>
35#include <t_syslog.h>
36#include <t_stdlib.h>
37#include <sil.h>
38#include "syssvc/syslog.h"
39#include "target_syssvc.h"
40#include "kernel_cfg.h"
41#include "main.h"
42#include "ffarch.h"
43#include "ff.h"
44#include "usrcmd.h"
45#include "core/ntshell.h"
46#include "core/ntlibc.h"
47#include "util/ntstdio.h"
48
49extern ntstdio_t *ntstdio;
50extern int ntshell_exit;
51
52/* musl_getopt from msul */
53char *optarg;
54int /*optind=1, opterr=1, */optopt, optpos, optreset=0;
55extern int optind, opterr;
56
57static void ntstdio_write(ntstdio_t *handle, const char *str, int l)
58{
59 for (; *str && l >= 0; l--) {
60 ntstdio_putc(handle, *str++);
61 }
62}
63
64static void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
65{
66 ntstdio_puts(&ntstdio, a);
67 ntstdio_write(&ntstdio, b, ntlibc_strlen(b));
68 ntstdio_write(&ntstdio, c, l);
69 ntstdio_putc(&ntstdio, '\n');
70}
71
72static int musl_getopt(int argc, char * const argv[], const char *optstring)
73{
74 int i;
75 wchar_t c, d;
76 int k, l;
77 char *optchar;
78
79 if (!optind || optreset) {
80 optreset = 0;
81 optpos = 0;
82 optind = 1;
83 }
84
85 if (optind >= argc || !argv[optind])
86 return -1;
87
88 if (argv[optind][0] != '-') {
89 if (optstring[0] == '-') {
90 optarg = argv[optind++];
91 return 1;
92 }
93 return -1;
94 }
95
96 if (!argv[optind][1])
97 return -1;
98
99 if (argv[optind][1] == '-' && !argv[optind][2])
100 return optind++, -1;
101
102 if (!optpos) optpos++;
103 if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
104 k = 1;
105 c = 0xfffd; /* replacement char */
106 }
107 optchar = argv[optind]+optpos;
108 optopt = c;
109 optpos += k;
110
111 if (!argv[optind][optpos]) {
112 optind++;
113 optpos = 0;
114 }
115
116 if (optstring[0] == '-' || optstring[0] == '+')
117 optstring++;
118
119 i = 0;
120 d = 0;
121 do {
122 l = mbtowc(&d, optstring+i, MB_LEN_MAX);
123 if (l>0) i+=l; else i++;
124 } while (l && d != c);
125
126 if (d != c) {
127 if (optstring[0] != ':' && opterr)
128 __getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
129 return '?';
130 }
131 if (optstring[i] == ':') {
132 if (optstring[i+1] == ':') optarg = 0;
133 else if (optind >= argc) {
134 if (optstring[0] == ':') return ':';
135 if (opterr) __getopt_msg(argv[0],
136 ": option requires an argument: ",
137 optchar, k);
138 return '?';
139 }
140 if (optstring[i+1] != ':' || optpos) {
141 optarg = argv[optind++] + optpos;
142 optpos = 0;
143 }
144 }
145 return c;
146}
147
148void put_rc(const char *func, FRESULT rc)
149{
150 const char *p =
151 "OK\0DISK_ERR\0INT_ERR\0NOT_READY\0NO_FILE\0NO_PATH\0INVALID_NAME\0"
152 "DENIED\0EXIST\0INVALID_OBJECT\0WRITE_PROTECTED\0INVALID_DRIVE\0"
153 "NOT_ENABLED\0NO_FILE_SYSTEM\0MKFS_ABORTED\0TIMEOUT\0LOCKED\0"
154 "NOT_ENOUGH_CORE\0TOO_MANY_OPEN_FILES\0";
155 FRESULT i;
156
157 for (i = 0; i != rc && *p; i++) {
158 while (*p++);
159 }
160 ntstdio_printf(ntstdio, "%s() =>%u FR_%s\n", func, (UINT)rc, p);
161}
162
163void put_drc(const char *func, DRESULT rc)
164{
165 const char *p =
166 "Successful\0R/W Error\0Write Protected\0Not Ready\0Invalid Parameter\0";
167 DRESULT i;
168
169 for (i = 0; i != rc && *p; i++) {
170 while (*p++);
171 }
172 ntstdio_printf(ntstdio, "%s() =>%u %s\n", func, (UINT)rc, p);
173}
174
175char *basename(char *s)
176{
177 size_t i, j;
178 if (!s || !*s) return ".";
179 i = ntlibc_strlen(s) - 1;
180 for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
181 for (; i&&s[i] == '/'; i--) s[i] = 0;
182 for (; i&&s[i - 1] != '/'; i--);
183 return s + i;
184}
185
186char *dirname(char *_s)
187{
188 char *s = _s;
189 size_t i, j;
190 if (!s || !*s) return ".";
191 i = ntlibc_strlen(s) - 1;
192 for (j = 0; j <= i; j++) if (s[j] == ':') { s = &s[j + 1]; i -= j; break; }
193 for (; s[i] == '/'; i--) if (!i) return (s == _s) ? "/" : _s;
194 for (; s[i] != '/'; i--) if (!i) return (s == _s) ? "." : _s;
195 for (; s[i] == '/'; i--) if (!i) { if (s == _s) return "/"; else break; }
196 s[i + 1] = 0;
197 return _s;
198}
199
200int usrcmd_cd(int argc, char **argv)
201{
202 FRESULT res;
203
204 if (argc == 2) {
205 if ((res = f_chdir(argv[1])) != FR_OK) {
206 put_rc("f_chdir", res);
207 return 0;
208 }
209 if ((res = f_chdrive(argv[1]) != FR_OK)) {
210 put_rc("f_chdrive", res);
211 return 0;
212 }
213 }
214
215 char path[256];
216 if ((res = f_getcwd(path, sizeof(path))) != FR_OK) {
217 put_rc("f_getcwd", res);
218 return 0;
219 }
220
221 ntlibc_strlcat(path, "\n", sizeof(path));
222 ntstdio_printf(ntstdio, path);
223
224 return 0;
225}
226
227#define LS_ALL 0x01
228#define LS_LONG 0x02
229/* lsコマンド 1行表示 */
230void print_one_list(FILINFO *fno, BYTE list_option)
231{
232 char *fn;
233
234#if FF_USE_LFN
235 fn = *fno->lfname ? fno->lfname : fno->fname;
236#else
237 fn = fno->fname;
238#endif
239 if (!(list_option & LS_ALL)) {
240 if ((fno->fattrib & AM_HID) || (fn[0] == '.'))
241 return;
242 }
243
244 if (list_option & LS_LONG) {
245 ntstdio_printf(ntstdio, "%c%c%c%c%c %04d/%02d/%02d %02d:%02d:%02d ",
246 (fno->fattrib & AM_DIR) ? 'd' : '-',
247 (fno->fattrib & AM_RDO) ? 'r' : '-',
248 (fno->fattrib & AM_HID) ? 'h' : '-',
249 (fno->fattrib & AM_SYS) ? 's' : '-',
250 (fno->fattrib & AM_ARC) ? 'a' : '-',
251 ((fno->fdate & 0xFE00) >> 9) + 1980,
252 ((fno->fdate & 0x01E0) >> 5),
253 ( fno->fdate & 0x001F),
254 ((fno->ftime & 0xF800) >> 11),
255 ((fno->ftime & 0x07E0) >> 5),
256 ( fno->ftime & 0x001F));
257
258 if (fno->fattrib & AM_DIR) { /* It is a directory */
259 ntstdio_printf(ntstdio, "%10s ", " ");
260 }
261 else {
262 ntstdio_printf(ntstdio, "%10lu ", fno->fsize);
263 }
264 }
265
266 if (fno->fattrib & AM_DIR) { /* It is a directory */
267 ntstdio_printf(ntstdio, "\x1B[32m%s\x1B[0m\n", fn);
268 }
269 else {
270 ntstdio_printf(ntstdio, "%s\n", fn);
271 }
272}
273
274#define LFN_BUF_SIZE (FF_MAX_LFN + 1)
275/* lsコマンド dir内 表示 */
276void print_ls(char *path_p, char *pattern_p, BYTE list_option)
277{
278 FRESULT res;
279 FILINFO fno;
280 FATFS_DIR dir;
281 char *fn; /* This function assumes non-Unicode configuration */
282
283 if ((pattern_p != NULL) && (pattern_p[0] == '\0'))
284 pattern_p = NULL;
285
286 char *path_backup = NULL;
287 path_backup = ff_memalloc(LFN_BUF_SIZE);
288 if (path_backup == NULL) {
289 ntstdio_printf(ntstdio, "ff_memalloc err.\n");
290 return;
291 }
292
293#if FF_USE_LFN
294 char *lfn = NULL;
295 lfn = ff_memalloc(LFN_BUF_SIZE);
296 if (lfn == NULL) {
297 ntstdio_printf(ntstdio, "ff_memalloc err.\n");
298 ff_memfree(path_backup);
299 return;
300 }
301 fno.lfname = lfn;
302 fno.lfsize = LFN_BUF_SIZE;
303#endif
304
305 if ((path_p != NULL) && (pattern_p == NULL)) {
306 if ((res = f_opendir(&dir, path_p)) != FR_OK)
307 put_rc("f_opendir", res);
308 res = f_readdir(&dir, &fno);
309 }
310 else {
311 res = f_findfirst(&dir, &fno, path_p, pattern_p);
312 }
313
314 while ((res == FR_OK) && (fno.fname[0] != 0)) {
315 if (pattern_p != NULL && (fno.fattrib & AM_DIR) && ((fno.fname[0] == '.') ? (pattern_p[0] == '.') : 1)) {/* DIR とパターンマッチしている場合は DIR 内部を ls する */
316#if FF_USE_LFN
317 fn = *fno.lfname ? fno.lfname : fno.fname;
318#else
319 fn = fno->fname;
320#endif
321 if ((res = f_getcwd(path_backup, LFN_BUF_SIZE)) != FR_OK) {
322 put_rc("f_getcwd", res);
323 }
324
325 if ((res = f_chdrive(path_p)) != FR_OK) {
326 put_rc("f_chdrive", res);
327 }
328
329 if ((res = f_chdir(path_p)) != FR_OK) {
330 put_rc("f_chdir", res);
331 }
332
333 ntstdio_printf(ntstdio, "\n%s/%s:\n", path_p, fn);
334
335 print_ls(fn, NULL, list_option);
336
337 ntstdio_printf(ntstdio, "\n");
338
339 if ((res = f_chdrive(path_backup)) != FR_OK) {
340 put_rc("f_chdrive", res);
341 }
342
343 if ((res = f_chdir(path_backup)) != FR_OK) {
344 put_rc("f_chdir", res);
345 }
346 }
347 else {
348 print_one_list(&fno, list_option);
349 }
350
351 if (pattern_p == NULL)
352 res = f_readdir(&dir, &fno); /* all */
353 else
354 res = f_findnext(&dir, &fno); /* pattern matching */
355 }
356
357 f_closedir(&dir);
358
359#if FF_USE_LFN
360 if (lfn != NULL) ff_memfree(lfn);
361#endif
362 if (path_backup != NULL) ff_memfree(path_backup);
363}
364
365int usrcmd_ls(int argc, char **argv)
366{
367 char *pattern_p = NULL, *basename_p = NULL, *dirname_p = NULL;
368 char default_pattern[FF_MAX_LFN] = "";
369 int c;
370 BYTE list_option = 0;
371
372 while ((c = musl_getopt(argc, argv, "al")) != -1) {
373 switch (c) {
374 case 'a':
375 list_option |= LS_ALL;
376 break;
377 case 'l':
378 list_option |= LS_LONG;
379 break;
380 default:
381 break;
382 }
383 }
384 pattern_p = *(argv + optind);
385
386 if (pattern_p != NULL)
387 ntlibc_strlcpy(default_pattern, pattern_p, sizeof(default_pattern));
388 basename_p = basename(pattern_p);
389 dirname_p = dirname(default_pattern);
390 if (((dirname_p[0] == '/') && (basename_p[0] == '/')) ||
391 (!ntlibc_strncmp(dirname_p, ".", ntlibc_strlen(dirname_p)) && !ntlibc_strncmp(basename_p, ".", ntlibc_strlen(basename_p))))
392 {
393 basename_p = NULL;
394 }
395 print_ls(dirname_p, basename_p, list_option);
396
397 return 0;
398}
399
400int usrcmd_cp(int argc, char **argv)
401{
402 char *src_str_p = NULL, *dst_str_p = NULL;
403 unsigned char i;
404 FRESULT res;
405 FILINFO fno;
406 FIL src_fp, dst_fp;
407 size_t read_size, write_size;
408 char *lfn = NULL, *local_buff = NULL, *dst_mod_str_p = NULL;
409 char *src_basename_p;
410
411 if (argc < 2)
412 return 0;
413
414 /* 引数チェック */
415 for (i = 1; i < argc; i++) {
416 if (argv[i][0] == '-')
417 continue;
418 if (argv[i][0] != '\0') {
419 if (src_str_p == NULL)
420 src_str_p = &argv[i][0];
421 else {
422 dst_str_p = &argv[i][0];
423 break;
424 }
425 }
426 }
427 if ((src_str_p == NULL) || (dst_str_p == NULL))
428 return 0;
429
430#if FF_USE_LFN
431 /* LFN buffer alloc */
432 lfn = ff_memalloc(LFN_BUF_SIZE);
433 if (lfn == NULL) {
434 ntstdio_printf(ntstdio, "alloc err.\n");
435 goto cp_end;
436 }
437 fno.lfname = lfn;
438 fno.lfsize = LFN_BUF_SIZE;
439#endif
440
441 /* copy buffer alloc */
442 local_buff = ff_memalloc(64);
443 if (local_buff == NULL) {
444 ntstdio_printf(ntstdio, "alloc err.\n");
445 goto cp_end;
446 }
447
448 /*************/
449 /* src check */
450 /*************/
451 res = f_stat(src_str_p, &fno);
452 if (res != FR_OK) {
453 if (res == FR_NO_FILE)
454 ntstdio_printf(ntstdio, "src no file.\n");
455 else
456 ntstdio_printf(ntstdio, "src stat err(%d).\n", res);
457 goto cp_end;
458 }
459 if (fno.fattrib & AM_DIR) { /* src is dir */
460 /*******************************************************/ /* from dir */ /* 未実装 */
461 }
462 else { /* src is file */
463 res = f_open(&src_fp, src_str_p, (FA_OPEN_EXISTING | FA_READ));
464 if (res != FR_OK) {
465 ntstdio_printf(ntstdio, "src open err(%d).\n", res);
466 goto cp_end;
467 }
468 }
469
470 /*************/
471 /* dst check */
472 /*************/
473 res = f_stat(dst_str_p, &fno);
474 if (res != FR_NO_FILE) {
475 if (res == FR_OK) {
476 if (fno.fattrib & AM_DIR) { /* dst is dir */
477 src_basename_p = basename(src_str_p);
478 dst_mod_str_p = ff_memalloc(LFN_BUF_SIZE);
479 if (dst_mod_str_p == NULL) {
480 ntstdio_printf(ntstdio, "alloc err.\n");
481 goto cp_end;
482 }
483 ntstdio_snprintf(dst_mod_str_p, LFN_BUF_SIZE, "%s/%s\0", dst_str_p, src_basename_p);
484 dst_str_p = dst_mod_str_p;
485 }
486 else {
487 ntstdio_printf(ntstdio, "dst file exists.\n");
488 goto cp_end_1;
489 }
490 }
491 else {
492 ntstdio_printf(ntstdio, "src stat err(%d).\n", res);
493 goto cp_end_1;
494 }
495 }
496 res = f_open(&dst_fp, dst_str_p, (FA_CREATE_NEW | FA_WRITE));
497 if (res != FR_OK) {
498 ntstdio_printf(ntstdio, "dst open err(%d).\n", res);
499 goto cp_end_1;
500 }
501
502 /********/
503 /* copy */
504 /********/
505 do {
506 /* read from src */
507 res = f_read(&src_fp, local_buff, sizeof(local_buff), &read_size);
508 if (res != FR_OK) {
509 ntstdio_printf(ntstdio, "src read err(%d).\n", res);
510 goto cp_end_2;
511 }
512
513 /* write to dst */
514 res = f_write(&dst_fp, local_buff, read_size, &write_size);
515 if (res != FR_OK) {
516 ntstdio_printf(ntstdio, "dst write err(%d).\n", res);
517 goto cp_end_2;
518 }
519 if (read_size != write_size) {
520 ntstdio_printf(ntstdio, "dst write err(disk full).\n");
521 goto cp_end_2;
522 }
523 } while (read_size == sizeof(local_buff));
524
525cp_end_2:
526 f_close(&dst_fp);
527cp_end_1:
528 f_close(&src_fp);
529cp_end:
530 if(dst_mod_str_p != NULL) ff_memfree(dst_mod_str_p);
531 if(local_buff != NULL) ff_memfree(local_buff);
532 if(lfn != NULL) ff_memfree(lfn);
533
534 return 0;
535}
536
537int usrcmd_rm(int argc, char **argv)
538{
539 FRESULT res;
540
541 if (argc == 2) {
542 if ((res = f_unlink(argv[1])) != FR_OK) {
543 put_rc("f_unlink", res);
544 return 0;
545 }
546 }
547
548 return 0;
549}
550
551int usrcmd_mv(int argc, char **argv)
552{
553 FRESULT res;
554
555 if (argc == 3) {
556 if ((res = f_rename(argv[1], argv[2])) != FR_OK) {
557 put_rc("f_rename", res);
558 return 0;
559 }
560 }
561
562 return 0;
563}
564
565int usrcmd_mkdir(int argc, char **argv)
566{
567 FRESULT res;
568
569 if (argc == 2) {
570 if ((res = f_mkdir(argv[1])) != FR_OK) {
571 put_rc("f_mkdir", res);
572 return 0;
573 }
574 }
575
576 return 0;
577}
578
579#define HEXDUMP_EXTRA_FOR_UTF8 3 /* need extra buffer size */
580#define CCOLOR_RESET 0
581#define CCOLOR_BLACK 30
582#define CCOLOR_RED 31
583#define CCOLOR_GREEN 32
584#define CCOLOR_YELLOW 33
585#define CCOLOR_BLUE 34
586#define CCOLOR_MAGENTA 35
587#define CCOLOR_CYAN 36
588#define CCOLOR_WHITE 37
589enum {
590 HEXDUMP_OPT_DEFAULT = 1 << 0,
591 HEXDUMP_OPT_UTF8 = 1 << 1,
592};
593
594int usrcmd_hexdump(int argc, char **argv)
595{
596 FRESULT res;
597 FIL fsrc;
598 unsigned char data[16 + 1 + HEXDUMP_EXTRA_FOR_UTF8];
599 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") + HEXDUMP_EXTRA_FOR_UTF8];
600 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)];
601 TCHAR *filename_p = NULL;
602 int op, option_flag = HEXDUMP_OPT_DEFAULT;
603 char *option_ptr, *option_endptr, ccolor, utf8_done_flg, utf8_odd_bytes = 0;
604 unsigned int op_offset = 0, op_size = 0, op_end = 0;
605
606 while ((op = musl_getopt(argc, argv, "hduos0123456789xX")) != -1) {
607 switch (op) {
608 case 'h': /* help */
609 ntstdio_printf(ntstdio, " hexdump [OPTION] file\n");
610 ntstdio_printf(ntstdio, " -h : help\n");
611 ntstdio_printf(ntstdio, " -d : print all byte with convert and color [in character area] (default)\n");
612 ntstdio_printf(ntstdio, " -u : try print UTF-8 code [in character area]\n");
613 ntstdio_printf(ntstdio, " -oOFFSET : print start offset address from top\n");
614 ntstdio_printf(ntstdio, " -sSIZE : print size\n");
615 break;
616 case 'd': /* print one byte character [in character area] (default) */
617 option_flag |= HEXDUMP_OPT_DEFAULT;
618 break;
619 case 'u': /* try print UTF-8 code [in character area] */
620 option_flag |= HEXDUMP_OPT_UTF8;
621 break;
622 case 'o': /* print start offset address from top */
623 option_ptr = *(argv + optind);
624 op_offset = ntlibc_strtoul(&option_ptr[2], &option_endptr, 0);
625 break;
626 case 's': /* print size */
627 option_ptr = *(argv + optind);
628 op_size = ntlibc_strtoul(&option_ptr[2], &option_endptr, 0);
629 break;
630 default:
631 break;
632 }
633 }
634 filename_p = *(argv + optind);
635 if (filename_p == NULL)
636 return 0;
637
638 if ((res = f_open(&fsrc, filename_p, FA_OPEN_EXISTING | FA_READ)) != FR_OK) {
639 put_rc("f_open", res);
640 return 0;
641 }
642
643 /* position adjusting */
644 if (op_offset >= fsrc.fsize) {
645 ntstdio_printf(ntstdio, "error : input offset is bigger than file size(0x%lX).\n", fsrc.fsize);
646 return 0;
647 }
648 op_end = op_offset + op_size;
649 if ((op_size == 0) || (op_end >= fsrc.fsize))
650 op_end = fsrc.fsize;
651 f_lseek(&fsrc, op_offset);
652
653 for (int i = op_offset; i < op_end; i += 16) {
654 ascii[0] = '\0';
655 line[0] = '\0';
656 char *pos = line;
657 int rst = sizeof(line);
658 int len = ntstdio_snprintf(pos, rst, "%08X: ", i);
659 pos += len;
660 rst -= len;
661
662 UINT br = 0;
663 if ((res = f_read(&fsrc, data, 16 + HEXDUMP_EXTRA_FOR_UTF8, &br)) != FR_OK) {
664 put_rc("f_read", res);
665 f_close(&fsrc);
666 return 0;
667 }
668 data[br] = '\0';
669 f_lseek(&fsrc, i + 16);
670 if (br > 16) br = 16;
671
672 unsigned char *apos = ascii;
673 int arst = sizeof(ascii);
674 for (int j = 0; j < br; j++) {
675 unsigned char c = data[j];
676 if (j != 7)
677 len = ntstdio_snprintf(pos, rst, "%02X ", c);
678 else
679 len = ntstdio_snprintf(pos, rst, "%02X-", c);
680 pos += len;
681 rst -= len;
682
683 len = 0;
684 utf8_done_flg = 0;
685 ccolor = CCOLOR_RESET;
686
687 if (c < 0x20) {
688 ccolor = CCOLOR_RED;
689 c = c + 0x40;
690 }
691 else {
692 if (option_flag & HEXDUMP_OPT_UTF8) { /* try UTF-8 */
693 /* check character code */
694 int bf_utf8_bytes, af_utf8_bytes;
695 unsigned char utf8_code[4];
696 WCHAR utf16_code;
697
698 utf16_code = Utf8_to_Utf16(&data[j], &bf_utf8_bytes); /* try UTF-8 -> UTF-16 */
699 Utf16_to_Utf8(utf8_code, &af_utf8_bytes, (UINT)utf16_code); /* try UTF-16 -> UTF-8 */
700 if ((af_utf8_bytes <= 3 && bf_utf8_bytes == af_utf8_bytes) &&
701 !memcmp(&data[j], utf8_code, af_utf8_bytes)) { /* size & code match */
702 utf8_done_flg = 1;
703 for (int k = 1; k < af_utf8_bytes; k++) { /* pos */
704 if (j + k >= 16)
705 break;
706 if (j + k != 7)
707 len = ntstdio_snprintf(pos, rst, "%02X ", data[j + k]);
708 else
709 len = ntstdio_snprintf(pos, rst, "%02X-", data[j + k]);
710 pos += len;
711 rst -= len;
712 }
713 memcpy(apos, &data[j], af_utf8_bytes); /* apos */
714 apos[af_utf8_bytes] = 0;
715 len = af_utf8_bytes;
716 j += af_utf8_bytes - 1;
717 if (af_utf8_bytes > 1) {
718 utf8_odd_bytes = j < 15 ? af_utf8_bytes - 2 : af_utf8_bytes - 1;
719 }
720 }
721 }
722 }
723
724 if (utf8_odd_bytes > 0 && j < 15) {
725 apos += len;
726 arst -= len;
727 len = ntstdio_snprintf(apos, arst, "\x1B[%dm%c\x1B[0m", CCOLOR_RESET, ' ');
728 utf8_odd_bytes--;
729 }
730 else if (utf8_done_flg == 0) {
731 if (c >= 0x80 && c < 0x9F) {
732 ccolor = CCOLOR_RED;
733 c = c - 0x60;
734 }
735 else if (c >= 0xA0 && c < 0xDF) {
736 ccolor = CCOLOR_GREEN;
737 c = c - 0x60;
738 }
739 else if (c >= 0xE0 && c < 0xFF) {
740 ccolor = CCOLOR_GREEN;
741 c = c - 0xC0;
742 }
743 else if (c == 0x7F || c == 0x9F || c == 0xDF || c == 0xFF) {
744 ccolor = CCOLOR_CYAN;
745 c = '?';
746 }
747 len = ntstdio_snprintf(apos, arst, "\x1B[%dm%c\x1B[0m", ccolor, c);
748 }
749
750 apos += len;
751 arst -= len;
752 }
753
754 for (int j = br; j < 16; j++) {
755 if (j != 7)
756 len = ntstdio_snprintf(pos, rst, " ");
757 else
758 len = ntstdio_snprintf(pos, rst, " -");
759 pos += len;
760 rst -= len;
761 }
762
763 len = ntstdio_snprintf(pos, rst, ": %s\n", ascii);
764 pos += len;
765 rst -= len;
766
767 ntstdio_puts(ntstdio, line);
768 }
769
770 f_close(&fsrc);
771 return 0;
772}
773
774int usrcmd_date(int argc, char **argv)
775{
776 int ret;
777 struct timespec tp;
778 char buf[30];
779
780 ret = shell_clock_gettime(CLOCK_REALTIME, &tp);
781 if (ret != 0) {
782 ntstdio_printf(ntstdio, "clock_gettime error %d", ret);
783 return 0;
784 }
785
786 memset(buf, 0, sizeof(buf));
787 if (ctime_r(&tp.tv_sec, buf) == NULL) {
788 ntstdio_printf(ntstdio, "ctime_r error");
789 return 0;
790 }
791
792 /* 改行コードの削除 */
793 ret = ntlibc_strlen(buf);
794 buf[ret - 1] = '\0';
795
796 ntstdio_printf(ntstdio, "%s .%09ld\n", buf, tp.tv_nsec);
797 return 0;
798}
799
800int usrcmd_info(int argc, char **argv)
801{
802 if (argc != 2) {
803 ntstdio_printf(ntstdio, "info sys\n");
804 ntstdio_printf(ntstdio, "info ver\n");
805 return 0;
806 }
807 if (ntlibc_strcmp(argv[1], "sys") == 0) {
808 ntstdio_printf(ntstdio, TARGET_NAME" Monitor\n");
809 return 0;
810 }
811 if (ntlibc_strcmp(argv[1], "ver") == 0) {
812 int mj, mn, bd;
813 ntshell_version(&mj, &mn, &bd);
814 ntstdio_printf(ntstdio, "Version %d.%d.%d\n", mj, mn, bd);
815 return 0;
816 }
817 ntstdio_printf(ntstdio, "Unknown sub command found\n");
818 return -1;
819}
820
821int usrcmd_exit(int argc, char **argv)
822{
823 ntshell_exit = 1;
824
825 return 0;
826}
Note: See TracBrowser for help on using the repository browser.