"Fossies" - the Free Open Source Software Archive

Member "uuencode-1.0/uudecode.c" (23 Aug 1993, 6797 Bytes) of package /linux/misc/old/uuencode-1.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 /* Reworked to GNU style by Ian Lance Taylor, ian@airs.com, August 93. */
35
36 /* AIX requires this to be the first thing in the file. */
37 #if defined (_AIX) && !defined (__GNUC__)
38 #pragma alloca
39 #endif
40
41 /*
42 * uudecode [file ...]
43 *
44 * create the specified file, decoding as you go.
45 * used with uuencode.
46 */
47 #include <sys/stat.h>
48 #include <pwd.h>
49 #include <stdio.h>
50 #include "getopt.h"
51
52 #ifdef __GNUC__
53 #undef alloca
54 #define alloca(n) __builtin_alloca (n)
55 #else /* Not GCC. */
56 #ifdef HAVE_ALLOCA_H
57 #include <alloca.h>
58 #else /* Not HAVE_ALLOCA_H. */
59 #ifndef _AIX
60 extern char *alloca ();
61 #endif /* Not AIX. */
62 #endif /* HAVE_ALLOCA_H. */
63 #endif /* GCC. */
64
65 /* Get definitions for the file permission bits. */
66
67 #ifndef S_IRWXU
68 #define S_IRWXU 0700
69 #endif
70 #ifndef S_IRUSR
71 #define S_IRUSR 0400
72 #endif
73 #ifndef S_IWUSR
74 #define S_IWUSR 0200
75 #endif
76 #ifndef S_IXUSR
77 #define S_IXUSR 0100
78 #endif
79
80 #ifndef S_IRWXG
81 #define S_IRWXG 0070
82 #endif
83 #ifndef S_IRGRP
84 #define S_IRGRP 0040
85 #endif
86 #ifndef S_IWGRP
87 #define S_IWGRP 0020
88 #endif
89 #ifndef S_IXGRP
90 #define S_IXGRP 0010
91 #endif
92
93 #ifndef S_IRWXO
94 #define S_IRWXO 0007
95 #endif
96 #ifndef S_IROTH
97 #define S_IROTH 0004
98 #endif
99 #ifndef S_IWOTH
100 #define S_IWOTH 0002
101 #endif
102 #ifndef S_IXOTH
103 #define S_IXOTH 0001
104 #endif
105
106 static struct option longopts[] =
107 {
108 { "version", 0, 0, 'v' },
109 { "help", 0, 0, 'h' },
110 { NULL, 0, 0, 0 }
111 };
112
113 #if __STDC__
114 static int decode (char *);
115 static void usage (FILE *, int);
116 #else
117 static int decode ();
118 static void usage ();
119 #endif
120
121 extern char version[];
122 static char *program_name;
123
124 int
125 main (argc, argv)
126 int argc;
127 char **argv;
128 {
129 int opt;
130 int rval;
131
132 program_name = argv[0];
133
134 while ((opt = getopt_long (argc, argv, "hv", longopts, (int *) NULL))
135 != EOF)
136 {
137 switch (opt)
138 {
139 case 'h':
140 printf ("Decode a file created by uuencode\n");
141 usage (stdout, 0);
142
143 case 'v':
144 printf ("%s\n", version);
145 exit (0);
146
147 case 0:
148 break;
149
150 default:
151 usage (stderr, 1);
152 }
153 }
154
155 if (optind == argc)
156 rval = decode ((char *) "stdin");
157 else
158 {
159 char *filename;
160
161 rval = 0;
162 do
163 {
164 if (freopen (argv[optind], "r", stdin) != NULL)
165 rval |= decode (argv[optind]);
166 else
167 {
168 fprintf (stderr, "%s:", program_name);
169 perror (argv[optind]);
170 rval = 1;
171 }
172 ++optind;
173 }
174 while (optind < argc);
175 }
176
177 exit (rval);
178 }
179
180 #define DEC(c) (((c) - ' ') & 077) /* single character decode */
181
182 static int
183 decode (filename)
184 char *filename;
185 {
186 struct passwd *pw;
187 register int n;
188 register char ch, *p;
189 int mode, n1;
190 char buf[2 * BUFSIZ];
191 char *outname;
192
193 /* search for header line */
194 do
195 {
196 if (fgets (buf, sizeof (buf), stdin) == NULL)
197 {
198 fprintf (stderr,
199 "%s:%s: no \"begin\" line\n", program_name, filename);
200 return 1;
201 }
202 }
203 while (strncmp (buf, "begin ", 6) != 0);
204
205 sscanf (buf, "begin %o %s", &mode, buf);
206
207 /* handle ~user/file format */
208 if (buf[0] != '~')
209 outname = buf;
210 else
211 {
212 p = buf + 1;
213 while (*p != '/')
214 ++p;
215 if (*p == '\0')
216 {
217 fprintf (stderr, "%s:%s: illegal ~user\n", program_name,
218 filename);
219 return 1;
220 }
221 *p++ = '\0';
222 pw = getpwnam (buf + 1);
223 if (pw == NULL)
224 {
225 fprintf (stderr, "%s:%s: no user %s\n", program_name,
226 filename, buf + 1);
227 return 1;
228 }
229 n = strlen (pw->pw_dir);
230 n1 = strlen (p);
231 outname = (char *) alloca (n + n1 + 2);
232 memcpy (outname + n + 1, p, n1 + 1);
233 memcpy (outname, pw->pw_dir, n);
234 outname[n] = '/';
235 }
236
237 /* create output file, set mode */
238 if (freopen (outname, "w", stdout) == NULL
239 || fchmod (fileno (stdout),
240 mode & (S_IRWXU | S_IRWXG | S_IRWXO)))
241 {
242 fprintf (stderr, "%s:%s:", program_name, outname);
243 perror (filename);
244 return 1;
245 }
246
247 /* for each input line */
248 while (1)
249 {
250 if (fgets (buf, sizeof(buf), stdin) == NULL)
251 {
252 fprintf (stderr, "%s:%s: short file.\n", program_name,
253 filename);
254 return 1;
255 }
256 p = buf;
257 /*
258 * `n' is used to avoid writing out all the characters
259 * at the end of the file.
260 */
261 n = DEC (*p);
262 if (n <= 0)
263 break;
264 for (++p; n > 0; p += 4, n -= 3)
265 {
266 if (n >= 3)
267 {
268 ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
269 putchar (ch);
270 ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
271 putchar (ch);
272 ch = DEC (p[2]) << 6 | DEC (p[3]);
273 putchar (ch);
274 }
275 else
276 {
277 if (n >= 1)
278 {
279 ch = DEC (p[0]) << 2 | DEC (p[1]) >> 4;
280 putchar (ch);
281 }
282 if (n >= 2)
283 {
284 ch = DEC (p[1]) << 4 | DEC (p[2]) >> 2;
285 putchar (ch);
286 }
287 }
288 }
289 }
290
291 if (fgets (buf, sizeof(buf), stdin) == NULL
292 || strcmp (buf, "end\n"))
293 {
294 fprintf (stderr, "%s:%s: no \"end\" line.\n", program_name,
295 filename);
296 return 1;
297 }
298
299 return 0;
300 }
301
302 static void
303 usage (f, status)
304 FILE *f;
305 int status;
306 {
307 fprintf (f, "usage: %s [file ...]\n", program_name);
308 exit (status);
309 }