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