#!/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"; }