1 /*- 2 * Copyright (c) 2011 Google, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 /* 31 * Read from the host filesystem 32 */ 33 34 #include <sys/param.h> 35 #include <sys/time.h> 36 #include <stddef.h> 37 #include <stdarg.h> 38 #include <string.h> 39 #include <stand.h> 40 #include <bootstrap.h> 41 42 #include "libuserboot.h" 43 44 /* 45 * Open a file. 46 */ 47 static int 48 host_open(const char *upath, struct open_file *f) 49 { 50 51 if (f->f_dev != &host_dev) 52 return (EINVAL); 53 54 return (CALLBACK(open, upath, &f->f_fsdata)); 55 } 56 57 static int 58 host_close(struct open_file *f) 59 { 60 61 CALLBACK(close, f->f_fsdata); 62 f->f_fsdata = (void *)0; 63 64 return (0); 65 } 66 67 /* 68 * Copy a portion of a file into memory. 69 */ 70 static int 71 host_read(struct open_file *f, void *start, size_t size, size_t *resid) 72 { 73 74 return (CALLBACK(read, f->f_fsdata, start, size, resid)); 75 } 76 77 static off_t 78 host_seek(struct open_file *f, off_t offset, int where) 79 { 80 81 return (CALLBACK(seek, f->f_fsdata, offset, where)); 82 } 83 84 static int 85 host_stat(struct open_file *f, struct stat *sb) 86 { 87 int mode; 88 int uid; 89 int gid; 90 uint64_t size; 91 92 CALLBACK(stat, f->f_fsdata, &mode, &uid, &gid, &size); 93 sb->st_mode = mode; 94 sb->st_uid = uid; 95 sb->st_gid = gid; 96 sb->st_size = size; 97 return (0); 98 } 99 100 static int 101 host_readdir(struct open_file *f, struct dirent *d) 102 { 103 uint32_t fileno; 104 uint8_t type; 105 size_t namelen; 106 int rc; 107 108 rc = CALLBACK(readdir, f->f_fsdata, &fileno, &type, &namelen, 109 d->d_name); 110 if (rc) 111 return (rc); 112 113 d->d_fileno = fileno; 114 d->d_type = type; 115 d->d_namlen = namelen; 116 117 return (0); 118 } 119 120 static int 121 host_dev_init(void) 122 { 123 124 return (0); 125 } 126 127 static int 128 host_dev_print(int verbose) 129 { 130 char line[80]; 131 132 printf("%s devices:", host_dev.dv_name); 133 if (pager_output("\n") != 0) 134 return (1); 135 136 snprintf(line, sizeof(line), " host%d: Host filesystem\n", 0); 137 return (pager_output(line)); 138 } 139 140 /* 141 * 'Open' the host device. 142 */ 143 static int 144 host_dev_open(struct open_file *f, ...) 145 { 146 va_list args; 147 struct devdesc *dev; 148 149 va_start(args, f); 150 dev = va_arg(args, struct devdesc*); 151 va_end(args); 152 153 return (0); 154 } 155 156 static int 157 host_dev_close(struct open_file *f) 158 { 159 160 return (0); 161 } 162 163 static int 164 host_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 165 char *buf, size_t *rsize) 166 { 167 168 return (ENOSYS); 169 } 170 171 struct fs_ops host_fsops = { 172 "host", 173 host_open, 174 host_close, 175 host_read, 176 null_write, 177 host_seek, 178 host_stat, 179 host_readdir 180 }; 181 182 struct devsw host_dev = { 183 .dv_name = "host", 184 .dv_type = DEVT_NET, 185 .dv_init = host_dev_init, 186 .dv_strategy = host_dev_strategy, 187 .dv_open = host_dev_open, 188 .dv_close = host_dev_close, 189 .dv_ioctl = noioctl, 190 .dv_print = host_dev_print, 191 .dv_cleanup = NULL 192 }; 193