boot1.c revision 133862
111126Sjulian/* 2103722Sphk * Copyright (c) 1998 Robert Nordier 311126Sjulian * All rights reserved. 411126Sjulian * Copyright (c) 2001 Robert Drehmel 511126Sjulian * All rights reserved. 611126Sjulian * 711126Sjulian * Redistribution and use in source and binary forms are freely 811126Sjulian * permitted provided that the above copyright notice and this 911126Sjulian * paragraph and the following disclaimer are duplicated in all 1011126Sjulian * such forms. 1111126Sjulian * 1211126Sjulian * This software is provided "AS IS" and without any express or 1311126Sjulian * implied warranties, including, without limitation, the implied 14103722Sphk * warranties of merchantability and fitness for a particular 15103722Sphk * purpose. 1611126Sjulian */ 17103722Sphk 1811126Sjulian#include <sys/cdefs.h> 1911126Sjulian__FBSDID("$FreeBSD: head/sys/boot/sparc64/boot1/boot1.c 133862 2004-08-16 15:45:27Z marius $"); 2011126Sjulian 2111126Sjulian#include <sys/param.h> 2211126Sjulian#include <sys/dirent.h> 2311126Sjulian#include <machine/elf.h> 2411126Sjulian#include <machine/stdarg.h> 2511126Sjulian 2611126Sjulian#define _PATH_LOADER "/boot/loader" 27116182Sobrien#define _PATH_KERNEL "/boot/kernel/kernel" 28116182Sobrien 29116182Sobrien#define BSIZEMAX 16384 3011126Sjulian 3148936Sphktypedef int putc_func_t(int c, void *arg); 3283366Sjuliantypedef int32_t ofwh_t; 33111179Sphk 3490737Sgreenstruct sp_data { 3590737Sgreen char *sp_buf; 3636735Sdfr u_int sp_len; 3748936Sphk u_int sp_size; 3811126Sjulian}; 3912954Sjulian 4048936Sphkstatic const char digits[] = "0123456789abcdef"; 41120514Sphk 42171181Skibstatic char bootpath[128]; 4365374Sphkstatic char bootargs[128]; 44126078Sphk 45147982Srwatsonstatic ofwh_t bootdev; 46171181Skib 4749535Sphkstatic struct fs fs; 4811126Sjulianstatic ino_t inomap; 49149144Sphkstatic char blkbuf[BSIZEMAX]; 50149144Sphkstatic unsigned int fsblks; 51131996Sphk 5248936Sphkstatic uint32_t fs_off; 53150342Sphk 54142242Sphkint main(int ac, char **av); 55171188Skib 56171188Skibstatic void exit(int) __dead2; 57171181Skibstatic void load(const char *); 58171181Skibstatic int dskread(void *, u_int64_t, int); 59171181Skib 60171181Skibstatic void usage(void); 61171181Skib 62170950Skibstatic void bcopy(const void *src, void *dst, size_t len); 63170950Skibstatic void bzero(void *b, size_t len); 64177301Skib 65177301Skibstatic int mount(const char *device); 66170950Skib 67135600Sphkstatic void panic(const char *fmt, ...) __dead2; 68135600Sphkstatic int printf(const char *fmt, ...); 69126082Sphkstatic int putchar(int c, void *arg); 70151450Sjhbstatic int vprintf(const char *fmt, va_list ap); 71126082Sphkstatic int vsnprintf(char *str, size_t sz, const char *fmt, va_list ap); 72126082Sphk 73126082Sphkstatic int __printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap); 74177301Skibstatic int __putc(int c, void *arg); 75177301Skibstatic int __puts(const char *s, putc_func_t *putc, void *arg); 76177301Skibstatic int __sputc(int c, void *arg); 77177301Skibstatic char *__uitoa(char *buf, u_int val, int base); 78177301Skibstatic char *__ultoa(char *buf, u_long val, int base); 79177301Skib 80170950Skib/* 81170950Skib * Open Firmware interface functions 82170950Skib */ 83177301Skibtypedef u_int64_t ofwcell_t; 84177301Skibtypedef u_int32_t u_ofwh_t; 85170950Skibtypedef int (*ofwfp_t)(ofwcell_t []); 86177301Skibofwfp_t ofw; /* the prom Open Firmware entry */ 87170950Skib 88170950Skibvoid ofw_init(int, int, int, int, ofwfp_t); 89177301Skibofwh_t ofw_finddevice(const char *); 90177301Skibofwh_t ofw_open(const char *); 91177301Skibint ofw_getprop(ofwh_t, const char *, void *, size_t); 92177301Skibint ofw_read(ofwh_t, void *, size_t); 93177301Skibint ofw_write(ofwh_t, const void *, size_t); 94177301Skibint ofw_seek(ofwh_t, u_int64_t); 95177301Skibvoid ofw_exit(void) __dead2; 96177301Skib 97177301Skibofwh_t bootdevh; 98177301Skibofwh_t stdinh, stdouth; 99177301Skib 100177301Skib/* 101177301Skib * This has to stay here, as the PROM seems to ignore the 102177301Skib * entry point specified in the a.out header. (or elftoaout is broken) 103170950Skib */ 104170950Skib 105177301Skibvoid 106177301Skibofw_init(int d, int d1, int d2, int d3, ofwfp_t ofwaddr) 107177301Skib{ 108177301Skib ofwh_t chosenh; 109170950Skib char *av[16]; 110170950Skib char *p; 111170950Skib int ac; 112170950Skib 113170950Skib ofw = ofwaddr; 114170950Skib 115170950Skib chosenh = ofw_finddevice("/chosen"); 116170950Skib ofw_getprop(chosenh, "stdin", &stdinh, sizeof(stdinh)); 117170950Skib ofw_getprop(chosenh, "stdout", &stdouth, sizeof(stdouth)); 118170950Skib ofw_getprop(chosenh, "bootargs", bootargs, sizeof(bootargs)); 119170950Skib ofw_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath)); 120170950Skib 121177301Skib bootargs[sizeof(bootargs) - 1] = '\0'; 122177301Skib bootpath[sizeof(bootpath) - 1] = '\0'; 123177301Skib 124177301Skib ac = 0; 125177301Skib p = bootargs; 126177301Skib for (;;) { 127177301Skib while (*p == ' ' && *p != '\0') 128177301Skib p++; 129135600Sphk if (*p == '\0' || ac >= 16) 130135600Sphk break; 131126082Sphk av[ac++] = p; 132135704Sphk while (*p != ' ' && *p != '\0') 133126082Sphk p++; 134126082Sphk if (*p != '\0') 135126082Sphk *p++ = '\0'; 136126082Sphk } 137144385Sphk 138144385Sphk exit(main(ac, av)); 139144385Sphk} 140144385Sphk 141144385Sphkofwh_t 142144385Sphkofw_finddevice(const char *name) 143144385Sphk{ 144144385Sphk ofwcell_t args[] = { 145144385Sphk (ofwcell_t)"finddevice", 146144385Sphk 1, 147144384Sphk 1, 148126082Sphk (ofwcell_t)name, 149135704Sphk 0 150142232Sphk }; 151126082Sphk 152126082Sphk if ((*ofw)(args)) { 153126082Sphk printf("ofw_finddevice: name=\"%s\"\n", name); 154126082Sphk return (1); 155142242Sphk } 156126082Sphk return (args[4]); 157142242Sphk} 158135600Sphk 159136014Sphkint 160136014Sphkofw_getprop(ofwh_t ofwh, const char *name, void *buf, size_t len) 161126082Sphk{ 162126082Sphk ofwcell_t args[] = { 163126082Sphk (ofwcell_t)"getprop", 164150342Sphk 4, 165142242Sphk 1, 166142242Sphk (u_ofwh_t)ofwh, 167150342Sphk (ofwcell_t)name, 168150342Sphk (ofwcell_t)buf, 169150342Sphk len, 170154029Sbz 0 171126082Sphk }; 172136014Sphk 173136014Sphk if ((*ofw)(args)) { 174136014Sphk printf("ofw_getprop: ofwh=0x%x buf=%p len=%u\n", 175136014Sphk ofwh, buf, len); 176150342Sphk return (1); 177126082Sphk } 178136014Sphk return (0); 179135704Sphk} 180135704Sphk 181135704Sphkofwh_t 182135704Sphkofw_open(const char *path) 183171181Skib{ 184126082Sphk ofwcell_t args[] = { 185135704Sphk (ofwcell_t)"open", 186135704Sphk 1, 187135704Sphk 1, 188171181Skib (ofwcell_t)path, 189171181Skib 0 190171181Skib }; 191171181Skib 192171181Skib if ((*ofw)(args)) { 193171181Skib printf("ofw_open: path=\"%s\"\n", path); 194171181Skib return (-1); 195135704Sphk } 196135704Sphk return (args[4]); 197135704Sphk} 198135704Sphk 199163529Skibint 200163529Skibofw_close(ofwh_t devh) 201163529Skib{ 202163529Skib ofwcell_t args[] = { 203171181Skib (ofwcell_t)"close", 204163529Skib 1, 205163529Skib 0, 206163529Skib (u_ofwh_t)devh 207163529Skib }; 208163529Skib 209163529Skib if ((*ofw)(args)) { 210171181Skib printf("ofw_close: devh=0x%x\n", devh); 211171181Skib return (1); 212171181Skib } 213171181Skib return (0); 214171181Skib} 215171181Skib 216163529Skibint 217163529Skibofw_read(ofwh_t devh, void *buf, size_t len) 218163529Skib{ 219163529Skib ofwcell_t args[] = { 220163529Skib (ofwcell_t)"read", 221135704Sphk 4, 222135704Sphk 1, 223135704Sphk (u_ofwh_t)devh, 224135704Sphk (ofwcell_t)buf, 225135704Sphk len, 226135704Sphk 0 227135704Sphk }; 228135704Sphk 229135704Sphk if ((*ofw)(args)) { 230135704Sphk printf("ofw_read: devh=0x%x buf=%p len=%u\n", devh, buf, len); 231120514Sphk return (1); 232120514Sphk } 233120514Sphk return (0); 23485603Sphk} 235120514Sphk 236120514Sphkint 237120514Sphkofw_write(ofwh_t devh, const void *buf, size_t len) 238120514Sphk{ 239120514Sphk ofwcell_t args[] = { 240120514Sphk (ofwcell_t)"write", 241120514Sphk 3, 242120514Sphk 1, 243120514Sphk (u_ofwh_t)devh, 244120514Sphk (ofwcell_t)buf, 245111179Sphk len, 246111179Sphk 0 247111179Sphk }; 248111179Sphk 249111179Sphk if ((*ofw)(args)) { 250111179Sphk printf("ofw_write: devh=0x%x buf=%p len=%u\n", devh, buf, len); 251120514Sphk return (1); 252120514Sphk } 253120514Sphk return (0); 254120514Sphk} 255120514Sphk 256120514Sphkint 257120514Sphkofw_seek(ofwh_t devh, u_int64_t off) 258120514Sphk{ 259111179Sphk ofwcell_t args[] = { 260111179Sphk (ofwcell_t)"seek", 261111179Sphk 4, 262111179Sphk 1, 263111179Sphk (u_ofwh_t)devh, 264120514Sphk off >> 32, 265120514Sphk off, 266111179Sphk 0 267111179Sphk }; 268111179Sphk 269111179Sphk if ((*ofw)(args)) { 270111179Sphk printf("ofw_seek: devh=0x%x off=0x%lx\n", devh, off); 271111179Sphk return (1); 272111179Sphk } 273111179Sphk return (0); 274111220Sphk} 275111179Sphk 276111179Sphkvoid 277111179Sphkofw_exit(void) 278126080Sphk{ 279126080Sphk ofwcell_t args[3]; 280111815Sphk 281111815Sphk args[0] = (ofwcell_t)"exit"; 282111815Sphk args[1] = 0; 283111815Sphk args[2] = 0; 284111815Sphk 285111815Sphk for (;;) 286111815Sphk (*ofw)(args); 287111815Sphk} 288111815Sphk 289111815Sphkstatic void 290111815Sphkbcopy(const void *src, void *dst, size_t len) 291111179Sphk{ 292111179Sphk const char *s = src; 293120514Sphk char *d = dst; 294111179Sphk 295120514Sphk while (len-- != 0) 296120514Sphk *d++ = *s++; 297120514Sphk} 298120514Sphk 299120514Sphkstatic void 300120514Sphkmemcpy(void *dst, const void *src, size_t len) 301133741Sjmg{ 302120514Sphk bcopy(src, dst, len); 303120514Sphk} 304120514Sphk 305120514Sphkstatic void 306120514Sphkbzero(void *b, size_t len) 307120514Sphk{ 308120514Sphk char *p = b; 309120514Sphk 310120514Sphk while (len-- != 0) 311130585Sphk *p++ = 0; 312120514Sphk} 313120514Sphk 314120514Sphkstatic int 315120514Sphkstrcmp(const char *s1, const char *s2) 316120514Sphk{ 317120514Sphk for (; *s1 == *s2 && *s1; s1++, s2++) 318120514Sphk ; 319120514Sphk return ((u_char)*s1 - (u_char)*s2); 320120514Sphk} 321120514Sphk 322120514Sphk#include "ufsread.c" 323120514Sphk 324120514Sphkint 325120514Sphkmain(int ac, char **av) 326120514Sphk{ 327120514Sphk const char *path; 328120514Sphk int i; 329149177Sphk 330149177Sphk path = _PATH_LOADER; 331149177Sphk for (i = 0; i < ac; i++) { 332177301Skib switch (av[i][0]) { 333149177Sphk case '-': 334149177Sphk switch (av[i][1]) { 335177301Skib default: 336177301Skib usage(); 337177301Skib } 338149177Sphk break; 339177301Skib default: 340149177Sphk path = av[i]; 341177301Skib break; 342149177Sphk } 343149177Sphk } 344149177Sphk 345149177Sphk printf(" \n>> FreeBSD/sparc64 boot block\n" 346170152Skib " Boot path: %s\n" 347149177Sphk " Boot loader: %s\n", bootpath, path); 348177301Skib 349149177Sphk if (mount(bootpath) == -1) 350149177Sphk panic("mount"); 351177301Skib 352177301Skib load(path); 353177301Skib return (1); 354149177Sphk} 355177301Skib 356149177Sphkstatic void 357177301Skibusage(void) 358149177Sphk{ 359149177Sphk 360149177Sphk printf("usage: boot device [/path/to/loader]\n"); 361149177Sphk exit(1); 362149177Sphk} 363149177Sphk 364177301Skibstatic void 365149177Sphkexit(int code) 366149177Sphk{ 367177301Skib 368177301Skib ofw_exit(); 369177301Skib} 370149177Sphk 371177301Skibstatic struct dmadat __dmadat; 372149177Sphk 373177301Skibstatic int 374149177Sphkmount(const char *device) 375149177Sphk{ 376149177Sphk 377149177Sphk dmadat = &__dmadat; 378149177Sphk if ((bootdev = ofw_open(device)) == -1) { 379149177Sphk printf("mount: can't open device\n"); 380177301Skib return (-1); 381177301Skib } 382149177Sphk if (fsread(0, NULL, 0)) { 383177301Skib printf("mount: can't read superblock\n"); 384177301Skib return (-1); 385177301Skib } 386177301Skib return (0); 387177301Skib} 388177301Skib 389149177Sphkstatic void 390177301Skibload(const char *fname) 391149177Sphk{ 392177301Skib Elf64_Ehdr eh; 393149177Sphk Elf64_Phdr ph; 394149177Sphk caddr_t p; 395149177Sphk ino_t ino; 396149177Sphk int i; 397149177Sphk 398177301Skib if ((ino = lookup(fname)) == 0) { 399149177Sphk printf("File %s not found\n", fname); 400149177Sphk return; 401177301Skib } 402177301Skib if (fsread(ino, &eh, sizeof(eh)) != sizeof(eh)) { 403177301Skib printf("Can't read elf header\n"); 404149177Sphk return; 405177858Skib } 406149177Sphk if (!IS_ELF(eh)) { 407177301Skib printf("Not an ELF file\n"); 408149177Sphk return; 409149177Sphk } 410149177Sphk for (i = 0; i < eh.e_phnum; i++) { 411149177Sphk fs_off = eh.e_phoff + i * eh.e_phentsize; 412149177Sphk if (fsread(ino, &ph, sizeof(ph)) != sizeof(ph)) { 413149177Sphk printf("Can't read program header %d\n", i); 414177301Skib return; 415149177Sphk } 416149177Sphk if (ph.p_type != PT_LOAD) 417177301Skib continue; 418177301Skib fs_off = ph.p_offset; 419177301Skib p = (caddr_t)ph.p_vaddr; 420149177Sphk if (fsread(ino, p, ph.p_filesz) != ph.p_filesz) { 421177858Skib printf("Can't read content of section %d\n", i); 422149177Sphk return; 423177301Skib } 424149177Sphk if (ph.p_filesz != ph.p_memsz) 425149177Sphk bzero(p + ph.p_filesz, ph.p_memsz - ph.p_filesz); 426149177Sphk } 427149177Sphk ofw_close(bootdev); 428149177Sphk (*(void (*)(int, int, int, int, ofwfp_t))eh.e_entry)(0, 0, 0, 0, ofw); 429149177Sphk} 430177301Skib 431149177Sphkstatic int 432149177Sphkdskread(void *buf, u_int64_t lba, int nblk) 433177301Skib{ 434177301Skib /* 435177301Skib * The Open Firmware should open the correct partition for us. 436149177Sphk * That means, if we read from offset zero on an open instance handle, 437177301Skib * we should read from offset zero of that partition. 438149177Sphk */ 439177301Skib ofw_seek(bootdev, lba * DEV_BSIZE); 440149177Sphk ofw_read(bootdev, buf, nblk * DEV_BSIZE); 441149177Sphk return (0); 442149177Sphk} 443149177Sphk 444149177Sphkstatic void 445149177Sphkpanic(const char *fmt, ...) 446177301Skib{ 447149177Sphk char buf[128]; 448149177Sphk va_list ap; 449177301Skib 450177301Skib va_start(ap, fmt); 451177301Skib vsnprintf(buf, sizeof buf, fmt, ap); 452149177Sphk printf("panic: %s\n", buf); 453177301Skib va_end(ap); 454149177Sphk 455177301Skib exit(1); 456149177Sphk} 457149177Sphk 458149177Sphkstatic int 459149177Sphkprintf(const char *fmt, ...) 460149177Sphk{ 461149177Sphk va_list ap; 462177301Skib int ret; 463149177Sphk 464149177Sphk va_start(ap, fmt); 465177301Skib ret = vprintf(fmt, ap); 466177301Skib va_end(ap); 467177301Skib return (ret); 468149177Sphk} 469177301Skib 470149177Sphkstatic int 471177301Skibputchar(int c, void *arg) 472149177Sphk{ 473149177Sphk char buf; 474149177Sphk 475149177Sphk if (c == '\n') { 476149177Sphk buf = '\r'; 477149177Sphk ofw_write(stdouth, &buf, 1); 478177301Skib } 479149177Sphk buf = c; 480149177Sphk ofw_write(stdouth, &buf, 1); 481177301Skib return (1); 482177301Skib} 483177301Skib 484149177Sphkstatic int 485177301Skibvprintf(const char *fmt, va_list ap) 486149177Sphk{ 487177301Skib int ret; 488149177Sphk 489149177Sphk ret = __printf(fmt, putchar, 0, ap); 490149177Sphk return (ret); 491149177Sphk} 49247640Sphk 493130936Slestatic int 49447028Sphkvsnprintf(char *str, size_t sz, const char *fmt, va_list ap) 49547028Sphk{ 49647028Sphk struct sp_data sp; 497130585Sphk int ret; 49847028Sphk 499130640Sphk sp.sp_buf = str; 500130640Sphk sp.sp_len = 0; 501143631Sphk sp.sp_size = sz; 50247028Sphk ret = __printf(fmt, __sputc, &sp, ap); 50347028Sphk return (ret); 50449826Sphk} 505130585Sphk 50649826Sphkstatic int 50749826Sphk__printf(const char *fmt, putc_func_t *putc, void *arg, va_list ap) 508130640Sphk{ 509130640Sphk char buf[(sizeof(long) * 8) + 1]; 510140964Sphk char *nbuf; 51149826Sphk u_long ul; 51249826Sphk u_int ui; 513143282Sphk int lflag; 514143282Sphk int sflag; 515140963Sphk char *s; 516140963Sphk int pad; 517140969Sphk int ret; 518143282Sphk int c; 519140963Sphk 520140963Sphk nbuf = &buf[sizeof buf - 1]; 521140963Sphk ret = 0; 52266067Sphk while ((c = *fmt++) != 0) { 52366067Sphk if (c != '%') { 52466067Sphk ret += putc(c, arg); 52574522Sphk continue; 52666067Sphk } 52766067Sphk lflag = 0; 52866067Sphk sflag = 0; 529130585Sphk pad = 0; 530144281Sphkreswitch: c = *fmt++; 53147028Sphk switch (c) { 532140733Sphk case '#': 533130640Sphk sflag = 1; 53448936Sphk goto reswitch; 535140733Sphk case '%': 536144292Sphk ret += putc('%', arg); 537144281Sphk break; 538143631Sphk case 'c': 539170950Skib c = va_arg(ap, int); 540140733Sphk ret += putc(c, arg); 541140733Sphk break; 54248936Sphk case 'd': 543143631Sphk if (lflag == 0) { 544150342Sphk ui = (u_int)va_arg(ap, int); 545144281Sphk if (ui < (int)ui) { 546125850Sbde ui = -ui; 54747028Sphk ret += putc('-', arg); 54847028Sphk } 54947028Sphk s = __uitoa(nbuf, ui, 10); 550130640Sphk } else { 55147028Sphk ul = (u_long)va_arg(ap, long); 552140969Sphk if (ul < (long)ul) { 55347028Sphk ul = -ul; 55447028Sphk ret += putc('-', arg); 55547028Sphk } 556130640Sphk s = __ultoa(nbuf, ul, 10); 55747028Sphk } 558140969Sphk ret += __puts(s, putc, arg); 55947028Sphk break; 56047028Sphk case 'l': 561125846Sphk lflag = 1; 562144292Sphk goto reswitch; 56349535Sphk case 'o': 564149324Sphk if (lflag == 0) { 56549535Sphk ui = (u_int)va_arg(ap, u_int); 566149324Sphk s = __uitoa(nbuf, ui, 8); 567149324Sphk } else { 568149324Sphk ul = (u_long)va_arg(ap, u_long); 569177301Skib s = __ultoa(nbuf, ul, 8); 570149324Sphk } 571149324Sphk ret += __puts(s, putc, arg); 572126156Sphk break; 573126082Sphk case 'p': 574126082Sphk ul = (u_long)va_arg(ap, void *); 575126082Sphk s = __ultoa(nbuf, ul, 16); 576126077Sphk ret += __puts("0x", putc, arg); 577126077Sphk ret += __puts(s, putc, arg); 578149177Sphk break; 579126077Sphk case 's': 580177301Skib s = va_arg(ap, char *); 581177301Skib ret += __puts(s, putc, arg); 582177301Skib break; 583177301Skib case 'u': 584177301Skib if (lflag == 0) { 585149177Sphk ui = va_arg(ap, u_int); 586177301Skib s = __uitoa(nbuf, ui, 10); 587177301Skib } else { 588149177Sphk ul = va_arg(ap, u_long); 589177301Skib s = __ultoa(nbuf, ul, 10); 590177301Skib } 591177301Skib ret += __puts(s, putc, arg); 592177301Skib break; 593177301Skib case 'x': 594126082Sphk if (lflag == 0) { 595143746Sphk ui = va_arg(ap, u_int); 596126082Sphk s = __uitoa(nbuf, ui, 16); 597126082Sphk } else { 598154266Salfred ul = va_arg(ap, u_long); 599154266Salfred s = __ultoa(nbuf, ul, 16); 600126082Sphk } 601126082Sphk if (sflag) 602126082Sphk ret += __puts("0x", putc, arg); 603126082Sphk ret += __puts(s, putc, arg); 604126082Sphk break; 605126082Sphk case '0': case '1': case '2': case '3': case '4': 606126082Sphk case '5': case '6': case '7': case '8': case '9': 607126082Sphk pad = pad * 10 + c - '0'; 608126082Sphk goto reswitch; 609126082Sphk default: 610126082Sphk break; 611126082Sphk } 612126078Sphk } 613129943Sphk return (ret); 614126078Sphk} 615126078Sphk 616126078Sphkstatic int 617126078Sphk__sputc(int c, void *arg) 618126078Sphk{ 619126078Sphk struct sp_data *sp; 620149177Sphk 621149177Sphk sp = arg; 622149177Sphk if (sp->sp_len < sp->sp_size) 623149177Sphk sp->sp_buf[sp->sp_len++] = c; 624177301Skib sp->sp_buf[sp->sp_len] = '\0'; 625177301Skib return (1); 626149177Sphk} 627149177Sphk 628149177Sphkstatic int 629149177Sphk__puts(const char *s, putc_func_t *putc, void *arg) 630149177Sphk{ 631149177Sphk const char *p; 632149177Sphk int ret; 633149177Sphk 634149177Sphk ret = 0; 635149177Sphk for (p = s; *p != '\0'; p++) 636149177Sphk ret += putc(*p, arg); 637149177Sphk return (ret); 638149177Sphk} 639149177Sphk 640149177Sphkstatic char * 641149177Sphk__uitoa(char *buf, u_int ui, int base) 642149177Sphk{ 643149177Sphk char *p; 644149177Sphk 645149177Sphk p = buf; 646149177Sphk *p = '\0'; 647149177Sphk do 648120514Sphk *--p = digits[ui % base]; 649126082Sphk while ((ui /= base) != 0); 650126082Sphk return (p); 651126082Sphk} 652126082Sphk 653126082Sphkstatic char * 654177301Skib__ultoa(char *buf, u_long ul, int base) 655177301Skib{ 656125846Sphk char *p; 657111622Sphk 658171181Skib p = buf; 659171181Skib *p = '\0'; 660171181Skib do 661147982Srwatson *--p = digits[ul % base]; 662125846Sphk while ((ul /= base) != 0); 663130585Sphk return (p); 664125846Sphk} 665125846Sphk