~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to disk-utils/mkfs.bfs.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 *  mkfs.bfs - Create SCO BFS filesystem - aeb, 1999-09-07
3
3
 *
4
 
 *  Usage: mkfs.bfs [-N nr-of-inodes] [-V volume-name] [-F fsname] device
5
4
 */
6
5
 
 
6
#include <errno.h>
 
7
#include <fcntl.h>
 
8
#include <getopt.h>
 
9
#include <limits.h>
7
10
#include <stdio.h>
8
11
#include <stdlib.h>
9
 
#include <unistd.h>
10
 
#include <stdarg.h>
11
 
#include <sys/types.h>
 
12
#include <string.h>
12
13
#include <sys/stat.h>
13
 
#include <fcntl.h>
14
 
#include <errno.h>
15
 
#include <string.h>
16
14
#include <time.h>
 
15
#include <unistd.h>
 
16
 
 
17
#include "blkdev.h"
 
18
#include "c.h"
17
19
#include "nls.h"
18
 
#include "blkdev.h"
 
20
#include "strutils.h"
 
21
#include "xalloc.h"
19
22
 
20
23
#define BFS_ROOT_INO            2
21
24
#define BFS_NAMELEN             14
24
27
 
25
28
/* superblock - 512 bytes */
26
29
struct bfssb {
27
 
        unsigned int s_magic;
28
 
        unsigned int s_start;     /* byte offset of start of data */
29
 
        unsigned int s_end;       /* sizeof(slice)-1 */
30
 
 
31
 
        /* for recovery during compaction */
32
 
        int s_from, s_to;         /* src and dest block of current transfer */
33
 
        int s_backup_from, s_backup_to;
34
 
 
35
 
        /* labels - may well contain garbage */
36
 
        char s_fsname[6];
37
 
        char s_volume[6];
38
 
        char s_pad[472];
 
30
        unsigned int s_magic;
 
31
        unsigned int s_start;   /* byte offset of start of data */
 
32
        unsigned int s_end;     /* sizeof(slice)-1 */
 
33
 
 
34
        /* for recovery during compaction */
 
35
        int s_from, s_to;       /* src and dest block of current transfer */
 
36
        int s_backup_from, s_backup_to;
 
37
 
 
38
        /* labels - may well contain garbage */
 
39
        char s_fsname[6];
 
40
        char s_volume[6];
 
41
        char s_pad[472];
39
42
};
40
43
 
41
44
/* inode - 64 bytes */
42
45
struct bfsi {
43
 
        unsigned short i_ino;
44
 
        unsigned char i_pad1[2];
45
 
        unsigned long i_first_block;
46
 
        unsigned long i_last_block;
47
 
        unsigned long i_bytes_to_end;
48
 
        unsigned long i_type;           /* 1: file, 2: the unique dir */
49
 
        unsigned long i_mode;
50
 
        unsigned long i_uid, i_gid;
51
 
        unsigned long i_nlinks;
52
 
        unsigned long i_atime, i_mtime, i_ctime;
53
 
        unsigned char i_pad2[16];
 
46
        unsigned short i_ino;
 
47
        unsigned char i_pad1[2];
 
48
        unsigned long i_first_block;
 
49
        unsigned long i_last_block;
 
50
        unsigned long i_bytes_to_end;
 
51
        unsigned long i_type;   /* 1: file, 2: the unique dir */
 
52
        unsigned long i_mode;
 
53
        unsigned long i_uid, i_gid;
 
54
        unsigned long i_nlinks;
 
55
        unsigned long i_atime, i_mtime, i_ctime;
 
56
        unsigned char i_pad2[16];
54
57
};
55
58
 
56
59
#define BFS_DIR_TYPE    2
57
60
 
58
61
/* directory entry - 16 bytes */
59
62
struct bfsde {
60
 
        unsigned short d_ino;
61
 
        char d_name[BFS_NAMELEN];
 
63
        unsigned short d_ino;
 
64
        char d_name[BFS_NAMELEN];
62
65
};
63
66
 
64
 
 
65
 
static char *progname;
66
 
 
67
 
static void
68
 
fatal(char *s, ...) {
69
 
    va_list p;
70
 
 
71
 
    va_start(p, s);
72
 
    fflush(stdout);
73
 
    fprintf(stderr, "\n%s: ", progname);
74
 
    vfprintf(stderr, s, p);
75
 
    va_end(p);
76
 
    fprintf(stderr, "\n");
77
 
    exit(1);
78
 
}
79
 
 
80
 
static void
81
 
usage(void) {
82
 
        fprintf(stderr, _(
83
 
                "Usage: %s [-v] [-N nr-of-inodes] [-V volume-name]\n"
84
 
                "       [-F fsname] device [block-count]\n"),
85
 
                progname);
86
 
        exit(1);
87
 
}
88
 
 
89
 
int
90
 
main(int argc, char *argv[]) {
 
67
static void __attribute__ ((__noreturn__)) usage(FILE * out)
 
68
{
 
69
        fprintf(out,
 
70
                _("Usage: %s [options] device [block-count]\n"),
 
71
                program_invocation_short_name);
 
72
        fprintf(out, _("\nOptions:\n"
 
73
                       " -N, --inodes=NUM    specify desired number of inodes\n"
 
74
                       " -V, --vname=NAME    specify volume name\n"
 
75
                       " -F, --fname=NAME    specify file system name\n"
 
76
                       " -v, --verbose       explain what is being done\n"
 
77
                       " -c                  this option is silently ignored\n"
 
78
                       " -l                  this option is silently ignored\n"
 
79
                       " -V, --version       output version information and exit\n"
 
80
                       "                     -V as version must be only option\n"
 
81
                       " -h, --help          display this help and exit\n\n"));
 
82
 
 
83
        exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 
84
}
 
85
 
 
86
static void __attribute__ ((__noreturn__)) print_version(void)
 
87
{
 
88
        printf(_("%s from %s\n"), program_invocation_short_name, PACKAGE_STRING);
 
89
        exit(EXIT_SUCCESS);
 
90
}
 
91
 
 
92
int main(int argc, char **argv)
 
93
{
91
94
        char *device, *volume, *fsname;
92
 
        int inodes;
 
95
        long inodes;
93
96
        unsigned long long total_blocks, ino_bytes, ino_blocks, data_blocks;
94
97
        unsigned long long user_specified_total_blocks = 0;
95
98
        int verbose = 0;
100
103
        struct stat statbuf;
101
104
        time_t now;
102
105
        int c, i, len;
103
 
        char *p;
104
106
 
105
 
        progname = argv[0];
106
 
        if ((p = strrchr(progname, '/')) != NULL)
107
 
                progname = p+1;
 
107
        enum { VERSION_OPTION = CHAR_MAX + 1 };
 
108
        static const struct option longopts[] = {
 
109
                {"inodes", required_argument, NULL, 'N'},
 
110
                {"vname", required_argument, NULL, 'V'},
 
111
                {"fname", required_argument, NULL, 'F'},
 
112
                {"verbose", no_argument, NULL, 'v'},
 
113
                {"version", no_argument, NULL, VERSION_OPTION},
 
114
                {"help", no_argument, NULL, 'h'},
 
115
                {NULL, 0, NULL, 0}
 
116
        };
108
117
 
109
118
        if (argc < 2)
110
 
                usage();
 
119
                usage(stderr);
111
120
 
112
 
        if (argc == 2 &&
113
 
            (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
114
 
                printf(_("%s (%s)\n"), progname, PACKAGE_STRING);
115
 
                exit(0);
116
 
        }
 
121
        if (argc == 2 && !strcmp(argv[1], "-V"))
 
122
                print_version();
117
123
 
118
124
        volume = fsname = "      ";     /* is there a default? */
119
125
        inodes = 0;
120
126
 
121
 
        while ((c = getopt(argc, argv, "vF:N:V:cl:")) != -1) {
 
127
        while ((c = getopt_long(argc, argv, "N:V:F:vhcl", longopts, NULL)) != -1) {
122
128
                switch (c) {
123
129
                case 'N':
124
 
                        inodes = atol(optarg);
 
130
                        inodes = strtol_or_err(optarg, _("invalid number of inodes"));
125
131
                        break;
126
132
 
127
133
                case 'V':
128
134
                        len = strlen(optarg);
129
135
                        if (len <= 0 || len > 6)
130
 
                                fatal(_("volume name too long"));
131
 
                        volume = strdup(optarg);
 
136
                                errx(EXIT_FAILURE, _("volume name too long"));
 
137
                        volume = xstrdup(optarg);
132
138
                        break;
133
139
 
134
140
                case 'F':
135
141
                        len = strlen(optarg);
136
142
                        if (len <= 0 || len > 6)
137
 
                                fatal(_("fsname name too long"));
138
 
                        fsname = strdup(optarg);
 
143
                                errx(EXIT_FAILURE, _("fsname name too long"));
 
144
                        fsname = xstrdup(optarg);
139
145
                        break;
140
146
 
141
147
                case 'v':
142
148
                        verbose = 1;
143
149
                        break;
144
150
 
145
 
                        /* when called via mkfs we may get options c,l,v */
146
151
                case 'c':
147
152
                case 'l':
 
153
                        /* when called via mkfs we may get options c,l,v */
148
154
                        break;
149
155
 
 
156
                case VERSION_OPTION:
 
157
                        print_version();
 
158
                case 'h':
 
159
                        usage(stdout);
150
160
                default:
151
 
                        usage();
 
161
                        usage(stderr);
152
162
                }
153
163
        }
154
164
 
155
165
        if (optind == argc)
156
 
                usage();
 
166
                usage(stderr);
157
167
 
158
168
        device = argv[optind++];
159
169
 
160
 
        if (stat(device, &statbuf) == -1) {
161
 
                perror(device);
162
 
                fatal(_("cannot stat device %s"), device);
163
 
        }
 
170
        if (stat(device, &statbuf) < 0)
 
171
                err(EXIT_FAILURE, _("cannot stat device %s"), device);
164
172
 
165
173
        if (!S_ISBLK(statbuf.st_mode))
166
 
                fatal(_("%s is not a block special device"), device);
 
174
                errx(EXIT_FAILURE, _("%s is not a block special device"), device);
167
175
 
168
176
        fd = open(device, O_RDWR | O_EXCL);
169
 
        if (fd == -1) {
170
 
                perror(device);
171
 
                fatal(_("cannot open %s"), device);
172
 
        }
 
177
        if (fd < 0)
 
178
                err(EXIT_FAILURE, _("cannot open %s"), device);
173
179
 
174
 
        if (optind == argc-1)
175
 
                user_specified_total_blocks = atoll(argv[optind]);
 
180
        if (optind == argc - 1)
 
181
                user_specified_total_blocks =
 
182
                        strtoll_or_err(argv[optind], _("invalid block-count"));
176
183
        else if (optind != argc)
177
 
                usage();
 
184
                usage(stderr);
178
185
 
179
186
        if (blkdev_get_sectors(fd, &total_blocks) == -1) {
180
 
                if (!user_specified_total_blocks) {
181
 
                        perror("blkdev_get_sectors");
182
 
                        fatal(_("cannot get size of %s"), device);
183
 
                }
 
187
                if (!user_specified_total_blocks)
 
188
                        err(EXIT_FAILURE, _("cannot get size of %s"), device);
184
189
                total_blocks = user_specified_total_blocks;
185
190
        } else if (user_specified_total_blocks) {
186
191
                if (user_specified_total_blocks > total_blocks)
187
 
                        fatal(_("blocks argument too large, max is %llu"),
188
 
                              total_blocks);
 
192
                        errx(EXIT_FAILURE,
 
193
                             _("blocks argument too large, max is %llu"),
 
194
                             total_blocks);
189
195
                total_blocks = user_specified_total_blocks;
190
196
        }
191
197
 
192
198
        if (!inodes) {
193
199
                /* pick some reasonable default */
194
 
                inodes = 8*(total_blocks/800);
 
200
                inodes = 8 * (total_blocks / 800);
195
201
                if (inodes < 48)
196
202
                        inodes = 48;
197
 
                if (inodes > 512)
 
203
                if (512 < inodes)
198
204
                        inodes = 512;
199
205
        } else {
200
206
                /* believe the user */
201
 
                if (inodes > 512)
202
 
                        fatal(_("too many inodes - max is 512"));
 
207
                if (512 < inodes)
 
208
                        errx(EXIT_FAILURE, _("too many inodes - max is 512"));
203
209
        }
204
210
 
205
211
        ino_bytes = inodes * sizeof(struct bfsi);
208
214
 
209
215
        /* mimic the behaviour of SCO's mkfs - maybe this limit is needed */
210
216
        if (data_blocks < 32)
211
 
                fatal(_("not enough space, need at least %llu blocks"),
212
 
                      ino_blocks + 33);
 
217
                errx(EXIT_FAILURE,
 
218
                     _("not enough space, need at least %llu blocks"),
 
219
                     ino_blocks + 33);
213
220
 
214
221
        memset(&sb, 0, sizeof(sb));
215
222
        sb.s_magic = BFS_SUPER_MAGIC;
224
231
                fprintf(stderr, _("Volume: <%-6s>\n"), volume);
225
232
                fprintf(stderr, _("FSname: <%-6s>\n"), fsname);
226
233
                fprintf(stderr, _("BlockSize: %d\n"), BFS_BLOCKSIZE);
227
 
                if (ino_blocks==1)
228
 
                        fprintf(stderr, _("Inodes: %d (in 1 block)\n"),
 
234
                if (ino_blocks == 1)
 
235
                        fprintf(stderr, _("Inodes: %lu (in 1 block)\n"),
229
236
                                inodes);
230
237
                else
231
 
                        fprintf(stderr, _("Inodes: %d (in %lld blocks)\n"),
 
238
                        fprintf(stderr, _("Inodes: %lu (in %llu blocks)\n"),
232
239
                                inodes, ino_blocks);
233
240
                fprintf(stderr, _("Blocks: %lld\n"), total_blocks);
234
241
                fprintf(stderr, _("Inode end: %d, Data end: %d\n"),
235
 
                        sb.s_start-1, sb.s_end);
 
242
                        sb.s_start - 1, sb.s_end);
236
243
        }
237
244
 
238
245
        if (write(fd, &sb, sizeof(sb)) != sizeof(sb))
239
 
                fatal(_("error writing superblock"));
 
246
                err(EXIT_FAILURE, _("error writing superblock"));
240
247
 
241
248
        memset(&ri, 0, sizeof(ri));
242
249
        ri.i_ino = BFS_ROOT_INO;
243
250
        ri.i_first_block = 1 + ino_blocks;
244
251
        ri.i_last_block = ri.i_first_block +
245
 
                (inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
 
252
            (inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
246
253
        ri.i_bytes_to_end = ri.i_first_block * BFS_BLOCKSIZE
247
 
                + 2 * sizeof(struct bfsde) - 1;
 
254
            + 2 * sizeof(struct bfsde) - 1;
248
255
        ri.i_type = BFS_DIR_TYPE;
249
 
        ri.i_mode = S_IFDIR | 0755;     /* or just 0755 */
 
256
        ri.i_mode = S_IFDIR | 0755;     /* or just 0755 */
250
257
        ri.i_uid = 0;
251
258
        ri.i_gid = 1;                   /* random */
252
259
        ri.i_nlinks = 2;
256
263
        ri.i_ctime = now;
257
264
 
258
265
        if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
259
 
                fatal(_("error writing root inode"));
 
266
                err(EXIT_FAILURE, _("error writing root inode"));
260
267
 
261
268
        memset(&ri, 0, sizeof(ri));
262
 
        for (i=1; i<inodes; i++)
 
269
        for (i = 1; i < inodes; i++)
263
270
                if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
264
 
                        fatal(_("error writing inode"));
 
271
                        err(EXIT_FAILURE, _("error writing inode"));
265
272
 
266
 
        if (lseek(fd, (1 + ino_blocks)*BFS_BLOCKSIZE, SEEK_SET) == -1)
267
 
                fatal(_("seek error"));
 
273
        if (lseek(fd, (1 + ino_blocks) * BFS_BLOCKSIZE, SEEK_SET) == -1)
 
274
                err(EXIT_FAILURE, _("seek error"));
268
275
 
269
276
        memset(&de, 0, sizeof(de));
270
277
        de.d_ino = BFS_ROOT_INO;
271
278
        memcpy(de.d_name, ".", 1);
272
279
        if (write(fd, &de, sizeof(de)) != sizeof(de))
273
 
                fatal(_("error writing . entry"));
 
280
                err(EXIT_FAILURE, _("error writing . entry"));
274
281
 
275
282
        memcpy(de.d_name, "..", 2);
276
283
        if (write(fd, &de, sizeof(de)) != sizeof(de))
277
 
                fatal(_("error writing .. entry"));
278
 
 
279
 
        if (close(fd) == -1) {
280
 
                perror(device);
281
 
                fatal(_("error closing %s"), device);
282
 
        }
283
 
 
284
 
        return 0;
 
284
                err(EXIT_FAILURE, _("error writing .. entry"));
 
285
 
 
286
        if (close(fd) < 0)
 
287
                err(EXIT_FAILURE, _("error closing %s"), device);
 
288
 
 
289
        return EXIT_SUCCESS;
285
290
}