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