[9] | 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 | */
|
---|