1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * pfmt_print() - format and print 34 */ 35 #include "lint.h" 36 #include "mtlib.h" 37 #include <pfmt.h> 38 #include <stdio.h> 39 #include <stdarg.h> 40 #include <string.h> 41 #include <thread.h> 42 #include <ctype.h> 43 #include "pfmt_data.h" 44 45 /* Catalogue for local messages */ 46 #define fmt_cat "uxlibc" 47 #define def_colon ": " 48 #define def_colonid 2 49 50 /* Table of default severities */ 51 static const char *sev_list[] = { 52 "SEV = %d", 53 "TO FIX", 54 "ERROR", 55 "HALT", 56 "WARNING", 57 "INFO" 58 }; 59 60 int 61 __pfmt_print(FILE *stream, long flag, const char *format, 62 const char **text_ptr, const char **sev_ptr, va_list args) 63 { 64 const char *ptr; 65 char catbuf[DB_NAME_LEN]; 66 int i, status; 67 int length = 0; 68 int txtmsgnum = 0; 69 int dofmt = (flag & (long)MM_NOSTD) == 0; 70 long doact = (flag & (long)MM_ACTION); 71 72 if (format && !(flag & (long)MM_NOGET)) { 73 char c; 74 ptr = format; 75 for (i = 0; i < DB_NAME_LEN - 1 && (c = *ptr++) && c != ':'; 76 i++) 77 catbuf[i] = c; 78 /* Extract the message number */ 79 if (i != DB_NAME_LEN - 1 && c) { 80 catbuf[i] = '\0'; 81 while (isdigit(c = *ptr++)) { 82 txtmsgnum *= 10; 83 txtmsgnum += c - '0'; 84 } 85 if (c != ':') 86 txtmsgnum = -1; 87 } 88 else 89 txtmsgnum = -1; 90 format = __gtxt(catbuf, txtmsgnum, ptr); 91 92 } 93 94 if (text_ptr) 95 *text_ptr = format; 96 if (dofmt) { 97 char label[MAXLABEL]; 98 int severity, sev, d_sev; 99 const char *psev = NULL, *colon; 100 101 lrw_rdlock(&_rw_pfmt_label); 102 (void) strlcpy(label, __pfmt_label, MAXLABEL); 103 lrw_unlock(&_rw_pfmt_label); 104 105 colon = __gtxt(fmt_cat, def_colonid, def_colon); 106 107 if (label[0] != '\0' && stream) { 108 if ((status = fputs(label, stream)) < 0) 109 return (-1); 110 length += status; 111 if ((status = fputs(colon, stream)) < 0) 112 return (-1); 113 length += status; 114 } 115 116 severity = (int)(flag & 0xff); 117 118 if (doact) { 119 d_sev = sev = 1; 120 } else if (severity <= MM_INFO) { 121 sev = severity + 3; 122 d_sev = severity + 2; 123 } else { 124 int i; 125 lrw_rdlock(&_rw_pfmt_sev_tab); 126 for (i = 0; i < __pfmt_nsev; i++) { 127 if (__pfmt_sev_tab[i].severity == severity) { 128 psev = __pfmt_sev_tab[i].string; 129 d_sev = sev = -1; 130 break; 131 } 132 } 133 lrw_unlock(&_rw_pfmt_sev_tab); 134 if (i == __pfmt_nsev) 135 d_sev = sev = 0; 136 } 137 138 if (sev >= 0) { 139 psev = __gtxt(fmt_cat, sev, sev_list[d_sev]); 140 } 141 142 if (sev_ptr) 143 *sev_ptr = psev; 144 145 if (stream) { 146 if ((status = fprintf(stream, psev, severity)) < 0) 147 return (-1); 148 length += status; 149 if ((status = fputs(colon, stream)) < 0) 150 return (-1); 151 length += status; 152 } else 153 return (-1); 154 } else if (sev_ptr) 155 *sev_ptr = NULL; 156 157 if (stream) { 158 if ((status = vfprintf(stream, format, args)) < 0) 159 return (-1); 160 length += status; 161 } else 162 return (-1); 163 164 return (length); 165 } 166