/*
* deps.c : handling of dependencies when trying to do
* the closure at package installation.
*
* See Copyright for the status of this software.
*
* $Id: deps.c,v 1.4 1998/06/10 22:26:41 veillard Exp $
*/
#include "config.h"
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include <time.h>
#include "rpmfind.h"
#include "deps.h"
/* #define DEBUG_RESOURCES */ /* Debug the needed resources */
/* #define DEBUG_PACKAGES */ /* Debug the needed packages */
void neededPackageDereference(neededPackagePtr pkg);
/****************************************************************
* *
* Needed Resources *
* *
****************************************************************/
int nbNeededResources = 0;
neededResourcePtr neededResourceList = NULL;
/*
* Print the packages needed by a resource.
*/
void neededResourcePrintPkgs(neededResourcePtr res) {
neededPackagePtr cur;
int i;
for (i = 0;i < res->nb_pkgs;i++) {
cur = res->pkgs[i];
neededPackagePrint(cur);
}
}
/*
* Print a needed resource
*/
void neededResourcePrint(neededResourcePtr cur) {
printf("%50s %d %d\n", cur->resource, cur->refcount, cur->nb_pkgs);
}
/*
* Print all needed resource
*/
void neededResourcePrintList() {
neededResourcePtr cur = neededResourceList;
printf(" %d Resources Cnt NPkg\n",
nbNeededResources);
while (cur != NULL) {
neededResourcePrint(cur);
cur = cur->next;
}
}
/*
* Add a new needed resource.
*/
neededResourcePtr neededResourceAdd(char *resource, neededPackagePtr father) {
neededResourcePtr cur;
#ifdef DEBUG_RESOURCES
printf("neededResourceAdd(%s, ...)\n", resource);
#endif
cur = (neededResourcePtr) malloc(sizeof(neededResource));
if (cur == NULL) {
fprintf(stderr, "neededResourceAdd : ran out of memory !\n");
exit(1);
}
cur->refcount = 1;
cur->nb_pkgs = 0;
cur->max_pkgs = 0;
cur->pkgs = NULL;
cur->resource = strdup(resource);
cur->next = neededResourceList;
neededResourceList = cur;
#ifdef DEBUG_RESOURCES
neededResourcePrintList();
#endif
return(cur);
}
/*
* Search a needed resource.
*/
neededResourcePtr neededResourceSearch(char *resource) {
neededResourcePtr cur;
#ifdef DEBUG_RESOURCES
printf("neededResourceSearch(%s, ...)\n", resource);
#endif
cur = neededResourceList;
while (cur != NULL) {
if (!strcmp(resource, cur->resource)) {
#ifdef DEBUG_RESOURCES
neededResourcePrint(cur);
#endif
return(cur);
}
cur = cur->next;
}
#ifdef DEBUG_RESOURCES
printf("\tnot found...\n");
#endif
return(NULL);
}
/*
* A resource is no more needed.
*/
void neededResourceDrop(neededResourcePtr res) {
neededPackagePtr cur;
int i;
if (res->refcount <= 0) return;
res->refcount--;
if (res->refcount > 0) return;
printf("Dropping resource %s\n", res->resource);
for (i = 0;i < res->nb_pkgs;i++) {
cur = res->pkgs[i];
neededPackageDereference(cur);
}
}
/****************************************************************
* *
* Needed Packages *
* *
****************************************************************/
int nbNeededPackages = 0;
static neededPackagePtr neededPackageList = NULL;
/*
* Print a neededPackage structure.
*/
void neededPackagePrint(neededPackagePtr cur) {
static char buf[500];
struct tm * tstruct;
if ((cur->rating < 0) && (rpmfindVerbose <= 2)) return;
if (rpmfindVerbose > 2) {
tstruct = localtime(&(cur->date));
#ifdef HAVE_STRFTIME
strftime(buf, sizeof(buf) - 1, "%c", tstruct);
#else
#error "no strftime, please check !"
#endif
printf("%s-%s-%s, %s/%s, %s(%s), %s : %d\n",
cur->name, cur->version, cur->release,
cur->os, cur->arch,
cur->vendor, cur->distribution,
buf, cur->rating);
} else if (rpmfindVerbose > 1) {
printf("%s-%s-%s, %s(%s) : %d\n",
cur->name, cur->version, cur->release,
cur->vendor, cur->distribution, cur->rating);
}
}
/*
* Print the list of needed packages
*/
void neededPackagePrintList() {
neededPackagePtr cur = neededPackageList;
printf(" %d Packages Cnt NPkg\n",
nbNeededPackages);
while (cur != NULL) {
neededPackagePrint(cur);
cur = cur->next;
}
}
/*
* Search a needed package referenced by an URL.
*/
neededPackagePtr neededPackageSearch(const char *URL) {
neededPackagePtr cur;
cur = neededPackageList;
while(cur != NULL) {
if (!strcmp(cur->URL,URL)) return(cur);
cur = cur->next;
}
return(NULL);
}
/*
* Add a needed package to the list.
*/
void neededPackageAdd(neededPackagePtr cur) {
neededPackagePtr tmp;
#ifdef DEBUG_PACKAGES
#endif
tmp = neededPackageSearch(cur->URL);
if (tmp == NULL) {
cur->next = neededPackageList;
neededPackageList = cur;
} else if (cur != tmp)
printf("neededPackageAdd : different pkgs with same URL!\n");
}
/*
* Add a resource link from a needed package.
*/
void neededPackageAddResource(neededPackagePtr pkg, neededResourcePtr res) {
if (pkg->nb_refs >= pkg->max_refs) {
pkg->max_refs += 10;
if (pkg->refs == NULL)
pkg->refs = (neededResourcePtr *)
malloc(pkg->max_refs * sizeof(neededResourcePtr));
else
pkg->refs = (neededResourcePtr *)
realloc(pkg->refs,
pkg->max_refs * sizeof(neededResourcePtr));
if (pkg->refs == NULL) {
fprintf(stderr, "neededPackageAddResource : out of memory!\n");
exit(1);
}
}
pkg->refs[pkg->nb_refs++] = res;
res->refcount++;
}
/*
* Add a needed package from a needed resource.
*/
void neededResourceAddPackage(neededResourcePtr cur, neededPackagePtr pkg) {
neededPackageAdd(pkg);
if (cur->nb_pkgs >= cur->max_pkgs) {
cur->max_pkgs += 10;
if (cur->pkgs == NULL)
cur->pkgs = (neededPackagePtr *)
malloc(cur->max_pkgs * sizeof(neededPackagePtr));
else
cur->pkgs = (neededPackagePtr *)
realloc(cur->pkgs,
cur->max_pkgs * sizeof(neededPackagePtr));
if (cur->pkgs == NULL) {
fprintf(stderr, "neededResourceAdd : out of memory!\n");
exit(1);
}
}
cur->pkgs[cur->nb_pkgs++] = pkg;
pkg->refcount++;
}
/*
* Dereference a needed package, decrement the refcount and propagate
* to childs
*/
void neededPackageDereference(neededPackagePtr pkg) {
neededResourcePtr res;
int i;
if (pkg->refcount <= 0) {
pkg->status = STATUS_NONE;
return;
}
if (pkg->refcount > 0) pkg->refcount--;
if (pkg->refcount <= 0) {
pkg->status = STATUS_NONE;
pkg->refcount = 0;
for (i = 0;i < pkg->nb_refs; i++) {
res = pkg->refs[i];
if (!strcmp(pkg->name, res->resource)) continue;
neededResourceDrop(res);
}
}
}
/*
* Print a neededPackage structure.
*/
void neededPackageListPrint(neededPackagePtr list) {
neededPackagePtr cur = list;
while (cur != NULL) {
neededPackagePrint(cur);
cur = cur->next;
}
}
/*
* Free a neededPackage structure.
*/
void neededPackageFree(neededPackagePtr cur) {
cur->next = NULL;
cur->rating = -1;
if (cur->URL != NULL) free(cur->URL);
if (cur->name != NULL) free(cur->name);
if (cur->version != NULL) free(cur->version);
if (cur->release != NULL) free(cur->release);
if (cur->arch != NULL) free(cur->arch);
if (cur->os != NULL) free(cur->os);
if (cur->vendor != NULL) free(cur->vendor);
if (cur->distribution != NULL) free(cur->distribution);
cur->date = 0;
if (cur->subdir != NULL) free(cur->subdir);
if (cur->rpmdata != NULL) cur->rpmdata = NULL;
free(cur);
}
/*
* Enter a dialog with the user to refine the package selection.
*/
void refinePackageSelection(char *resource) {
neededResourcePtr res;
/*
neededPackagePtr packages;
int msg = 0;
*/
res = neededResourceSearch(resource);
if (res != NULL) {
printf("installing %s\n", resource);
}
}
/*
* Show the list of packages to fetch
*/
void dumpTransferList(void) {
neededPackagePtr packages;
int msg = 0;
packages = neededPackageList;
while (packages != NULL) {
if (packages->status == STATUS_TO_INSTALL) {
if (!msg) {
printf("\n### To Transfer:\n");
msg = 1;
}
printf("%s\n", packages->URL);
}
packages = packages->next;
}
}
/*
* Ask for download and fetch the packages if accepted.
*/
int rpmFindDownload(void) {
neededPackagePtr packages;
int msg = 0;
char val;
int res;
int getall;
printf("Do you want to download these files to %s ? : [Y/n/a]");
fflush(stdout);
res = scanf("%c", &val);
if (res != 1) return(0);
packages = neededPackageList;
while (packages != NULL) {
if (packages->status == STATUS_TO_INSTALL) {
printf("%s\n", packages->URL);
}
packages = packages->next;
}
}
Webmaster