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