1: /*
   2:  * Copyright (c) 1982, 1986 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	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   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"
  20: #include "ioctl.h"
  21: #include "tty.h"
  22: #include "syslog.h"
  23: 
  24: #ifdef vax
  25: #include "../vax/mtpr.h"
  26: #endif
  27: 
  28: #define TOCONS  0x1
  29: #define TOTTY   0x2
  30: #define TOLOG   0x4
  31: 
  32: /*
  33:  * In case console is off,
  34:  * panicstr contains argument to last
  35:  * call to panic.
  36:  */
  37: char    *panicstr;
  38: 
  39: /*
  40:  * Scaled down version of C Library printf.
  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:
  55:  *	reg=3<BITTWO,BITONE>
  56:  */
  57: /*VARARGS1*/
  58: printf(fmt, x1)
  59:     char *fmt;
  60:     unsigned x1;
  61: {
  62: 
  63:     prf(fmt, &x1, TOCONS | TOLOG, (struct tty *)0);
  64:     logwakeup();
  65: }
  66: 
  67: /*
  68:  * Uprintf prints to the current user's terminal.
  69:  * It may block if the tty queue is overfull.
  70:  * Should determine whether current terminal user is related
  71:  * to this process.
  72:  */
  73: /*VARARGS1*/
  74: uprintf(fmt, x1)
  75:     char *fmt;
  76:     unsigned x1;
  77: {
  78: #ifdef notdef
  79:     register struct proc *p;
  80: #endif
  81:     register struct tty *tp;
  82: 
  83:     if ((tp = u.u_ttyp) == NULL)
  84:         return;
  85: #ifdef notdef
  86:     if (tp->t_pgrp && (p = pfind(tp->t_pgrp)))
  87:         if (p->p_uid != u.u_uid)    /* doesn't account for setuid */
  88:             return;
  89: #endif
  90:     (void)ttycheckoutq(tp, 1);
  91:     prf(fmt, &x1, TOTTY, tp);
  92: }
  93: 
  94: /*
  95:  * tprintf prints on the specified terminal (console if none)
  96:  * and logs the message.  It is designed for error messages from
  97:  * single-open devices, and may be called from interrupt level
  98:  * (does not sleep).
  99:  */
 100: /*VARARGS2*/
 101: tprintf(tp, fmt, x1)
 102:     register struct tty *tp;
 103:     char *fmt;
 104:     unsigned x1;
 105: {
 106:     int flags = TOTTY | TOLOG;
 107:     extern struct tty cons;
 108: 
 109:     logpri(LOG_INFO);
 110:     if (tp == (struct tty *)NULL)
 111:         tp = &cons;
 112:     if (ttycheckoutq(tp, 0) == 0)
 113:         flags = TOLOG;
 114:     prf(fmt, &x1, flags, tp);
 115:     logwakeup();
 116: }
 117: 
 118: /*
 119:  * Log writes to the log buffer,
 120:  * and guarantees not to sleep (so can be called by interrupt routines).
 121:  * If there is no process reading the log yet, it writes to the console also.
 122:  */
 123: /*VARARGS2*/
 124: log(level, fmt, x1)
 125:     char *fmt;
 126:     unsigned x1;
 127: {
 128:     register s = splhigh();
 129:     extern int log_open;
 130: 
 131:     logpri(level);
 132:     prf(fmt, &x1, TOLOG, (struct tty *)0);
 133:     splx(s);
 134:     if (!log_open)
 135:         prf(fmt, &x1, TOCONS, (struct tty *)0);
 136:     logwakeup();
 137: }
 138: 
 139: logpri(level)
 140:     int level;
 141: {
 142: 
 143:     putchar('<', TOLOG, (struct tty *)0);
 144:     printn((u_long)level, 10, TOLOG, (struct tty *)0);
 145:     putchar('>', TOLOG, (struct tty *)0);
 146: }
 147: 
 148: prf(fmt, adx, flags, ttyp)
 149:     register char *fmt;
 150:     register u_int *adx;
 151:     struct tty *ttyp;
 152: {
 153:     register int b, c, i;
 154:     char *s;
 155:     int any;
 156: 
 157: loop:
 158:     while ((c = *fmt++) != '%') {
 159:         if (c == '\0')
 160:             return;
 161:         putchar(c, flags, ttyp);
 162:     }
 163: again:
 164:     c = *fmt++;
 165:     /* THIS CODE IS VAX DEPENDENT IN HANDLING %l? AND %c */
 166:     switch (c) {
 167: 
 168:     case 'l':
 169:         goto again;
 170:     case 'x': case 'X':
 171:         b = 16;
 172:         goto number;
 173:     case 'd': case 'D':
 174:     case 'u':       /* what a joke */
 175:         b = 10;
 176:         goto number;
 177:     case 'o': case 'O':
 178:         b = 8;
 179: number:
 180:         printn((u_long)*adx, b, flags, ttyp);
 181:         break;
 182:     case 'c':
 183:         b = *adx;
 184:         for (i = 24; i >= 0; i -= 8)
 185:             if (c = (b >> i) & 0x7f)
 186:                 putchar(c, flags, ttyp);
 187:         break;
 188:     case 'b':
 189:         b = *adx++;
 190:         s = (char *)*adx;
 191:         printn((u_long)b, *s++, flags, ttyp);
 192:         any = 0;
 193:         if (b) {
 194:             while (i = *s++) {
 195:                 if (b & (1 << (i-1))) {
 196:                     putchar(any? ',' : '<', flags, ttyp);
 197:                     any = 1;
 198:                     for (; (c = *s) > 32; s++)
 199:                         putchar(c, flags, ttyp);
 200:                 } else
 201:                     for (; *s > 32; s++)
 202:                         ;
 203:             }
 204:             if (any)
 205:                 putchar('>', flags, ttyp);
 206:         }
 207:         break;
 208: 
 209:     case 's':
 210:         s = (char *)*adx;
 211:         while (c = *s++)
 212:             putchar(c, flags, ttyp);
 213:         break;
 214: 
 215:     case '%':
 216:         putchar('%', flags, ttyp);
 217:         break;
 218:     }
 219:     adx++;
 220:     goto loop;
 221: }
 222: 
 223: /*
 224:  * Printn prints a number n in base b.
 225:  * We don't use recursion to avoid deep kernel stacks.
 226:  */
 227: printn(n, b, flags, ttyp)
 228:     u_long n;
 229:     struct tty *ttyp;
 230: {
 231:     char prbuf[11];
 232:     register char *cp;
 233: 
 234:     if (b == 10 && (int)n < 0) {
 235:         putchar('-', flags, ttyp);
 236:         n = (unsigned)(-(int)n);
 237:     }
 238:     cp = prbuf;
 239:     do {
 240:         *cp++ = "0123456789abcdef"[n%b];
 241:         n /= b;
 242:     } while (n);
 243:     do
 244:         putchar(*--cp, flags, ttyp);
 245:     while (cp > prbuf);
 246: }
 247: 
 248: /*
 249:  * Panic is called on unresolvable fatal errors.
 250:  * It prints "panic: mesg", and then reboots.
 251:  * If we are called twice, then we avoid trying to
 252:  * sync the disks as this often leads to recursive panics.
 253:  */
 254: panic(s)
 255:     char *s;
 256: {
 257:     int bootopt = RB_AUTOBOOT;
 258: 
 259:     if (panicstr)
 260:         bootopt |= RB_NOSYNC;
 261:     else {
 262:         panicstr = s;
 263:     }
 264:     printf("panic: %s\n", s);
 265:     boot(RB_PANIC, bootopt);
 266: }
 267: 
 268: /*
 269:  * Warn that a system table is full.
 270:  */
 271: tablefull(tab)
 272:     char *tab;
 273: {
 274: 
 275:     log(LOG_ERR, "%s: table is full\n", tab);
 276: }
 277: 
 278: /*
 279:  * Hard error is the preface to plaintive error messages
 280:  * about failing disk transfers.
 281:  */
 282: harderr(bp, cp)
 283:     struct buf *bp;
 284:     char *cp;
 285: {
 286: 
 287:     printf("%s%d%c: hard error sn%d ", cp,
 288:         minor(bp->b_dev) >> 3, 'a'+(minor(bp->b_dev)&07), bp->b_blkno);
 289: }
 290: 
 291: /*
 292:  * Print a character on console or users terminal.
 293:  * If destination is console then the last MSGBUFS characters
 294:  * are saved in msgbuf for inspection later.
 295:  */
 296: /*ARGSUSED*/
 297: putchar(c, flags, tp)
 298:     register int c;
 299:     struct tty *tp;
 300: {
 301: 
 302:     if (flags & TOTTY) {
 303:         register s = spltty();
 304: 
 305:         if (tp && (tp->t_state & (TS_CARR_ON | TS_ISOPEN)) ==
 306:             (TS_CARR_ON | TS_ISOPEN)) {
 307:             if (c == '\n')
 308:                 (void) ttyoutput('\r', tp);
 309:             (void) ttyoutput(c, tp);
 310:             ttstart(tp);
 311:         }
 312:         splx(s);
 313:     }
 314:     if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177
 315: #ifdef vax
 316:         && mfpr(MAPEN)
 317: #endif
 318:         ) {
 319:         if (msgbuf.msg_magic != MSG_MAGIC) {
 320:             register int i;
 321: 
 322:             msgbuf.msg_magic = MSG_MAGIC;
 323:             msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
 324:             for (i=0; i < MSG_BSIZE; i++)
 325:                 msgbuf.msg_bufc[i] = 0;
 326:         }
 327:         msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
 328:         if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
 329:             msgbuf.msg_bufx = 0;
 330:     }
 331:     if ((flags & TOCONS) && c != '\0')
 332:         cnputc(c);
 333: }

Defined functions

logpri defined in line 139; used 2 times
panic defined in line 254; used 233 times
prf defined in line 148; used 5 times
printf defined in line 58; used 2 times
printn defined in line 227; used 3 times
putchar defined in line 297; used 11 times

Defined variables

panicstr defined in line 37; used 2 times

Defined macros

TOCONS defined in line 28; used 3 times
TOLOG defined in line 30; used 8 times
TOTTY defined in line 29; used 3 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1061
Valid CSS Valid XHTML 1.0 Strict