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