summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <lekensteyn@gmail.com>2013-11-30 19:40:55 +0100
committerPeter Wu <lekensteyn@gmail.com>2013-11-30 19:40:55 +0100
commit88179a47fe5871f9af2eba5706fb32d036b7991c (patch)
tree121a4423b297c641614ab456a49b681dfbadd420
parent3deb7268fa2041849b7e69e01545f5df4157c5a0 (diff)
downloadc-files-88179a47fe5871f9af2eba5706fb32d036b7991c.tar.gz
xor-files: xor two files
-rw-r--r--xor-files.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/xor-files.c b/xor-files.c
new file mode 100644
index 0000000..762ad63
--- /dev/null
+++ b/xor-files.c
@@ -0,0 +1,63 @@
+/* Calculates the xor of two files.
+ * Copyright (C) 2013 Peter Wu <lekensteyn@gmail.com>
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+int main(int argc, char **argv) {
+ int fd1, fd2;
+ int r1, r2;
+
+ if (argc < 3)
+ errx(1, "Usage: xor-files file1 file2");
+
+ fd1 = open(argv[1], O_RDONLY);
+ if (fd1 < 0)
+ errx(1, "open(%s)", argv[1]);
+
+ fd2 = open(argv[2], O_RDONLY);
+ if (fd2 < 0)
+ errx(1, "open(%s)", argv[2]);
+
+ do {
+ int errno1, errno2;
+ char buf1[1024], buf2[1024];
+ int i;
+
+ r1 = read(fd1, buf1, sizeof(buf1));
+ errno1 = errno;
+ r2 = read(fd2, buf2, sizeof(buf2));
+ errno2 = errno;
+
+ if (r1 == -1) {
+ errno = errno1;
+ warn("read 1 failed");
+ }
+ if (r2 == -1) {
+ errno = errno2;
+ warn("read 2 failed");
+ }
+
+ if (r1 != r2)
+ warnx("read blocks do not match: %i != %i", r1, r2);
+
+ // in case the sizes are not equal, truncate.
+ if (r2 < r1)
+ r1 = r2;
+
+ if (r1 > 0) {
+ for (i = 0; i < r1; i++)
+ buf1[i] ^= buf2[i];
+
+ write(STDOUT_FILENO, buf1, r1);
+ }
+ } while (r1 > 0 && r1 == r2);
+
+ close(fd1);
+ close(fd2);
+
+ return 0;
+}