/*- * Copyright (c) 2001-2004 * HATANOU Tomomi. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static char sccsid[] = "@(#)mkfile.c 1.3 (HATANOU Tomomi) 2004/01/21"; #endif /* !lint */ #include #include #include #include #include #include #include #include #define MKFILE_WBUF (1048576) /* XXX - is 1M an reasonable value? */ /* * Try settting "sticky bit" for compatibility with SunOS's mkfile(8). */ #define MKFILE_MODE (S_IRUSR | S_IWUSR | S_ISVTX) static char buf[MKFILE_WBUF]; static int nofill = 0; static int verbose = 0; static void usage() { fprintf(stderr, "\ Usage: mkfile [-nv] [e|p|t|g|m|k|b] ...\n"); exit(0); } /* * NOTE: On many *BSD systems, size_t is still 32bit width. * We use `off_t' instead here. * This may also be okay for LP64 systems. */ static off_t getsize(s) char *s; { int sft; off_t length; char *suffix; length = (off_t)strtoll(s, &suffix, 10); sft = 0; switch (*suffix) { case 'e': case 'E': /* exabytes */ sft = 60; break; case 'p': case 'P': /* petabytes */ sft = 50; break; case 't': case 'T': /* terabytes */ sft = 40; break; case 'g': case 'G': /* gigabytes */ sft = 30; break; case 'm': case 'M': /* megabytes */ sft = 20; break; case 'k': case 'K': /* kilobytes */ sft = 10; break; case 'b': case 'B': /* blocks */ sft = 9; break; } if (sft) { off_t len; len = length; length <<= sft; /* check overflow */ if ((length >> sft) != len) { printf("Size too large.\n"); exit(0); } } return length; } static void init_buf() { bzero(buf, MKFILE_WBUF); } static void create_file(f, s) char *f; off_t s; { int fd, i; size_t bk, ix; if (verbose) { fprintf(stdout, "%s %qu bytes\n", f, s); fflush(stdout); } if ((fd = open(f, O_WRONLY | O_CREAT | O_TRUNC, MKFILE_MODE)) < 0) { perror(f); } else { lseek(fd, s - (off_t)1, SEEK_SET); write(fd, buf, (size_t)1); if (!nofill) { lseek(fd, (off_t)0, SEEK_SET); bk = (size_t)(s / (off_t)MKFILE_WBUF); ix = (size_t)(s % (off_t)MKFILE_WBUF); for (i = 0; i < bk; i++) { write(fd, buf, (size_t)MKFILE_WBUF); } if (ix) { write(fd, buf, (size_t)ix); } } close(fd); } } int main(argc, argv) int argc; char **argv; { off_t fsize; char *p; if (argc < 3) { usage(); } argv++; init_buf(); for (fsize = 0; *argv != NULL; argv++) { switch (**argv) { case '-': for (p = *argv + 1; *p; p++) { switch (*p) { case 'n': /* no filling */ nofill = 1; break; case 'v': /* verbose */ verbose = 1; break; } } break; default: if (!fsize) { fsize = getsize(*argv); } else { create_file(*argv, fsize); } } } return 0; }