mkfile.c

Go to the documentation of this file.
00001 /*      mkfile 1.0 - create a file under DOS for use as a Minix "disk".
00002  *                                                      Author: Kees J. Bot
00003  *                                                              9 May 1998
00004  */
00005 #define nil 0
00006 #include <sys/types.h>
00007 #include <string.h>
00008 #include <limits.h>
00009 
00010 /* Stuff normally found in <unistd.h>, <errno.h>, etc. */
00011 extern int errno;
00012 int creat(const char *file, int mode);
00013 int open(const char *file, int oflag);
00014 off_t lseek(int fd, off_t offset, int whence);
00015 ssize_t write(int fd, const char *buf, size_t len);
00016 void exit(int status);
00017 int printf(const char *fmt, ...);
00018 
00019 #define O_WRONLY        1
00020 #define SEEK_SET        0
00021 #define SEEK_END        2
00022 
00023 /* Kernel printf requires a putk() function. */
00024 int putk(int c)
00025 {
00026         char ch = c;
00027 
00028         if (c == 0) return;
00029         if (c == '\n') putk('\r');
00030         (void) write(2, &ch, 1);
00031 }
00032 
00033 static void usage(void)
00034 {
00035         printf("Usage: mkfile <size>[gmk] <file>\n"
00036                 "(Example sizes, all 50 meg: 52428800, 51200k, 50m)\n");
00037         exit(1);
00038 }
00039 
00040 char *strerror(int err)
00041 /* Translate some DOS error numbers to text. */
00042 {
00043         static struct errlist {
00044                 int     err;
00045                 char    *what;
00046         } errlist[] = {
00047                 {  0, "No error" },
00048                 {  1, "Function number invalid" },
00049                 {  2, "File not found" },
00050                 {  3, "Path not found" },
00051                 {  4, "Too many open files" },
00052                 {  5, "Access denied" },
00053                 {  6, "Invalid handle" },
00054                 { 12, "Access code invalid" },
00055                 { 39, "Insufficient disk space" },
00056         };
00057         struct errlist *ep;
00058         static char unknown[]= "Error 65535";
00059         unsigned e;
00060         char *p;
00061 
00062         for (ep= errlist; ep < errlist + sizeof(errlist)/sizeof(errlist[0]);
00063                                                                         ep++) {
00064                 if (ep->err == err) return ep->what;
00065         }
00066         p= unknown + sizeof(unknown) - 1;
00067         e= err;
00068         do *--p= '0' + (e % 10); while ((e /= 10) > 0);
00069         strcpy(unknown + 6, p);
00070         return unknown;
00071 }
00072 
00073 int main(int argc, char **argv)
00074 {
00075         int i;
00076         static char buf[512];
00077         unsigned long size, mul;
00078         off_t offset;
00079         char *cp;
00080         int fd;
00081         char *file;
00082 
00083         if (argc != 3) usage();
00084 
00085         cp= argv[1];
00086         size= 0;
00087         while ((unsigned) (*cp - '0') < 10) {
00088                 unsigned d= *cp++ - '0';
00089                 if (size <= (ULONG_MAX-9) / 10) {
00090                         size= size * 10 + d;
00091                 } else {
00092                         size= ULONG_MAX;
00093                 }
00094         }
00095         if (cp == argv[1]) usage();
00096         while (*cp != 0) {
00097                 mul = 1;
00098                 switch (*cp++) {
00099                 case 'G':
00100                 case 'g':       mul *= 1024;
00101                 case 'M':
00102                 case 'm':       mul *= 1024;
00103                 case 'K':
00104                 case 'k':       mul *= 1024;
00105                 case 'B':
00106                 case 'b':       break;
00107                 default:        usage();
00108                 }
00109                 if (size <= ULONG_MAX / mul) {
00110                         size *= mul;
00111                 } else {
00112                         size= ULONG_MAX;
00113                 }
00114         }
00115 
00116         if (size > 1024L*1024*1024) {
00117                 printf("mkfile: A file size over 1G is a bit too much\n");
00118                 exit(1);
00119         }
00120 
00121         /* Open existing file, or create a new file. */
00122         file= argv[2];
00123         if ((fd= open(file, O_WRONLY)) < 0) {
00124                 if (errno == 2) {
00125                         fd= creat(file, 0666);
00126                 }
00127         }
00128         if (fd < 0) {
00129                 printf("mkfile: Can't open %s: %s\n", file, strerror(errno));
00130                 exit(1);
00131         }
00132 
00133         /* How big is the file now? */
00134         if ((offset= lseek(fd, 0, SEEK_END)) == -1) {
00135                 printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
00136                 exit(1);
00137         }
00138 
00139         if (offset == 0 && size == 0) exit(0);  /* Huh? */
00140 
00141         /* Write the first bit if the file is zero length.  This is necessary
00142          * to circumvent a DOS bug by extending a new file by lseek.  We also
00143          * want to make sure there are zeros in the first sector.
00144          */
00145         if (offset == 0) {
00146                 if (write(fd, buf, sizeof(buf)) == -1) {
00147                         printf("mkfile: Can't write to %s: %s\n",
00148                                 file, strerror(errno));
00149                         exit(1);
00150                 }
00151         }
00152 
00153         /* Seek to the required size and write 0 bytes to extend/truncate the
00154          * file to that size.
00155          */
00156         if (lseek(fd, size, SEEK_SET) == -1) {
00157                 printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
00158                 exit(1);
00159         }
00160         if (write(fd, buf, 0) == -1) {
00161                 printf("mkfile: Can't write to %s: %s\n",
00162                         file, strerror(errno));
00163                 exit(1);
00164         }
00165 
00166         /* Did the file become the required size? */
00167         if ((offset= lseek(fd, 0, SEEK_END)) == -1) {
00168                 printf("mkfile: Can't seek in %s: %s\n", file, strerror(errno));
00169                 exit(1);
00170         }
00171         if (offset != size) {
00172                 printf("mkfile: Failed to extend %s.  Disk full?\n", file);
00173                 exit(1);
00174         }
00175         return 0;
00176 }
00177 
00178 /*
00179  * $PchId: mkfile.c,v 1.4 2000/08/13 22:06:40 philip Exp $
00180  */

Generated on Fri Apr 14 22:56:37 2006 for minix by  doxygen 1.4.6