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 /* 31 * pfmt_print() - format and print 32 */ 33 #include "lint.h" 34 #include "mtlib.h" 35 #include <pfmt.h> 36 #include <stdio.h> 37 #include <stdarg.h> 38 #include <string.h> 39 #include <thread.h> 40 #include <ctype.h> 41 #include "pfmt_data.h" 42 43 /* Catalogue for local messages */ 44 #define fmt_cat "uxlibc" 45 #define def_colon ": " 46 #define def_colonid 2 47 48 /* Table of default severities */ 49 static const char *sev_list[] = { 50 "SEV = %d", 51 "TO FIX", 52 "ERROR", 53 "HALT", 54 "WARNING", 55 "INFO" 56 }; 57 58 int 59 __pfmt_print(FILE *stream, long flag, const char *format, 60 const char **text_ptr, const char **sev_ptr, va_list args) 61 { 62 const char *ptr; 63 char catbuf[DB_NAME_LEN]; 64 int i, status; 65 int length = 0; 66 int txtmsgnum = 0; 67 int dofmt = (flag & (long)MM_NOSTD) == 0; 68 long doact = (flag & (long)MM_ACTION); 69 70 if (format && !(flag & (long)MM_NOGET)) { 71 char c; 72 ptr = format; 73 for (i = 0; i < DB_NAME_LEN - 1 && (c = *ptr++) && c != ':'; 74 i++) 75 catbuf[i] = c; 76 /* Extract the message number */ 77 if (i != DB_NAME_LEN - 1 && c) { 78 catbuf[i] = '\0'; 79 while (isdigit(c = *ptr++)) { 80 txtmsgnum *= 10; 81 txtmsgnum += c - '0'; 82 } 83 if (c != ':') 84 txtmsgnum = -1; 85 } 86 else 87 txtmsgnum = -1; 88 format = __gtxt(catbuf, txtmsgnum, ptr); 89 90 } 91 92 if (text_ptr) 93 *text_ptr = format; 94 if (dofmt) { 95 char label[MAXLABEL]; 96 int severity, sev, d_sev; 97 const char *psev = NULL, *colon; 98 99 lrw_rdlock(&_rw_pfmt_label); 100 (void) strlcpy(label, __pfmt_label, MAXLABEL); 101 lrw_unlock(&_rw_pfmt_label); 102 103 colon = __gtxt(fmt_cat, def_colonid, def_colon); 104 105 if (label[0] != '\0' && stream) { 106 if ((status = fputs(label, stream)) < 0) 107 return (-1); 108 length += status; 109 if ((status = fputs(colon, stream)) < 0) 110 return (-1); 111 length += status; 112 } 113 114 severity = (int)(flag & 0xff); 115 116 if (doact) { 117 d_sev = sev = 1; 118 } else if (severity <= MM_INFO) { 119 sev = severity + 3; 120 d_sev = severity + 2; 121 } else { 122 int i; 123 lrw_rdlock(&_rw_pfmt_sev_tab); 124 for (i = 0; i < __pfmt_nsev; i++) { 125 if (__pfmt_sev_tab[i].severity == severity) { 126 psev = __pfmt_sev_tab[i].string; 127 d_sev = sev = -1; 128 break; 129 } 130 } 131 lrw_unlock(&_rw_pfmt_sev_tab); 132 if (i == __pfmt_nsev) 133 d_sev = sev = 0; 134 } 135 136 if (sev >= 0) { 137 psev = __gtxt(fmt_cat, sev, sev_list[d_sev]); 138 } 139 140 if (sev_ptr) 141 *sev_ptr = psev; 142 143 if (stream) { 144 if ((status = fprintf(stream, psev, severity)) < 0) 145 return (-1); 146 length += status; 147 if ((status = fputs(colon, stream)) < 0) 148 return (-1); 149 length += status; 150 } else 151 return (-1); 152 } else if (sev_ptr) 153 *sev_ptr = NULL; 154 155 if (stream) { 156 if ((status = vfprintf(stream, format, args)) < 0) 157 return (-1); 158 length += status; 159 } else 160 return (-1); 161 162 return (length); 163 } 164