Skip to content

Instantly share code, notes, and snippets.

@mainframed
Last active March 20, 2021 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mainframed/4e3511cbf1ebf793e97051269c378525 to your computer and use it in GitHub Desktop.
Save mainframed/4e3511cbf1ebf793e97051269c378525 to your computer and use it in GitHub Desktop.
Rexx script to base64 encode files in TSO, OMVS and IXRJCL
/* REXX */
/* Script to base64 encode files on mainframes */
/* -D prints debug messages */
/* In tso: */
/* BASE64 IN.DATA.SET */
/* BASE64 IN.DATA.SET(MEMBER) */
/* BASE64 IN.DATA.SET(MEMBER) OUT.SEQ.DATA.SET <-- MUST BE SEQUENTIAL*/
/* BASE64 IN.DATA.SET(MEMBER) OUT.SEQ.DATA.SET -D */
/* BASE64 IN.DATA.SET(MEMBER) -D */
/* With IXRJCL: */
/* //JOBCARD JOB */
/* // * REMOVE THE -D TO DISABLE DEBUG MESSAGES */
/* //BASE64 EXEC PGM=IRXJCL,PARM='BASE64 -D' */
/* //SYSEXEC DD DSN=DATA.SET.WITH.REXX,DISP=SHR */
/* //SYSTSPRT DD SYSOUT=* */
/* // * MEMBER FOR INDD IS OPTIONAL */
/* //INDD DD DSN=SOME.DATA.SET(MEMBER),DISP=SHR */
/* // * OUTDD IS OPTIONAL, IF OMMITTED PRINTS OUTPUT TO SYSTSPRT */
/* //OUTDD DD DSN=PHIL.B64OUT(TESTJCL),DISP=SHR */
/* //SYSTSIN DD DUMMY */
/* In OMVS: */
/* ./base64 infile.whatever */
/* ./base64 infile.whatever outfile */
/* ./base64 infile.whatever -D */
/* ./base64 infile.whatever outfile -D */
/* */
/* Base64 linewrap per RFC is 76, change to 72 to be ispf friendly */
linewrap = 76
/* TRACE I */
/* (^_^) (T_T) [o_o] (^.^) (".") ($.$) */
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'||,
'abcdefghijklmnopqrstuvwxyz0123456789+/'
do i=0 to 64
stem64.i = substr(chars, i + 1, 1)
end
debug = 0
outputf = 0
where_are_we = address()
select
/* From JCL */
when where_are_we == "MVS" then do
arg d .
call enable_debug(d)
call debug("In MVS")
"EXECIO * DISKR INDD (FINIS STEM indata."
if rc > 0 then do
say "(T_T) Error reading SYSUT1:" rc
exit 1
end
ddname = "OUTDD"
outputf = 1
outdd = ddname
call debug("Opened file INDD")
end
/* From TSO */
when where_are_we == "TSO" then do
arg indd outdd d .
if d == "" then
d = outdd
if outdd == "" then
d = indd
call enable_debug(d)
call debug("In TSO")
if indd == "" | indd == "-D" then do
say "(T_T) No file to read"
call print_usage
exit 1
end
/* file to convert */
dsi_rc = LISTDSI("'"||indd||"'")
if dsi_rc > 0 then do
say "(T_T) Error reading" indd
say "SYSREASON:" SYSREASON
exit 1
end
ddname = "B64LYFE"
call debug("Reading" indd)
call debug("Allocating" ddname "to read" indd)
address TSO "ALLOCATE FILE("ddname")" ,
"DA('"indd"') SHR REUSE"
"EXECIO * DISKR "ddname" (FINIS STEM indata."
if rc > 0 then do
say "(T_T) Error reading" indd rc
exit 1
end
address TSO "FREE FILE("ddname")"
/* Output to dataset or dataset(member) */
ddname = "B64OUTF"
if outdd /== "-D" & outdd /== "" then do
outputf = 1
dsi_rc = LISTDSI("'"||outdd||"'")
if dsi_rc <> 0 then do
call debug(outdd "does not exist creating it")
call debug("Allocating" ddname "to write to" outdd)
"ALLOCATE FILE("ddname") DA('"outdd"') NEW" ,
"UNIT(SYSDA) DSORG(PS)",
"LRECL("linewrap") BLKSIZE(8800) RECFM(F,B)"
end
else do
call debug("Allocating" ddname "to write to" outdd)
"ALLOCATE FILE("ddname") DA('"outdd"') SHR REUSE"
end
end
end
/* From USS/OMVS */
when where_are_we == "SH" then do
parse arg indd outdd d .
if d == "" then
d = outdd
if outdd == "" then
d = indd
call enable_debug(d)
call debug("In Unix")
if indd == "" | indd == "-D" then do
say "(T_T) No file to read"
call print_usage
exit 1
end
address syscall
"readfile" indd "indata."
if outdd /== "" & outdd /== "-D" then do
outputf = 1
end
end
otherwise
say "(T_T) Only MVS, USS and TSO support for now"
exit 1
end /* end select */
/* All that crap above was just to load a file the next */
/* 20 lines is the actual b64 */
filesize = 0
file = ''
outfile = ''
do i = 1 to indata.0
file = file||indata.i
filesize = filesize + length(indata.i)
drop indata.i
end
drop indata.0
call debug("Read:" filesize "bytes")
L = filesize * 8
bits = x2b( c2x(file) )0000000000000000
do i=1 by 6 to L
num = x2d( b2x( substr(bits, i, 6) ) )
/* call debug(i "num:" num "b64" stem64.num) */
outfile = outfile || stem64.num
end
outfile = outfile || copies('=', 2 * (L//6==2) + (L//6==4) )
/* Done b64 */
b64.0= 0
linenum = 0
do i=1 by 76 to length(outfile)
linenum = linenum + 1
b64.linenum = substr(outfile, i, 76)
end
b64.0 = linenum
/* Try to write to file if that fails print to screen/syslog */
if outputf then do
call debug("Writing" length(outfile) "bytes to:" outdd)
if where_are_we /== "SH" then do
"EXECIO * DISKW "ddname" (STEM b64. FINIS"
if where_am_i == "TSO" then do
"FREE FILE("ddname")"
end
if rc > 0 then do
say "OUTDD not in job printing base64 below"
say ""
end
end
else do
"writefile" outdd "600 b64."
end
end
if rc > 0 | outputf /== 1 then do
do i = 1 to b64.0
say b64.i
end
end
return
/**********************************************************************/
/**********************************************************************/
enable_debug:
parse arg d
if d == "-D" | d == "-d" then do
debug = 1
call debug("Debug Enabled")
end
return
debug:
parse arg msg
if debug then do
face = random_face()
say "DEBUG:" face msg
end
return
random_face:
faces = "(U_U) (0_0) (O.O) (-_-) (*.*) (T_T) (^_^) (^.^) "||,
"(o_o) ('.') ($.$) (-.-) (*_*)"
parse value faces with f.1 f.2 f.3 f.4 f.5 f.6 f.7 f.8 f.9 f.10,
f.11 f.12 f.13
f.0 = 13
r = random(1,13)
return f.r
print_usage:
select
when where_are_we == "TSO" then do
say "Usage:"
say "BASE64 IN.DATASET OUT.DATASET"
say "BASE64 IN.DATASET(MEMBER) OUT.DATASET"
say "BASE64 IN.DATASET(MEMBER)"
say 'Use -D for debug info:'
say "BASE64 IN.DATASET(MEMBER) -D"
say "BASE64 IN.DATASET(MEMBER) OUT.DATASET -D"
end
when where_are_we == "SH" then do
say "Usage:"
say "BASE64 /path/to/infile"
say "BASE64 infile outfile"
say 'Use -D for debug info:'
say "BASE64 /path/to/infile -D"
say "BASE64 infile outfile -D"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment