xref: /illumos-gate/usr/src/cmd/sgs/error/common/errorfilter.c (revision c65ebfc7045424bd04a6c7719a27b0ad3399ad54)
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 /*
24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <pwd.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include "error.h"
37 
38 char	*lint_libs[] = {
39 	IG_FILE1,
40 	IG_FILE2,
41 	IG_FILE3,
42 	IG_FILE4,
43 	0
44 };
45 
46 extern	char	*processname;
47 
48 static int lexsort(const void *arg1, const void *arg2);
49 
50 /*
51  *	Read the file ERRORNAME of the names of functions in lint
52  *	to ignore complaints about.
53  */
54 void
55 getignored(char *auxname)
56 {
57 	int	i;
58 	FILE	*fyle;
59 	char	inbuffer[256];
60 	int	uid;
61 	char	filename[128];
62 	char	*username;
63 	struct	passwd *passwdentry;
64 
65 	nignored = 0;
66 	if (auxname == 0) {	/* use the default */
67 		if ((username = (char *)getlogin()) == NULL) {
68 			username = "Unknown";
69 			uid = getuid();
70 			if ((passwdentry = getpwuid(uid)) == NULL) {
71 				return;
72 			}
73 		} else {
74 			if ((passwdentry = getpwnam(username)) == NULL)
75 				return;
76 		}
77 		(void) strcpy(filename, passwdentry->pw_dir);
78 		(void) strcat(filename, ERRORNAME);
79 	} else
80 		(void) strcpy(filename, auxname);
81 #ifdef FULLDEBUG
82 	printf("Opening file \"%s\" to read names to ignore.\n",
83 		filename);
84 #endif
85 	if ((fyle = fopen(filename, "r")) == NULL) {
86 #ifdef FULLDEBUG
87 		fprintf(stderr, "%s: Can't open file \"%s\"\n",
88 			processname, filename);
89 #endif
90 		return;
91 	}
92 	/*
93 	 *	Make the first pass through the file, counting lines
94 	 */
95 	for (nignored = 0; fgets(inbuffer, 255, fyle) != NULL; nignored++)
96 		continue;
97 	names_ignored = Calloc(nignored+1, sizeof (char *));
98 	(void) fclose(fyle);
99 	if (freopen(filename, "r", fyle) == NULL) {
100 #ifdef FULLDEBUG
101 		fprintf(stderr, "%s: Failure to open \"%s\" for second read.\n",
102 			processname, filename);
103 #endif
104 		nignored = 0;
105 		return;
106 	}
107 	for (i = 0; i < nignored && (fgets(inbuffer, 255, fyle) != NULL);
108 	    i++) {
109 		names_ignored[i] = strsave(inbuffer);
110 		(void) substitute(names_ignored[i], '\n', '\0');
111 	}
112 	qsort(names_ignored, nignored, sizeof (*names_ignored), lexsort);
113 #ifdef FULLDEBUG
114 	printf("Names to ignore follow.\n");
115 	for (i = 0; i < nignored; i++) {
116 		printf("\tIgnore: %s\n", names_ignored[i]);
117 	}
118 #endif
119 }
120 
121 static int
122 lexsort(const void *arg1, const void *arg2)
123 {
124 	char **cpp1 = (char **)arg1;
125 	char **cpp2 = (char **)arg2;
126 
127 	return (strcmp(*cpp1, *cpp2));
128 }
129 
130 int
131 search_ignore(char *key)
132 {
133 	int	ub, lb;
134 	int	halfway;
135 	int	order;
136 
137 	if (nignored == 0)
138 		return (-1);
139 	for (lb = 0, ub = nignored - 1; ub >= lb; /* NULL */) {
140 		halfway = (ub + lb)/2;
141 		if ((order = strcmp(key, names_ignored[halfway])) == 0)
142 			return (halfway);
143 		if (order < 0)	/* key is less than probe, throw away above */
144 			ub = halfway - 1;
145 		else
146 			lb = halfway + 1;
147 	}
148 	return (-1);
149 }
150 
151 /*
152  *	Tell if the error text is to be ignored.
153  *	The error must have been canonicalized, with
154  *	the file name the zeroth entry in the errorv,
155  *	and the linenumber the second.
156  *	Return the new categorization of the error class.
157  */
158 Errorclass
159 discardit(Eptr errorp)
160 {
161 	int	language;
162 	int	i;
163 	Errorclass	errorclass = errorp->error_e_class;
164 
165 	switch (errorclass) {
166 	case C_SYNC:
167 	case C_NONSPEC:
168 	case C_UNKNOWN:
169 		return (errorclass);
170 	default:
171 		break;
172 	}
173 	if (errorp->error_lgtext < 2) {
174 		return (C_NONSPEC);
175 	}
176 	language = errorp->error_language;
177 	if (language == INLINT) {
178 		if (errorclass != C_NONSPEC) {	/* no file */
179 			for (i = 0; lint_libs[i] != 0; i++) {
180 				if (strcmp(errorp->error_text[0],
181 				    lint_libs[i]) == 0) {
182 					return (C_DISCARD);
183 				}
184 			}
185 		}
186 		/*
187 		 * check if the argument to the error message
188 		 * is to be ignored
189 		 */
190 		if (ispunct(lastchar(errorp->error_text[2])))
191 			clob_last(errorp->error_text[2], '\0');
192 		if (search_ignore(
193 		    errorp->error_text[errorclass == C_NONSPEC ? 0 : 2]) >= 0) {
194 			return (C_NULLED);
195 		}
196 	}
197 	return (errorclass);
198 }
199