firmware-utils/mktplinkfw: add support for GL.iNet v1
[openwrt.git] / tools / firmware-utils / src / buffalo-tftp.c
1 /*
2  * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <libgen.h>
15 #include <getopt.h>     /* for getopt() */
16 #include <stdarg.h>
17
18 #include "buffalo-lib.h"
19
20 #define ERR(fmt, args...) do { \
21         fflush(0); \
22         fprintf(stderr, "[%s] *** error: " fmt "\n", \
23                         progname, ## args ); \
24 } while (0)
25
26 static char *progname;
27 static char *ifname;
28 static char *ofname;
29 static int do_decrypt;
30
31 void usage(int status)
32 {
33         FILE *stream = (status != EXIT_SUCCESS) ? stderr : stdout;
34
35         fprintf(stream, "Usage: %s [OPTIONS...]\n", progname);
36         fprintf(stream,
37 "\n"
38 "Options:\n"
39 "  -d              decrypt instead of encrypt\n"
40 "  -i <file>       read input from the file <file>\n"
41 "  -o <file>       write output to the file <file>\n"
42 "  -h              show this screen\n"
43         );
44
45         exit(status);
46 }
47
48 static const unsigned char *crypt_key1 = (unsigned char *)
49         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
50 static const unsigned char *crypt_key2 = (unsigned char *)
51         "XYZ0123hijklmnopqABCDEFGHrstuvabcdefgwxyzIJKLMSTUVW456789NOPQR";
52
53 static void crypt_header(unsigned char *buf, ssize_t len,
54                          const unsigned char *key1, const unsigned char *key2)
55 {
56         ssize_t i;
57
58         for (i = 0; i < len; i++) {
59                 unsigned int j;
60
61                 for (j = 0; key1[j]; j++)
62                         if (buf[i] == key1[j]) {
63                                 buf[i] = key2[j];
64                                 break;
65                         }
66         }
67 }
68
69 static int crypt_file(void)
70 {
71         unsigned char *buf = NULL;
72         ssize_t src_len;
73         ssize_t crypt_len;
74         int err;
75         int ret = -1;
76
77         src_len = get_file_size(ifname);
78         if (src_len < 0) {
79                 ERR("unable to get size of '%s'", ifname);
80                 goto out;
81         }
82
83         buf = malloc(src_len);
84         if (buf == NULL) {
85                 ERR("no memory for the buffer");
86                 goto out;
87         }
88
89         err = read_file_to_buf(ifname, buf, src_len);
90         if (err) {
91                 ERR("unable to read from file '%s'", ifname);
92                 goto out;
93         }
94
95         crypt_len = (src_len > 512) ? 512 : src_len;
96         if (do_decrypt)
97                 crypt_header(buf, 512, crypt_key2, crypt_key1);
98         else
99                 crypt_header(buf, 512, crypt_key1, crypt_key2);
100
101         err = write_buf_to_file(ofname, buf, src_len);
102         if (err) {
103                 ERR("unable to write to file '%s'", ofname);
104                 goto out;
105         }
106
107         ret = 0;
108
109 out:
110         free(buf);
111         return ret;
112 }
113
114 static int check_params(void)
115 {
116         int ret = -1;
117
118         if (ifname == NULL) {
119                 ERR("no input file specified");
120                 goto out;
121         }
122
123         if (ofname == NULL) {
124                 ERR("no output file specified");
125                 goto out;
126         }
127
128         ret = 0;
129
130 out:
131         return ret;
132 }
133
134 int main(int argc, char *argv[])
135 {
136         int res = EXIT_FAILURE;
137         int err;
138
139         progname = basename(argv[0]);
140
141         while ( 1 ) {
142                 int c;
143
144                 c = getopt(argc, argv, "di:o:h");
145                 if (c == -1)
146                         break;
147
148                 switch (c) {
149                 case 'd':
150                         do_decrypt = 1;
151                         break;
152                 case 'i':
153                         ifname = optarg;
154                         break;
155                 case 'o':
156                         ofname = optarg;
157                         break;
158                 case 'h':
159                         usage(EXIT_SUCCESS);
160                         break;
161                 default:
162                         usage(EXIT_FAILURE);
163                         break;
164                 }
165         }
166
167         err = check_params();
168         if (err)
169                 goto out;
170
171         err = crypt_file();
172         if (err)
173                 goto out;
174
175         res = EXIT_SUCCESS;
176
177 out:
178         return res;
179 }