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