Ejemplo n.º 1
0
static int rpmtsSetup(rpmts ts, rpmprobFilterFlags ignoreSet)
{
    rpm_tid_t tid = (rpm_tid_t) time(NULL);
    int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST) ?  O_RDONLY : (O_RDWR|O_CREAT);

    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));

    if (rpmtsFlags(ts) & (RPMTRANS_FLAG_JUSTDB | RPMTRANS_FLAG_TEST))
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));

    /* 
     * Make sure the database is open RDWR for package install/erase.
     * Note that we initialize chroot state here even if it's just "/" as
     * this ensures we can successfully perform open(".") which is
     * required to reliably restore cwd after Lua scripts.
     */ 
    if (rpmtsOpenDB(ts, dbmode) || rpmChrootSet(rpmtsRootDir(ts)))
	return -1;

    ts->ignoreSet = ignoreSet;
    (void) rpmtsSetTid(ts, tid);

    /* Get available space on mounted file systems. */
    (void) rpmtsInitDSI(ts);

    return 0;
}
Ejemplo n.º 2
0
static JSObject *
rpmtsLoadNVRA(JSContext *cx, JSObject *obj)
{
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL);
    rpmts ts = ptr;
    JSObject * NVRA = JS_NewArrayObject(cx, 0, NULL);
    ARGV_t keys = NULL;
    int nkeys;
    int xx;
    int i;

    if (ts->rdb == NULL)
	(void) rpmtsOpenDB(ts, O_RDONLY);

    xx = rpmdbMireApply(rpmtsGetRdb(ts), RPMTAG_NVRA,
		RPMMIRE_STRCMP, NULL, &keys);
    nkeys = argvCount(keys);

    if (keys)
    for (i = 0; i < nkeys; i++) {
	JSString * valstr = JS_NewStringCopyZ(cx, keys[i]);
	jsval id = STRING_TO_JSVAL(valstr);
	JS_SetElement(cx, NVRA, i, &id);
    }

    JS_DefineProperty(cx, obj, "NVRA", OBJECT_TO_JSVAL(NVRA),
				NULL, NULL, JSPROP_ENUMERATE);

if (_debug)
fprintf(stderr, "==> %s(%p,%p) ptr %p NVRA %p\n", __FUNCTION__, cx, obj, ptr, NVRA);

    return NVRA;
}
Ejemplo n.º 3
0
static PyObject *
rpmts_index(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
    rpmDbiTagVal tag;
    PyObject *mio = NULL;
    char * kwlist[] = {"tag", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:Keys", kwlist,
              tagNumFromPyObject, &tag))
	return NULL;

    /* XXX If not already opened, open the database O_RDONLY now. */
    if (rpmtsGetRdb(s->ts) == NULL) {
	int rc = rpmtsOpenDB(s->ts, O_RDONLY);
	if (rc || rpmtsGetRdb(s->ts) == NULL) {
	    PyErr_SetString(pyrpmError, "rpmdb open failed");
	    goto exit;
	}
    }

    rpmdbIndexIterator ii = rpmdbIndexIteratorInit(rpmtsGetRdb(s->ts), tag);
    if (ii == NULL) {
        PyErr_SetString(PyExc_KeyError, "No index for this tag");
        return NULL;
    }
    mio = rpmii_Wrap(&rpmii_Type, ii, (PyObject*)s);

exit:
    return mio;
}
Ejemplo n.º 4
0
Archivo: verify.c Proyecto: xrg/RPM
int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv)
{
    rpmVSFlags vsflags, ovsflags;
    int ec = 0, xx;
    const char * rootDir = rpmtsRootDir(ts);

    /* 
     * Open the DB + indices explicitly before possible chroot,
     * otherwises BDB is going to be unhappy...
     */
    rpmtsOpenDB(ts, O_RDONLY);
    rpmdbOpenAll(rpmtsGetRdb(ts));
    if (rootDir && strcmp(rootDir, "/") != 0) {
	if (chroot(rootDir) == -1) {
	    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
	    ec = 1;
	    goto exit;
	} else {
	    rpmtsSetChrootDone(ts, 1);
	}
    }

    if (qva->qva_showPackage == NULL)
        qva->qva_showPackage = showVerifyPackage;

    /* XXX verify flags are inverted from query. */
    vsflags = rpmExpandNumeric("%{?_vsflags_verify}");
    if (!(qva->qva_flags & VERIFY_DIGEST))
	vsflags |= _RPMVSF_NODIGESTS;
    if (!(qva->qva_flags & VERIFY_SIGNATURE))
	vsflags |= _RPMVSF_NOSIGNATURES;
    if (!(qva->qva_flags & VERIFY_HDRCHK))
	vsflags |= RPMVSF_NOHDRCHK;
    vsflags &= ~RPMVSF_NEEDPAYLOAD;

    ovsflags = rpmtsSetVSFlags(ts, vsflags);
    ec = rpmcliArgIter(ts, qva, argv);
    vsflags = rpmtsSetVSFlags(ts, ovsflags);

    if (qva->qva_showPackage == showVerifyPackage)
        qva->qva_showPackage = NULL;

    rpmtsEmpty(ts);

    if (rpmtsChrootDone(ts)) {
	/* only done if previous chroot succeeded, assume success */
	xx = chroot(".");
	rpmtsSetChrootDone(ts, 0);
    }

exit:

    return ec;
}
Ejemplo n.º 5
0
static PyObject *
rpmts_OpenDB(rpmtsObject * s)
{
    int dbmode;

    dbmode = rpmtsGetDBMode(s->ts);
    if (dbmode == -1)
	dbmode = O_RDONLY;

    return Py_BuildValue("i", rpmtsOpenDB(s->ts, dbmode));
}
Ejemplo n.º 6
0
rpmRC rpmtsImportHeader(rpmtxn txn, Header h, rpmFlags flags)
{
    rpmRC rc = RPMRC_FAIL;

    if (txn && h && rpmtsOpenDB(txn->ts, (O_RDWR|O_CREAT)) == 0) {
	if (rpmdbAdd(rpmtsGetRdb(txn->ts), h) == 0) {
	    rc = RPMRC_OK;
	}
    }
    return rc;
}
Ejemplo n.º 7
0
static PyObject *
rpmts_Match(rpmtsObject * s, PyObject * args, PyObject * kwds)
{
    PyObject *Key = NULL;
    PyObject *str = NULL;
    PyObject *mio = NULL;
    char *key = NULL;
    /* XXX lkey *must* be a 32 bit integer, int "works" on all known platforms. */
    int lkey = 0;
    int len = 0;
    rpmDbiTagVal tag = RPMDBI_PACKAGES;
    char * kwlist[] = {"tagNumber", "key", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O:Match", kwlist,
                                     tagNumFromPyObject, &tag, &Key))
        return NULL;

    if (Key) {
        if (PyInt_Check(Key)) {
            lkey = PyInt_AsLong(Key);
            key = (char *)&lkey;
            len = sizeof(lkey);
        } else if (PyLong_Check(Key)) {
            lkey = PyLong_AsLong(Key);
            key = (char *)&lkey;
            len = sizeof(lkey);
        } else if (utf8FromPyObject(Key, &str)) {
            key = PyBytes_AsString(str);
            len = PyBytes_Size(str);
        } else {
            PyErr_SetString(PyExc_TypeError, "unknown key type");
            return NULL;
        }
        /* One of the conversions above failed, exception is set already */
        if (PyErr_Occurred()) goto exit;
    }

    /* XXX If not already opened, open the database O_RDONLY now. */
    /* XXX FIXME: lazy default rdonly open also done by rpmtsInitIterator(). */
    if (rpmtsGetRdb(s->ts) == NULL) {
        int rc = rpmtsOpenDB(s->ts, O_RDONLY);
        if (rc || rpmtsGetRdb(s->ts) == NULL) {
            PyErr_SetString(pyrpmError, "rpmdb open failed");
            goto exit;
        }
    }

    mio = rpmmi_Wrap(&rpmmi_Type, rpmtsInitIterator(s->ts, tag, key, len), (PyObject*)s);

exit:
    Py_XDECREF(str);
    return mio;
}
Ejemplo n.º 8
0
Archivo: verify.c Proyecto: kaltsi/rpm
int rpmcliVerify(rpmts ts, QVA_t qva, char * const * argv)
{
    rpmVSFlags vsflags, ovsflags;
    int ec = 0;
    FD_t scriptFd = fdDup(STDOUT_FILENO);

    /* 
     * Open the DB + indices explicitly before possible chroot,
     * otherwises BDB is going to be unhappy...
     */
    rpmtsOpenDB(ts, O_RDONLY);
    rpmdbOpenAll(rpmtsGetRdb(ts));
    if (rpmChrootSet(rpmtsRootDir(ts)) || rpmChrootIn()) {
	ec = 1;
	goto exit;
    }

    if (qva->qva_showPackage == NULL)
        qva->qva_showPackage = showVerifyPackage;

    vsflags = rpmExpandNumeric("%{?_vsflags_verify}");
    if (rpmcliQueryFlags & VERIFY_DIGEST)
	vsflags |= _RPMVSF_NODIGESTS;
    if (rpmcliQueryFlags & VERIFY_SIGNATURE)
	vsflags |= _RPMVSF_NOSIGNATURES;
    if (rpmcliQueryFlags & VERIFY_HDRCHK)
	vsflags |= RPMVSF_NOHDRCHK;
    vsflags &= ~RPMVSF_NEEDPAYLOAD;

    rpmtsSetScriptFd(ts, scriptFd);
    ovsflags = rpmtsSetVSFlags(ts, vsflags);
    ec = rpmcliArgIter(ts, qva, argv);
    vsflags = rpmtsSetVSFlags(ts, ovsflags);
    rpmtsSetScriptFd(ts, NULL);

    if (qva->qva_showPackage == showVerifyPackage)
        qva->qva_showPackage = NULL;

    rpmtsEmpty(ts);

    if (rpmChrootOut() || rpmChrootSet(NULL))
	ec = 1;

exit:
    Fclose(scriptFd);

    return ec;
}
Ejemplo n.º 9
0
rpmRC rpmtsImportPubkey(const rpmts ts, const unsigned char * pkt, size_t pktlen)
{
    Header h = NULL;
    rpmRC rc = RPMRC_FAIL;		/* assume failure */
    rpmPubkey pubkey = NULL;
    rpmVSFlags oflags = rpmtsVSFlags(ts);
    rpmKeyring keyring;
    int krc;

    /* XXX keyring wont load if sigcheck disabled, force it temporarily */
    rpmtsSetVSFlags(ts, (oflags & ~_RPMVSF_NOSIGNATURES));
    keyring = rpmtsGetKeyring(ts, 1);
    rpmtsSetVSFlags(ts, oflags);

    if ((pubkey = rpmPubkeyNew(pkt, pktlen)) == NULL)
	goto exit;
    krc = rpmKeyringAddKey(keyring, pubkey);
    if (krc < 0)
	goto exit;

    /* If we dont already have the key, make a persistent record of it */
    if (krc == 0) {
	rpm_tid_t tid = rpmtsGetTid(ts);

	if (makePubkeyHeader(ts, pubkey, &h) != 0) 
	    goto exit;

	headerPutUint32(h, RPMTAG_INSTALLTIME, &tid, 1);
	headerPutUint32(h, RPMTAG_INSTALLTID, &tid, 1);

	/* Add header to database. */
	if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
	    if (rpmtsOpenDB(ts, (O_RDWR|O_CREAT)))
		goto exit;
	    if (rpmdbAdd(rpmtsGetRdb(ts), h) != 0)
		goto exit;
	}
    }
    rc = RPMRC_OK;

exit:
    /* Clean up. */
    headerFree(h);
    rpmPubkeyFree(pubkey);
    rpmKeyringFree(keyring);
    return rc;
}
Ejemplo n.º 10
0
Archivo: tssl.c Proyecto: avokhmin/RPM5
int
main(int argc, char *argv[])
{
    poptContext optCon = rpmcliInit(argc, argv, optionsTable);
    rpmts ts = rpmtsCreate();
    int rc = rpmtsOpenDB(ts, O_RDONLY);

fprintf(stderr, " DSA");
    rc = doit(ts, "DSA");
fprintf(stderr, " RSA");
    rc = doit(ts, "RSA");
fprintf(stderr, "\n");

    (void) rpmtsFree(ts); 
    ts = NULL;

    optCon = rpmcliFini(optCon);

    return rc;
}
Ejemplo n.º 11
0
static JSBool
rpmts_dbkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
    void * ptr = JS_GetInstancePrivate(cx, obj, &rpmtsClass, NULL);
    rpmts ts = ptr;
    jsval tagid = JSVAL_VOID;
    jsval v = JSVAL_VOID;
    rpmTag tag = RPMTAG_NVRA;
    rpmMireMode _mode = RPMMIRE_PCRE;
    const char * _pat = "^a.*$";
    ARGV_t _av = NULL;
    JSBool ok = JS_FALSE;
    int xx;

_METHOD_DEBUG_ENTRY(_debug);

    if (!(ok = JS_ConvertArguments(cx, argc, argv, "/vvu", &v, &tagid, &v, &_mode)))
        goto exit;

    if (!JSVAL_IS_VOID(tagid)) {
	/* XXX TODO: make sure both tag and key were specified. */
	tag = JSVAL_IS_INT(tagid)
		? (rpmTag) JSVAL_TO_INT(tagid)
		: tagValue(JS_GetStringBytes(JS_ValueToString(cx, tagid)));
    }

    if (JSVAL_IS_VOID(v))
	_pat = "^.*$";
    else if (JSVAL_IS_NULL(v))
	_pat = NULL;
    else if (JSVAL_IS_STRING(v))
	_pat = JS_GetStringBytes(JS_ValueToString(cx, v));
#ifdef	NOTYET
    else if (JSVAL_IS_NUMBER(v)) {
	uint32_t _u = 0;
	if (!JS_ValueToECMAUint32(cx, v, &_u)) {
	    *rval = JSVAL_VOID;
	    goto exit;
	}
    } else
	;
#endif

    switch (_mode) {
    default:
	*rval = JSVAL_VOID;
	goto exit;
	break;
    case RPMMIRE_DEFAULT:
    case RPMMIRE_STRCMP:
    case RPMMIRE_REGEX:
    case RPMMIRE_GLOB:
    case RPMMIRE_PCRE:
	break;
    }

    if (rpmtsGetRdb(ts) == NULL)
	xx = rpmtsOpenDB(ts, O_RDONLY);

    if (rpmdbMireApply(rpmtsGetRdb(ts), tag, _mode, _pat, &_av))
	*rval = JSVAL_VOID;
    else if (_av == NULL || _av[0] == NULL)
	*rval = JSVAL_NULL;
    else {
	int _ac = argvCount(_av);
	int i;
	JSObject * arr = JS_NewArrayObject(cx, 0, NULL);
	*rval = OBJECT_TO_JSVAL(arr);

	for (i = 0; i < _ac; i++) {
	    v = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, _av[i]));
	    ok = JS_SetElement(cx, arr, i, &v);
	}
    }

exit:
    ok = JS_TRUE;
    _av = argvFree(_av);
    return ok;
}
Ejemplo n.º 12
0
int main(int argc, char **argv)
{
	rpmts ts;
	rpmps probs;
	int probFilter = 0;
	int notifyFlags = 0;
	int tsFlags = 0;
	int rc = 0;
	
	/* Read configuration, initialize transaction */
	rpmReadConfigFiles(NULL, NULL);
	ts = rpmtsCreate();

	/* Set verification flags if needed, for example --nomd5 */
	/* rpmtsSetVSFlags(ts, rpmtsVSFlags(ts) | RPMVSF_NOMD5); */

	/* Open rpmdb */
	//rpmtsSetRootDir(ts, NULL);
	rc = rpmtsOpenDB(ts, O_RDWR);
	if (rc) {
		printf("Error opening rpmdb\n");
		goto exit;
	}

	/* Add packages for install/upgrade/erase */
	while (optind < argc) {
		int upgrade = 0;
		switch (getopt(argc, argv, "i:U:e:")) {
			case 'U':
				upgrade = 1;
			case 'i':
				add_for_install(ts, optarg, upgrade);
				break;
			case 'e':
				add_for_erase(ts, optarg);
				break;
			default:
				printf("usage ...\n");
				goto exit;
		}
	}

	/* Set problem filters if needed, for example --oldpackage */
	/* rpmbFilter |= RPMPROB_FILTER_OLDPACKAGE /*

	/* Set transaction flags if needed, for example --excludedocs */
	/* tsFlags |= RPMTRANS_FLAG_NODOCS */
	
	/* Check transaction sanity */
	rc = rpmtsCheck(ts);
	probs = rpmtsProblems(ts);
	if (rc || rpmpsNumProblems(probs)) {
		rpmpsPrint(NULL, probs);
		rpmpsFree(probs);
		goto exit;
	}
	
        /* Create ordering for the transaction */
	rc = rpmtsOrder(ts);
	if (rc > 0) {
		printf("Ordering failed\n");
		goto exit;
	}
	rpmtsClean(ts);

	/* Set callback routine & flags, for example -vh */
	notifyFlags |= INSTALL_LABEL | INSTALL_HASH;
	rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *)notifyFlags);

	/* Set transaction flags and run the actual transaction */
	rpmtsSetFlags(ts, (rpmtransFlags)(rpmtsFlags(ts) | tsFlags));
	rc = rpmtsRun(ts, NULL, (rpmprobFilterFlags)probFilter);
	/* Check for results .. */
   	if (rc || rpmpsNumProblems(probs) > 0)
		rpmpsPrint(stderr, probs);
	rpmpsFree(probs);

exit:
	/* ..and clean up */
	rpmtsFree(ts);
	exit(rc);
}	
Ejemplo n.º 13
0
/**
 * gs_plugin_refine_app:
 */
gboolean
gs_plugin_refine_app (GsPlugin *plugin,
		      GsApp *app,
		      GsPluginRefineFlags flags,
		      GCancellable *cancellable,
		      GError **error)
{
	Header h;
	const gchar *fn;
	gint rc;
	g_auto(rpmdbMatchIterator) mi = NULL;
	g_auto(rpmts) ts = NULL;

	/* not required */
	if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION) == 0 &&
	    (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE) == 0 &&
	    (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE) == 0 &&
	    (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SETUP_ACTION) == 0)
		return TRUE;

	/* no need to run the plugin */
	if (gs_app_get_source_default (app) != NULL &&
	    gs_app_get_source_id_default (app) != NULL)
		return TRUE;

	/* open db readonly */
	ts = rpmtsCreate();
	rpmtsSetRootDir (ts, NULL);
	rc = rpmtsOpenDB (ts, O_RDONLY);
	if (rc != 0) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_FAILED,
			     "Failed to open rpmdb: %i", rc);
		return FALSE;
	}

	/* look for a specific file */
	fn = gs_app_get_metadata_item (app, "appstream::source-file");
	if (fn == NULL)
		return TRUE;
	if (!g_str_has_prefix (fn, "/usr"))
		return TRUE;
	mi = rpmtsInitIterator (ts, RPMDBI_INSTFILENAMES, fn, 0);
	if (mi == NULL) {
		g_debug ("rpm: no search results for %s", fn);
		return TRUE;
	}

	/* on rpm-ostree this package cannot be removed 'live' */
	gs_app_add_quirk (app, AS_APP_QUIRK_COMPULSORY);

	/* process any results */
	g_debug ("rpm: querying for %s with %s", gs_app_get_id (app), fn);
	while ((h = rpmdbNextIterator (mi)) != NULL) {
		guint64 epoch;
		const gchar *name;
		const gchar *version;
		const gchar *arch;
		const gchar *release;
		const gchar *license;

		/* add default source */
		name = headerGetString (h, RPMTAG_NAME);
		if (gs_app_get_source_default (app) == NULL) {
			g_debug ("rpm: setting source to %s", name);
			gs_app_add_source (app, name);
		}

		/* set size */
		if (gs_app_get_size_download (app) == 0)
			gs_app_set_size_download (app, 0);
		if (gs_app_get_size_installed (app) == 0) {
			guint64 tmp;
			tmp = headerGetNumber (h, RPMTAG_SIZE);
			gs_app_set_size_installed (app, tmp);
		}

		/* set license */
		license = headerGetString (h, RPMTAG_LICENSE);
		if (gs_app_get_license (app) == NULL && license != NULL) {
			g_autofree gchar *tmp = NULL;
			tmp = as_utils_license_to_spdx (license);
			gs_app_set_license (app, GS_APP_QUALITY_NORMAL, tmp);
		}

		/* add version */
		version = headerGetString (h, RPMTAG_VERSION);
		if (gs_app_get_version (app) == NULL) {
			g_debug ("rpm: setting version to %s", version);
			gs_app_set_version (app, version);
		}

		/* add source-id */
		if (gs_app_get_source_id_default (app) == NULL) {
			g_autofree gchar *tmp = NULL;
			release = headerGetString (h, RPMTAG_RELEASE);
			arch = headerGetString (h, RPMTAG_ARCH);
			epoch = headerGetNumber (h, RPMTAG_EPOCH);
			if (epoch > 0) {
				tmp = g_strdup_printf ("%s;%" G_GUINT64_FORMAT ":%s-%s;%s;installed",
						       name, epoch, version, release, arch);
			} else {
				tmp = g_strdup_printf ("%s;%s-%s;%s;installed",
						       name, version, release, arch);
			}
			g_debug ("rpm: setting source-id to %s", tmp);
			gs_app_add_source_id (app, tmp);
		}
	}

	return TRUE;
}
Ejemplo n.º 14
0
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    int i;
    int rc = 0;
    int totalFileCount = 0;
    rpmfi fi;
    fingerPrintCache fpc;
    rpmps ps;
    rpmtsi pi;	rpmte p;
    int numAdded;
    int numRemoved;
    void * lock = NULL;
    int xx;

    /* XXX programmer error segfault avoidance. */
    if (rpmtsNElements(ts) <= 0)
	return -1;

    /* If we are in test mode, then there's no need for transaction lock. */
    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
	lock = rpmtsAcquireLock(ts);
	if (lock == NULL)
	    return -1;	/* XXX W2DO? */
    }

    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOSCRIPTS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));
    if (rpmtsFlags(ts) & RPMTRANS_FLAG_NOTRIGGERS)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransTriggers));

    if (rpmtsFlags(ts) & RPMTRANS_FLAG_JUSTDB)
	(void) rpmtsSetFlags(ts, (rpmtsFlags(ts) | _noTransScripts | _noTransTriggers));

    /* if SELinux isn't enabled or init fails, don't bother... */
    if (!rpmtsSELinuxEnabled(ts)) {
        rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
    }

    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
	char *fn = rpmGetPath("%{?_install_file_context_path}", NULL);
	if (matchpathcon_init(fn) == -1) {
	    rpmtsSetFlags(ts, (rpmtsFlags(ts) | RPMTRANS_FLAG_NOCONTEXTS));
	}
	free(fn);
    }

    ts->probs = rpmpsFree(ts->probs);
    ts->probs = rpmpsCreate();

    /* XXX Make sure the database is open RDWR for package install/erase. */
    {	int dbmode = (rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)
		? O_RDONLY : (O_RDWR|O_CREAT);

	/* Open database RDWR for installing packages. */
	if (rpmtsOpenDB(ts, dbmode)) {
	    rpmtsFreeLock(lock);
	    return -1;	/* XXX W2DO? */
	}
    }

    ts->ignoreSet = ignoreSet;
    {	char * currDir = rpmGetCwd();
	rpmtsSetCurrDir(ts, currDir);
	currDir = _free(currDir);
    }

    (void) rpmtsSetChrootDone(ts, 0);

    {	rpm_tid_t tid = (rpm_tid_t) time(NULL);
	(void) rpmtsSetTid(ts, tid);
    }

    /* Get available space on mounted file systems. */
    xx = rpmtsInitDSI(ts);

    /* ===============================================
     * For packages being installed:
     * - verify package arch/os.
     * - verify package epoch:version-release is newer.
     * - count files.
     * For packages being removed:
     * - count files.
     */

    rpmlog(RPMLOG_DEBUG, "sanity checking %d elements\n", rpmtsNElements(ts));
    ps = rpmtsProblems(ts);
    /* The ordering doesn't matter here */
    pi = rpmtsiInit(ts);
    /* XXX Only added packages need be checked. */
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
	rpmdbMatchIterator mi;
	int fc;

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREARCH))
	    if (!archOkay(rpmteA(p)))
		rpmpsAppend(ps, RPMPROB_BADARCH,
			rpmteNEVRA(p), rpmteKey(p),
			rpmteA(p), NULL,
			NULL, 0);

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_IGNOREOS))
	    if (!osOkay(rpmteO(p)))
		rpmpsAppend(ps, RPMPROB_BADOS,
			rpmteNEVRA(p), rpmteKey(p),
			rpmteO(p), NULL,
			NULL, 0);

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_OLDPACKAGE)) {
	    Header h;
	    mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
	    while ((h = rpmdbNextIterator(mi)) != NULL)
		xx = ensureOlder(ts, p, h);
	    mi = rpmdbFreeIterator(mi);
	}

	if (!(rpmtsFilterFlags(ts) & RPMPROB_FILTER_REPLACEPKG)) {
	    mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(p), 0);
	    xx = rpmdbSetIteratorRE(mi, RPMTAG_EPOCH, RPMMIRE_STRCMP,
				rpmteE(p));
	    xx = rpmdbSetIteratorRE(mi, RPMTAG_VERSION, RPMMIRE_STRCMP,
				rpmteV(p));
	    xx = rpmdbSetIteratorRE(mi, RPMTAG_RELEASE, RPMMIRE_STRCMP,
				rpmteR(p));
	    if (tscolor) {
		xx = rpmdbSetIteratorRE(mi, RPMTAG_ARCH, RPMMIRE_STRCMP,
				rpmteA(p));
		xx = rpmdbSetIteratorRE(mi, RPMTAG_OS, RPMMIRE_STRCMP,
				rpmteO(p));
	    }

	    while (rpmdbNextIterator(mi) != NULL) {
		rpmpsAppend(ps, RPMPROB_PKG_INSTALLED,
			rpmteNEVRA(p), rpmteKey(p),
			NULL, NULL,
			NULL, 0);
		break;
	    }
	    mi = rpmdbFreeIterator(mi);
	}

	/* Count no. of files (if any). */
	totalFileCount += fc;

    }
    pi = rpmtsiFree(pi);
    ps = rpmpsFree(ps);

    /* The ordering doesn't matter here */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
	int fc;

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	totalFileCount += fc;
    }
    pi = rpmtsiFree(pi);


    /* Run pre-transaction scripts, but only if there are no known
     * problems up to this point and not disabled otherwise. */
    if (!((rpmtsFlags(ts) & (RPMTRANS_FLAG_BUILD_PROBS|RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPRE))
     	  || (rpmpsNumProblems(ts->probs) &&
		(okProbs == NULL || rpmpsTrim(ts->probs, okProbs))))) {
	rpmlog(RPMLOG_DEBUG, "running pre-transaction scripts\n");
	runTransScripts(ts, RPMTAG_PRETRANS);
    }

    /* ===============================================
     * Initialize transaction element file info for package:
     */

    /*
     * FIXME?: we'd be better off assembling one very large file list and
     * calling fpLookupList only once. I'm not sure that the speedup is
     * worth the trouble though.
     */
    rpmlog(RPMLOG_DEBUG, "computing %d file fingerprints\n", totalFileCount);

    numAdded = numRemoved = 0;
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	int fc;

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	switch (rpmteType(p)) {
	case TR_ADDED:
	    numAdded++;
	    /* Skip netshared paths, not our i18n files, and excluded docs */
	    if (fc > 0)
		skipFiles(ts, p);
	    break;
	case TR_REMOVED:
	    numRemoved++;
	    break;
	}
    }
    pi = rpmtsiFree(pi);

    if (!rpmtsChrootDone(ts)) {
	const char * rootDir = rpmtsRootDir(ts);
	xx = chdir("/");
	if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/') {
	    /* opening db before chroot not optimal, see rhbz#103852 c#3 */
	    xx = rpmdbOpenAll(ts->rdb);
	    if (chroot(rootDir) == -1) {
		rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
		return -1;
	    }
	}
	(void) rpmtsSetChrootDone(ts, 1);
    }

    ts->ht = rpmFpHashCreate(totalFileCount/2+1, fpHashFunction, fpEqual,
			     NULL, NULL);
    rpmFpHash symlinks = rpmFpHashCreate(totalFileCount/16+16, fpHashFunction, fpEqual, NULL, NULL);
    fpc = fpCacheCreate(totalFileCount/2 + 10001);

    /* ===============================================
     * Add fingerprint for each file not skipped.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	int fc;

	(void) rpmdbCheckSignals();

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fc = rpmfiFC(fi);

	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
	rpmfiFpLookup(fi, fpc);
	/* collect symbolic links */
 	fi = rpmfiInit(fi, 0);
 	if (fi != NULL)		/* XXX lclint */
	while ((i = rpmfiNext(fi)) >= 0) {
	    struct rpmffi_s ffi;
	    char const *linktarget;
	    linktarget = rpmfiFLink(fi);
	    if (!(linktarget && *linktarget != '\0'))
		continue;
	    if (XFA_SKIPPING(rpmfsGetAction(rpmteGetFileStates(p), i)))
		continue;
	    ffi.p = p;
	    ffi.fileno = i;
	    rpmFpHashAddEntry(symlinks, rpmfiFpsIndex(fi, i), ffi);
	}
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), fc);

    }
    pi = rpmtsiFree(pi);

    /* ===============================================
     * Check fingerprints if they contain symlinks
     * and add them to the ts->ht hash table
     */

    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	(void) rpmdbCheckSignals();

	if ((fi = rpmteFI(p)) == NULL)
	    continue;	/* XXX can't happen */
	fi = rpmfiInit(fi, 0);
	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
	if (fi != NULL)		/* XXX lclint */
	while ((i = rpmfiNext(fi)) >= 0) {
	    if (XFA_SKIPPING(rpmfsGetAction(rpmteGetFileStates(p), i)))
		continue;
	    fpLookupSubdir(symlinks, ts->ht, fpc, p, i);
	}
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
    }
    pi = rpmtsiFree(pi);

    rpmFpHashFree(symlinks);

    /* ===============================================
     * Compute file disposition for each package in transaction set.
     */
    rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_START, 6, ts->orderCount);

    /* check against files in the rpmdb */
    checkInstalledFiles(ts, fpc);

    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {

	if ((fi = rpmteFI(p)) == NULL)
	    continue;   /* XXX can't happen */

	(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
	/* check files in ts against each other and update disk space
	   needs on each partition for this package. */
	handleOverlappedFiles(ts, p, fi);

	/* Check added package has sufficient space on each partition used. */
	if (rpmteType(p) == TR_ADDED) {
	    rpmtsCheckDSIProblems(ts, p);
	}
	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
    }
    pi = rpmtsiFree(pi);

    if (rpmtsChrootDone(ts)) {
	const char * rootDir = rpmtsRootDir(ts);
	const char * currDir = rpmtsCurrDir(ts);
	if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
	    xx = chroot(".");
	(void) rpmtsSetChrootDone(ts, 0);
	if (currDir != NULL)
	    xx = chdir(currDir);
    }

    rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_STOP, 6, ts->orderCount);

    /* ===============================================
     * Free unused memory as soon as possible.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, 0)) != NULL) {
	rpmteSetFI(p, NULL);
    }
    pi = rpmtsiFree(pi);

    fpc = fpCacheFree(fpc);
    ts->ht = rpmFpHashFree(ts->ht);

    /* ===============================================
     * If unfiltered problems exist, free memory and return.
     */
    if ((rpmtsFlags(ts) & RPMTRANS_FLAG_BUILD_PROBS)
     || (rpmpsNumProblems(ts->probs) &&
		(okProbs == NULL || rpmpsTrim(ts->probs, okProbs)))
       )
    {
	rpmtsFreeLock(lock);
	return ts->orderCount;
    }

    /* Actually install and remove packages */
    rc = rpmtsProcess(ts);

    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_NOPOST))) {
	rpmlog(RPMLOG_DEBUG, "running post-transaction scripts\n");
	runTransScripts(ts, RPMTAG_POSTTRANS);
    }

    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_NOCONTEXTS)) {
	matchpathcon_fini();
    }

    rpmtsFreeLock(lock);

    /* FIX: ts->flList may be NULL */
    if (rc)
    	return -1;
    else
	return 0;
}
Ejemplo n.º 15
0
int rpmtsCheck(rpmts ts)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    rpmtsi pi = NULL; rpmte p;
    int closeatexit = 0;
    int rc = 0;
    depCache dcache = NULL;
    filedepHash confilehash = NULL;	/* file conflicts of installed packages */
    filedepHash connotfilehash = NULL;	/* file conflicts of installed packages */
    depexistsHash connothash = NULL;
    filedepHash reqfilehash = NULL;	/* file requires of installed packages */
    filedepHash reqnotfilehash = NULL;	/* file requires of installed packages */
    depexistsHash reqnothash = NULL;
    fingerPrintCache fpc = NULL;
    rpmdb rdb = NULL;
    
    (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    /* Do lazy, readonly, open of rpm database. */
    rdb = rpmtsGetRdb(ts);
    if (rdb == NULL && rpmtsGetDBMode(ts) != -1) {
	if ((rc = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0)
	    goto exit;
	rdb = rpmtsGetRdb(ts);
	closeatexit = 1;
    }

    if (rdb)
	rpmdbCtrl(rdb, RPMDB_CTRL_LOCK_RO);

    /* XXX FIXME: figure some kind of heuristic for the cache size */
    dcache = depCacheCreate(5001, rstrhash, strcmp,
				     (depCacheFreeKey)rfree, NULL);

    /* build hashes of all confilict sdependencies */
    confilehash = filedepHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    connothash = depexistsHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree);
    connotfilehash = filedepHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    addIndexToDepHashes(ts, RPMTAG_CONFLICTNAME, NULL, confilehash, connothash, connotfilehash);
    if (!filedepHashNumKeys(confilehash))
	confilehash = filedepHashFree(confilehash);
    if (!depexistsHashNumKeys(connothash))
	connothash= depexistsHashFree(connothash);
    if (!filedepHashNumKeys(connotfilehash))
	connotfilehash = filedepHashFree(connotfilehash);

    /* build hashes of all requires dependencies */
    reqfilehash = filedepHashCreate(8191, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    reqnothash = depexistsHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree);
    reqnotfilehash = filedepHashCreate(257, rstrhash, strcmp,
				    (filedepHashFreeKey)rfree,
				    (filedepHashFreeData)rfree);
    addIndexToDepHashes(ts, RPMTAG_REQUIRENAME, NULL, reqfilehash, reqnothash, reqnotfilehash);
    if (!filedepHashNumKeys(reqfilehash))
	reqfilehash = filedepHashFree(reqfilehash);
    if (!depexistsHashNumKeys(reqnothash))
	reqnothash= depexistsHashFree(reqnothash);
    if (!filedepHashNumKeys(reqnotfilehash))
	reqnotfilehash = filedepHashFree(reqnotfilehash);

    /*
     * Look at all of the added packages and make sure their dependencies
     * are satisfied.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));

	rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_REQUIRENAME),
		tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_CONFLICTNAME),
		tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_OBSOLETENAME),
		tscolor);

	/* Check provides against conflicts in installed packages. */
	while (rpmdsNext(provides) >= 0) {
	    const char *dep = rpmdsN(provides);
	    checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, dep);
	    if (reqnothash && depexistsHashHasEntry(reqnothash, dep))
		checkNotInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, dep);
	}

	/* Skip obsoletion checks for source packages (ie build) */
	if (rpmteIsSource(p))
	    continue;

	/* Check package name (not provides!) against installed obsoletes */
	checkInstDeps(ts, dcache, p, RPMTAG_OBSOLETENAME, rpmteN(p));

	/* Check filenames against installed conflicts */
        if (confilehash || reqnotfilehash) {
	    rpmfiles files = rpmteFiles(p);
	    rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);
	    while (rpmfiNext(fi) >= 0) {
		if (confilehash)
		    checkInstFileDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fi, 0, confilehash, &fpc);
		if (reqnotfilehash)
		    checkInstFileDeps(ts, dcache, p, RPMTAG_REQUIRENAME, fi, 1, reqnotfilehash, &fpc);
	    }
	    rpmfiFree(fi);
	    rpmfilesFree(files);
	}
    }
    rpmtsiFree(pi);

    /*
     * Look at the removed packages and make sure they aren't critical.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));

	rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	/* Check provides and filenames against installed dependencies. */
	while (rpmdsNext(provides) >= 0) {
	    const char *dep = rpmdsN(provides);
	    checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, dep);
	    if (connothash && depexistsHashHasEntry(connothash, dep))
		checkNotInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, dep);
	}

	if (reqfilehash || connotfilehash) {
	    rpmfiles files = rpmteFiles(p);
	    rpmfi fi = rpmfilesIter(files, RPMFI_ITER_FWD);;
	    while (rpmfiNext(fi) >= 0) {
		if (RPMFILE_IS_INSTALLED(rpmfiFState(fi))) {
		    if (reqfilehash)
			checkInstFileDeps(ts, dcache, p, RPMTAG_REQUIRENAME, fi, 0, reqfilehash, &fpc);
		    if (connotfilehash)
			checkInstFileDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fi, 1, connotfilehash, &fpc);
		}
	    }
	    rpmfiFree(fi);
	    rpmfilesFree(files);
	}
    }
    rpmtsiFree(pi);

    if (rdb)
	rpmdbCtrl(rdb, RPMDB_CTRL_UNLOCK_RO);

exit:
    depCacheFree(dcache);
    filedepHashFree(confilehash);
    filedepHashFree(connotfilehash);
    depexistsHashFree(connothash);
    filedepHashFree(reqfilehash);
    filedepHashFree(reqnotfilehash);
    depexistsHashFree(reqnothash);
    fpCacheFree(fpc);

    (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    if (closeatexit)
	(void) rpmtsCloseDB(ts);
    return rc;
}
Ejemplo n.º 16
0
static int addPackage(rpmts ts, Header h,
		    fnpyKey key, int op, rpmRelocation * relocs)
{
    tsMembers tsmem = rpmtsMembers(ts);
    rpm_color_t tscolor = rpmtsColor(ts);
    rpmte p = NULL;
    int isSource = headerIsSource(h);
    int ec = 0;
    int oc = tsmem->orderCount;

    /* Check for supported payload format if it's a package */
    if (key && headerCheckPayloadFormat(h) != RPMRC_OK) {
	ec = 1;
	goto exit;
    }

    /* Source packages are never "upgraded" */
    if (isSource)
	op = RPMTE_INSTALL;

    /* Do lazy (readonly?) open of rpm database for upgrades. */
    if (op != RPMTE_INSTALL && rpmtsGetRdb(ts) == NULL && rpmtsGetDBMode(ts) != -1) {
	if ((ec = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0)
	    goto exit;
    }

    p = rpmteNew(ts, h, TR_ADDED, key, relocs);
    if (p == NULL) {
	ec = 1;
	goto exit;
    }

    /* Check binary packages for redundancies in the set */
    if (!isSource) {
	oc = findPos(ts, tscolor, p, (op == RPMTE_UPGRADE));
	/* If we're replacing a previously added element, free the old one */
	if (oc >= 0 && oc < tsmem->orderCount) {
	    rpmalDel(tsmem->addedPackages, tsmem->order[oc]);
	    tsmem->order[oc] = rpmteFree(tsmem->order[oc]);
	/* If newer NEVR was already added, we're done */
	} else if (oc < 0) {
	    p = rpmteFree(p);
	    goto exit;
	}
    }

    if (oc >= tsmem->orderAlloced) {
	tsmem->orderAlloced += (oc - tsmem->orderAlloced) + tsmem->delta;
	tsmem->order = xrealloc(tsmem->order,
			tsmem->orderAlloced * sizeof(*tsmem->order));
    }


    tsmem->order[oc] = p;
    if (oc == tsmem->orderCount) {
	tsmem->orderCount++;
    }
    
    if (tsmem->addedPackages == NULL) {
	tsmem->addedPackages = rpmalCreate(rpmtsPool(ts), 5, rpmtsFlags(ts),
					   tscolor, rpmtsPrefColor(ts));
    }
    rpmalAdd(tsmem->addedPackages, p);

    /* Add erasure elements for old versions and obsoletions on upgrades */
    /* XXX TODO: If either of these fails, we'd need to undo all additions */
    if (op != RPMTE_INSTALL)
	addSelfErasures(ts, tscolor, op, p, rpmteColor(p), h);
    if (op == RPMTE_UPGRADE)
	addObsoleteErasures(ts, tscolor, p);

exit:
    return ec;
}
Ejemplo n.º 17
0
int rpmtsCheck(rpmts ts)
{
    rpm_color_t tscolor = rpmtsColor(ts);
    rpmtsi pi = NULL; rpmte p;
    int closeatexit = 0;
    int rc = 0;
    depCache dcache = NULL;
    conflictsCache confcache = NULL;
    
    (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    /* Do lazy, readonly, open of rpm database. */
    if (rpmtsGetRdb(ts) == NULL && rpmtsGetDBMode(ts) != -1) {
	if ((rc = rpmtsOpenDB(ts, rpmtsGetDBMode(ts))) != 0)
	    goto exit;
	closeatexit = 1;
    }

    /* XXX FIXME: figure some kind of heuristic for the cache size */
    dcache = depCacheCreate(5001, rstrhash, strcmp,
				     (depCacheFreeKey)rfree, NULL);

    confcache = conflictsCacheCreate(257, rstrhash, strcmp,
				     (depCacheFreeKey)rfree);
    if (confcache) {
	rpmdbIndexIterator ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMTAG_CONFLICTNAME);
	if (ii) {
	    char *key;
	    size_t keylen;
	    while ((rpmdbIndexIteratorNext(ii, (const void**)&key, &keylen)) == 0) {
		char *k;
		if (!key || keylen == 0 || key[0] != '/')
		    continue;
		k = rmalloc(keylen + 1);
		memcpy(k, key, keylen);
		k[keylen] = 0;
		conflictsCacheAddEntry(confcache, k);
	    }
	    rpmdbIndexIteratorFree(ii);
	}
    }

    
    /*
     * Look at all of the added packages and make sure their dependencies
     * are satisfied.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));

	rpmlog(RPMLOG_DEBUG, "========== +++ %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_REQUIRENAME),
		NULL, tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_CONFLICTNAME),
		NULL, tscolor);
	checkDS(ts, dcache, p, rpmteNEVRA(p), rpmteDS(p, RPMTAG_OBSOLETENAME),
		NULL, tscolor);

	/* Check provides against conflicts in installed packages. */
	while (rpmdsNext(provides) >= 0) {
	    checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, rpmdsN(provides));
	}

	/* Skip obsoletion checks for source packages (ie build) */
	if (rpmteIsSource(p))
	    continue;

	/* Check package name (not provides!) against installed obsoletes */
	checkInstDeps(ts, dcache, p, RPMTAG_OBSOLETENAME, rpmteN(p));

	/* Check filenames against installed conflicts */
        if (conflictsCacheNumKeys(confcache)) {
	    rpmfi fi = rpmfiInit(rpmteFI(p), 0);
	    while (rpmfiNext(fi) >= 0) {
		const char *fn = rpmfiFN(fi);
		if (!conflictsCacheHasEntry(confcache, fn))
		    continue;
		checkInstDeps(ts, dcache, p, RPMTAG_CONFLICTNAME, fn);
	    }
	}
    }
    rpmtsiFree(pi);

    /*
     * Look at the removed packages and make sure they aren't critical.
     */
    pi = rpmtsiInit(ts);
    while ((p = rpmtsiNext(pi, TR_REMOVED)) != NULL) {
	rpmds provides = rpmdsInit(rpmteDS(p, RPMTAG_PROVIDENAME));
	rpmfi fi = rpmfiInit(rpmteFI(p), 0);

	rpmlog(RPMLOG_DEBUG, "========== --- %s %s/%s 0x%x\n",
		rpmteNEVR(p), rpmteA(p), rpmteO(p), rpmteColor(p));

	/* Check provides and filenames against installed dependencies. */
	while (rpmdsNext(provides) >= 0) {
	    checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, rpmdsN(provides));
	}

	while (rpmfiNext(fi) >= 0) {
	    if (RPMFILE_IS_INSTALLED(rpmfiFState(fi)))
		checkInstDeps(ts, dcache, p, RPMTAG_REQUIRENAME, rpmfiFN(fi));
	}
    }
    rpmtsiFree(pi);

exit:
    depCacheFree(dcache);
    conflictsCacheFree(confcache);

    (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_CHECK), 0);

    if (closeatexit)
	(void) rpmtsCloseDB(ts);
    return rc;
}
Ejemplo n.º 18
0
/* keyp might no be defined. */
rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmDbiTagVal rpmtag,
			const void * keyp, size_t keylen)
{
    rpmdbMatchIterator mi = NULL;
    char *tmp = NULL;

    if (ts == NULL)
	return NULL;

    if (ts && ts->keyring == NULL)
	loadKeyring(ts);

    if (ts->rdb == NULL && rpmtsOpenDB(ts, ts->dbmode))
	return NULL;

    /* Parse out "N(EVR)" tokens from a label key if present */
    if (rpmtag == RPMDBI_LABEL && keyp != NULL && strchr(keyp, '(')) {
	const char *se, *s = keyp;
	char *t;
	size_t slen = strlen(s);
	int level = 0;
	int c;

	tmp = xmalloc(slen+1);
	keyp = t = tmp;
	while ((c = *s++) != '\0') {
	    switch (c) {
	    default:
		*t++ = c;
		break;
	    case '(':
		/* XXX Fail if nested parens. */
		if (level++ != 0) {
		    rpmlog(RPMLOG_ERR, _("extra '(' in package label: %s\n"), (const char*)keyp);
		    goto exit;
		}
		/* Parse explicit epoch. */
		for (se = s; *se && risdigit(*se); se++)
		    {};
		if (*se == ':') {
		    /* XXX skip explicit epoch's (for now) */
		    *t++ = '-';
		    s = se + 1;
		} else {
		    /* No Epoch: found. Convert '(' to '-' and chug. */
		    *t++ = '-';
		}
		break;
	    case ')':
		/* XXX Fail if nested parens. */
		if (--level != 0) {
		    rpmlog(RPMLOG_ERR, _("missing '(' in package label: %s\n"), (const char*)keyp);
		    goto exit;
		}
		/* Don't copy trailing ')' */
		break;
	    }
	}
	if (level) {
	    rpmlog(RPMLOG_ERR, _("missing ')' in package label: %s\n"), (const char*)keyp);
	    goto exit;
	}
	*t = '\0';
    }

    mi = rpmdbInitIterator(ts->rdb, rpmtag, keyp, keylen);

    /* Verify header signature/digest during retrieve (if not disabled). */
    if (mi && !(ts->vsflags & RPMVSF_NOHDRCHK))
	(void) rpmdbSetHdrChk(mi, ts, headerCheck);

exit:
    free(tmp);

    return mi;
}
Ejemplo n.º 19
0
int loadTs(rpmts **ts, int *tsct, const char *dblistfn)
{
    int count = 0;
    int sz = 5;
    int rc = 0;
    int listfile = 1;
    struct stat st_buf;

    rc = stat(dblistfn, &st_buf);
    if(rc != 0) {
        perror("stat");
        return 1;
    }
    if(S_ISDIR(st_buf.st_mode))
        listfile = 0;

    if(listfile) {
        if(debugmode)
            printf("DEBUG: reading database list file '%s'\n", dblistfn);
        *ts = malloc(sz * sizeof(rpmts));
        FILE *f = fopen(dblistfn, "r" );
        if(f) {
            char line[2048];
            while(fgets(line, sizeof(line), f)) {
                int len = strlen(line) - 1;
                if(len > 0)
                    // Trim trailing whitespace
                    while(len > 0 && isspace(line[len]))
                        line[len--] = '\0';

                if(len > 0) {
                    // Expand array if needed
                    if(count == sz) {
                        sz += 5;
                        *ts = (rpmts *)realloc(*ts, sz);
                    }

                    if(debugmode)
                        printf("DEBUG: opening database '%s'\n", line);
                    char *dbpathm = malloc(strlen(line) + 10);
                    sprintf(dbpathm, "_dbpath %s", line);
                    rpmDefineMacro(NULL, dbpathm, RMIL_CMDLINE);
                    free(dbpathm);

                    rpmts tsi = rpmtsCreate();
                    (*ts)[count] = tsi;
                    rc = rpmtsOpenDB(tsi, O_RDONLY);
                    if( rc ) {
                        fprintf(stderr, "Failed to open database %s\n", line);
                        rc = -1;
                        break;
                    }

                    count++;
                }
            }
            fclose(f);
            *tsct = count;
        }
        else {
            perror(dblistfn);
            rc = -1;
        }
    }
    else {
        if(debugmode)
            printf("DEBUG: opening database '%s'\n", dblistfn);
        // Load from single database
        *ts = malloc(sizeof(rpmts));
        char *dbpathm = malloc(strlen(dblistfn) + 10);
        sprintf(dbpathm, "_dbpath %s", dblistfn);
        rpmDefineMacro(NULL, dbpathm, RMIL_CMDLINE);
        free(dbpathm);

        rpmts tsi = rpmtsCreate();
        (*ts)[0] = tsi;
        rc = rpmtsOpenDB(tsi, O_RDONLY);
        if( rc ) {
            fprintf(stderr, "Failed to open database %s\n", dblistfn);
            rc = -1;
        }
        *tsct = 1;
    }

    return rc;
}
Ejemplo n.º 20
0
static void integrity_check(const char *progname, enum modes progmode_num)
{
    rpmts ts = NULL;
    rpmlua lua = NULL;
    char *spec_fn = NULL;
    char *proc_fn = NULL;
    char *pkey_fn = NULL;
    char *spec = NULL;
    char *proc = NULL;
    rpmiob spec_iob = NULL;
    rpmiob proc_iob = NULL;
    const char *result = NULL;
    const char *error = NULL;
    int xx;
    const char *progmode;
    int rc = INTEGRITY_ERROR;

    /* determine paths of integrity checking related files */
    spec_fn = rpmExpand("%{?_integrity_spec_cfg}%{!?_integrity_spec_cfg:scripts/integrity.cfg}", NULL);
    if (spec_fn == NULL || spec_fn[0] == '\0') {
        integrity_check_message("ERROR: Integrity Configuration Specification file not configured.\n"
            "rpm: HINT: macro %%{_integrity_spec_cfg} not configured correctly.\n");
        goto failure;
    }
    proc_fn = rpmExpand("%{?_integrity_proc_lua}%{!?_integrity_proc_lua:scripts/integrity.lua}", NULL);
    if (proc_fn == NULL || proc_fn[0] == '\0') {
        integrity_check_message("ERROR: Integrity Validation Processor file not configured.\n"
            "rpm: HINT: macro %%{_integrity_proc_lua} not configured correctly.\n");
        goto failure;
    }
    pkey_fn = rpmExpand("%{?_integrity_pkey_pgp}%{!?_integrity_pkey_pgp:scripts/integrity.pgp}", NULL);
    if (pkey_fn == NULL || pkey_fn[0] == '\0') {
        integrity_check_message("ERROR: Integrity Autority Public-Key file not configured.\n"
            "rpm: HINT: macro %%{_integrity_pkey_pgp} not configured correctly.\n");
        goto failure;
    }

    /* create RPM transaction environment and open RPM database */
    ts = rpmtsCreate();
    (void)rpmtsOpenDB(ts, O_RDONLY);

    /* check signature on integrity configuration specification file */
    if (rpmnsProbeSignature(ts, spec_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) {
        integrity_check_message("ERROR: Integrity Configuration Specification file contains invalid signature.\n"
            "rpm: HINT: Check file \"%s\".\n", spec_fn);
        goto failure;
    }

    /* check signature on integrity validation processor file */
    if (rpmnsProbeSignature(ts, proc_fn, NULL, pkey_fn, RPM_INTEGRITY_FP, 0) != RPMRC_OK) {
        integrity_check_message("ERROR: Integrity Validation Processor file contains invalid signature.\n"
            "rpm: HINT: Check file \"%s\".\n", proc_fn);
        goto failure;
    }

    /* load integrity configuration specification file */
    xx = rpmiobSlurp(spec_fn, &spec_iob);
    if (!(xx == 0 && spec_iob != NULL)) {
        integrity_check_message("ERROR: Unable to load Integrity Configuration Specification file.\n"
            "rpm: HINT: Check file \"%s\".\n", spec_fn);
        goto failure;
    }
    spec = rpmiobStr(spec_iob);

    /* load integrity validation processor file */
    xx = rpmiobSlurp(proc_fn, &proc_iob);
    if (!(xx == 0 && proc_iob != NULL)) {
        integrity_check_message("ERROR: Unable to load Integrity Validation Processor file.\n"
            "rpm: HINT: Check file \"%s\".\n", proc_fn);
        goto failure;
    }
    proc = rpmiobStr(proc_iob);

    /* provision program name and mode */
    if (progname == NULL || progname[0] == '\0')
        progname = "rpm";
    switch (progmode_num) {
        case MODE_QUERY:     progmode = "query";     break;
        case MODE_VERIFY:    progmode = "verify";    break;
        case MODE_CHECKSIG:  progmode = "checksig";  break;
        case MODE_RESIGN:    progmode = "resign";    break;
        case MODE_INSTALL:   progmode = "install";   break;
        case MODE_ERASE:     progmode = "erase";     break;
        case MODE_BUILD:     progmode = "build";     break;
        case MODE_REBUILD:   progmode = "rebuild";   break;
        case MODE_RECOMPILE: progmode = "recompile"; break;
        case MODE_TARBUILD:  progmode = "tarbuild";  break;
        case MODE_REBUILDDB: progmode = "rebuilddb"; break;
        case MODE_UNKNOWN:   progmode = "unknown";   break;
        default:             progmode = "unknown";   break;
    }

    /* execute Integrity Validation Processor via Lua glue code */
    lua = rpmluaNew();
    rpmluaSetPrintBuffer(lua, 1);
    rpmluaextActivate(lua);
    lua_getfield(lua->L, LUA_GLOBALSINDEX, "integrity");
    lua_getfield(lua->L, -1, "processor");
    lua_remove(lua->L, -2);
    lua_pushstring(lua->L, progname);
    lua_pushstring(lua->L, progmode);
    lua_pushstring(lua->L, spec_fn);
    lua_pushstring(lua->L, spec);
    lua_pushstring(lua->L, proc_fn);
    lua_pushstring(lua->L, proc);
#ifdef RPM_INTEGRITY_MV
    lua_pushstring(lua->L, RPM_INTEGRITY_MV);
#else
    lua_pushstring(lua->L, "0");
#endif
    if (lua_pcall(lua->L, 7, 1, 0) != 0) {
        error = lua_isstring(lua->L, -1) ? lua_tostring(lua->L, -1) : "unknown error";
        lua_pop(lua->L, 1);
        integrity_check_message("ERROR: Failed to execute Integrity Validation Processor.\n"
            "rpm: ERROR: Lua: %s.\n"
            "rpm: HINT: Check file \"%s\".\n", error, proc_fn);
        goto failure;
    }

    /* check Integrity Validation Processor results */
    if (!lua_isstring(lua->L, -1)) {
        integrity_check_message("ERROR: Failed to fetch Integrity Validation Processor results.\n"
            "rpm: HINT: Check file \"%s\".\n", proc_fn);
        goto failure;
    }
    result = lua_tostring(lua->L, -1);
    if (strcmp(result, "OK") == 0)
        rc = INTEGRITY_OK;
    else if (strncmp(result, "WARNING:", 8) == 0) {
        rc = INTEGRITY_WARNING;
        integrity_check_message("%s\n", result);
    }
    else {
        rc = INTEGRITY_ERROR;
        integrity_check_message("%s\n", result);
    }

    /* cleanup processing */
    failure:
    if (lua != NULL)
	rpmluaFree(lua);
    if (ts != NULL)
	(void)rpmtsFree(ts);
    ts = NULL;
    if (spec_iob != NULL)
	spec_iob = rpmiobFree(spec_iob);
    if (proc_iob != NULL)
	proc_iob = rpmiobFree(proc_iob);

    /* final result handling */
    if (rc != INTEGRITY_OK) {
        if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO))
            sleep(4);
        if (rc == INTEGRITY_ERROR)
            exit(42);
    }
    return;
}