1/* 2 * xorimage.c - partially based on OpenWrt's addpattern.c 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19 20#include <stdio.h> 21#include <stdlib.h> 22#include <string.h> 23#include <stdint.h> 24#include <time.h> 25#include <unistd.h> 26#include <sys/stat.h> 27 28static char default_pattern[] = "12345678"; 29 30 31int xor_data(uint8_t *data, size_t len, const uint8_t *pattern, int p_len, int p_off) 32{ 33 int offset = p_off; 34 while (len--) { 35 *data ^= pattern[offset]; 36 data++; 37 offset = (offset + 1) % p_len; 38 } 39 return offset; 40} 41 42 43void usage(void) __attribute__ (( __noreturn__ )); 44 45void usage(void) 46{ 47 fprintf(stderr, "Usage: xorimage [-i infile] [-o outfile] [-p <pattern>]\n"); 48 exit(EXIT_FAILURE); 49} 50 51 52int main(int argc, char **argv) 53{ 54 char buf[1024]; /* keep this at 1k or adjust garbage calc below */ 55 FILE *in = stdin; 56 FILE *out = stdout; 57 char *ifn = NULL; 58 char *ofn = NULL; 59 const char *pattern = default_pattern; 60 int c; 61 int v0, v1, v2; 62 size_t n; 63 int p_len, p_off = 0; 64 65 while ((c = getopt(argc, argv, "i:o:p:h")) != -1) { 66 switch (c) { 67 case 'i': 68 ifn = optarg; 69 break; 70 case 'o': 71 ofn = optarg; 72 break; 73 case 'p': 74 pattern = optarg; 75 break; 76 case 'h': 77 default: 78 usage(); 79 } 80 } 81 82 if (optind != argc || optind == 1) { 83 fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); 84 usage(); 85 } 86 87 if (ifn && !(in = fopen(ifn, "r"))) { 88 fprintf(stderr, "can not open \"%s\" for reading\n", ifn); 89 usage(); 90 } 91 92 if (ofn && !(out = fopen(ofn, "w"))) { 93 fprintf(stderr, "can not open \"%s\" for writing\n", ofn); 94 usage(); 95 } 96 97 p_len = strlen(pattern); 98 99 if (p_len == 0) { 100 fprintf(stderr, "pattern cannot be empty\n"); 101 usage(); 102 } 103 104 105 while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { 106 if (n < sizeof(buf)) { 107 if (ferror(in)) { 108 FREAD_ERROR: 109 fprintf(stderr, "fread error\n"); 110 return EXIT_FAILURE; 111 } 112 } 113 114 p_off = xor_data(buf, n, pattern, p_len, p_off); 115 116 if (!fwrite(buf, n, 1, out)) { 117 FWRITE_ERROR: 118 fprintf(stderr, "fwrite error\n"); 119 return EXIT_FAILURE; 120 } 121 } 122 123 if (ferror(in)) { 124 goto FREAD_ERROR; 125 } 126 127 if (fflush(out)) { 128 goto FWRITE_ERROR; 129 } 130 131 fclose(in); 132 fclose(out); 133 134 return EXIT_SUCCESS; 135} 136