#include <stdio.h>
#include <sys/param.h>
#include <fcntl.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/stat.h>
#include "list.h"
#include "protodir.h"
#include "arch.h"
static pkg_list *packages[HASH_SIZE];
#define HASH(name) (hash(name) % HASH_SIZE)
int
processed_package(const char *pkgname)
{
int bucket;
pkg_list *tmp;
bucket = HASH(pkgname);
for (tmp = packages[bucket]; tmp != NULL; tmp = tmp->next) {
if (strcmp(tmp->pkg_name, pkgname) == 0)
return (1);
}
return (0);
}
void
mark_processed(const char *pkgname)
{
int bucket;
pkg_list *tmp;
bucket = HASH(pkgname);
tmp = malloc(sizeof (pkg_list));
bzero(tmp, sizeof (pkg_list));
(void) strcpy(tmp->pkg_name, pkgname);
tmp->next = packages[bucket];
packages[bucket] = tmp;
}
static pkg_list *
add_dependency(pkg_list *dependlist, const char *pkgname)
{
pkg_list *tmp;
pkg_list *pkg;
pkg = malloc(sizeof (pkg_list));
bzero(pkg, sizeof (pkg_list));
(void) strcpy(pkg->pkg_name, pkgname);
if (dependlist == NULL)
return (pkg);
for (tmp = dependlist; tmp->next != NULL; tmp = tmp->next) {
}
tmp->next = pkg;
return (dependlist);
}
static void
free_dependency_list(pkg_list *dependlist)
{
pkg_list *tmp;
while (dependlist) {
tmp = dependlist;
dependlist = dependlist->next;
tmp->next = NULL;
free(tmp);
}
}
#ifdef DEBUG
void
print_dependencies(const char *pkgname, pkg_list *dependlist)
{
pkg_list *tmp;
fprintf(stderr, "%s:", pkgname);
for (tmp = dependlist; tmp != NULL; tmp = tmp->next)
fprintf(stderr, " %s", tmp->pkg_name);
fprintf(stderr, "\n");
}
#endif
static char *suffix_list[] = {
#if defined(__i386)
".i",
#elif defined(__sparc)
".c",
".d",
".m",
".u",
".v",
#else
#error "Unknown architecture."
#endif
NULL,
};
static pkg_list *
find_dependencies(const char *pkgname, const char *parentdir)
{
char dependfile[MAXPATHLEN + 1];
char pkgdir[MAXPATHLEN + 1];
char buf[BUFSIZ];
char deppkg[MAXNAME];
char archpkg[MAXNAME];
struct stat sbuf;
FILE *fp;
pkg_list *dependlist = NULL;
char **suffixes;
(void) sprintf(dependfile, "%s/%s/depend", parentdir, pkgname);
fp = fopen(dependfile, "r");
if (fp == NULL) {
(void) sprintf(dependfile, "%s/common_files/depend", parentdir);
fp = fopen(dependfile, "r");
if (fp == NULL)
return (NULL);
}
while (fgets(buf, BUFSIZ, fp) != NULL) {
if ((buf[0] == '\0') || (buf[0] == '#') || isspace(buf[0]))
continue;
if (buf[0] != 'P')
continue;
(void) sscanf(buf, "P %s", deppkg);
(void) sprintf(pkgdir, "%s/%s", parentdir, deppkg);
if (stat(pkgdir, &sbuf) == -1) {
if (errno != ENOENT) {
continue;
}
for (suffixes = &suffix_list[0]; *suffixes != NULL;
suffixes++) {
(void) sprintf(archpkg, "%s%s", deppkg,
*suffixes);
(void) sprintf(pkgdir, "%s/%s", parentdir,
archpkg);
if (stat(pkgdir, &sbuf) == -1) {
continue;
}
if (!S_ISDIR(sbuf.st_mode)) {
continue;
}
dependlist = add_dependency(dependlist,
archpkg);
}
}
if (!S_ISDIR(sbuf.st_mode)) {
continue;
}
dependlist = add_dependency(dependlist, deppkg);
}
(void) fclose(fp);
return (dependlist);
}
int
process_dependencies(const char *pkgname, const char *parentdir,
elem_list *list, int verbose)
{
int count = 0;
char pkgdir[MAXPATHLEN + 1];
pkg_list *dependlist;
pkg_list *tmp;
dependlist = find_dependencies(pkgname, parentdir);
if (dependlist == NULL)
return (0);
for (tmp = dependlist; tmp != NULL; tmp = tmp->next) {
(void) sprintf(pkgdir, "%s/%s", parentdir, tmp->pkg_name);
count += process_package_dir(tmp->pkg_name, pkgdir, list,
verbose);
}
free_dependency_list(dependlist);
return (count);
}