1 | /* mkfile 1.0 - create a file under DOS for use as a Minix "disk".
|
---|
2 | * Author: Kees J. Bot
|
---|
3 | * 9 May 1998
|
---|
4 | */
|
---|
5 | #define nil 0
|
---|
6 | #include <sys/types.h>
|
---|
7 | #include <string.h>
|
---|
8 | #include <limits.h>
|
---|
9 |
|
---|
10 | /* Stuff normally found in <unistd.h>, <errno.h>, etc. */
|
---|
11 | extern int errno;
|
---|
12 | int creat(const char *file, int mode);
|
---|
13 | int open(const char *file, int oflag);
|
---|
14 | off_t lseek(int fd, off_t offset, int whence);
|
---|
15 | ssize_t write(int fd, const char *buf, size_t len);
|
---|
16 | void exit(int status);
|
---|
17 | int printf(const char *fmt, ...);
|
---|
18 |
|
---|
19 | #define O_WRONLY 1
|
---|
20 | #define SEEK_SET 0
|
---|
21 | #define SEEK_END 2
|
---|
22 |
|
---|
23 | /* Kernel printf requires a putk() function. */
|
---|
24 | int putk(int c)
|
---|
25 | {
|
---|
26 | char ch = c;
|
---|
27 |
|
---|
28 | if (c == 0) return;
|
---|
29 | if (c == '\n') putk('\r');
|
---|
30 | (void) write(2, &ch, 1);
|
---|
31 | }
|
---|
32 |
|
---|
33 | static void usage(void)
|
---|
34 | {
|
---|
35 | printf("Usage: mkfile <size>[gmk] <file>\n"
|
---|
36 | "(Example sizes, all 50 meg: 52428800, 51200k, 50m)\n");
|
---|
37 | exit(1);
|
---|
38 | }
|
---|
39 |
|
---|
40 | char *strerror(int err)
|
---|
41 | /* Translate some DOS error numbers to text. */
|
---|
42 | {
|
---|
43 | static struct errlist {
|
---|
44 | int err;
|
---|
45 | char *what;
|
---|
46 | } errlist[] = {
|
---|
47 | { 0, "No error" },
|
---|
48 | { 1, "Function number invalid" },
|
---|
49 | { 2, "File not found" },
|
---|
50 | { 3, "Path not found" },
|
---|
51 | { 4, "Too many open files" },
|
---|
52 | { 5, "Access denied" },
|
---|
53 | { 6, "Invalid handle" },
|
---|
54 | { 12, "Access code invalid" },
|
---|
55 | { 39, "Insufficient disk space" },
|
---|
56 | };
|
---|
57 | struct errlist *ep;
|
---|
58 | static char unknown[]= "Error 65535";
|
---|
59 | unsigned e;
|
---|
60 | char *p;
|
---|
61 |
|
---|
62 | for (ep= errlist; ep < errlist + sizeof(errlist)/sizeof(errlist[0]);
|
---|
63 | ep++) {
|
---|
64 | if (ep->err == err) return ep->what;
|
---|
65 | }
|
---|
66 | p= unknown + sizeof(unknown) - 1;
|
---|
67 | e= err;
|
---|
68 | do *--p= '0' + (e % 10); while ((e /= 10) > 0);
|
---|
69 | strcpy(unknown + 6, p);
|
---|
70 | return unknown;
|
---|
71 | }
|
---|
72 |
|
---|
73 | int main(int argc, char **argv)
|
---|
74 | {
|
---|
75 | int i;
|
---|
76 | static char buf[512];
|
---|
77 | unsigned long size, mul;
|
---|
78 | off_t offset;
|
---|
79 | char *cp;
|
---|
80 | int fd;
|
---|
81 | char *file;
|
---|
82 |
|
---|
83 | if (argc != 3) usage();
|
---|
84 |
|
---|
85 | cp= argv[1];
|
---|
86 | size= 0;
|
---|
87 | while ((unsigned) (*cp - '0') < 10) {
|
---|
88 | unsigned d= *cp++ - '0';
|
---|
89 | if (size <= (ULONG_MAX-9) / 10) {
|
---|
90 | size= size * 10 + d;
|
---|
91 | } else {
|
---|
92 | size= ULONG_MAX;
|
---|
93 | }
|
---|
94 | }
|
---|
95 | if (cp == argv[1]) usage();
|
---|
96 | while (*cp != 0) {
|
---|
97 | mul = 1;
|
---|
98 | switch (*cp++) {
|
---|
99 | case 'G':
|
---|
100 | case 'g': mul *= 1024;
|
---|
101 | case 'M':
|
---|
102 | case 'm': mul *= 1024;
|
---|
103 | case 'K':
|
---|
104 | case 'k': mul *= 1024;
|
---|
105 | case 'B':
|
---|
106 | case 'b': break;
|
---|
107 | default: usage();
|
---|
108 | }
|
---|
109 | if (size <= ULONG_MAX / mul) {
|
---|
110 | size *= mul;
|
---|
111 | } else {
|
---|
112 | size= ULONG_MAX;
|
---|
113 | }
|
---|
114 | }
|
---|
115 |
|
---|
116 | if (size > 1024L*1024*1024) {
|
---|
117 | printf("mkfile: A file size over 1G is a bit too much\n");
|
---|
118 | exit(1);
|
---|
119 | }
|
---|
120 |
|
---|
121 | /* Open existing file, or create a new file. */
|
---|
122 | file= argv[2];
|
---|
123 | if ((fd= open(file, O_WRONLY)) < 0) {
|
---|
124 | if (errno == 2) {
|
---|
125 | fd= creat(file, 0666);
|
---|
126 | }
|
---|
127 | }
|
---|
128 | if (fd < 0) {
|
---|
129 | printf("mkfile: Can't open %s: %s\n", file, strerror(errno));
|
---|
130 | exit(1);
|
---|
131 | }
|
---|
132 |
|
---|
133 | /* How big is the file now? */
|
---|
134 | if ((offset= lseek(fd, 0, SEEK_END)) == -1) {
|
---|
135 | printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
|
---|
136 | exit(1);
|
---|
137 | }
|
---|
138 |
|
---|
139 | if (offset == 0 && size == 0) exit(0); /* Huh? */
|
---|
140 |
|
---|
141 | /* Write the first bit if the file is zero length. This is necessary
|
---|
142 | * to circumvent a DOS bug by extending a new file by lseek. We also
|
---|
143 | * want to make sure there are zeros in the first sector.
|
---|
144 | */
|
---|
145 | if (offset == 0) {
|
---|
146 | if (write(fd, buf, sizeof(buf)) == -1) {
|
---|
147 | printf("mkfile: Can't write to %s: %s\n",
|
---|
148 | file, strerror(errno));
|
---|
149 | exit(1);
|
---|
150 | }
|
---|
151 | }
|
---|
152 |
|
---|
153 | /* Seek to the required size and write 0 bytes to extend/truncate the
|
---|
154 | * file to that size.
|
---|
155 | */
|
---|
156 | if (lseek(fd, size, SEEK_SET) == -1) {
|
---|
157 | printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
|
---|
158 | exit(1);
|
---|
159 | }
|
---|
160 | if (write(fd, buf, 0) == -1) {
|
---|
161 | printf("mkfile: Can't write to %s: %s\n",
|
---|
162 | file, strerror(errno));
|
---|
163 | exit(1);
|
---|
164 | }
|
---|
165 |
|
---|
166 | /* Did the file become the required size? */
|
---|
167 | if ((offset= lseek(fd, 0, SEEK_END)) == -1) {
|
---|
168 | printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
|
---|
169 | exit(1);
|
---|
170 | }
|
---|
171 | if (offset != size) {
|
---|
172 | printf("mkfile: Failed to extend %s. Disk full?\n", file);
|
---|
173 | exit(1);
|
---|
174 | }
|
---|
175 | return 0;
|
---|
176 | }
|
---|
177 |
|
---|
178 | /*
|
---|
179 | * $PchId: mkfile.c,v 1.4 2000/08/13 22:06:40 philip Exp $
|
---|
180 | */
|
---|