int do_cat_pdsmember(CIFBLK *cif, DSXTENT *extent, int noext, char* dsname, char *pdsmember, unsigned long optflags) { int rc; u_int trk; U8 rec; /* Point to the start of the directory */ trk = 0; rec = 1; /* Read the directory */ while (1) { BYTE *blkptr; BYTE dirblk[256]; U32 cyl; U8 head; U16 len; EXTGUIMSG( "CTRK=%d\n", trk ); rc = convert_tt(trk, noext, extent, cif->heads, &cyl, &head); if (rc < 0) return -1; rc = read_block(cif, cyl, head, rec, 0, 0, &blkptr, &len); if (rc < 0) return -1; if (rc > 0) /* end of track */ { trk++; rec = 1; continue; } if (len == 0) /* physical end of file */ return 0; memcpy(dirblk, blkptr, sizeof(dirblk)); rc = process_dirblk(cif, noext, extent, dirblk, dsname, pdsmember, optflags); if (rc < 0) return -1; if (rc > 0) /* logical end of file */ return 0; rec++; } UNREACHABLE_CODE(); }
int fbcopy( FILE *fout, CIFBLK *cif, DADSM *dadsm, int tran, int verbose) { FORMAT1_DSCB *f1dscb = &dadsm->f1buf; DSXTENT extent[MAX_EXTENTS]; int rc, trk = 0, trkconv = 999, rec = 1; int cyl = 0, head = 0, rc_rb, len, offset; int rc_copy = 0; int recs_written = 0, lrecl, num_extents; int lstartrack = 0, lstarrec = 0, lstarvalid = 0; BYTE *buffer; char *pascii = NULL; char zdsn[sizeof(f1dscb->ds1dsnam) + 1]; // ascii dsn // Kludge to avoid rewriting this code (for now): memcpy(&extent, (void *)&(dadsm->f1ext), sizeof(extent)); num_extents = f1dscb->ds1noepv; lrecl = (f1dscb->ds1lrecl[0] << 8) | (f1dscb->ds1lrecl[1]); if (absvalid) { strcpy(zdsn, argdsn); if (debug) fprintf(stderr, "fbcopy absvalid\n"); } else { make_asciiz(zdsn, sizeof(zdsn), f1dscb->ds1dsnam, sizeof(f1dscb->ds1dsnam)); if ((f1dscb->ds1lstar[0] !=0) || (f1dscb->ds1lstar[1] != 0) || (f1dscb->ds1lstar[2] != 0)) { lstartrack = (f1dscb->ds1lstar[0] << 8) | (f1dscb->ds1lstar[1]); lstarrec = f1dscb->ds1lstar[2]; lstarvalid = 1; // DS1LSTAR valid } } if (debug) { fprintf(stderr, "fbcopy zdsn %s\n", zdsn); fprintf(stderr, "fbcopy num_extents %d\n", num_extents); fprintf(stderr, "fbcopy lrecl %d\n", lrecl); fprintf(stderr, "fbcopy F1 DSCB\n"); data_dump(f1dscb, sizeof(FORMAT1_DSCB)); sayext(num_extents, (void *)&extent); } if (verbose) // DS1LSTAR = last block written TTR fprintf(stderr, "fbcopy DS1LSTAR %2.2X%2.2X%2.2X lstartrack %d " "lstarrec %d lstarvalid %d\n", f1dscb->ds1lstar[0], f1dscb->ds1lstar[1], f1dscb->ds1lstar[2], lstartrack, lstarrec, lstarvalid); if (tran) { // need ASCII translation buffer? pascii = malloc(lrecl + 1); if (pascii == NULL) { fprintf(stderr, "fbcopy unable to allocate ascii buffer\n"); return -1; } } while (1) { // output records until something stops us // Honor DS1LSTAR when valid if ((lstarvalid) && (trk == lstartrack) && (rec > lstarrec)) { if (verbose) fprintf(stderr, "fbcopy DS1LSTAR indicates EOF\n" "fbcopy DS1LSTAR %2.2X%2.2X%2.2X " "track %d record %d\n", f1dscb->ds1lstar[0], f1dscb->ds1lstar[1], f1dscb->ds1lstar[2], trk, rec); rc_copy = recs_written; break; } // Convert TT to CCHH for upcoming read_block call if (trkconv != trk) { // avoid converting for each block trkconv = trk; // current track converted rc = convert_tt(trk, num_extents, extent, cif->heads, &cyl, &head); if (rc < 0) { fprintf(stderr, "fbcopy convert_tt track %5.5d, rc %d\n", trk, rc); if (absvalid) rc_copy = recs_written; else rc_copy = -1; break; } if (verbose > 1) fprintf(stderr, "fbcopy convert TT %5.5d CCHH %4.4X %4.4X\n", trk, cyl, head); } // Read block from dasd if (verbose > 2) fprintf(stderr, "fbcopy reading track %d " "record %d CCHHR = %4.4X %4.4X %2.2X\n", trk, rec, cyl, head, rec); rc_rb = read_block(cif, cyl, head, rec, NULL, NULL, &buffer, &len); if (rc_rb < 0) { // error fprintf(stderr, "fbcopy error reading %s, rc %d\n", zdsn, rc_rb); rc_copy = -1; break; } // Handle end of track return from read_block if (rc_rb > 0) { // end of track if (verbose > 2) fprintf(stderr, "fbcopy End Of Track %d rec %d\n", trk, rec); trk++; // next track rec = 1; // record 1 on new track continue; } // Check for dataset EOF if (len == 0) { // EOF if (verbose) fprintf(stderr, "fbcopy EOF track %5.5d rec %d\n", trk, rec); if (absvalid) { // capture as much -abs data as possible if (verbose) fprintf(stderr, "fbcopy ignoring -abs EOF\n"); } else { rc_copy = recs_written; break; } } if (verbose > 3) fprintf(stderr, "fbcopy read %d bytes\n", len); if (verbose > 2) { data_dump(buffer, len); fprintf(stderr, "\n"); } // Deblock input dasd block, write records to output dataset for (offset = 0; offset < len; offset += lrecl) { if (verbose > 3) { fprintf(stderr, "fbcopy offset %d length %d rec %d\n", offset, lrecl, recs_written); } if (tran) { // ASCII output memset(pascii, 0, lrecl + 1); make_asciiz(pascii, lrecl + 1, buffer + offset, lrecl); if (verbose > 4) { fprintf(stderr, "fbcopy buffer offset %d rec %d\n", offset, rec); data_dump(buffer + offset, lrecl); } if (verbose > 3) { fprintf(stderr, "->%s<-\n", pascii); data_dump(pascii, lrecl); } fprintf(fout, "%s\n", pascii); } else { // EBCDIC output if (verbose > 3) { fprintf(stderr, "fbcopy EBCDIC buffer\n"); data_dump(buffer + offset, lrecl); } fwrite(buffer + offset, lrecl, 1, fout); } if (ferror(fout)) { fprintf(stderr, "fbcopy error writing %s\n", zdsn); fprintf(stderr, "%s\n", strerror(errno)); rc_copy = -1; } recs_written++; } if (rc_copy != 0) break; else rec++; // next record on track } /* while (1) */ if (pascii) free(pascii); // release ASCII conversion buffer return rc_copy; } /* fbcopy */
/*-------------------------------------------------------------------*/ int main (int argc, char *argv[]) { char *pgm; /* less any extension (.ext) */ int rc; /* Return code */ int i=0; /* Arument index */ U16 len; /* Record length */ U32 cyl; /* Cylinder number */ U8 head; /* Head number */ U8 rec; /* Record number */ u_int trk; /* Relative track number */ char *fname; /* -> CKD image file name */ char *sfname=NULL; /* -> CKD shadow file name */ char dsnama[45]; /* Dataset name (ASCIIZ) */ int noext; /* Number of extents */ DSXTENT extent[16]; /* Extent descriptor array */ BYTE *blkptr; /* -> PDS directory block */ BYTE dirblk[256]; /* Copy of directory block */ CIFBLK *cif; /* CKD image file descriptor */ INITIALIZE_UTILITY( UTILITY_NAME, "PDS unload", &pgm ); /* Check the number of arguments */ if (argc < 3 || argc > 5) { FWRMSG( stderr, HHC02463, "I", pgm, " pdsname [ascii]" ); return -1; } /* The first argument is the name of the CKD image file */ fname = argv[1]; /* The next argument may be the shadow file name */ if (!memcmp (argv[2], "sf=", 3)) { sfname = argv[2]; i = 1; } /* The second argument is the dataset name */ memset (dsnama, 0, sizeof(dsnama)); strncpy (dsnama, argv[2|+i], sizeof(dsnama)-1); string_to_upper (dsnama); /* The third argument is an optional keyword */ if (argc > 3+i && argv[3+i] != NULL) { if (strcasecmp(argv[3+i], "ascii") == 0) asciiflag = 1; else { FWRMSG( stderr, HHC02465, "E", argv[3+i] ); FWRMSG( stderr, HHC02463, "I", argv[0], " pdsname [ascii]" ); return -1; } } /* Open the CKD image file */ cif = open_ckd_image (fname, sfname, O_RDONLY|O_BINARY, IMAGE_OPEN_NORMAL); if (cif == NULL) return -1; /* Build the extent array for the requested dataset */ rc = build_extent_array (cif, dsnama, extent, &noext); if (rc < 0) return -1; #ifdef EXTERNALGUI /* Calculate ending relative track */ if (extgui) { int bcyl; /* Extent begin cylinder */ int btrk; /* Extent begin head */ int ecyl; /* Extent end cylinder */ int etrk; /* Extent end head */ int trks; /* total tracks in dataset */ int i; /* loop control */ for (i = 0, trks = 0; i < noext; i++) { bcyl = (extent[i].xtbcyl[0] << 8) | extent[i].xtbcyl[1]; btrk = (extent[i].xtbtrk[0] << 8) | extent[i].xtbtrk[1]; ecyl = (extent[i].xtecyl[0] << 8) | extent[i].xtecyl[1]; etrk = (extent[i].xtetrk[0] << 8) | extent[i].xtetrk[1]; trks += (((ecyl * cif->heads) + etrk) - ((bcyl * cif->heads) + btrk)) + 1; } EXTGUIMSG( "ETRK=%d\n", trks-1 ); } #endif /*EXTERNALGUI*/ /* Point to the start of the directory */ trk = 0; rec = 1; /* Read the directory */ while (1) { EXTGUIMSG( "CTRK=%d\n", trk ); /* Convert relative track to cylinder and head */ rc = convert_tt (trk, noext, extent, cif->heads, &cyl, &head); if (rc < 0) return -1; /* Read a directory block */ WRMSG( HHC02466, "I", cyl, head, rec ); rc = read_block (cif, cyl, head, rec, NULL, NULL, &blkptr, &len); if (rc < 0) return -1; /* Move to next track if block not found */ if (rc > 0) { trk++; rec = 1; continue; } /* Exit at end of directory */ if (len == 0) break; /* Copy the directory block */ memcpy (dirblk, blkptr, sizeof(dirblk)); /* Process each member in the directory block */ rc = process_dirblk (cif, noext, extent, dirblk); if (rc < 0) return -1; if (rc > 0) break; /* Point to the next directory block */ rec++; } /* end while */ WRMSG( HHC02467, "I" ); /* Close the CKD image file and exit */ rc = close_ckd_image (cif); return rc; } /* end function main */
int process_member(CIFBLK *cif, int noext, DSXTENT extent[], BYTE *ttr, unsigned long optflags, char* dsname, char* memname) { int rc; u_int trk; U16 len; U32 cyl; U8 head; U8 rec; BYTE *buf; U32 beg_cyl = 0; U8 beg_head = 0; U8 beg_rec = 0; U64 tot_len = 0; set_codepage(NULL); trk = (ttr[0] << 8) | ttr[1]; rec = ttr[2]; while (1) { rc = convert_tt(trk, noext, extent, cif->heads, &cyl, &head); if (rc < 0) return -1; rc = read_block(cif, cyl, head, rec, 0, 0, &buf, &len); if (rc < 0) return -1; if (rc > 0) /* end of track */ { trk++; rec = 1; continue; } if (len == 0) /* end of member */ break; if (optflags & OPT_MEMINFO_ONLY) { if (!beg_cyl) { beg_cyl = cyl; beg_head = head; beg_rec = rec; } tot_len += len; } else if (optflags & OPT_CARDS) { /* Formatted 72 or 80 column ASCII card images */ if ((rc = do_cat_cards(buf, len, optflags)) != 0) return -1; // (len not multiple of 80 bytes) } else if (optflags & OPT_ASCIIFY) { /* Unformatted ASCII text */ BYTE *p; for (p = buf; len--; p++) putchar(guest_to_host(*p)); } else { /* Output member in binary exactly as-is */ #if O_BINARY != 0 setmode(fileno(stdout),O_BINARY); #endif fwrite(buf, len, 1, stdout); } rec++; } if (optflags & OPT_MEMINFO_ONLY) // "%s/%s/%-8s %8s bytes from %4.4"PRIX32"%2.2"PRIX32"%2.2"PRIX32" to %4.4"PRIX32"%2.2"PRIX32"%2.2"PRIX32 FWRMSG( stdout, HHC02407, "I", volser, dsname, memname, fmt_memsize( tot_len ), (U32) beg_cyl, (U32) beg_head, (U32) beg_rec, (U32) cyl, (U32) head, (U32) rec ); return 0; }
/*-------------------------------------------------------------------*/ static int process_member (CIFBLK *cif, int noext, DSXTENT extent[], char *memname, BYTE *ttr) { int rc; /* Return code */ U16 len; /* Record length */ u_int trk; /* Relative track number */ U32 cyl; /* Cylinder number */ U8 head; /* Head number */ U8 rec; /* Record number */ BYTE *buf; /* -> Data block */ FILE *ofp; /* Output file pointer */ char ofname[256]; /* Output file name */ int offset; /* Offset of record in buffer*/ char card[81]; /* Logical record (ASCIIZ) */ char pathname[MAX_PATH]; /* ofname in host format */ /* Build the output file name */ memset (ofname, 0, sizeof(ofname)); strncpy (ofname, memname, 8); string_to_lower (ofname); strlcat (ofname, ".mac", sizeof(ofname)); /* Open the output file */ hostpath(pathname, ofname, sizeof(pathname)); ofp = fopen (pathname, (asciiflag? "w" : "wb")); if (ofp == NULL) { FWRMSG( stderr, HHC02468, "E", ofname, "fopen", strerror( errno )); return -1; } /* Point to the start of the member */ trk = (ttr[0] << 8) | ttr[1]; rec = ttr[2]; WRMSG( HHC02469, "I", memname, trk, rec ); /* Read the member */ while (1) { /* Convert relative track to cylinder and head */ rc = convert_tt (trk, noext, extent, cif->heads, &cyl, &head); if (rc < 0) return -1; // fprintf (stderr, // "CCHHR=%4.4X%4.4X%2.2X\n", // cyl, head, rec); /* Read a data block */ rc = read_block (cif, cyl, head, rec, NULL, NULL, &buf, &len); if (rc < 0) return -1; /* Move to next track if record not found */ if (rc > 0) { trk++; rec = 1; continue; } /* Exit at end of member */ if (len == 0) break; /* Check length of data block */ if (len % 80 != 0) { FWRMSG( stderr, HHC02470, "E", len, cyl, head, rec ); return -1; } /* Process each record in the data block */ for (offset = 0; offset < len; offset += 80) { if (asciiflag) { make_asciiz (card, sizeof(card), buf + offset, 72); fprintf (ofp, "%s\n", card); } else { fwrite (buf+offset, 80, 1, ofp); } if (ferror(ofp)) { FWRMSG( stderr, HHC02468, "E", ofname, "fwrite", strerror( errno )); return -1; } } /* end for(offset) */ /* Point to the next data block */ rec++; } /* end while */ /* Close the output file and exit */ fclose (ofp); return 0; } /* end function process_member */