misc.c revision 1.5
1/* $NetBSD: misc.c,v 1.5 2009/07/20 04:59:03 kiyohara Exp $ */ 2 3/*- 4 * Copyright (c) 1998 Michael Smith <msmith@freebsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30/* __FBSDID("$FreeBSD: src/sys/boot/common/misc.c,v 1.8.4.1 2004/09/03 19:25:40 iedowse Exp $"); */ 31 32#include <lib/libsa/stand.h> 33#include <lib/libsa/loadfile.h> 34#include <bootstrap.h> 35 36/* 37 * Concatenate the (argc) elements of (argv) into a single string, and return 38 * a copy of same. 39 */ 40char * 41unargv(int argc, char *argv[]) 42{ 43 size_t hlong; 44 int i; 45 char *cp; 46 47 for (hlong = 0, i = 0, hlong = 0; i < argc; i++) 48 hlong += strlen(argv[i]) + 2; 49 50 if(hlong == 0) 51 return(NULL); 52 53 cp = alloc(hlong); 54 cp[0] = 0; 55 for (i = 0; i < argc; i++) { 56 strcat(cp, argv[i]); 57 if (i < (argc - 1)) 58 strcat(cp, " "); 59 } 60 61 return(cp); 62} 63 64/* 65 * Get the length of a string in kernel space 66 */ 67size_t 68strlenout(vaddr_t src) 69{ 70 char c; 71 size_t len; 72 73 for (len = 0; ; len++) { 74 archsw.arch_copyout(src++, &c, 1); 75 if (c == 0) 76 break; 77 } 78 return(len); 79} 80 81/* 82 * Make a duplicate copy of a string in kernel space 83 */ 84char * 85strdupout(vaddr_t str) 86{ 87 char *result, *cp; 88 89 result = alloc(strlenout(str) + 1); 90 for (cp = result; ;cp++) { 91 archsw.arch_copyout(str++, cp, 1); 92 if (*cp == 0) 93 break; 94 } 95 return(result); 96} 97 98/* Zero a region in kernel space. */ 99void 100kern_bzero(vaddr_t dest, size_t len) 101{ 102 char buf[256]; 103 size_t chunk, resid; 104 105 memset(buf, 0, sizeof(buf)); 106 resid = len; 107 while (resid > 0) { 108 chunk = min(sizeof(buf), resid); 109 archsw.arch_copyin(buf, dest, chunk); 110 resid -= chunk; 111 dest += chunk; 112 } 113} 114 115/* 116 * Read the specified part of a file to kernel space. Unlike regular 117 * pread, the file pointer is advanced to the end of the read data, 118 * and it just returns 0 if successful. 119 */ 120int 121kern_pread(int fd, vaddr_t dest, size_t len, off_t off) 122{ 123 ssize_t nread; 124 125 if (lseek(fd, off, SEEK_SET) == -1) { 126 printf("\nlseek failed\n"); 127 return (-1); 128 } 129 nread = archsw.arch_readin(fd, dest, len); 130 if (nread != len) { 131 printf("\nreadin failed\n"); 132 return (-1); 133 } 134 return (0); 135} 136 137/* 138 * Read the specified part of a file to a malloced buffer. The file 139 * pointer is advanced to the end of the read data. 140 */ 141void * 142alloc_pread(int fd, off_t off, size_t len) 143{ 144 void *buf; 145 ssize_t nread; 146 147 buf = alloc(len); 148 if (buf == NULL) { 149 printf("\nalloc(%d) failed\n", (int)len); 150 return (NULL); 151 } 152 if (lseek(fd, off, SEEK_SET) == -1) { 153 printf("\nlseek failed\n"); 154 free(buf); 155 return (NULL); 156 } 157 nread = read(fd, buf, len); 158 if (nread != len) { 159 printf("\nread failed\n"); 160 free(buf); 161 return (NULL); 162 } 163 return (buf); 164} 165 166/* 167 * Display a region in traditional hexdump format. 168 */ 169void 170hexdump(void *region, size_t len) 171{ 172 void * line; 173 int x, c; 174 char lbuf[80]; 175#define emit(fmt, args...) {sprintf(lbuf, fmt , ## args); pager_output(lbuf);} 176 177 pager_open(); 178 for (line = region; line < (region + len); line += 16) { 179 emit("%08lx ", (long) line); 180 181 for (x = 0; x < 16; x++) { 182 if ((line + x) < (region + len)) { 183 emit("%02x ", *(u_int8_t *)(line + x)); 184 } else { 185 emit("-- "); 186 } 187 if (x == 7) 188 emit(" "); 189 } 190 emit(" |"); 191 for (x = 0; x < 16; x++) { 192 if ((line + x) < (region + len)) { 193 c = *(u_int8_t *)(line + x); 194 if ((c < ' ') || (c > '~')) /* !isprint(c) */ 195 c = '.'; 196 emit("%c", c); 197 } else { 198 emit(" "); 199 } 200 } 201 emit("|\n"); 202 } 203 pager_close(); 204} 205 206void 207dev_cleanup(void) 208{ 209 210} 211