/*- * Copyright (c) 2011 Google, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); /* * Read from the host filesystem */ #include #include #include #include #include #include #include #include "libuserboot.h" /* * Open a file. */ static int host_open(const char *upath, struct open_file *f) { if (f->f_dev != &host_dev) return (EINVAL); return (CALLBACK(open, upath, &f->f_fsdata)); } static int host_close(struct open_file *f) { CALLBACK(close, f->f_fsdata); f->f_fsdata = (void *)0; return (0); } /* * Copy a portion of a file into memory. */ static int host_read(struct open_file *f, void *start, size_t size, size_t *resid) { return (CALLBACK(read, f->f_fsdata, start, size, resid)); } /* * Don't be silly - the bootstrap has no business writing anything. */ static int host_write(struct open_file *f, void *start, size_t size, size_t *resid) { return (EROFS); } static off_t host_seek(struct open_file *f, off_t offset, int where) { return (CALLBACK(seek, f->f_fsdata, offset, where)); } static int host_stat(struct open_file *f, struct stat *sb) { int mode; int uid; int gid; uint64_t size; CALLBACK(stat, f->f_fsdata, &mode, &uid, &gid, &size); sb->st_mode = mode; sb->st_uid = uid; sb->st_gid = gid; sb->st_size = size; return (0); } static int host_readdir(struct open_file *f, struct dirent *d) { uint32_t fileno; uint8_t type; size_t namelen; int rc; rc = CALLBACK(readdir, f->f_fsdata, &fileno, &type, &namelen, d->d_name); if (rc) return (rc); d->d_fileno = fileno; d->d_type = type; d->d_namlen = namelen; return (0); } static int host_dev_init(void) { return (0); } static void host_dev_print(int verbose) { char line[80]; sprintf(line, " host%d: Host filesystem\n", 0); pager_output(line); } /* * 'Open' the host device. */ static int host_dev_open(struct open_file *f, ...) { va_list args; struct devdesc *dev; va_start(args, f); dev = va_arg(args, struct devdesc*); va_end(args); return (0); } static int host_dev_close(struct open_file *f) { return (0); } static int host_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize) { return (ENOSYS); } struct fs_ops host_fsops = { "host", host_open, host_close, host_read, host_write, host_seek, host_stat, host_readdir }; struct devsw host_dev = { .dv_name = "host", .dv_type = DEVT_NET, .dv_init = host_dev_init, .dv_strategy = host_dev_strategy, .dv_open = host_dev_open, .dv_close = host_dev_close, .dv_ioctl = noioctl, .dv_print = host_dev_print, .dv_cleanup = NULL };