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
getignored(char * auxname)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
lexsort(const void * arg1,const void * arg2)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
search_ignore(char * key)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
discardit(Eptr errorp)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