boot1.c revision 97864
190699Srobert/* 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 * 1790699Srobert */ 1891295Srobert 1991295Srobert#include <sys/cdefs.h> 2091295Srobert__FBSDID("$FreeBSD: head/sys/boot/sparc64/boot1/boot1.c 97864 2002-06-05 12:00:53Z phk $"); 2191295Srobert 2290699Srobert#include <sys/param.h> 2390699Srobert#include <sys/reboot.h> 2490699Srobert#include <sys/diskslice.h> 2590699Srobert#include <sys/disklabel.h> 2690699Srobert#include <sys/dirent.h> 2790699Srobert#include <machine/elf.h> 2890699Srobert#include <machine/stdarg.h> 2990699Srobert 3090699Srobert#include <ufs/ffs/fs.h> 3190699Srobert#include <ufs/ufs/dinode.h> 3290699Srobert 3395337Sjake#define _PATH_LOADER "/boot/loader" 3495337Sjake#define _PATH_KERNEL "/boot/kernel/kernel" 3590699Srobert 3696497Sobrien#define BSIZEMAX 16384 3790699Srobert 3895351Sjaketypedef int putc_func_t(int c, void *arg); 3995351Sjaketypedef int32_t ofwh_t; 4095351Sjake 4195351Sjakestruct sp_data { 4295351Sjake char *sp_buf; 4395351Sjake u_int sp_len; 4495351Sjake u_int sp_size; 4590699Srobert}; 4690699Srobert 4795346Sjakestatic const char digits[] = "0123456789abcdef"; 4890699Srobert 4995346Sjakestatic char bootpath[128]; 5095346Sjakestatic char bootargs[128]; 5195346Sjake 5295351Sjakestatic ofwh_t bootdev; 5395346Sjake 5495351Sjakestatic struct fs fs; 5595351Sjakestatic ino_t inomap; 5695351Sjakestatic char blkbuf[BSIZEMAX]; 5795351Sjakestatic unsigned int fsblks; 5895351Sjake 5990699Srobertstatic uint32_t fs_off; 6090699Srobert 6195346Sjakeint main(int ac, char **av); 6295346Sjake 6395351Sjakestatic void exit(int) __dead2; 6490699Srobertstatic void load(const char *); 6590699Srobertstatic int dskread(void *, u_int64_t, int); 6690699Srobert 6795351Sjakestatic void usage(void); 6895351Sjake 6995340Sjakestatic void bcopy(const void *src, void *dst, size_t len); 7095340Sjakestatic void bzero(void *b, size_t len); 7190699Srobert 7295351Sjakestatic int mount(const char *device); 7395351Sjake 7495351Sjakestatic void panic(const char *fmt, ...) __dead2; 7595346Sjakestatic int printf(const char *fmt, ...); 7695351Sjakestatic int putchar(int c, void *arg); 7795346Sjakestatic int vprintf(const char *fmt, va_list ap); 7895351Sjakestatic int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); 7995346Sjake 8095346Sjakestatic int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap); 8195346Sjakestatic int __putc(int c, void *arg); 8295346Sjakestatic int __puts(const char *s, putc_func_t *putc, void *arg); 8395351Sjakestatic int __sputc(int c, void *arg); 8495346Sjakestatic char *__uitoa(char *buf, u_int val, int base); 8595346Sjakestatic char *__ultoa(char *buf, u_long val, int base); 8695346Sjake 8790699Srobert/* 8890699Srobert * Open Firmware interface functions 8990699Srobert */ 9090699Sroberttypedef u_int64_t ofwcell_t; 9190699Sroberttypedef u_int32_t u_ofwh_t; 9290699Sroberttypedef int (*ofwfp_t)(ofwcell_t []); 9390699Srobertofwfp_t ofw; /* the prom Open Firmware entry */ 9490699Srobert 9590699Srobertvoid ofw_init(int, int, int, int, ofwfp_t); 9690699Srobertofwh_t ofw_finddevice(const char *); 9790699Srobertofwh_t ofw_open(const char *); 9890699Srobertint ofw_getprop(ofwh_t, const char *, void *, size_t); 9990699Srobertint ofw_read(ofwh_t, void *, size_t); 10090699Srobertint ofw_write(ofwh_t, const void *, size_t); 10190699Srobertint ofw_seek(ofwh_t, u_int64_t); 10295351Sjakevoid ofw_exit(void) __dead2; 10390699Srobert 10490699Srobertofwh_t bootdevh; 10590699Srobertofwh_t stdinh, stdouth; 10690699Srobert 10790699Srobert/* 10890699Srobert * This has to stay here, as the PROM seems to ignore the 10990699Srobert * entry point specified in the a.out header. (or elftoaout is broken) 11090699Srobert */ 11190699Srobert 11290699Srobertvoid 11390699Srobertofw_init(int d, int d1, int d2, int d3, ofwfp_t ofwaddr) 11490699Srobert{ 11590699Srobert ofwh_t chosenh; 11695346Sjake char *av[16]; 11795346Sjake char *p; 11895346Sjake int ac; 11990699Srobert 12090699Srobert ofw = ofwaddr; 12190699Srobert 12290699Srobert chosenh = ofw_finddevice("/chosen"); 12390699Srobert ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh)); 12490699Srobert ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth)); 12595346Sjake ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs)); 12690699Srobert ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath)); 12790699Srobert 12895346Sjake bootargs[sizeof(bootargs) - 1] = '\0'; 12995346Sjake bootpath[sizeof(bootpath) - 1] = '\0'; 13095346Sjake 13195346Sjake ac = 0; 13295346Sjake p = bootargs; 13395346Sjake for (;;) { 13495346Sjake while (*p == ' ' && *p != '\0') 13595346Sjake p++; 13695346Sjake if (*p == '\0' || ac >= 16) 13795346Sjake break; 13895346Sjake av[ac++] = p; 13995346Sjake while (*p != ' ' && *p != '\0') 14095346Sjake p++; 14195346Sjake if (*p != '\0') 14295346Sjake *p++ = '\0'; 14395346Sjake } 14495346Sjake 14595346Sjake exit(main(ac, av)); 14690699Srobert} 14790699Srobert 14890699Srobertofwh_t 14990699Srobertofw_finddevice(const char *name) 15090699Srobert{ 15191295Srobert ofwcell_t args[] = { 15291295Srobert (ofwcell_t)"finddevice", 15391295Srobert 1, 15491295Srobert 1, 15591295Srobert (ofwcell_t)name, 15691295Srobert 0 15791295Srobert }; 15891295Srobert 15991295Srobert if ((*ofw)(args)) { 16091295Srobert printf("ofw_finddevice: name=\"%s\"\n", name); 16191295Srobert return (1); 16291295Srobert } 16391295Srobert return (args[4]); 16490699Srobert} 16590699Srobert 16690699Srobertint 16790699Srobertofw_getprop(ofwh_t ofwh, const char *name, void *buf, size_t len) 16890699Srobert{ 16991295Srobert ofwcell_t args[] = { 17091295Srobert (ofwcell_t)"getprop", 17191295Srobert 4, 17291295Srobert 1, 17391295Srobert (u_ofwh_t)ofwh, 17491295Srobert (ofwcell_t)name, 17591295Srobert (ofwcell_t)buf, 17691295Srobert len, 17790699Srobert 0 17891295Srobert }; 17991295Srobert 18091295Srobert if ((*ofw)(args)) { 18191295Srobert printf("ofw_getprop: ofwh=0x%x buf=%p len=%u\n", 18291295Srobert ofwh, buf, len); 18391295Srobert return (1); 18491295Srobert } 18591295Srobert return (0); 18690699Srobert} 18790699Srobert 18890699Srobertofwh_t 18990699Srobertofw_open(const char *path) 19090699Srobert{ 19191295Srobert ofwcell_t args[] = { 19291295Srobert (ofwcell_t)"open", 19391295Srobert 1, 19491295Srobert 1, 19591295Srobert (ofwcell_t)path, 19691295Srobert 0 19791295Srobert }; 19891295Srobert 19991295Srobert if ((*ofw)(args)) { 20091295Srobert printf("ofw_open: path=\"%s\"\n", path); 20191295Srobert return (-1); 20291295Srobert } 20391295Srobert return (args[4]); 20490699Srobert} 20590699Srobert 20690699Srobertint 20790699Srobertofw_close(ofwh_t devh) 20890699Srobert{ 20991295Srobert ofwcell_t args[] = { 21091295Srobert (ofwcell_t)"close", 21191295Srobert 1, 21291295Srobert 0, 21391295Srobert (u_ofwh_t)devh 21491295Srobert }; 21591295Srobert 21691295Srobert if ((*ofw)(args)) { 21791295Srobert printf("ofw_close: devh=0x%x\n", devh); 21891295Srobert return (1); 21991295Srobert } 22091295Srobert return (0); 22190699Srobert} 22290699Srobert 22390699Srobertint 22490699Srobertofw_read(ofwh_t devh, void *buf, size_t len) 22590699Srobert{ 22691295Srobert ofwcell_t args[] = { 22791295Srobert (ofwcell_t)"read", 22891295Srobert 4, 22991295Srobert 1, 23091295Srobert (u_ofwh_t)devh, 23191295Srobert (ofwcell_t)buf, 23291295Srobert len, 23391295Srobert 0 23491295Srobert }; 23591295Srobert 23691295Srobert if ((*ofw)(args)) { 23791295Srobert printf("ofw_read: devh=0x%x buf=%p len=%u\n", devh, buf, len); 23891295Srobert return (1); 23991295Srobert } 24091295Srobert return (0); 24190699Srobert} 24290699Srobert 24390699Srobertint 24490699Srobertofw_write(ofwh_t devh, const void *buf, size_t len) 24590699Srobert{ 24691295Srobert ofwcell_t args[] = { 24791295Srobert (ofwcell_t)"write", 24891295Srobert 3, 24991295Srobert 1, 25091295Srobert (u_ofwh_t)devh, 25191295Srobert (ofwcell_t)buf, 25291295Srobert len, 25391295Srobert 0 25491295Srobert }; 25591295Srobert 25691295Srobert if ((*ofw)(args)) { 25791295Srobert printf("ofw_write: devh=0x%x buf=%p len=%u\n", devh, buf, len); 25891295Srobert return (1); 25991295Srobert } 26091295Srobert return (0); 26190699Srobert} 26290699Srobert 26390699Srobertint 26490699Srobertofw_seek(ofwh_t devh, u_int64_t off) 26590699Srobert{ 26691295Srobert ofwcell_t args[] = { 26791295Srobert (ofwcell_t)"seek", 26891295Srobert 4, 26991295Srobert 1, 27091295Srobert (u_ofwh_t)devh, 27191295Srobert off >> 32, 27291678Srobert off, 27391295Srobert 0 27491295Srobert }; 27591295Srobert 27691295Srobert if ((*ofw)(args)) { 27791295Srobert printf("ofw_seek: devh=0x%x off=0x%lx\n", devh, off); 27891295Srobert return (1); 27991295Srobert } 28091295Srobert return (0); 28190699Srobert} 28290699Srobert 28395342Sjakevoid 28495342Sjakeofw_exit(void) 28595342Sjake{ 28695342Sjake ofwcell_t args[3]; 28795342Sjake 28895342Sjake args[0] = (ofwcell_t)"exit"; 28995342Sjake args[1] = 0; 29095342Sjake args[2] = 0; 29195342Sjake 29295351Sjake for (;;) 29395351Sjake (*ofw)(args); 29495342Sjake} 29595342Sjake 29695340Sjakestatic void 29797863Sphkbcopy(const void *src, void *dst, size_t len) 29895340Sjake{ 29997863Sphk const char *s = src; 30097863Sphk char *d = dst; 30195340Sjake 30295340Sjake while (len-- != 0) 30397863Sphk *d++ = *s++; 30495340Sjake} 30595340Sjake 30695340Sjakestatic void 30797864Sphkmemcpy(void *dst, const void *src, size_t len) 30897864Sphk{ 30997864Sphk bcopy(src, dst, len); 31097864Sphk} 31197864Sphk 31297864Sphkstatic void 31395340Sjakebzero(void *b, size_t len) 31495340Sjake{ 31595340Sjake char *p = b; 31695340Sjake 31795340Sjake while (len-- != 0) 31895340Sjake *p++ = 0; 31995340Sjake} 32095340Sjake 32190699Srobertstatic int 32290699Srobertstrcmp(const char *s1, const char *s2) 32390699Srobert{ 32491295Srobert for (; *s1 == *s2 && *s1; s1++, s2++) 32591295Srobert ; 32691295Srobert return ((u_char)*s1 - (u_char)*s2); 32790699Srobert} 32890699Srobert 32997864Sphk#include "ufsread.c" 33090699Srobert 33195346Sjakeint 33295346Sjakemain(int ac, char **av) 33390699Srobert{ 33495346Sjake const char *path; 33595346Sjake int i; 33691295Srobert 33795346Sjake path = _PATH_LOADER; 33895346Sjake for (i = 0; i < ac; i++) { 33995346Sjake switch (av[i][0]) { 34095346Sjake case '-': 34195346Sjake switch (av[i][1]) { 34295346Sjake default: 34395351Sjake usage(); 34495346Sjake } 34595346Sjake break; 34695346Sjake default: 34795346Sjake path = av[i]; 34895346Sjake break; 34995346Sjake } 35095346Sjake } 35190699Srobert 35291295Srobert printf(" \n>> FreeBSD/sparc64 boot block\n" 35390699Srobert " Boot path: %s\n" 35495346Sjake " Boot loader: %s\n", bootpath, path); 35595351Sjake 35695351Sjake if (mount(bootpath) == -1) 35795351Sjake panic("mount"); 35895351Sjake 35995346Sjake load(path); 36091295Srobert return (1); 36190699Srobert} 36290699Srobert 36390699Srobertstatic void 36495351Sjakeusage(void) 36595351Sjake{ 36695351Sjake 36795351Sjake printf("usage: boot device [/path/to/loader]\n"); 36895351Sjake exit(1); 36995351Sjake} 37095351Sjake 37195351Sjakestatic void 37295342Sjakeexit(int code) 37395342Sjake{ 37495342Sjake 37595342Sjake ofw_exit(); 37695342Sjake} 37795342Sjake 37897864Sphkstatic struct dmadat __dmadat; 37997864Sphk 38095351Sjakestatic int 38195351Sjakemount(const char *device) 38295351Sjake{ 38395351Sjake 38497864Sphk dmadat = &__dmadat; 38595351Sjake if ((bootdev = ofw_open(device)) == -1) { 38695351Sjake printf("mount: can't open device\n"); 38795351Sjake return (-1); 38895351Sjake } 38997864Sphk if (fsread(0, NULL, 0)) { 39095351Sjake printf("mount: can't read superblock\n"); 39195351Sjake return (-1); 39295351Sjake } 39395351Sjake return (0); 39495351Sjake} 39595351Sjake 39695342Sjakestatic void 39790699Srobertload(const char *fname) 39890699Srobert{ 39991295Srobert Elf64_Ehdr eh; 40095339Sjake Elf64_Phdr ph; 40191295Srobert caddr_t p; 40291295Srobert ino_t ino; 40395339Sjake int i; 40490699Srobert 40591295Srobert if ((ino = lookup(fname)) == 0) { 40695337Sjake printf("File %s not found\n", fname); 40790699Srobert return; 40890699Srobert } 40995339Sjake if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) { 41095339Sjake printf("Can't read elf header\n"); 41191295Srobert return; 41295339Sjake } 41391295Srobert if (!IS_ELF(eh)) { 41491295Srobert printf("Not an ELF file\n"); 41591295Srobert return; 41691295Srobert } 41795339Sjake for (i = 0; i < eh.e_phnum; i++) { 41895339Sjake fs_off = eh.e_phoff + i * eh.e_phentsize; 41995339Sjake if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) { 42095339Sjake printf("Can't read program header %d\n", i); 42191295Srobert return; 42291295Srobert } 42395339Sjake if (ph.p_type != PT_LOAD) 42495339Sjake continue; 42595339Sjake fs_off = ph.p_offset; 42695339Sjake p = (caddr_t)ph.p_vaddr; 42795339Sjake if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) { 42895339Sjake printf("Can't read content of section %d\n", i); 42991295Srobert return; 43091295Srobert } 43195339Sjake if (ph.p_filesz != ph.p_memsz) 43295340Sjake bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz); 43391295Srobert } 43495351Sjake ofw_close(bootdev); 43595339Sjake (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw); 43690699Srobert} 43790699Srobert 43890699Srobertstatic int 43990699Srobertdskread(void *buf, u_int64_t lba, int nblk) 44090699Srobert{ 44191295Srobert /* 44291295Srobert * The OpenFirmware should open the correct partition for us. 44391295Srobert * That means, if we read from offset zero on an open instance handle, 44491295Srobert * we should read from offset zero of that partition. 44591295Srobert */ 44695351Sjake ofw_seek(bootdev, lba * DEV_BSIZE); 44795351Sjake ofw_read(bootdev, buf, nblk * DEV_BSIZE); 44891295Srobert return (0); 44990699Srobert} 45090699Srobert 45195351Sjakestatic void 45295351Sjakepanic(const char *fmt, ...) 45390699Srobert{ 45495351Sjake char buf[128]; 45591295Srobert va_list ap; 45695346Sjake 45795346Sjake va_start(ap, fmt); 45895351Sjake vsnprintf(buf, sizeof buf, fmt, ap); 45995351Sjake printf("panic: %s\n", buf); 46095346Sjake va_end(ap); 46195351Sjake 46295351Sjake exit(1); 46395346Sjake} 46495346Sjake 46595346Sjakestatic int 46695351Sjakeprintf(const char *fmt, ...) 46795346Sjake{ 46895351Sjake va_list ap; 46995346Sjake int ret; 47095346Sjake 47195351Sjake va_start(ap, fmt); 47295351Sjake ret = vprintf(fmt, ap); 47395351Sjake va_end(ap); 47495346Sjake return (ret); 47595346Sjake} 47695346Sjake 47795346Sjakestatic int 47895346Sjakeputchar(int c, void *arg) 47995346Sjake{ 48095346Sjake char buf; 48195346Sjake 48295346Sjake if (c == '\n') { 48395346Sjake buf = '\r'; 48495346Sjake ofw_write(stdouth, &buf, 1); 48595346Sjake } 48695346Sjake buf = c; 48795346Sjake ofw_write(stdouth, &buf, 1); 48895346Sjake return (1); 48995346Sjake} 49095346Sjake 49195346Sjakestatic int 49295351Sjakevprintf(const char *fmt, va_list ap) 49395351Sjake{ 49495351Sjake int ret; 49595351Sjake 49695351Sjake ret = __printf(fmt, putchar, 0, ap); 49795351Sjake return (ret); 49895351Sjake} 49995351Sjake 50095351Sjakestatic int 50195351Sjakevsnprintf(char *str, size_t sz, const char *fmt, va_list ap) 50295351Sjake{ 50395351Sjake struct sp_data sp; 50495351Sjake int ret; 50595351Sjake 50695351Sjake sp.sp_buf = str; 50795351Sjake sp.sp_len = 0; 50895351Sjake sp.sp_size = sz; 50995351Sjake ret = __printf(fmt, __sputc, &sp, ap); 51095351Sjake return (ret); 51195351Sjake} 51295351Sjake 51395351Sjakestatic int 51495346Sjake__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) 51595346Sjake{ 51695346Sjake char buf[(sizeof(long) * 8) + 1]; 51795346Sjake char *nbuf; 51895346Sjake u_long ul; 51995346Sjake u_int ui; 52095346Sjake int lflag; 52195346Sjake int sflag; 52291295Srobert char *s; 52395346Sjake int pad; 52495346Sjake int ret; 52595346Sjake int c; 52690699Srobert 52795346Sjake nbuf = &buf[sizeof buf - 1]; 52895346Sjake ret = 0; 52995346Sjake while ((c = *fmt++) != 0) { 53095346Sjake if (c != '%') { 53195346Sjake ret += putc(c, arg); 53295346Sjake continue; 53395346Sjake } 53495346Sjake lflag = 0; 53595346Sjake sflag = 0; 53695346Sjake pad = 0; 53795346Sjakereswitch: c = *fmt++; 53895346Sjake switch (c) { 53995346Sjake case '#': 54095346Sjake sflag = 1; 54195346Sjake goto reswitch; 54295346Sjake case '%': 54395346Sjake ret += putc('%', arg); 54495346Sjake break; 54595346Sjake case 'c': 54695346Sjake c = va_arg(ap, int); 54795346Sjake ret += putc(c, arg); 54895346Sjake break; 54995346Sjake case 'd': 55095346Sjake if (lflag == 0) { 55195346Sjake ui = (u_int)va_arg(ap, int); 55295346Sjake if (ui < (int)ui) { 55395346Sjake ui = -ui; 55495346Sjake ret += putc('-', arg); 55591295Srobert } 55695346Sjake s = __uitoa(nbuf, ui, 10); 55795346Sjake } else { 55895346Sjake ul = (u_long)va_arg(ap, long); 55995346Sjake if (ul < (long)ul) { 56095346Sjake ul = -ul; 56195346Sjake ret += putc('-', arg); 56295346Sjake } 56395346Sjake s = __ultoa(nbuf, ul, 10); 56491295Srobert } 56595346Sjake ret += __puts(s, putc, arg); 56695346Sjake break; 56795346Sjake case 'l': 56895346Sjake lflag = 1; 56995346Sjake goto reswitch; 57095346Sjake case 'o': 57195346Sjake if (lflag == 0) { 57295346Sjake ui = (u_int)va_arg(ap, u_int); 57395346Sjake s = __uitoa(nbuf, ui, 8); 57495346Sjake } else { 57595346Sjake ul = (u_long)va_arg(ap, u_long); 57695346Sjake s = __ultoa(nbuf, ul, 8); 57795346Sjake } 57895346Sjake ret += __puts(s, putc, arg); 57995346Sjake break; 58095346Sjake case 'p': 58195346Sjake ul = (u_long)va_arg(ap, void *); 58295346Sjake s = __ultoa(nbuf, ul, 16); 58395346Sjake ret += __puts("0x", putc, arg); 58495346Sjake ret += __puts(s, putc, arg); 58595346Sjake break; 58695346Sjake case 's': 58795346Sjake s = va_arg(ap, char *); 58895346Sjake ret += __puts(s, putc, arg); 58995346Sjake break; 59095346Sjake case 'u': 59195346Sjake if (lflag == 0) { 59295346Sjake ui = va_arg(ap, u_int); 59395346Sjake s = __uitoa(nbuf, ui, 10); 59495346Sjake } else { 59595346Sjake ul = va_arg(ap, u_long); 59695346Sjake s = __ultoa(nbuf, ul, 10); 59795346Sjake } 59895346Sjake ret += __puts(s, putc, arg); 59995346Sjake break; 60095346Sjake case 'x': 60195346Sjake if (lflag == 0) { 60295346Sjake ui = va_arg(ap, u_int); 60395346Sjake s = __uitoa(nbuf, ui, 16); 60495346Sjake } else { 60595346Sjake ul = va_arg(ap, u_long); 60695346Sjake s = __ultoa(nbuf, ul, 16); 60795346Sjake } 60895346Sjake if (sflag) 60995346Sjake ret += __puts("0x", putc, arg); 61095346Sjake ret += __puts(s, putc, arg); 61195346Sjake break; 61295346Sjake case '0': case '1': case '2': case '3': case '4': 61395346Sjake case '5': case '6': case '7': case '8': case '9': 61495346Sjake pad = pad * 10 + c - '0'; 61595346Sjake goto reswitch; 61695346Sjake default: 61795346Sjake break; 61890699Srobert } 61990699Srobert } 62095346Sjake return (ret); 62190699Srobert} 62290699Srobert 62390699Srobertstatic int 62495351Sjake__sputc(int c, void *arg) 62595351Sjake{ 62695351Sjake struct sp_data *sp; 62795351Sjake 62895351Sjake sp = arg; 62995351Sjake if (sp->sp_len < sp->sp_size) 63095351Sjake sp->sp_buf[sp->sp_len++] = c; 63195351Sjake sp->sp_buf[sp->sp_len] = '\0'; 63295351Sjake return (1); 63395351Sjake} 63495351Sjake 63595351Sjakestatic int 63695346Sjake__puts(const char *s, putc_func_t *putc, void *arg) 63790699Srobert{ 63895346Sjake const char *p; 63995346Sjake int ret; 64095346Sjake 64195346Sjake ret = 0; 64295346Sjake for (p = s; *p != '\0'; p++) 64395346Sjake ret += putc(*p, arg); 64495346Sjake return (ret); 64590699Srobert} 64695346Sjake 64795346Sjakestatic char * 64895346Sjake__uitoa(char *buf, u_int ui, int base) 64995346Sjake{ 65095346Sjake char *p; 65195346Sjake 65295346Sjake p = buf; 65395346Sjake *p = '\0'; 65495346Sjake do 65595346Sjake *--p = digits[ui % base]; 65695346Sjake while ((ui /= base) != 0); 65795346Sjake return (p); 65895346Sjake} 65995346Sjake 66095346Sjakestatic char * 66195346Sjake__ultoa(char *buf, u_long ul, int base) 66295346Sjake{ 66395346Sjake char *p; 66495346Sjake 66595346Sjake p = buf; 66695346Sjake *p = '\0'; 66795346Sjake do 66895346Sjake *--p = digits[ul % base]; 66995346Sjake while ((ul /= base) != 0); 67095346Sjake return (p); 67195346Sjake} 672