sparse

sparse file tool
git clone http://frotz.net/git/sparse.git
Log | Files | Refs | README

mksparse.c (1851B)


      1 /* Copyright 2013 Brian Swetland <swetland@frotz.net>
      2  *
      3  * Licensed under the Apache License, Version 2.0 (the "License");
      4  * you may not use this file except in compliance with the License.
      5  * You may obtain a copy of the License at
      6  *
      7  *     http://www.apache.org/licenses/LICENSE-2.0
      8  *
      9  * Unless required by applicable law or agreed to in writing, software
     10  * distributed under the License is distributed on an "AS IS" BASIS,
     11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12  * See the License for the specific language governing permissions and
     13  * limitations under the License.
     14  */
     15 
     16 #define _GNU_SOURCE /* for SEEK_HOLE */
     17 
     18 #include <stdio.h>
     19 #include <string.h>
     20 #include <errno.h>
     21 #include <unistd.h>
     22 #include <fcntl.h>
     23 
     24 #include "util.h"
     25 
     26 static u8 buffer[1024*1024];
     27 
     28 int main(int argc, char **argv) {
     29 	struct chunk c;
     30 	off_t a, b = 0;
     31 	int fin, fout;
     32 
     33 	if (argc != 3) {
     34 		fprintf(stderr, "usage: mksparse <infile> <outfile>");
     35 		return -1;
     36 	}
     37 
     38 	if ((fin = open(argv[1], O_RDONLY)) < 0) {
     39 		fprintf(stderr, "error: cannot open '%s' for reading\n", argv[1]);
     40 		return -1;
     41 	}
     42 
     43 	if (!strcmp(argv[2], "-")) {
     44 		fout = 1;
     45 	} else if ((fout = open(argv[2], O_WRONLY | O_CREAT, 0600)) < 0) {
     46 		fprintf(stderr, "error: cannot open '%s' for writing\n", argv[2]);
     47 		return -1;
     48 	}
     49 
     50 	while ((a = lseek(fin, b, SEEK_DATA)) >= 0) {
     51 		b = lseek(fin, a, SEEK_HOLE);
     52 		c.start = a;
     53 		c.length = b - a;
     54 		if (lseek(fin, a, SEEK_SET) != a)
     55 			goto fail;
     56 		if (writex(fout, &c, sizeof(c)))
     57 			goto fail;
     58 		if (copyx(fin, fout, c.length, buffer, sizeof(buffer)))
     59 			goto fail;
     60 		/* fprintf(stderr, "%lu bytes at %lu\n", c.length, c.start); */
     61 	}
     62 
     63 	c.start = c.length = 0;
     64 	if (writex(fout, &c, sizeof(c)))
     65 		goto fail;
     66 
     67 	if (close(fout))
     68 		goto fail;
     69 
     70 	return 0;
     71 
     72 fail:
     73 	fprintf(stderr, "error: %s\n", strerror(errno));
     74 	return -1;
     75 }
     76