1 /* CCKDSWAP.C   (c) Copyright Greg Smith, 2000-2009                  */
2 /*              Swap the endianess of a compressed CKD file          */
3 
4 /*-------------------------------------------------------------------*/
5 /* This module changes the `endianess' of a compressed CKD file.     */
6 /*-------------------------------------------------------------------*/
7 
8 #include "hstdinc.h"
9 
10 #include "hercules.h"
11 
12 /*-------------------------------------------------------------------*/
13 /* Swap the `endianess' of  cckd file                                */
14 /*-------------------------------------------------------------------*/
15 
16 int syntax ();
17 
main(int argc,char * argv[])18 int main ( int argc, char *argv[])
19 {
20 CKDDASD_DEVHDR  devhdr;                 /* CKD device header         */
21 CCKDDASD_DEVHDR cdevhdr;                /* Compressed CKD device hdr */
22 int             level = 0;              /* Chkdsk level              */
23 int             force = 0;              /* 1=swap if OPENED bit on   */
24 int             rc;                     /* Return code               */
25 int             i;                      /* Index                     */
26 int             bigend;                 /* 1=big-endian file         */
27 DEVBLK          devblk;                 /* DEVBLK                    */
28 DEVBLK         *dev=&devblk;            /* -> DEVBLK                 */
29 
30     INITIALIZE_UTILITY("cckdswap");
31 
32     /* parse the arguments */
33     for (argc--, argv++ ; argc > 0 ; argc--, argv++)
34     {
35         if(**argv != '-') break;
36 
37         switch(argv[0][1])
38         {
39             case '0':
40             case '1':
41             case '2':
42             case '3':  if (argv[0][2] != '\0') return syntax ();
43                        level = (argv[0][1] & 0xf);
44                        break;
45             case 'f':  if (argv[0][2] != '\0') return syntax ();
46                        force = 1;
47                        break;
48             case 'v':  if (argv[0][2] != '\0') return syntax ();
49                        display_version
50                          (stderr, "Hercules cckd swap program ", FALSE);
51                        return 0;
52             default:   return syntax ();
53         }
54     }
55 
56     if (argc < 1) return syntax ();
57 
58     for (i = 0; i < argc; i++)
59     {
60         memset (dev, 0, sizeof (DEVBLK));
61         dev->batch = 1;
62 
63         /* open the input file */
64         hostpath(dev->filename, argv[i], sizeof(dev->filename));
65         dev->fd = hopen(dev->filename, O_RDWR|O_BINARY);
66         if (dev->fd < 0)
67         {
68             cckdumsg (dev, 700, "open error: %s\n", strerror(errno));
69             continue;
70         }
71 
72         /* read the CKD device header */
73         if ((rc = read (dev->fd, &devhdr, CKDDASD_DEVHDR_SIZE)) < CKDDASD_DEVHDR_SIZE)
74         {
75             cckdumsg (dev, 703, "read error rc=%d offset 0x%" I64_FMT "x len %d: %s\n",
76                       rc, (long long)0, CKDDASD_DEVHDR_SIZE,
77                       rc < 0 ? strerror(errno) : "incomplete");
78             close (dev->fd);
79             continue;
80         }
81         if (memcmp(devhdr.devid, "CKD_C370", 8) != 0
82          && memcmp(devhdr.devid, "CKD_S370", 8) != 0
83          && memcmp(devhdr.devid, "FBA_C370", 8) != 0
84          && memcmp(devhdr.devid, "FBA_S370", 8) != 0)
85         {
86             cckdumsg (dev, 999, "not a compressed dasd file\n");
87             close (dev->fd);
88             continue;
89         }
90 
91         /* read the compressed CKD device header */
92         if ((rc = read (dev->fd, &cdevhdr, CCKD_DEVHDR_SIZE)) < CCKD_DEVHDR_SIZE)
93         {
94             cckdumsg (dev, 703, "read error rc=%d offset 0x%" I64_FMT "x len %d: %s\n",
95                       rc, (long long)CCKD_DEVHDR_POS, CCKD_DEVHDR_SIZE,
96                       rc < 0 ? strerror(errno) : "incomplete");
97             close (dev->fd);
98             continue;
99         }
100 
101         /* Check the OPENED bit */
102         if (!force && (cdevhdr.options & CCKD_OPENED))
103         {
104             cckdumsg (dev, 707, "OPENED bit is on, use -f\n");
105             close (dev->fd);
106             continue;
107         }
108 
109         /* get the byte order of the file */
110         bigend = (cdevhdr.options & CCKD_BIGENDIAN);
111 
112         /* call chkdsk */
113         if (cckd_chkdsk (dev, level) < 0)
114         {
115             cckdumsg (dev, 708, "chkdsk errors\n");
116             close (dev->fd);
117             continue;
118         }
119 
120         /* re-read the compressed CKD device header */
121         if (lseek (dev->fd, CCKD_DEVHDR_POS, SEEK_SET) < 0)
122         {
123             cckdumsg (dev, 702, "lseek error offset 0x%" I64_FMT "x: %s\n",
124                       (long long)CCKD_DEVHDR_POS, strerror(errno));
125             close (dev->fd);
126             continue;
127         }
128         if ((rc = read (dev->fd, &cdevhdr, CCKD_DEVHDR_SIZE)) < CCKD_DEVHDR_SIZE)
129         {
130             cckdumsg (dev, 703, "read error rc=%d offset 0x%" I64_FMT "x len %d: %s\n",
131                       rc, (long long)CCKD_DEVHDR_POS, CCKD_DEVHDR_SIZE,
132                       rc < 0 ? strerror(errno) : "incomplete");
133             close (dev->fd);
134             continue;
135         }
136 
137         /* swap the byte order of the file if chkdsk didn't do it for us */
138         if (bigend == (cdevhdr.options & CCKD_BIGENDIAN))
139         {
140             cckdumsg (dev, 101, "converting to %s\n",
141                       bigend ? "litle-endian" : "big-endian");
142             if (cckd_swapend (dev) < 0)
143                 cckdumsg (dev, 910, "error during swap\n");
144         }
145 
146         close (dev->fd);
147     } /* for each arg */
148 
149     return 0;
150 } /* end main */
151 
syntax()152 int syntax ()
153 {
154     fprintf (stderr, "\ncckdswap [-v] [-f] file1 [file2 ... ]\n"
155                 "\n"
156                 "          -v      display version and exit\n"
157                 "\n"
158                 "          -f      force check even if OPENED bit is on\n"
159                 "\n"
160                 "        chkdsk level is a digit 0 - 3:\n"
161                 "          -0  --  minimal checking\n"
162                 "          -1  --  normal  checking\n"
163                 "          -2  --  intermediate checking\n"
164                 "          -3  --  maximal checking\n"
165                 "         default  0\n"
166                 "\n");
167     return -1;
168 } /* end function syntax */
169