boot1.c revision 212729
1139738Simp/*-
290699Srobert * Copyright (c) 1998 Robert Nordier
390699Srobert * All rights reserved.
490699Srobert * Copyright (c) 2001 Robert Drehmel
590699Srobert * All rights reserved.
690699Srobert *
790699Srobert * Redistribution and use in source and binary forms are freely
890699Srobert * permitted provided that the above copyright notice and this
990699Srobert * paragraph and the following disclaimer are duplicated in all
1090699Srobert * such forms.
1190699Srobert *
1290699Srobert * This software is provided "AS IS" and without any express or
1390699Srobert * implied warranties, including, without limitation, the implied
1490699Srobert * warranties of merchantability and fitness for a particular
1590699Srobert * purpose.
1690699Srobert */
1791295Srobert
1891295Srobert#include <sys/cdefs.h>
1991295Srobert__FBSDID("$FreeBSD: head/sys/boot/sparc64/boot1/boot1.c 212729 2010-09-16 12:05:00Z marius $");
2091295Srobert
2190699Srobert#include <sys/param.h>
2290699Srobert#include <sys/dirent.h>
2390699Srobert#include <machine/elf.h>
2490699Srobert#include <machine/stdarg.h>
2590699Srobert
2695337Sjake#define _PATH_LOADER	"/boot/loader"
2795337Sjake#define _PATH_KERNEL	"/boot/kernel/kernel"
2890699Srobert
29212729Smariustypedef int putc_func_t(char c, void *arg);
3095351Sjaketypedef int32_t ofwh_t;
3195351Sjake
3295351Sjakestruct sp_data {
3395351Sjake	char	*sp_buf;
3495351Sjake	u_int	sp_len;
3595351Sjake	u_int	sp_size;
3690699Srobert};
3790699Srobert
3895346Sjakestatic const char digits[] = "0123456789abcdef";
3990699Srobert
4095346Sjakestatic char bootpath[128];
4195346Sjakestatic char bootargs[128];
4295346Sjake
4395351Sjakestatic ofwh_t bootdev;
4495346Sjake
4590699Srobertstatic uint32_t fs_off;
4690699Srobert
4795346Sjakeint main(int ac, char **av);
4895346Sjake
4995351Sjakestatic void exit(int) __dead2;
5090699Srobertstatic void load(const char *);
5190699Srobertstatic int dskread(void *, u_int64_t, int);
5290699Srobert
5395351Sjakestatic void usage(void);
5495351Sjake
5595340Sjakestatic void bcopy(const void *src, void *dst, size_t len);
5695340Sjakestatic void bzero(void *b, size_t len);
5790699Srobert
5895351Sjakestatic int mount(const char *device);
5995351Sjake
6095351Sjakestatic void panic(const char *fmt, ...) __dead2;
6195346Sjakestatic int printf(const char *fmt, ...);
62212729Smariusstatic int putchar(char c, void *arg);
6395346Sjakestatic int vprintf(const char *fmt, va_list ap);
6495351Sjakestatic int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap);
6595346Sjake
6695346Sjakestatic int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap);
6795346Sjakestatic int __puts(const char *s, putc_func_t *putc, void *arg);
68212729Smariusstatic int __sputc(char c, void *arg);
6995346Sjakestatic char *__uitoa(char *buf, u_int val, int base);
7095346Sjakestatic char *__ultoa(char *buf, u_long val, int base);
7195346Sjake
7290699Srobert/*
7390699Srobert * Open Firmware interface functions
7490699Srobert */
7590699Sroberttypedef u_int64_t	ofwcell_t;
7690699Sroberttypedef u_int32_t	u_ofwh_t;
7790699Sroberttypedef int (*ofwfp_t)(ofwcell_t []);
78212729Smariusstatic ofwfp_t ofw;			/* the PROM Open Firmware entry */
7990699Srobert
8090699Srobertvoid ofw_init(int, int, int, int, ofwfp_t);
81212729Smariusstatic ofwh_t ofw_finddevice(const char *);
82212729Smariusstatic ofwh_t ofw_open(const char *);
83212729Smariusstatic int ofw_getprop(ofwh_t, const char *, void *, size_t);
84212729Smariusstatic int ofw_read(ofwh_t, void *, size_t);
85212729Smariusstatic int ofw_write(ofwh_t, const void *, size_t);
86212729Smariusstatic int ofw_seek(ofwh_t, u_int64_t);
87212729Smariusstatic void ofw_exit(void) __dead2;
8890699Srobert
89212729Smariusstatic ofwh_t stdinh, stdouth;
9090699Srobert
9190699Srobert/*
9290699Srobert * This has to stay here, as the PROM seems to ignore the
9390699Srobert * entry point specified in the a.out header.  (or elftoaout is broken)
9490699Srobert */
9590699Srobert
9690699Srobertvoid
9790699Srobertofw_init(int d, int d1, int d2, int d3, ofwfp_t ofwaddr)
9890699Srobert{
9990699Srobert	ofwh_t chosenh;
10095346Sjake	char *av[16];
10195346Sjake	char *p;
10295346Sjake	int ac;
10390699Srobert
10490699Srobert	ofw = ofwaddr;
10590699Srobert
10690699Srobert	chosenh = ofw_finddevice("/chosen");
10790699Srobert	ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh));
10890699Srobert	ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth));
10995346Sjake	ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs));
11090699Srobert	ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath));
11190699Srobert
11295346Sjake	bootargs[sizeof(bootargs) - 1] = '\0';
11395346Sjake	bootpath[sizeof(bootpath) - 1] = '\0';
11495346Sjake
11595346Sjake	ac = 0;
11695346Sjake	p = bootargs;
11795346Sjake	for (;;) {
11895346Sjake		while (*p == ' ' && *p != '\0')
11995346Sjake			p++;
12095346Sjake		if (*p == '\0' || ac >= 16)
12195346Sjake			break;
12295346Sjake		av[ac++] = p;
12395346Sjake		while (*p != ' ' && *p != '\0')
12495346Sjake			p++;
12595346Sjake		if (*p != '\0')
12695346Sjake			*p++ = '\0';
12795346Sjake	}
12895346Sjake
12995346Sjake	exit(main(ac, av));
13090699Srobert}
13190699Srobert
132212729Smariusstatic ofwh_t
13390699Srobertofw_finddevice(const char *name)
13490699Srobert{
13591295Srobert	ofwcell_t args[] = {
13691295Srobert		(ofwcell_t)"finddevice",
13791295Srobert		1,
13891295Srobert		1,
13991295Srobert		(ofwcell_t)name,
14091295Srobert		0
14191295Srobert	};
14291295Srobert
14391295Srobert	if ((*ofw)(args)) {
14491295Srobert		printf("ofw_finddevice: name=\"%s\"\n", name);
14591295Srobert		return (1);
14691295Srobert	}
14791295Srobert	return (args[4]);
14890699Srobert}
14990699Srobert
150212729Smariusstatic int
15190699Srobertofw_getprop(ofwh_t ofwh, const char *name, void *buf, size_t len)
15290699Srobert{
15391295Srobert	ofwcell_t args[] = {
15491295Srobert		(ofwcell_t)"getprop",
15591295Srobert		4,
15691295Srobert		1,
15791295Srobert		(u_ofwh_t)ofwh,
15891295Srobert		(ofwcell_t)name,
15991295Srobert		(ofwcell_t)buf,
16091295Srobert		len,
16190699Srobert	0
16291295Srobert	};
16391295Srobert
16491295Srobert	if ((*ofw)(args)) {
16591295Srobert		printf("ofw_getprop: ofwh=0x%x buf=%p len=%u\n",
16691295Srobert			ofwh, buf, len);
16791295Srobert		return (1);
16891295Srobert	}
16991295Srobert	return (0);
17090699Srobert}
17190699Srobert
172212729Smariusstatic ofwh_t
17390699Srobertofw_open(const char *path)
17490699Srobert{
17591295Srobert	ofwcell_t args[] = {
17691295Srobert		(ofwcell_t)"open",
17791295Srobert		1,
17891295Srobert		1,
17991295Srobert		(ofwcell_t)path,
18091295Srobert		0
18191295Srobert	};
18291295Srobert
18391295Srobert	if ((*ofw)(args)) {
18491295Srobert		printf("ofw_open: path=\"%s\"\n", path);
18591295Srobert		return (-1);
18691295Srobert	}
18791295Srobert	return (args[4]);
18890699Srobert}
18990699Srobert
190212729Smariusstatic int
19190699Srobertofw_close(ofwh_t devh)
19290699Srobert{
19391295Srobert	ofwcell_t args[] = {
19491295Srobert		(ofwcell_t)"close",
19591295Srobert		1,
19691295Srobert		0,
19791295Srobert		(u_ofwh_t)devh
19891295Srobert	};
19991295Srobert
20091295Srobert	if ((*ofw)(args)) {
20191295Srobert		printf("ofw_close: devh=0x%x\n", devh);
20291295Srobert		return (1);
20391295Srobert	}
20491295Srobert	return (0);
20590699Srobert}
20690699Srobert
207212729Smariusstatic int
20890699Srobertofw_read(ofwh_t devh, void *buf, size_t len)
20990699Srobert{
21091295Srobert	ofwcell_t args[] = {
21191295Srobert		(ofwcell_t)"read",
212212729Smarius		3,
21391295Srobert		1,
21491295Srobert		(u_ofwh_t)devh,
21591295Srobert		(ofwcell_t)buf,
21691295Srobert		len,
21791295Srobert		0
21891295Srobert	};
21991295Srobert
22091295Srobert	if ((*ofw)(args)) {
22191295Srobert		printf("ofw_read: devh=0x%x buf=%p len=%u\n", devh, buf, len);
22291295Srobert		return (1);
22391295Srobert	}
22491295Srobert	return (0);
22590699Srobert}
22690699Srobert
227212729Smariusstatic int
22890699Srobertofw_write(ofwh_t devh, const void *buf, size_t len)
22990699Srobert{
23091295Srobert	ofwcell_t args[] = {
23191295Srobert		(ofwcell_t)"write",
23291295Srobert		3,
23391295Srobert		1,
23491295Srobert		(u_ofwh_t)devh,
23591295Srobert		(ofwcell_t)buf,
23691295Srobert		len,
23791295Srobert		0
23891295Srobert	};
23991295Srobert
24091295Srobert	if ((*ofw)(args)) {
24191295Srobert		printf("ofw_write: devh=0x%x buf=%p len=%u\n", devh, buf, len);
24291295Srobert		return (1);
24391295Srobert	}
24491295Srobert	return (0);
24590699Srobert}
24690699Srobert
247212729Smariusstatic int
24890699Srobertofw_seek(ofwh_t devh, u_int64_t off)
24990699Srobert{
25091295Srobert	ofwcell_t args[] = {
25191295Srobert		(ofwcell_t)"seek",
252212729Smarius		3,
25391295Srobert		1,
25491295Srobert		(u_ofwh_t)devh,
25591295Srobert		off >> 32,
25691678Srobert		off,
25791295Srobert		0
25891295Srobert	};
25991295Srobert
26091295Srobert	if ((*ofw)(args)) {
26191295Srobert		printf("ofw_seek: devh=0x%x off=0x%lx\n", devh, off);
26291295Srobert		return (1);
26391295Srobert	}
26491295Srobert	return (0);
26590699Srobert}
26690699Srobert
267212729Smariusstatic void
26895342Sjakeofw_exit(void)
26995342Sjake{
27095342Sjake	ofwcell_t args[3];
27195342Sjake
27295342Sjake	args[0] = (ofwcell_t)"exit";
27395342Sjake	args[1] = 0;
27495342Sjake	args[2] = 0;
27595342Sjake
27695351Sjake	for (;;)
27795351Sjake		(*ofw)(args);
27895342Sjake}
27995342Sjake
28095340Sjakestatic void
28197863Sphkbcopy(const void *src, void *dst, size_t len)
28295340Sjake{
28397863Sphk	const char *s = src;
28497863Sphk	char *d = dst;
28595340Sjake
28695340Sjake	while (len-- != 0)
28797863Sphk		*d++ = *s++;
28895340Sjake}
28995340Sjake
29095340Sjakestatic void
29197864Sphkmemcpy(void *dst, const void *src, size_t len)
29297864Sphk{
293212729Smarius
29497864Sphk	bcopy(src, dst, len);
29597864Sphk}
29697864Sphk
29797864Sphkstatic void
29895340Sjakebzero(void *b, size_t len)
29995340Sjake{
30095340Sjake	char *p = b;
30195340Sjake
30295340Sjake	while (len-- != 0)
30395340Sjake		*p++ = 0;
30495340Sjake}
30595340Sjake
30690699Srobertstatic int
30790699Srobertstrcmp(const char *s1, const char *s2)
30890699Srobert{
309212729Smarius
31091295Srobert	for (; *s1 == *s2 && *s1; s1++, s2++)
31191295Srobert		;
31291295Srobert	return ((u_char)*s1 - (u_char)*s2);
31390699Srobert}
31490699Srobert
31597864Sphk#include "ufsread.c"
31690699Srobert
31795346Sjakeint
31895346Sjakemain(int ac, char **av)
31990699Srobert{
32095346Sjake	const char *path;
32195346Sjake	int i;
32291295Srobert
32395346Sjake	path = _PATH_LOADER;
32495346Sjake	for (i = 0; i < ac; i++) {
32595346Sjake		switch (av[i][0]) {
32695346Sjake		case '-':
32795346Sjake			switch (av[i][1]) {
32895346Sjake			default:
32995351Sjake				usage();
33095346Sjake			}
33195346Sjake			break;
33295346Sjake		default:
33395346Sjake			path = av[i];
33495346Sjake			break;
33595346Sjake		}
33695346Sjake	}
33790699Srobert
33891295Srobert	printf(" \n>> FreeBSD/sparc64 boot block\n"
33990699Srobert	"   Boot path:   %s\n"
34095346Sjake	"   Boot loader: %s\n", bootpath, path);
34195351Sjake
34295351Sjake	if (mount(bootpath) == -1)
34395351Sjake		panic("mount");
34495351Sjake
34595346Sjake	load(path);
34691295Srobert	return (1);
34790699Srobert}
34890699Srobert
34990699Srobertstatic void
35095351Sjakeusage(void)
35195351Sjake{
35295351Sjake
35395351Sjake	printf("usage: boot device [/path/to/loader]\n");
35495351Sjake	exit(1);
35595351Sjake}
35695351Sjake
35795351Sjakestatic void
35895342Sjakeexit(int code)
35995342Sjake{
36095342Sjake
36195342Sjake	ofw_exit();
36295342Sjake}
36395342Sjake
36497864Sphkstatic struct dmadat __dmadat;
36597864Sphk
36695351Sjakestatic int
36795351Sjakemount(const char *device)
36895351Sjake{
36995351Sjake
37097864Sphk	dmadat = &__dmadat;
37195351Sjake	if ((bootdev = ofw_open(device)) == -1) {
37295351Sjake		printf("mount: can't open device\n");
37395351Sjake		return (-1);
37495351Sjake	}
37597864Sphk	if (fsread(0, NULL, 0)) {
37695351Sjake		printf("mount: can't read superblock\n");
37795351Sjake		return (-1);
37895351Sjake	}
37995351Sjake	return (0);
38095351Sjake}
38195351Sjake
38295342Sjakestatic void
38390699Srobertload(const char *fname)
38490699Srobert{
38591295Srobert	Elf64_Ehdr eh;
38695339Sjake	Elf64_Phdr ph;
38791295Srobert	caddr_t p;
38891295Srobert	ino_t ino;
38995339Sjake	int i;
39090699Srobert
39191295Srobert	if ((ino = lookup(fname)) == 0) {
39295337Sjake		printf("File %s not found\n", fname);
39390699Srobert		return;
39490699Srobert	}
39595339Sjake	if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) {
39695339Sjake		printf("Can't read elf header\n");
39791295Srobert		return;
39895339Sjake	}
39991295Srobert	if (!IS_ELF(eh)) {
40091295Srobert		printf("Not an ELF file\n");
40191295Srobert		return;
40291295Srobert	}
40395339Sjake	for (i = 0; i < eh.e_phnum; i++) {
40495339Sjake		fs_off = eh.e_phoff + i * eh.e_phentsize;
40595339Sjake		if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) {
40695339Sjake			printf("Can't read program header %d\n", i);
40791295Srobert			return;
40891295Srobert		}
40995339Sjake		if (ph.p_type != PT_LOAD)
41095339Sjake			continue;
41195339Sjake		fs_off = ph.p_offset;
41295339Sjake		p = (caddr_t)ph.p_vaddr;
41395339Sjake		if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) {
41495339Sjake			printf("Can't read content of section %d\n", i);
41591295Srobert			return;
41691295Srobert		}
41795339Sjake		if (ph.p_filesz != ph.p_memsz)
41895340Sjake			bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz);
41991295Srobert	}
42095351Sjake	ofw_close(bootdev);
42195339Sjake	(*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw);
42290699Srobert}
42390699Srobert
42490699Srobertstatic int
42590699Srobertdskread(void *buf, u_int64_t lba, int nblk)
42690699Srobert{
427212729Smarius
42891295Srobert	/*
429133862Smarius	 * The Open Firmware should open the correct partition for us.
43091295Srobert	 * That means, if we read from offset zero on an open instance handle,
43191295Srobert	 * we should read from offset zero of that partition.
43291295Srobert	 */
43395351Sjake	ofw_seek(bootdev, lba * DEV_BSIZE);
43495351Sjake	ofw_read(bootdev, buf, nblk * DEV_BSIZE);
43591295Srobert	return (0);
43690699Srobert}
43790699Srobert
43895351Sjakestatic void
43995351Sjakepanic(const char *fmt, ...)
44090699Srobert{
44195351Sjake	char buf[128];
44291295Srobert	va_list ap;
44395346Sjake
44495346Sjake	va_start(ap, fmt);
44595351Sjake	vsnprintf(buf, sizeof buf, fmt, ap);
44695351Sjake	printf("panic: %s\n", buf);
44795346Sjake	va_end(ap);
44895351Sjake
44995351Sjake	exit(1);
45095346Sjake}
45195346Sjake
45295346Sjakestatic int
45395351Sjakeprintf(const char *fmt, ...)
45495346Sjake{
45595351Sjake	va_list ap;
45695346Sjake	int ret;
45795346Sjake
45895351Sjake	va_start(ap, fmt);
45995351Sjake	ret = vprintf(fmt, ap);
46095351Sjake	va_end(ap);
46195346Sjake	return (ret);
46295346Sjake}
46395346Sjake
46495346Sjakestatic int
465212729Smariusputchar(char c, void *arg)
46695346Sjake{
46795346Sjake	char buf;
46895346Sjake
46995346Sjake	if (c == '\n') {
47095346Sjake		buf = '\r';
47195346Sjake		ofw_write(stdouth, &buf, 1);
47295346Sjake	}
47395346Sjake	buf = c;
47495346Sjake	ofw_write(stdouth, &buf, 1);
47595346Sjake	return (1);
47695346Sjake}
47795346Sjake
47895346Sjakestatic int
47995351Sjakevprintf(const char *fmt, va_list ap)
48095351Sjake{
48195351Sjake	int ret;
48295351Sjake
48395351Sjake	ret = __printf(fmt, putchar, 0, ap);
48495351Sjake	return (ret);
48595351Sjake}
48695351Sjake
48795351Sjakestatic int
48895351Sjakevsnprintf(char *str, size_t sz, const char *fmt, va_list ap)
48995351Sjake{
49095351Sjake	struct sp_data sp;
49195351Sjake	int ret;
49295351Sjake
49395351Sjake	sp.sp_buf = str;
49495351Sjake	sp.sp_len = 0;
49595351Sjake	sp.sp_size = sz;
49695351Sjake	ret = __printf(fmt, __sputc, &sp, ap);
49795351Sjake	return (ret);
49895351Sjake}
49995351Sjake
50095351Sjakestatic int
50195346Sjake__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap)
50295346Sjake{
50395346Sjake	char buf[(sizeof(long) * 8) + 1];
50495346Sjake	char *nbuf;
50595346Sjake	u_long ul;
50695346Sjake	u_int ui;
50795346Sjake	int lflag;
50895346Sjake	int sflag;
50991295Srobert	char *s;
51095346Sjake	int pad;
51195346Sjake	int ret;
51295346Sjake	int c;
51390699Srobert
51495346Sjake	nbuf = &buf[sizeof buf - 1];
51595346Sjake	ret = 0;
51695346Sjake	while ((c = *fmt++) != 0) {
51795346Sjake		if (c != '%') {
51895346Sjake			ret += putc(c, arg);
51995346Sjake			continue;
52095346Sjake		}
52195346Sjake		lflag = 0;
52295346Sjake		sflag = 0;
52395346Sjake		pad = 0;
52495346Sjakereswitch:	c = *fmt++;
52595346Sjake		switch (c) {
52695346Sjake		case '#':
52795346Sjake			sflag = 1;
52895346Sjake			goto reswitch;
52995346Sjake		case '%':
53095346Sjake			ret += putc('%', arg);
53195346Sjake			break;
53295346Sjake		case 'c':
53395346Sjake			c = va_arg(ap, int);
53495346Sjake			ret += putc(c, arg);
53595346Sjake			break;
53695346Sjake		case 'd':
53795346Sjake			if (lflag == 0) {
53895346Sjake				ui = (u_int)va_arg(ap, int);
53995346Sjake				if (ui < (int)ui) {
54095346Sjake					ui = -ui;
54195346Sjake					ret += putc('-', arg);
54291295Srobert				}
54395346Sjake				s = __uitoa(nbuf, ui, 10);
54495346Sjake			} else {
54595346Sjake				ul = (u_long)va_arg(ap, long);
54695346Sjake				if (ul < (long)ul) {
54795346Sjake					ul = -ul;
54895346Sjake					ret += putc('-', arg);
54995346Sjake				}
55095346Sjake				s = __ultoa(nbuf, ul, 10);
55191295Srobert			}
55295346Sjake			ret += __puts(s, putc, arg);
55395346Sjake			break;
55495346Sjake		case 'l':
55595346Sjake			lflag = 1;
55695346Sjake			goto reswitch;
55795346Sjake		case 'o':
55895346Sjake			if (lflag == 0) {
55995346Sjake				ui = (u_int)va_arg(ap, u_int);
56095346Sjake				s = __uitoa(nbuf, ui, 8);
56195346Sjake			} else {
56295346Sjake				ul = (u_long)va_arg(ap, u_long);
56395346Sjake				s = __ultoa(nbuf, ul, 8);
56495346Sjake			}
56595346Sjake			ret += __puts(s, putc, arg);
56695346Sjake			break;
56795346Sjake		case 'p':
56895346Sjake			ul = (u_long)va_arg(ap, void *);
56995346Sjake			s = __ultoa(nbuf, ul, 16);
57095346Sjake			ret += __puts("0x", putc, arg);
57195346Sjake			ret += __puts(s, putc, arg);
57295346Sjake			break;
57395346Sjake		case 's':
57495346Sjake			s = va_arg(ap, char *);
57595346Sjake			ret += __puts(s, putc, arg);
57695346Sjake			break;
57795346Sjake		case 'u':
57895346Sjake			if (lflag == 0) {
57995346Sjake				ui = va_arg(ap, u_int);
58095346Sjake				s = __uitoa(nbuf, ui, 10);
58195346Sjake			} else {
58295346Sjake				ul = va_arg(ap, u_long);
58395346Sjake				s = __ultoa(nbuf, ul, 10);
58495346Sjake			}
58595346Sjake			ret += __puts(s, putc, arg);
58695346Sjake			break;
58795346Sjake		case 'x':
58895346Sjake			if (lflag == 0) {
58995346Sjake				ui = va_arg(ap, u_int);
59095346Sjake				s = __uitoa(nbuf, ui, 16);
59195346Sjake			} else {
59295346Sjake				ul = va_arg(ap, u_long);
59395346Sjake				s = __ultoa(nbuf, ul, 16);
59495346Sjake			}
59595346Sjake			if (sflag)
59695346Sjake				ret += __puts("0x", putc, arg);
59795346Sjake			ret += __puts(s, putc, arg);
59895346Sjake			break;
59995346Sjake		case '0': case '1': case '2': case '3': case '4':
60095346Sjake		case '5': case '6': case '7': case '8': case '9':
60195346Sjake			pad = pad * 10 + c - '0';
60295346Sjake			goto reswitch;
60395346Sjake		default:
60495346Sjake			break;
60590699Srobert		}
60690699Srobert	}
60795346Sjake	return (ret);
60890699Srobert}
60990699Srobert
61090699Srobertstatic int
611212729Smarius__sputc(char c, void *arg)
61295351Sjake{
61395351Sjake	struct sp_data *sp;
61495351Sjake
61595351Sjake	sp = arg;
61695351Sjake	if (sp->sp_len < sp->sp_size)
61795351Sjake		sp->sp_buf[sp->sp_len++] = c;
61895351Sjake	sp->sp_buf[sp->sp_len] = '\0';
61995351Sjake	return (1);
62095351Sjake}
62195351Sjake
62295351Sjakestatic int
62395346Sjake__puts(const char *s, putc_func_t *putc, void *arg)
62490699Srobert{
62595346Sjake	const char *p;
62695346Sjake	int ret;
62795346Sjake
62895346Sjake	ret = 0;
62995346Sjake	for (p = s; *p != '\0'; p++)
63095346Sjake		ret += putc(*p, arg);
63195346Sjake	return (ret);
63290699Srobert}
63395346Sjake
63495346Sjakestatic char *
63595346Sjake__uitoa(char *buf, u_int ui, int base)
63695346Sjake{
63795346Sjake	char *p;
63895346Sjake
63995346Sjake	p = buf;
64095346Sjake	*p = '\0';
64195346Sjake	do
64295346Sjake		*--p = digits[ui % base];
64395346Sjake	while ((ui /= base) != 0);
64495346Sjake	return (p);
64595346Sjake}
64695346Sjake
64795346Sjakestatic char *
64895346Sjake__ultoa(char *buf, u_long ul, int base)
64995346Sjake{
65095346Sjake	char *p;
65195346Sjake
65295346Sjake	p = buf;
65395346Sjake	*p = '\0';
65495346Sjake	do
65595346Sjake		*--p = digits[ul % base];
65695346Sjake	while ((ul /= base) != 0);
65795346Sjake	return (p);
65895346Sjake}
659