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 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
334