138465Smsmith/*-
238465Smsmith * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
338465Smsmith * All rights reserved.
438465Smsmith *
538465Smsmith * Redistribution and use in source and binary forms, with or without
638465Smsmith * modification, are permitted provided that the following conditions
738465Smsmith * are met:
838465Smsmith * 1. Redistributions of source code must retain the above copyright
938465Smsmith *    notice, this list of conditions and the following disclaimer.
1038465Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1138465Smsmith *    notice, this list of conditions and the following disclaimer in the
1238465Smsmith *    documentation and/or other materials provided with the distribution.
1338465Smsmith *
1438465Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1538465Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1638465Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1738465Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1838465Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1938465Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2038465Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2138465Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2238465Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2338465Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2438465Smsmith * SUCH DAMAGE.
2538465Smsmith */
2638465Smsmith
27119483Sobrien#include <sys/cdefs.h>
28119483Sobrien__FBSDID("$FreeBSD: stable/11/stand/common/misc.c 332154 2018-04-06 21:37:25Z kevans $");
29119483Sobrien
3038465Smsmith#include <string.h>
3138465Smsmith#include <stand.h>
3238764Smsmith#include <bootstrap.h>
3338465Smsmith
3438465Smsmith/*
3538465Smsmith * Concatenate the (argc) elements of (argv) into a single string, and return
3638465Smsmith * a copy of same.
3738465Smsmith */
3838465Smsmithchar *
3938465Smsmithunargv(int argc, char *argv[])
4038465Smsmith{
4138465Smsmith    size_t	hlong;
4238465Smsmith    int		i;
4338465Smsmith    char	*cp;
4438465Smsmith
45181278Scperciva    for (i = 0, hlong = 0; i < argc; i++)
4639968Smsmith	hlong += strlen(argv[i]) + 2;
4738465Smsmith
4838465Smsmith    if(hlong == 0)
4938465Smsmith	return(NULL);
5038465Smsmith
5138465Smsmith    cp = malloc(hlong);
5238465Smsmith    cp[0] = 0;
5339968Smsmith    for (i = 0; i < argc; i++) {
5438465Smsmith	strcat(cp, argv[i]);
5539968Smsmith	if (i < (argc - 1))
5639968Smsmith	  strcat(cp, " ");
5739968Smsmith    }
5839968Smsmith
5938465Smsmith    return(cp);
6038465Smsmith}
6138465Smsmith
6238764Smsmith/*
6338764Smsmith * Get the length of a string in kernel space
6438764Smsmith */
6538764Smsmithsize_t
6638764Smsmithstrlenout(vm_offset_t src)
6738764Smsmith{
6838764Smsmith    char	c;
6938764Smsmith    size_t	len;
7038764Smsmith
7138764Smsmith    for (len = 0; ; len++) {
7238764Smsmith	archsw.arch_copyout(src++, &c, 1);
7338764Smsmith	if (c == 0)
7438764Smsmith	    break;
7538764Smsmith    }
7638764Smsmith    return(len);
7738764Smsmith}
7838764Smsmith
7938764Smsmith/*
8038764Smsmith * Make a duplicate copy of a string in kernel space
8138764Smsmith */
8238764Smsmithchar *
8338764Smsmithstrdupout(vm_offset_t str)
8438764Smsmith{
8538764Smsmith    char	*result, *cp;
8638764Smsmith
8738764Smsmith    result = malloc(strlenout(str) + 1);
8838764Smsmith    for (cp = result; ;cp++) {
8938764Smsmith	archsw.arch_copyout(str++, cp, 1);
9038764Smsmith	if (*cp == 0)
9138764Smsmith	    break;
9238764Smsmith    }
9338764Smsmith    return(result);
9438764Smsmith}
9539472Smsmith
96134441Siedowse/* Zero a region in kernel space. */
97134441Siedowsevoid
98134441Siedowsekern_bzero(vm_offset_t dest, size_t len)
99134441Siedowse{
100134441Siedowse	char buf[256];
101134441Siedowse	size_t chunk, resid;
102134441Siedowse
103134441Siedowse	bzero(buf, sizeof(buf));
104134441Siedowse	resid = len;
105134441Siedowse	while (resid > 0) {
106134441Siedowse		chunk = min(sizeof(buf), resid);
107134441Siedowse		archsw.arch_copyin(buf, dest, chunk);
108134441Siedowse		resid -= chunk;
109134441Siedowse		dest += chunk;
110134441Siedowse	}
111134441Siedowse}
112134441Siedowse
11339472Smsmith/*
114134441Siedowse * Read the specified part of a file to kernel space.  Unlike regular
115134441Siedowse * pread, the file pointer is advanced to the end of the read data,
116134441Siedowse * and it just returns 0 if successful.
117134441Siedowse */
118134441Siedowseint
119134441Siedowsekern_pread(int fd, vm_offset_t dest, size_t len, off_t off)
120134441Siedowse{
121134441Siedowse
122134441Siedowse	if (lseek(fd, off, SEEK_SET) == -1) {
123274127Smarcel#ifdef DEBUG
124134441Siedowse		printf("\nlseek failed\n");
125274127Smarcel#endif
126134441Siedowse		return (-1);
127134441Siedowse	}
128293724Ssmh	if ((size_t)archsw.arch_readin(fd, dest, len) != len) {
129274127Smarcel#ifdef DEBUG
130134441Siedowse		printf("\nreadin failed\n");
131274127Smarcel#endif
132134441Siedowse		return (-1);
133134441Siedowse	}
134134441Siedowse	return (0);
135134441Siedowse}
136134441Siedowse
137134441Siedowse/*
138134441Siedowse * Read the specified part of a file to a malloced buffer.  The file
139134441Siedowse * pointer is advanced to the end of the read data.
140134441Siedowse */
141329183Skevans/* coverity[ -tainted_data_return ] */
142134441Siedowsevoid *
143134441Siedowsealloc_pread(int fd, off_t off, size_t len)
144134441Siedowse{
145134441Siedowse	void *buf;
146134441Siedowse
147134441Siedowse	buf = malloc(len);
148134441Siedowse	if (buf == NULL) {
149274127Smarcel#ifdef DEBUG
150134441Siedowse		printf("\nmalloc(%d) failed\n", (int)len);
151274127Smarcel#endif
152134441Siedowse		return (NULL);
153134441Siedowse	}
154134441Siedowse	if (lseek(fd, off, SEEK_SET) == -1) {
155274127Smarcel#ifdef DEBUG
156134441Siedowse		printf("\nlseek failed\n");
157274127Smarcel#endif
158134441Siedowse		free(buf);
159134441Siedowse		return (NULL);
160134441Siedowse	}
161293724Ssmh	if ((size_t)read(fd, buf, len) != len) {
162274127Smarcel#ifdef DEBUG
163134441Siedowse		printf("\nread failed\n");
164274127Smarcel#endif
165134441Siedowse		free(buf);
166134441Siedowse		return (NULL);
167134441Siedowse	}
168134441Siedowse	return (buf);
169134441Siedowse}
170134441Siedowse
171134441Siedowse/*
17239472Smsmith * Display a region in traditional hexdump format.
17339472Smsmith */
17439472Smsmithvoid
17539472Smsmithhexdump(caddr_t region, size_t len)
17639472Smsmith{
17739472Smsmith    caddr_t	line;
17839472Smsmith    int		x, c;
17939472Smsmith    char	lbuf[80];
18039472Smsmith#define emit(fmt, args...)	{sprintf(lbuf, fmt , ## args); pager_output(lbuf);}
18139472Smsmith
18239472Smsmith    pager_open();
18339472Smsmith    for (line = region; line < (region + len); line += 16) {
18439673Sdfr	emit("%08lx  ", (long) line);
18539472Smsmith
18639472Smsmith	for (x = 0; x < 16; x++) {
18739472Smsmith	    if ((line + x) < (region + len)) {
188332154Skevans		emit("%02x ", *(uint8_t *)(line + x));
18939472Smsmith	    } else {
19039472Smsmith		emit("-- ");
19139472Smsmith	    }
19239472Smsmith	    if (x == 7)
19339472Smsmith		emit(" ");
19439472Smsmith	}
19539472Smsmith	emit(" |");
19639472Smsmith	for (x = 0; x < 16; x++) {
19739472Smsmith	    if ((line + x) < (region + len)) {
198332154Skevans		c = *(uint8_t *)(line + x);
19939472Smsmith		if ((c < ' ') || (c > '~'))	/* !isprint(c) */
20039472Smsmith		    c = '.';
20139472Smsmith		emit("%c", c);
20239472Smsmith	    } else {
20339472Smsmith		emit(" ");
20439472Smsmith	    }
20539472Smsmith	}
20639472Smsmith	emit("|\n");
20739472Smsmith    }
20839472Smsmith    pager_close();
20939472Smsmith}
21061659Sps
21161659Spsvoid
21261659Spsdev_cleanup(void)
21361659Sps{
21461659Sps    int		i;
21561659Sps
21661659Sps    /* Call cleanup routines */
21761659Sps    for (i = 0; devsw[i] != NULL; ++i)
21861659Sps	if (devsw[i]->dv_cleanup != NULL)
21961659Sps	    (devsw[i]->dv_cleanup)();
22061659Sps}
221