Example #1
0
/*-------------------------------------------------------------------*/
int main (int argc, char *argv[])
{
char           *pgmname;                /* prog name in host format  */
char           *pgm;                    /* less any extension (.ext) */
char            msgbuf[512];            /* message build work area   */
int             cckd_diag_rc = 0;       /* Program return code       */
char           *fn;                     /* File name                 */

CKDDASD_DEVHDR  devhdr;                 /* [C]CKD device hdr         */
CCKDDASD_DEVHDR cdevhdr;                /* Compressed CKD device hdr */
CKDDEV         *ckd=0;                  /* CKD DASD table entry      */
FBADEV         *fba=0;                  /* FBA DASD table entry      */

int             cmd_devhdr = 0;         /* display DEVHDR            */
int             cmd_cdevhdr = 0;        /* display CDEVHDR           */
int             cmd_l1tab = 0;          /* display L1TAB             */
int             cmd_l2tab = 0;          /* display L2TAB             */
int             cmd_trkdata = 0;        /* display track data        */
int             cmd_hexdump = 0;        /* display track data (hex)  */

int             cmd_offset = 0;         /* 1 = display data at       */
int             op_offset = 0;          /* op_offset of length       */
int             op_length = 0;          /* op_length                 */

int             cmd_cchh = 0;           /* 1 = display CCHH data     */
int             op_cc = 0;              /* CC = cylinder             */
int             op_hh = 0;              /* HH = head                 */

int             cmd_tt = 0;             /* 1 = display TT data       */
int             op_tt = 0;              /* relative track #          */

int             swapend;                /* 1 = New endianess doesn't
                                             match machine endianess */
int             n, trk=0, l1ndx=0, l2ndx=0;
off_t           l2taboff=0;             /* offset to assoc. L2 table */
int             ckddasd;                /* 1=CKD dasd  0=FBA dasd    */
int             heads=0;                /* Heads per cylinder        */
off_t           trkhdroff=0;            /* offset to assoc. trk hdr  */
int             imglen=0;               /* track length              */
char            pathname[MAX_PATH];     /* file path in host format  */
char           *strtok_str = NULL;

    /* Set program name */
    if ( argc > 0 )
    {
        if ( strlen(argv[0]) == 0 )
        {
            pgmname = strdup( UTILITY_NAME );
        }
        else
        {
            char path[MAX_PATH];
#if defined( _MSVC_ )
            GetModuleFileName( NULL, path, MAX_PATH );
#else
            strncpy( path, argv[0], sizeof( path ) );
#endif
            pgmname = strdup(basename(path));
#if !defined( _MSVC_ )
            strncpy( path, argv[0], sizeof(path) );
#endif
        }
    }
    else
    {
        pgmname = strdup( UTILITY_NAME );
    }

    pgm = strtok_r( strdup(pgmname), ".", &strtok_str);
    INITIALIZE_UTILITY( pgmname );

    /* Display the program identification message */
    MSGBUF( msgbuf, MSG_C( HHC02499, "I", pgm, "CCKD diagnostic program" ) );
    display_version (stderr, msgbuf+10, FALSE);

    /* parse the arguments */
    argc--;
    argv++ ;
    while (argc > 0) {
        if(**argv != '-') break;

        switch(argv[0][1]) {
            case 'v':  if (argv[0][2] != '\0') return syntax (pgm);
                       return 0;
            case 'd':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_devhdr = 1;
                       break;
            case 'c':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_cdevhdr = 1;
                       break;
            case '1':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_l1tab = 1;
                       break;
            case '2':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_l2tab = 1;
                       break;
            case 'a':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_cchh = 1;
                       argc--; argv++;
                       op_cc = offtify(*argv);
                       argc--; argv++;
                       op_hh = offtify(*argv);
                       break;
            case 'r':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_tt = 1;
                       argc--; argv++;
                       op_tt = offtify(*argv);
                       break;
            case 'o':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_offset = 1;
                       argc--;
                       argv++;
                       op_offset = offtify(*argv);
                       argc--;
                       argv++;
                       op_length = offtify(*argv);
                       break;
            case 't':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_trkdata = 1;
                       break;
            case 'x':  if (argv[0][2] != '\0') return syntax (pgm);
                       cmd_hexdump = 1;
                       cmd_trkdata = 1;
                       break;
            case 'g':  if (argv[0][2] != '\0') return syntax (pgm);
                       debug = 1;
                       break;
            default:   return syntax (pgm);
        }
        argc--;
        argv++;
    }
    if (argc != 1) return syntax (pgm);
    fn = argv[0];

    /* open the file */
    hostpath(pathname, fn, sizeof(pathname));
    fd = HOPEN(pathname, O_RDONLY | O_BINARY);
    if (fd < 0) {
        fprintf(stderr,
                _("cckddiag: error opening file %s: %s\n"),
                fn, strerror(errno));
        return -1;
    }

    /*---------------------------------------------------------------*/
    /* display DEVHDR - first 512 bytes of dasd image                */
    /*---------------------------------------------------------------*/
    readpos(fd, &devhdr, 0, sizeof(devhdr));
    if (cmd_devhdr) {
        fprintf(stderr, "\nDEVHDR - %d (decimal) bytes:\n",
                (int)sizeof(devhdr));
        data_dump(&devhdr, sizeof(devhdr));
    }

    /*---------------------------------------------------------------*/
    /* Determine CKD or FBA device type                              */
    /*---------------------------------------------------------------*/
    if (memcmp(devhdr.devid, "CKD_C370", 8) == 0
       || memcmp(devhdr.devid, "CKD_S370", 8) == 0) {
        ckddasd = 1;
        ckd = dasd_lookup(DASD_CKDDEV, NULL, devhdr.devtype, 0);
        if (ckd == NULL) {
            fprintf(stderr,
                    "DASD table entry not found for devtype 0x%2.2X\n",
                    devhdr.devtype);
            clean();
            exit(5);
        }
    }
    else
        if (memcmp(devhdr.devid, "FBA_C370", 8) == 0
           || memcmp(devhdr.devid, "FBA_S370", 8) == 0) {
        ckddasd = 0;
        fba = dasd_lookup(DASD_FBADEV, NULL, devhdr.devtype, 0);
        if (fba == NULL) {
            fprintf(stderr,
                    "DASD table entry not found for "
                    "devtype 0x%2.2X\n",
                    DEFAULT_FBA_TYPE);
            clean();
            exit(6);
        }
    }
    else {
        fprintf(stderr, "incorrect header id\n");
        clean();
        return -1;
    }

    /*---------------------------------------------------------------*/
    /* Set up device characteristics                                 */
    /*---------------------------------------------------------------*/
    if (ckddasd) {
        heads = ((U32)(devhdr.heads[3]) << 24)
              | ((U32)(devhdr.heads[2]) << 16)
              | ((U32)(devhdr.heads[1]) << 8)
              | (U32)(devhdr.heads[0]);
        if (debug)
            fprintf(stderr,
                "\nHHC90000D DBG: %s device has %d heads/cylinder\n",
                ckd->name, heads);
    } 


    /*---------------------------------------------------------------*/
    /* display CDEVHDR - follows DEVHDR                              */
    /*---------------------------------------------------------------*/
    readpos(fd, &cdevhdr, CKDDASD_DEVHDR_SIZE, sizeof(cdevhdr));
    if (cmd_cdevhdr) {
        fprintf(stderr, "\nCDEVHDR - %d (decimal) bytes:\n",
                (int)sizeof(cdevhdr));
        data_dump(&cdevhdr, sizeof(cdevhdr));
    }

    /*---------------------------------------------------------------*/
    /* Find machine endian-ness                                      */
    /*---------------------------------------------------------------*/
    /* cckd_endian() returns 1 for big-endian machines               */
    swapend = (cckd_endian() !=
               ((cdevhdr.options & CCKD_BIGENDIAN) != 0));

    /*---------------------------------------------------------------*/
    /* display L1TAB - follows CDEVHDR                               */
    /*---------------------------------------------------------------*/
    /* swap numl1tab if needed */
    n = cdevhdr.numl1tab;
    if (swapend) cckd_swapend4((char *)&n);

    l1 = makbuf(n * CCKD_L1ENT_SIZE, "L1TAB");
    readpos(fd, l1, CCKD_L1TAB_POS, n * CCKD_L1ENT_SIZE);
    /* L1TAB itself is not adjusted for endian-ness                  */
    if (cmd_l1tab) {
        fprintf(stderr, "\nL1TAB - %d (0x%X) bytes:\n",
                (int)(n * CCKD_L1ENT_SIZE), (unsigned int)(n * CCKD_L1ENT_SIZE));
        data_dump(l1, n * CCKD_L1ENT_SIZE);
    }

    /*---------------------------------------------------------------*/
    /* display OFFSET, LENGTH data                                   */
    /*---------------------------------------------------------------*/
    if (cmd_offset) {
        bulk = makbuf(op_length, "BULK");
        readpos(fd, bulk, op_offset, op_length);
        fprintf(stderr,
            "\nIMAGE OFFSET %d (0x%8.8X) "
            "of length %d (0x%8.8X) bytes:\n",
            op_offset, op_offset, op_length, op_length);
        data_dump(bulk, op_length);
        free(bulk);
        bulk = NULL;
    }

    /*---------------------------------------------------------------*/
    /* FBA isn't supported here because I don't know much about FBA  */
    /*---------------------------------------------------------------*/
    if ( (!ckddasd) && ((cmd_cchh) || (cmd_tt)) ) {
        fprintf(stderr, "CCHH/reltrk not supported for FBA\n");
        clean();
        exit(3);
    }

    /*---------------------------------------------------------------*/
    /* Setup CCHH or relative track request                          */
    /*---------------------------------------------------------------*/
    if (ckddasd) {
        if (cmd_tt) {
            trk = op_tt;
            op_cc = trk / heads;
            op_hh = trk % heads;
        } else {
            trk = (op_cc * heads) + op_hh;
        }
        l1ndx = trk / cdevhdr.numl2tab;
        l2ndx = trk % cdevhdr.numl2tab;
        l2taboff = l1[l1ndx];
        if (swapend) cckd_swapend4((char *)&l2taboff);
    }

    /*---------------------------------------------------------------*/
    /* display CKD CCHH or relative track data                       */
    /*---------------------------------------------------------------*/
    if ((cmd_cchh) || (cmd_tt)) {
        fprintf(stderr,
                "CC %d HH %d = reltrk %d; "
                "L1 index = %d, L2 index = %d\n"
                "L1 index %d = L2TAB offset %d (0x%8.8X)\n",
                op_cc, op_hh, trk,
                l1ndx, l2ndx,
                l1ndx, (int)l2taboff, (int)l2taboff);
        l2 = makbuf(cdevhdr.numl2tab * sizeof(CCKD_L2ENT), "L2TAB");
        readpos(fd, l2, l2taboff,
                cdevhdr.numl2tab * sizeof(CCKD_L2ENT));
        if (cmd_l2tab) {
            fprintf(stderr,
                   "\nL2TAB - %d (decimal) bytes\n",
                   (int)(cdevhdr.numl2tab * sizeof(CCKD_L2ENT)));
            data_dump(l2, (cdevhdr.numl2tab * sizeof(CCKD_L2ENT)) );
        }
        fprintf(stderr, "\nL2 index %d = L2TAB entry %d bytes\n",
               l2ndx, (int)sizeof(CCKD_L2ENT) );
        data_dump(&l2[l2ndx], sizeof(CCKD_L2ENT) );
        trkhdroff = l2[l2ndx].pos;
        imglen = l2[l2ndx].len;
        if (swapend) {
            cckd_swapend4((char *)&trkhdroff);
            cckd_swapend4((char *)&imglen);
        }
        fprintf(stderr, "\nTRKHDR offset %d (0x%8.8X); "
                "length %d (0x%4.4X)\n",
                (int)trkhdroff, (int)trkhdroff, imglen, imglen);
        tbuf = makbuf(imglen, "TRKHDR+DATA");
        readpos(fd, tbuf, trkhdroff, imglen);
        fprintf(stderr, "\nTRKHDR track %d\n", trk);
        data_dump(tbuf, sizeof(CKDDASD_TRKHDR) );
        if (cmd_trkdata) showtrk(tbuf, imglen, trk, cmd_hexdump);
        free(l2); free(tbuf);
        l2 = NULL; tbuf = NULL;
    }

    /* Close file, exit */
    fprintf(stderr, "\n");
    clean();
    return cckd_diag_rc;
}
Example #2
0
/*-------------------------------------------------------------------*/
int main (int argc, char *argv[])
{
char           *pgm;                    /* less any extension (.ext) */
int             ckddasd=-1;             /* 1=CKD  0=FBA              */
int             rc;                     /* Return code               */
int             quiet=0;                /* 1=Don't display status    */
int             comp=255;               /* Compression algorithm     */
int             cyls=-1, blks=-1;       /* Size of output file       */
int             lfs=0;                  /* 1=Create 1 large file     */
int             alt=0;                  /* 1=Create alt cyls         */
int             r=0;                    /* 1=Replace output file     */
int             in=0, out=0;            /* Input/Output file types   */
int             fd;                     /* Input file descriptor     */
char           *ifile, *ofile;          /* -> Input/Output file names*/
char           *sfile=NULL;             /* -> Input shadow file name */
CIFBLK         *icif, *ocif;            /* -> Input/Output CIFBLK    */
DEVBLK         *idev, *odev;            /* -> Input/Output DEVBLK    */

CKDDEV         *ckd=NULL;               /* -> CKD device table entry */
FBADEV         *fba=NULL;               /* -> FBA device table entry */
int             i, n, max;              /* Loop index, limits        */
BYTE            unitstat;               /* Device unit status        */
size_t          fba_bytes_remaining=0;  /* FBA bytes to be copied    */
int             nullfmt = CKDDASD_NULLTRK_FMT0; /* Null track format */
char            pathname[MAX_PATH];     /* file path in host format  */

    INITIALIZE_UTILITY( UTILITY_NAME, "DASD copy/convert", &pgm );

    if (strcasecmp(pgm, "ckd2cckd") == 0)
    {
        in = CKD;
        out = CCKD;
    }
    else if (strcasecmp(pgm, "cckd2ckd") == 0)
    {
        in = CCKD;
        out = CKD;
    }
    else if (strcasecmp(pgm, "fba2cfba") == 0)
    {
        in = FBA;
        out = CFBA;
    }
    else if (strcasecmp(pgm, "cfba2fba") == 0)
    {
        in = CFBA;
        out = FBA;
    }

    /* Process the arguments */
    for (argc--, argv++ ; argc > 0 ; argc--, argv++)
    {
        if (argv[0][0] != '-') break;
        if (strcmp(argv[0], "-h") == 0)
        {
            syntax( pgm );
            return 0;
        }
        else if (strcmp(argv[0], "-q") == 0
              || strcmp(argv[0], "-quiet") == 0)
            quiet = 1;
        else if (strcmp(argv[0], "-r") == 0)
            r = 1;
#ifdef CCKD_COMPRESS_ZLIB
        else if (strcmp(argv[0], "-z") == 0)
            comp = CCKD_COMPRESS_ZLIB;
#endif
#ifdef CCKD_COMPRESS_BZIP2
        else if (strcmp(argv[0], "-bz2") == 0)
            comp = CCKD_COMPRESS_BZIP2;
#endif
        else if (strcmp(argv[0], "-0") == 0)
            comp = CCKD_COMPRESS_NONE;
        else if ((strcmp(argv[0], "-cyl") == 0
               || strcmp(argv[0], "-cyls") == 0) && cyls < 0)
        {
            if (argc < 2 || (cyls = atoi(argv[1])) < 0)
                return syntax( pgm );
            argc--; argv++;
        }
        else if ((strcmp(argv[0], "-blk") == 0
               || strcmp(argv[0], "-blks") == 0) && blks < 0)
        {
            if (argc < 2 || (blks = atoi(argv[1])) < 0)
                return syntax( pgm );
            argc--; argv++;
        }
        else if (strcmp(argv[0], "-a") == 0
              || strcmp(argv[0], "-alt") == 0
              || strcmp(argv[0], "-alts") == 0)
            alt = 1;
        else if (strcmp(argv[0], "-lfs") == 0)
            lfs = 1;
        else if (out == 0 && strcmp(argv[0], "-o") == 0)
        {
            if (argc < 2 || out != 0) return syntax( pgm );
            if (strcasecmp(argv[1], "ckd") == 0)
                out = CKD;
            else if (strcasecmp(argv[1], "cckd") == 0)
                out = CCKD;
            else if (strcasecmp(argv[1], "fba") == 0)
                out = FBA;
            else if (strcasecmp(argv[1], "cfba") == 0)
                out = CFBA;
            else
                return syntax( pgm );
            argc--; argv++;
        }
        else
            return syntax( pgm );
    }

    /* Get the file names:
       input-file [sf=shadow-file] output-file   */
    if (argc < 2 || argc > 3) return syntax( pgm );
    ifile = argv[0];
    if (argc < 3)
        ofile = argv[1];
    else
    {
        if (strlen(argv[1]) < 4 || memcmp(argv[1], "sf=", 3))
            return syntax( pgm );
        sfile = argv[1];
        ofile = argv[2];
    }

    /* If we don't know what the input file is then find out */
    if (in == 0)
    {
        BYTE buf[8];
        hostpath(pathname, ifile, sizeof(pathname));
        fd = HOPEN (pathname, O_RDONLY|O_BINARY);
        if (fd < 0)
        {
            // "Error in function %s: %s"
            FWRMSG( stderr, HHC02412, "E", "open()", strerror(errno) );
            return -1;
        }
        rc = read (fd, buf, 8);
        if (rc < 8)
        {
            // "Error in function %s: %s"
            FWRMSG( stderr, HHC02412, "E", "read()", strerror(errno) );
            return -1;
        }
        if (memcmp(buf, "CKD_P370", 8) == 0)
            in = CKD;
        else if (memcmp(buf, "CKD_C370", 8) == 0)
            in = CCKD;
        else if (memcmp(buf, "FBA_C370", 8) == 0)
            in = CFBA;
        else
            in = FBA;
        close (fd);
    }

    /* If we don't know what the output file type is
       then derive it from the input file type */
    if (out == 0)
    {
        switch (in) {
        case CKD:  if (!lfs) out = CCKD;
                   else out = CKD;
                   break;
        case CCKD: if (comp == 255) out = CKD;
                   else out = CCKD;
                   break;
        case FBA:  if (!lfs) out = CFBA;
                   else out = FBA;
                   break;
        case CFBA: if (comp == 255) out = FBA;
                   else out = CFBA;
                   break;
        }
    }

    /* Set default compression if out file is to be compressed */
    if (comp == 255 && (out & COMPMASK))
#ifdef CCKD_COMPRESS_ZLIB
        comp = CCKD_COMPRESS_ZLIB;
#else
        comp = CCKD_COMPRESS_NONE;
#endif

    /* Perform sanity checks on the options */
    if ((in & CKDMASK) && !(out & CKDMASK)) return syntax( pgm );
    if ((in & FBAMASK) && !(out & FBAMASK)) return syntax( pgm );
    if (sfile && !(in & COMPMASK))          return syntax( pgm );
    if (comp != 255 && !(out & COMPMASK))   return syntax( pgm );
    if (lfs && (out & COMPMASK))            return syntax( pgm );
    if (cyls >= 0 && !(in & CKDMASK))       return syntax( pgm );
    if (blks >= 0 && !(in & FBAMASK))       return syntax( pgm );
    if (!(in & CKDMASK) && alt)             return syntax( pgm );

    /* Set the type of processing (ckd or fba) */
    ckddasd = (in & CKDMASK);

    /* Open the input file */
    if (ckddasd)
        icif = open_ckd_image (ifile, sfile, O_RDONLY|O_BINARY, IMAGE_OPEN_NORMAL);
    else
        icif = open_fba_image (ifile, sfile, O_RDONLY|O_BINARY, IMAGE_OPEN_NORMAL);
    if (icif == NULL)
    {
        // "Failed opening %s"
        FWRMSG( stderr, HHC02403, "E", ifile );
        return -1;
    }
    idev = &icif->devblk;
    if (idev->oslinux) nullfmt = CKDDASD_NULLTRK_FMT2;

    /* Calculate the number of tracks or blocks to copy */
    if (ckddasd)
    {
        if (cyls < 0) cyls = idev->ckdcyls;
        else if (cyls == 0) cyls = (idev->hnd->used)(idev);
        ckd = dasd_lookup (DASD_CKDDEV, NULL, idev->devtype, 0);
        if (ckd == NULL)
        {
            // "CKD lookup failed: device type %04X cyls %d"
            FWRMSG( stderr, HHC02430, "E",
                     idev->devtype, cyls );
            close_image_file (icif);
            return -1;
        }
        if (cyls <= ckd->cyls && alt) cyls = ckd->cyls + ckd->altcyls;
        n = cyls * idev->ckdheads;
        max = idev->ckdtrks;
        if (max < n && out == CCKD) n = max;
    }
    else
    {
        fba_bytes_remaining = idev->fbanumblk * idev->fbablksiz;
        if (blks < 0) blks = idev->fbanumblk;
        else if (blks == 0) blks = (idev->hnd->used)(idev);
        fba = dasd_lookup (DASD_FBADEV, NULL, idev->devtype, 0);
        if (fba == NULL)
        {
            // "FBA lookup failed: blks %d"
            FWRMSG( stderr, HHC02431, "E", blks );
            close_image_file (icif);
            return -1;
        }
        n = blks;
        max = idev->fbanumblk;
        if (max < n && out == CFBA) n = max;
        n = (n + FBA_BLKS_PER_GRP - 1) / FBA_BLKS_PER_GRP;
        max = (max + FBA_BLKS_PER_GRP - 1) / FBA_BLKS_PER_GRP;
    }

    /* Create the output file */
    if (ckddasd)
        rc = create_ckd(ofile, idev->devtype, idev->ckdheads,
                        ckd->r1, cyls, "", comp, lfs, 1+r, nullfmt, 0,
                        1, 0);
    else
        rc = create_fba(ofile, idev->devtype, fba->size,
                        blks, "", comp, lfs, 1+r, 0);
    if (rc < 0)
    {
        // "Failed creating %s"
        FWRMSG( stderr, HHC02432, "E", ofile );
        close_image_file (icif);
        return -1;
    }

    /* Open the output file */
    if (ckddasd)
        ocif = open_ckd_image (ofile, NULL, O_RDWR|O_BINARY, IMAGE_OPEN_DASDCOPY);
    else
        ocif = open_fba_image (ofile, NULL, O_RDWR|O_BINARY, IMAGE_OPEN_DASDCOPY);
    if (ocif == NULL)
    {
        // "Failed opening %s"
        FWRMSG( stderr, HHC02403, "E", ofile );
        close_image_file (icif);
        return -1;
    }
    odev = &ocif->devblk;

    /* Notify GUI of total #of tracks or blocks being copied... */
    EXTGUIMSG( "TRKS=%d\n", n );

    /* Copy the files */

#if defined( EXTERNALGUI )
    if (!extgui)
#endif
        if (!quiet)
            printf ( "  %3d%% %7d of %d", 0, 0, n );

    for (i = 0; i < n; i++)
    {
        /* Read a track or block */
        if (ckddasd)
        {
            if (i < max)
                rc = (idev->hnd->read)(idev, i, &unitstat);
            else
            {
                memset (idev->buf, 0, idev->ckdtrksz);
                rc = nulltrk(idev->buf, i, idev->ckdheads, nullfmt);
            }
        }
        else
        {
            if (i < max)
                rc = (idev->hnd->read)(idev, i, &unitstat);
            else
                memset (idev->buf, 0, FBA_BLKGRP_SIZE);
                rc = 0;
        }
        if (rc < 0)
        {
            // "Read error on file %s: %s %d stat=%2.2X, null %s substituted"
            FWRMSG( stderr, HHC02433, "E",
                     ifile, ckddasd ? "track" : "block", i, unitstat,
                     ckddasd ? "track" : "block" );
            if (ckddasd)
                nulltrk(idev->buf, i, idev->ckdheads, nullfmt);
            else
                memset (idev->buf, 0, FBA_BLKGRP_SIZE);
            if (!quiet)
            {
#if defined( EXTERNALGUI )
                if (!extgui)
#endif
                    printf ( "  %3d%% %7d of %d", 0, 0, n );
                status (i, n);
            }
        }

        /* Write the track or block just read */
        if (ckddasd)
        {
            rc = (odev->hnd->write)(odev, i, 0, idev->buf,
                      idev->ckdtrksz, &unitstat);
        }
        else
        {
            if (fba_bytes_remaining >= (size_t)idev->buflen)
            {
                rc = (odev->hnd->write)(odev,  i, 0, idev->buf,
                          idev->buflen, &unitstat);
                fba_bytes_remaining -= (size_t)idev->buflen;
            }
            else
            {
                ASSERT(fba_bytes_remaining > 0 && (i+1) >= n);
                rc = (odev->hnd->write)(odev,  i, 0, idev->buf,
                          (int)fba_bytes_remaining, &unitstat);
                fba_bytes_remaining = 0;
            }
        }
        if (rc < 0)
        {
            // "Write error on file %s: %s %d stat=%2.2X"
            FWRMSG( stderr, HHC02434, "E",
                     ofile, ckddasd ? "track" : "block", i, unitstat );
            close_image_file(icif); close_image_file(ocif);
            return -1;
        }

        /* Update the status indicator */
        if (!quiet) status (i+1, n);
    }

    close_image_file(icif); close_image_file(ocif);

#if defined( EXTERNALGUI )
    if (!extgui)
#endif
        if (!quiet)
            printf (_("\r"));

    // "DASD operation completed"
    WRMSG( HHC02423, "I" );
    return 0;
}
Example #3
0
/*-------------------------------------------------------------------*/
int main (int argc, char *argv[])
{
char           *pgm;                    /* -> Program name           */
int             ckddasd=-1;             /* 1=CKD  0=FBA              */
int             rc;                     /* Return code               */
int             quiet=0;                /* 1=Don't display status    */
int             comp=255;               /* Compression algorithm     */
int             cyls=-1, blks=-1;       /* Size of output file       */
int             lfs=0;                  /* 1=Create 1 large file     */
int             alt=0;                  /* 1=Create alt cyls         */
int             r=0;                    /* 1=Replace output file     */
int             in=0, out=0;            /* Input/Output file types   */
int             fd;                     /* Input file descriptor     */
char           *ifile, *ofile;          /* -> Input/Output file names*/
char           *sfile=NULL;             /* -> Input shadow file name */
CIFBLK         *icif, *ocif;            /* -> Input/Output CIFBLK    */
DEVBLK         *idev, *odev;            /* -> Input/Output DEVBLK    */

CKDDEV         *ckd=NULL;               /* -> CKD device table entry */
FBADEV         *fba=NULL;               /* -> FBA device table entry */
int             i, n, max;              /* Loop index, limits        */
BYTE            unitstat;               /* Device unit status        */
char            msgbuf[512];            /* Message buffer            */
size_t          fba_bytes_remaining=0;  /* FBA bytes to be copied    */
int             nullfmt = CKDDASD_NULLTRK_FMT0; /* Null track format */
char            pathname[MAX_PATH];     /* file path in host format  */
char            pgmpath[MAX_PATH];      /* prog path in host format  */

    INITIALIZE_UTILITY("dasdcopy");

    /* Figure out processing based on the program name */
    hostpath(pgmpath, argv[0], sizeof(pgmpath));
    pgm = strrchr (pgmpath, '/');
    if (pgm) pgm++;
    else pgm = argv[0];
    strtok (pgm, ".");
    if (strcmp(pgm, "ckd2cckd") == 0)
    {
        in = CKD;
        out = CCKD;
    }
    else if (strcmp(pgm, "cckd2ckd") == 0)
    {
        in = CCKD;
        out = CKD;
    }
    else if (strcmp(pgm, "fba2cfba") == 0)
    {
        in = FBA;
        out = CFBA;
    }
    else if (strcmp(pgm, "cfba2fba") == 0)
    {
        in = CFBA;
        out = FBA;
    }

    /* Process the arguments */
    for (argc--, argv++ ; argc > 0 ; argc--, argv++)
    {
        if (argv[0][0] != '-') break;
        if (strcmp(argv[0], "-v") == 0)
        {
             snprintf (msgbuf, 512, _("Hercules %s copy program "), pgm);
             display_version (stderr, msgbuf, FALSE);
             return 0;
        }
        else if (strcmp(argv[0], "-h") == 0)
        {
            syntax(pgm);
            return 0;
        }
        else if (strcmp(argv[0], "-q") == 0
              || strcmp(argv[0], "-quiet") == 0)
            quiet = 1;
        else if (strcmp(argv[0], "-r") == 0)
            r = 1;
#ifdef CCKD_COMPRESS_ZLIB
        else if (strcmp(argv[0], "-z") == 0)
            comp = CCKD_COMPRESS_ZLIB;
#endif
#ifdef CCKD_COMPRESS_BZIP2
        else if (strcmp(argv[0], "-bz2") == 0)
            comp = CCKD_COMPRESS_BZIP2;
#endif
        else if (strcmp(argv[0], "-0") == 0)
            comp = CCKD_COMPRESS_NONE;
        else if ((strcmp(argv[0], "-cyl") == 0
               || strcmp(argv[0], "-cyls") == 0) && cyls < 0)
        {
            if (argc < 2 || (cyls = atoi(argv[1])) < 0)
                return syntax(pgm);
            argc--; argv++;
        }
        else if ((strcmp(argv[0], "-blk") == 0
               || strcmp(argv[0], "-blks") == 0) && blks < 0)
        {
            if (argc < 2 || (blks = atoi(argv[1])) < 0)
                return syntax(pgm);
            argc--; argv++;
        }
        else if (strcmp(argv[0], "-a") == 0
              || strcmp(argv[0], "-alt") == 0
              || strcmp(argv[0], "-alts") == 0)
            alt = 1;
        else if (strcmp(argv[0], "-lfs") == 0)
            lfs = 1;
        else if (out == 0 && strcmp(argv[0], "-o") == 0)
        {
            if (argc < 2 || out != 0) return syntax(pgm);
            if (strcasecmp(argv[1], "ckd") == 0)
                out = CKD;
            else if (strcasecmp(argv[1], "cckd") == 0)
                out = CCKD;
            else if (strcasecmp(argv[1], "fba") == 0)
                out = FBA;
            else if (strcasecmp(argv[1], "cfba") == 0)
                out = CFBA;
            else
                return syntax(pgm);
            argc--; argv++;
        }
        else
            return syntax(pgm);
    }

    /* Get the file names:
       input-file [sf=shadow-file] output-file   */
    if (argc < 2 || argc > 3) return syntax(pgm);
    ifile = argv[0];
    if (argc < 3)
        ofile = argv[1];
    else
    {
        if (strlen(argv[1]) < 4 || memcmp(argv[1], "sf=", 3))
            return syntax(pgm);
        sfile = argv[1];
        ofile = argv[2];
    }

    /* If we don't know what the input file is then find out */
    if (in == 0)
    {
        BYTE buf[8];
        hostpath(pathname, ifile, sizeof(pathname));
        fd = hopen(pathname, O_RDONLY|O_BINARY);
        if (fd < 0)
        {
            fprintf (stderr, _("HHCDC001E %s: %s open error: %s\n"),
                     pgm, ifile, strerror(errno));
            return -1;
        }
        rc = read (fd, buf, 8);
        if (rc < 8)
        {
            fprintf (stderr, _("HHCDC002E %s: %s read error: %s\n"),
                     pgm, ifile, strerror(errno));
            return -1;
        }
        if (memcmp(buf, "CKD_P370", 8) == 0)
            in = CKD;
        else if (memcmp(buf, "CKD_C370", 8) == 0)
            in = CCKD;
        else if (memcmp(buf, "FBA_C370", 8) == 0)
            in = CFBA;
        else
            in = FBA;
        close (fd);
    }

    /* If we don't know what the output file type is
       then derive it from the input file type */
    if (out == 0)
    {
        switch (in) {
        case CKD:  if (!lfs) out = CCKD;
                   else out = CKD;
                   break;
        case CCKD: if (comp == 255) out = CKD;
                   else out = CCKD;
                   break;
        case FBA:  if (!lfs) out = CFBA;
                   else out = FBA;
                   break;
        case CFBA: if (comp == 255) out = FBA;
                   else out = CFBA;
                   break;
        }
    }

    /* Set default compression if out file is to be compressed */
    if (comp == 255 && (out & COMPMASK))
#ifdef CCKD_COMPRESS_ZLIB
        comp = CCKD_COMPRESS_ZLIB;
#else
        comp = CCKD_COMPRESS_NONE;
#endif

    /* Perform sanity checks on the options */
    if ((in & CKDMASK) && !(out & CKDMASK)) return syntax(pgm);
    if ((in & FBAMASK) && !(out & FBAMASK)) return syntax(pgm);
    if (sfile && !(in & COMPMASK)) return syntax(pgm);
    if (comp != 255 && !(out & COMPMASK)) return syntax(pgm);
    if (lfs && (out & COMPMASK)) return syntax(pgm);
    if (cyls >= 0 && !(in & CKDMASK)) return syntax(pgm);
    if (blks >= 0 && !(in & FBAMASK)) return syntax(pgm);
    if (!(in & CKDMASK) && alt) return syntax(pgm);

    /* Set the type of processing (ckd or fba) */
    ckddasd = (in & CKDMASK);

    /* Open the input file */
    if (ckddasd)
        icif = open_ckd_image (ifile, sfile, O_RDONLY|O_BINARY, 0);
    else
        icif = open_fba_image (ifile, sfile, O_RDONLY|O_BINARY, 0);
    if (icif == NULL)
    {
        fprintf (stderr, _("HHCDC003E %s: %s open failed\n"), pgm, ifile);
        return -1;
    }
    idev = &icif->devblk;
    if (idev->oslinux) nullfmt = CKDDASD_NULLTRK_FMT2;

    /* Calculate the number of tracks or blocks to copy */
    if (ckddasd)
    {
        if (cyls < 0) cyls = idev->ckdcyls;
        else if (cyls == 0) cyls = (idev->hnd->used)(idev);
        ckd = dasd_lookup (DASD_CKDDEV, NULL, idev->devtype, cyls);
        if (ckd == NULL)
        {
            fprintf (stderr, _("HHCDC004E %s: ckd lookup failed for %4.4X "
                     "cyls %d\n"),
                     pgm, idev->devtype, cyls);
            close_image_file (icif);
            return -1;
        }
        if (out == CCKD) cyls = ckd->cyls;
        if (cyls <= ckd->cyls && alt) cyls = ckd->cyls + ckd->altcyls;
        n = cyls * idev->ckdheads;
        max = idev->ckdtrks;
        if (max < n && out == CCKD) n = max;
    }
    else
    {
        fba_bytes_remaining = idev->fbanumblk * idev->fbablksiz;
        if (blks < 0) blks = idev->fbanumblk;
        else if (blks == 0) blks = (idev->hnd->used)(idev);
        fba = dasd_lookup (DASD_FBADEV, NULL, idev->devtype, blks);
        if (fba == NULL)
        {
            fprintf (stderr, _("HHCDC005E %s: fba lookup failed, blks %d\n"),
                     pgm, blks);
            close_image_file (icif);
            return -1;
        }
        n = blks;
        max = idev->fbanumblk;
        if (max < n && out == CFBA) n = max;
        n = (n + FBA_BLKS_PER_GRP - 1) / FBA_BLKS_PER_GRP;
        max = (max + FBA_BLKS_PER_GRP - 1) / FBA_BLKS_PER_GRP;
    }

    /* Create the output file */
    if (ckddasd)
        rc = create_ckd(ofile, idev->devtype, idev->ckdheads,
                        ckd->r1, cyls, "", comp, lfs, 1+r, nullfmt, 0);
    else
        rc = create_fba(ofile, idev->devtype, fba->size,
                        blks, "", comp, lfs, 1+r, 0);
    if (rc < 0)
    {
        fprintf (stderr, _("HHCDC006E %s: %s create failed\n"), pgm, ofile);
        close_image_file (icif);
        return -1;
    }

    /* Open the output file */
    if (ckddasd)
        ocif = open_ckd_image (ofile, NULL, O_RDWR|O_BINARY, 1);
    else
        ocif = open_fba_image (ofile, NULL, O_RDWR|O_BINARY, 1);
    if (ocif == NULL)
    {
        fprintf (stderr, _("HHCDC007E %s: %s open failed\n"), pgm, ofile);
        close_image_file (icif);
        return -1;
    }
    odev = &ocif->devblk;

    /* Copy the files */
#ifdef EXTERNALGUI
    if (extgui)
        /* Notify GUI of total #of tracks or blocks being copied... */
        fprintf (stderr, "TRKS=%d\n", n);
    else
#endif /*EXTERNALGUI*/
    if (!quiet) printf ("  %3d%% %7d of %d", 0, 0, n);
    for (i = 0; i < n; i++)
    {
        /* Read a track or block */
        if (ckddasd)
        {
            if (i < max)
                rc = (idev->hnd->read)(idev, i, &unitstat);
            else
            {
                memset (idev->buf, 0, idev->ckdtrksz);
                rc = nulltrk(idev->buf, i, idev->ckdheads, nullfmt);
            }
        }
        else
        {
            if (i < max)
                rc = (idev->hnd->read)(idev, i, &unitstat);
            else
                memset (idev->buf, 0, FBA_BLKGRP_SIZE);
                rc = 0;
        }
        if (rc < 0)
        {
            fprintf (stderr, _("HHCDC008E %s: %s read error %s %d "
                               "stat=%2.2X, null %s substituted\n"),
                     pgm, ifile, ckddasd ? "track" : "block", i, unitstat,
                     ckddasd ? "track" : "block");
            if (ckddasd)
                nulltrk(idev->buf, i, idev->ckdheads, nullfmt);
            else
                memset (idev->buf, 0, FBA_BLKGRP_SIZE);
            if (!quiet)
            {
                printf (_("  %3d%% %7d of %d"), 0, 0, n);
                status (i, n);
            }
        }

        /* Write the track or block just read */
        if (ckddasd)
        {
            rc = (odev->hnd->write)(odev, i, 0, idev->buf,
                      idev->ckdtrksz, &unitstat);
        }
        else
        {
            if (fba_bytes_remaining >= (size_t)idev->buflen)
            {
                rc = (odev->hnd->write)(odev,  i, 0, idev->buf,
                          idev->buflen, &unitstat);
                fba_bytes_remaining -= (size_t)idev->buflen;
            }
            else
            {
                ASSERT(fba_bytes_remaining > 0 && (i+1) >= n);
                rc = (odev->hnd->write)(odev,  i, 0, idev->buf,
                          (int)fba_bytes_remaining, &unitstat);
                fba_bytes_remaining = 0;
            }
        }
        if (rc < 0)
        {
            fprintf (stderr, _("HHCDC009E %s: %s write error %s %d "
                               "stat=%2.2X\n"),
                     pgm, ofile, ckddasd ? "track" : "block", i, unitstat);
            close_image_file(icif); close_image_file(ocif);
            return -1;
        }

        /* Update the status indicator */
        if (!quiet) status (i+1, n);
    }

    close_image_file(icif); close_image_file(ocif);
    if (!quiet) printf (_("\r"));
    printf (_("HHCDC010I %s successfully completed.\n"), pgm);
    return 0;
}
Example #4
0
/*-------------------------------------------------------------------*/
int main ( int argc, char *argv[] )
{
int     altcylflag = 0;                 /* Alternate cylinders flag  */
int     rawflag = 0;                    /* Raw format flag           */
int     volsize_argnum = 4;             /* argc value of size option */
U32     size = 0;                       /* Volume size               */
U32     altsize = 0;                    /* Alternate cylinders       */
U32     heads = 0;                      /* Number of tracks/cylinder */
U32     maxdlen = 0;                    /* Maximum R1 data length    */
U32     sectsize = 0;                   /* Sector size               */
U16     devtype = 0;                    /* Device type               */
BYTE    comp = 0xff;                    /* Compression algoritm      */
BYTE    type = 0;                       /* C=CKD, F=FBA              */
char    fname[1024];                    /* File name                 */
char    volser[7];                      /* Volume serial number      */
BYTE    c;                              /* Character work area       */
CKDDEV *ckd;                            /* -> CKD device table entry */
FBADEV *fba;                            /* -> FBA device table entry */
int     lfs = 0;                        /* 1 = Build large file      */
int     nullfmt = CKDDASD_NULLTRK_FMT1; /* Null track format type    */
int     rc;                             /* Return code               */

    INITIALIZE_UTILITY("dasdinit");

    /* Display program identification and help */
    if (argc <= 1 || (argc == 2 && !strcmp(argv[1], "-v")))
        argexit(-1, NULL);

    /* Process optional arguments */
    for ( ; argc > 1 && argv[1][0] == '-'; argv++, argc--)
    {
        if (strcmp("0", &argv[1][1]) == 0)
            comp = CCKD_COMPRESS_NONE;
#ifdef HAVE_LIBZ
        else if (strcmp("z", &argv[1][1]) == 0)
            comp = CCKD_COMPRESS_ZLIB;
#endif
#ifdef CCKD_BZIP2
        else if (strcmp("bz2", &argv[1][1]) == 0)
            comp = CCKD_COMPRESS_BZIP2;
#endif
        else if (strcmp("a", &argv[1][1]) == 0)
            altcylflag = 1;
        else if (strcmp("r", &argv[1][1]) == 0)
            rawflag = 1;
        else if (strcmp("lfs", &argv[1][1]) == 0 && sizeof(off_t) > 4)
            lfs = 1;
        else if (strcmp("linux", &argv[1][1]) == 0)
            nullfmt = CKDDASD_NULLTRK_FMT2;
        else argexit(0, argv[1]);
    }

    /* Check remaining number of arguments */
    if (argc < (rawflag ? 3 : 4) || argc > (rawflag ? 4 : 5))
        argexit(5, NULL);

    /* The first argument is the file name */
    if (argv[1] == NULL || strlen(argv[1]) == 0
        || strlen(argv[1]) > sizeof(fname)-1)
        argexit(1, argv[1]);

    strcpy (fname, argv[1]);

    /* The second argument is the device type.
       Model number may also be specified */
    if (argv[2] == NULL)
        argexit(2, argv[2]);
    ckd = dasd_lookup (DASD_CKDDEV, argv[2], 0, 0);
    if (ckd != NULL)
    {
        type = 'C';
        devtype = ckd->devt;
        size = ckd->cyls;
        altsize = ckd->altcyls;
        heads = ckd->heads;
        maxdlen = ckd->r1;
    }
    else
    {
        fba = dasd_lookup (DASD_FBADEV, argv[2], 0, 0);
        if (fba != NULL)
        {
            type = 'F';
            devtype = fba->devt;
            size = fba->blks;
            altsize = 0;
            sectsize = fba->size;
        }
    }

    if (!type)
        /* Specified model not found */
        argexit(2, argv[2]);

    /* If -r option specified, then there is not volume serial
       argument and volume size argument is actually argument
       number 3 and not argument number 4 as otherwise */
    if (rawflag)
        volsize_argnum = 3;
    else
    {
        volsize_argnum = 4;

        /* The third argument is the volume serial number */
        if (argv[3] == NULL || strlen(argv[3]) == 0
            || strlen(argv[3]) > sizeof(volser)-1)
            argexit(3, argv[3]);

        strcpy (volser, argv[3]);
        string_to_upper (volser);
    }

    /* The fourth argument (or third for -r) is the volume size */
    if (argc > volsize_argnum)
    {
        if (argc > (volsize_argnum+1))
            argexit(5, NULL);

        if (!argv[volsize_argnum] || strlen(argv[volsize_argnum]) == 0
            || sscanf(argv[volsize_argnum], "%u%c", &size, &c) != 1)
            argexit(4, argv[volsize_argnum]);

        altcylflag = 0;
    }

    /* `-linux' only supported for 3390 device type */
    if (nullfmt == CKDDASD_NULLTRK_FMT2 && devtype != 0x3390)
        argexit(6, NULL);

    if (altcylflag)
        size += altsize;

    /* Create the device */
    if (type == 'C')
        rc = create_ckd (fname, devtype, heads, maxdlen, size, volser,
                        comp, lfs, 0, nullfmt, rawflag);
    else
        rc = create_fba (fname, devtype, sectsize, size, volser, comp,
                        lfs, 0, rawflag);

    /* Display completion message */
    if (rc == 0)
    {
        fprintf (stderr, _("HHCDI001I DASD initialization successfully "
                "completed.\n"));
    } else {
        fprintf (stderr, _("HHCDI002I DASD initialization unsuccessful"
                "\n"));
    }

    return rc;

} /* end function main */