unsparse.c (1606B)
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 #include <stdio.h> 17 #include <string.h> 18 #include <errno.h> 19 #include <unistd.h> 20 #include <fcntl.h> 21 22 #include "util.h" 23 24 static u8 buffer[1024*1024]; 25 26 int main(int argc, char **argv) { 27 struct chunk c; 28 int fin = 0; 29 int fout = 0; 30 31 if (argc != 3) { 32 fprintf(stderr, "usage: unsparse <infile> <outfile>\n"); 33 return -1; 34 } 35 36 if (!strcmp(argv[1], "-")) { 37 fin = 0; 38 } else 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 ((fout = open(argv[2], O_WRONLY | O_CREAT, 0600)) < 0) { 44 fprintf(stderr, "error: cannot open '%s' for writing\n", argv[2]); 45 return -1; 46 } 47 48 for (;;) { 49 if (readx(fin, &c, sizeof(c))) 50 break; 51 if ((c.start == 0) && (c.length == 0)) { 52 if (close(fout)) 53 break; 54 return 0; 55 } 56 if (lseek(fout, c.start, SEEK_SET) != c.start) 57 break; 58 if (copyx(fin, fout, c.length, buffer, sizeof(buffer))) 59 break; 60 } 61 62 fprintf(stderr, "error: %s\n", strerror(errno)); 63 return -1; 64 } 65