134953Sbostic /* 2*62415Sbostic * Copyright (c) 1983, 1993 3*62415Sbostic * The Regents of the University of California. All rights reserved. 434953Sbostic * 542781Sbostic * %sccs.include.redist.c% 634953Sbostic */ 734953Sbostic 813681Ssam #ifndef lint 9*62415Sbostic static char sccsid[] = "@(#)uudecode.c 8.1 (Berkeley) 06/06/93"; 1034953Sbostic #endif /* not lint */ 1113681Ssam 1213681Ssam /* 1338475Sbostic * uudecode [file ...] 1413681Ssam * 1513681Ssam * create the specified file, decoding as you go. 1613681Ssam * used with uuencode. 1713681Ssam */ 1838475Sbostic #include <sys/param.h> 1937845Sbostic #include <sys/stat.h> 2038475Sbostic #include <pwd.h> 2113681Ssam #include <stdio.h> 2242049Sbostic #include <string.h> 2313681Ssam 2438475Sbostic char *filename; 2513681Ssam 2638475Sbostic /* ARGSUSED */ 2713681Ssam main(argc, argv) 2838475Sbostic int argc; 2938475Sbostic char **argv; 3013681Ssam { 3138475Sbostic extern int errno; 3238475Sbostic int rval; 3313681Ssam 3438475Sbostic if (*++argv) { 3538475Sbostic rval = 0; 3638475Sbostic do { 3738475Sbostic if (!freopen(filename = *argv, "r", stdin)) { 3838475Sbostic (void)fprintf(stderr, "uudecode: %s: %s\n", 3938475Sbostic *argv, strerror(errno)); 4038475Sbostic rval = 1; 4138475Sbostic continue; 4238475Sbostic } 4338475Sbostic rval |= decode(); 4438475Sbostic } while (*++argv); 4538475Sbostic } else { 4638475Sbostic filename = "stdin"; 4738475Sbostic rval = decode(); 4813681Ssam } 4938475Sbostic exit(rval); 5038475Sbostic } 5113681Ssam 5238475Sbostic decode() 5338475Sbostic { 5438475Sbostic extern int errno; 5538475Sbostic struct passwd *pw; 5638475Sbostic register int n; 5738475Sbostic register char ch, *p; 5838475Sbostic int mode, n1; 5938475Sbostic char buf[MAXPATHLEN]; 6038475Sbostic 6113681Ssam /* search for header line */ 6238475Sbostic do { 6338475Sbostic if (!fgets(buf, sizeof(buf), stdin)) { 6438475Sbostic (void)fprintf(stderr, 6538475Sbostic "uudecode: %s: no \"begin\" line\n", filename); 6638475Sbostic return(1); 6713681Ssam } 6838475Sbostic } while (strncmp(buf, "begin ", 6)); 6938475Sbostic (void)sscanf(buf, "begin %o %s", &mode, buf); 7013681Ssam 7113681Ssam /* handle ~user/file format */ 7238475Sbostic if (buf[0] == '~') { 7338475Sbostic if (!(p = index(buf, '/'))) { 7438475Sbostic (void)fprintf(stderr, "uudecode: %s: illegal ~user.\n", 7538475Sbostic filename); 7638475Sbostic return(1); 7713681Ssam } 7838475Sbostic *p++ = NULL; 7938475Sbostic if (!(pw = getpwnam(buf + 1))) { 8038475Sbostic (void)fprintf(stderr, "uudecode: %s: no user %s.\n", 8138475Sbostic filename, buf); 8238475Sbostic return(1); 8313681Ssam } 8438475Sbostic n = strlen(pw->pw_dir); 8538475Sbostic n1 = strlen(p); 8638475Sbostic if (n + n1 + 2 > MAXPATHLEN) { 8738475Sbostic (void)fprintf(stderr, "uudecode: %s: path too long.\n", 8838475Sbostic filename); 8938475Sbostic return(1); 9038475Sbostic } 9138475Sbostic bcopy(p, buf + n + 1, n1 + 1); 9238475Sbostic bcopy(pw->pw_dir, buf, n); 9338475Sbostic buf[n] = '/'; 9413681Ssam } 9513681Ssam 9638475Sbostic /* create output file, set mode */ 9738720Sbostic if (!freopen(buf, "w", stdout) || 9838720Sbostic fchmod(fileno(stdout), mode&0666)) { 9938475Sbostic (void)fprintf(stderr, "uudecode: %s: %s: %s\n", buf, 10038475Sbostic filename, strerror(errno)); 10138475Sbostic return(1); 10213681Ssam } 10313681Ssam 10438475Sbostic /* for each input line */ 10513681Ssam for (;;) { 10638475Sbostic if (!fgets(p = buf, sizeof(buf), stdin)) { 10738475Sbostic (void)fprintf(stderr, "uudecode: %s: short file.\n", 10838475Sbostic filename); 10938475Sbostic return(1); 11013681Ssam } 11138475Sbostic #define DEC(c) (((c) - ' ') & 077) /* single character decode */ 11238475Sbostic /* 11338475Sbostic * `n' is used to avoid writing out all the characters 11438475Sbostic * at the end of the file. 11538475Sbostic */ 11638475Sbostic if ((n = DEC(*p)) <= 0) 11713681Ssam break; 11838475Sbostic for (++p; n > 0; p += 4, n -= 3) 11938475Sbostic if (n >= 3) { 12038475Sbostic ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; 12138475Sbostic putchar(ch); 12238475Sbostic ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; 12338475Sbostic putchar(ch); 12438475Sbostic ch = DEC(p[2]) << 6 | DEC(p[3]); 12538475Sbostic putchar(ch); 12638475Sbostic } 12738475Sbostic else { 12838475Sbostic if (n >= 1) { 12938475Sbostic ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; 13038475Sbostic putchar(ch); 13138475Sbostic } 13238475Sbostic if (n >= 2) { 13338475Sbostic ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; 13438475Sbostic putchar(ch); 13538475Sbostic } 13638475Sbostic if (n >= 3) { 13738475Sbostic ch = DEC(p[2]) << 6 | DEC(p[3]); 13838475Sbostic putchar(ch); 13938475Sbostic } 14038475Sbostic } 14113681Ssam } 14238475Sbostic if (!fgets(buf, sizeof(buf), stdin) || strcmp(buf, "end\n")) { 14338475Sbostic (void)fprintf(stderr, "uudecode: %s: no \"end\" line.\n", 14438475Sbostic filename); 14538475Sbostic return(1); 14638475Sbostic } 14738475Sbostic return(0); 14813681Ssam } 14913681Ssam 15038475Sbostic usage() 15113681Ssam { 15238475Sbostic (void)fprintf(stderr, "usage: uudecode [file ...]\n"); 15338475Sbostic exit(1); 15413681Ssam } 155