1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * xorimage.c - partially based on OpenWrt's addpattern.c 4 */ 5 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <stdbool.h> 11 #include <stdint.h> 12 #include <unistd.h> 13 #include <sys/stat.h> 14 15 static char default_pattern[] = "12345678"; 16 static int is_hex_pattern; 17 18 19 int xor_data(void *data, size_t len, const void *pattern, int p_len, int p_off) 20 { 21 const uint8_t *key = pattern; 22 uint8_t *d = data; 23 24 while (len--) { 25 *d ^= key[p_off]; 26 d++; 27 p_off = (p_off + 1) % p_len; 28 } 29 return p_off; 30 } 31 32 33 void usage(void) __attribute__ (( __noreturn__ )); 34 35 void usage(void) 36 { 37 fprintf(stderr, "Usage: xorimage [-i infile] [-o outfile] [-p <pattern>] [-x]\n"); 38 exit(EXIT_FAILURE); 39 } 40 41 42 int main(int argc, char **argv) 43 { 44 char buf[1024]; /* keep this at 1k or adjust garbage calc below */ 45 FILE *in = stdin; 46 FILE *out = stdout; 47 char *ifn = NULL; 48 char *ofn = NULL; 49 const char *pattern = default_pattern; 50 char hex_pattern[128]; 51 unsigned int hex_buf; 52 int c; 53 size_t n; 54 int p_len, p_off = 0; 55 56 while ((c = getopt(argc, argv, "i:o:p:xh")) != -1) { 57 switch (c) { 58 case 'i': 59 ifn = optarg; 60 break; 61 case 'o': 62 ofn = optarg; 63 break; 64 case 'p': 65 pattern = optarg; 66 break; 67 case 'x': 68 is_hex_pattern = true; 69 break; 70 case 'h': 71 default: 72 usage(); 73 } 74 } 75 76 if (optind != argc || optind == 1) { 77 fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); 78 usage(); 79 } 80 81 if (ifn && !(in = fopen(ifn, "r"))) { 82 fprintf(stderr, "can not open \"%s\" for reading\n", ifn); 83 usage(); 84 } 85 86 if (ofn && !(out = fopen(ofn, "w"))) { 87 fprintf(stderr, "can not open \"%s\" for writing\n", ofn); 88 usage(); 89 } 90 91 p_len = strlen(pattern); 92 93 if (p_len == 0) { 94 fprintf(stderr, "pattern cannot be empty\n"); 95 usage(); 96 } 97 98 if (is_hex_pattern) { 99 int i; 100 101 if ((p_len / 2) > sizeof(hex_pattern)) { 102 fprintf(stderr, "provided hex pattern is too long\n"); 103 usage(); 104 } 105 106 if (p_len % 2 != 0) { 107 fprintf(stderr, "the number of characters (hex) is incorrect\n"); 108 usage(); 109 } 110 111 for (i = 0; i < (p_len / 2); i++) { 112 if (sscanf(pattern + (i * 2), "%2x", &hex_buf) < 0) { 113 fprintf(stderr, "invalid hex digit around %d\n", i * 2); 114 usage(); 115 } 116 hex_pattern[i] = (char)hex_buf; 117 } 118 } 119 120 while ((n = fread(buf, 1, sizeof(buf), in)) > 0) { 121 if (n < sizeof(buf)) { 122 if (ferror(in)) { 123 FREAD_ERROR: 124 fprintf(stderr, "fread error\n"); 125 return EXIT_FAILURE; 126 } 127 } 128 129 if (is_hex_pattern) { 130 p_off = xor_data(buf, n, hex_pattern, (p_len / 2), 131 p_off); 132 } else { 133 p_off = xor_data(buf, n, pattern, p_len, p_off); 134 } 135 136 if (!fwrite(buf, n, 1, out)) { 137 FWRITE_ERROR: 138 fprintf(stderr, "fwrite error\n"); 139 return EXIT_FAILURE; 140 } 141 } 142 143 if (ferror(in)) { 144 goto FREAD_ERROR; 145 } 146 147 if (fflush(out)) { 148 goto FWRITE_ERROR; 149 } 150 151 fclose(in); 152 fclose(out); 153 154 return EXIT_SUCCESS; 155 } 156
This page was automatically generated by LXR 0.3.1. • OpenWrt