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