]>
Commit | Line | Data |
---|---|---|
a306f2dd | 1 | /* |
2 | * base-64 encoding pinched from lynx2-7-2, who pinched it from rpem. | |
3 | * Originally written by Mark Riordan 12 August 1990 and 17 Feb 1991 | |
4 | * and placed in the public domain. | |
5 | * | |
6 | * Dug Song <dugsong@UMICH.EDU> | |
7 | */ | |
8 | ||
9 | #include "includes.h" | |
10 | #include "xmalloc.h" | |
11 | ||
12 | char six2pr[64] = { | |
13 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', | |
14 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | |
15 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | |
16 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |
17 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' | |
18 | }; | |
19 | ||
20 | unsigned char pr2six[256]; | |
21 | ||
22 | int | |
23 | uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded) | |
24 | { | |
25 | /* ENC is the basic 1 character encoding function to make a char printing */ | |
26 | #define ENC(c) six2pr[c] | |
27 | ||
28 | register char *outptr = bufcoded; | |
29 | unsigned int i; | |
30 | ||
31 | for (i = 0; i < nbytes; i += 3) { | |
32 | *(outptr++) = ENC(*bufin >> 2); /* c1 */ | |
33 | *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /* c2 */ | |
34 | *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03)); /* c3 */ | |
35 | *(outptr++) = ENC(bufin[2] & 077); /* c4 */ | |
36 | bufin += 3; | |
37 | } | |
38 | if (i == nbytes + 1) { | |
39 | outptr[-1] = '='; | |
40 | } else if (i == nbytes + 2) { | |
41 | outptr[-1] = '='; | |
42 | outptr[-2] = '='; | |
43 | } else if (i == nbytes) { | |
44 | *(outptr++) = '='; | |
45 | } | |
46 | *outptr = '\0'; | |
47 | return (outptr - bufcoded); | |
48 | } | |
49 | ||
50 | int | |
51 | uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize) | |
52 | { | |
53 | /* single character decode */ | |
54 | #define DEC(c) pr2six[(unsigned char)c] | |
55 | #define MAXVAL 63 | |
56 | ||
57 | static int first = 1; | |
58 | int nbytesdecoded, j; | |
59 | const char *bufin = bufcoded; | |
60 | register unsigned char *bufout = bufplain; | |
61 | register int nprbytes; | |
62 | ||
63 | /* If this is the first call, initialize the mapping table. */ | |
64 | if (first) { | |
65 | first = 0; | |
66 | for (j = 0; j < 256; j++) | |
67 | pr2six[j] = MAXVAL + 1; | |
68 | for (j = 0; j < 64; j++) | |
69 | pr2six[(unsigned char) six2pr[j]] = (unsigned char) j; | |
70 | } | |
71 | /* Strip leading whitespace. */ | |
72 | while (*bufcoded == ' ' || *bufcoded == '\t') | |
73 | bufcoded++; | |
74 | ||
75 | /* | |
76 | * Figure out how many characters are in the input buffer. If this | |
77 | * would decode into more bytes than would fit into the output | |
78 | * buffer, adjust the number of input bytes downwards. | |
79 | */ | |
80 | bufin = bufcoded; | |
81 | while (DEC(*(bufin++)) <= MAXVAL) | |
82 | ; | |
83 | nprbytes = bufin - bufcoded - 1; | |
84 | nbytesdecoded = ((nprbytes + 3) / 4) * 3; | |
85 | if (nbytesdecoded > outbufsize) | |
86 | nprbytes = (outbufsize * 4) / 3; | |
87 | ||
88 | bufin = bufcoded; | |
89 | ||
90 | while (nprbytes > 0) { | |
91 | *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4); | |
92 | *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2); | |
93 | *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3])); | |
94 | bufin += 4; | |
95 | nprbytes -= 4; | |
96 | } | |
97 | if (nprbytes & 03) { | |
98 | if (DEC(bufin[-2]) > MAXVAL) | |
99 | nbytesdecoded -= 2; | |
100 | else | |
101 | nbytesdecoded -= 1; | |
102 | } | |
103 | return (nbytesdecoded); | |
104 | } | |
105 | ||
106 | void | |
107 | dump_base64(FILE *fp, unsigned char *data, int len) | |
108 | { | |
109 | unsigned char *buf = xmalloc(2*len); | |
110 | int i, n; | |
111 | n = uuencode(data, len, buf); | |
112 | for (i = 0; i < n; i++) { | |
113 | fprintf(fp, "%c", buf[i]); | |
114 | if (i % 70 == 69) | |
115 | fprintf(fp, "\n"); | |
116 | } | |
117 | if (i % 70 != 69) | |
118 | fprintf(fp, "\n"); | |
119 | xfree(buf); | |
120 | } |