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 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 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 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 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