Stop the analysis pass in Loopy's redraw routine from being
[sgt/puzzles] / obfusc.c
1 /*
2 * Stand-alone tool to access the Puzzles obfuscation algorithm.
3 *
4 * To deobfuscate, use "obfusc -d":
5 *
6 * obfusc -d reads binary data from stdin, writes to stdout
7 * obfusc -d <hex string> works on the given hex string instead of stdin
8 * obfusc -d -h writes a hex string instead of binary to stdout
9 *
10 * To obfuscate, "obfusc -e":
11 *
12 * obfusc -e reads binary from stdin, writes hex to stdout
13 * obfusc -e <hex string> works on the given hex string instead of stdin
14 * obfusc -e -b writes binary instead of text to stdout
15 *
16 * The default output format is hex for -e and binary for -d
17 * because that's the way obfuscation is generally used in
18 * Puzzles. Either of -b and -h can always be specified to set it
19 * explicitly.
20 *
21 * Data read from standard input is assumed always to be binary;
22 * data provided on the command line is taken to be hex.
23 */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #include <errno.h>
30
31 #include "puzzles.h"
32
33 int main(int argc, char **argv)
34 {
35 enum { BINARY, DEFAULT, HEX } outputmode = DEFAULT;
36 char *inhex = NULL;
37 unsigned char *data;
38 int datalen;
39 int decode = -1;
40 int doing_opts = TRUE;
41
42 while (--argc > 0) {
43 char *p = *++argv;
44
45 if (doing_opts && *p == '-') {
46 if (!strcmp(p, "--")) {
47 doing_opts = 0;
48 continue;
49 }
50 p++;
51 while (*p) {
52 switch (*p) {
53 case 'e':
54 decode = 0;
55 break;
56 case 'd':
57 decode = 1;
58 break;
59 case 'b':
60 outputmode = BINARY;
61 break;
62 case 'h':
63 outputmode = HEX;
64 break;
65 default:
66 fprintf(stderr, "obfusc: unrecognised option '-%c'\n",
67 *p);
68 return 1;
69 }
70 p++;
71 }
72 } else {
73 if (!inhex) {
74 inhex = p;
75 } else {
76 fprintf(stderr, "obfusc: expected at most one argument\n");
77 return 1;
78 }
79 }
80 }
81
82 if (decode < 0) {
83 fprintf(stderr, "usage: obfusc < -e | -d > [ -b | -h ] [hex data]\n");
84 return 0;
85 }
86
87 if (outputmode == DEFAULT)
88 outputmode = (decode ? BINARY : HEX);
89
90 if (inhex) {
91 datalen = strlen(inhex) / 2;
92 data = hex2bin(inhex, datalen);
93 } else {
94 int datasize = 4096;
95 datalen = 0;
96 data = snewn(datasize, unsigned char);
97 while (1) {
98 int ret = fread(data + datalen, 1, datasize - datalen, stdin);
99 if (ret < 0) {
100 fprintf(stderr, "obfusc: read: %s\n", strerror(errno));
101 return 1;
102 } else if (ret == 0) {
103 break;
104 } else {
105 datalen += ret;
106 if (datasize - datalen < 4096) {
107 datasize = datalen * 5 / 4 + 4096;
108 data = sresize(data, datasize, unsigned char);
109 }
110 }
111 }
112 }
113
114 obfuscate_bitmap(data, datalen * 8, decode);
115
116 if (outputmode == BINARY) {
117 int ret = fwrite(data, 1, datalen, stdout);
118 if (ret < 0) {
119 fprintf(stderr, "obfusc: write: %s\n", strerror(errno));
120 return 1;
121 }
122 } else {
123 int i;
124 for (i = 0; i < datalen; i++)
125 printf("%02x", data[i]);
126 printf("\n");
127 }
128
129 return 0;
130 }