xref: /illumos-gate/usr/src/cmd/make/lib/vroot/report.cc (revision e7afc443cb8c2e0a379fe48b15a0c7fb61a4b2fc)
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 *
get_report_file(void)50 get_report_file(void)
51 {
52 	return(report_file);
53 }
54 
55 char *
get_target_being_reported_for(void)56 get_target_being_reported_for(void)
57 {
58 	return(target_being_reported_for);
59 }
60 
61 extern "C" {
62 static void
close_report_file(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
clean_up(FILE * nse_depinfo_fp,FILE * merge_fp,char * nse_depinfo_file,char * merge_file,int unlinkf)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
close_file(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
report_dep(char * iflag,char * filename)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
report_libdep(char * lib,char * flag)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
report_search_path(char * iflag)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
report_dependency(const char * name)284 report_dependency(const char *name)
285 {
286 	char	*filename;
287 	char		buffer[MAXPATHLEN+1];
288 	char	*p;
289 	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 
334