]>
Commit | Line | Data |
---|---|---|
1815bff5 | 1 | /* |
cf37c299 | 2 | * Copyright (c) 1999-2016 Apple Inc. All rights reserved. |
1815bff5 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
cf37c299 | 5 | * |
2fc1e207 A |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
cf37c299 | 13 | * |
1815bff5 A |
14 | * The Original Code and all software distributed under the License are |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
2fc1e207 A |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
cf37c299 | 21 | * |
1815bff5 A |
22 | * @APPLE_LICENSE_HEADER_END@ |
23 | */ | |
24 | /* | |
cf37c299 A |
25 | * Copyright (c) 1997 Apple Computer, Inc. All Rights Reserved |
26 | * | |
1815bff5 A |
27 | * HISTORY |
28 | * 29-Aug-97 Daniel Wade (danielw) at Apple | |
29 | * Created. | |
30 | * | |
cf37c299 | 31 | */ |
1815bff5 A |
32 | |
33 | #include <sys/types.h> | |
34 | #include <sys/stat.h> | |
35 | #include <fcntl.h> | |
36 | #include <errno.h> | |
37 | #include <stdio.h> | |
38 | #include <stdlib.h> | |
39 | #include <string.h> | |
40 | #include <unistd.h> | |
41 | #include <ctype.h> | |
34d340d7 | 42 | #include <err.h> |
1815bff5 | 43 | |
cf37c299 | 44 | #define BF_SZ 512 /* Size of write chunks */ |
1815bff5 A |
45 | |
46 | extern void usage(char *, char *); | |
47 | extern void create_file(char *, quad_t, int, int); | |
48 | extern void err_rm(char *, char *); | |
49 | ||
50 | int | |
cf37c299 | 51 | main(int argc, char **argv) |
1815bff5 A |
52 | { |
53 | char *b_num, *prog_name; | |
54 | char *options = "nv"; | |
55 | char c; | |
ef8ad44b A |
56 | off_t multiplier = 1; |
57 | off_t file_size; | |
cf37c299 | 58 | size_t len; |
1815bff5 A |
59 | int empty = 0; |
60 | int verbose = 0; | |
ef8ad44b | 61 | char* endptr = NULL; |
1815bff5 A |
62 | |
63 | prog_name = argv[0]; /* Get program name */ | |
cf37c299 | 64 | if (1 == argc) |
1815bff5 A |
65 | usage(prog_name, options); |
66 | ||
67 | /* Get options */ | |
68 | opterr=1; | |
cf37c299 A |
69 | |
70 | while ((c=getopt(argc, argv, options)) != EOF) | |
71 | switch (c) { | |
72 | case 'v': /* Turn on verbose setting */ | |
1815bff5 A |
73 | verbose = 1; |
74 | break; | |
75 | case 'n': /* Create an empty file */ | |
76 | empty = 1; | |
77 | break; | |
78 | default: | |
79 | usage(prog_name, options); | |
80 | break; | |
81 | } | |
82 | ||
83 | /* Stop getting options | |
84 | */ | |
85 | argv += optind; | |
86 | if (*argv == NULL) /* Is there a size given? */ | |
87 | usage(prog_name, options); | |
cf37c299 | 88 | |
1815bff5 A |
89 | b_num = *argv++; /* Size of file and byte multiplier */ |
90 | len = strlen(b_num) - 1; | |
91 | ||
92 | if (!isdigit(b_num[len])) { | |
93 | switch(b_num[len]) { /* Figure out multiplier */ | |
94 | case 'B': | |
95 | case 'b': | |
96 | multiplier = 512; | |
97 | break; | |
98 | case 'K': | |
99 | case 'k': | |
100 | multiplier = 1024; | |
cf37c299 | 101 | break; |
1815bff5 A |
102 | case 'M': |
103 | case 'm': | |
104 | multiplier = 1024 * 1024; | |
105 | break; | |
106 | case 'G': | |
107 | case 'g': | |
108 | multiplier = 1024 * 1024 * 1024; | |
109 | break; | |
110 | default: | |
cf37c299 | 111 | usage(prog_name, options); |
1815bff5 A |
112 | } |
113 | } | |
cf37c299 | 114 | |
1815bff5 | 115 | if (*argv == NULL) /* Was a file name given? */ |
cf37c299 | 116 | usage(prog_name, options); |
1815bff5 | 117 | |
ef8ad44b A |
118 | if ((file_size = strtoll(b_num, &endptr, 10)) == 0 && |
119 | (*endptr != 0 && endptr != &b_num[len])) { | |
1815bff5 | 120 | err(1, "Bad file size!"); |
ef8ad44b | 121 | } |
1815bff5 A |
122 | |
123 | while ( *argv != NULL ) { /* Create file for each file_name */ | |
124 | create_file(*argv, file_size*multiplier, empty, verbose); | |
125 | argv++; | |
126 | } | |
127 | ||
128 | return (0); | |
1815bff5 A |
129 | } |
130 | ||
131 | ||
132 | /* Create a file and make it empty (lseek) or zero'd */ | |
133 | ||
cf37c299 A |
134 | void |
135 | create_file(char *file_name, quad_t size, int empty, int verbose) | |
1815bff5 A |
136 | { |
137 | char buff[BF_SZ]; | |
cf37c299 A |
138 | int fd; |
139 | ssize_t bytes_written = BF_SZ; | |
1815bff5 | 140 | quad_t i; |
34d340d7 | 141 | mode_t mode = S_IRUSR | S_IWUSR; |
1815bff5 | 142 | |
34d340d7 A |
143 | /* If superuser, then set sticky bit */ |
144 | if (!geteuid()) mode |= S_ISVTX; | |
145 | ||
146 | if ((fd = open(file_name, O_RDWR | O_CREAT | O_TRUNC, mode)) == -1) | |
1815bff5 A |
147 | err(1, NULL); |
148 | ||
149 | ||
150 | if (empty) { /* Create an empty file */ | |
151 | lseek(fd, (off_t)size-1, SEEK_SET); | |
152 | if ( 1 != write(fd, "\0", 1)) | |
153 | err_rm(file_name, "Write Error"); | |
154 | } | |
155 | else { | |
156 | bzero(buff, BF_SZ); | |
157 | ||
158 | /* | |
159 | * First loop: write BF_SZ chunks until you have | |
160 | * less then BF_SZ bytes to write. | |
161 | * Second loop: write the remaining bytes. | |
162 | * ERRORS in the write process will cause the | |
163 | * file to be removed before the error is | |
164 | * reported. | |
165 | */ | |
166 | for (i = size; i > BF_SZ; i -= bytes_written) { | |
167 | bytes_written = write (fd, buff, BF_SZ); | |
168 | if ( bytes_written == -1 ) | |
169 | err_rm (file_name, "Write Error"); | |
170 | } | |
171 | for (; i > 0; i -= bytes_written) { | |
cf37c299 | 172 | bytes_written = write (fd, buff, (size_t)i); |
1815bff5 A |
173 | if ( bytes_written == -1 ) |
174 | err_rm (file_name, "Write Error"); | |
175 | } | |
176 | } | |
177 | ||
34d340d7 A |
178 | if (fchmod(fd, mode)) /* Change permissions */ |
179 | err_rm(file_name, NULL); | |
1815bff5 | 180 | |
34d340d7 A |
181 | if ((close(fd)) == -1) |
182 | err_rm(file_name, NULL); | |
1815bff5 A |
183 | |
184 | if (verbose) | |
185 | (void)fprintf(stderr, "%s %qd bytes\n", file_name, size); | |
1815bff5 A |
186 | } |
187 | ||
188 | /* On error remove the file */ | |
189 | ||
190 | void | |
cf37c299 | 191 | err_rm(char *filename, char *msg) |
1815bff5 A |
192 | { |
193 | unlink(filename); | |
cf37c299 | 194 | err(1, "(%s removed) %s", filename, msg); |
1815bff5 A |
195 | } |
196 | ||
1815bff5 | 197 | /* Print usage string */ |
cf37c299 A |
198 | void |
199 | usage(char *prog_name, char *options) | |
1815bff5 | 200 | { |
cf37c299 | 201 | (void)fprintf(stderr, |
1815bff5 A |
202 | "usage: %s [-%s] size[b|k|m|g] filename ...\n", prog_name, options); |
203 | exit(1); | |
1815bff5 | 204 | } |