annotate toys/posix/uudecode.c @ 840:8a6b36696ca6

Clean uudecode up the rest of the way, move pending->posix and default y.
author Rob Landley <rob@landley.net>
date Tue, 02 Apr 2013 01:34:34 -0500
parents toys/pending/uudecode.c@a315fb343e2b
children
rev   line source
rob@823 1 /* uudecode.c - uudecode / base64 decode
rob@823 2 *
rob@823 3 * Copyright 2013 Erich Plondke <toybox@erich.wreck.org>
rob@823 4 *
rob@823 5 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/uudecode.html
rob@823 6
rob@835 7 USE_UUDECODE(NEWTOY(uudecode, ">1o:", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_UMASK))
rob@823 8
rob@823 9 config UUDECODE
rob@823 10 bool "uudecode"
rob@840 11 default y
rob@823 12 help
rob@834 13 usage: uudecode [-o OUTFILE] [INFILE]
rob@823 14
rob@834 15 Decode file from stdin (or INFILE).
rob@834 16
rob@834 17 -o write to OUTFILE instead of filename in header
rob@823 18 */
rob@823 19
rob@823 20 #define FOR_uudecode
rob@823 21 #include "toys.h"
rob@823 22
rob@823 23 GLOBALS(
rob@823 24 char *o;
rob@823 25 )
rob@823 26
rob@823 27 void uudecode_main(void)
rob@823 28 {
rob@840 29 int ifd = 0, ofd, idx = 0, m = m;
rob@840 30 char *line = 0, mode[16],
rob@839 31 *class[] = {"begin%*[ ]%15s%*[ ]%n", "begin-base64%*[ ]%15s%*[ ]%n"};
rob@839 32
rob@835 33 if (toys.optc) ifd = xopen(*toys.optargs, O_RDONLY);
rob@834 34
rob@840 35 while (!idx) {
rob@839 36 free(line);
rob@839 37 if (!(line = get_line(ifd))) error_exit("bad EOF");
rob@840 38 for (m=0; m < 2; m++) {
rob@839 39 sscanf(line, class[m], mode, &idx);
rob@839 40 if (idx) break;
rob@835 41 }
rob@835 42 }
rob@835 43
rob@840 44 ofd = xcreate(TT.o ? TT.o : line+idx, O_WRONLY|O_CREAT|O_TRUNC,
rob@840 45 string_to_mode(mode, 0777^toys.old_umask));
rob@840 46
rob@840 47 for(;;) {
rob@840 48 char *in, *out;
rob@840 49 int olen;
rob@840 50
rob@839 51 free(line);
rob@840 52 if (m == 2 || !(line = get_line(ifd))) break;
rob@840 53 if (!strcmp(line, m ? "====" : "end")) {
rob@840 54 m = 2;
rob@840 55 continue;
rob@840 56 }
rob@840 57
rob@840 58 olen = 0;
rob@840 59 in = out = line;
rob@840 60 if (!m) olen = (*(in++) - 32) & 0x3f;
rob@840 61
rob@840 62 for (;;) {
rob@840 63 int i = 0, x = 0, len = 4;
rob@840 64 char c = 0;
rob@840 65
rob@840 66 if (!m) {
rob@840 67 if (olen < 1) break;
rob@840 68 if (olen < 3) len = olen + 1;
rob@840 69 }
rob@840 70
rob@840 71 while (i < len) {
rob@840 72 if (!(c = *(in++))) goto line_done;
rob@840 73
rob@840 74 if (m) {
rob@840 75 if (c == '=') {
rob@840 76 len--;
rob@840 77 continue;
rob@840 78 } else if (len != 4) break;
rob@840 79
rob@840 80 if (c >= 'A' && c <= 'Z') c -= 'A';
rob@840 81 else if (c >= 'a' && c <= 'z') c += 26 - 'a';
rob@840 82 else if (c >= '0' && c <= '9') c += 52 - '0';
rob@840 83 else if (c == '+') c = 62;
rob@840 84 else if (c == '/') c = 63;
rob@840 85 else continue;
rob@840 86 } else c = (c - 32) & 0x3f;
rob@840 87
rob@840 88 x |= c << (6*(3-i));
rob@840 89
rob@840 90 if (i && i < len) {
rob@840 91 *(out++) = (x>>(8*(3-i))) & 0xff;
rob@840 92 olen--;
rob@840 93 }
rob@840 94 i++;
rob@840 95 }
rob@840 96
rob@840 97 if (i && i!=len) error_exit("bad %s", line);
rob@840 98 }
rob@840 99 line_done:
rob@840 100 xwrite(ofd, line, out-line);
rob@839 101 }
rob@839 102
rob@835 103 if (CFG_TOYBOX_FREE) {
rob@835 104 if (ifd) close(ifd);
rob@835 105 close(ofd);
rob@835 106 }
rob@823 107 }