#!/usr/bin/env python3 import sys import subprocess import tempfile import os # Force temp files into a folder inside your project custom_temp_dir = os.path.join(os.getcwd(), "tmp") os.makedirs(custom_temp_dir, exist_ok=True) tempfile.tempdir = custom_temp_dir MVSHOST = "oldcomputernerd.com" RDRPORT = 3505 MVS_PASSWORD = os.environ.get("MVS_BATCH_PASSWORD") def create_delete_jcl(dataset_name, member_name): """Create JCL to delete a PDS member using IEHPROGM""" jcl = f""" //DELETE JOB (ACCT),'DELETE', // USER=@05054,PASSWORD={MVS_PASSWORD}, // CLASS=A,MSGCLASS=H,NOTIFY=@05054 //DELMEM EXEC PGM=IEHPROGM //SYSPRINT DD SYSOUT=* //DD1 DD DSN={dataset_name},DISP=SHR //SYSIN DD * DELETE DSNAME={dataset_name},MEMBER={member_name} /* """ return jcl def delete_member(dataset_name, member_name, mvshost=MVSHOST): """Delete a member from MVS PDS""" payload = create_delete_jcl(dataset_name, member_name) # Write JCL to temporary file and submit via netcat with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.jcl') as tmpfile: tmpfile.write(payload) tmpfile.flush() tmpfile_path = tmpfile.name try: with open(tmpfile_path, 'rb') as f: result = subprocess.run( ['nc', '-w', '5', mvshost, str(RDRPORT)], input=f.read(), check=True, capture_output=True ) print(f"Deleted {dataset_name}({member_name})") if result.stdout: print("JES response:", result.stdout.decode(errors='ignore').strip()) return 0 except subprocess.CalledProcessError as e: print(f"Deletion failed: {e}") print("stderr:", e.stderr.decode(errors='ignore')) return 1 finally: os.unlink(tmpfile_path) if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: delete_mvs_member.py [mvshost]") print() print("Arguments:") print(" pds_destination - PDS destination as DATASET(MEMBER) (required)") print(" mvshost - MVS host (optional, default: oldcomputernerd.com)") print() print("Examples:") print(" delete_mvs_member.py '@05054.SRCLIB.C(SIEVE11)'") print(" delete_mvs_member.py '@05054.SRCLIB.C(HELLO)' mainframe.example.com") sys.exit(1) destination = sys.argv[1] # Parse PDS syntax: DATASET(MEMBER) if '(' in destination and destination.endswith(')'): dataset_name = destination[:destination.index('(')] member_name = destination[destination.index('(')+1:-1] else: print(f"Error: Invalid PDS syntax '{destination}'. Use format: DATASET(MEMBER)") sys.exit(1) # Optional host override mvshost = sys.argv[2] if len(sys.argv) > 2 else MVSHOST print(f"Deleting: {dataset_name}({member_name})") print(f"Host: {mvshost}") print() sys.exit(delete_member(dataset_name, member_name, mvshost))