1 /* DASDCOPY.C   (c) Copyright Roger Bowler, 1999-2010                */
2 /*              Copy a dasd file to another dasd file                */
3 
4 /*-------------------------------------------------------------------*/
5 /*      This program copies a dasd file to another dasd file.        */
6 /*      Input file and output file may be compressed or not.         */
7 /*      Files may be either ckd (or cckd) or fba (or cfba) but       */
8 /*      file types (ckd/cckd or fba/cfba) may not be mixed.          */
9 /*                                                                   */
10 /*      Usage:                                                       */
11 /*              dasdcopy [-options] ifile [sf=sfile] ofile           */
12 /*                                                                   */
13 /*      Refer to the usage section below for details of options.     */
14 /*                                                                   */
15 /*      The program may also be invoked by one of the following      */
16 /*      aliases which override the default output file format:       */
17 /*                                                                   */
18 /*              ckd2cckd [-options] ifile ofile                      */
19 /*              cckd2ckd [-options] ifile [sf=sfile] ofile           */
20 /*              fba2cfba [-options] ifile ofile                      */
21 /*              cfba2fba [-options] ifile [sf=sfile] ofile           */
22 /*-------------------------------------------------------------------*/
23 
24 #include "hstdinc.h"
25 
26 #include "hercules.h"
27 #include "dasdblks.h"
28 #include "devtype.h"
29 #include "opcode.h"
30 
31 #define FBA_BLKGRP_SIZE  (120 * 512)    /* Size of block group       */
32 #define FBA_BLKS_PER_GRP        120     /* Blocks per group          */
33 
34 int syntax (char *);
35 void status (int, int);
36 int nulltrk(BYTE *, int, int, int);
37 
38 #define CKD      0x01
39 #define CCKD     0x02
40 #define FBA      0x04
41 #define CFBA     0x08
42 #define CKDMASK  0x03
43 #define FBAMASK  0x0c
44 #define COMPMASK 0x0a
45 
46 /*-------------------------------------------------------------------*/
47 /* Copy a dasd file to another dasd file                             */
48 /*-------------------------------------------------------------------*/
main(int argc,char * argv[])49 int main (int argc, char *argv[])
50 {
51 char           *pgm;                    /* -> Program name           */
52 int             ckddasd=-1;             /* 1=CKD  0=FBA              */
53 int             rc;                     /* Return code               */
54 int             quiet=0;                /* 1=Don't display status    */
55 int             comp=255;               /* Compression algorithm     */
56 int             cyls=-1, blks=-1;       /* Size of output file       */
57 int             lfs=0;                  /* 1=Create 1 large file     */
58 int             alt=0;                  /* 1=Create alt cyls         */
59 int             r=0;                    /* 1=Replace output file     */
60 int             in=0, out=0;            /* Input/Output file types   */
61 int             fd;                     /* Input file descriptor     */
62 char           *ifile, *ofile;          /* -> Input/Output file names*/
63 char           *sfile=NULL;             /* -> Input shadow file name */
64 CIFBLK         *icif, *ocif;            /* -> Input/Output CIFBLK    */
65 DEVBLK         *idev, *odev;            /* -> Input/Output DEVBLK    */
66 
67 CKDDEV         *ckd=NULL;               /* -> CKD device table entry */
68 FBADEV         *fba=NULL;               /* -> FBA device table entry */
69 int             i, n, max;              /* Loop index, limits        */
70 BYTE            unitstat;               /* Device unit status        */
71 char            msgbuf[512];            /* Message buffer            */
72 size_t          fba_bytes_remaining=0;  /* FBA bytes to be copied    */
73 int             nullfmt = CKDDASD_NULLTRK_FMT0; /* Null track format */
74 char            pathname[MAX_PATH];     /* file path in host format  */
75 char            pgmpath[MAX_PATH];      /* prog path in host format  */
76 
77     INITIALIZE_UTILITY("dasdcopy");
78 
79     /* Figure out processing based on the program name */
80     hostpath(pgmpath, argv[0], sizeof(pgmpath));
81     pgm = strrchr (pgmpath, '/');
82     if (pgm) pgm++;
83     else pgm = argv[0];
84     strtok (pgm, ".");
85     if (strcmp(pgm, "ckd2cckd") == 0)
86     {
87         in = CKD;
88         out = CCKD;
89     }
90     else if (strcmp(pgm, "cckd2ckd") == 0)
91     {
92         in = CCKD;
93         out = CKD;
94     }
95     else if (strcmp(pgm, "fba2cfba") == 0)
96     {
97         in = FBA;
98         out = CFBA;
99     }
100     else if (strcmp(pgm, "cfba2fba") == 0)
101     {
102         in = CFBA;
103         out = FBA;
104     }
105 
106     /* Process the arguments */
107     for (argc--, argv++ ; argc > 0 ; argc--, argv++)
108     {
109         if (argv[0][0] != '-') break;
110         if (strcmp(argv[0], "-v") == 0)
111         {
112              snprintf (msgbuf, 512, _("Hercules %s copy program "), pgm);
113              display_version (stderr, msgbuf, FALSE);
114              return 0;
115         }
116         else if (strcmp(argv[0], "-h") == 0)
117         {
118             syntax(pgm);
119             return 0;
120         }
121         else if (strcmp(argv[0], "-q") == 0
122               || strcmp(argv[0], "-quiet") == 0)
123             quiet = 1;
124         else if (strcmp(argv[0], "-r") == 0)
125             r = 1;
126 #ifdef CCKD_COMPRESS_ZLIB
127         else if (strcmp(argv[0], "-z") == 0)
128             comp = CCKD_COMPRESS_ZLIB;
129 #endif
130 #ifdef CCKD_COMPRESS_BZIP2
131         else if (strcmp(argv[0], "-bz2") == 0)
132             comp = CCKD_COMPRESS_BZIP2;
133 #endif
134         else if (strcmp(argv[0], "-0") == 0)
135             comp = CCKD_COMPRESS_NONE;
136         else if ((strcmp(argv[0], "-cyl") == 0
137                || strcmp(argv[0], "-cyls") == 0) && cyls < 0)
138         {
139             if (argc < 2 || (cyls = atoi(argv[1])) < 0)
140                 return syntax(pgm);
141             argc--; argv++;
142         }
143         else if ((strcmp(argv[0], "-blk") == 0
144                || strcmp(argv[0], "-blks") == 0) && blks < 0)
145         {
146             if (argc < 2 || (blks = atoi(argv[1])) < 0)
147                 return syntax(pgm);
148             argc--; argv++;
149         }
150         else if (strcmp(argv[0], "-a") == 0
151               || strcmp(argv[0], "-alt") == 0
152               || strcmp(argv[0], "-alts") == 0)
153             alt = 1;
154         else if (strcmp(argv[0], "-lfs") == 0)
155             lfs = 1;
156         else if (out == 0 && strcmp(argv[0], "-o") == 0)
157         {
158             if (argc < 2 || out != 0) return syntax(pgm);
159             if (strcasecmp(argv[1], "ckd") == 0)
160                 out = CKD;
161             else if (strcasecmp(argv[1], "cckd") == 0)
162                 out = CCKD;
163             else if (strcasecmp(argv[1], "fba") == 0)
164                 out = FBA;
165             else if (strcasecmp(argv[1], "cfba") == 0)
166                 out = CFBA;
167             else
168                 return syntax(pgm);
169             argc--; argv++;
170         }
171         else
172             return syntax(pgm);
173     }
174 
175     /* Get the file names:
176        input-file [sf=shadow-file] output-file   */
177     if (argc < 2 || argc > 3) return syntax(pgm);
178     ifile = argv[0];
179     if (argc < 3)
180         ofile = argv[1];
181     else
182     {
183         if (strlen(argv[1]) < 4 || memcmp(argv[1], "sf=", 3))
184             return syntax(pgm);
185         sfile = argv[1];
186         ofile = argv[2];
187     }
188 
189     /* If we don't know what the input file is then find out */
190     if (in == 0)
191     {
192         BYTE buf[8];
193         hostpath(pathname, ifile, sizeof(pathname));
194         fd = hopen(pathname, O_RDONLY|O_BINARY);
195         if (fd < 0)
196         {
197             fprintf (stderr, _("HHCDC001E %s: %s open error: %s\n"),
198                      pgm, ifile, strerror(errno));
199             return -1;
200         }
201         rc = read (fd, buf, 8);
202         if (rc < 8)
203         {
204             fprintf (stderr, _("HHCDC002E %s: %s read error: %s\n"),
205                      pgm, ifile, strerror(errno));
206             return -1;
207         }
208         if (memcmp(buf, "CKD_P370", 8) == 0)
209             in = CKD;
210         else if (memcmp(buf, "CKD_C370", 8) == 0)
211             in = CCKD;
212         else if (memcmp(buf, "FBA_C370", 8) == 0)
213             in = CFBA;
214         else
215             in = FBA;
216         close (fd);
217     }
218 
219     /* If we don't know what the output file type is
220        then derive it from the input file type */
221     if (out == 0)
222     {
223         switch (in) {
224         case CKD:  if (!lfs) out = CCKD;
225                    else out = CKD;
226                    break;
227         case CCKD: if (comp == 255) out = CKD;
228                    else out = CCKD;
229                    break;
230         case FBA:  if (!lfs) out = CFBA;
231                    else out = FBA;
232                    break;
233         case CFBA: if (comp == 255) out = FBA;
234                    else out = CFBA;
235                    break;
236         }
237     }
238 
239     /* Set default compression if out file is to be compressed */
240     if (comp == 255 && (out & COMPMASK))
241 #ifdef CCKD_COMPRESS_ZLIB
242         comp = CCKD_COMPRESS_ZLIB;
243 #else
244         comp = CCKD_COMPRESS_NONE;
245 #endif
246 
247     /* Perform sanity checks on the options */
248     if ((in & CKDMASK) && !(out & CKDMASK)) return syntax(pgm);
249     if ((in & FBAMASK) && !(out & FBAMASK)) return syntax(pgm);
250     if (sfile && !(in & COMPMASK)) return syntax(pgm);
251     if (comp != 255 && !(out & COMPMASK)) return syntax(pgm);
252     if (lfs && (out & COMPMASK)) return syntax(pgm);
253     if (cyls >= 0 && !(in & CKDMASK)) return syntax(pgm);
254     if (blks >= 0 && !(in & FBAMASK)) return syntax(pgm);
255     if (!(in & CKDMASK) && alt) return syntax(pgm);
256 
257     /* Set the type of processing (ckd or fba) */
258     ckddasd = (in & CKDMASK);
259 
260     /* Open the input file */
261     if (ckddasd)
262         icif = open_ckd_image (ifile, sfile, O_RDONLY|O_BINARY, 0);
263     else
264         icif = open_fba_image (ifile, sfile, O_RDONLY|O_BINARY, 0);
265     if (icif == NULL)
266     {
267         fprintf (stderr, _("HHCDC003E %s: %s open failed\n"), pgm, ifile);
268         return -1;
269     }
270     idev = &icif->devblk;
271     if (idev->oslinux) nullfmt = CKDDASD_NULLTRK_FMT2;
272 
273     /* Calculate the number of tracks or blocks to copy */
274     if (ckddasd)
275     {
276         if (cyls < 0) cyls = idev->ckdcyls;
277         else if (cyls == 0) cyls = (idev->hnd->used)(idev);
278         ckd = dasd_lookup (DASD_CKDDEV, NULL, idev->devtype, cyls);
279         if (ckd == NULL)
280         {
281             fprintf (stderr, _("HHCDC004E %s: ckd lookup failed for %4.4X "
282                      "cyls %d\n"),
283                      pgm, idev->devtype, cyls);
284             close_image_file (icif);
285             return -1;
286         }
287      // if (out == CCKD) cyls = ckd->cyls;
288         if (cyls <= ckd->cyls && alt) cyls = ckd->cyls + ckd->altcyls;
289         n = cyls * idev->ckdheads;
290         max = idev->ckdtrks;
291         if (max < n && out == CCKD) n = max;
292     }
293     else
294     {
295         fba_bytes_remaining = idev->fbanumblk * idev->fbablksiz;
296         if (blks < 0) blks = idev->fbanumblk;
297         else if (blks == 0) blks = (idev->hnd->used)(idev);
298         fba = dasd_lookup (DASD_FBADEV, NULL, idev->devtype, blks);
299         if (fba == NULL)
300         {
301             fprintf (stderr, _("HHCDC005E %s: fba lookup failed, blks %d\n"),
302                      pgm, blks);
303             close_image_file (icif);
304             return -1;
305         }
306         n = blks;
307         max = idev->fbanumblk;
308         if (max < n && out == CFBA) n = max;
309         n = (n + FBA_BLKS_PER_GRP - 1) / FBA_BLKS_PER_GRP;
310         max = (max + FBA_BLKS_PER_GRP - 1) / FBA_BLKS_PER_GRP;
311     }
312 
313     /* Create the output file */
314     if (ckddasd)
315         rc = create_ckd(ofile, idev->devtype, idev->ckdheads,
316                         ckd->r1, cyls, "", comp, lfs, 1+r, nullfmt, 0);
317     else
318         rc = create_fba(ofile, idev->devtype, fba->size,
319                         blks, "", comp, lfs, 1+r, 0);
320     if (rc < 0)
321     {
322         fprintf (stderr, _("HHCDC006E %s: %s create failed\n"), pgm, ofile);
323         close_image_file (icif);
324         return -1;
325     }
326 
327     /* Open the output file */
328     if (ckddasd)
329         ocif = open_ckd_image (ofile, NULL, O_RDWR|O_BINARY, 1);
330     else
331         ocif = open_fba_image (ofile, NULL, O_RDWR|O_BINARY, 1);
332     if (ocif == NULL)
333     {
334         fprintf (stderr, _("HHCDC007E %s: %s open failed\n"), pgm, ofile);
335         close_image_file (icif);
336         return -1;
337     }
338     odev = &ocif->devblk;
339 
340     /* Copy the files */
341 #ifdef EXTERNALGUI
342     if (extgui)
343         /* Notify GUI of total #of tracks or blocks being copied... */
344         fprintf (stderr, "TRKS=%d\n", n);
345     else
346 #endif /*EXTERNALGUI*/
347     if (!quiet) printf ("  %3d%% %7d of %d", 0, 0, n);
348     for (i = 0; i < n; i++)
349     {
350         /* Read a track or block */
351         if (ckddasd)
352         {
353             if (i < max)
354                 rc = (idev->hnd->read)(idev, i, &unitstat);
355             else
356             {
357                 memset (idev->buf, 0, idev->ckdtrksz);
358                 rc = nulltrk(idev->buf, i, idev->ckdheads, nullfmt);
359             }
360         }
361         else
362         {
363             if (i < max)
364                 rc = (idev->hnd->read)(idev, i, &unitstat);
365             else
366                 memset (idev->buf, 0, FBA_BLKGRP_SIZE);
367                 rc = 0;
368         }
369         if (rc < 0)
370         {
371             fprintf (stderr, _("HHCDC008E %s: %s read error %s %d "
372                                "stat=%2.2X, null %s substituted\n"),
373                      pgm, ifile, ckddasd ? "track" : "block", i, unitstat,
374                      ckddasd ? "track" : "block");
375             if (ckddasd)
376                 nulltrk(idev->buf, i, idev->ckdheads, nullfmt);
377             else
378                 memset (idev->buf, 0, FBA_BLKGRP_SIZE);
379             if (!quiet)
380             {
381                 printf (_("  %3d%% %7d of %d"), 0, 0, n);
382                 status (i, n);
383             }
384         }
385 
386         /* Write the track or block just read */
387         if (ckddasd)
388         {
389             rc = (odev->hnd->write)(odev, i, 0, idev->buf,
390                       idev->ckdtrksz, &unitstat);
391         }
392         else
393         {
394             if (fba_bytes_remaining >= (size_t)idev->buflen)
395             {
396                 rc = (odev->hnd->write)(odev,  i, 0, idev->buf,
397                           idev->buflen, &unitstat);
398                 fba_bytes_remaining -= (size_t)idev->buflen;
399             }
400             else
401             {
402                 ASSERT(fba_bytes_remaining > 0 && (i+1) >= n);
403                 rc = (odev->hnd->write)(odev,  i, 0, idev->buf,
404                           (int)fba_bytes_remaining, &unitstat);
405                 fba_bytes_remaining = 0;
406             }
407         }
408         if (rc < 0)
409         {
410             fprintf (stderr, _("HHCDC009E %s: %s write error %s %d "
411                                "stat=%2.2X\n"),
412                      pgm, ofile, ckddasd ? "track" : "block", i, unitstat);
413             close_image_file(icif); close_image_file(ocif);
414             return -1;
415         }
416 
417         /* Update the status indicator */
418         if (!quiet) status (i+1, n);
419     }
420 
421     close_image_file(icif); close_image_file(ocif);
422     if (!quiet) printf (_("\r"));
423     printf (_("HHCDC010I %s successfully completed.\n"), pgm);
424     return 0;
425 }
426 
427 /*-------------------------------------------------------------------*/
428 /* Build a null track image                                          */
429 /*-------------------------------------------------------------------*/
nulltrk(BYTE * buf,int trk,int heads,int nullfmt)430 int nulltrk(BYTE *buf, int trk, int heads, int nullfmt)
431 {
432 int             i;                      /* Loop counter              */
433 CKDDASD_TRKHDR *trkhdr;                 /* -> Track header           */
434 CKDDASD_RECHDR *rechdr;                 /* -> Record header          */
435 U32             cyl;                    /* Cylinder number           */
436 U32             head;                   /* Head number               */
437 BYTE            r;                      /* Record number             */
438 BYTE           *pos;                    /* -> Next position in buffer*/
439     static BYTE eighthexFF[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
440 
441     /* cylinder and head calculations */
442     cyl = trk / heads;
443     head = trk % heads;
444 
445     /* Build the track header */
446     trkhdr = (CKDDASD_TRKHDR*)buf;
447     trkhdr->bin = 0;
448     store_hw(&trkhdr->cyl, cyl);
449     store_hw(&trkhdr->head, head);
450     pos = buf + CKDDASD_TRKHDR_SIZE;
451 
452     /* Build record zero */
453     r = 0;
454     rechdr = (CKDDASD_RECHDR*)pos;
455     pos += CKDDASD_RECHDR_SIZE;
456     store_hw(&rechdr->cyl, cyl);
457     store_hw(&rechdr->head, head);
458     rechdr->rec = r;
459     rechdr->klen = 0;
460     store_hw(&rechdr->dlen, 8);
461     pos += 8;
462     r++;
463 
464     /* Specific null track formatting */
465     if (nullfmt == CKDDASD_NULLTRK_FMT0)
466     {
467         rechdr = (CKDDASD_RECHDR*)pos;
468         pos += CKDDASD_RECHDR_SIZE;
469 
470         store_hw(&rechdr->cyl, cyl);
471         store_hw(&rechdr->head, head);
472         rechdr->rec = r;
473         rechdr->klen = 0;
474         store_hw(&rechdr->dlen, 0);
475         r++;
476     }
477     else if (nullfmt == CKDDASD_NULLTRK_FMT2)
478     {
479         for (i = 0; i < 12; i++)
480         {
481             rechdr = (CKDDASD_RECHDR*)pos;
482             pos += CKDDASD_RECHDR_SIZE;
483 
484             store_hw(&rechdr->cyl, cyl);
485             store_hw(&rechdr->head, head);
486             rechdr->rec = r;
487             rechdr->klen = 0;
488             store_hw(&rechdr->dlen, 4096);
489             r++;
490 
491             pos += 4096;
492         }
493     }
494 
495     /* Build the end of track marker */
496     memcpy (pos, eighthexFF, 8);
497     pos += 8;
498 
499     return 0;
500 }
501 
502 /*-------------------------------------------------------------------*/
503 /* Display command syntax                                            */
504 /*-------------------------------------------------------------------*/
syntax(char * pgm)505 int syntax (char *pgm)
506 {
507     char usage[8192];
508 
509     if (strcmp(pgm, "ckd2cckd") == 0)
510         snprintf(usage,8192,_(
511             "usage:  ckd2cckd [-options] ifile ofile\n"
512             "\n"
513             "     copy a ckd dasd file to a compressed ckd dasd file\n"
514             "\n"
515             "     ifile        --   input ckd dasd file\n"
516             "     ofile        --   output compressed ckd dasd file\n"
517             "\n"
518             "   options:\n"
519             "     -v                display program version and quit\n"
520             "     -h                display this help and quit\n"
521             "     -q                quiet mode, don't display status\n"
522             "     -r                replace the output file if it exists\n"
523             "%s"
524             "%s"
525             "     -0                don't compress track images\n"
526             "     -cyls  n          size of output file\n"
527             "     -a                output file will have alt cyls\n"
528             ),
529 #ifdef CCKD_COMPRESS_ZLIB
530             _(
531             "     -z                compress using zlib [default]\n"
532             ),
533 #else
534             "",
535 #endif
536 #ifdef CCKD_COMPRESS_BZIP2
537             _(
538             "     -bz2              compress using bzip2\n"
539             )
540 #else
541             ""
542 #endif
543             );
544     else if (strcmp(pgm, "cckd2ckd") == 0)
545         snprintf(usage,8192,_(
546             "usage:  cckd2ckd [-options] ifile [sf=sfile] ofile\n"
547             "\n"
548             "     copy a compressed ckd file to a ckd file\n"
549             "\n"
550             "     ifile        --   input compressed ckd dasd file\n"
551             "     sfile        --   input compressed ckd shadow file\n"
552             "                       (optional)\n"
553             "     ofile        --   output ckd dasd file\n"
554             "\n"
555             "   options:\n"
556             "     -v                display program version and quit\n"
557             "     -h                display this help and quit\n"
558             "     -q                quiet mode, don't display status\n"
559             "     -r                replace the output file if it exists\n"
560             "%s"
561             "     -cyls  n          size of output file\n"
562             "     -a                output file will have alt cyls\n"
563             ),
564             (sizeof(off_t) > 4) ? _( "     -lfs              create single large output file\n" ) : ( "" )
565             );
566     else if (strcmp(pgm, "fba2cfba") == 0)
567         snprintf(usage,8192,_(
568             "usage:  fba2cfba [-options] ifile ofile\n"
569             "\n"
570             "     copy a fba dasd file to a compressed fba dasd file\n"
571             "\n"
572             "     ifile        --   input fba dasd file\n"
573             "     ofile        --   output compressed fba dasd file\n"
574             "\n"
575             "   options:\n"
576             "     -v                display program version and quit\n"
577             "     -h                display this help and quit\n"
578             "     -q                quiet mode, don't display status\n"
579             "     -r                replace the output file if it exists\n"
580             "%s"
581             "%s"
582             "     -0                don't compress track images\n"
583             "     -blks  n          size of output file\n"
584             ),
585 #ifdef CCKD_COMPRESS_ZLIB
586             _(
587             "     -z                compress using zlib [default]\n"
588             ),
589 #else
590             "",
591 #endif
592 #ifdef CCKD_COMPRESS_BZIP2
593             _(
594             "     -bz2              compress using bzip2\n"
595             )
596 #else
597             ""
598 #endif
599             );
600     else if (strcmp(pgm, "cfba2fba") == 0)
601         snprintf(usage,8192,_(
602             "usage:  cfba2fba [-options] ifile [sf=sfile] ofile\n"
603             "\n"
604             "     copy a compressed fba file to a fba file\n"
605             "\n"
606             "     ifile        --   input compressed fba dasd file\n"
607             "     sfile        --   input compressed fba shadow file\n"
608             "                       (optional)\n"
609             "     ofile        --   output fba dasd file\n"
610             "\n"
611             "   options:\n"
612             "     -v                display program version and quit\n"
613             "     -h                display this help and quit\n"
614             "     -q                quiet mode, don't display status\n"
615             "     -r                replace the output file if it exists\n"
616             "%s"
617             "     -blks  n          size of output file\n"
618             ),
619             (sizeof(off_t) > 4) ? _( "     -lfs              create single large output file\n" ) : ( "" )
620             );
621     else
622         snprintf(usage,8192,_(
623             "usage:  %s [-options] ifile [sf=sfile] ofile\n"
624             "\n"
625             "     copy a dasd file to another dasd file\n"
626             "\n"
627             "     ifile        --   input dasd file\n"
628             "     sfile        --   input shadow file [optional]\n"
629             "     ofile        --   output dasd file\n"
630             "\n"
631             "   options:\n"
632             "     -v                display program version and quit\n"
633             "     -h                display this help and quit\n"
634             "     -q                quiet mode, don't display status\n"
635             "     -r                replace the output file if it exists\n"
636             "%s"
637             "%s"
638             "     -0                don't compress output\n"
639             "     -blks  n          size of output fba file\n"
640             "     -cyls  n          size of output ckd file\n"
641             "     -a                output ckd file will have alt cyls\n"
642             "%s"
643             "                       even if it exceeds 2G in size\n"
644             "     -o     type       output file type (CKD, CCKD, FBA, CFBA)\n"
645             ),
646             pgm,
647 #ifdef CCKD_COMPRESS_ZLIB
648             _(
649             "     -z                compress using zlib [default]\n"
650             ),
651 #else
652             "",
653 #endif
654 #ifdef CCKD_COMPRESS_BZIP2
655             _(
656             "     -bz2              compress output using bzip2\n"
657             )
658 #else
659             ""
660 #endif
661             ,(sizeof(off_t) > 4) ? _( "     -lfs              output ckd file will be a single file\n" ) : ( "" )
662             );
663     printf ("%s", usage);
664     return -1;
665 } /* end function syntax */
666 
667 /*-------------------------------------------------------------------*/
668 /* Display progress status                                           */
669 /*-------------------------------------------------------------------*/
status(int i,int n)670 void status (int i, int n)
671 {
672 static char indic[] = "|/-\\";
673 
674 #ifdef EXTERNALGUI
675     if (extgui)
676     {
677         if (i % 100) return;
678         fprintf (stderr, "TRK=%d\n", i);
679         return;
680     }
681 #endif /*EXTERNALGUI*/
682 //  if (i % 101 != 1) return;
683     printf ("\r%c %3d%% %7d", indic[i%4], (int)((i*100.0)/n), i);
684 } /* end function status */
685