Annotation of src/usr.sbin/makefs/msdos.c, Revision 1.8
1.8 ! christos 1: /* $NetBSD: msdos.c,v 1.7 2013/01/27 15:35:45 christos Exp $ */
1.1 christos 2:
3: /*-
4: * Copyright (c) 2013 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Christos Zoulas.
9: *
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.
18: * 3. Neither the name of The NetBSD Foundation nor the names of its
19: * contributors may be used to endorse or promote products derived
20: * from this software without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32: * POSSIBILITY OF SUCH DAMAGE.
33: */
34: #if HAVE_NBTOOL_CONFIG_H
35: #include "nbtool_config.h"
36: #endif
37:
38: #include <sys/cdefs.h>
39: #if defined(__RCSID) && !defined(__lint)
1.8 ! christos 40: __RCSID("$NetBSD: msdos.c,v 1.7 2013/01/27 15:35:45 christos Exp $");
1.1 christos 41: #endif /* !__lint */
42:
43: #include <sys/param.h>
44:
45: #if !HAVE_NBTOOL_CONFIG_H
46: #include <sys/mount.h>
47: #endif
48:
49: #include <assert.h>
50: #include <errno.h>
51: #include <fcntl.h>
52: #include <stdarg.h>
53: #include <stdio.h>
54: #include <stdlib.h>
55: #include <string.h>
56: #include <unistd.h>
1.6 christos 57: #include <dirent.h>
1.1 christos 58:
1.6 christos 59: #include <ffs/buf.h>
60: #include <fs/msdosfs/denode.h>
1.1 christos 61: #include "makefs.h"
1.6 christos 62: #include "msdos.h"
1.1 christos 63: #include "mkfs_msdos.h"
64:
1.7 christos 65: extern int sectorsize; /* XXX: horrid */
66:
1.6 christos 67: static int msdos_populate_dir(const char *, struct denode *, fsnode *,
68: fsnode *, fsinfo_t *);
69:
1.1 christos 70: void
71: msdos_prep_opts(fsinfo_t *fsopts)
72: {
73: struct msdos_options *msdos_opts;
74:
75: if ((msdos_opts = calloc(1, sizeof(*msdos_opts))) == NULL)
76: err(1, "Allocating memory for msdos_options");
77:
78: fsopts->fs_specific = msdos_opts;
79: }
80:
81: void
82: msdos_cleanup_opts(fsinfo_t *fsopts)
83: {
84: if (fsopts->fs_specific)
85: free(fsopts->fs_specific);
86: }
87:
88: int
89: msdos_parse_opts(const char *option, fsinfo_t *fsopts)
90: {
91: struct msdos_options *msdos_opt = fsopts->fs_specific;
92:
93: option_t msdos_options[] = {
94: #define AOPT(_opt, _type, _name, _min, _desc) { \
95: .letter = _opt, \
96: .name = # _name, \
97: .type = _min == -1 ? OPT_STRPTR : \
98: (_min == -2 ? OPT_BOOL : \
99: (sizeof(_type) == 1 ? OPT_INT8 : \
100: (sizeof(_type) == 2 ? OPT_INT16 : \
101: (sizeof(_type) == 4 ? OPT_INT32 : OPT_INT64)))), \
102: .value = &msdos_opt->_name, \
103: .minimum = _min, \
104: .maximum = sizeof(_type) == 1 ? 0xff : \
105: (sizeof(_type) == 2 ? 0xffff : \
106: (sizeof(_type) == 4 ? 0xffffffff : 0xffffffffffffffffLL)), \
107: .desc = _desc, \
108: },
109: ALLOPTS
110: #undef AOPT
111: { .name = NULL }
112: };
1.5 christos 113: int rv;
1.1 christos 114:
115: assert(option != NULL);
116: assert(fsopts != NULL);
117: assert(msdos_opt != NULL);
118:
119: if (debug & DEBUG_FS_PARSE_OPTS)
120: printf("msdos_parse_opts: got `%s'\n", option);
121:
1.3 christos 122: rv = set_option(msdos_options, option);
1.5 christos 123: if (rv == -1)
1.3 christos 124: return rv;
125:
1.5 christos 126: if (strcmp(msdos_options[rv].name, "volume_id") == 0)
1.3 christos 127: msdos_opt->volume_id_set = 1;
1.5 christos 128: else if (strcmp(msdos_options[rv].name, "media_descriptor") == 0)
1.3 christos 129: msdos_opt->media_descriptor_set = 1;
1.5 christos 130: else if (strcmp(msdos_options[rv].name, "hidden_sectors") == 0)
1.3 christos 131: msdos_opt->hidden_sectors_set = 1;
1.5 christos 132: return 1;
1.1 christos 133: }
134:
135:
136: void
137: msdos_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts)
138: {
1.4 christos 139: struct msdos_options *msdos_opt = fsopts->fs_specific;
1.6 christos 140: struct vnode vp, rootvp;
141: struct timeval start;
142: struct msdosfsmount *pmp;
143:
144: assert(image != NULL);
145: assert(dir != NULL);
146: assert(root != NULL);
147: assert(fsopts != NULL);
1.4 christos 148:
149: /*
150: * XXX: pick up other options from the msdos specific ones?
151: * Is minsize right here?
152: */
153: msdos_opt->create_size = MAX(msdos_opt->create_size, fsopts->minsize);
1.7 christos 154: msdos_opt->bytes_per_sector = sectorsize = 512;
1.4 christos 155:
1.6 christos 156: /* create image */
157: printf("Creating `%s'\n", image);
158: TIMER_START(start);
1.4 christos 159: if (mkfs_msdos(image, NULL, msdos_opt) == -1)
160: return;
1.6 christos 161: TIMER_RESULTS(start, "mkfs_msdos");
162:
163: vp.fd = open(image, O_RDWR);
164: vp.fs = msdos_opt;
165:
166: if ((pmp = msdosfs_mount(&vp, 0)) == NULL)
167: err(1, "msdosfs_mount");
1.1 christos 168:
1.6 christos 169: if (msdosfs_root(pmp, &rootvp) != 0)
170: err(1, "msdosfs_root");
1.1 christos 171:
172: if (debug & DEBUG_FS_MAKEFS)
173: printf("msdos_makefs: image %s directory %s root %p\n",
174: image, dir, root);
175:
1.6 christos 176: /* populate image */
177: printf("Populating `%s'\n", image);
1.1 christos 178: TIMER_START(start);
1.6 christos 179: if (msdos_populate_dir(dir, VTODE(&rootvp), root, root, fsopts) == -1)
1.1 christos 180: errx(1, "Image file `%s' not created.", image);
1.6 christos 181: TIMER_RESULTS(start, "msdos_populate_dir");
1.1 christos 182:
183: if (debug & DEBUG_FS_MAKEFS)
184: putchar('\n');
185:
186: /* ensure no outstanding buffers remain */
187: if (debug & DEBUG_FS_MAKEFS)
188: bcleanup();
189:
190: printf("Image `%s' complete\n", image);
1.6 christos 191: }
192:
193: static int
194: msdos_populate_dir(const char *path, struct denode *dir, fsnode *root,
195: fsnode *parent, fsinfo_t *fsopts)
196: {
197: fsnode *cur;
198: char pbuf[MAXPATHLEN];
199:
200: assert(dir != NULL);
201: assert(root != NULL);
202: assert(fsopts != NULL);
203:
204: for (cur = root->next; cur != NULL; cur = cur->next) {
205: if ((size_t)snprintf(pbuf, sizeof(pbuf), "%s/%s", path,
206: cur->name) >= sizeof(pbuf)) {
207: warnx("path %s too long", pbuf);
208: return -1;
209: }
210:
211: if ((cur->inode->flags & FI_ALLOCATED) == 0) {
212: cur->inode->flags |= FI_ALLOCATED;
213: if (cur != root) {
214: fsopts->curinode++;
215: cur->inode->ino = fsopts->curinode;
216: cur->parent = parent;
217: }
218: }
219:
220: if (cur->inode->flags & FI_WRITTEN) {
221: continue; // hard link
222: }
223: cur->inode->flags |= FI_WRITTEN;
224:
225: if (cur->child) {
226: struct denode *de;
227: if ((de = msdosfs_mkdire(pbuf, dir, cur)) == NULL)
228: err(1, "msdosfs_mkdire");
229: if (!msdos_populate_dir(pbuf, de, cur->child, cur,
230: fsopts))
231: err(1, "populate_dir");
232: continue;
233: } else if (!S_ISREG(cur->type)) {
234: warnx("skipping non-regular file %s/%s", cur->path,
235: cur->name);
236: continue;
237: }
238: if (msdosfs_mkfile(pbuf, dir, cur) == NULL)
1.8 ! christos 239: err(1, "msdosfs_mkfile %s", pbuf);
1.6 christos 240: }
241: return 0;
1.1 christos 242: }
CVSweb <webmaster@jp.NetBSD.org>