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