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 * @(#)report.cc 1.17 06/12/12 27 */ 28 29 #pragma ident "@(#)report.cc 1.17 06/12/12" 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <sys/param.h> 35 #include <sys/wait.h> 36 #include <unistd.h> 37 38 #include <vroot/report.h> 39 #include <vroot/vroot.h> 40 #include <mksdmsi18n/mksdmsi18n.h> 41 #include <avo/intl.h> /* for NOCATGETS */ 42 #include <mk/defs.h> /* for tmpdir */ 43 44 static FILE *report_file; 45 static FILE *command_output_fp; 46 static char *target_being_reported_for; 47 static char *search_dir; 48 static char command_output_tmpfile[30]; 49 static int is_path = 0; 50 static char sfile[MAXPATHLEN]; 51 extern "C" { 52 static void (*warning_ptr) (char *, ...) = (void (*) (char *, ...)) NULL; 53 } 54 55 FILE * 56 get_report_file(void) 57 { 58 return(report_file); 59 } 60 61 char * 62 get_target_being_reported_for(void) 63 { 64 return(target_being_reported_for); 65 } 66 67 #if defined(SUN5_0) || defined(HP_UX) || defined(linux) 68 extern "C" { 69 static void 70 close_report_file(void) 71 { 72 (void)fputs("\n", report_file); 73 (void)fclose(report_file); 74 } 75 } // extern "C" 76 #else 77 static void 78 close_report_file(int, ...) 79 { 80 (void)fputs("\n", report_file); 81 (void)fclose(report_file); 82 } 83 #endif 84 85 static void 86 clean_up(FILE *nse_depinfo_fp, FILE *merge_fp, char *nse_depinfo_file, char *merge_file, int unlinkf) 87 { 88 fclose(nse_depinfo_fp); 89 fclose(merge_fp); 90 fclose(command_output_fp); 91 unlink(command_output_tmpfile); 92 if (unlinkf) 93 unlink(merge_file); 94 else 95 rename(merge_file, nse_depinfo_file); 96 } 97 98 99 /* 100 * Update the file, if necessary. We don't want to rewrite 101 * the file if we don't have to because we don't want the time of the file 102 * to change in that case. 103 */ 104 105 #if defined(SUN5_0) || defined(HP_UX) || defined(linux) 106 extern "C" { 107 static void 108 close_file(void) 109 #else 110 static void 111 close_file(int, ...) 112 #endif 113 { 114 char line[MAXPATHLEN+2]; 115 char buf[MAXPATHLEN+2]; 116 FILE *nse_depinfo_fp; 117 FILE *merge_fp; 118 char nse_depinfo_file[MAXPATHLEN]; 119 char merge_file[MAXPATHLEN]; 120 char lock_file[MAXPATHLEN]; 121 int err; 122 int len; 123 int changed = 0; 124 int file_locked; 125 126 fprintf(command_output_fp, "\n"); 127 fclose(command_output_fp); 128 if ((command_output_fp = fopen(command_output_tmpfile, "r")) == NULL) { 129 return; 130 } 131 sprintf(nse_depinfo_file, "%s/%s", search_dir, NSE_DEPINFO); 132 sprintf(merge_file, NOCATGETS("%s/.tmp%s.%d"), search_dir, NSE_DEPINFO, getpid()); 133 sprintf(lock_file, "%s/%s", search_dir, NSE_DEPINFO_LOCK); 134 err = file_lock(nse_depinfo_file, lock_file, &file_locked, 0); 135 if (err) { 136 if (warning_ptr != (void (*) (char *, ...)) NULL) { 137 (*warning_ptr)(catgets(libmksdmsi18n_catd, 1, 147, "Couldn't write to %s"), nse_depinfo_file); 138 } 139 unlink(command_output_tmpfile); 140 return; 141 } 142 /* If .nse_depinfo file doesn't exist */ 143 if ((nse_depinfo_fp = fopen(nse_depinfo_file, "r+")) == NULL) { 144 if (is_path) { 145 if ((nse_depinfo_fp = 146 fopen(nse_depinfo_file, "w")) == NULL) { 147 fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 148, "Cannot open `%s' for writing\n"), 148 nse_depinfo_file); 149 unlink(command_output_tmpfile); 150 151 unlink(lock_file); 152 return; 153 } 154 while (fgets(line, MAXPATHLEN+2, command_output_fp) 155 != NULL) { 156 fprintf(nse_depinfo_fp, "%s", line); 157 } 158 fclose(command_output_fp); 159 } 160 fclose(nse_depinfo_fp); 161 if (file_locked) { 162 unlink(lock_file); 163 } 164 unlink(command_output_tmpfile); 165 return; 166 } 167 if ((merge_fp = fopen(merge_file, "w")) == NULL) { 168 fprintf(stderr, catgets(libmksdmsi18n_catd, 1, 149, "Cannot open %s for writing\n"), merge_file); 169 if (file_locked) { 170 unlink(lock_file); 171 } 172 unlink(command_output_tmpfile); 173 return; 174 } 175 len = strlen(sfile); 176 while (fgets(line, MAXPATHLEN+2, nse_depinfo_fp) != NULL) { 177 if (strncmp(line, sfile, len) == 0 && line[len] == ':') { 178 while (fgets(buf, MAXPATHLEN+2, command_output_fp) 179 != NULL) { 180 if (is_path) { 181 fprintf(merge_fp, "%s", buf); 182 if (strcmp(line, buf)) { 183 /* changed */ 184 changed = 1; 185 } 186 } 187 if (buf[strlen(buf)-1] == '\n') { 188 break; 189 } 190 } 191 if (changed || !is_path) { 192 while (fgets(line, MAXPATHLEN, nse_depinfo_fp) 193 != NULL) { 194 fputs(line, merge_fp); 195 } 196 clean_up(nse_depinfo_fp, merge_fp, 197 nse_depinfo_file, merge_file, 0); 198 } else { 199 clean_up(nse_depinfo_fp, merge_fp, 200 nse_depinfo_file, merge_file, 1); 201 } 202 if (file_locked) { 203 unlink(lock_file); 204 } 205 unlink(command_output_tmpfile); 206 return; 207 } /* entry found */ 208 fputs(line, merge_fp); 209 } 210 /* Entry never found. Add it if there is a search path */ 211 if (is_path) { 212 while (fgets(line, MAXPATHLEN+2, command_output_fp) != NULL) { 213 fprintf(nse_depinfo_fp, "%s", line); 214 } 215 } 216 clean_up(nse_depinfo_fp, merge_fp, nse_depinfo_file, merge_file, 1); 217 if (file_locked) { 218 unlink(lock_file); 219 } 220 } 221 222 #if defined(SUN5_0) || defined(HP_UX) || defined(linux) 223 } // extern "C" 224 #endif 225 226 static void 227 report_dep(char *iflag, char *filename) 228 { 229 230 if (command_output_fp == NULL) { 231 sprintf(command_output_tmpfile, 232 NOCATGETS("%s/%s.%d.XXXXXX"), tmpdir, NSE_DEPINFO, getpid()); 233 int fd = mkstemp(command_output_tmpfile); 234 if ((fd < 0) || (command_output_fp = fdopen(fd, "w")) == NULL) { 235 return; 236 } 237 if ((search_dir = getenv(NOCATGETS("NSE_DEP"))) == NULL) { 238 return; 239 } 240 #if defined(SUN5_0) || defined(HP_UX) || defined(linux) 241 atexit(close_file); 242 #else 243 on_exit(close_file, 0); 244 #endif 245 strcpy(sfile, filename); 246 if (iflag == NULL || *iflag == '\0') { 247 return; 248 } 249 fprintf(command_output_fp, "%s:", sfile); 250 } 251 fprintf(command_output_fp, " "); 252 fprintf(command_output_fp, iflag); 253 if (iflag != NULL) { 254 is_path = 1; 255 } 256 } 257 258 void 259 report_libdep(char *lib, char *flag) 260 { 261 char *ptr; 262 char filename[MAXPATHLEN]; 263 char *p; 264 265 if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { 266 return; 267 } 268 ptr = strchr(p, ' '); 269 if(ptr) { 270 sprintf(filename, "%s-%s", ptr+1, flag); 271 is_path = 1; 272 report_dep(lib, filename); 273 } 274 } 275 276 void 277 report_search_path(char *iflag) 278 { 279 char curdir[MAXPATHLEN]; 280 char *sdir; 281 char *newiflag; 282 char filename[MAXPATHLEN]; 283 char *p, *ptr; 284 285 if ((sdir = getenv(NOCATGETS("NSE_DEP"))) == NULL) { 286 return; 287 } 288 if ((p= getenv(SUNPRO_DEPENDENCIES)) == NULL) { 289 return; 290 } 291 ptr = strchr(p, ' '); 292 if( ! ptr ) { 293 return; 294 } 295 sprintf(filename, NOCATGETS("%s-CPP"), ptr+1); 296 #if defined(SUN5_0) || defined(HP_UX) || defined(linux) 297 getcwd(curdir, sizeof(curdir)); 298 #else 299 getwd(curdir); 300 #endif 301 if (strcmp(curdir, sdir) != 0 && strlen(iflag) > 2 && 302 iflag[2] != '/') { 303 /* Makefile must have had an "cd xx; cc ..." */ 304 /* Modify the -I path to be relative to the cd */ 305 newiflag = (char *)malloc(strlen(iflag) + strlen(curdir) + 2); 306 sprintf(newiflag, "-%c%s/%s", iflag[1], curdir, &iflag[2]); 307 report_dep(newiflag, filename); 308 } else { 309 report_dep(iflag, filename); 310 } 311 } 312 313 void 314 report_dependency(register char *name) 315 { 316 register char *filename; 317 char buffer[MAXPATHLEN+1]; 318 register char *p; 319 register char *p2; 320 char nse_depinfo_file[MAXPATHLEN]; 321 322 if (report_file == NULL) { 323 if ((filename= getenv(SUNPRO_DEPENDENCIES)) == NULL) { 324 report_file = (FILE *)-1; 325 return; 326 } 327 if (strlen(filename) == 0) { 328 report_file = (FILE *)-1; 329 return; 330 } 331 (void)strcpy(buffer, name); 332 name = buffer; 333 p = strchr(filename, ' '); 334 if(p) { 335 *p= 0; 336 } else { 337 report_file = (FILE *)-1; 338 return; 339 } 340 if ((report_file= fopen(filename, "a")) == NULL) { 341 if ((report_file= fopen(filename, "w")) == NULL) { 342 report_file= (FILE *)-1; 343 return; 344 } 345 } 346 #if defined(SUN5_0) || defined(HP_UX) || defined(linux) 347 atexit(close_report_file); 348 #else 349 (void)on_exit(close_report_file, (char *)report_file); 350 #endif 351 if ((p2= strchr(p+1, ' ')) != NULL) 352 *p2= 0; 353 target_being_reported_for= (char *)malloc((unsigned)(strlen(p+1)+1)); 354 (void)strcpy(target_being_reported_for, p+1); 355 (void)fputs(p+1, report_file); 356 (void)fputs(":", report_file); 357 *p= ' '; 358 if (p2 != NULL) 359 *p2= ' '; 360 } 361 if (report_file == (FILE *)-1) 362 return; 363 (void)fputs(name, report_file); 364 (void)fputs(" ", report_file); 365 } 366 367 #ifdef MAKE_IT 368 void 369 make_it(filename) 370 register char *filename; 371 { 372 register char *command; 373 register char *argv[6]; 374 register int pid; 375 union wait foo; 376 377 if (getenv(SUNPRO_DEPENDENCIES) == NULL) return; 378 command= alloca(strlen(filename)+32); 379 (void)sprintf(command, NOCATGETS("make %s\n"), filename); 380 switch (pid= fork()) { 381 case 0: /* child */ 382 argv[0]= NOCATGETS("csh"); 383 argv[1]= NOCATGETS("-c"); 384 argv[2]= command; 385 argv[3]= 0; 386 (void)dup2(2, 1); 387 execve(NOCATGETS("/bin/sh"), argv, environ); 388 perror(NOCATGETS("execve error")); 389 exit(1); 390 case -1: /* error */ 391 perror(NOCATGETS("fork error")); 392 default: /* parent */ 393 while (wait(&foo) != pid);}; 394 } 395 #endif 396