1 1.4 joerg /* $NetBSD: prephandlers.c,v 1.4 2013/07/02 11:59:46 joerg Exp $ */ 2 1.1 garbled 3 1.1 garbled /*- 4 1.1 garbled * Copyright (c) 2006 The NetBSD Foundation, Inc. 5 1.1 garbled * All rights reserved. 6 1.1 garbled * 7 1.1 garbled * This code is derived from software contributed to The NetBSD Foundation 8 1.1 garbled * by Tim Rightnour. 9 1.1 garbled * 10 1.1 garbled * Redistribution and use in source and binary forms, with or without 11 1.1 garbled * modification, are permitted provided that the following conditions 12 1.1 garbled * are met: 13 1.1 garbled * 1. Redistributions of source code must retain the above copyright 14 1.1 garbled * notice, this list of conditions and the following disclaimer. 15 1.1 garbled * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 garbled * notice, this list of conditions and the following disclaimer in the 17 1.1 garbled * documentation and/or other materials provided with the distribution. 18 1.1 garbled * 19 1.1 garbled * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 garbled * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 garbled * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 garbled * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 garbled * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 garbled * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 garbled * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 garbled * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 garbled * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 garbled * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 garbled * POSSIBILITY OF SUCH DAMAGE. 30 1.1 garbled */ 31 1.1 garbled 32 1.1 garbled #include <sys/types.h> 33 1.1 garbled #include <sys/ioctl.h> 34 1.1 garbled #include <err.h> 35 1.1 garbled #include <errno.h> 36 1.1 garbled #include <fcntl.h> 37 1.1 garbled #include <string.h> 38 1.1 garbled #include <stdio.h> 39 1.1 garbled #include <string.h> 40 1.1 garbled #include <unistd.h> 41 1.1 garbled 42 1.1 garbled #include <machine/nvram.h> 43 1.1 garbled 44 1.1 garbled #include "defs.h" 45 1.1 garbled 46 1.1 garbled extern char *path_prepnvram; 47 1.1 garbled extern int eval; 48 1.1 garbled extern int verbose; 49 1.1 garbled 50 1.1 garbled static char err_str[BUFSIZE]; 51 1.1 garbled 52 1.4 joerg static void prep_notsupp(const struct extabent *, struct pnviocdesc *, char *); 53 1.1 garbled 54 1.1 garbled /* 55 1.1 garbled * XXX 56 1.1 garbled * This file needs a recalc checksum routine, and a routine to call a 57 1.1 garbled * write back to nvram. The prep NVRAM is stored in RAM after boot, to 58 1.1 garbled * prevent horrific bitbanging on the NVRAM chip, we read and write into RAM 59 1.1 garbled * until a save operation is called. At that time we write the ram-based 60 1.1 garbled * NVRAM back to the physical NVRAM. This is a fairly expensive operation. 61 1.1 garbled */ 62 1.1 garbled 63 1.1 garbled 64 1.1 garbled /* 65 1.1 garbled * There are several known fields that I either don't know how to 66 1.1 garbled * deal with or require special treatment. 67 1.1 garbled */ 68 1.4 joerg static const struct extabent prepextab[] = { 69 1.1 garbled {NULL, prep_notsupp}, 70 1.1 garbled }; 71 1.1 garbled #define BARF(str1, str2) { \ 72 1.1 garbled snprintf(err_str, sizeof err_str, "%s: %s", (str1), (str2)); \ 73 1.1 garbled ++eval; \ 74 1.1 garbled return (err_str); \ 75 1.1 garbled }; 76 1.1 garbled 77 1.1 garbled void 78 1.1 garbled prep_action(char *keyword, char *arg) 79 1.1 garbled { 80 1.1 garbled char *cp; 81 1.1 garbled 82 1.1 garbled if ((cp = prep_handler(keyword, arg)) != NULL) 83 1.1 garbled warnx("%s", cp); 84 1.1 garbled return; 85 1.1 garbled } 86 1.1 garbled 87 1.1 garbled char * 88 1.1 garbled prep_handler(char *keyword, char *arg) 89 1.1 garbled { 90 1.1 garbled struct pnviocdesc nvio; 91 1.4 joerg const struct extabent *ex; 92 1.1 garbled char nvio_buf[BUFSIZE]; 93 1.1 garbled int fd; 94 1.1 garbled 95 1.1 garbled if ((fd = open(path_prepnvram, arg ? O_RDWR : O_RDONLY, 0640)) < 0) 96 1.1 garbled BARF(path_prepnvram, strerror(errno)); 97 1.1 garbled 98 1.1 garbled /* Check to see if it's a special-case keyword. */ 99 1.1 garbled for (ex = prepextab; ex->ex_keyword != NULL; ++ex) 100 1.1 garbled if (strcmp(ex->ex_keyword, keyword) == 0) 101 1.1 garbled break; 102 1.1 garbled 103 1.1 garbled memset(&nvio_buf[0], 0, sizeof(nvio_buf)); 104 1.1 garbled memset(&nvio, 0, sizeof(nvio)); 105 1.1 garbled nvio.pnv_name = keyword; 106 1.1 garbled nvio.pnv_namelen = strlen(nvio.pnv_name); 107 1.1 garbled 108 1.1 garbled if (arg) { 109 1.1 garbled if (verbose) { 110 1.1 garbled printf("old: "); 111 1.1 garbled 112 1.1 garbled nvio.pnv_buf = &nvio_buf[0]; 113 1.1 garbled nvio.pnv_buflen = sizeof(nvio_buf); 114 1.3 wiz if (ioctl(fd, PNVIOCGET, (char *) &nvio) < 0) { 115 1.3 wiz (void)close(fd); 116 1.1 garbled BARF("PNVIOCGET", strerror(errno)); 117 1.3 wiz } 118 1.1 garbled 119 1.1 garbled if (nvio.pnv_buflen <= 0) { 120 1.1 garbled printf("nothing available for %s\n", keyword); 121 1.1 garbled goto out; 122 1.1 garbled } 123 1.1 garbled if (ex->ex_keyword != NULL) 124 1.1 garbled (*ex->ex_handler) (ex, &nvio, NULL); 125 1.1 garbled else 126 1.1 garbled printf("%s\n", nvio.pnv_buf); 127 1.1 garbled } 128 1.1 garbled out: 129 1.1 garbled if (ex->ex_keyword != NULL) 130 1.1 garbled (*ex->ex_handler) (ex, &nvio, arg); 131 1.1 garbled else { 132 1.1 garbled nvio.pnv_buf = arg; 133 1.1 garbled nvio.pnv_buflen = strlen(arg); 134 1.1 garbled } 135 1.1 garbled 136 1.3 wiz if (ioctl(fd, PNVIOCSET, (char *) &nvio) < 0) { 137 1.3 wiz (void)close(fd); 138 1.1 garbled BARF("invalid keyword", keyword); 139 1.3 wiz } 140 1.1 garbled 141 1.1 garbled if (verbose) { 142 1.1 garbled printf("new: "); 143 1.1 garbled if (ex->ex_keyword != NULL) 144 1.1 garbled (*ex->ex_handler) (ex, &nvio, NULL); 145 1.1 garbled else 146 1.1 garbled printf("%s\n", nvio.pnv_buf); 147 1.1 garbled } 148 1.1 garbled } else { 149 1.1 garbled nvio.pnv_buf = &nvio_buf[0]; 150 1.1 garbled nvio.pnv_buflen = sizeof(nvio_buf); 151 1.3 wiz if (ioctl(fd, PNVIOCGET, (char *) &nvio) < 0) { 152 1.3 wiz (void)close(fd); 153 1.1 garbled BARF("PNVIOCGET", strerror(errno)); 154 1.3 wiz } 155 1.1 garbled 156 1.1 garbled if (nvio.pnv_buflen <= 0) { 157 1.1 garbled (void) snprintf(err_str, sizeof err_str, 158 1.1 garbled "nothing available for %s", keyword); 159 1.1 garbled return (err_str); 160 1.1 garbled } 161 1.1 garbled if (ex->ex_keyword != NULL) 162 1.1 garbled (*ex->ex_handler) (ex, &nvio, NULL); 163 1.1 garbled else 164 1.1 garbled printf("%s=%s\n", keyword, nvio.pnv_buf); 165 1.1 garbled } 166 1.1 garbled 167 1.1 garbled (void) close(fd); 168 1.1 garbled return (NULL); 169 1.1 garbled } 170 1.1 garbled /* ARGSUSED */ 171 1.1 garbled static void 172 1.4 joerg prep_notsupp(const struct extabent * exent, struct pnviocdesc * nviop, char *arg) 173 1.1 garbled { 174 1.1 garbled 175 1.1 garbled warnx("property `%s' not yet supported", exent->ex_keyword); 176 1.1 garbled } 177 1.1 garbled /* 178 1.1 garbled * Derrived from op_dump(). This should dump the contents of the PReP 179 1.1 garbled * NVRAM chip. 180 1.1 garbled */ 181 1.1 garbled 182 1.1 garbled void 183 1.4 joerg prep_dump(void) 184 1.1 garbled { 185 1.1 garbled struct pnviocdesc nvio1, nvio2; 186 1.1 garbled char buf1[BUFSIZE], buf2[BUFSIZE], buf3[BUFSIZE], buf4[BUFSIZE]; 187 1.1 garbled int fd, optnode, nrofvars; 188 1.1 garbled 189 1.1 garbled if ((fd = open(path_prepnvram, O_RDONLY, 0640)) < 0) 190 1.1 garbled err(1, "open: %s", path_prepnvram); 191 1.1 garbled 192 1.1 garbled memset(&nvio1, 0, sizeof(nvio1)); 193 1.1 garbled 194 1.1 garbled if (ioctl(fd, PNVIOCGETNUMGE, (char *) &nvio1) < 0) 195 1.1 garbled err(1, "PNVIOCGETNUMGE"); 196 1.1 garbled 197 1.1 garbled nrofvars = nvio1.pnv_num; 198 1.1 garbled if (nrofvars < 1) 199 1.1 garbled err(1, "PNVIOCGETNUMGE"); 200 1.1 garbled 201 1.1 garbled memset(&nvio1, 0, sizeof(nvio1)); 202 1.1 garbled memset(buf1, 0, sizeof(buf1)); 203 1.1 garbled memset(buf2, 0, sizeof(buf2)); 204 1.1 garbled memset(buf3, 0, sizeof(buf3)); 205 1.1 garbled memset(buf4, 0, sizeof(buf4)); 206 1.1 garbled nvio1.pnv_name = NULL; 207 1.1 garbled nvio1.pnv_buf = buf2; 208 1.1 garbled nvio2.pnv_name = buf3; 209 1.1 garbled nvio2.pnv_buf = buf4; 210 1.1 garbled for (optnode = 0; optnode < nrofvars; optnode++) { 211 1.1 garbled nvio1.pnv_buflen = sizeof(buf2); 212 1.1 garbled 213 1.1 garbled if (ioctl(fd, PNVIOCGETNEXTNAME, (char *) &nvio1) < 0) 214 1.1 garbled err(1, "PNVIOCGETNEXTNAME"); 215 1.1 garbled 216 1.1 garbled if (optnode == 0) 217 1.1 garbled nvio1.pnv_name = buf1; 218 1.1 garbled 219 1.1 garbled /* the property name is now stored in nvio1.pnv_buf */ 220 1.1 garbled strcpy(nvio2.pnv_name, nvio1.pnv_buf); /* safe */ 221 1.1 garbled nvio2.pnv_namelen = strlen(nvio2.pnv_name); 222 1.1 garbled 223 1.1 garbled if (nvio2.pnv_namelen == 0) { 224 1.1 garbled (void) close(fd); 225 1.1 garbled return; 226 1.1 garbled } 227 1.1 garbled memset(nvio2.pnv_buf, 0, sizeof(buf4)); 228 1.1 garbled nvio2.pnv_buflen = sizeof(buf4); 229 1.1 garbled 230 1.1 garbled if (ioctl(fd, PNVIOCGET, (char *) &nvio2) < 0) 231 1.1 garbled err(1, "PNVIOCGET"); 232 1.1 garbled 233 1.1 garbled printf("%s=%s\n", nvio1.pnv_buf, nvio2.pnv_buf); 234 1.1 garbled 235 1.1 garbled /* now clean out the buffers for the next loop */ 236 1.1 garbled 237 1.1 garbled memset(nvio1.pnv_name, 0, sizeof(buf1)); 238 1.1 garbled memset(nvio1.pnv_buf, 0, sizeof(buf2)); 239 1.1 garbled strcpy(nvio1.pnv_name, nvio2.pnv_name); /* safe */ 240 1.1 garbled nvio1.pnv_namelen = strlen(nvio1.pnv_name); 241 1.1 garbled } 242 1.1 garbled close(fd); 243 1.1 garbled } 244