Drop main() prototype. Syncs with NetBSD-8
[minix.git] / usr.sbin / makefs / chfs.c
blobde14246c03c7c311889193061c61d31034665097
1 /*-
2 * Copyright (c) 2012 Department of Software Engineering,
3 * University of Szeged, Hungary
4 * Copyright (c) 2012 Tamas Toth <ttoth@inf.u-szeged.hu>
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by the Department of Software Engineering, University of Szeged, Hungary
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #if HAVE_NBTOOL_CONFIG_H
33 #include "nbtool_config.h"
34 #endif
36 #include <sys/param.h>
38 #include <assert.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44 #include <util.h>
46 #include "makefs.h"
47 #include "chfs_makefs.h"
49 #include "chfs/chfs_mkfs.h"
51 static void chfs_validate(const char *, fsnode *, fsinfo_t *);
52 static int chfs_create_image(const char *, fsinfo_t *);
53 static int chfs_populate_dir(const char *, fsnode *, fsnode *, fsinfo_t *);
56 void
57 chfs_prep_opts(fsinfo_t *fsopts)
59 chfs_opt_t *chfs_opts = ecalloc(1, sizeof(*chfs_opts));
61 const option_t chfs_options[] = {
62 { 'p', "pagesize", &chfs_opts->pagesize, OPT_INT32,
63 1, INT_MAX, "page size" },
64 { 'e', "eraseblock", &chfs_opts->eraseblock, OPT_INT32,
65 1, INT_MAX, "eraseblock size" },
66 { 'm', "mediatype", &chfs_opts->mediatype, OPT_INT32,
67 0, 1, "type of the media, 0 (nor) or 1 (nand)" },
68 { .name = NULL }
71 chfs_opts->pagesize = -1;
72 chfs_opts->eraseblock = -1;
73 chfs_opts->mediatype = -1;
75 fsopts->size = 0;
76 fsopts->fs_specific = chfs_opts;
77 fsopts->fs_options = copy_opts(chfs_options);
80 void
81 chfs_cleanup_opts(fsinfo_t *fsopts)
83 free(fsopts->fs_specific);
84 free(fsopts->fs_options);
87 int
88 chfs_parse_opts(const char *option, fsinfo_t *fsopts)
91 assert(option != NULL);
92 assert(fsopts != NULL);
94 return set_option(fsopts->fs_options, option, NULL, 0) != -1;
97 void
98 chfs_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts)
100 struct timeval start;
102 assert(image != NULL);
103 assert(dir != NULL);
104 assert(root != NULL);
105 assert(fsopts != NULL);
107 TIMER_START(start);
108 chfs_validate(dir, root, fsopts);
109 TIMER_RESULTS(start, "chfs_validate");
111 printf("Creating `%s'\n", image);
112 TIMER_START(start);
113 if (chfs_create_image(image, fsopts) == -1) {
114 errx(EXIT_FAILURE, "Image file `%s' not created", image);
116 TIMER_RESULTS(start, "chfs_create_image");
118 fsopts->curinode = CHFS_ROOTINO;
119 root->inode->ino = CHFS_ROOTINO;
121 printf("Populating `%s'\n", image);
122 TIMER_START(start);
123 write_eb_header(fsopts);
124 if (!chfs_populate_dir(dir, root, root, fsopts)) {
125 errx(EXIT_FAILURE, "Image file `%s' not populated", image);
127 TIMER_RESULTS(start, "chfs_populate_dir");
129 padblock(fsopts);
131 if (close(fsopts->fd) == -1) {
132 err(EXIT_FAILURE, "Closing `%s'", image);
134 fsopts->fd = -1;
136 printf("Image `%s' complete\n", image);
139 static void
140 chfs_validate(const char* dir, fsnode *root, fsinfo_t *fsopts)
142 chfs_opt_t *chfs_opts;
143 assert(dir != NULL);
144 assert(root != NULL);
145 assert(fsopts != NULL);
147 chfs_opts = fsopts->fs_specific;
149 if (chfs_opts->pagesize == -1) {
150 chfs_opts->pagesize = DEFAULT_PAGESIZE;
152 if (chfs_opts->eraseblock == -1) {
153 chfs_opts->eraseblock = DEFAULT_ERASEBLOCK;
155 if (chfs_opts->mediatype == -1) {
156 chfs_opts->mediatype = DEFAULT_MEDIATYPE;
160 static int
161 chfs_create_image(const char *image, fsinfo_t *fsopts)
163 assert(image != NULL);
164 assert(fsopts != NULL);
166 if ((fsopts->fd = open(image, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1) {
167 warn("Can't open `%s' for writing", image);
168 return -1;
171 return fsopts->fd;
174 static int
175 chfs_populate_dir(const char *dir, fsnode *root, fsnode *parent,
176 fsinfo_t *fsopts)
178 fsnode *cur;
179 char path[MAXPATHLEN + 1];
181 assert(dir != NULL);
182 assert(root != NULL);
183 assert(fsopts != NULL);
185 for (cur = root->next; cur != NULL; cur = cur->next) {
186 if ((cur->inode->flags & FI_ALLOCATED) == 0) {
187 cur->inode->flags |= FI_ALLOCATED;
188 if (cur != root) {
189 fsopts->curinode++;
190 cur->inode->ino = fsopts->curinode;
191 cur->parent = parent;
195 if (cur->inode->flags & FI_WRITTEN) {
196 continue; // hard link
198 cur->inode->flags |= FI_WRITTEN;
200 write_vnode(fsopts, cur);
201 write_dirent(fsopts, cur);
202 if (!S_ISDIR(cur->type & S_IFMT)) {
203 write_file(fsopts, cur, dir);
207 for (cur = root; cur != NULL; cur = cur->next) {
208 if (cur->child == NULL) {
209 continue;
211 if ((size_t)snprintf(path, sizeof(path), "%s/%s", dir,
212 cur->name) >= sizeof(path)) {
213 errx(EXIT_FAILURE, "Pathname too long");
215 if (!chfs_populate_dir(path, cur->child, cur, fsopts)) {
216 return 0;
220 return 1;