dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / tools / protocmp / depend.c
blobff72dec975ad0c9ee1052c2effec48c03aeb1d05
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 #include <stdio.h>
29 #include <sys/param.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <strings.h>
33 #include <errno.h>
34 #include <dirent.h>
35 #include <ctype.h>
36 #include <sys/stat.h>
38 #include "list.h"
39 #include "protodir.h"
40 #include "arch.h"
42 static pkg_list *packages[HASH_SIZE];
44 #define HASH(name) (hash(name) % HASH_SIZE)
46 int
47 processed_package(const char *pkgname)
49 int bucket;
50 pkg_list *tmp;
52 bucket = HASH(pkgname);
53 for (tmp = packages[bucket]; tmp != NULL; tmp = tmp->next) {
54 if (strcmp(tmp->pkg_name, pkgname) == 0)
55 return (1);
57 return (0);
60 void
61 mark_processed(const char *pkgname)
63 int bucket;
64 pkg_list *tmp;
66 bucket = HASH(pkgname);
67 tmp = malloc(sizeof (pkg_list));
68 bzero(tmp, sizeof (pkg_list));
69 (void) strcpy(tmp->pkg_name, pkgname);
70 tmp->next = packages[bucket];
71 packages[bucket] = tmp;
74 static pkg_list *
75 add_dependency(pkg_list *dependlist, const char *pkgname)
77 pkg_list *tmp;
78 pkg_list *pkg;
80 pkg = malloc(sizeof (pkg_list));
81 bzero(pkg, sizeof (pkg_list));
82 (void) strcpy(pkg->pkg_name, pkgname);
84 /* easy case */
85 if (dependlist == NULL)
86 return (pkg);
87 /* insert at end, since the order matters */
88 for (tmp = dependlist; tmp->next != NULL; tmp = tmp->next) {
89 /* NULL */
91 tmp->next = pkg;
92 return (dependlist);
95 static void
96 free_dependency_list(pkg_list *dependlist)
98 pkg_list *tmp;
100 while (dependlist) {
101 tmp = dependlist;
102 dependlist = dependlist->next;
103 tmp->next = NULL;
104 free(tmp);
108 #ifdef DEBUG
109 void
110 print_dependencies(const char *pkgname, pkg_list *dependlist)
112 pkg_list *tmp;
114 fprintf(stderr, "%s:", pkgname);
115 for (tmp = dependlist; tmp != NULL; tmp = tmp->next)
116 fprintf(stderr, " %s", tmp->pkg_name);
117 fprintf(stderr, "\n");
119 #endif
121 static char *suffix_list[] = {
122 #if defined(__i386)
123 ".i",
124 #elif defined(__sparc)
125 ".c",
126 ".d",
127 ".m",
128 ".u",
129 ".v",
130 #else
131 #error "Unknown architecture."
132 #endif
133 NULL,
136 static pkg_list *
137 find_dependencies(const char *pkgname, const char *parentdir)
139 char dependfile[MAXPATHLEN + 1];
140 char pkgdir[MAXPATHLEN + 1];
141 char buf[BUFSIZ];
142 char deppkg[MAXNAME];
143 char archpkg[MAXNAME];
144 struct stat sbuf;
145 FILE *fp;
146 pkg_list *dependlist = NULL;
147 char **suffixes;
149 (void) sprintf(dependfile, "%s/%s/depend", parentdir, pkgname);
150 fp = fopen(dependfile, "r");
151 if (fp == NULL) {
153 * depend won't exist in ON packages until a build
154 * has been done, but it would be nice if you didn't have
155 * to do that. So try the generic depend file that those
156 * packages would copy in during the build.
158 (void) sprintf(dependfile, "%s/common_files/depend", parentdir);
159 fp = fopen(dependfile, "r");
160 if (fp == NULL)
161 return (NULL);
163 while (fgets(buf, BUFSIZ, fp) != NULL) {
164 if ((buf[0] == '\0') || (buf[0] == '#') || isspace(buf[0]))
165 continue;
166 /* we only care about prerequisites */
167 if (buf[0] != 'P')
168 continue;
169 (void) sscanf(buf, "P %s", deppkg);
171 * We have to be careful with some of the packages that are
172 * listed as dependencies but exist under a different name -
173 * SUNWcar is good, because it's actually SUNWcar.{c,d,i,m,u}.
174 * What do we do there? We can't just go for all the '.'
175 * packages, since on x86 we only want the .i one, and on sparc
176 * we want everything _but_ .i. Maybe
178 * I think perhaps what we do is, if we don't find a package
179 * dependency, on intel we append '.i' and try for that, and on
180 * sparc we try the other extensions. Any we find get added.
182 * Note also we're quiet on failures. This is because you might
183 * be dependant on some outside package.
185 (void) sprintf(pkgdir, "%s/%s", parentdir, deppkg);
186 if (stat(pkgdir, &sbuf) == -1) {
187 if (errno != ENOENT) {
188 continue;
190 for (suffixes = &suffix_list[0]; *suffixes != NULL;
191 suffixes++) {
192 (void) sprintf(archpkg, "%s%s", deppkg,
193 *suffixes);
194 (void) sprintf(pkgdir, "%s/%s", parentdir,
195 archpkg);
196 if (stat(pkgdir, &sbuf) == -1) {
197 continue;
199 if (!S_ISDIR(sbuf.st_mode)) {
200 continue;
202 /* found one */
203 dependlist = add_dependency(dependlist,
204 archpkg);
207 if (!S_ISDIR(sbuf.st_mode)) {
208 continue;
210 dependlist = add_dependency(dependlist, deppkg);
212 (void) fclose(fp);
213 return (dependlist);
217 process_dependencies(const char *pkgname, const char *parentdir,
218 elem_list *list, int verbose)
220 int count = 0;
221 char pkgdir[MAXPATHLEN + 1];
222 pkg_list *dependlist;
223 pkg_list *tmp;
225 dependlist = find_dependencies(pkgname, parentdir);
227 * print_dependencies(pkgname, dependlist);
229 if (dependlist == NULL)
230 return (0);
232 for (tmp = dependlist; tmp != NULL; tmp = tmp->next) {
233 (void) sprintf(pkgdir, "%s/%s", parentdir, tmp->pkg_name);
234 count += process_package_dir(tmp->pkg_name, pkgdir, list,
235 verbose);
238 free_dependency_list(dependlist);
239 return (count);