update madwifi
[linux-2.6/zen-sources.git] / drivers / net / wireless / madwifi / ath_hal / uudecode.c
blobadfd5707dc2c617426f81fe7a48aeaa2409ddeb7
1 /*
2 * GPLv2
3 * Copyright 2003, Glenn McGrath <bug1@iinet.net.au>
4 * Copyright 2006, Pavel Roskin <proski@gnu.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as published
8 * by the Free Software Foundation; either version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Based on specification from
20 * http://www.opengroup.org/onlinepubs/007904975/utilities/uuencode.html
22 * Bugs: the spec doesn't mention anything about "`\n`\n" prior to the "end" line
26 #include <stdio.h>
27 #include <errno.h>
28 #include <getopt.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <sys/fcntl.h>
33 #include <sys/stat.h>
35 static void uudecode_usage(void)
37 printf("Usage: uudecode [-o OUTFILE] [INFILE]\n");
40 static char *get_line_from_file(FILE *file)
42 int ch;
43 int idx = 0;
44 static char linebuf[80];
46 while ((ch = getc(file)) != EOF) {
47 linebuf[idx++] = (char)ch;
48 if (!ch)
49 return linebuf;
50 if (ch == '\n') {
51 --idx;
52 break;
54 /* Dumb overflow protection */
55 if (idx >= (int)sizeof(linebuf))
56 idx--;
58 if (ferror(file))
59 return NULL;
61 linebuf[idx] = 0;
62 if (idx > 0 && linebuf[idx - 1] == '\r')
63 linebuf[idx - 1] = 0;
65 return linebuf;
68 #define char_val(n) ((line_ptr[n] - 0x20) & 0x3f)
70 static void read_stduu(FILE *src_stream, FILE *dst_stream)
72 char *line;
74 while ((line = get_line_from_file(src_stream)) != NULL) {
75 int length;
76 char *line_ptr = line;
78 if (strcmp(line, "end") == 0)
79 return;
80 length = char_val(0) * 4 / 3;
82 /* Ignore the "`\n" line, why is it even in the encode file ? */
83 if (length <= 0)
84 continue;
86 if (length > 60) {
87 fprintf(stderr, "uudecode: Line too long\n");
88 exit(1);
91 line_ptr++;
92 /* Tolerate an overly long line to accommodate an extra '`' */
93 if ((int)strlen(line_ptr) < length) {
94 fprintf(stderr, "uudecode: Short line detected\n");
95 exit(1);
98 while (length > 0) {
99 /* Merge four 6 bit chars to three 8 bit chars */
100 fputc(char_val(0) << 2 | char_val(1) >> 4, dst_stream);
101 line_ptr++;
102 if (--length == 0)
103 break;
105 fputc(char_val(0) << 4 | char_val(1) >> 2, dst_stream);
106 line_ptr++;
107 if (--length == 0)
108 break;
110 fputc(char_val(0) << 6 | char_val(1), dst_stream);
111 line_ptr += 2;
112 length -= 2;
115 fprintf(stderr, "uudecode: no `end' found\n");
116 exit(1);
119 int main(int argc, char **argv)
121 FILE *src_stream;
122 FILE *dst_stream = NULL;
123 char *outname = NULL;
124 char *line;
125 int mode;
126 char *line_ptr = NULL;
127 int c;
128 int forced_output = 0;
130 while ((c = getopt (argc, argv, "o:")) != -1)
131 switch (c) {
132 case 'o':
133 forced_output = 1;
134 outname = optarg;
135 break;
136 default:
137 uudecode_usage();
138 exit(1);
141 if (optind == argc) {
142 src_stream = stdin;
143 } else if (optind + 1 == argc) {
144 src_stream = fopen(argv[optind], "rt");
145 if (!src_stream) {
146 fprintf(stderr, "uudecode: Cannot open \"%s\": %s\n",
147 argv[optind], strerror(errno));
148 exit(1);
150 } else {
151 uudecode_usage();
152 exit(1);
155 /* Search for the start of the encoding */
156 while ((line = get_line_from_file(src_stream)) != NULL) {
157 if (strncmp(line, "begin ", 6) == 0) {
158 line_ptr = line + 6;
159 break;
163 if (!line_ptr) {
164 fprintf(stderr, "uudecode: No `begin' line\n");
165 exit(1);
168 mode = strtoul(line_ptr, NULL, 8);
169 if (outname == NULL) {
170 outname = strchr(line_ptr, ' ');
171 if ((outname == NULL) || (*outname == '\0')) {
172 fprintf(stderr, "uudecode: No file name specified\n");
173 exit(1);
175 outname++;
178 if (forced_output && (strcmp(outname, "-") == 0)) {
179 dst_stream = stdout;
180 } else {
181 int fd;
182 int flags = O_WRONLY | O_CREAT | O_TRUNC;
184 /* don't clobber files without an explicit "-o" */
185 if (!forced_output)
186 flags |= O_EXCL;
188 fd = open(outname, flags,
189 mode & (S_IRWXU | S_IRWXG | S_IRWXO));
190 if (fd != -1)
191 dst_stream = fdopen(fd, "wb");
192 if ((fd == -1) || !dst_stream) {
193 fprintf(stderr, "uudecode: Cannot open \"%s\": %s\n",
194 outname, strerror(errno));
195 exit(1);
199 read_stduu(src_stream, dst_stream);
200 if (src_stream != stdin)
201 fclose(src_stream);
202 if (dst_stream != stdout)
203 fclose(dst_stream);
204 return 0;