csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
2ff057
#include "system.h"
2ff057
2ff057
#include <rpm/rpmcli.h>
2ff057
#include <rpm/rpmlib.h>		/* rpmReadPackageFile */
2ff057
#include <rpm/rpmdb.h>
2ff057
#include <rpm/rpmps.h>
2ff057
#include <rpm/rpmte.h>
2ff057
#include <rpm/rpmts.h>
2ff057
#include <rpm/rpmds.h>
2ff057
2ff057
#include <rpm/rpmlog.h>
2ff057
#include <rpm/rpmfileutil.h>
2ff057
2ff057
#include "lib/manifest.h"
2ff057
#include "debug.h"
2ff057
2ff057
static int noDeps = 1;
2ff057
2ff057
static rpmVSFlags vsflags = 0;
2ff057
2ff057
static int
2ff057
rpmGraph(rpmts ts, struct rpmInstallArguments_s * ia, const char ** fileArgv)
2ff057
{
2ff057
    char ** pkgURL = NULL;
2ff057
    char * pkgState = NULL;
2ff057
    const char ** fnp;
2ff057
    char * fileURL = NULL;
2ff057
    int numPkgs = 0;
2ff057
    int numFailed = 0;
2ff057
    int prevx = 0;
2ff057
    int pkgx = 0;
2ff057
    char ** argv = NULL;
2ff057
    int argc = 0;
2ff057
    char ** av = NULL;
2ff057
    int ac = 0;
2ff057
    Header h;
2ff057
    rpmRC rpmrc;
2ff057
    int rc = 0;
2ff057
    rpmVSFlags ovsflags;
2ff057
    int i;
2ff057
2ff057
    if (fileArgv == NULL)
2ff057
	return 0;
2ff057
2ff057
    /* Build fully globbed list of arguments in argv[argc]. */
2ff057
    for (fnp = fileArgv; *fnp; fnp++) {
2ff057
	av = _free(av);
2ff057
	ac = 0;
2ff057
	rc = rpmGlob(*fnp, &ac, &av;;
2ff057
	if (rc || ac == 0) continue;
2ff057
2ff057
	argv = xrealloc(argv, (argc+2) * sizeof(*argv));
2ff057
	memcpy(argv+argc, av, ac * sizeof(*av));
2ff057
	argc += ac;
2ff057
	argv[argc] = NULL;
2ff057
    }
2ff057
    av = _free(av);	ac = 0;
2ff057
2ff057
restart:
2ff057
    /* Allocate sufficient storage for next set of args. */
2ff057
    if (pkgx >= numPkgs) {
2ff057
	numPkgs = pkgx + argc;
2ff057
	pkgURL = xrealloc(pkgURL, (numPkgs + 1) * sizeof(*pkgURL));
2ff057
	memset(pkgURL + pkgx, 0, ((argc + 1) * sizeof(*pkgURL)));
2ff057
	pkgState = xrealloc(pkgState, (numPkgs + 1) * sizeof(*pkgState));
2ff057
	memset(pkgState + pkgx, 0, ((argc + 1) * sizeof(*pkgState)));
2ff057
    }
2ff057
2ff057
    /* Copy next set of args. */
2ff057
    for (i = 0; i < argc; i++) {
2ff057
	fileURL = _free(fileURL);
2ff057
	fileURL = argv[i];
2ff057
	argv[i] = NULL;
2ff057
2ff057
	pkgURL[pkgx] = fileURL;
2ff057
	fileURL = NULL;
2ff057
	pkgx++;
2ff057
    }
2ff057
    fileURL = _free(fileURL);
2ff057
2ff057
    /* Continue processing file arguments, building transaction set. */
2ff057
    for (fnp = (const char **) pkgURL+prevx; *fnp != NULL; fnp++, prevx++) {
2ff057
	const char * fileName;
2ff057
	FD_t fd;
2ff057
2ff057
	(void) urlPath(*fnp, &fileName);
2ff057
2ff057
	/* Try to read the header from a package file. */
2ff057
	fd = Fopen(*fnp, "r.ufdio");
2ff057
	if (fd == NULL || Ferror(fd)) {
2ff057
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *fnp,
2ff057
			Fstrerror(fd));
2ff057
	    if (fd) {
2ff057
		Fclose(fd);
2ff057
		fd = NULL;
2ff057
	    }
2ff057
	    numFailed++; *fnp = NULL;
2ff057
	    continue;
2ff057
	}
2ff057
2ff057
	/* Read the header, verifying signatures (if present). */
2ff057
	ovsflags = rpmtsSetVSFlags(ts, vsflags);
2ff057
	rpmrc = rpmReadPackageFile(ts, fd, *fnp, &h);
2ff057
	rpmtsSetVSFlags(ts, ovsflags);
2ff057
	Fclose(fd);
2ff057
	fd = NULL;
2ff057
2ff057
	switch (rpmrc) {
2ff057
	case RPMRC_FAIL:
2ff057
	default:
2ff057
	    rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *fnp);
2ff057
	    numFailed++; *fnp = NULL;
2ff057
	    break;
2ff057
	case RPMRC_OK:
2ff057
	    rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName, 0, NULL);
2ff057
	    break;
2ff057
	case RPMRC_NOTFOUND:
2ff057
	    goto maybe_manifest;
2ff057
	    break;
2ff057
	}
2ff057
	h = headerFree(h); 
2ff057
	continue;
2ff057
2ff057
maybe_manifest:
2ff057
	/* Try to read a package manifest. */
2ff057
	fd = Fopen(*fnp, "r.ufdio");
2ff057
	if (fd == NULL || Ferror(fd)) {
2ff057
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *fnp,
2ff057
			Fstrerror(fd));
2ff057
	    if (fd) {
2ff057
		Fclose(fd);
2ff057
		fd = NULL;
2ff057
	    }
2ff057
	    numFailed++; *fnp = NULL;
2ff057
	    break;
2ff057
	}
2ff057
2ff057
	/* Read list of packages from manifest. */
2ff057
	rc = rpmReadPackageManifest(fd, &argc, &argv);
2ff057
	if (rc)
2ff057
	    rpmlog(RPMLOG_NOTICE, _("%s: read manifest failed: %s\n"),
2ff057
			fileURL, Fstrerror(fd));
2ff057
	Fclose(fd);
2ff057
	fd = NULL;
2ff057
2ff057
	/* If successful, restart the query loop. */
2ff057
	if (rc == 0) {
2ff057
	    prevx++;
2ff057
	    goto restart;
2ff057
	}
2ff057
2ff057
	numFailed++; *fnp = NULL;
2ff057
	break;
2ff057
    }
2ff057
2ff057
    if (numFailed > 0) goto exit;
2ff057
2ff057
    if (!noDeps) {
2ff057
	rpmps ps;
2ff057
	rc = rpmtsCheck(ts);
2ff057
	if (rc) {
2ff057
	    numFailed += numPkgs;
2ff057
	    goto exit;
2ff057
	}
2ff057
	ps = rpmtsProblems(ts);
2ff057
	if (rpmpsNumProblems(ps) > 0) {
2ff057
	    rpmlog(RPMLOG_ERR, _("Failed dependencies:\n"));
2ff057
	    rpmpsPrint(NULL, ps);
2ff057
	    numFailed += numPkgs;
2ff057
	}
2ff057
	rpmpsFree(ps);
2ff057
    }
2ff057
2ff057
    rc = rpmtsOrder(ts);
2ff057
    if (rc)
2ff057
	goto exit;
2ff057
2ff057
    {	rpmtsi pi;
2ff057
	rpmte p;
2ff057
	rpmte q;
2ff057
	int oType = TR_ADDED;
2ff057
2ff057
	fprintf(stdout, "digraph XXX {\n");
2ff057
2ff057
	fprintf(stdout, "  rankdir=LR\n");
2ff057
2ff057
	fprintf(stdout, "//===== Packages:\n");
2ff057
	pi = rpmtsiInit(ts);
2ff057
	while ((p = rpmtsiNext(pi, oType)) != NULL) {
2ff057
	    q = rpmteParent(p);
2ff057
	    if (q != NULL)
2ff057
		fprintf(stdout, "  \"%s\" -> \"%s\"\n", rpmteN(p), rpmteN(q));
2ff057
	    else {
2ff057
		fprintf(stdout, "  \"%s\"\n", rpmteN(p));
2ff057
		fprintf(stdout, "  { rank=max ; \"%s\" }\n", rpmteN(p));
2ff057
	    }
2ff057
	}
2ff057
	rpmtsiFree(pi);
2ff057
2ff057
	fprintf(stdout, "}\n");
2ff057
    }
2ff057
2ff057
    rc = 0;
2ff057
2ff057
exit:
2ff057
    for (i = 0; i < numPkgs; i++)
2ff057
        pkgURL[i] = _free(pkgURL[i]);
2ff057
    pkgState = _free(pkgState);
2ff057
    pkgURL = _free(pkgURL);
2ff057
    argv = _free(argv);
2ff057
2ff057
    return rc;
2ff057
}
2ff057
2ff057
static struct poptOption optionsTable[] = {
2ff057
 { "check", '\0', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &noDeps, 0,
2ff057
	N_("don't verify package dependencies"), NULL },
2ff057
 { "nolegacy", '\0', POPT_BIT_SET,	&vsflags, RPMVSF_NEEDPAYLOAD,
2ff057
        N_("don't verify header+payload signature"), NULL },
2ff057
 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
2ff057
	N_("Common options for all rpm modes and executables:"),
2ff057
	NULL }, 
2ff057
2ff057
   POPT_AUTOALIAS
2ff057
   POPT_AUTOHELP
2ff057
   POPT_TABLEEND
2ff057
};
2ff057
2ff057
int
2ff057
main(int argc, char *argv[])
2ff057
{
2ff057
    rpmts ts = NULL;
2ff057
    struct rpmInstallArguments_s * ia = &rpmIArgs;
2ff057
    poptContext optCon;
2ff057
    int ec = 0;
2ff057
2ff057
    xsetprogname(argv[0]); /* Portability call -- see system.h */
2ff057
2ff057
    optCon = rpmcliInit(argc, argv, optionsTable);
2ff057
    if (optCon == NULL)
2ff057
	exit(EXIT_FAILURE);
2ff057
2ff057
    ts = rpmtsCreate();
2ff057
    vsflags |= rpmcliVSFlags;
2ff057
    (void) rpmtsSetVSFlags(ts, vsflags);
2ff057
2ff057
    ec = rpmGraph(ts, ia, poptGetArgs(optCon));
2ff057
2ff057
    rpmtsFree(ts);
2ff057
2ff057
    rpmcliFini(optCon);
2ff057
2ff057
    return ec;
2ff057
}