mkfile.c

00001 /*
00002  * Copyright (c) 2009 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <dirent.h>
00033 #include <fcntl.h>
00034 #include <sys/types.h>
00035 #include <sys/stat.h>
00036 #include <fcntl.h>
00037 #include <macros.h>
00038 #include <getopt.h>
00039 #include <stdarg.h>
00040 #include <str.h>
00041 #include <ctype.h>
00042 
00043 #include "config.h"
00044 #include "errors.h"
00045 #include "util.h"
00046 #include "entry.h"
00047 #include "mkfile.h"
00048 #include "cmds.h"
00049 
00051 #define BUFFER_SIZE 16384
00052 
00053 static const char *cmdname = "mkfile";
00054 
00055 static struct option const long_options[] = {
00056         {"size", required_argument, 0, 's'},
00057         {"help", no_argument, 0, 'h'},
00058         {0, 0, 0, 0}
00059 };
00060 
00061 void help_cmd_mkfile(unsigned int level)
00062 {
00063         if (level == HELP_SHORT) {
00064                 printf("`%s' creates a new zero-filled file\n", cmdname);
00065         } else {
00066                 help_cmd_mkfile(HELP_SHORT);
00067                 printf(
00068                 "Usage:  %s [options] <path>\n"
00069                 "Options:\n"
00070                 "  -h, --help       A short option summary\n"
00071                 "  -s, --size sz    Size of the file\n"
00072                 "\n"
00073                 "Size is a number followed by 'k', 'm' or 'g' for kB, MB, GB.\n"
00074                 "E.g. 100k, 2m, 1g.\n",
00075                 cmdname);
00076         }
00077 
00078         return;
00079 }
00080 
00089 static ssize_t read_size(const char *str)
00090 {
00091         ssize_t number, unit;
00092         char *ep;
00093 
00094         number = strtol(str, &ep, 10);
00095         if (ep[0] == '\0')
00096                 return number;
00097 
00098         if (ep[1] != '\0')
00099                     return -1;
00100 
00101         switch (tolower(ep[0])) {
00102         case 'k': unit = 1024; break;
00103         case 'm': unit = 1024*1024; break;
00104         case 'g': unit = 1024*1024*1024; break;
00105         default: return -1;
00106         }
00107 
00108         return number * unit;
00109 }
00110 
00111 int cmd_mkfile(char **argv)
00112 {
00113         unsigned int argc;
00114         int c, opt_ind;
00115         int fd;
00116         ssize_t file_size;
00117         ssize_t total_written;
00118         ssize_t to_write, rc;
00119         char *file_name;
00120         void *buffer;
00121 
00122         file_size = 0;
00123 
00124         argc = cli_count_args(argv);
00125 
00126         for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
00127                 c = getopt_long(argc, argv, "s:h", long_options, &opt_ind);
00128                 switch (c) {
00129                 case 'h':
00130                         help_cmd_mkfile(HELP_LONG);
00131                         return CMD_SUCCESS;
00132                 case 's':
00133                         file_size = read_size(optarg);
00134                         if (file_size < 0) {
00135                                 printf("%s: Invalid file size specification.\n",
00136                                     cmdname);
00137                                 return CMD_FAILURE;
00138                         }
00139                         break;
00140                 }
00141         }
00142 
00143         argc -= optind;
00144 
00145         if (argc != 1) {
00146                 printf("%s: incorrect number of arguments. Try `%s --help'\n",
00147                         cmdname, cmdname);
00148                 return CMD_FAILURE;
00149         }
00150 
00151         file_name = argv[optind];
00152 
00153         fd = open(file_name, O_CREAT | O_EXCL | O_WRONLY, 0666);
00154         if (fd < 0) {
00155                 printf("%s: failed to create file %s.\n", cmdname, file_name);
00156                 return CMD_FAILURE;
00157         }
00158 
00159         buffer = calloc(BUFFER_SIZE, 1);
00160         if (buffer == NULL) {
00161                 printf("%s: Error, out of memory.\n", cmdname);
00162                 return CMD_FAILURE;
00163         }
00164 
00165         total_written = 0;
00166         while (total_written < file_size) {
00167                 to_write = min(file_size - total_written, BUFFER_SIZE);
00168                 rc = write(fd, buffer, to_write);
00169                 if (rc <= 0) {
00170                         printf("%s: Error writing file (%zd).\n", cmdname, rc);
00171                         close(fd);
00172                         return CMD_FAILURE;
00173                 }
00174                 total_written += rc;
00175         }
00176 
00177         rc = close(fd);
00178         if (rc != 0) {
00179                 printf("%s: Error writing file (%zd).\n", cmdname, rc);
00180                 return CMD_FAILURE;
00181         }
00182 
00183         free(buffer);
00184 
00185         return CMD_SUCCESS;
00186 }

Generated on Thu Jun 2 07:45:41 2011 for HelenOS/USB by  doxygen 1.4.7