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