/* Reads two files, writes their bit-wise XOR. */ /* Last edited on 2013-09-04 18:34:50 by stolfi */ #define PROG_NAME "xor" #define PROG_VERSION "1.0" #define xor_C_copyright \ "Copyright © 2013 Jorge Stolfi, State University of Campinas" #define PROG_HELP \ PROG_NAME " {FILE1} {FILE2} > {OUTFILE}" #define xor_C_rights \ xor_C_copyright ".\n" \ "This file is provided 'as is'; the author and his employer are" \ " not liable for any damages that may result from its use. This" \ " file can be used and modified for any purpose as long as" \ " the copyright and this 'rights' note are preserved in" \ " all copies and derived versions." #define PROG_INFO \ "SYNOPSIS\n" \ "\n" \ " " PROG_HELP "\n" \ "\n" \ "DESCRIPTION\n" \ "\n" \ " Reads two files named {FILE1} and {FILE2}, computes their" \ " bitwise exclusive or (XOR), writes the result to standard" \ " output.\n" \ "\n" \ " Fails if file {FILE1} is longer than {FILE2}.\n" \ "\n" \ " If either {FILE1} or {FILE2} is \"-\", assumes it is standard input.\n" \ "\n" \ "OPTIONS\n" \ "\n" \ " -h\n" \ " --help\n" \ " Prints the SYNOPSIS above.\n" \ "\n" \ " -i\n" \ " --info\n" \ " Prints this manpage.\n" \ "\n" \ "RIGHTS\n" \ "\n" \ " " xor_C_rights "\n" #define _GNU_SOURCE #include #include #include #include FILE *get_in_file(char *name); /* If {name} is "-", returns {stdin}, otherwise returns an open file descriptor on file {name}. in this second case, prints a message to {stderr} and returns NULL if the open failed. */ void arg_error(char *msg); /* Prints {PROG_NAME} and {msg} to {stderr}, then {PROG_HELP}. */ int main(int argc, char **argv); int main(int argc, char **argv) { /* Command line options: */ int iarg = 1; while (iarg < argc) { if ((strcmp(argv[iarg],"-h") == 0) || (strcmp(argv[iarg],"--help") == 0)) { fprintf(stderr, "USAGE: %s\n", PROG_HELP); return 0; } else if ((strcmp(argv[iarg],"-i") == 0) || (strcmp(argv[iarg],"--info") == 0)) { fprintf(stderr, "%s\n", PROG_INFO); return 0; } else { break; } iarg++; } /* Command line arguments: */ if ((argc - iarg) != 2) { arg_error("wrong number of arguments"); return 1; } FILE *a = get_in_file(argv[iarg]); iarg++; FILE *b = get_in_file(argv[iarg]); iarg++; if ((a == NULL) || (b == NULL)) { return 1; } if (a == b) { arg_error("cannot read both files from same file descriptor"); return 1; } int nw = cryptoy_xor_files(a, b, stdout); if (nw < 0) { fprintf(stderr, "aborted.\n"); return 1; } else { return 0; } } FILE *get_in_file(char *name) { fprintf(stderr, "opening \"%s\"... \n", name); if (strlen(name) == 0) { fprintf(stderr, "%s: ** empty file name\n", PROG_NAME); return NULL; } else if (strcmp(name, "-") == 0) { return stdin; } else { FILE *d = fopen(name, "rb"); if (d == NULL) { perror(PROG_NAME); } return d; } } void arg_error(char *msg) { fprintf(stderr, "%s: ** %s\n", PROG_NAME, msg); fprintf(stderr, "%s\n", PROG_HELP); }