1*753d2d2eSraf /* 2*753d2d2eSraf * CDDL HEADER START 3*753d2d2eSraf * 4*753d2d2eSraf * The contents of this file are subject to the terms of the 5*753d2d2eSraf * Common Development and Distribution License, Version 1.0 only 6*753d2d2eSraf * (the "License"). You may not use this file except in compliance 7*753d2d2eSraf * with the License. 8*753d2d2eSraf * 9*753d2d2eSraf * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*753d2d2eSraf * or http://www.opensolaris.org/os/licensing. 11*753d2d2eSraf * See the License for the specific language governing permissions 12*753d2d2eSraf * and limitations under the License. 13*753d2d2eSraf * 14*753d2d2eSraf * When distributing Covered Code, include this CDDL HEADER in each 15*753d2d2eSraf * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*753d2d2eSraf * If applicable, add the following below this CDDL HEADER, with the 17*753d2d2eSraf * fields enclosed by brackets "[]" replaced with your own identifying 18*753d2d2eSraf * information: Portions Copyright [yyyy] [name of copyright owner] 19*753d2d2eSraf * 20*753d2d2eSraf * CDDL HEADER END 21*753d2d2eSraf */ 22*753d2d2eSraf /* 23*753d2d2eSraf * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*753d2d2eSraf * Use is subject to license terms. 25*753d2d2eSraf */ 26*753d2d2eSraf 27*753d2d2eSraf #pragma ident "%Z%%M% %I% %E% SMI" 28*753d2d2eSraf 29*753d2d2eSraf /* 30*753d2d2eSraf * errlog -- error logging facility for application programs 31*753d2d2eSraf */ 32*753d2d2eSraf 33*753d2d2eSraf #include <stdio.h> 34*753d2d2eSraf #include <stdarg.h> 35*753d2d2eSraf #include <stdlib.h> 36*753d2d2eSraf #include "errlog.h" 37*753d2d2eSraf 38*753d2d2eSraf /* Statics (this object is not threadable). */ 39*753d2d2eSraf static int Severity; 40*753d2d2eSraf static struct location { 41*753d2d2eSraf char *l_file; 42*753d2d2eSraf int l_lineno; 43*753d2d2eSraf char *l_tag; 44*753d2d2eSraf char *l_line; 45*753d2d2eSraf } Location; 46*753d2d2eSraf 47*753d2d2eSraf /* Indentation */ 48*753d2d2eSraf static int Trace_indent; 49*753d2d2eSraf /* XXX YES, its 80 spaces !@#$%^ */ 50*753d2d2eSraf static char Trace_padding[] = 51*753d2d2eSraf " " 52*753d2d2eSraf " "; 53*753d2d2eSraf 54*753d2d2eSraf #define INDENT &Trace_padding[80-(Trace_indent*4)] 55*753d2d2eSraf #define PRINTHDR INPUT 56*753d2d2eSraf 57*753d2d2eSraf /* 58*753d2d2eSraf * errlog -- simulate the syslog printf-like interface, but 59*753d2d2eSraf * with a first argument oriented toward reporting 60*753d2d2eSraf * application errors. 61*753d2d2eSraf */ 62*753d2d2eSraf /*VARARGS2*/ 63*753d2d2eSraf void 64*753d2d2eSraf errlog(const int descriptor, const char *format, ...) 65*753d2d2eSraf { 66*753d2d2eSraf va_list ap; 67*753d2d2eSraf 68*753d2d2eSraf va_start(ap, format); 69*753d2d2eSraf if ((Severity < (descriptor & FATAL)) && 70*753d2d2eSraf ((descriptor & FATAL) != FATAL)) { 71*753d2d2eSraf /* We don't need to say/do anything. */ 72*753d2d2eSraf return; 73*753d2d2eSraf } 74*753d2d2eSraf 75*753d2d2eSraf /* Produce the message. */ 76*753d2d2eSraf (void) fflush(stdout); /* Synchronize streams. */ 77*753d2d2eSraf if ((descriptor & PRINTHDR) != 0) { 78*753d2d2eSraf if (Location.l_file == NULL) { 79*753d2d2eSraf (void) fprintf(stderr, "programmer error, logerr " 80*753d2d2eSraf "told to print file, line number, " 81*753d2d2eSraf "but file was not set.\n"); 82*753d2d2eSraf } else { 83*753d2d2eSraf (void) fprintf(stderr, "\"%s\", line %d: ", 84*753d2d2eSraf Location.l_file, Location.l_lineno); 85*753d2d2eSraf } 86*753d2d2eSraf } 87*753d2d2eSraf 88*753d2d2eSraf /* Indent/outdent. */ 89*753d2d2eSraf if (descriptor & INDENTED) { 90*753d2d2eSraf (void) fprintf(stderr, "%s", INDENT); 91*753d2d2eSraf Trace_indent = (Trace_indent < 20)? Trace_indent + 1: 20; 92*753d2d2eSraf } else if (descriptor & OUTDENTED) { 93*753d2d2eSraf Trace_indent = (Trace_indent > 0)? Trace_indent - 1: 0; 94*753d2d2eSraf (void) fprintf(stderr, "%s", INDENT); 95*753d2d2eSraf } else { 96*753d2d2eSraf (void) fprintf(stderr, "%s", INDENT); 97*753d2d2eSraf } 98*753d2d2eSraf 99*753d2d2eSraf /* Print the stuff we did all this for. */ 100*753d2d2eSraf (void) vfprintf(stderr, format, ap); 101*753d2d2eSraf 102*753d2d2eSraf if ((descriptor & INPUT) && Location.l_line != NULL) { 103*753d2d2eSraf /* Emit trailers. Formatting TBD. */ 104*753d2d2eSraf (void) putc('\n', stderr); 105*753d2d2eSraf (void) fprintf(stderr, "\tLine was: %s %s", 106*753d2d2eSraf Location.l_tag, Location.l_line); 107*753d2d2eSraf } 108*753d2d2eSraf (void) putc('\n', stderr); 109*753d2d2eSraf (void) fflush(stderr); /* No-op on Solaris. */ 110*753d2d2eSraf 111*753d2d2eSraf if ((descriptor & FATAL) == FATAL) { 112*753d2d2eSraf /* Say goodbye! */ 113*753d2d2eSraf exit(1); 114*753d2d2eSraf } 115*753d2d2eSraf va_end(ap); 116*753d2d2eSraf } 117*753d2d2eSraf 118*753d2d2eSraf /* 119*753d2d2eSraf * seterrline -- tell errlog what the context of the error is. 120*753d2d2eSraf */ 121*753d2d2eSraf void 122*753d2d2eSraf seterrline(const int lineno, const char *file, 123*753d2d2eSraf const char *tag, const char *line) 124*753d2d2eSraf { 125*753d2d2eSraf Location.l_lineno = lineno; 126*753d2d2eSraf Location.l_file = (char *)file; 127*753d2d2eSraf Location.l_tag = (char *)tag; 128*753d2d2eSraf Location.l_line = (char *)line; 129*753d2d2eSraf } 130*753d2d2eSraf 131*753d2d2eSraf /* 132*753d2d2eSraf * seterrseverity -- set the severity/loudness variable. 133*753d2d2eSraf * This is traditionally the ``Verbosity'' level. 134*753d2d2eSraf */ 135*753d2d2eSraf void 136*753d2d2eSraf seterrseverity(const int loudness) 137*753d2d2eSraf { 138*753d2d2eSraf Severity = (loudness & FATAL); 139*753d2d2eSraf } 140