1/* trunc.c: Set the size of an existing file, or create a file of a 2 * specified size. 3 * 4 * Copyright (C) 2008 Micah J. Cowan 5 * 6 * Copying and distribution of this file, with or without modification, 7 * are permitted in any medium without royalty provided the copyright 8 * notice and this notice are preserved. */ 9 10#include <errno.h> 11#include <fcntl.h> 12#include <sys/stat.h> 13#include <unistd.h> 14#include <stdlib.h> 15#include <stdio.h> 16 17#define PROGRAM_NAME "trunc" 18 19void 20usage (FILE *f) 21{ 22 fputs ( 23PROGRAM_NAME " [-c] file sz\n\ 24\n\ 25Set the filesize of FILE to SIZE.\n\ 26\n\ 27 -c: create FILE if it doesn't exist.\n\ 28\n\ 29 Multiplier suffixes for SIZE (case-insensitive):\n\ 30 k: SIZE * 1024\n\ 31 m: SIZE * 1024 * 1024\n", f); 32} 33 34off_t 35get_size (const char str[]) 36{ 37 unsigned long val; 38 int suffix; 39 char *end; 40 41 errno = 0; 42 val = strtoul(str, &end, 10); 43 if (end == str) 44 { 45 fputs (PROGRAM_NAME ": size is not a number.\n", stderr); 46 usage (stderr); 47 exit (EXIT_FAILURE); 48 } 49 else if (errno == ERANGE 50 || (unsigned long)(off_t)val != val) 51 { 52 fputs (PROGRAM_NAME ": size is out of range.\n", stderr); 53 exit (EXIT_FAILURE); 54 } 55 56 suffix = tolower ((unsigned char) end[0]); 57 if (suffix == 'k') 58 { 59 val *= 1024; 60 } 61 else if (suffix == 'm') 62 { 63 val *= 1024 * 1024; 64 } 65 66 return val; 67} 68 69int 70main (int argc, char *argv[]) 71{ 72 const char *fname; 73 const char *szstr; 74 off_t sz; 75 int create = 0; 76 int option; 77 int fd; 78 79#ifdef ENABLE_NLS 80 /* Set the current locale. */ 81 setlocale (LC_ALL, ""); 82 /* Set the text message domain. */ 83 bindtextdomain ("wget", LOCALEDIR); 84 textdomain ("wget"); 85#endif /* ENABLE_NLS */ 86 87 /* Parse options. */ 88 while ((option = getopt (argc, argv, "c")) != -1) 89 { 90 switch (option) { 91 case 'c': 92 create = 1; 93 break; 94 case '?': 95 fprintf (stderr, PROGRAM_NAME ": Unrecognized option `%c'.\n\n", 96 optopt); 97 usage (stderr); 98 exit (EXIT_FAILURE); 99 default: 100 /* We shouldn't reach here. */ 101 abort(); 102 } 103 } 104 105 if (argv[optind] == NULL 106 || argv[optind+1] == NULL 107 || argv[optind+2] != NULL) 108 { 109 usage (stderr); 110 exit (EXIT_FAILURE); 111 } 112 113 fname = argv[optind]; 114 szstr = argv[optind+1]; 115 116 sz = get_size(szstr); 117 if (create) 118 { 119 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 120 fd = open(fname, O_WRONLY | O_CREAT, mode); 121 } 122 else 123 { 124 fd = open(fname, O_WRONLY); 125 } 126 127 if (fd == -1) 128 { 129 perror (PROGRAM_NAME ": open"); 130 exit (EXIT_FAILURE); 131 } 132 133 if (ftruncate(fd, sz) == -1) 134 { 135 perror (PROGRAM_NAME ": truncate"); 136 exit (EXIT_FAILURE); 137 } 138 139 if (close (fd) < 0) 140 { 141 perror (PROGRAM_NAME ": close"); 142 exit (EXIT_FAILURE); 143 } 144 145 return 0; 146} 147