csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
2ff057
/* rpmarchive: spit out the main archive portion of a package */
2ff057
2ff057
#include "system.h"
2ff057
2ff057
#include <rpm/rpmlib.h>		/* rpmReadPackageFile .. */
2ff057
#include <rpm/rpmtag.h>
2ff057
#include <rpm/rpmio.h>
2ff057
#include <rpm/rpmpgp.h>
2ff057
2ff057
#include <rpm/rpmts.h>
2ff057
#include <unistd.h>
2ff057
2ff057
#include "debug.h"
2ff057
2ff057
int main(int argc, char *argv[])
2ff057
{
2ff057
    FD_t fdi, fdo;
2ff057
    Header h;
2ff057
    char * rpmio_flags = NULL;
2ff057
    int rc;
2ff057
    off_t payload_size;
2ff057
    FD_t gzdi;
2ff057
    
2ff057
    xsetprogname(argv[0]); /* Portability call -- see system.h */
2ff057
2ff057
    rpmReadConfigFiles(NULL, NULL);
2ff057
    if (argc == 1)
2ff057
	fdi = fdDup(STDIN_FILENO);
2ff057
    else {
2ff057
	if (rstreq(argv[1], "-h") || rstreq(argv[1], "--help")) {
2ff057
	    fprintf(stderr, "Usage: rpm2cpio file.rpm\n");
2ff057
	    exit(EXIT_FAILURE);
2ff057
	}
2ff057
	fdi = Fopen(argv[1], "r.ufdio");
2ff057
    }
2ff057
2ff057
    if (Ferror(fdi)) {
2ff057
	fprintf(stderr, "%s: %s: %s\n", argv[0],
2ff057
		(argc == 1 ? "<stdin>" : argv[1]), Fstrerror(fdi));
2ff057
	exit(EXIT_FAILURE);
2ff057
    }
2ff057
    if (isatty(STDOUT_FILENO)) {
2ff057
	fprintf(stderr, "Error: refusing to output cpio data to a terminal.\n");
2ff057
	exit(EXIT_FAILURE);
2ff057
    }
2ff057
    fdo = fdDup(STDOUT_FILENO);
2ff057
2ff057
    {	rpmts ts = rpmtsCreate();
2ff057
	rpmVSFlags vsflags = 0;
2ff057
2ff057
	/* XXX retain the ageless behavior of rpm2cpio */
2ff057
        vsflags |= RPMVSF_MASK_NODIGESTS;
2ff057
        vsflags |= RPMVSF_MASK_NOSIGNATURES;
2ff057
        vsflags |= RPMVSF_NOHDRCHK;
2ff057
	(void) rpmtsSetVSFlags(ts, vsflags);
2ff057
2ff057
	rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h);
2ff057
2ff057
	ts = rpmtsFree(ts);
2ff057
    }
2ff057
2ff057
    switch (rc) {
2ff057
    case RPMRC_OK:
2ff057
    case RPMRC_NOKEY:
2ff057
    case RPMRC_NOTTRUSTED:
2ff057
	break;
2ff057
    case RPMRC_NOTFOUND:
2ff057
	fprintf(stderr, _("argument is not an RPM package\n"));
2ff057
	exit(EXIT_FAILURE);
2ff057
	break;
2ff057
    case RPMRC_FAIL:
2ff057
    default:
2ff057
	fprintf(stderr, _("error reading header from package\n"));
2ff057
	exit(EXIT_FAILURE);
2ff057
	break;
2ff057
    }
2ff057
2ff057
    /* Retrieve payload size and compression type. */
2ff057
    {	const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
2ff057
	rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
2ff057
	payload_size = headerGetNumber(h, RPMTAG_LONGARCHIVESIZE);
2ff057
    }
2ff057
2ff057
    gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
2ff057
    free(rpmio_flags);
2ff057
2ff057
    if (gzdi == NULL) {
2ff057
	fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
2ff057
	exit(EXIT_FAILURE);
2ff057
    }
2ff057
0c944f
    /*
0c944f
     * XXX HACK for #1142949: should be equality test, but archive size
0c944f
     * short by cpio trailer size in packages built with rpm 4.12.0
0c944f
     * and its pre-releases.
0c944f
     */
0c944f
    rc = (ufdCopy(gzdi, fdo) >= payload_size) ? EXIT_SUCCESS : EXIT_FAILURE;
2ff057
2ff057
    Fclose(fdo);
2ff057
2ff057
    Fclose(gzdi);	/* XXX gzdi == fdi */
2ff057
2ff057
    return rc;
2ff057
}