#include "dsynth.h"
#define PKG_HSIZE 32768
#define PKG_HMASK 32767
static int parsepkglist_file(const char *path, int debugstop);
static void childGetPackageInfo(bulk_t *bulk);
static void childGetBinaryDistInfo(bulk_t *bulk);
static void childOptimizeEnv(bulk_t *bulk);
static pkg_t *resolveDeps(pkg_t *dep_list, pkg_t ***list_tailp, int gentopo);
static void resolveFlavors(pkg_t *pkg, char *flavors, int gentopo);
static void resolveDepString(pkg_t *pkg, char *depstr,
int gentopo, int dep_type);
static pkg_t *processPackageListBulk(int total);
static int scan_and_queue_dir(const char *path, const char *level1, int level);
static int scan_binary_repo(const char *path);
#if 0
static void pkgfree(pkg_t *pkg);
#endif
static int PrepareSystemFlag;
static pkg_t *PkgHash1[PKG_HSIZE];
static pkg_t *PkgHash2[PKG_HSIZE];
static __inline pkg_t *
allocpkg(void)
{
pkg_t *pkg;
pkg = calloc(1, sizeof(*pkg));
pkg->idepon_list.next = &pkg->idepon_list;
pkg->idepon_list.prev = &pkg->idepon_list;
pkg->deponi_list.next = &pkg->deponi_list;
pkg->deponi_list.prev = &pkg->deponi_list;
return pkg;
}
static __inline int
pkghash(const char *str)
{
int hv = 0xABC32923;
while (*str) {
hv = (hv << 5) ^ *str;
++str;
}
hv = hv ^ (hv / PKG_HSIZE) ^ (hv / PKG_HSIZE / PKG_HSIZE);
return (hv & PKG_HMASK);
}
static __inline const char *
deptype2str(int dep_type)
{
switch (dep_type) {
case DEP_TYPE_FETCH:
return("FETCH_DEPENDS");
case DEP_TYPE_EXT:
return("EXTRACT_DEPENDS");
case DEP_TYPE_PATCH:
return("PATCH_DEPENDS");
case DEP_TYPE_BUILD:
return("BUILD_DEPENDS");
case DEP_TYPE_LIB:
return("LIB_DEPENDS");
case DEP_TYPE_RUN:
return("RUN_DEPENDS");
default:
return("UNKNOWN");
}
}
static void
pkg_enter(pkg_t *pkg)
{
pkg_t **pkgp;
pkg_t *scan;
if (pkg->portdir) {
pkgp = &PkgHash1[pkghash(pkg->portdir)];
while ((scan = *pkgp) != NULL) {
if (strcmp(pkg->portdir, scan->portdir) == 0)
break;
pkgp = &scan->hnext1;
}
ddassert(scan == NULL || (scan->flags & PKGF_PLACEHOLD));
if (scan && (scan->flags & PKGF_PLACEHOLD)) {
ddassert(scan->idepon_list.next == &scan->idepon_list);
ddassert(scan->deponi_list.next == &scan->deponi_list);
*pkgp = pkg;
pkg->hnext1 = scan->hnext1;
free(scan->portdir);
free(scan);
scan = NULL;
}
if (scan == NULL)
*pkgp = pkg;
}
if (pkg->pkgfile) {
pkgp = &PkgHash2[pkghash(pkg->pkgfile)];
while ((scan = *pkgp) != NULL) {
if (strcmp(pkg->pkgfile, scan->pkgfile) == 0)
break;
pkgp = &scan->hnext2;
}
if (scan == NULL)
*pkgp = pkg;
}
}
static pkg_t *
pkg_find(const char *match)
{
pkg_t **pkgp;
pkg_t *pkg;
pkgp = &PkgHash1[pkghash(match)];
for (pkg = *pkgp; pkg; pkg = pkg->hnext1) {
if (strcmp(pkg->portdir, match) == 0)
return pkg;
}
pkgp = &PkgHash2[pkghash(match)];
for (pkg = *pkgp; pkg; pkg = pkg->hnext2) {
if (strcmp(pkg->pkgfile, match) == 0)
return pkg;
}
return NULL;
}
pkg_t *
ParsePackageList(int n, char **ary, int debugstop)
{
pkg_t *list;
int total;
int fail;
int i;
total = 0;
fail = 0;
initbulk(childGetPackageInfo, MaxBulk);
queuebulk("ports-mgmt", "pkg", NULL, "x");
for (i = 0; i < n; ++i) {
char *l1;
char *l2;
char *l3;
struct stat st;
l1 = strdup(ary[i]);
if (stat(l1, &st) == 0 && S_ISREG(st.st_mode)) {
total += parsepkglist_file(l1, debugstop);
continue;
}
l2 = strchr(l1, '/');
if (l2 == NULL) {
printf("Bad portdir specification: %s\n", l1);
free(l1);
fail = 1;
continue;
}
*l2++ = 0;
l3 = strchr(l2, '@');
if (l3)
*l3++ = 0;
if (strcmp(l1, "ports-mgmt") != 0 ||
strcmp(l2, "pkg") != 0)
{
queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
}
++total;
free(l1);
}
printf("Processing %d ports\n", total);
list = processPackageListBulk(total);
if (fail) {
dfatal("Bad specifications, exiting");
exit(1);
}
return list;
}
static
int
parsepkglist_file(const char *path, int debugstop)
{
FILE *fp;
char *base;
char *l1;
char *l2;
char *l3;
size_t len;
int total;
if ((fp = fopen(path, "r")) == NULL) {
dpanic_errno("Cannot read %s\n", path);
return 0;
}
total = 0;
while ((base = fgetln(fp, &len)) != NULL) {
if (len == 0 || base[len-1] != '\n')
continue;
base[--len] = 0;
l1 = strtok(base, " \t\r\n");
if (l1 == NULL) {
printf("Badly formatted pkg info line: %s\n", base);
continue;
}
l2 = strchr(l1, '/');
if (l2 == NULL) {
printf("Badly formatted specification: %s\n", l1);
continue;
}
*l2++ = 0;
l3 = strchr(l2, '@');
if (l3)
*l3++ = 0;
queuebulk(l1, l2, l3, (debugstop ? "d" : NULL));
++total;
}
fclose(fp);
return total;
}
pkg_t *
GetLocalPackageList(void)
{
pkg_t *list;
FILE *fp;
char *base;
char *data;
char *l1;
char *l2;
char *l3;
int total;
int state;
size_t len;
PrepareSystemFlag = 1;
initbulk(childGetPackageInfo, MaxBulk);
total = 0;
state = 0;
l1 = NULL;
l2 = NULL;
l3 = NULL;
fp = popen("pkg info -a -o -A", "r");
queuebulk("ports-mgmt", "pkg", NULL, "x");
while ((base = fgetln(fp, &len)) != NULL) {
if (len == 0 || base[len-1] != '\n')
continue;
base[--len] = 0;
data = strchr(base, ':');
if (data == NULL)
continue;
*data++ = 0;
base = strtok(base, " \t\r");
data = strtok(data, " \t\r");
if (base == NULL || data == NULL)
continue;
if (strcmp(base, "Origin") == 0) {
if (state == 1) {
queuebulk(l1, l2, NULL, NULL);
state = 0;
++total;
}
if (strchr(data, '/') == NULL) {
printf("Badly formatted origin: %s\n", l1);
}
if (l1)
free(l1);
if (l3)
free(l3);
l1 = strdup(data);
l2 = strchr(l1, '/');
*l2++ = 0;
l3 = strchr(l2, '@');
if (l3) {
*l3++ = 0;
l3 = strdup(l3);
}
if (strcmp(l1, "ports-mgmt") != 0 ||
strcmp(l2, "pkg") != 0) {
state = 1;
}
continue;
}
if (state == 1 && strcmp(base, "flavor") == 0) {
queuebulk(l1, l2, data, NULL);
state = 0;
++total;
}
}
if (state == 1) {
queuebulk(l1, l2, NULL, NULL);
}
if (l1)
free(l1);
if (l3)
free(l3);
pclose(fp);
printf("Processing %d ports\n", total);
list = processPackageListBulk(total);
return list;
}
pkg_t *
GetFullPackageList(void)
{
int total;
initbulk(childGetPackageInfo, MaxBulk);
total = scan_and_queue_dir(DPortsPath, NULL, 1);
printf("Scanning %d ports\n", total);
return processPackageListBulk(total);
}
static pkg_t *
processPackageListBulk(int total)
{
bulk_t *bulk;
pkg_t *scan;
pkg_t *list;
pkg_t *dep_list;
pkg_t **list_tail;
int count;
int stop_fail;
int stop_base_list;
int remove_corrupt;
list = NULL;
list_tail = &list;
count = 0;
remove_corrupt = 0;
while ((bulk = getbulk()) != NULL) {
++count;
if ((count & 255) == 0) {
printf("%6.2f%%\r",
(double)count * 100.0 / (double)total + 0.001);
fflush(stdout);
}
if (bulk->list) {
*list_tail = bulk->list;
bulk->list = NULL;
while ((scan = *list_tail) != NULL) {
if (bulk->s4 == NULL || bulk->s4[0] != 'x')
scan->flags |= PKGF_MANUALSEL;
pkg_enter(scan);
list_tail = &scan->bnext;
}
}
freebulk(bulk);
}
printf("100.00%%\n");
printf("\nTotal %d\n", count);
fflush(stdout);
printf("Resolving dependencies...");
fflush(stdout);
dep_list = list;
while (dep_list) {
dep_list = resolveDeps(dep_list, &list_tail, 0);
}
printf("done\n");
donebulk();
resolveDeps(list, NULL, 1);
count = 0;
stop_fail = 0;
stop_base_list = 0;
for (scan = list; scan; scan = scan->bnext) {
if ((scan->flags & PKGF_ERROR) == 0) {
++count;
}
if ((scan->flags & PKGF_MANUALSEL) && MaskProbeAbort == 0) {
pkglink_t *link;
if (scan->flags & PKGF_CORRUPT) {
++stop_fail;
++stop_base_list;
}
PKGLIST_FOREACH(link, &scan->idepon_list) {
if (link->pkg &&
(link->pkg->flags & PKGF_CORRUPT)) {
++stop_fail;
}
}
}
}
printf("Total Returned %d\n", count);
if (stop_fail) {
printf("%d packages failed to probe\n", stop_fail);
if (PrepareSystemFlag) {
if (stop_fail == stop_base_list) {
printf(
"prepare-system: Some of your installed packages no longer exist in\n"
"dports, do you wish to continue rebuilding what does exist?\n");
if (askyn("Continue anyway? "))
remove_corrupt = 1;
} else {
printf(
"prepare-system: Some of your installed packages have dependencies\n"
"which could not be found in dports, cannot continue, aborting\n");
}
} else {
if (ForceOpt) {
remove_corrupt = 1;
printf("continuing despite pkglist "
"errors (-f)\n");
} else {
printf("unable to continue, aborting\n");
}
}
if (remove_corrupt == 0)
exit(1);
}
if (remove_corrupt) {
list_tail = &list;
while ((scan = *list_tail) != NULL) {
if (scan->flags & PKGF_CORRUPT)
*list_tail = scan->bnext;
else
list_tail = &scan->bnext;
}
}
initbulk(childGetBinaryDistInfo, MaxBulk);
total = scan_binary_repo(RepositoryPath);
count = 0;
printf("Scanning %d packages\n", total);
while ((bulk = getbulk()) != NULL) {
++count;
if ((count & 255) == 0) {
printf("%6.2f%%\r",
(double)count * 100.0 / (double)total + 0.001);
fflush(stdout);
}
freebulk(bulk);
}
printf("100.00%%\n");
printf("\nTotal %d\n", count);
fflush(stdout);
donebulk();
printf("all done\n");
return list;
}
pkg_t *
GetPkgPkg(pkg_t **listp)
{
bulk_t *bulk;
pkg_t *scan;
pkg_t *s2;
for (scan = *listp; scan; scan = scan->bnext) {
if (strcmp(scan->portdir, "ports-mgmt/pkg") == 0)
return scan;
}
initbulk(childGetPackageInfo, MaxBulk);
queuebulk("ports-mgmt", "pkg", NULL, "x");
bulk = getbulk();
dassert(bulk, "Cannot find ports-mgmt/pkg");
scan = bulk->list;
bulk->list = NULL;
freebulk(bulk);
donebulk();
for (s2 = scan; s2->bnext; s2 = s2->bnext)
++BuildTotal;
for (s2 = scan; s2->bnext; s2 = s2->bnext)
;
s2->bnext = *listp;
*listp = scan;
++BuildTotal;
return scan;
}
void
OptimizeEnv(void)
{
bulk_t *bulk;
initbulk(childOptimizeEnv, MaxBulk);
queuebulk("ports-mgmt", "pkg", NULL, NULL);
bulk = getbulk();
freebulk(bulk);
donebulk();
}
static pkg_t *
resolveDeps(pkg_t *list, pkg_t ***list_tailp, int gentopo)
{
pkg_t *ret_list = NULL;
pkg_t *scan;
pkg_t *use;
bulk_t *bulk;
for (scan = list; scan; scan = scan->bnext) {
use = pkg_find(scan->portdir);
resolveFlavors(use, scan->flavors, gentopo);
resolveDepString(use, scan->fetch_deps,
gentopo, DEP_TYPE_FETCH);
resolveDepString(use, scan->ext_deps,
gentopo, DEP_TYPE_EXT);
resolveDepString(use, scan->patch_deps,
gentopo, DEP_TYPE_PATCH);
resolveDepString(use, scan->build_deps,
gentopo, DEP_TYPE_BUILD);
resolveDepString(use, scan->lib_deps,
gentopo, DEP_TYPE_LIB);
resolveDepString(use, scan->run_deps,
gentopo, DEP_TYPE_RUN);
}
if (gentopo)
return NULL;
while ((bulk = getbulk()) != NULL) {
if (bulk->list) {
if (ret_list == NULL)
ret_list = bulk->list;
**list_tailp = bulk->list;
bulk->list = NULL;
while ((scan = **list_tailp) != NULL) {
pkg_enter(scan);
*list_tailp = &scan->bnext;
}
}
freebulk(bulk);
}
return (ret_list);
}
static void
resolveFlavors(pkg_t *pkg, char *flavors, int gentopo)
{
char *flavor_base;
char *flavor_scan;
char *flavor;
char *portdir;
char *s1;
char *s2;
pkg_t *dpkg;
pkglink_t *link;
if ((pkg->flags & PKGF_DUMMY) == 0)
return;
if (pkg->flavors == NULL || pkg->flavors[0] == 0)
return;
flavor_base = strdup(flavors);
flavor_scan = flavor_base;
for (;;) {
do {
flavor = strsep(&flavor_scan, " \t");
} while (flavor && *flavor == 0);
if (flavor == NULL)
break;
asprintf(&portdir, "%s@%s", pkg->portdir, flavor);
s1 = strdup(pkg->portdir);
s2 = strchr(s1, '/');
*s2++ = 0;
dpkg = pkg_find(portdir);
if (dpkg && gentopo) {
free(portdir);
link = calloc(1, sizeof(*link));
link->pkg = dpkg;
link->next = &pkg->idepon_list;
link->prev = pkg->idepon_list.prev;
link->next->prev = link;
link->prev->next = link;
link->dep_type = DEP_TYPE_BUILD;
link = calloc(1, sizeof(*link));
link->pkg = pkg;
link->next = &dpkg->deponi_list;
link->prev = dpkg->deponi_list.prev;
link->next->prev = link;
link->prev->next = link;
link->dep_type = DEP_TYPE_BUILD;
++dpkg->depi_count;
} else if (gentopo == 0 && dpkg == NULL) {
dpkg = allocpkg();
dpkg->portdir = portdir;
dpkg->flags = PKGF_PLACEHOLD;
pkg_enter(dpkg);
queuebulk(s1, s2, flavor, NULL);
}
free(s1);
}
free(flavor_base);
}
static void
resolveDepString(pkg_t *pkg, char *depstr, int gentopo, int dep_type)
{
char *copy_base;
char *copy;
char *dep;
char *log_component;
char *sep;
char *tag;
char *flavor;
pkg_t *dpkg;
if (depstr == NULL || depstr[0] == 0)
return;
copy_base = strdup(depstr);
copy = copy_base;
log_component = copy;
for (;;) {
do {
dep = strsep(©, " \t");
} while (dep && *dep == 0);
if (dep == NULL)
break;
if (strncmp(dep, "/nonexistent:", 13) == 0)
continue;
log_component = dep;
dep = strchr(dep, ':');
if (dep == NULL || *dep != ':') {
printf("Error parsing %s dependency for "
"%s: '%s' at index %zd '%s' "
"(looking for ':')\n",
deptype2str(dep_type),
pkg->portdir, depstr,
log_component - copy_base,
log_component);
continue;
}
++dep;
if (strncmp(dep, DPortsPath, strlen(DPortsPath)) == 0) {
dep += strlen(DPortsPath);
if (*dep == '/')
++dep;
}
tag = strchr(dep, ':');
if (tag)
*tag++ = 0;
log_component = dep;
if ((dpkg = pkg_find(dep)) != NULL) {
if (gentopo) {
pkglink_t *link;
ddprintf(0, "Add Dependency %s -> %s\n",
pkg->portdir, dpkg->portdir);
link = calloc(1, sizeof(*link));
link->pkg = dpkg;
link->next = &pkg->idepon_list;
link->prev = pkg->idepon_list.prev;
link->next->prev = link;
link->prev->next = link;
link->dep_type = dep_type;
link = calloc(1, sizeof(*link));
link->pkg = pkg;
link->next = &dpkg->deponi_list;
link->prev = dpkg->deponi_list.prev;
link->next->prev = link;
link->prev->next = link;
link->dep_type = dep_type;
++dpkg->depi_count;
}
continue;
}
if (gentopo) {
printf("Topology Generate failed for %s: %s\n",
pkg->portdir, copy_base);
continue;
}
sep = strchr(dep, '/');
if (sep == NULL) {
printf("Error parsing %s dependency for "
"%s: '%s' at index %zd '%s' "
"(looking for '/')\n",
deptype2str(dep_type),
pkg->portdir, depstr,
log_component - copy_base,
log_component);
continue;
}
*sep++ = 0;
flavor = strrchr(sep, '@');
#if 0
if (tag)
flavor = strrchr(tag, '@');
else
flavor = strrchr(sep, '@');
#endif
if (flavor)
*flavor++ = 0;
if (flavor)
ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s@%s\n",
pkg->portdir, dep, sep, flavor);
else
ddprintf(0, "QUEUE DEPENDENCY FROM PKG %s: %s/%s\n",
pkg->portdir, dep, sep);
dpkg = allocpkg();
if (flavor)
asprintf(&dpkg->portdir, "%s/%s@%s", dep, sep, flavor);
else
asprintf(&dpkg->portdir, "%s/%s", dep, sep);
dpkg->flags = PKGF_PLACEHOLD;
pkg_enter(dpkg);
queuebulk(dep, sep, flavor, NULL);
}
free(copy_base);
}
void
FreePackageList(pkg_t *pkgs __unused)
{
dfatal("not implemented");
}
static void
childGetPackageInfo(bulk_t *bulk)
{
pkg_t *pkg;
char *flavor;
char *ptr;
FILE *fp;
int line;
size_t len;
char *portpath;
char *flavarg;
char *localbase;
const char *cav[MAXCAC];
pid_t pid;
int cac;
flavor = bulk->s3;
bulk->list = NULL;
asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
if (flavor)
asprintf(&flavarg, "FLAVOR=%s", flavor);
else
flavarg = NULL;
cac = 0;
cav[cac++] = MAKE_BINARY;
cav[cac++] = "-C";
cav[cac++] = portpath;
if (flavarg)
cav[cac++] = flavarg;
asprintf(&localbase, "LOCALBASE=%s/empty", BuildBase);
cav[cac++] = localbase;
cav[cac++] = "-VPKGVERSION";
cav[cac++] = "-VPKGFILE:T";
cav[cac++] = "-VALLFILES";
cav[cac++] = "-VDIST_SUBDIR";
cav[cac++] = "-VMAKE_JOBS_NUMBER";
cav[cac++] = "-VIGNORE";
cav[cac++] = "-VFETCH_DEPENDS";
cav[cac++] = "-VEXTRACT_DEPENDS";
cav[cac++] = "-VPATCH_DEPENDS";
cav[cac++] = "-VBUILD_DEPENDS";
cav[cac++] = "-VLIB_DEPENDS";
cav[cac++] = "-VRUN_DEPENDS";
cav[cac++] = "-VSELECTED_OPTIONS";
cav[cac++] = "-VDESELECTED_OPTIONS";
cav[cac++] = "-VUSE_LINUX";
cav[cac++] = "-VFLAVORS";
cav[cac++] = "-VUSES";
fp = dexec_open(portpath + strlen(DPortsPath) + 1, cav, cac,
&pid, NULL, 1, 1);
freestrp(&flavarg);
freestrp(&localbase);
pkg = allocpkg();
if (flavor)
asprintf(&pkg->portdir, "%s/%s@%s", bulk->s1, bulk->s2, flavor);
else
asprintf(&pkg->portdir, "%s/%s", bulk->s1, bulk->s2);
line = 1;
while ((ptr = fgetln(fp, &len)) != NULL) {
if (len == 0 || ptr[len-1] != '\n') {
dfatal("Bad package info for %s/%s response line %d",
bulk->s1, bulk->s2, line);
}
ptr[--len] = 0;
switch(line) {
case 1:
asprintf(&pkg->version, "%s", ptr);
break;
case 2:
asprintf(&pkg->pkgfile, "%s", ptr);
break;
case 3:
asprintf(&pkg->distfiles, "%s", ptr);
break;
case 4:
pkg->distsubdir = strdup_or_null(ptr);
break;
case 5:
pkg->make_jobs_number = strtol(ptr, NULL, 0);
break;
case 6:
pkg->ignore = strdup_or_null(ptr);
break;
case 7:
pkg->fetch_deps = strdup_or_null(ptr);
break;
case 8:
pkg->ext_deps = strdup_or_null(ptr);
break;
case 9:
pkg->patch_deps = strdup_or_null(ptr);
break;
case 10:
pkg->build_deps = strdup_or_null(ptr);
break;
case 11:
pkg->lib_deps = strdup_or_null(ptr);
break;
case 12:
pkg->run_deps = strdup_or_null(ptr);
break;
case 13:
pkg->pos_options = strdup_or_null(ptr);
break;
case 14:
pkg->neg_options = strdup_or_null(ptr);
break;
case 15:
if (ptr[0])
pkg->use_linux = 1;
break;
case 16:
asprintf(&pkg->flavors, "%s", ptr);
break;
case 17:
asprintf(&pkg->uses, "%s", ptr);
if (strstr(pkg->uses, "metaport"))
pkg->flags |= PKGF_META;
break;
default:
printf("EXTRA LINE: %s\n", ptr);
break;
}
++line;
}
if (line == 1) {
printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
pkg->flags |= PKGF_NOTFOUND;
} else if (line != 17 + 1) {
printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
pkg->flags |= PKGF_CORRUPT;
}
if (dexec_close(fp, pid)) {
printf("make -V* command for %s/%s failed\n",
bulk->s1, bulk->s2);
pkg->flags |= PKGF_CORRUPT;
}
ddassert(bulk->s1);
if (bulk->s4 && bulk->s4[0] == 'd')
pkg->flags |= PKGF_DEBUGSTOP;
if (flavor == NULL && pkg->flavors && pkg->flavors[0]) {
pkg->flags |= PKGF_DUMMY;
freestrp(&pkg->fetch_deps);
freestrp(&pkg->ext_deps);
freestrp(&pkg->patch_deps);
freestrp(&pkg->build_deps);
freestrp(&pkg->lib_deps);
freestrp(&pkg->run_deps);
freestrp(&pkg->pkgfile);
}
pkg->crc32 = crcDirTree(portpath);
bulk->list = pkg;
free(portpath);
}
static void
childGetBinaryDistInfo(bulk_t *bulk)
{
char *ptr;
FILE *fp;
size_t len;
pkg_t *pkg;
const char *cav[MAXCAC];
char *repopath;
char buf[1024];
pid_t pid;
int cac;
int deleteme;
asprintf(&repopath, "%s/%s", RepositoryPath, bulk->s1);
cac = 0;
cav[cac++] = PKG_BINARY;
cav[cac++] = "query";
cav[cac++] = "-F";
cav[cac++] = repopath;
cav[cac++] = "%n-%v";
fp = dexec_open(NULL, cav, cac, &pid, NULL, 1, 0);
deleteme = DeleteObsoletePkgs;
while ((ptr = fgetln(fp, &len)) != NULL) {
if (len == 0 || ptr[len-1] != '\n')
continue;
ptr[len-1] = 0;
snprintf(buf, sizeof(buf), "%s%s", ptr, ".pkg");
pkg = pkg_find(buf);
if (pkg == NULL) {
snprintf(buf, sizeof(buf), "%s%s", ptr, UsePkgSufx);
pkg = pkg_find(buf);
}
if (pkg) {
if (FetchOnlyOpt) {
ddprintf(0, "Note: Package is already packaged, ignore for -f: %s\n", ptr);
deleteme = 0;
} else {
pkg->flags |= PKGF_PACKAGED;
deleteme = 0;
}
} else {
ddprintf(0, "Note: package scan, not in list, "
"skipping %s{.%s,.pkg}\n", ptr, UsePkgSufx);
}
}
if (dexec_close(fp, pid)) {
printf("pkg query command failed for %s\n", repopath);
}
if (deleteme) {
dlog(DLOG_ALL | DLOG_STDOUT,
"Deleting obsolete package %s\n", repopath);
remove(repopath);
}
free(repopath);
}
static void
childOptimizeEnv(bulk_t *bulk)
{
char *portpath;
char *localbase;
char *ptr;
FILE *fp;
int line;
size_t len;
const char *cav[MAXCAC];
pid_t pid;
int cac;
asprintf(&portpath, "%s/%s/%s", DPortsPath, bulk->s1, bulk->s2);
asprintf(&localbase, "LOCALBASE=%s/empty", BuildBase);
cac = 0;
cav[cac++] = MAKE_BINARY;
cav[cac++] = "-C";
cav[cac++] = portpath;
cav[cac++] = localbase;
cav[cac++] = "-V_PERL5_FROM_BIN";
fp = dexec_open(portpath + strlen(DPortsPath) + 1, cav, cac,
&pid, NULL, 1, 1);
free(localbase);
free(portpath);
line = 1;
while ((ptr = fgetln(fp, &len)) != NULL) {
if (len == 0 || ptr[len-1] != '\n') {
dfatal("Bad package info for %s/%s response line %d",
bulk->s1, bulk->s2, line);
}
ptr[--len] = 0;
switch(line) {
case 1:
addbuildenv("_PERL5_FROM_BIN", ptr, BENV_ENVIRONMENT);
break;
default:
printf("childOptimizeEnv: EXTRA LINE: %s\n", ptr);
break;
}
++line;
}
if (line == 1) {
printf("DPort not found: %s/%s\n", bulk->s1, bulk->s2);
} else if (line != 1 + 1) {
printf("DPort corrupt: %s/%s\n", bulk->s1, bulk->s2);
}
if (dexec_close(fp, pid)) {
printf("childOptimizeEnv() failed\n");
}
}
static int
scan_and_queue_dir(const char *path, const char *level1, int level)
{
DIR *dir;
char *s1;
char *s2;
struct dirent *den;
struct stat st;
int count = 0;
dir = opendir(path);
dassert(dir, "Cannot open dports path \"%s\"", path);
while ((den = readdir(dir)) != NULL) {
if (den->d_namlen == 1 && den->d_name[0] == '.')
continue;
if (den->d_namlen == 2 &&
den->d_name[0] == '.' && den->d_name[1] == '.')
continue;
asprintf(&s1, "%s/%s", path, den->d_name);
if (lstat(s1, &st) < 0 || !S_ISDIR(st.st_mode)) {
free(s1);
continue;
}
if (level == 1) {
count += scan_and_queue_dir(s1, den->d_name, 2);
free(s1);
continue;
}
asprintf(&s2, "%s/Makefile", s1);
if (lstat(s2, &st) == 0) {
queuebulk(level1, den->d_name, NULL, NULL);
++count;
}
free(s1);
free(s2);
}
closedir(dir);
return count;
}
static int
scan_binary_repo(const char *path)
{
DIR *dir;
struct dirent *den;
int count;
count = 0;
dir = opendir(path);
dassert(dir, "Cannot open repository path \"%s\"", path);
while ((den = readdir(dir)) != NULL) {
const char *suffix;
suffix = strrchr(den->d_name, '.');
if (suffix && suffix != den->d_name &&
strcmp(suffix, UsePkgSufx) == 0)
{
queuebulk(den->d_name, NULL, NULL, NULL);
++count;
}
if (suffix && suffix != den->d_name &&
strcmp(suffix, ".pkg") == 0)
{
queuebulk(den->d_name, NULL, NULL, NULL);
++count;
}
}
closedir(dir);
return count;
}
#if 0
static void
pkgfree(pkg_t *pkg)
{
freestrp(&pkg->portdir);
freestrp(&pkg->version);
freestrp(&pkg->pkgfile);
freestrp(&pkg->ignore);
freestrp(&pkg->fetch_deps);
freestrp(&pkg->ext_deps);
freestrp(&pkg->patch_deps);
freestrp(&pkg->build_deps);
freestrp(&pkg->lib_deps);
freestrp(&pkg->run_deps);
freestrp(&pkg->pos_options);
freestrp(&pkg->neg_options);
freestrp(&pkg->flavors);
free(pkg);
}
#endif