From 14465b85c49678ab0e5ef58aff8d825876841101 Mon Sep 17 00:00:00 2001 From: anjiahao Date: Tue, 8 Nov 2022 11:53:33 +0800 Subject: [PATCH] cmd_dd:support dd can do verify After writing the file, compare the contents of the two files again Signed-off-by: anjiahao --- nshlib/nsh_command.c | 4 +- nshlib/nsh_ddcmd.c | 107 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index fa73d6b93..9adf0d058 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -160,9 +160,9 @@ static const struct cmdmap_s g_cmdmap[] = #endif #ifndef CONFIG_NSH_DISABLE_DD - { "dd", cmd_dd, 3, 6, + { "dd", cmd_dd, 3, 7, "if= of= [bs=] [count=] " - "[skip=]" }, + "[skip=] [verify]" }, # endif #if defined(CONFIG_NET) && defined(CONFIG_NET_ROUTE) && !defined(CONFIG_NSH_DISABLE_DELROUTE) diff --git a/nshlib/nsh_ddcmd.c b/nshlib/nsh_ddcmd.c index 467fa6e00..3890616e8 100644 --- a/nshlib/nsh_ddcmd.c +++ b/nshlib/nsh_ddcmd.c @@ -71,6 +71,7 @@ struct dd_s uint32_t nsectors; /* Number of sectors to transfer */ uint32_t skip; /* The number of sectors skipped on input */ bool eof; /* true: The end of the input or output file has been hit */ + bool verify; /* true: Verify infile and outfile correctness */ uint16_t sectsize; /* Size of one sector */ uint16_t nbytes; /* Number of valid bytes in the buffer */ FAR uint8_t *buffer; /* Buffer of data to write to the output file */ @@ -171,7 +172,8 @@ static inline int dd_infopen(FAR const char *name, FAR struct dd_s *dd) static inline int dd_outfopen(FAR const char *name, FAR struct dd_s *dd) { - dd->outfd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0644); + dd->outfd = open(name, (dd->verify ? O_RDWR : O_WRONLY) | + O_CREAT | O_TRUNC, 0644); if (dd->outfd < 0) { FAR struct nsh_vtbl_s *vtbl = dd->vtbl; @@ -182,6 +184,100 @@ static inline int dd_outfopen(FAR const char *name, FAR struct dd_s *dd) return OK; } +static int dd_verify(FAR const char *infile, FAR const char *outfile, + FAR struct dd_s *dd) +{ + FAR uint8_t *buffer; + int sector = 0; + int ret = OK; + + ret = lseek(dd->infd, dd->skip ? dd->skip * dd->sectsize : 0, SEEK_SET); + if (ret < 0) + { + nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "lseek", NSH_ERRNO); + return ret; + } + + dd->eof = 0; + ret = lseek(dd->outfd, 0, SEEK_SET); + if (ret < 0) + { + nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "lseek", NSH_ERRNO); + return ret; + } + + buffer = malloc(dd->sectsize); + if (buffer == NULL) + { + return ERROR; + } + + while (!dd->eof && sector < dd->nsectors) + { + ret = dd_read(dd); + if (ret < 0) + { + break; + } + + ret = read(dd->outfd, buffer, dd->nbytes); + if (ret != dd->nbytes) + { + nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "read", NSH_ERRNO); + break; + } + + if (memcmp(dd->buffer, buffer, dd->nbytes) != 0) + { + int i; + + nsh_output(dd->vtbl, "infile sector %d", sector); + for (i = 0; i < dd->nbytes; i++) + { + if (i % 16 == 0) + { + nsh_output(dd->vtbl, "\n"); + } + + nsh_output(dd->vtbl, "%02x", dd->buffer[i]); + if (i + 1 % 2 == 0) + { + nsh_output(dd->vtbl, " "); + } + } + + nsh_output(dd->vtbl, "\noutfile sector %d", sector); + for (i = 0; i < dd->nbytes; i++) + { + if (i % 16 == 0) + { + nsh_output(dd->vtbl, "\n"); + } + + nsh_output(dd->vtbl, "%02x", dd->buffer[i]); + if (i + 1 % 2 == 0) + { + nsh_output(dd->vtbl, " "); + } + } + + nsh_output(dd->vtbl, "\n"); + ret = ERROR; + break; + } + + sector++; + } + + if (ret < 0) + { + nsh_error(dd->vtbl, g_fmtcmdfailed, g_dd, "dd_verify", ret); + } + + free(buffer); + return ret; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -262,6 +358,10 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) { dd.skip = atoi(&argv[i][5]); } + else if (strncmp(argv[i], "verify", 6) == 0) + { + dd.verify = true; + } } #ifndef CAN_PIPE_FROM_STD @@ -360,6 +460,11 @@ int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, FAR char **argv) / ((double)elapsed / USEC_PER_SEC))); #endif + if (ret == 0 && dd.verify) + { + ret = dd_verify(infile, outfile, &dd); + } + errout_with_outf: close(dd.outfd);