15a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner/* 25a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * Copyright (C) 2010 The Android Open Source Project 35a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * 45a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * Licensed under the Apache License, Version 2.0 (the "License"); 55a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * you may not use this file except in compliance with the License. 65a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * You may obtain a copy of the License at 75a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * 85a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * http://www.apache.org/licenses/LICENSE-2.0 95a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * 105a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * Unless required by applicable law or agreed to in writing, software 115a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * distributed under the License is distributed on an "AS IS" BASIS, 125a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * See the License for the specific language governing permissions and 145a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner * limitations under the License. 155a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner */ 165a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 175a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <fcntl.h> 185a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <libgen.h> 195a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <stdio.h> 205a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <unistd.h> 215a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 225a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#if defined(__linux__) 235a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <linux/fs.h> 245a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#elif defined(__APPLE__) && defined(__MACH__) 255a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <sys/disk.h> 265a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 275a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 285a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifdef ANDROID 295a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <private/android_filesystem_config.h> 305a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 315a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 325a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifndef USE_MINGW 335a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <selinux/selinux.h> 345a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <selinux/label.h> 355a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include <selinux/android.h> 365a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#else 375a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnerstruct selabel_handle; 385a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 395a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 405a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include "make_ext4fs.h" 415a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#include "ext4_utils.h" 425a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 435a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifndef USE_MINGW /* O_BINARY is windows-specific flag */ 445a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#define O_BINARY 0 455a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 465a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 475a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnerextern struct fs_info info; 485a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 495a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 505a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnerstatic void usage(char *path) 515a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner{ 525a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "%s [ -l <len> ] [ -j <journal size> ] [ -b <block_size> ]\n", basename(path)); 535a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, " [ -g <blocks per group> ] [ -i <inodes> ] [ -I <inode size> ]\n"); 545a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, " [ -L <label> ] [ -f ] [ -a <android mountpoint> ]\n"); 555a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, " [ -S file_contexts ]\n"); 565a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, " [ -z | -s ] [ -w ] [ -c ] [ -J ] [ -v ]\n"); 575a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, " <filename> [<directory>]\n"); 585a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner} 595a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 605a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turnerint main(int argc, char **argv) 615a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner{ 625a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int opt; 635a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner const char *filename = NULL; 645a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner const char *directory = NULL; 655a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner char *mountpoint = NULL; 665a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fs_config_func_t fs_config_func = NULL; 675a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int gzip = 0; 685a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int sparse = 0; 695a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int crc = 0; 705a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int wipe = 0; 715a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int fd; 725a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int exitcode; 735a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner int verbose = 0; 745a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner struct selabel_handle *sehnd = NULL; 755a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifndef USE_MINGW 765a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "" } }; 775a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 785a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 795a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner while ((opt = getopt(argc, argv, "l:j:b:g:i:I:L:a:S:fwzJsctv")) != -1) { 805a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner switch (opt) { 815a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'l': 825a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.len = parse_num(optarg); 835a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 845a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'j': 855a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.journal_blocks = parse_num(optarg); 865a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 875a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'b': 885a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.block_size = parse_num(optarg); 895a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 905a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'g': 915a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.blocks_per_group = parse_num(optarg); 925a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 935a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'i': 945a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.inodes = parse_num(optarg); 955a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 965a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'I': 975a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.inode_size = parse_num(optarg); 985a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 995a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'L': 1005a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.label = optarg; 1015a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1025a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'f': 1035a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner force = 1; 1045a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1055a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'a': 1065a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifdef ANDROID 1075a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fs_config_func = fs_config; 1085a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner mountpoint = optarg; 1095a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#else 1105a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "can't set android permissions - built without android support\n"); 1115a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner usage(argv[0]); 1125a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1135a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 1145a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1155a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'w': 1165a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner wipe = 1; 1175a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1185a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'z': 1195a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner gzip = 1; 1205a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1215a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'J': 1225a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner info.no_journal = 1; 1235a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1245a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'c': 1255a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner crc = 1; 1265a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1275a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 's': 1285a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner sparse = 1; 1295a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1305a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 't': 1315a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "Warning: -t (initialize inode tables) is deprecated\n"); 1325a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1335a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'S': 1345a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#ifndef USE_MINGW 1355a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner seopts[0].value = optarg; 1365a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner sehnd = selabel_open(SELABEL_CTX_FILE, seopts, 1); 1375a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (!sehnd) { 1385a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner perror(optarg); 1395a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1405a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1415a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 1425a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1435a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner case 'v': 1445a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner verbose = 1; 1455a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner break; 1465a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner default: /* '?' */ 1475a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner usage(argv[0]); 1485a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1495a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1505a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1515a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1525a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#if !defined(HOST) 1535a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner // Use only if -S option not requested 1545a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (!sehnd && mountpoint) { 1555a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner sehnd = selinux_android_file_context_handle(); 1565a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1575a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (!sehnd) { 1585a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner perror(optarg); 1595a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1605a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1615a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1625a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner#endif 1635a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1645a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (wipe && sparse) { 1655a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "Cannot specifiy both wipe and sparse\n"); 1665a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner usage(argv[0]); 1675a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1685a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1695a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1705a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (wipe && gzip) { 1715a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "Cannot specifiy both wipe and gzip\n"); 1725a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner usage(argv[0]); 1735a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1745a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1755a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1765a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (optind >= argc) { 1775a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "Expected filename after options\n"); 1785a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner usage(argv[0]); 1795a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1805a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1815a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1825a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner filename = argv[optind++]; 1835a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1845a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (optind < argc) 1855a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner directory = argv[optind++]; 1865a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1875a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (optind < argc) { 1885a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fprintf(stderr, "Unexpected argument: %s\n", argv[optind]); 1895a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner usage(argv[0]); 1905a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exit(EXIT_FAILURE); 1915a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1925a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 1935a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (strcmp(filename, "-")) { 1945a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); 1955a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (fd < 0) { 1965a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner perror("open"); 1975a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner return EXIT_FAILURE; 1985a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 1995a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } else { 2005a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner fd = STDOUT_FILENO; 2015a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner } 2025a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner 2035a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner exitcode = make_ext4fs_internal(fd, directory, mountpoint, fs_config_func, gzip, 2045a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner sparse, crc, wipe, sehnd, verbose); 2055a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner close(fd); 2065a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner if (exitcode && strcmp(filename, "-")) 2075a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner unlink(filename); 2085a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner return exitcode; 2095a60dc51ef5c2b97db192244e79b12ad03ee885eDavid 'Digit' Turner} 210