summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-07-18 08:24:29 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-07-18 08:24:29 -0600
commit54fdd99901b8db5ba275ea9c1f3f56efe24232ad (patch)
tree92da53e2c07893a7e8f019203d137e45c5c8eac2 /apps
parent2e8e47d417fb0b1e5b2386548f9c308fd74edec9 (diff)
downloadnuttx-54fdd99901b8db5ba275ea9c1f3f56efe24232ad.tar.gz
nuttx-54fdd99901b8db5ba275ea9c1f3f56efe24232ad.tar.bz2
nuttx-54fdd99901b8db5ba275ea9c1f3f56efe24232ad.zip
NSH cmp command by Andrew Twidgell
Diffstat (limited to 'apps')
-rw-r--r--apps/ChangeLog.txt4
-rw-r--r--apps/nshlib/Kconfig4
-rw-r--r--apps/nshlib/README.txt5
-rw-r--r--apps/nshlib/nsh.h7
-rw-r--r--apps/nshlib/nsh_fscmds.c112
-rw-r--r--apps/nshlib/nsh_parse.c3
6 files changed, 132 insertions, 3 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index 7800c837c..bfc4615a8 100644
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -612,4 +612,6 @@
issues that I am still uncertain how should be handled (2012-7-15).
* apps/system/zmodem/Makefile.host and host/: The Zmodem utilities
can now be built to execute on a Linux host.
-
+ * apps/nshlib/nsh_fscmds.c: Add a 'cmp' command that can be used to
+ compare two files for equivalence. Returns an indication if the files
+ differ. Contributed by Andrew Twidgell (via Lorenz Meier) (2013-7-18).
diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig
index ded9f2e67..5d5677f7e 100644
--- a/apps/nshlib/Kconfig
+++ b/apps/nshlib/Kconfig
@@ -55,6 +55,10 @@ config NSH_DISABLE_CP
bool "Disable cp"
default n
+config NSH_DISABLE_CMP
+ bool "Disable cmp"
+ default n
+
config NSH_DISABLE_DD
bool "Disable dd"
default n
diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt
index bd2dd75f7..7be3be5df 100644
--- a/apps/nshlib/README.txt
+++ b/apps/nshlib/README.txt
@@ -261,6 +261,11 @@ o cd [<dir-path>|-|~|..]
'home' directory is '/'.
'cd ..' sets the current working directory to the parent directory.
+o cmp <path1> <path2>
+
+ Compare of the contents of the file at <file1> with the contents of
+ the file at <path2>. Returns an indication only if the files differ.
+
o cp <source-path> <dest-path>
Copy of the contents of the file at <source-path> to the location
diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h
index b842bb70e..957f08bc1 100644
--- a/apps/nshlib/nsh.h
+++ b/apps/nshlib/nsh.h
@@ -126,7 +126,7 @@
# ifndef CONFIG_USBDEV_TRACE
# undef CONFIG_NSH_USBDEV_TRACE
-# endif
+# endif
# ifdef CONFIG_NSH_USBDEV_TRACE
# ifdef CONFIG_NSH_USBDEV_TRACEINIT
@@ -597,7 +597,7 @@ void nsh_usbtrace(void);
#ifndef CONFIG_NSH_DISABLE_XD
int cmd_xd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
-
+
#if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST)
int cmd_test(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
int cmd_lbracket(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
@@ -616,6 +616,9 @@ void nsh_usbtrace(void);
# ifndef CONFIG_NSH_DISABLE_CP
int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
+# ifndef CONFIG_NSH_DISABLE_CMP
+ int cmd_cmp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
+# endif
# ifndef CONFIG_NSH_DISABLE_DD
int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c
index 99d6268a5..c2fb55078 100644
--- a/apps/nshlib/nsh_fscmds.c
+++ b/apps/nshlib/nsh_fscmds.c
@@ -1288,3 +1288,115 @@ int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
}
#endif
#endif
+
+/****************************************************************************
+ * Name: cmd_cmp
+ ****************************************************************************/
+
+#if CONFIG_NFILE_DESCRIPTORS > 0
+#ifndef CONFIG_NSH_DISABLE_CMP
+int cmd_cmp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
+{
+ FAR char *path1 = NULL;
+ FAR char *path2 = NULL;
+ off_t total_read = 0;
+ int fd1 = -1;
+ int fd2 = -1;
+ int ret = ERROR;
+
+ /* Get the full path to the two files */
+
+ path1 = nsh_getfullpath(vtbl, argv[1]);
+ if (!path1)
+ {
+ nsh_output(vtbl, g_fmtargrequired, argv[0]);
+ goto errout;
+ }
+
+ path2 = nsh_getfullpath(vtbl, argv[2]);
+ if (!path2)
+ {
+ nsh_output(vtbl, g_fmtargrequired, argv[0]);
+ goto errout_with_path1;
+ }
+
+ /* Open the files for reading */
+
+ fd1 = open(path1, O_RDONLY);
+ if (fd1 < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
+ goto errout_with_path2;
+ }
+
+ fd2 = open(path2, O_RDONLY);
+ if (fd2 < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
+ goto errout_with_fd1;
+ }
+
+ /* The loop until we hit the end of file or find a difference in the two
+ * files.
+ */
+
+ for (;;)
+ {
+ char buf1[128];
+ char buf2[128];
+
+ /* Read the file data */
+
+ ssize_t nbytesread1 = read(fd1, buf1, sizeof(buf1));
+ ssize_t nbytesread2 = read(fd2, buf2, sizeof(buf2));
+
+ if (nbytesread1 < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
+ goto errout_with_fd2;
+ }
+
+ if (nbytesread2 < 0)
+ {
+ nsh_output(vtbl, g_fmtcmdfailed, argv[0], "read", NSH_ERRNO);
+ goto errout_with_fd2;
+ }
+
+ total_read += nbytesread1 > nbytesread2 ? nbytesread2 : nbytesread1;
+
+ /* Compare the file data */
+
+ if (nbytesread1 != nbytesread2 ||
+ memcmp(buf1, buf2, nbytesread1) != 0)
+ {
+ nsh_output(vtbl, "files differ: byte %u\n", total_read);
+ goto errout_with_fd2;
+ }
+
+ /* A partial read indicates the end of file (usually) */
+
+ if (nbytesread1 < sizeof(buf1))
+ {
+ break;
+ }
+ }
+
+ /* The files are the same, i.e., the end of file was encountered
+ * without finding any differences.
+ */
+
+ ret = OK;
+
+errout_with_fd2:
+ close(fd2);
+errout_with_fd1:
+ close(fd1);
+errout_with_path2:
+ nsh_freefullpath(path2);
+errout_with_path1:
+ nsh_freefullpath(path1);
+errout:
+ return ret;
+}
+#endif
+#endif
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index 5722023d3..3f17149f5 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -175,6 +175,9 @@ static const struct cmdmap_s g_cmdmap[] =
# ifndef CONFIG_NSH_DISABLE_CP
{ "cp", cmd_cp, 3, 3, "<source-path> <dest-path>" },
# endif
+# ifndef CONFIG_NSH_DISABLE_CMP
+ { "cmp", cmd_cmp, 3, 3, "<path1> <path2>" },
+# endif
#endif
#if defined (CONFIG_RTC) && !defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_NSH_DISABLE_DATE)