annotate toys/pending/uuencode.c @ 828:1fdaba9a7124

uuencode/decode tests and tweaks from Erich Plondke.
author Rob Landley <rob@landley.net>
date Fri, 22 Mar 2013 00:26:12 -0500
parents 0429050a224b
children ce155547bca2
rev   line source
rob@823 1 /* uuencode.c - uuencode / base64 encode
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/uuencode.html
rob@823 6
rob@823 7 USE_UUENCODE(NEWTOY(uuencode, "<1>2m", TOYFLAG_USR|TOYFLAG_BIN))
rob@823 8
rob@823 9 config UUENCODE
rob@823 10 bool "uuencode"
rob@823 11 default n
rob@823 12 help
rob@823 13 usage: uuencode [-m] [file] encode-filename
rob@823 14
rob@823 15 Uuencode or (with -m option) base64-encode stdin or [file],
rob@823 16 with encode-filename in the output, which is sent to stdout.
rob@823 17 */
rob@823 18
rob@823 19 #define FOR_uuencode
rob@823 20 #include "toys.h"
rob@823 21
rob@823 22
rob@823 23
rob@823 24 static void uuencode_b64_3bytes(char *out, const char *in, int bytes)
rob@823 25 {
rob@823 26 static const char *table = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
rob@823 27 "abcdefghijklmnopqrstuvwxyz"
rob@823 28 "0123456789+/";
rob@823 29 unsigned int i,x=0;
rob@823 30 for (i = 0; i < bytes; i++) {
rob@823 31 x |= (in[i] & 0x0ff) << (8*(2-i));
rob@823 32 }
rob@823 33 out[0] = table[(x>>(3*6)) & 0x3f];
rob@823 34 out[1] = table[(x>>(2*6)) & 0x3f];
rob@823 35 out[2] = table[(x>>(1*6)) & 0x3f];
rob@823 36 out[3] = table[(x>>(0*6)) & 0x3f];
rob@823 37 if (bytes <= 1) out[2] = '=';
rob@823 38 if (bytes <= 2) out[3] = '=';
rob@823 39 }
rob@823 40
rob@823 41 static void uuencode_b64_line(char *out, const char *in, int len)
rob@823 42 {
rob@823 43 while (len > 0) {
rob@823 44 uuencode_b64_3bytes(out,in,len < 3 ? len : 3);
rob@823 45 xprintf("%c%c%c%c",out[0],out[1],out[2],out[3]);
rob@823 46 in += 3;
rob@823 47 len -= 3;
rob@823 48 };
rob@823 49 xprintf("\n");
rob@823 50 }
rob@823 51
rob@823 52 static void uuencode_b64(int fd, const char *name)
rob@823 53 {
rob@823 54 int len;
rob@823 55 char *inbuf = toybuf;
rob@823 56 char *outbuf = toybuf+64;
rob@823 57 xprintf("begin-base64 744 %s\n",name);
rob@823 58 do {
rob@823 59 len = xread(fd,inbuf,48);
rob@828 60 if (len > 0) uuencode_b64_line(outbuf,inbuf,len);
rob@823 61 } while (len > 0);
rob@823 62 xprintf("====\n");
rob@823 63 }
rob@823 64
rob@823 65
rob@823 66 static void uuencode_uu_3bytes(char *out, const char *in)
rob@823 67 {
rob@823 68 unsigned int i,x=0;
rob@823 69 for (i = 0; i <= 2; i++) {
rob@823 70 x |= (in[i] & 0x0ff) << (8*(2-i));
rob@823 71 }
rob@823 72 for (i = 0; i <= 3; i++) {
rob@823 73 out[i] = 32 + ((x >> (6*(3-i))) & 0x3f);
rob@823 74 }
rob@823 75 }
rob@823 76
rob@823 77 static void uuencode_uu_line(char *out, const char *in, int len)
rob@823 78 {
rob@823 79 int i;
rob@823 80 if (len == 0) {
rob@823 81 xprintf("`\n");
rob@823 82 return;
rob@823 83 }
rob@823 84 xprintf("%c",len+32);
rob@823 85 for (i = 0; i < len; i += 3) {
rob@823 86 uuencode_uu_3bytes(out,in+i);
rob@823 87 xprintf("%c%c%c%c",out[0],out[1],out[2],out[3]);
rob@823 88 }
rob@823 89 xprintf("\n");
rob@823 90 }
rob@823 91
rob@823 92 static void uuencode_uu(int fd, const char *name)
rob@823 93 {
rob@823 94 int len;
rob@823 95 char *inbuf = toybuf;
rob@823 96 char *outbuf = toybuf+64;
rob@823 97 xprintf("begin 744 %s\n",name);
rob@823 98 do {
rob@823 99 len = xread(fd,inbuf,45);
rob@823 100 uuencode_uu_line(outbuf,inbuf,len);
rob@823 101 } while (len > 0);
rob@823 102 xprintf("end\n");
rob@823 103 }
rob@823 104
rob@823 105 void uuencode_main(void)
rob@823 106 {
rob@823 107 char *encode_filename = toys.optargs[0];
rob@823 108 int fd = 0; /* STDIN */
rob@823 109
rob@823 110 if (toys.optc == 2) {
rob@823 111 fd = xopen(toys.optargs[0],O_RDONLY); // dies if error
rob@823 112 encode_filename = toys.optargs[1];
rob@823 113 }
rob@823 114 if (toys.optflags & FLAG_m) uuencode_b64(fd,encode_filename);
rob@823 115 else uuencode_uu(fd,encode_filename);
rob@823 116 }