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