root/trunk/client/revimage/decompress.c

Revision 12, 7.0 kB (checked in by ludo, 4 years ago)

initial ci: revimage= filesystem compression programs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
Line 
1 /*
2  *  $Id$
3  */
4 /*
5  *  Linbox Rescue Server
6  *  Copyright (C) 2002-2005 Linbox FAS, Free & Alter Soft
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #define _GNU_SOURCE
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 #include <fcntl.h>
31
32 #include "zlib.h"
33
34 #define INSIZE 2048
35
36 unsigned char BUFFER[24064];
37 unsigned char Bitmap[24064 - 2048];
38 unsigned char IN[INSIZE];
39 unsigned char zero[512];
40
41 typedef struct params_
42 {
43   int bitindex;
44   int fo;
45   unsigned long long offset;
46 }
47 PARAMS;
48
49 int
50 eof (int fd)
51 {
52   __off64_t pos, end;
53   pos = lseek64 (fd, 0, SEEK_CUR);
54   if (pos < 0)
55     {
56       fprintf (stderr, "Error LSEEK : eof,pos\n");
57     }
58   end = lseek64 (fd, 0, SEEK_END);
59   if (end < 0)
60     {
61       fprintf (stderr, "Error LSEEK : eof,end\n");
62     }
63   if (lseek64 (fd, pos, SEEK_SET) < 0)
64     {
65       fprintf (stderr, "Error LSEEK, reseek\n");
66     }
67   if (end == pos)
68     return 1;
69   return 0;
70 }
71
72 void
73 fill (int fd, int bytes, int dir)
74 {
75   int err = 0;
76   int lg = bytes;
77
78   if (eof (fd))
79     {
80       while (bytes > 512)
81         {
82           if (write (fd, zero, 512) != 512)
83             {
84               if (!err)
85                 {
86                   err = 1;
87                   fprintf (stderr, "Error FILL : write 512!=512\n");
88                 }
89             }
90           bytes -= 512;
91         }
92       if (write (fd, zero, bytes) != bytes)
93         {
94           fprintf (stderr, "Error FILL : %d bytes write...\n", bytes);
95           err = 1;
96         }
97     }
98   else
99     {
100       if (lseek64 (fd, bytes, dir) < 0)
101         {
102           fprintf (stderr, "Error FILL : skip error");
103           err = 1;
104         }
105     }
106   if (err)
107     fprintf (stderr, "Error when filling %d bytes\n", lg);
108 }
109
110 void
111 flushToDisk (unsigned char *buff, unsigned char *bit, PARAMS * cp, int lg)
112 {
113   unsigned char *ptr = buff;
114   unsigned char mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
115   int indx = cp->bitindex;
116
117 // printf("Enter : bitindex -> %d\n",indx);
118   while (lg > 0)
119     {
120       while (!(bit[indx >> 3] & mask[indx & 7]))
121         {
122           indx++;
123           cp->offset += 512;
124           if (cp->fo)
125             fill (cp->fo, 512, SEEK_CUR);
126         }
127 //      printf("Write @offset : %lld\t",cp->offset);
128 //      {int i; for(i=0;i<15;i++) printf("%02x ",ptr[i]); printf("\n");}
129       if (cp->fo)
130         {
131           if (write (cp->fo, ptr, 512) != 512)
132             fprintf (stderr, "Flush Error : write 512!=512\n");
133         }
134       cp->offset += 512;
135       ptr += 512;
136       indx++;
137       lg -= 512;
138     }
139 // printf("Exit  : bitindex -> %d\n",indx);
140   cp->bitindex = indx;
141 }
142
143 int
144 main (int argc, char *argv[])
145 {
146   z_stream zptr;
147   int state;
148   int ret, firstpass, bitmaplg;
149   FILE *fi;
150   PARAMS currentparams;
151
152 start:
153   state = Z_SYNC_FLUSH;
154   firstpass = 1;
155   bitmaplg = 0;
156
157   zptr.zalloc = NULL;
158   zptr.zfree = NULL;
159
160   fi = fopen (argv[1], "rb");
161   if (fi == NULL)
162     {
163       printf ("Cannot open input file\n");
164       exit (1);
165     }
166   zptr.avail_in = fread (IN, 1, INSIZE, fi);
167
168   memset (zero, 0, 512);
169
170   currentparams.fo = 0;
171   currentparams.offset = 0;
172   currentparams.bitindex = 0;
173   if (argc > 2)
174     {
175       currentparams.fo = open (argv[2], O_RDWR | O_CREAT | O_LARGEFILE);
176       sscanf (argv[3], "%lld", &currentparams.offset);
177       if (currentparams.fo)
178         {
179           unsigned long long i;
180           printf ("Seeking to : %lld\n", currentparams.offset);
181           i = lseek64 (currentparams.fo, currentparams.offset, SEEK_SET);
182           if (i != currentparams.offset)
183             {
184               fprintf (stderr, "Seek error : %lld\n", i);
185             }
186         }
187     }
188
189   zptr.next_in = (char *) IN;
190   zptr.next_out = (char *) BUFFER;      // was dbuf.data;
191   zptr.avail_out = 24064;
192
193   inflateInit (&zptr);
194
195   do
196     {
197 //  if (inflateSyncPoint(&zptr)) printf("#");
198
199       ret = inflate (&zptr, state);
200
201 //  printf("-> %d : %d / %d\n",ret ,zptr.avail_in ,zptr.avail_out );
202
203       if ((ret == Z_OK) && (zptr.avail_out == 0))
204         {
205           if (firstpass)
206             {
207               printf ("Params : *%s*\n", BUFFER);
208               if (strstr (BUFFER, "BLOCKS="))
209                 {
210                   FILE *fo;
211                   int i = 0;
212                   sscanf (strstr (BUFFER, "BLOCKS=") + 7, "%d", &i);
213                   fo = fopen ("/tmp/blocks", "w");
214                   fprintf (fo, "%d\n", i);
215                   fclose (fo);
216                 }
217               if (strstr (BUFFER, "ALLOCTABLELG="))
218                 sscanf (strstr (BUFFER, "ALLOCTABLELG=") + 13, "%d",
219                         &bitmaplg);
220               memcpy (Bitmap, BUFFER + 2048, 24064 - 2048);
221 #if 0
222               {
223                 int i;
224                 for (i = 0; i < 256; i++)
225                   {
226                     if ((i & 15) == 0)
227                       printf ("\n%04x : ", i);
228                     printf ("%02X ", Bitmap[i]);
229                   }
230                 printf ("\n");
231               }
232 #endif
233               currentparams.bitindex = 0;
234               firstpass = 0;
235             }
236           else
237             {
238               flushToDisk (BUFFER, Bitmap, &currentparams, 24064);
239             }
240
241           zptr.next_out = (char *) BUFFER;
242           zptr.avail_out = 24064;
243         }
244
245       if ((ret == Z_OK) && (zptr.avail_in == 0))
246         {
247           zptr.avail_in = fread (IN, 1, INSIZE, fi);
248           zptr.next_in = (char *) IN;
249         }
250     }
251   while (ret == Z_OK);
252
253   if (ret == Z_STREAM_END)
254     {
255       {
256         if (firstpass)
257           {
258             printf ("Params : *%s*\n", BUFFER);
259             if (strstr (BUFFER, "BLOCKS="))
260               {
261                 FILE *fo;
262                 int i = 0;
263                 sscanf (strstr (BUFFER, "BLOCKS=") + 7, "%d", &i);
264                 fo = fopen ("/tmp/blocks", "w");
265                 fprintf (fo, "%d\n", i);
266                 fclose (fo);
267               }
268             if (strstr (BUFFER, "ALLOCTABLELG="))
269               sscanf (strstr (BUFFER, "ALLOCTABLELG=") + 13, "%d", &bitmaplg);
270             memcpy (Bitmap, BUFFER + 2048, 24064 - 2048);
271             zptr.next_out = (char *) BUFFER;
272             zptr.avail_out = 24064;
273           }
274       }
275
276       printf ("Flushing to EOF ... (%d bytes)\n", 24064 - zptr.avail_out);
277       flushToDisk (BUFFER, Bitmap, &currentparams, 24064 - zptr.avail_out);
278       zptr.next_out = (char *) BUFFER;
279       zptr.avail_out = 24064;
280     }
281
282   ret = inflate (&zptr, Z_FINISH);
283   inflateEnd (&zptr);
284
285   printf ("Returned : %d\t", ret);
286   printf ("(AvailIn : %d / ", zptr.avail_in);
287   printf ("AvailOut: %d)\n", zptr.avail_out);
288
289   if (ret < 0)
290     {
291       fprintf (stderr, "ZLIB error, restarting...\n");
292       goto start;
293     }
294
295   printf ("Offset : %lld\n", currentparams.offset);
296   printf ("Bitmap index : %d\n", currentparams.bitindex);
297
298   if (bitmaplg)
299     {
300       if (bitmaplg * 8 > currentparams.bitindex)
301         {
302           printf ("Remaining bitmap : %d\n",
303                   bitmaplg * 8 - currentparams.bitindex);
304           currentparams.offset +=
305             512 * (bitmaplg * 8 - currentparams.bitindex);
306           if (currentparams.fo)
307             {
308               // why fill ?
309               fill(currentparams.fo,512*(bitmaplg*8-currentparams.bitindex),SEEK_CUR);
310             }
311         }
312     }
313
314   if (currentparams.fo)
315     close (currentparams.fo);
316
317   {
318     FILE *fo;
319     fo = fopen ("/tmp/offset", "w");
320     fprintf (fo, "%lld\n", currentparams.offset);
321   }
322   fclose (fi);
323   return 0;
324 }
Note: See TracBrowser for help on using the browser.