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 /* 78 * Don't be silly - the bootstrap has no business writing anything. 79 */ 80 static int 81 host_write(struct open_file *f, void *start, size_t size, size_t *resid) 82 { 83 84 return (EROFS); 85 } 86 87 static off_t 88 host_seek(struct open_file *f, off_t offset, int where) 89 { 90 91 return (CALLBACK(seek, f->f_fsdata, offset, where)); 92 } 93 94 static int 95 host_stat(struct open_file *f, struct stat *sb) 96 { 97 int mode; 98 int uid; 99 int gid; 100 uint64_t size; 101 102 CALLBACK(stat, f->f_fsdata, &mode, &uid, &gid, &size); 103 sb->st_mode = mode; 104 sb->st_uid = uid; 105 sb->st_gid = gid; 106 sb->st_size = size; 107 return (0); 108 } 109 110 static int 111 host_readdir(struct open_file *f, struct dirent *d) 112 { 113 uint32_t fileno; 114 uint8_t type; 115 size_t namelen; 116 int rc; 117 118 rc = CALLBACK(readdir, f->f_fsdata, &fileno, &type, &namelen, 119 d->d_name); 120 if (rc) 121 return (rc); 122 123 d->d_fileno = fileno; 124 d->d_type = type; 125 d->d_namlen = namelen; 126 127 return (0); 128 } 129 130 static int 131 host_dev_init(void) 132 { 133 134 return (0); 135 } 136 137 static int 138 host_dev_print(int verbose) 139 { 140 char line[80]; 141 142 printf("%s devices:", host_dev.dv_name); 143 if (pager_output("\n") != 0) 144 return (1); 145 146 snprintf(line, sizeof(line), " host%d: Host filesystem\n", 0); 147 return (pager_output(line)); 148 } 149 150 /* 151 * 'Open' the host device. 152 */ 153 static int 154 host_dev_open(struct open_file *f, ...) 155 { 156 va_list args; 157 struct devdesc *dev; 158 159 va_start(args, f); 160 dev = va_arg(args, struct devdesc*); 161 va_end(args); 162 163 return (0); 164 } 165 166 static int 167 host_dev_close(struct open_file *f) 168 { 169 170 return (0); 171 } 172 173 static int 174 host_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, 175 char *buf, size_t *rsize) 176 { 177 178 return (ENOSYS); 179 } 180 181 struct fs_ops host_fsops = { 182 "host", 183 host_open, 184 host_close, 185 host_read, 186 host_write, 187 host_seek, 188 host_stat, 189 host_readdir 190 }; 191 192 struct devsw host_dev = { 193 .dv_name = "host", 194 .dv_type = DEVT_NET, 195 .dv_init = host_dev_init, 196 .dv_strategy = host_dev_strategy, 197 .dv_open = host_dev_open, 198 .dv_close = host_dev_close, 199 .dv_ioctl = noioctl, 200 .dv_print = host_dev_print, 201 .dv_cleanup = NULL 202 }; 203