1 /* DMAP2HRC.C (c) Copyright Jay Maynard, 2001-2009 */
2 /* Convert P/390 DEVMAP to Hercules config file */
3
4 /*-------------------------------------------------------------------*/
5 /* This program reads a P/390 DEVMAP file and extracts the device */
6 /* definitions from it, then writes them to the standard output in */
7 /* the format Hercules uses for its .cnf file. */
8 /*-------------------------------------------------------------------*/
9
10 #include "hstdinc.h"
11
12 #include "hercules.h"
13
14 /*-------------------------------------------------------------------*/
15 /* Structure definition for DEVMAP controller record */
16 /*-------------------------------------------------------------------*/
17 typedef struct _DEVMAP_CTLR {
18 BYTE channel; /* High order dev addr byte */
19 BYTE name[8]; /* Name of controller program*/
20 BYTE lowdev; /* Low addr byte first dev */
21 BYTE highdev; /* Low addr byte last dev */
22 BYTE filler1; /* Fill byte */
23 BYTE type[4]; /* Type of controller */
24 BYTE flags; /* Flag byte */
25 BYTE filler2[47]; /* More filler bytes */
26 } DEVMAP_CTLR;
27
28 /*-------------------------------------------------------------------*/
29 /* Structure definition for DEVMAP device record */
30 /*-------------------------------------------------------------------*/
31 typedef struct _DEVMAP_DEV {
32 BYTE highaddr; /* High order dev addr byte */
33 BYTE lowaddr; /* Low order dev addr byte */
34 char type[4]; /* Type of device */
35 union {
36 struct { /* Disk devices: */
37 BYTE filler1[4]; /* filler */
38 BYTE volser[6]; /* Volume serial */
39 BYTE filler2[2]; /* more filler */
40 char filename[45]; /* name of file on disk */
41 BYTE flags; /* flag byte */
42 } disk;
43 struct { /* Other devices: */
44 BYTE filler1[7]; /* fill bytes */
45 char filename[50]; /* device filename */
46 BYTE flags; /* flag byte */
47 } other;
48 } parms;
49 } DEVMAP_DEV;
50
51 /*-------------------------------------------------------------------*/
52 /* DEVMAP2CNF main entry point */
53 /*-------------------------------------------------------------------*/
main(int argc,char * argv[])54 int main (int argc, char *argv[])
55 {
56 int i; /* Array subscript */
57 int len; /* Length of actual read */
58 char *filename; /* -> Input file name */
59 int infd = -1; /* Input file descriptor */
60 DEVMAP_CTLR controller; /* Controller record */
61 DEVMAP_DEV device; /* Device record */
62 char output_type[5]; /* Device type to print */
63 char *output_filename; /* -> filename to print */
64 int more_devices; /* More devices this ctlr? */
65 char pathname[MAX_PATH]; /* file path in host format */
66
67 INITIALIZE_UTILITY("dmap2hrc");
68
69 /* Display the program identification message */
70 display_version (stderr,
71 "P/390 DEVMAP to Hercules conversion program\n", FALSE);
72
73 /* The only argument is the DEVMAP file name */
74 if (argc == 2 && argv[1] != NULL)
75 {
76 filename = argv[1];
77 }
78 else
79 {
80 fprintf (stderr,"Usage: dmap2hrc filename\n");
81 exit (1);
82 }
83
84 /* Open the devmap file */
85 hostpath(pathname, filename, sizeof(pathname));
86 infd = hopen(pathname, O_RDONLY | O_BINARY);
87 if (infd < 0)
88 {
89 fprintf (stderr,"dmap2hrc: Error opening %s: %s\n",
90 filename, strerror(errno));
91 exit (2);
92 }
93
94 /* Skip the file header */
95 for (i = 0; i < 9; i++)
96 {
97 len = read (infd, (void *)&controller, sizeof(DEVMAP_CTLR));
98 if (len < 0)
99 {
100 fprintf (stderr,
101 "dmap2hrc: error reading header records from %s: %s\n",
102 filename, strerror(errno));
103 exit (3);
104 }
105 }
106
107 /* Read records from the input file and convert them */
108 while (1)
109 {
110 /* Read a controller record. */
111 len = read (infd, (void *)&controller, sizeof(DEVMAP_CTLR));
112 if (len < 0)
113 {
114 fprintf (stderr,
115 "dmap2hrc: error reading controller record from %s:"
116 " %s\n",
117 filename, strerror(errno));
118 exit (4);
119 }
120
121 /* Did we finish too soon? */
122 if ((len > 0) && (len < (int)sizeof(DEVMAP_CTLR)))
123 {
124 fprintf (stderr,
125 "dmap2hrc: incomplete controller record on %s\n",
126 filename);
127 exit(5);
128 }
129
130 /* Check for end of file. */
131 if (len == 0)
132 {
133 fprintf(stderr, "End of input file.\n");
134 break;
135 }
136
137 /* Read devices on this controller. */
138 more_devices = 1;
139 while (more_devices)
140 {
141
142 /* Read a device record. */
143 len = read (infd, (void *)&device, sizeof(DEVMAP_DEV));
144 if (len < 0)
145 {
146 fprintf (stderr,
147 "dmap2hrc: error reading device record from %s:"
148 " %s\n",
149 filename, strerror(errno));
150 exit (6);
151 }
152
153 /* Did we finish too soon? */
154 if ((len > 0) && (len < (int)sizeof(DEVMAP_DEV)))
155 {
156 fprintf (stderr,
157 "dmap2hrc: incomplete device record on %s\n",
158 filename);
159 exit(7);
160 }
161
162 /* Check for end of file. */
163 if (len == 0)
164 {
165 fprintf (stderr,"dmap2hrc: premature end of input file\n");
166 exit(8);
167 }
168
169 /* Is this the dummy device record at the end of the controller's
170 set of devices? */
171 if (strncmp(device.type," ",4) == 0)
172 {
173 more_devices = 0;
174 break;
175 }
176
177 /* It's a real device. Fix the type so Hercules can use it and
178 locate the output filename. */
179 strncpy(output_type, device.type, 4);
180 output_type[4] = '\0';
181 if (isprint(device.parms.disk.volser[0]))
182 output_filename = device.parms.disk.filename;
183 else output_filename = device.parms.other.filename;
184
185 if (strncmp(device.type, "3278", 4) == 0)
186 {
187 strcpy(output_type, "3270");
188 output_filename = "";
189 }
190 if (strncmp(device.type, "2540", 4) == 0)
191 strcpy(output_type, "3505");
192
193 /* Emit the Hercules config file entry. */
194 printf("%02X%02X %s",
195 device.highaddr, device.lowaddr,
196 output_type);
197 if (strlen(output_filename) > 0)
198 printf(" %s", output_filename);
199 puts(""); /* newline */
200
201 } /* end while more_devices) */
202
203 } /* end while (1) */
204
205 /* Close files and exit */
206 close (infd);
207
208 return 0;
209
210 } /* end function main */
211