use dataset pipes + dtlspawn + jar to zip a mainframe file.

Discussion of the Co:Z Toolkit Dataset Pipes utilities
Post Reply
john.mckown
Posts: 48
Joined: Tue Jun 12, 2007 2:46 pm

use dataset pipes + dtlspawn + jar to zip a mainframe file.

Post by john.mckown »

I'm never one to do things the easy way when I can do it the complicated
way <grin>. Anyway, below is a way to create a ZIP file containing a
SINGLE z/OS sequential file. It uses Dovetailed Technologies DTLSPAWN,
fromdsn, todsn, and the Java jar command. It must use a z/OS UNIX file
as intermediary storage.

//EX1 EXEC DTLSPAWN
//STDIN DD *
. /etc/profile
cd /tozip &&
fromdsn -t 819 "//...zos.file..." >intermediate.unix.file &&
jar cvM intermediate.unix.file |
todsn -o 'recfm=fb,lrecl=1,space=(cyl,(500,200))' -b \
"//...zos.file.ZIP"
rm intermediate.unix.file
/*

The fromdsn command copies the data to the intermediate unix file,
converting it to ISO8859-1 (with UNIX line endings, not Windows line
endings, but you can specify other line endings with the -l parameter).
The jar command reads the intermediate unix file, sending its output to
STDOUT.
Which is piped to the todsn command which writes its output to a z/OS
sequential file.
You need to replace "intermediate.unix.file" to be the proper file name.
That is, what you want it called when unzipped.

You can create a ZIP with multiple files by simply using multiple fromdsn commands before the jar command, each going to a unique UNIX file name. Be sure to end each extra fromdsn with a &&. Note that the && guarantees that the previous command finished correctly before doing the next command. A primitive form of condition code checking.
dovetail
Site Admin
Posts: 2022
Joined: Thu Jul 29, 2004 12:12 pm

Post by dovetail »

Pretty nice.
A nit, but DTLSPAWN executes a login shell by default, so dotting in /etc/profile is not necessary.

The "jar" command is actually a special java launcher for a Java program that use's java's Zip library. You can write your own that Zips input from stdin and writes it to stdout, then you can do something like the following:

Code: Select all

//EX1 EXEC DTLSPAWN
//STDIN DD *
fromdsn -t 819 //DD:ZIPIN |
  java -cp /home/myid ZipStream |
  todsn -b //DD:ZIPOUT
//ZIPIN DD DSN=MYID.IN.DATA,DISP=SHR
//ZIPOUT DD  DSN=MYID.OUT.ZIP.DATA,
//            DISP=(NEW,CATLG),
//            DCB=(RECFM=U,BLKSIZE=27998),
//            SPACE=(CYL,(500,200),RLSE)
//
(I used DD name references rather than DSN references,
so you could actually make this into a reusable PROC).

Here's the Java program:

Code: Select all

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Zips the contents of System.in (stdin) to System.out (stdout).
 * If given, the first argument is used as the entry file name.
 */
public class ZipStream {

	public static final int BUF_SIZE = 32*1024;
	
	public static void main(String[] args) throws IOException {
		String entryName = args.length > 0 ? args[0] : "ENTRY";
		ZipOutputStream zos = new ZipOutputStream(
								new BufferedOutputStream(System.out, BUF_SIZE));
		byte[] buffer = new byte[BUF_SIZE];
		zos.putNextEntry(new ZipEntry(entryName));
		int bytesRead;
		long totalBytes = 0L;	
		while ((bytesRead = System.in.read(buffer)) >= 0) {
			zos.write(buffer, 0, bytesRead);
			totalBytes += bytesRead;
		}
		zos.closeEntry();
		zos.close();
		System.err.println("Zipped " + totalBytes + " bytes from stdin to stdout");
	}
}
Post Reply