|
|
1.1 ! root 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 are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)uudecode.c 5.10 (Berkeley) 6/1/90"; ! 22: #endif /* not lint */ ! 23: ! 24: /* ! 25: * uudecode [file ...] ! 26: * ! 27: * create the specified file, decoding as you go. ! 28: * used with uuencode. ! 29: */ ! 30: #include <sys/param.h> ! 31: #include <sys/stat.h> ! 32: #include <pwd.h> ! 33: #include <stdio.h> ! 34: #include <string.h> ! 35: ! 36: char *filename; ! 37: ! 38: /* ARGSUSED */ ! 39: main(argc, argv) ! 40: int argc; ! 41: char **argv; ! 42: { ! 43: extern int errno; ! 44: int rval; ! 45: ! 46: if (*++argv) { ! 47: rval = 0; ! 48: do { ! 49: if (!freopen(filename = *argv, "r", stdin)) { ! 50: (void)fprintf(stderr, "uudecode: %s: %s\n", ! 51: *argv, strerror(errno)); ! 52: rval = 1; ! 53: continue; ! 54: } ! 55: rval |= decode(); ! 56: } while (*++argv); ! 57: } else { ! 58: filename = "stdin"; ! 59: rval = decode(); ! 60: } ! 61: exit(rval); ! 62: } ! 63: ! 64: decode() ! 65: { ! 66: extern int errno; ! 67: struct passwd *pw; ! 68: register int n; ! 69: register char ch, *p; ! 70: int mode, n1; ! 71: char buf[MAXPATHLEN]; ! 72: ! 73: /* search for header line */ ! 74: do { ! 75: if (!fgets(buf, sizeof(buf), stdin)) { ! 76: (void)fprintf(stderr, ! 77: "uudecode: %s: no \"begin\" line\n", filename); ! 78: return(1); ! 79: } ! 80: } while (strncmp(buf, "begin ", 6)); ! 81: (void)sscanf(buf, "begin %o %s", &mode, buf); ! 82: ! 83: /* handle ~user/file format */ ! 84: if (buf[0] == '~') { ! 85: if (!(p = index(buf, '/'))) { ! 86: (void)fprintf(stderr, "uudecode: %s: illegal ~user.\n", ! 87: filename); ! 88: return(1); ! 89: } ! 90: *p++ = NULL; ! 91: if (!(pw = getpwnam(buf + 1))) { ! 92: (void)fprintf(stderr, "uudecode: %s: no user %s.\n", ! 93: filename, buf); ! 94: return(1); ! 95: } ! 96: n = strlen(pw->pw_dir); ! 97: n1 = strlen(p); ! 98: if (n + n1 + 2 > MAXPATHLEN) { ! 99: (void)fprintf(stderr, "uudecode: %s: path too long.\n", ! 100: filename); ! 101: return(1); ! 102: } ! 103: bcopy(p, buf + n + 1, n1 + 1); ! 104: bcopy(pw->pw_dir, buf, n); ! 105: buf[n] = '/'; ! 106: } ! 107: ! 108: /* create output file, set mode */ ! 109: if (!freopen(buf, "w", stdout) || ! 110: fchmod(fileno(stdout), mode&0666)) { ! 111: (void)fprintf(stderr, "uudecode: %s: %s: %s\n", buf, ! 112: filename, strerror(errno)); ! 113: return(1); ! 114: } ! 115: ! 116: /* for each input line */ ! 117: for (;;) { ! 118: if (!fgets(p = buf, sizeof(buf), stdin)) { ! 119: (void)fprintf(stderr, "uudecode: %s: short file.\n", ! 120: filename); ! 121: return(1); ! 122: } ! 123: #define DEC(c) (((c) - ' ') & 077) /* single character decode */ ! 124: /* ! 125: * `n' is used to avoid writing out all the characters ! 126: * at the end of the file. ! 127: */ ! 128: if ((n = DEC(*p)) <= 0) ! 129: break; ! 130: for (++p; n > 0; p += 4, n -= 3) ! 131: if (n >= 3) { ! 132: ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; ! 133: putchar(ch); ! 134: ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; ! 135: putchar(ch); ! 136: ch = DEC(p[2]) << 6 | DEC(p[3]); ! 137: putchar(ch); ! 138: } ! 139: else { ! 140: if (n >= 1) { ! 141: ch = DEC(p[0]) << 2 | DEC(p[1]) >> 4; ! 142: putchar(ch); ! 143: } ! 144: if (n >= 2) { ! 145: ch = DEC(p[1]) << 4 | DEC(p[2]) >> 2; ! 146: putchar(ch); ! 147: } ! 148: if (n >= 3) { ! 149: ch = DEC(p[2]) << 6 | DEC(p[3]); ! 150: putchar(ch); ! 151: } ! 152: } ! 153: } ! 154: if (!fgets(buf, sizeof(buf), stdin) || strcmp(buf, "end\n")) { ! 155: (void)fprintf(stderr, "uudecode: %s: no \"end\" line.\n", ! 156: filename); ! 157: return(1); ! 158: } ! 159: return(0); ! 160: } ! 161: ! 162: usage() ! 163: { ! 164: (void)fprintf(stderr, "usage: uudecode [file ...]\n"); ! 165: exit(1); ! 166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.