1 /* CCKDCOMP.C   (c) Copyright Greg Smith, 2000-2009                  */
2 /*              Compress a Compressed CKD DASD file                  */
3 
4 /*-------------------------------------------------------------------*/
5 /* Remove all free space on a compressed ckd file                    */
6 /*-------------------------------------------------------------------*/
7 
8 #include "hstdinc.h"
9 
10 #include "hercules.h"
11 
12 int syntax ();
13 
14 /*-------------------------------------------------------------------*/
15 /* Main function for stand-alone compress                            */
16 /*-------------------------------------------------------------------*/
17 
main(int argc,char * argv[])18 int main (int argc, char *argv[])
19 {
20 int             i;                      /* Index                     */
21 int             rc;                     /* Return code               */
22 int             level=-1;               /* Level for chkdsk          */
23 int             force=0;                /* 1=Compress if OPENED set  */
24 CCKDDASD_DEVHDR cdevhdr;                /* Compressed CKD device hdr */
25 DEVBLK          devblk;                 /* DEVBLK                    */
26 DEVBLK         *dev=&devblk;            /* -> DEVBLK                 */
27 
28     INITIALIZE_UTILITY("cckdcomp");
29 
30     /* parse the arguments */
31     for (argc--, argv++ ; argc > 0 ; argc--, argv++)
32     {
33         if(**argv != '-') break;
34 
35         switch(argv[0][1])
36         {
37             case '0':
38             case '1':
39             case '2':
40             case '3':  if (argv[0][2] != '\0') return syntax ();
41                        level = (argv[0][1] & 0xf);
42                        break;
43             case 'f':  if (argv[0][2] != '\0') return syntax ();
44                        force = 1;
45                        break;
46             case 'v':  if (argv[0][2] != '\0') return syntax ();
47                        display_version
48                          (stderr, "Hercules cckd compress program ", FALSE);
49                        return 0;
50             default:   return syntax ();
51         }
52     }
53 
54     if (argc < 1) return syntax ();
55 
56     for (i = 0; i < argc; i++)
57     {
58         memset (dev, 0, sizeof(DEVBLK));
59         dev->batch = 1;
60 
61         /* open the file */
62         hostpath(dev->filename, argv[i], sizeof(dev->filename));
63         dev->fd = hopen(dev->filename, O_RDWR|O_BINARY);
64         if (dev->fd < 0)
65         {
66             cckdumsg (dev, 700, "open error: %s\n", strerror(errno));
67             continue;
68         }
69 
70         /* Check CCKD_OPENED bit if -f not specified */
71         if (!force)
72         {
73             if (lseek (dev->fd, CCKD_DEVHDR_POS, SEEK_SET) < 0)
74             {
75                 cckdumsg (dev, 702, "lseek error offset 0x%" I64_FMT "x: %s\n",
76                           (long long)CCKD_DEVHDR_POS, strerror(errno));
77                 close (dev->fd);
78                 continue;
79             }
80             if ((rc = read (dev->fd, &cdevhdr, CCKD_DEVHDR_SIZE)) < CCKD_DEVHDR_SIZE)
81             {
82                 cckdumsg (dev, 703, "read error rc=%d offset 0x%" I64_FMT "x len %d: %s\n",
83                           rc, (long long)CCKD_DEVHDR_POS, CCKD_DEVHDR_SIZE,
84                           rc < 0 ? strerror(errno) : "incomplete");
85                 close (dev->fd);
86                 continue;
87             }
88             if (cdevhdr.options & CCKD_OPENED)
89             {
90                 cckdumsg (dev, 707, "OPENED bit is on, use -f\n");
91                 close (dev->fd);
92                 continue;
93             }
94         } /* if (!force) */
95 
96         /* call chkdsk */
97         if (cckd_chkdsk (dev, level) < 0)
98         {
99             cckdumsg (dev, 708, "chkdsk errors\n");
100             close (dev->fd);
101             continue;
102         }
103 
104         /* call compress */
105         rc = cckd_comp (dev);
106 
107         close (dev->fd);
108 
109     } /* for each arg */
110 
111     return 0;
112 }
113 
114 /*-------------------------------------------------------------------*/
115 /* print syntax                                                      */
116 /*-------------------------------------------------------------------*/
117 
syntax()118 int syntax()
119 {
120     fprintf (stderr, "\ncckdcomp [-v] [-f] [-level] file1 [file2 ... ]\n"
121                 "\n"
122                 "          -v      display version and exit\n"
123                 "\n"
124                 "          -f      force check even if OPENED bit is on\n"
125                 "\n"
126                 "        chkdsk level is a digit 0 - 3:\n"
127                 "          -0  --  minimal checking\n"
128                 "          -1  --  normal  checking\n"
129                 "          -2  --  intermediate checking\n"
130                 "          -3  --  maximal checking\n"
131                 "         default  0\n"
132                 "\n");
133     return -1;
134 }
135