since it replaces cu, put it in usr/bin
[unix-history] / usr / src / sys / kern / subr_prf.c
CommitLineData
b4e32d36 1/* subr_prf.c 4.24 82/10/31 */
8cbb423c
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/seg.h"
6#include "../h/buf.h"
7#include "../h/conf.h"
0dc06be8 8#include "../h/reboot.h"
90f8d91f
BJ
9#include "../h/vm.h"
10#include "../h/msgbuf.h"
d11b28dc
RE
11#include "../h/dir.h"
12#include "../h/user.h"
13#include "../h/tty.h"
96d38f03 14
8cbb423c
BJ
15/*
16 * In case console is off,
17 * panicstr contains argument to last
18 * call to panic.
19 */
8cbb423c
BJ
20char *panicstr;
21
22/*
23 * Scaled down version of C Library printf.
b725a0ca
BJ
24 * Used to print diagnostic information directly on console tty.
25 * Since it is not interrupt driven, all system activities are
26 * suspended. Printf should not be used for chit-chat.
27 *
28 * One additional format: %b is supported to decode error registers.
29 * Usage is:
30 * printf("reg=%b\n", regval, "<base><arg>*");
31 * Where <base> is the output base expressed as a control character,
32 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of
33 * characters, the first of which gives the bit number to be inspected
34 * (origin 1), and the next characters (up to a control character, i.e.
35 * a character <= 32), give the name of the register. Thus
36 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
37 * would produce output:
38 * reg=2<BITTWO,BITONE>
8cbb423c
BJ
39 */
40/*VARARGS1*/
41printf(fmt, x1)
b725a0ca
BJ
42 char *fmt;
43 unsigned x1;
96d38f03
BJ
44{
45
46 prf(fmt, &x1, 0);
47}
48
843267b1 49/*
b725a0ca
BJ
50 * Uprintf prints to the current user's terminal,
51 * guarantees not to sleep (so can be called by interrupt routines)
52 * and does no watermark checking - (so no verbose messages).
843267b1
BJ
53 */
54/*VARARGS1*/
55uprintf(fmt, x1)
b725a0ca 56 char *fmt;
843267b1 57 unsigned x1;
96d38f03
BJ
58{
59
843267b1 60 prf(fmt, &x1, 2);
96d38f03
BJ
61}
62
843267b1 63prf(fmt, adx, touser)
b725a0ca
BJ
64 register char *fmt;
65 register u_int *adx;
8cbb423c 66{
d5726689 67 register int b, c, i;
8cbb423c 68 char *s;
3c79e4ff 69 int any;
8cbb423c 70
8cbb423c 71loop:
843267b1 72 while ((c = *fmt++) != '%') {
8cbb423c
BJ
73 if(c == '\0')
74 return;
843267b1 75 putchar(c, touser);
8cbb423c 76 }
843267b1 77again:
8cbb423c 78 c = *fmt++;
b725a0ca 79 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
843267b1
BJ
80 switch (c) {
81
82 case 'l':
83 goto again;
84 case 'x': case 'X':
85 b = 16;
86 goto number;
87 case 'd': case 'D':
88 case 'u': /* what a joke */
89 b = 10;
90 goto number;
91 case 'o': case 'O':
92 b = 8;
93number:
a0eab615 94 printn((u_long)*adx, b, touser);
843267b1
BJ
95 break;
96 case 'c':
d5726689
BJ
97 b = *adx;
98 for (i = 24; i >= 0; i -= 8)
99 if (c = (b >> i) & 0x7f)
100 putchar(c, touser);
843267b1 101 break;
3c79e4ff
BJ
102 case 'b':
103 b = *adx++;
104 s = (char *)*adx;
a0eab615 105 printn((u_long)b, *s++, touser);
3c79e4ff
BJ
106 any = 0;
107 if (b) {
108 putchar('<', touser);
109 while (i = *s++) {
110 if (b & (1 << (i-1))) {
111 if (any)
112 putchar(',', touser);
113 any = 1;
114 for (; (c = *s) > 32; s++)
115 putchar(c, touser);
116 } else
117 for (; *s > 32; s++)
118 ;
119 }
1ce587f2
BJ
120 if (any)
121 putchar('>', touser);
3c79e4ff
BJ
122 }
123 break;
124
843267b1 125 case 's':
8cbb423c 126 s = (char *)*adx;
96d38f03 127 while (c = *s++)
843267b1
BJ
128 putchar(c, touser);
129 break;
2bb8d359
BJ
130
131 case '%':
132 putchar('%', touser);
133 break;
8cbb423c
BJ
134 }
135 adx++;
136 goto loop;
137}
138
b725a0ca
BJ
139/*
140 * Printn prints a number n in base b.
141 * We don't use recursion to avoid deep kernel stacks.
142 */
843267b1 143printn(n, b, touser)
a0eab615 144 u_long n;
8cbb423c 145{
d5726689 146 char prbuf[11];
843267b1 147 register char *cp;
8cbb423c 148
843267b1
BJ
149 if (b == 10 && (int)n < 0) {
150 putchar('-', touser);
151 n = (unsigned)(-(int)n);
8cbb423c 152 }
d5726689 153 cp = prbuf;
843267b1
BJ
154 do {
155 *cp++ = "0123456789abcdef"[n%b];
156 n /= b;
157 } while (n);
158 do
159 putchar(*--cp, touser);
d5726689 160 while (cp > prbuf);
8cbb423c
BJ
161}
162
163/*
0dc06be8 164 * Panic is called on unresolvable fatal errors.
b725a0ca
BJ
165 * It prints "panic: mesg", and then reboots.
166 * If we are called twice, then we avoid trying to
167 * sync the disks as this often leads to recursive panics.
8cbb423c
BJ
168 */
169panic(s)
b725a0ca 170 char *s;
8cbb423c 171{
b4e32d36 172#ifdef sun
cddce008
BJ
173 register int *a5;
174#endif
68503f9a 175 int bootopt = RB_AUTOBOOT;
843267b1 176
68503f9a
BJ
177 if (panicstr)
178 bootopt |= RB_NOSYNC;
b4e32d36 179#ifdef sun
cddce008
BJ
180 else {
181 asm("movl a6, a5");
182 traceback(a5, a5);
183 }
184#endif
8cbb423c 185 panicstr = s;
a9c526c1 186 printf("panic: %s\n", s);
b725a0ca 187 boot(RB_PANIC, bootopt);
8cbb423c
BJ
188}
189
fdd11a14
BJ
190/*
191 * Warn that a system table is full.
192 */
193tablefull(tab)
194 char *tab;
195{
196
197 printf("%s: table is full\n", tab);
198}
199
b725a0ca
BJ
200/*
201 * Hard error is the preface to plaintive error messages
fdd11a14 202 * about failing disk transfers.
b725a0ca 203 */
fdd11a14 204harderr(bp, cp)
3c79e4ff 205 struct buf *bp;
fdd11a14 206 char *cp;
8cbb423c
BJ
207{
208
fdd11a14
BJ
209 printf("%s%d%c: hard error sn%d ", cp,
210 dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
8cbb423c 211}
b725a0ca 212
96d38f03 213/*
843267b1 214 * Print a character on console or users terminal.
96d38f03
BJ
215 * If destination is console then the last MSGBUFS characters
216 * are saved in msgbuf for inspection later.
217 */
49c84d3f 218/*ARGSUSED*/
843267b1
BJ
219putchar(c, touser)
220 register int c;
96d38f03 221{
96d38f03 222
843267b1
BJ
223 if (touser) {
224 register struct tty *tp = u.u_ttyp;
d11b28dc 225
c30cd845 226 if (tp && (tp->t_state&TS_CARR_ON)) {
843267b1
BJ
227 register s = spl6();
228 if (c == '\n')
2752c877
BJ
229 (void) ttyoutput('\r', tp);
230 (void) ttyoutput(c, tp);
d11b28dc
RE
231 ttstart(tp);
232 splx(s);
233 }
234 return;
235 }
b4e32d36 236#ifdef vax
b9fda884 237#include "../vax/mtpr.h" /* XXX */
cddce008
BJ
238#endif
239 if (c != '\0' && c != '\r' && c != 0177
b4e32d36 240#ifdef vax
cddce008
BJ
241 && mfpr(MAPEN)
242#endif
243 ) {
90f8d91f
BJ
244 if (msgbuf.msg_magic != MSG_MAGIC) {
245 msgbuf.msg_bufx = 0;
246 msgbuf.msg_magic = MSG_MAGIC;
247 }
248 if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
249 msgbuf.msg_bufx = 0;
250 msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
96d38f03
BJ
251 }
252 if (c == 0)
253 return;
254 cnputc(c);
255}