/[gxemul]/upstream/0.3.6.1/experiments/cp_removeblocks.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/0.3.6.1/experiments/cp_removeblocks.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 17 - (hide annotations)
Mon Oct 8 16:19:05 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 4202 byte(s)
0.3.6.1
1 dpavlin 2 /*
2     * Copyright (C) 2004 Anders Gavare. All rights reserved.
3     *
4     * Redistribution and use in source and binary forms, with or without
5     * modification, are permitted provided that the following conditions are met:
6     *
7     * 1. Redistributions of source code must retain the above copyright
8     * notice, this list of conditions and the following disclaimer.
9     * 2. Redistributions in binary form must reproduce the above copyright
10     * notice, this list of conditions and the following disclaimer in the
11     * documentation and/or other materials provided with the distribution.
12     * 3. The name of the author may not be used to endorse or promote products
13     * derived from this software without specific prior written permission.
14     *
15     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18     * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25     * SUCH DAMAGE.
26     *
27     *
28     * $Id: cp_removeblocks.c,v 1.11 2005/01/09 01:55:27 debug Exp $
29     *
30     * This program copies a file, but only those blocks that are not zero-
31     * filled. Typical usage would be if you have a harddisk image stored
32     * as a file, which has all its zeroed blocks explicitly saved on disk,
33     * and would like to save space.
34     *
35     * Example: You download a file called diskimage.gz from somewhere,
36     * run gunzip on it, and the resulting file diskimage is
37     * 1 GB large. ls -l reports the file size as 1 GB, and
38     * so does 'du -k diskimage'. If a lot of the space used
39     * by diskimage is actually zeroes, those parts do not need
40     * to actually be saved. By running this program on diskimage:
41     *
42     * ./cp_removeblocks diskimage diskimage_compact
43     *
44     * you will get a file with the same functionality, but possibly
45     * using less disk space. ('ls -l diskimage_compact' should
46     * return the same size as for diskimage, but 'du -k' will
47     * print only how many kb the file takes up on your disk.)
48     *
49     * You don't even need to gunzip the file to be 1 GB first,
50     * you can pipe it through cp_removeblocks directly.
51     *
52     * gunzip -c file.img.gz | ./cp_removeblocks - file.img
53     */
54    
55     #include <stdio.h>
56     #include <stdlib.h>
57     #include <string.h>
58     #include <sys/types.h>
59    
60     #define BSIZE 512
61    
62    
63     int main(int argc, char *argv[])
64     {
65     FILE *f1, *f2;
66     unsigned char buf[BSIZE];
67     off_t len;
68     off_t in_pos = 0;
69     int i, res, wrote_last = 0;
70    
71     if (argc != 3) {
72     fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
73     fprintf(stderr, "if infile is \"-\", then stdin is used.\n");
74     fprintf(stderr, "if outfile is \"-\", then stdout is used.\n");
75     exit(1);
76     }
77    
78     if (strcmp(argv[1], "-") == 0)
79     f1 = stdin;
80     else
81     f1 = fopen(argv[1], "r");
82    
83     if (f1 == NULL) {
84     perror(argv[1]);
85     exit(1);
86     }
87    
88     if (strcmp(argv[2], "-") == 0)
89     f2 = stdout;
90     else
91     f2 = fopen(argv[2], "w");
92    
93     if (f2 == NULL) {
94     perror(argv[2]);
95     exit(1);
96     }
97    
98     while (!feof(f1)) {
99     len = fread(buf, 1, BSIZE, f1);
100    
101     if (len > 0) {
102     /* Check for data in buf: */
103     for (i=0; i<len; i++)
104     if (buf[i])
105     break;
106    
107     if (i < len) {
108     fseeko(f2, in_pos, SEEK_SET);
109     fwrite(buf, 1, len, f2);
110     wrote_last = 1;
111     } else
112     wrote_last = 0;
113    
114     in_pos += len;
115     }
116     }
117    
118     /*
119     * Copy the last byte explicitly, if necessary.
120     * (This causes f2 to get the correct file size.)
121     */
122     if (!wrote_last && in_pos > 0) {
123     res = fseeko(f2, in_pos - 1, SEEK_SET);
124     if (res != 0)
125     perror("fseeko(f2)");
126    
127     buf[0] = '\0';
128     fwrite(&buf[0], 1, 1, f2);
129     }
130    
131     fclose(f1);
132     fclose(f2);
133    
134     return 0;
135     }
136    

  ViewVC Help
Powered by ViewVC 1.1.26