1*2434Swnj /* subr_prf.c 4.9 02/15/81 */ 231Sbill 331Sbill #include "../h/param.h" 431Sbill #include "../h/systm.h" 531Sbill #include "../h/seg.h" 631Sbill #include "../h/buf.h" 731Sbill #include "../h/conf.h" 8285Sbill #include "../h/mtpr.h" 91184Sbill #include "../h/reboot.h" 102172Swnj #include "../h/vm.h" 112172Swnj #include "../h/msgbuf.h" 122360Skre #include "../h/dir.h" 132360Skre #include "../h/user.h" 142360Skre #include "../h/tty.h" 1531Sbill 1631Sbill /* 1731Sbill * In case console is off, 1831Sbill * panicstr contains argument to last 1931Sbill * call to panic. 2031Sbill */ 2131Sbill 2231Sbill char *panicstr; 2331Sbill 2431Sbill /* 2531Sbill * Scaled down version of C Library printf. 2631Sbill * Only %s %u %d (==%u) %o %x %D are recognized. 2731Sbill * Used to print diagnostic information 2831Sbill * directly on console tty. 2931Sbill * Since it is not interrupt driven, 3031Sbill * all system activities are pretty much 3131Sbill * suspended. 3231Sbill * Printf should not be used for chit-chat. 3331Sbill */ 3431Sbill /*VARARGS1*/ 3531Sbill printf(fmt, x1) 3631Sbill register char *fmt; 3731Sbill unsigned x1; 3831Sbill { 39285Sbill 40285Sbill prf(fmt, &x1, 0); 41285Sbill } 42285Sbill 432377Swnj /* 442377Swnj * print to the current users terminal, 452377Swnj * guarantee not to sleep (so can be called by intr routine) 462377Swnj * no watermark checking - so no verbose messages 472377Swnj */ 482377Swnj /*VARARGS1*/ 492377Swnj uprintf(fmt, x1) 502377Swnj char *fmt; 512377Swnj unsigned x1; 52285Sbill { 53285Sbill 542377Swnj prf(fmt, &x1, 2); 55285Sbill } 56285Sbill 572377Swnj /* THIS CODE IS VAX DEPENDENT */ 582377Swnj prf(fmt, adx, touser) 59285Sbill register char *fmt; 602377Swnj register u_int *adx; 61285Sbill { 62*2434Swnj register int b, c, i; 6331Sbill char *s; 6431Sbill 6531Sbill loop: 662377Swnj while ((c = *fmt++) != '%') { 6731Sbill if(c == '\0') 6831Sbill return; 692377Swnj putchar(c, touser); 7031Sbill } 712377Swnj again: 7231Sbill c = *fmt++; 732377Swnj switch (c) { 742377Swnj 752377Swnj case 'l': 762377Swnj goto again; 772377Swnj case 'x': case 'X': 782377Swnj b = 16; 792377Swnj goto number; 802377Swnj case 'd': case 'D': 812377Swnj case 'u': /* what a joke */ 822377Swnj b = 10; 832377Swnj goto number; 842377Swnj case 'o': case 'O': 852377Swnj b = 8; 862377Swnj number: 872377Swnj printn(*adx, b, touser); 882377Swnj break; 892377Swnj case 'c': 90*2434Swnj b = *adx; 91*2434Swnj for (i = 24; i >= 0; i -= 8) 92*2434Swnj if (c = (b >> i) & 0x7f) 93*2434Swnj putchar(c, touser); 942377Swnj break; 952377Swnj case 's': 9631Sbill s = (char *)*adx; 97285Sbill while (c = *s++) 982377Swnj putchar(c, touser); 992377Swnj break; 10031Sbill } 10131Sbill adx++; 10231Sbill goto loop; 10331Sbill } 1042377Swnj /* END VAX DEPENDENT CODE */ 10531Sbill 1062377Swnj printn(n, b, touser) 1072377Swnj unsigned long n; 10831Sbill { 109*2434Swnj char prbuf[11]; 1102377Swnj register char *cp; 11131Sbill 1122377Swnj if (b == 10 && (int)n < 0) { 1132377Swnj putchar('-', touser); 1142377Swnj n = (unsigned)(-(int)n); 11531Sbill } 116*2434Swnj cp = prbuf; 1172377Swnj do { 1182377Swnj *cp++ = "0123456789abcdef"[n%b]; 1192377Swnj n /= b; 1202377Swnj } while (n); 1212377Swnj do 1222377Swnj putchar(*--cp, touser); 123*2434Swnj while (cp > prbuf); 12431Sbill } 12531Sbill 12631Sbill /* 1271184Sbill * Panic is called on unresolvable fatal errors. 1281184Sbill * It syncs, prints "panic: mesg", and then reboots. 12931Sbill */ 13031Sbill panic(s) 13131Sbill char *s; 13231Sbill { 1332377Swnj 13431Sbill panicstr = s; 13531Sbill printf("panic: %s\n", s); 1361787Sbill (void) spl0(); 13731Sbill for(;;) 1381401Sbill boot(RB_PANIC, RB_AUTOBOOT); 13931Sbill } 14031Sbill 14131Sbill /* 14231Sbill * prdev prints a warning message of the 14331Sbill * form "mesg on dev x/y". 14431Sbill * x and y are the major and minor parts of 14531Sbill * the device argument. 14631Sbill */ 14731Sbill prdev(str, dev) 1482377Swnj char *str; 1492377Swnj dev_t dev; 15031Sbill { 15131Sbill 1522377Swnj printf("%s on dev %d/%d\n", str, major(dev), minor(dev)); 15331Sbill } 15431Sbill 15531Sbill /* 15631Sbill * deverr prints a diagnostic from 15731Sbill * a device driver. 15831Sbill * It prints the device, block number, 15931Sbill * and an octal word (usually some error 16031Sbill * status register) passed as argument. 16131Sbill */ 16231Sbill deverror(bp, o1, o2) 1632377Swnj register struct buf *bp; 16431Sbill { 16531Sbill 1662360Skre printf("bn=%d er=%x,%x", bp->b_blkno, o1,o2); 1672360Skre prdev("", bp->b_dev); 16831Sbill } 169285Sbill 170285Sbill /* 1712377Swnj * Print a character on console or users terminal. 172285Sbill * If destination is console then the last MSGBUFS characters 173285Sbill * are saved in msgbuf for inspection later. 174285Sbill */ 1751785Sbill /*ARGSUSED*/ 1762377Swnj putchar(c, touser) 1772377Swnj register int c; 178285Sbill { 179285Sbill 1802377Swnj if (touser) { 1812377Swnj register struct tty *tp = u.u_ttyp; 1822360Skre 1832377Swnj if (tp && (tp->t_state&CARR_ON)) { 1842377Swnj register s = spl6(); 1852377Swnj if (c == '\n') 1862377Swnj ttyoutput('\r', tp); 1872360Skre ttyoutput(c, tp); 1882360Skre ttstart(tp); 1892360Skre splx(s); 1902360Skre } 1912360Skre return; 1922360Skre } 1932386Swnj if (c != '\0' && c != '\r' && c != 0177 && mfpr(MAPEN)) { 1942172Swnj if (msgbuf.msg_magic != MSG_MAGIC) { 1952172Swnj msgbuf.msg_bufx = 0; 1962172Swnj msgbuf.msg_magic = MSG_MAGIC; 1972172Swnj } 1982172Swnj if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE) 1992172Swnj msgbuf.msg_bufx = 0; 2002172Swnj msgbuf.msg_bufc[msgbuf.msg_bufx++] = c; 201285Sbill } 202285Sbill if (c == 0) 203285Sbill return; 204285Sbill cnputc(c); 205285Sbill } 206