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