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