]> sjero.net Git - wget/blob - util/trunc.c
Use /usr/bin/env to find the perl interpreter.
[wget] / util / trunc.c
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
19 void
20 usage (FILE *f)
21 {
22   fputs (
23 PROGRAM_NAME " [-c] file sz\n\
24 \n\
25 Set 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
34 off_t
35 get_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
69 int
70 main (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   /* Parse options. */
80   while ((option = getopt (argc, argv, "c")) != -1)
81     {
82       switch (option) {
83         case 'c':
84           create = 1;
85           break;
86         case '?':
87           fprintf (stderr, PROGRAM_NAME ": Unrecognized option `%c'.\n\n",
88                    optopt);
89           usage (stderr);
90           exit (EXIT_FAILURE);
91         default:
92           /* We shouldn't reach here. */
93           abort();
94       }
95     }
96
97   if (argv[optind] == NULL
98       || argv[optind+1] == NULL
99       || argv[optind+2] != NULL)
100     {
101       usage (stderr);
102       exit (EXIT_FAILURE);
103     }
104
105   fname = argv[optind];
106   szstr = argv[optind+1];
107
108   sz = get_size(szstr);
109   if (create)
110     {
111       mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
112       fd = open(fname, O_WRONLY | O_CREAT, mode);
113     }
114   else
115     {
116       fd = open(fname, O_WRONLY);
117     }
118
119   if (fd == -1)
120     {
121       perror (PROGRAM_NAME ": open");
122       exit (EXIT_FAILURE);
123     }
124
125   if (ftruncate(fd, sz) == -1)
126     {
127       perror (PROGRAM_NAME ": truncate");
128       exit (EXIT_FAILURE);
129     }
130
131   return 0;
132 }