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