[BACK]Return to msdos.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / makefs

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>