File:  [Public] / rpmfind / deps.c
Revision 1.4: download - view: text, annotated - select for diffs
Wed Jun 10 22:26:41 1998 UTC (25 years, 11 months ago) by veillard
Branches: MAIN
CVS tags: HEAD
Start adding transfer capability, Daniel.

/*
 * 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