1*9f988b79SJean-Baptiste Boric /* $NetBSD: v7fs.c,v 1.8 2013/01/29 15:52:25 christos Exp $ */
2*9f988b79SJean-Baptiste Boric
3*9f988b79SJean-Baptiste Boric /*-
4*9f988b79SJean-Baptiste Boric * Copyright (c) 2011 The NetBSD Foundation, Inc.
5*9f988b79SJean-Baptiste Boric * All rights reserved.
6*9f988b79SJean-Baptiste Boric *
7*9f988b79SJean-Baptiste Boric * This code is derived from software contributed to The NetBSD Foundation
8*9f988b79SJean-Baptiste Boric * by UCHIYAMA Yasushi.
9*9f988b79SJean-Baptiste Boric *
10*9f988b79SJean-Baptiste Boric * Redistribution and use in source and binary forms, with or without
11*9f988b79SJean-Baptiste Boric * modification, are permitted provided that the following conditions
12*9f988b79SJean-Baptiste Boric * are met:
13*9f988b79SJean-Baptiste Boric * 1. Redistributions of source code must retain the above copyright
14*9f988b79SJean-Baptiste Boric * notice, this list of conditions and the following disclaimer.
15*9f988b79SJean-Baptiste Boric * 2. Redistributions in binary form must reproduce the above copyright
16*9f988b79SJean-Baptiste Boric * notice, this list of conditions and the following disclaimer in the
17*9f988b79SJean-Baptiste Boric * documentation and/or other materials provided with the distribution.
18*9f988b79SJean-Baptiste Boric *
19*9f988b79SJean-Baptiste Boric * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*9f988b79SJean-Baptiste Boric * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*9f988b79SJean-Baptiste Boric * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*9f988b79SJean-Baptiste Boric * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*9f988b79SJean-Baptiste Boric * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*9f988b79SJean-Baptiste Boric * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*9f988b79SJean-Baptiste Boric * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*9f988b79SJean-Baptiste Boric * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*9f988b79SJean-Baptiste Boric * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*9f988b79SJean-Baptiste Boric * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*9f988b79SJean-Baptiste Boric * POSSIBILITY OF SUCH DAMAGE.
30*9f988b79SJean-Baptiste Boric */
31*9f988b79SJean-Baptiste Boric
32*9f988b79SJean-Baptiste Boric #if HAVE_NBTOOL_CONFIG_H
33*9f988b79SJean-Baptiste Boric #include "nbtool_config.h"
34*9f988b79SJean-Baptiste Boric #endif
35*9f988b79SJean-Baptiste Boric
36*9f988b79SJean-Baptiste Boric #include <sys/cdefs.h>
37*9f988b79SJean-Baptiste Boric #if defined(__RCSID) && !defined(__lint)
38*9f988b79SJean-Baptiste Boric __RCSID("$NetBSD: v7fs.c,v 1.8 2013/01/29 15:52:25 christos Exp $");
39*9f988b79SJean-Baptiste Boric #endif /* !__lint */
40*9f988b79SJean-Baptiste Boric
41*9f988b79SJean-Baptiste Boric #include <stdio.h>
42*9f988b79SJean-Baptiste Boric #include <stdlib.h>
43*9f988b79SJean-Baptiste Boric #include <unistd.h>
44*9f988b79SJean-Baptiste Boric #include <string.h>
45*9f988b79SJean-Baptiste Boric #include <fcntl.h>
46*9f988b79SJean-Baptiste Boric #include <util.h>
47*9f988b79SJean-Baptiste Boric
48*9f988b79SJean-Baptiste Boric #include "makefs.h"
49*9f988b79SJean-Baptiste Boric #include "v7fs.h"
50*9f988b79SJean-Baptiste Boric #include "v7fs_impl.h"
51*9f988b79SJean-Baptiste Boric #include "v7fs_makefs.h"
52*9f988b79SJean-Baptiste Boric #include "newfs_v7fs.h"
53*9f988b79SJean-Baptiste Boric
54*9f988b79SJean-Baptiste Boric
55*9f988b79SJean-Baptiste Boric #ifndef HAVE_NBTOOL_CONFIG_H
56*9f988b79SJean-Baptiste Boric #include "progress.h"
57*9f988b79SJean-Baptiste Boric static bool progress_bar_enable;
58*9f988b79SJean-Baptiste Boric #endif
59*9f988b79SJean-Baptiste Boric int v7fs_newfs_verbose;
60*9f988b79SJean-Baptiste Boric
61*9f988b79SJean-Baptiste Boric void
v7fs_prep_opts(fsinfo_t * fsopts)62*9f988b79SJean-Baptiste Boric v7fs_prep_opts(fsinfo_t *fsopts)
63*9f988b79SJean-Baptiste Boric {
64*9f988b79SJean-Baptiste Boric v7fs_opt_t *v7fs_opts = ecalloc(1, sizeof(*v7fs_opts));
65*9f988b79SJean-Baptiste Boric const option_t v7fs_options[] = {
66*9f988b79SJean-Baptiste Boric { 'p', "pdp", &v7fs_opts->pdp_endian, OPT_INT32, false, true,
67*9f988b79SJean-Baptiste Boric "PDP endian" },
68*9f988b79SJean-Baptiste Boric { 'P', "progress", &v7fs_opts->progress, OPT_INT32, false, true,
69*9f988b79SJean-Baptiste Boric "Progress bar" },
70*9f988b79SJean-Baptiste Boric { .name = NULL }
71*9f988b79SJean-Baptiste Boric };
72*9f988b79SJean-Baptiste Boric
73*9f988b79SJean-Baptiste Boric fsopts->fs_specific = v7fs_opts;
74*9f988b79SJean-Baptiste Boric fsopts->fs_options = copy_opts(v7fs_options);
75*9f988b79SJean-Baptiste Boric }
76*9f988b79SJean-Baptiste Boric
77*9f988b79SJean-Baptiste Boric void
v7fs_cleanup_opts(fsinfo_t * fsopts)78*9f988b79SJean-Baptiste Boric v7fs_cleanup_opts(fsinfo_t *fsopts)
79*9f988b79SJean-Baptiste Boric {
80*9f988b79SJean-Baptiste Boric free(fsopts->fs_specific);
81*9f988b79SJean-Baptiste Boric free(fsopts->fs_options);
82*9f988b79SJean-Baptiste Boric }
83*9f988b79SJean-Baptiste Boric
84*9f988b79SJean-Baptiste Boric int
v7fs_parse_opts(const char * option,fsinfo_t * fsopts)85*9f988b79SJean-Baptiste Boric v7fs_parse_opts(const char *option, fsinfo_t *fsopts)
86*9f988b79SJean-Baptiste Boric {
87*9f988b79SJean-Baptiste Boric
88*9f988b79SJean-Baptiste Boric return set_option_var(fsopts->fs_options, option, "1", NULL, 0) != -1;
89*9f988b79SJean-Baptiste Boric }
90*9f988b79SJean-Baptiste Boric
91*9f988b79SJean-Baptiste Boric void
v7fs_makefs(const char * image,const char * dir,fsnode * root,fsinfo_t * fsopts)92*9f988b79SJean-Baptiste Boric v7fs_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts)
93*9f988b79SJean-Baptiste Boric {
94*9f988b79SJean-Baptiste Boric struct v7fs_mount_device v7fs_mount;
95*9f988b79SJean-Baptiste Boric int fd, endian, error = 1;
96*9f988b79SJean-Baptiste Boric v7fs_opt_t *v7fs_opts = fsopts->fs_specific;
97*9f988b79SJean-Baptiste Boric
98*9f988b79SJean-Baptiste Boric v7fs_newfs_verbose = debug;
99*9f988b79SJean-Baptiste Boric #ifndef HAVE_NBTOOL_CONFIG_H
100*9f988b79SJean-Baptiste Boric if ((progress_bar_enable = v7fs_opts->progress)) {
101*9f988b79SJean-Baptiste Boric progress_switch(progress_bar_enable);
102*9f988b79SJean-Baptiste Boric progress_init();
103*9f988b79SJean-Baptiste Boric progress(&(struct progress_arg){ .cdev = image });
104*9f988b79SJean-Baptiste Boric }
105*9f988b79SJean-Baptiste Boric #endif
106*9f988b79SJean-Baptiste Boric
107*9f988b79SJean-Baptiste Boric /* Determine filesystem image size */
108*9f988b79SJean-Baptiste Boric v7fs_estimate(dir, root, fsopts);
109*9f988b79SJean-Baptiste Boric printf("Calculated size of `%s': %lld bytes, %ld inodes\n",
110*9f988b79SJean-Baptiste Boric image, (long long)fsopts->size, (long)fsopts->inodes);
111*9f988b79SJean-Baptiste Boric
112*9f988b79SJean-Baptiste Boric if ((fd = open(image, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) {
113*9f988b79SJean-Baptiste Boric err(EXIT_FAILURE, "%s", image);
114*9f988b79SJean-Baptiste Boric }
115*9f988b79SJean-Baptiste Boric if (lseek(fd, fsopts->size - 1, SEEK_SET) == -1) {
116*9f988b79SJean-Baptiste Boric goto err_exit;
117*9f988b79SJean-Baptiste Boric }
118*9f988b79SJean-Baptiste Boric if (write(fd, &fd, 1) != 1) {
119*9f988b79SJean-Baptiste Boric goto err_exit;
120*9f988b79SJean-Baptiste Boric }
121*9f988b79SJean-Baptiste Boric if (lseek(fd, 0, SEEK_SET) == -1) {
122*9f988b79SJean-Baptiste Boric goto err_exit;
123*9f988b79SJean-Baptiste Boric }
124*9f988b79SJean-Baptiste Boric fsopts->fd = fd;
125*9f988b79SJean-Baptiste Boric v7fs_mount.device.fd = fd;
126*9f988b79SJean-Baptiste Boric
127*9f988b79SJean-Baptiste Boric #if !defined BYTE_ORDER
128*9f988b79SJean-Baptiste Boric #error
129*9f988b79SJean-Baptiste Boric #endif
130*9f988b79SJean-Baptiste Boric #if BYTE_ORDER == LITTLE_ENDIAN
131*9f988b79SJean-Baptiste Boric if (fsopts->needswap)
132*9f988b79SJean-Baptiste Boric endian = BIG_ENDIAN;
133*9f988b79SJean-Baptiste Boric else
134*9f988b79SJean-Baptiste Boric endian = LITTLE_ENDIAN;
135*9f988b79SJean-Baptiste Boric #else
136*9f988b79SJean-Baptiste Boric if (fsopts->needswap)
137*9f988b79SJean-Baptiste Boric endian = LITTLE_ENDIAN;
138*9f988b79SJean-Baptiste Boric else
139*9f988b79SJean-Baptiste Boric endian = BIG_ENDIAN;
140*9f988b79SJean-Baptiste Boric #endif
141*9f988b79SJean-Baptiste Boric if (v7fs_opts->pdp_endian) {
142*9f988b79SJean-Baptiste Boric endian = PDP_ENDIAN;
143*9f988b79SJean-Baptiste Boric }
144*9f988b79SJean-Baptiste Boric
145*9f988b79SJean-Baptiste Boric v7fs_mount.endian = endian;
146*9f988b79SJean-Baptiste Boric v7fs_mount.sectors = fsopts->size >> V7FS_BSHIFT;
147*9f988b79SJean-Baptiste Boric if (v7fs_newfs(&v7fs_mount, fsopts->inodes) != 0) {
148*9f988b79SJean-Baptiste Boric goto err_exit;
149*9f988b79SJean-Baptiste Boric }
150*9f988b79SJean-Baptiste Boric
151*9f988b79SJean-Baptiste Boric if (v7fs_populate(dir, root, fsopts, &v7fs_mount) != 0) {
152*9f988b79SJean-Baptiste Boric error = 2; /* some files couldn't add */
153*9f988b79SJean-Baptiste Boric goto err_exit;
154*9f988b79SJean-Baptiste Boric }
155*9f988b79SJean-Baptiste Boric
156*9f988b79SJean-Baptiste Boric close(fd);
157*9f988b79SJean-Baptiste Boric return;
158*9f988b79SJean-Baptiste Boric
159*9f988b79SJean-Baptiste Boric err_exit:
160*9f988b79SJean-Baptiste Boric close(fd);
161*9f988b79SJean-Baptiste Boric err(error, "%s", image);
162*9f988b79SJean-Baptiste Boric }
163*9f988b79SJean-Baptiste Boric
164*9f988b79SJean-Baptiste Boric void
progress(const struct progress_arg * p)165*9f988b79SJean-Baptiste Boric progress(const struct progress_arg *p)
166*9f988b79SJean-Baptiste Boric {
167*9f988b79SJean-Baptiste Boric #ifndef HAVE_NBTOOL_CONFIG_H
168*9f988b79SJean-Baptiste Boric static struct progress_arg Progress;
169*9f988b79SJean-Baptiste Boric static char cdev[32];
170*9f988b79SJean-Baptiste Boric static char label[32];
171*9f988b79SJean-Baptiste Boric
172*9f988b79SJean-Baptiste Boric if (!progress_bar_enable)
173*9f988b79SJean-Baptiste Boric return;
174*9f988b79SJean-Baptiste Boric
175*9f988b79SJean-Baptiste Boric if (p) {
176*9f988b79SJean-Baptiste Boric Progress = *p;
177*9f988b79SJean-Baptiste Boric if (p->cdev)
178*9f988b79SJean-Baptiste Boric strcpy(cdev, p->cdev);
179*9f988b79SJean-Baptiste Boric if (p->label)
180*9f988b79SJean-Baptiste Boric strcpy(label, p->label);
181*9f988b79SJean-Baptiste Boric }
182*9f988b79SJean-Baptiste Boric
183*9f988b79SJean-Baptiste Boric if (!Progress.tick)
184*9f988b79SJean-Baptiste Boric return;
185*9f988b79SJean-Baptiste Boric if (++Progress.cnt > Progress.tick) {
186*9f988b79SJean-Baptiste Boric Progress.cnt = 0;
187*9f988b79SJean-Baptiste Boric Progress.total++;
188*9f988b79SJean-Baptiste Boric progress_bar(cdev, label, Progress.total, PROGRESS_BAR_GRANULE);
189*9f988b79SJean-Baptiste Boric }
190*9f988b79SJean-Baptiste Boric #endif
191*9f988b79SJean-Baptiste Boric }
192