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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <sys/param.h> 30 #include <sys/wait.h> 31 #include <unistd.h> 32 #include <libintl.h> 33 34 #include <vroot/report.h> 35 #include <vroot/vroot.h> 36 #include <mk/defs.h> /* for tmpdir */ 37 38 static FILE *report_file; 39 static FILE *command_output_fp; 40 static char *target_being_reported_for; 41 static char *search_dir; 42 static char command_output_tmpfile[30]; 43 static int is_path = 0; 44 static char sfile[MAXPATHLEN]; 45 extern "C" { 46 static void (*warning_ptr) (char *, ...) = (void (*) (char *, ...)) NULL; 47 } 48 49 FILE * 50 get_report_file(void) 51 { 52 return(report_file); 53 } 54 55 char * 56 get_target_being_reported_for(void) 57 { 58 return(target_being_reported_for); 59 } 60 61 extern "C" { 62 static void 63 close_report_file(void) 64 { 65 (void)fputs("\n", report_file); 66 (void)fclose(report_file); 67 } 68 } // extern "C" 69 70 static void 71 clean_up(FILE *nse_depinfo_fp, FILE *merge_fp, char *nse_depinfo_file, char *merge_file, int unlinkf) 72 { 73 fclose(nse_depinfo_fp); 74 fclose(merge_fp); 75 fclose(command_output_fp); 76 unlink(command_output_tmpfile); 77 if (unlinkf) 78 unlink(merge_file); 79 else 80 rename(merge_file, nse_depinfo_file); 81 } 82 83 84 /* 85 * Update the file, if necessary. We don't want to rewrite 86 * the file if we don't have to because we don't want the time of the file 87 * to change in that case. 88 */ 89 90 extern "C" { 91 static void 92 close_file(void) 93 { 94 char line[MAXPATHLEN+2]; 95 char buf[MAXPATHLEN+2]; 96 FILE *nse_depinfo_fp; 97 FILE *merge_fp; 98 char nse_depinfo_file[MAXPATHLEN]; 99 char merge_file[MAXPATHLEN]; 100 char lock_file[MAXPATHLEN]; 101 int err; 102 int len; 103 int changed = 0; 104 int file_locked; 105 106 fprintf(command_output_fp, "\n"); 107 fclose(command_output_fp); 108 if ((command_output_fp = fopen(command_output_tmpfile, "r")) == NULL) { 109 return; 110 } 111 sprintf(nse_depinfo_file, "%s/%s", search_dir, NSE_DEPINFO); 112 sprintf(merge_file, "%s/.tmp%s.%d", search_dir, NSE_DEPINFO, getpid()); 113 sprintf(lock_file, "%s/%s", search_dir, NSE_DEPINFO_LOCK); 114 err = file_lock(nse_depinfo_file, lock_file, &file_locked, 0); 115 if (err) { 116 if (warning_ptr != (void (*) (char *, ...)) NULL) { 117 (*warning_ptr)(gettext("Couldn't write to %s"), nse_depinfo_file); 118 } 119 unlink(command_output_tmpfile); 120 return; 121 } 122 /* If .nse_depinfo file doesn't exist */ 123 if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) { 124 if (is_path) { 125 if ((nse_depinfo_fp = 126 fopen(nse_depinfo_file, "w")) == NULL) { 127 fprintf(stderr, gettext("Cannot open `%s' for writing\n"), 128 nse_depinfo_file); 129 unlink(command_output_tmpfile); 130 131 unlink(lock_file); 132 return; 133 } 134 while (fgets(line, MAXPATHLEN+2, command_output_fp) 135 != NULL) { 136 fprintf(nse_depinfo_fp, "%s", line); 137 } 138 fclose(command_output_fp); 139 } 140 fclose(nse_depinfo_fp); 141 if (file_locked) { 142 unlink(lock_file); 143 } 144 unlink(command_output_tmpfile); 145 return; 146 } 147 if ((merge_fp = fopen(merge_file, "w")) == NULL) { 148 fprintf(stderr, gettext("Cannot open %s for writing\n"), merge_file); 149 if (file_locked) { 150 unlink(lock_file); 151 } 152 unlink(command_output_tmpfile); 153 return; 154 } 155 len = strlen(sfile); 156 while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) { 157 if (strncmp(line, sfile, len) == 0 && line[len] == ':') { 158 while (fgets(buf, MAXPATHLEN+2, command_output_fp) 159 != NULL) { 160 if (is_path) { 161 fprintf(merge_fp, "%s", buf); 162 if (strcmp(line, buf)) { 163 /* changed */ 164 changed = 1; 165 } 166 } 167 if (buf[strlen(buf)-1] == '\n') { 168 break; 169 } 170 } 171 if (changed || !is_path) { 172 while (fgets(line, MAXPATHLEN, nse_depinfo_fp) 173 != NULL) { 174 fputs(line, merge_fp); 175 } 176 clean_up(nse_depinfo_fp, merge_fp, 177 nse_depinfo_file, merge_file, 0); 178 } else { 179 clean_up(nse_depinfo_fp, merge_fp, 180 nse_depinfo_file, merge_file, 1); 181 } 182 if (file_locked) { 183 unlink(lock_file); 184 } 185 unlink(command_output_tmpfile); 186 return; 187 } /* entry found */ 188 fputs(line, merge_fp); 189 } 190 /* Entry never found. Add it if there is a search path */ 191 if (is_path) { 192 while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) { 193 fprintf(nse_depinfo_fp, "%s", line); 194 } 195 } 196 clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1); 197 if (file_locked) { 198 unlink(lock_file); 199 } 200 } 201 202 } // extern "C" 203 204 static void 205 report_dep(char *iflag, char *filename) 206 { 207 208 if (command_output_fp == NULL) { 209 sprintf(command_output_tmpfile, 210 "%s/%s.%d.XXXXXX", tmpdir, NSE_DEPINFO, getpid()); 211 int fd = mkstemp(command_output_tmpfile); 212 if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) { 213 return; 214 } 215 if ((search_dir = getenv("NSE_DEP")) == NULL) { 216 return; 217 } 218 atexit(close_file); 219 strcpy(sfile, filename); 220 if (iflag == NULL || *iflag == '\0') { 221 return; 222 } 223 fprintf(command_output_fp, "%s:", sfile); 224 } 225 fprintf(command_output_fp, " "); 226 fprintf(command_output_fp, iflag); 227 if (iflag != NULL) { 228 is_path = 1; 229 } 230 } 231 232 void 233 report_libdep(char *lib, char *flag) 234 { 235 char *ptr; 236 char filename[MAXPATHLEN]; 237 char *p; 238 239 if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { 240 return; 241 } 242 ptr = strchr(p, ' '); 243 if(ptr) { 244 sprintf(filename, "%s-%s", ptr+1, flag); 245 is_path = 1; 246 report_dep(lib, filename); 247 } 248 } 249 250 void 251 report_search_path(char *iflag) 252 { 253 char curdir[MAXPATHLEN]; 254 char *sdir; 255 char *newiflag; 256 char filename[MAXPATHLEN]; 257 char *p, *ptr; 258 259 if ((sdir = getenv("NSE_DEP")) == NULL) { 260 return; 261 } 262 if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { 263 return; 264 } 265 ptr = strchr(p, ' '); 266 if( ! ptr ) { 267 return; 268 } 269 sprintf(filename, "%s-CPP", ptr+1); 270 getcwd(curdir, sizeof(curdir)); 271 if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 && 272 iflag[2] != '/') { 273 /* Makefile must have had an "cd xx; cc ..." */ 274 /* Modify the -I path to be relative to the cd */ 275 newiflag = (char *)malloc(strlen(iflag) + strlen(curdir) + 2); 276 sprintf(newiflag, "-%c%s/%s", iflag[1], curdir, &iflag[2]); 277 report_dep(newiflag, filename); 278 } else { 279 report_dep(iflag, filename); 280 } 281 } 282 283 void 284 report_dependency(const char *name) 285 { 286 register char *filename; 287 char buffer[MAXPATHLEN+1]; 288 register char *p; 289 register char *p2; 290 char nse_depinfo_file[MAXPATHLEN]; 291 292 if (report_file == NULL) { 293 if ((filename= getenv(SUNPRO_DEPENDENCIES)) == NULL) { 294 report_file = (FILE *)-1; 295 return; 296 } 297 if (strlen(filename) == 0) { 298 report_file = (FILE *)-1; 299 return; 300 } 301 (void)strcpy(buffer, name); 302 name = buffer; 303 p = strchr(filename, ' '); 304 if(p) { 305 *p= 0; 306 } else { 307 report_file = (FILE *)-1; 308 return; 309 } 310 if ((report_file= fopen(filename, "a")) == NULL) { 311 if ((report_file= fopen(filename, "w")) == NULL) { 312 report_file= (FILE *)-1; 313 return; 314 } 315 } 316 atexit(close_report_file); 317 if ((p2= strchr(p+1, ' ')) != NULL) 318 *p2= 0; 319 target_being_reported_for= (char *)malloc((unsigned)(strlen(p+1)+1)); 320 (void)strcpy(target_being_reported_for, p+1); 321 (void)fputs(p+1, report_file); 322 (void)fputs(":", report_file); 323 *p= ' '; 324 if (p2 != NULL) 325 *p2= ' '; 326 } 327 if (report_file == (FILE *)-1) 328 return; 329 (void)fputs(name, report_file); 330 (void)fputs(" ", report_file); 331 } 332 333