patch by Dirk Mueller to fix crash in case outfile of unclicfs
[opensuse:clicfs.git] / src / unclicfs.c
1
2 /* This file is part of Clic FS
3    Copyright (C) 2009 Stephan Kulow (coolo@suse.de)
4
5    Clicfs is free software; you can redistribute it and/or
6    modify it under the terms of the GNU General Public
7    License as published by the Free Software Foundation, version 2.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA
18 */
19
20 #include "clicfs.h"   
21 #include <stdio.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <assert.h>
26 #include <stdlib.h>
27
28 static unsigned char *inbuf = 0;
29 static unsigned char *outbuf = 0;
30
31 int main(int argc, char *argv[])
32 {
33     if (argc != 2) {
34       return 1;
35     }
36     const char *packfilename = argv[1];
37
38     if (clicfs_read_pack(packfilename))
39       return 1;
40
41     FILE *outfile = fopen(thefile, "w");
42
43     if (!outfile) {
44         perror("Error while opening");
45         return 1;
46     }
47
48     inbuf = malloc(blocksize_large*pagesize + 300);
49     outbuf = malloc(blocksize_large*pagesize);
50
51     size_t delta = num_pages / 100;
52
53     size_t page;
54     off_t cpart;
55     size_t written_pages = 0;
56
57     for (cpart = 0; cpart < parts; ++cpart)
58     {
59         size_t readin = clic_readpart(inbuf, cpart);
60         if (readin == 0) {
61             return 1;
62         }
63         if (!clic_decompress_part(outbuf, inbuf, readin))
64         {
65           /* continue - TODO: make this an option */
66         }
67
68         for (page = 0; page < num_pages; ++page)
69         {
70             off_t mapped_block = clic_map_block(page);
71             assert(mapped_block < (off_t)num_pages);
72
73             off_t part, off;
74             clic_find_block( mapped_block, &part, &off);
75             assert(part < parts);
76
77             if (part != cpart) continue;
78
79             if (++written_pages % delta == 0)
80             {
81                 fprintf(stderr, "read %d%%\n", (int)(written_pages * 100 / num_pages));
82             }
83             if (fseeko(outfile, page * pagesize, SEEK_SET)) {
84                 perror("seek");
85                 return 1;
86             }
87
88             if (fwrite(outbuf + pagesize * off, 1, pagesize, outfile) != pagesize) {
89                 perror("Error while writing the file");
90                 return 1;
91             }
92         }
93     }
94
95     if (fclose(outfile)) {
96         perror("Error while closing the file");
97         return 1;
98     }
99
100     return 0;
101 }