added fsck like -p flag (from ulysses!amw)
[unix-history] / usr / src / sys / kern / subr_prf.c
CommitLineData
da7c5cc6
KM
1/*
2 * Copyright (c) 1982 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
6 * @(#)subr_prf.c 6.7 (Berkeley) %G%
7 */
8cbb423c 8
94368568
JB
9#include "param.h"
10#include "systm.h"
11#include "seg.h"
12#include "buf.h"
13#include "conf.h"
14#include "reboot.h"
15#include "vm.h"
16#include "msgbuf.h"
17#include "dir.h"
18#include "user.h"
19#include "proc.h"
3358b36b 20#include "ioctl.h"
94368568 21#include "tty.h"
bd10af3f 22#include "syslog.h"
96d38f03 23
e3d5bfde
SL
24#ifdef vax
25#include "../vax/mtpr.h"
26#endif
27
34ef3482
RC
28#define TOCONS 0x1
29#define TOTTY 0x2
30#define TOLOG 0x4
31
8cbb423c
BJ
32/*
33 * In case console is off,
34 * panicstr contains argument to last
35 * call to panic.
36 */
8cbb423c
BJ
37char *panicstr;
38
39/*
40 * Scaled down version of C Library printf.
b725a0ca
BJ
41 * Used to print diagnostic information directly on console tty.
42 * Since it is not interrupt driven, all system activities are
43 * suspended. Printf should not be used for chit-chat.
44 *
45 * One additional format: %b is supported to decode error registers.
46 * Usage is:
47 * printf("reg=%b\n", regval, "<base><arg>*");
48 * Where <base> is the output base expressed as a control character,
49 * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of
50 * characters, the first of which gives the bit number to be inspected
51 * (origin 1), and the next characters (up to a control character, i.e.
52 * a character <= 32), give the name of the register. Thus
53 * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
54 * would produce output:
8d907ccf 55 * reg=3<BITTWO,BITONE>
8cbb423c
BJ
56 */
57/*VARARGS1*/
58printf(fmt, x1)
b725a0ca
BJ
59 char *fmt;
60 unsigned x1;
96d38f03
BJ
61{
62
34ef3482
RC
63 prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0);
64 logwakeup();
96d38f03
BJ
65}
66
843267b1 67/*
8d907ccf 68 * Uprintf prints to the current user's terminal
b725a0ca 69 * and does no watermark checking - (so no verbose messages).
843267b1
BJ
70 */
71/*VARARGS1*/
72uprintf(fmt, x1)
b725a0ca 73 char *fmt;
843267b1 74 unsigned x1;
96d38f03
BJ
75{
76
34ef3482
RC
77 prf(fmt, &x1, TOTTY, u.u_ttyp);
78}
79
bd10af3f
MK
80/*
81 * tprintf prints on the specified terminal (console if none)
82 * and logs the message. It is designed for error messages from
83 * single-open devices, and may be called from interrupt level.
84 */
34ef3482
RC
85/*VARARGS2*/
86tprintf(ttyp, fmt, x1)
87 struct tty *ttyp;
88 char *fmt;
89 unsigned x1;
90{
91
bd10af3f 92 prf(fmt, &x1, TOTTY | TOLOG, ttyp);
34ef3482
RC
93}
94
95/*
96 * Log writes to the log buffer,
8d907ccf 97 * and guarantees not to sleep (so can be called by interrupt routines).
bd10af3f 98 * If there is no process reading the log yet, it writes to the console also.
34ef3482
RC
99 */
100/*VARARGS2*/
101log(level, fmt, x1)
102 char *fmt;
103 unsigned x1;
104{
105 register s = splhigh();
bd10af3f 106 extern int log_open;
34ef3482
RC
107
108 putchar('<', TOLOG, (struct tty *)0);
109 printn(level, 10, TOLOG, (struct tty *)0);
110 putchar('>', TOLOG, (struct tty *)0);
111 prf(fmt, &x1, TOLOG, (struct tty *)0);
112 splx(s);
bd10af3f
MK
113 if (!log_open)
114 prf(fmt, &x1, TOCONS, (struct tty *)0);
34ef3482 115 logwakeup();
96d38f03
BJ
116}
117
34ef3482 118prf(fmt, adx, flags, ttyp)
b725a0ca
BJ
119 register char *fmt;
120 register u_int *adx;
34ef3482 121 struct tty *ttyp;
8cbb423c 122{
d5726689 123 register int b, c, i;
8cbb423c 124 char *s;
3c79e4ff 125 int any;
8cbb423c 126
8cbb423c 127loop:
843267b1 128 while ((c = *fmt++) != '%') {
34ef3482 129 if (c == '\0')
8cbb423c 130 return;
34ef3482 131 putchar(c, flags, ttyp);
8cbb423c 132 }
843267b1 133again:
8cbb423c 134 c = *fmt++;
b725a0ca 135 /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
843267b1
BJ
136 switch (c) {
137
138 case 'l':
139 goto again;
140 case 'x': case 'X':
141 b = 16;
142 goto number;
143 case 'd': case 'D':
144 case 'u': /* what a joke */
145 b = 10;
146 goto number;
147 case 'o': case 'O':
148 b = 8;
149number:
34ef3482 150 printn((u_long)*adx, b, flags, ttyp);
843267b1
BJ
151 break;
152 case 'c':
d5726689
BJ
153 b = *adx;
154 for (i = 24; i >= 0; i -= 8)
155 if (c = (b >> i) & 0x7f)
34ef3482 156 putchar(c, flags, ttyp);
843267b1 157 break;
3c79e4ff
BJ
158 case 'b':
159 b = *adx++;
160 s = (char *)*adx;
34ef3482 161 printn((u_long)b, *s++, flags, ttyp);
3c79e4ff
BJ
162 any = 0;
163 if (b) {
3c79e4ff
BJ
164 while (i = *s++) {
165 if (b & (1 << (i-1))) {
8d907ccf 166 putchar(any? ',' : '<', flags, ttyp);
3c79e4ff
BJ
167 any = 1;
168 for (; (c = *s) > 32; s++)
34ef3482 169 putchar(c, flags, ttyp);
3c79e4ff
BJ
170 } else
171 for (; *s > 32; s++)
172 ;
173 }
1ce587f2 174 if (any)
34ef3482 175 putchar('>', flags, ttyp);
3c79e4ff
BJ
176 }
177 break;
178
843267b1 179 case 's':
8cbb423c 180 s = (char *)*adx;
96d38f03 181 while (c = *s++)
34ef3482 182 putchar(c, flags, ttyp);
843267b1 183 break;
2bb8d359
BJ
184
185 case '%':
34ef3482 186 putchar('%', flags, ttyp);
2bb8d359 187 break;
8cbb423c
BJ
188 }
189 adx++;
190 goto loop;
191}
192
b725a0ca
BJ
193/*
194 * Printn prints a number n in base b.
195 * We don't use recursion to avoid deep kernel stacks.
196 */
34ef3482 197printn(n, b, flags, ttyp)
a0eab615 198 u_long n;
34ef3482 199 struct tty *ttyp;
8cbb423c 200{
d5726689 201 char prbuf[11];
843267b1 202 register char *cp;
8cbb423c 203
843267b1 204 if (b == 10 && (int)n < 0) {
34ef3482 205 putchar('-', flags, ttyp);
843267b1 206 n = (unsigned)(-(int)n);
8cbb423c 207 }
d5726689 208 cp = prbuf;
843267b1
BJ
209 do {
210 *cp++ = "0123456789abcdef"[n%b];
211 n /= b;
212 } while (n);
213 do
34ef3482 214 putchar(*--cp, flags, ttyp);
d5726689 215 while (cp > prbuf);
8cbb423c
BJ
216}
217
218/*
0dc06be8 219 * Panic is called on unresolvable fatal errors.
b725a0ca
BJ
220 * It prints "panic: mesg", and then reboots.
221 * If we are called twice, then we avoid trying to
222 * sync the disks as this often leads to recursive panics.
8cbb423c
BJ
223 */
224panic(s)
b725a0ca 225 char *s;
8cbb423c 226{
68503f9a 227 int bootopt = RB_AUTOBOOT;
843267b1 228
68503f9a
BJ
229 if (panicstr)
230 bootopt |= RB_NOSYNC;
cddce008 231 else {
961945a8 232 panicstr = s;
961945a8 233 }
a9c526c1 234 printf("panic: %s\n", s);
b725a0ca 235 boot(RB_PANIC, bootopt);
8cbb423c
BJ
236}
237
fdd11a14
BJ
238/*
239 * Warn that a system table is full.
240 */
241tablefull(tab)
242 char *tab;
243{
244
bd10af3f 245 log(KERN_FAIL, "%s: table is full\n", tab);
fdd11a14
BJ
246}
247
b725a0ca
BJ
248/*
249 * Hard error is the preface to plaintive error messages
fdd11a14 250 * about failing disk transfers.
b725a0ca 251 */
fdd11a14 252harderr(bp, cp)
3c79e4ff 253 struct buf *bp;
fdd11a14 254 char *cp;
8cbb423c
BJ
255{
256
fdd11a14
BJ
257 printf("%s%d%c: hard error sn%d ", cp,
258 dkunit(bp), 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
8cbb423c 259}
b725a0ca 260
96d38f03 261/*
843267b1 262 * Print a character on console or users terminal.
96d38f03
BJ
263 * If destination is console then the last MSGBUFS characters
264 * are saved in msgbuf for inspection later.
265 */
49c84d3f 266/*ARGSUSED*/
8d907ccf 267putchar(c, flags, tp)
843267b1 268 register int c;
8d907ccf 269 struct tty *tp;
96d38f03 270{
8d907ccf 271 extern struct tty cons;
96d38f03 272
34ef3482 273 if (flags & TOTTY) {
8d907ccf
MK
274 if (tp == (struct tty *)NULL && (flags & TOCONS) == 0)
275 tp = &cons;
34ef3482 276 if (tp && (tp->t_state & TS_CARR_ON)) {
843267b1
BJ
277 register s = spl6();
278 if (c == '\n')
2752c877
BJ
279 (void) ttyoutput('\r', tp);
280 (void) ttyoutput(c, tp);
d11b28dc
RE
281 ttstart(tp);
282 splx(s);
283 }
d11b28dc 284 }
34ef3482 285 if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177
b4e32d36 286#ifdef vax
cddce008
BJ
287 && mfpr(MAPEN)
288#endif
289 ) {
90f8d91f 290 if (msgbuf.msg_magic != MSG_MAGIC) {
76db4195
SL
291 register int i;
292
90f8d91f 293 msgbuf.msg_magic = MSG_MAGIC;
34ef3482 294 msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
76db4195
SL
295 for (i=0; i < MSG_BSIZE; i++)
296 msgbuf.msg_bufc[i] = 0;
90f8d91f
BJ
297 }
298 if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
299 msgbuf.msg_bufx = 0;
300 msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
96d38f03 301 }
34ef3482
RC
302 if ((flags & TOCONS) && c != '\0')
303 cnputc(c);
96d38f03 304}