1 /* DASDINIT.C   (c) Copyright Roger Bowler, 1999-2009                */
2 /*              Hercules DASD Utilities: DASD image builder          */
3 
4 /*-------------------------------------------------------------------*/
5 /* This program creates a disk image file and initializes it as      */
6 /* a blank FBA or CKD DASD volume.                                   */
7 /*                                                                   */
8 /* The program is invoked from the shell prompt using the command:   */
9 /*                                                                   */
10 /*      dasdinit [-options] filename devtype[-model] [volser] [size] */
11 /*                                                                   */
12 /* options      options:                                             */
13 /*                -a    include alternate cylinders                  */
14 /*                      (ignored if size specified manually)         */
15 /*                -z    build compressed device using zlib           */
16 /*                -bz2  build compressed device using bzip2          */
17 /*                -0    build compressed device with no compression  */
18 /*                -r    "raw" init (bypass VOL1 & IPL track fmt)     */
19 /*                                                                   */
20 /* filename     is the name of the disk image file to be created     */
21 /*              (this program will not overwrite an existing file)   */
22 /*                                                                   */
23 /* devtype      is the emulated device type.                         */
24 /*              CKD: 2305, 2311, 2314, 3330, 3350, 3375, 3380,       */
25 /*                   3390, 9345                                      */
26 /*              FBA: 0671, 3310, 3370, 9313, 9332, 9335, 9336        */
27 /*                                                                   */
28 /* model        is the device model number and implies the device    */
29 /*              size. If specified, then size shouldn't be specified.*/
30 /*                                                                   */
31 /* volser       is the volume serial number (1-6 characters)         */
32 /*              (only if '-r' option not used)                       */
33 /*                                                                   */
34 /* size         is the size of the device (in cylinders for CKD      */
35 /*              devices, or in 512-byte sectors for FBA devices).    */
36 /*              Shouldn't be specified if model is specified.        */
37 /*                                                                   */
38 /*-------------------------------------------------------------------*/
39 
40 #include "hstdinc.h"
41 
42 #include "hercules.h"
43 #include "dasdblks.h"
44 
45 /*-------------------------------------------------------------------*/
46 /* Subroutine to display command syntax and exit                     */
47 /*-------------------------------------------------------------------*/
48 static void
argexit(int code,char * m)49 argexit ( int code, char *m )
50 {
51 
52     switch (code) {
53     case 0:
54         fprintf (stderr, "Invalid or unsupported option: %s\n",
55                  m ? m : "(null)");
56         break;
57     case 1:
58         fprintf (stderr, "Invalid or missing filename: %s\n",
59                  m ? m : "(null)");
60         break;
61     case 2:
62         fprintf (stderr, "Invalid or missing device type: %s\n",
63                  m ? m : "(null)");
64         break;
65     case 3:
66         fprintf (stderr, "Invalid or missing volser: %s\n",
67                  m ? m : "(null)");
68         break;
69     case 4:
70         fprintf (stderr, "Invalid or missing size: %s\n",
71                  m ? m : "(null)");
72         break;
73     case 5:
74         fprintf (stderr, "Invalid number of arguments\n");
75         break;
76     case 6:
77         fprintf (stderr, "`-linux' only supported for device type 3390\n");
78         break;
79     default:
80 
81         display_version (stderr,
82                      "Hercules DASD image file creation program\n", FALSE);
83 
84         fprintf (stderr,
85 
86 "Builds an empty dasd image file:\n\n"
87 
88 "  dasdinit [-options] filename devtype[-model] [volser] [size]\n\n"
89 
90 "where:\n\n"
91 
92 "  -v         display version info and help\n"
93 #ifdef HAVE_LIBZ
94 "  -z         build compressed dasd image file using zlib\n"
95 #endif
96 #ifdef CCKD_BZIP2
97 "  -bz2       build compressed dasd image file using bzip2\n"
98 #endif
99 "  -0         build compressed dasd image file with no compression\n"
100 );
101         if (sizeof(off_t) > 4) fprintf(stderr,
102 "  -lfs       build a large (uncompressed) dasd file (if supported)\n"
103 );
104         fprintf(stderr,
105 "  -a         build dasd image file that includes alternate cylinders\n"
106 "             (option ignored if size is manually specified)\n"
107 "  -r         build 'raw' dasd image file  (no VOL1 or IPL track)\n"
108 "  -linux     null track images will look like linux dasdfmt'ed images\n"
109 "             (3390 device type only)\n\n"
110 
111 "  filename   name of dasd image file to be created\n\n"
112 
113 "  devtype    CKD: 2305, 2311, 2314, 3330, 3340, 3350, 3375, 3380, 3390, 9345\n"
114 "             FBA: 0671, 3310, 3370, 9313, 9332, 9335, 9336\n\n"
115 
116 "  model      device model (implies size) (opt)\n\n"
117 
118 "  volser     volume serial number (1-6 characters)\n"
119 "             (specified only if '-r' option not used)\n\n"
120 
121 "  size       number of CKD cylinders or 512-byte FBA sectors\n"
122 "             (required if model not specified else optional)\n"
123 
124 );
125         break;
126     }
127     exit(code);
128 } /* end function argexit */
129 
130 /*-------------------------------------------------------------------*/
131 /* DASDINIT program main entry point                                 */
132 /*-------------------------------------------------------------------*/
main(int argc,char * argv[])133 int main ( int argc, char *argv[] )
134 {
135 int     altcylflag = 0;                 /* Alternate cylinders flag  */
136 int     rawflag = 0;                    /* Raw format flag           */
137 int     volsize_argnum = 4;             /* argc value of size option */
138 U32     size = 0;                       /* Volume size               */
139 U32     altsize = 0;                    /* Alternate cylinders       */
140 U32     heads = 0;                      /* Number of tracks/cylinder */
141 U32     maxdlen = 0;                    /* Maximum R1 data length    */
142 U32     sectsize = 0;                   /* Sector size               */
143 U16     devtype = 0;                    /* Device type               */
144 BYTE    comp = 0xff;                    /* Compression algoritm      */
145 BYTE    type = 0;                       /* C=CKD, F=FBA              */
146 char    fname[1024];                    /* File name                 */
147 char    volser[7];                      /* Volume serial number      */
148 BYTE    c;                              /* Character work area       */
149 CKDDEV *ckd;                            /* -> CKD device table entry */
150 FBADEV *fba;                            /* -> FBA device table entry */
151 int     lfs = 0;                        /* 1 = Build large file      */
152 int     nullfmt = CKDDASD_NULLTRK_FMT1; /* Null track format type    */
153 int     rc;                             /* Return code               */
154 
155     INITIALIZE_UTILITY("dasdinit");
156 
157     /* Display program identification and help */
158     if (argc <= 1 || (argc == 2 && !strcmp(argv[1], "-v")))
159         argexit(-1, NULL);
160 
161     /* Process optional arguments */
162     for ( ; argc > 1 && argv[1][0] == '-'; argv++, argc--)
163     {
164         if (strcmp("0", &argv[1][1]) == 0)
165             comp = CCKD_COMPRESS_NONE;
166 #ifdef HAVE_LIBZ
167         else if (strcmp("z", &argv[1][1]) == 0)
168             comp = CCKD_COMPRESS_ZLIB;
169 #endif
170 #ifdef CCKD_BZIP2
171         else if (strcmp("bz2", &argv[1][1]) == 0)
172             comp = CCKD_COMPRESS_BZIP2;
173 #endif
174         else if (strcmp("a", &argv[1][1]) == 0)
175             altcylflag = 1;
176         else if (strcmp("r", &argv[1][1]) == 0)
177             rawflag = 1;
178         else if (strcmp("lfs", &argv[1][1]) == 0 && sizeof(off_t) > 4)
179             lfs = 1;
180         else if (strcmp("linux", &argv[1][1]) == 0)
181             nullfmt = CKDDASD_NULLTRK_FMT2;
182         else argexit(0, argv[1]);
183     }
184 
185     /* Check remaining number of arguments */
186     if (argc < (rawflag ? 3 : 4) || argc > (rawflag ? 4 : 5))
187         argexit(5, NULL);
188 
189     /* The first argument is the file name */
190     if (argv[1] == NULL || strlen(argv[1]) == 0
191         || strlen(argv[1]) > sizeof(fname)-1)
192         argexit(1, argv[1]);
193 
194     strcpy (fname, argv[1]);
195 
196     /* The second argument is the device type.
197        Model number may also be specified */
198     if (argv[2] == NULL)
199         argexit(2, argv[2]);
200     ckd = dasd_lookup (DASD_CKDDEV, argv[2], 0, 0);
201     if (ckd != NULL)
202     {
203         type = 'C';
204         devtype = ckd->devt;
205         size = ckd->cyls;
206         altsize = ckd->altcyls;
207         heads = ckd->heads;
208         maxdlen = ckd->r1;
209     }
210     else
211     {
212         fba = dasd_lookup (DASD_FBADEV, argv[2], 0, 0);
213         if (fba != NULL)
214         {
215             type = 'F';
216             devtype = fba->devt;
217             size = fba->blks;
218             altsize = 0;
219             sectsize = fba->size;
220         }
221     }
222 
223     if (!type)
224         /* Specified model not found */
225         argexit(2, argv[2]);
226 
227     /* If -r option specified, then there is not volume serial
228        argument and volume size argument is actually argument
229        number 3 and not argument number 4 as otherwise */
230     if (rawflag)
231         volsize_argnum = 3;
232     else
233     {
234         volsize_argnum = 4;
235 
236         /* The third argument is the volume serial number */
237         if (argv[3] == NULL || strlen(argv[3]) == 0
238             || strlen(argv[3]) > sizeof(volser)-1)
239             argexit(3, argv[3]);
240 
241         strcpy (volser, argv[3]);
242         string_to_upper (volser);
243     }
244 
245     /* The fourth argument (or third for -r) is the volume size */
246     if (argc > volsize_argnum)
247     {
248         if (argc > (volsize_argnum+1))
249             argexit(5, NULL);
250 
251         if (!argv[volsize_argnum] || strlen(argv[volsize_argnum]) == 0
252             || sscanf(argv[volsize_argnum], "%u%c", &size, &c) != 1)
253             argexit(4, argv[volsize_argnum]);
254 
255         altcylflag = 0;
256     }
257 
258     /* `-linux' only supported for 3390 device type */
259     if (nullfmt == CKDDASD_NULLTRK_FMT2 && devtype != 0x3390)
260         argexit(6, NULL);
261 
262     if (altcylflag)
263         size += altsize;
264 
265     /* Create the device */
266     if (type == 'C')
267         rc = create_ckd (fname, devtype, heads, maxdlen, size, volser,
268                         comp, lfs, 0, nullfmt, rawflag);
269     else
270         rc = create_fba (fname, devtype, sectsize, size, volser, comp,
271                         lfs, 0, rawflag);
272 
273     /* Display completion message */
274     if (rc == 0)
275     {
276         fprintf (stderr, _("HHCDI001I DASD initialization successfully "
277                 "completed.\n"));
278     } else {
279         fprintf (stderr, _("HHCDI002I DASD initialization unsuccessful"
280                 "\n"));
281     }
282 
283     return rc;
284 
285 } /* end function main */
286