#!/usr/bin/nawk -f
# uu2b64: convert uuencoded file to base64
# $Id$
#
# Possible usage:
# tar cf -
| compress -c | uuencode "${EXP_FNAME}.tar.Z" | nawk -f uu2b64
BEGIN {
ORS = "";
for (i = 32; i < 96; i++) {
uuchars = uuchars sprintf("%c", i);
}
b64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
b64chars = b64chars "abcdefghijklmnopqrstuvwxyz";
b64chars = b64chars "0123456789+/";
}
#
# convert a string of uuencoded characters to base64 characters
#
function uu2b64 (uustring, b64string) {
for (i = 1; i <= length(uustring); i++) {
if (val = index(uuchars, substr(uustring, i, 1))) {
b64string = b64string substr(b64chars, val, 1);
}
}
return b64string;
}
# uuencode and base64 both follow a 3-bytes => 4-printable-characters scheme.
# base64 specifies that when the input is not a multiple of three, that bytes
# of all zeroes be encoded. uuencode, however, leaves slop it its remaining
# bits, and instead has a length of valid bytes (not sextets) specified as the
# first character of each line.
# so, sex2() and sex3() will "clean up" the 2nd or 3rd sextet that was left
# behind by uuencode, assuming the 2nd or 3rd byte is invalid.
function sex2 (uuchar, uuvalue, clean) {
uuvalue = index(uuchars, uuchar) - 1;
clean = 16 * int(uuvalue / 16);
return substr(b64chars, clean + 1, 1);
}
function sex3 (uuchar, uuvalue, clean) {
uuvalue = index(uuchars, uuchar) - 1;
clean = 4 * int(uuvalue / 4);
return substr(b64chars, clean + 1, 1);
}
# main loop assumes that only the last line of uuencode output may have
# a number of valid bytes not divisible by three.
! /(^begin |^end$|^ $)/ {
uubytes = index(uuchars, substr($0, 1, 1)) - 1;
trios = int(uubytes / 3);
clean = trios * 4;
cruft = uubytes % 3;
print uu2b64(substr($0, 2, clean));
if (cruft != 0) {
print uu2b64(substr($0, 2 + clean, 1));
if (cruft == 1) {
print sex2(substr($0, 3 + clean, 1)) "==";
} else {
print uu2b64(substr($0, 3 + clean, 1));
print sex3(substr($0, 4 + clean, 1)) "=";
}
}
print "\n";
}