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