Home | History | Annotate | Download | only in protocmp
      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, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 /*
     23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 
     30 #include <stdio.h>
     31 #include <sys/param.h>
     32 #include <fcntl.h>
     33 #include <stdlib.h>
     34 #include <strings.h>
     35 #include <errno.h>
     36 #include <dirent.h>
     37 #include <ctype.h>
     38 #include <sys/stat.h>
     39 
     40 #include "list.h"
     41 #include "protodir.h"
     42 #include "arch.h"
     43 
     44 static pkg_list *packages[HASH_SIZE];
     45 
     46 #define	HASH(name) (hash(name) % HASH_SIZE)
     47 
     48 int
     49 processed_package(const char *pkgname)
     50 {
     51 	int	bucket;
     52 	pkg_list *tmp;
     53 
     54 	bucket = HASH(pkgname);
     55 	for (tmp = packages[bucket]; tmp != NULL; tmp = tmp->next) {
     56 		if (strcmp(tmp->pkg_name, pkgname) == 0)
     57 			return (1);
     58 	}
     59 	return (0);
     60 }
     61 
     62 void
     63 mark_processed(const char *pkgname)
     64 {
     65 	int	bucket;
     66 	pkg_list *tmp;
     67 
     68 	bucket = HASH(pkgname);
     69 	tmp = malloc(sizeof (pkg_list));
     70 	bzero(tmp, sizeof (pkg_list));
     71 	(void) strcpy(tmp->pkg_name, pkgname);
     72 	tmp->next = packages[bucket];
     73 	packages[bucket] = tmp;
     74 }
     75 
     76 static pkg_list *
     77 add_dependency(pkg_list *dependlist, const char *pkgname)
     78 {
     79 	pkg_list *tmp;
     80 	pkg_list *pkg;
     81 
     82 	pkg = malloc(sizeof (pkg_list));
     83 	bzero(pkg, sizeof (pkg_list));
     84 	(void) strcpy(pkg->pkg_name, pkgname);
     85 
     86 	/* easy case */
     87 	if (dependlist == NULL)
     88 		return (pkg);
     89 	/* insert at end, since the order matters */
     90 	for (tmp = dependlist; tmp->next != NULL; tmp = tmp->next) {
     91 		/* NULL */
     92 	}
     93 	tmp->next = pkg;
     94 	return (dependlist);
     95 }
     96 
     97 static void
     98 free_dependency_list(pkg_list *dependlist)
     99 {
    100 	pkg_list *tmp;
    101 
    102 	while (dependlist) {
    103 		tmp = dependlist;
    104 		dependlist = dependlist->next;
    105 		tmp->next = NULL;
    106 		free(tmp);
    107 	}
    108 }
    109 
    110 #ifdef DEBUG
    111 void
    112 print_dependencies(const char *pkgname, pkg_list *dependlist)
    113 {
    114 	pkg_list *tmp;
    115 
    116 	fprintf(stderr, "%s:", pkgname);
    117 	for (tmp = dependlist; tmp != NULL; tmp = tmp->next)
    118 		fprintf(stderr, " %s", tmp->pkg_name);
    119 	fprintf(stderr, "\n");
    120 }
    121 #endif
    122 
    123 static char *suffix_list[] = {
    124 #if defined(__i386)
    125 	".i",
    126 #elif defined(__sparc)
    127 	".c",
    128 	".d",
    129 	".m",
    130 	".u",
    131 #else
    132 #error "Unknown architecture."
    133 #endif
    134 	NULL,
    135 };
    136 
    137 static pkg_list *
    138 find_dependencies(const char *pkgname, const char *parentdir)
    139 {
    140 	char	dependfile[MAXPATHLEN + 1];
    141 	char	pkgdir[MAXPATHLEN + 1];
    142 	char	buf[BUFSIZ];
    143 	char	deppkg[MAXNAME];
    144 	char	archpkg[MAXNAME];
    145 	struct stat sbuf;
    146 	FILE	*fp;
    147 	pkg_list *dependlist = NULL;
    148 	char	**suffixes;
    149 
    150 	(void) sprintf(dependfile, "%s/%s/depend", parentdir, pkgname);
    151 	fp = fopen(dependfile, "r");
    152 	if (fp == NULL) {
    153 		/*
    154 		 * depend won't exist in ON packages until a build
    155 		 * has been done, but it would be nice if you didn't have
    156 		 * to do that. So try the generic depend file that those
    157 		 * packages would copy in during the build.
    158 		 */
    159 		(void) sprintf(dependfile, "%s/common_files/depend", parentdir);
    160 		fp = fopen(dependfile, "r");
    161 		if (fp == NULL)
    162 			return (NULL);
    163 	}
    164 	while (fgets(buf, BUFSIZ, fp) != NULL) {
    165 		if ((buf[0] == '\0') || (buf[0] == '#') || isspace(buf[0]))
    166 			continue;
    167 		/* we only care about prerequisites */
    168 		if (buf[0] != 'P')
    169 			continue;
    170 		(void) sscanf(buf, "P %s", deppkg);
    171 		/*
    172 		 * We have to be careful with some of the packages that are
    173 		 * listed as dependencies but exist under a different name -
    174 		 * SUNWcar is good, because it's actually SUNWcar.{c,d,i,m,u}.
    175 		 * What do we do there? We can't just go for all the '.'
    176 		 * packages, since on x86 we only want the .i one, and on sparc
    177 		 * we want everything _but_ .i. Maybe
    178 		 *
    179 		 * I think perhaps what we do is, if we don't find a package
    180 		 * dependency, on intel we append '.i' and try for that, and on
    181 		 * sparc we try the other extensions. Any we find get added.
    182 		 *
    183 		 * Note also we're quiet on failures. This is because you might
    184 		 * be dependant on some outside package.
    185 		 */
    186 		(void) sprintf(pkgdir, "%s/%s", parentdir, deppkg);
    187 		if (stat(pkgdir, &sbuf) == -1) {
    188 			if (errno != ENOENT) {
    189 				continue;
    190 			}
    191 			for (suffixes = &suffix_list[0]; *suffixes != NULL;
    192 			    suffixes++) {
    193 				(void) sprintf(archpkg, "%s%s", deppkg,
    194 				    *suffixes);
    195 				(void) sprintf(pkgdir, "%s/%s", parentdir,
    196 				    archpkg);
    197 				if (stat(pkgdir, &sbuf) == -1) {
    198 					continue;
    199 				}
    200 				if (!S_ISDIR(sbuf.st_mode)) {
    201 					continue;
    202 				}
    203 				/* found one */
    204 				dependlist = add_dependency(dependlist,
    205 				    archpkg);
    206 			}
    207 		}
    208 		if (!S_ISDIR(sbuf.st_mode)) {
    209 			continue;
    210 		}
    211 		dependlist = add_dependency(dependlist, deppkg);
    212 	}
    213 	(void) fclose(fp);
    214 	return (dependlist);
    215 }
    216 
    217 int
    218 process_dependencies(const char *pkgname, const char *parentdir,
    219     elem_list *list, int verbose)
    220 {
    221 	int	count = 0;
    222 	char	pkgdir[MAXPATHLEN + 1];
    223 	pkg_list *dependlist;
    224 	pkg_list *tmp;
    225 
    226 	dependlist = find_dependencies(pkgname, parentdir);
    227 /*
    228  *	print_dependencies(pkgname, dependlist);
    229  */
    230 	if (dependlist == NULL)
    231 		return (0);
    232 
    233 	for (tmp = dependlist; tmp != NULL; tmp = tmp->next) {
    234 		(void) sprintf(pkgdir, "%s/%s", parentdir, tmp->pkg_name);
    235 		count += process_package_dir(tmp->pkg_name, pkgdir, list,
    236 		    verbose);
    237 	}
    238 
    239 	free_dependency_list(dependlist);
    240 	return (count);
    241 }
    242