Example #1
0
char * rpmfiFNIndex(rpmfi fi, int ix)
{
    char *fn = NULL;
    if (fi != NULL && ix >= 0 && ix < fi->fc) {
	fn = rstrscat(NULL, rpmstrPoolStr(fi->pool, fi->dnid[fi->dil[ix]]),
			    rpmstrPoolStr(fi->pool, fi->bnid[ix]), NULL);
    }
    return fn;
}
Example #2
0
static rpmte * rpmalAllFileSatisfiesDepend(const rpmal al, const char *fileName, const rpmds filterds)
{
    const char *slash; 
    rpmte * ret = NULL;

    if (al == NULL || fileName == NULL || *fileName != '/')
	return NULL;

    /* Split path into dirname and basename components for lookup */
    if ((slash = strrchr(fileName, '/')) != NULL) {
	availableIndexFileEntry result;
	int resultCnt = 0;
	size_t bnStart = (slash - fileName) + 1;
	rpmsid baseName;

	if (al->fileHash == NULL)
	    rpmalMakeFileIndex(al);

	baseName = rpmstrPoolId(al->pool, fileName + bnStart, 0);
	if (!baseName)
	    return NULL;	/* no match possible */

	rpmalFileHashGetEntry(al->fileHash, baseName, &result, &resultCnt, NULL);

	if (resultCnt > 0) {
	    int i, found;
	    ret = xmalloc((resultCnt+1) * sizeof(*ret));
	    fingerPrint * fp = NULL;
	    rpmsid dirName = rpmstrPoolIdn(al->pool, fileName, bnStart, 1);

	    if (!al->fpc)
		al->fpc = fpCacheCreate(1001, NULL);
	    fpLookup(al->fpc, rpmstrPoolStr(al->pool, dirName), fileName + bnStart, &fp);

	    for (found = i = 0; i < resultCnt; i++) {
		availablePackage alp = al->list + result[i].pkgNum;
		if (alp->p == NULL) /* deleted */
		    continue;
		/* ignore self-conflicts/obsoletes */
		if (filterds && rpmteDS(alp->p, rpmdsTagN(filterds)) == filterds)
		    continue;
		if (result[i].dirName != dirName &&
		    !fpLookupEquals(al->fpc, fp, rpmstrPoolStr(al->pool, result[i].dirName), fileName + bnStart))
		    continue;

		ret[found] = alp->p;
		found++;
	    }
	    _free(fp);
	    ret[found] = NULL;
	}
    }

    return ret;
}
Example #3
0
const char * rpmdsEVRIndex(rpmds ds, int i)
{
    const char * EVR = NULL;
    if (ds != NULL && i >= 0 && i < ds->Count && ds->EVR != NULL)
	EVR = rpmstrPoolStr(ds->pool, ds->EVR[i]);
    return EVR;
}
Example #4
0
const char * fpEntryDir(fingerPrintCache cache, fingerPrint *fp)
{
    const char * dn = NULL;
    if (fp && fp->entry)
	dn = rpmstrPoolStr(cache->pool, fp->entry->dirId);
    return dn;
}
Example #5
0
const char * rpmdsNIndex(rpmds ds, int i)
{
    const char * N = NULL;
    if (ds != NULL && i >= 0 && i < ds->Count && ds->N != NULL)
	N = rpmstrPoolStr(ds->pool, ds->N[i]);
    return N;
}
Example #6
0
static int doLookupId(fingerPrintCache cache,
	     rpmsid dirNameId, rpmsid baseNameId,
	     fingerPrint *fp)
{
    struct stat sb;
    const struct fprintCacheEntry_s * cacheHit;
    char *cdn = canonDir(cache->pool, dirNameId);
    rpmsid fpId;
    size_t fpLen;
    
    if (cdn == NULL) goto exit; /* XXX only if realpath() above fails */

    memset(fp, 0, sizeof(*fp));
    fpId = rpmstrPoolId(cache->pool, cdn, 1);
    fpLen = rpmstrPoolStrlen(cache->pool, fpId);;

    while (1) {
	/* as we're stating paths here, we want to follow symlinks */
	cacheHit = cacheContainsDirectory(cache, fpId);
	if (cacheHit != NULL) {
	    fp->entry = cacheHit;
	} else if (!stat(rpmstrPoolStr(cache->pool, fpId), &sb)) {
	    struct fprintCacheEntry_s * newEntry = xmalloc(sizeof(* newEntry));

	    newEntry->ino = sb.st_ino;
	    newEntry->dev = sb.st_dev;
	    newEntry->dirId = fpId;
	    fp->entry = newEntry;

	    rpmFpEntryHashAddEntry(cache->ht, fpId, fp->entry);
	}

        if (fp->entry) {
	    const char * subDir = cdn + fpLen - 1;
	    /* XXX don't bother saving '/' as subdir */
	    if (subDir[0] == '\0' || (subDir[0] == '/' && subDir[1] == '\0'))
		subDir = NULL;
	    fp->baseNameId = baseNameId;
	    if (subDir != NULL)
		fp->subDirId = rpmstrPoolId(cache->pool, subDir, 1);
	    goto exit;
	}

        /* stat of '/' just failed! */
	if (fpLen == 1)
	    abort();

	/* Find the parent directory and its id for the next round */
	fpLen--;
	while (fpLen > 1 && cdn[fpLen-1] != '/')
	    fpLen--;
	fpId = rpmstrPoolIdn(cache->pool, cdn, fpLen, 1);
    }

exit:
    free(cdn);
    /* XXX TODO: failure from eg realpath() should be returned and handled */
    return 0;
}
Example #7
0
const char * rpmfiFLangsIndex(rpmfi fi, int ix)
{
    const char *flangs = NULL;
    if (fi != NULL && fi->flangs != NULL && ix >= 0 && ix < fi->fc) {
	flangs = rpmstrPoolStr(fi->pool, fi->flangs[ix]);
    }
    return flangs;
}
Example #8
0
const char * rpmfiBNIndex(rpmfi fi, int ix)
{
    const char * BN = NULL;

    if (fi != NULL && ix >= 0 && ix < fi->fc) {
	if (fi->bnid != NULL)
	    BN = rpmstrPoolStr(fi->pool, fi->bnid[ix]);
    }
    return BN;
}
Example #9
0
const char * rpmfiFLinkIndex(rpmfi fi, int ix)
{
    const char * flink = NULL;

    if (fi != NULL && ix >= 0 && ix < fi->fc) {
	if (fi->flinks != NULL)
	    flink = rpmstrPoolStr(fi->pool, fi->flinks[ix]);
    }
    return flink;
}
Example #10
0
const char * rpmfiDNIndex(rpmfi fi, int jx)
{
    const char * DN = NULL;

    if (fi != NULL && jx >= 0 && jx < fi->dc) {
	if (fi->dnid != NULL)
	    DN = rpmstrPoolStr(fi->pool, fi->dnid[jx]);
    }
    return DN;
}
Example #11
0
const char * rpmfiFUserIndex(rpmfi fi, int ix)
{
    const char * fuser = NULL;

    if (fi != NULL && ix >= 0 && ix < fi->fc) {
	if (fi->fuser != NULL)
	    fuser = rpmstrPoolStr(fi->pool, fi->fuser[ix]);
    }
    return fuser;
}
Example #12
0
const char * rpmfiFGroupIndex(rpmfi fi, int ix)
{
    const char * fgroup = NULL;

    if (fi != NULL && ix >= 0 && ix < fi->fc) {
	if (fi->fgroup != NULL)
	    fgroup = rpmstrPoolStr(fi->pool, fi->fgroup[ix]);
    }
    return fgroup;
}
Example #13
0
/* Get a rpmdbMatchIterator containing all files in
 * the rpmdb that share the basename with one from
 * the transaction.
 * @param ts		transaction set
 * @return		rpmdbMatchIterator sorted
			by (package, fileNum)
 */
static
rpmdbMatchIterator rpmFindBaseNamesInDB(rpmts ts, uint64_t fileCount)
{
    tsMembers tsmem = rpmtsMembers(ts);
    rpmstrPool tspool = rpmtsPool(ts);
    rpmtsi pi;  rpmte p;
    rpmfiles files;
    rpmfi fi;
    rpmdbMatchIterator mi;
    int oc = 0;
    const char * baseName;
    rpmsid baseNameId;

    rpmStringSet baseNames = rpmStringSetCreate(fileCount, 
					sidHash, sidCmp, NULL);

    mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_BASENAMES);

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

	rpmtsNotify(ts, NULL, RPMCALLBACK_TRANS_PROGRESS, oc++, tsmem->orderCount);

	/* Gather all installed headers with matching basename's. */
	files = rpmteFiles(p);
	fi = rpmfilesIter(files, RPMFI_ITER_FWD);
	while (rpmfiNext(fi) >= 0) {
	    size_t keylen;

	    baseNameId = rpmfiBNId(fi);

	    if (rpmStringSetHasEntry(baseNames, baseNameId))
		continue;

	    keylen = rpmstrPoolStrlen(tspool, baseNameId);
	    baseName = rpmstrPoolStr(tspool, baseNameId);
	    if (keylen == 0)
		keylen++;	/* XXX "/" fixup. */
	    rpmdbExtendIterator(mi, baseName, keylen);
	    rpmStringSetAddEntry(baseNames, baseNameId);
	}
	rpmfiFree(fi);
	rpmfilesFree(files);
    }
    rpmtsiFree(pi);
    rpmStringSetFree(baseNames);

    rpmdbSortIterator(mi);
    /* iterator is now sorted by (recnum, filenum) */
    return mi;
}
Example #14
0
static char * canonDir(rpmstrPool pool, rpmsid dirNameId)
{
    const char * dirName = rpmstrPoolStr(pool, dirNameId);
    size_t cdnl = rpmstrPoolStrlen(pool, dirNameId);;
    char *cdnbuf = NULL;

    if (*dirName == '/') {
	cdnbuf = xstrdup(dirName);
	cdnbuf = rpmCleanPath(cdnbuf);
	/* leave my trailing slashes along you b**** */
	if (cdnl > 1)
	    cdnbuf = rstrcat(&cdnbuf, "/");
    } else {
	/* Using realpath on the arg isn't correct if the arg is a symlink,
	 * especially if the symlink is a dangling link.  What we 
	 * do instead is use realpath() on `.' and then append arg to
	 * the result.
	 */

	/* if the current directory doesn't exist, we might fail. 
	   oh well. likewise if it's too long.  */

	/* XXX we should let realpath() allocate if it can */
	cdnbuf = xmalloc(PATH_MAX);
	cdnbuf[0] = '\0';
	if (realpath(".", cdnbuf) != NULL) {
	    char *end = cdnbuf + strlen(cdnbuf);
	    if (end[-1] != '/')	*end++ = '/';
	    end = stpncpy(end, dirName, PATH_MAX - (end - cdnbuf));
	    *end = '\0';
	    (void)rpmCleanPath(cdnbuf); /* XXX possible /../ from concatenation */
	    end = cdnbuf + strlen(cdnbuf);
	    if (end[-1] != '/')	*end++ = '/';
	    *end = '\0';
	} else {
	    cdnbuf = _free(cdnbuf);
	}
    }
    return cdnbuf;
}
Example #15
0
/* Check file for to be installed symlinks in their path and correct their fp */
static void fpLookupSubdir(rpmFpHash symlinks, fingerPrintCache fpc, rpmte p, int filenr)
{
    rpmfiles fi = rpmteFiles(p);
    struct fingerPrint_s current_fp;
    const char *currentsubdir;
    size_t lensubDir, bnStart, bnEnd;

    struct rpmffi_s * recs;
    int numRecs;
    int i;
    fingerPrint *fp = rpmfilesFps(fi) + filenr;
    int symlinkcount = 0;
    struct rpmffi_s ffi = { p, filenr};

    if (fp->subDirId == 0) {
	rpmFpHashAddEntry(fpc->fp, fp, ffi);
	goto exit;
    }

    currentsubdir = rpmstrPoolStr(fpc->pool, fp->subDirId);
    lensubDir = rpmstrPoolStrlen(fpc->pool, fp->subDirId);
    current_fp = *fp;

    /* Set baseName to the upper most dir */
    bnStart = bnEnd = 1;
    while (bnEnd < lensubDir && currentsubdir[bnEnd] != '/')
	bnEnd++;
    /* no subDir for now */
    current_fp.subDirId = 0;

    while (bnEnd < lensubDir) {
	char found = 0;

	current_fp.baseNameId = rpmstrPoolIdn(fpc->pool,
						currentsubdir + bnStart,
						bnEnd - bnStart, 1);

	rpmFpHashGetEntry(symlinks, &current_fp, &recs, &numRecs, NULL);

	for (i = 0; i < numRecs; i++) {
	    rpmfiles foundfi = rpmteFiles(recs[i].p);
	    char const *linktarget = rpmfilesFLink(foundfi, recs[i].fileno);
	    char *link;

	    /* Ignore already removed (by eg %pretrans) links */
	    if (linktarget && rpmteType(recs[i].p) == TR_REMOVED) {
		char *path = rpmfilesFN(foundfi, recs[i].fileno);
		struct stat sb;
		if (lstat(path, &sb) == -1)
		    linktarget = NULL;
		free(path);
	    }

	    foundfi = rpmfilesFree(foundfi);

	    if (linktarget && *linktarget != '\0') {
		const char *bn;
		/* this "directory" is a symlink */
		link = NULL;
		if (*linktarget != '/') {
		    const char *dn, *subDir = NULL;
		    dn = rpmstrPoolStr(fpc->pool, current_fp.entry->dirId);
		    if (current_fp.subDirId) {
			subDir = rpmstrPoolStr(fpc->pool, current_fp.subDirId);
		    }
		    rstrscat(&link, dn, subDir ? subDir : "", "/", NULL);
		}
		rstrscat(&link, linktarget, "/", NULL);
		if (strlen(currentsubdir + bnEnd)) {
		    rstrscat(&link, currentsubdir + bnEnd, NULL);
		}

		bn = rpmstrPoolStr(fpc->pool, fp->baseNameId);
		doLookup(fpc, link, bn, fp);

		free(link);
		symlinkcount++;

		/* setup current_fp for the new path */
		found = 1;
		current_fp = *fp;
		if (fp->subDirId == 0) {
		    /* directory exists - no need to look for symlinks */
		    rpmFpHashAddEntry(fpc->fp, fp, ffi);
		    goto exit;
		}
		currentsubdir = rpmstrPoolStr(fpc->pool, fp->subDirId);
		lensubDir = rpmstrPoolStrlen(fpc->pool, fp->subDirId);
		/* no subDir for now */
		current_fp.subDirId = 0;

		/* Set baseName to the upper most dir */
		bnStart = bnEnd = 1;
		while (bnEnd < lensubDir && currentsubdir[bnEnd] != '/')
		    bnEnd++;
		break;

	    }
	}
	if (symlinkcount > 50) {
	    // found too many symlinks in the path
	    // most likley a symlink cicle
	    // giving up
	    // TODO warning/error
	    break;
	}
	if (found) {
	    continue; // restart loop after symlink
	}

	/* Set former baseName as subDir */
	bnEnd++;
	current_fp.subDirId = rpmstrPoolIdn(fpc->pool, currentsubdir, bnEnd, 1);

	/* set baseName to the next lower dir */
	bnStart = bnEnd;
	while (bnEnd < lensubDir && currentsubdir[bnEnd] != '/')
	    bnEnd++;
    }
    rpmFpHashAddEntry(fpc->fp, fp, ffi);

exit:
    rpmfilesFree(fi);
}
Example #16
0
int parseFiles(rpmSpec spec)
{
    int nextPart, res = PART_ERROR;
    Package pkg;
    int rc, argc;
    int arg;
    const char ** argv = NULL;
    const char *name = NULL;
    int flag = PART_SUBNAME;
    poptContext optCon = NULL;
    struct poptOption optionsTable[] = {
	{ NULL, 'n', POPT_ARG_STRING, &name, 'n', NULL, NULL},
	{ NULL, 'f', POPT_ARG_STRING, NULL, 'f', NULL, NULL},
	{ 0, 0, 0, 0, 0, NULL, NULL}
    };

    /* XXX unmask %license while parsing %files */
    rpmPushMacro(spec->macros, "license", NULL, "%%license", RMIL_SPEC);

    if ((rc = poptParseArgvString(spec->line, &argc, &argv))) {
	rpmlog(RPMLOG_ERR, _("line %d: Error parsing %%files: %s\n"),
		 spec->lineNum, poptStrerror(rc));
	goto exit;
    }

    optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
    while ((arg = poptGetNextOpt(optCon)) > 0) {
	if (arg == 'n') {
	    flag = PART_NAME;
	}
    }

    if (arg < -1) {
	rpmlog(RPMLOG_ERR, _("line %d: Bad option %s: %s\n"),
		 spec->lineNum,
		 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
		 spec->line);
	goto exit;
    }

    if (poptPeekArg(optCon)) {
	if (name == NULL)
	    name = poptGetArg(optCon);
	if (poptPeekArg(optCon)) {
	    rpmlog(RPMLOG_ERR, _("line %d: Too many names: %s\n"),
		     spec->lineNum,
		     spec->line);
	    goto exit;
	}
    }

    if (lookupPackage(spec, name, flag, &pkg))
	goto exit;

    /*
     * This should be an error, but its surprisingly commonly abused for the
     * effect of multiple -f arguments in versions that dont support it.
     * Warn but preserve behavior, except for leaking memory.
     */
    if (pkg->fileList != NULL) {
	rpmlog(RPMLOG_WARNING, _("line %d: multiple %%files for package '%s'\n"),
	       spec->lineNum, rpmstrPoolStr(pkg->pool, pkg->name));
	pkg->fileList = argvFree(pkg->fileList);
    }

    for (arg=1; arg<argc; arg++) {
	if (rstreq(argv[arg], "-f") && argv[arg+1]) {
	    char *file = rpmGetPath(argv[arg+1], NULL);
	    argvAdd(&(pkg->fileFile), file);
	    free(file);
	}
    }

    pkg->fileList = argvNew();

    if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
	nextPart = PART_NONE;
    } else if (rc < 0) {
	goto exit;
    } else {
	while (! (nextPart = isPart(spec->line))) {
	    argvAdd(&(pkg->fileList), spec->line);
	    if ((rc = readLine(spec, STRIP_COMMENTS)) > 0) {
		nextPart = PART_NONE;
		break;
	    } else if (rc < 0) {
		goto exit;
	    }
	}
    }
    res = nextPart;

exit:
    rpmPopMacro(NULL, "license");
    free(argv);
    poptFreeContext(optCon);
	
    return res;
}
Example #17
0
rpmte * rpmalAllSatisfiesDepend(const rpmal al, const rpmds ds)
{
    rpmte * ret = NULL;
    int i, ix, found;
    rpmsid nameId;
    const char *name;
    availableIndexEntry result;
    int resultCnt;
    int obsolete;
    rpmTagVal dtag;
    rpmds filterds = NULL;

    availablePackage alp;
    int rc;

    if (al == NULL || ds == NULL || (nameId = rpmdsNId(ds)) == 0)
	return ret;

    dtag = rpmdsTagN(ds);
    obsolete = (dtag == RPMTAG_OBSOLETENAME);
    if (dtag == RPMTAG_OBSOLETENAME || dtag == RPMTAG_CONFLICTNAME)
	filterds = ds;
    name = rpmstrPoolStr(al->pool, nameId);
    if (!obsolete && *name == '/') {
	/* First, look for files "contained" in package ... */
	ret = rpmalAllFileSatisfiesDepend(al, name, filterds);
	if (ret != NULL && *ret != NULL) {
	    rpmdsNotify(ds, "(added files)", 0);
	    return ret;
	}
	/* ... then, look for files "provided" by package. */
	ret = _free(ret);
    }

    if (al->providesHash == NULL)
	rpmalMakeProvidesIndex(al);

    rpmalDepHashGetEntry(al->providesHash, nameId, &result,
			      &resultCnt, NULL);

    if (resultCnt==0) return NULL;

    ret = xmalloc((resultCnt+1) * sizeof(*ret));

    for (found=i=0; i<resultCnt; i++) {
	alp = al->list + result[i].pkgNum;
	if (alp->p == NULL) /* deleted */
	    continue;
	/* ignore self-conflicts/obsoletes */
	if (filterds && rpmteDS(alp->p, rpmdsTagN(filterds)) == filterds)
	    continue;
	ix = result[i].entryIx;

	if (obsolete) {
	    /* Obsoletes are on package NEVR only */
	    rpmds thisds;
	    if (!rstreq(rpmdsNIndex(alp->provides, ix), rpmteN(alp->p)))
		continue;
	    thisds = rpmteDS(alp->p, RPMTAG_NAME);
	    rc = rpmdsCompareIndex(thisds, rpmdsIx(thisds), ds, rpmdsIx(ds));
	} else {
	    rc = rpmdsCompareIndex(alp->provides, ix, ds, rpmdsIx(ds));
	}

	if (rc)
	    ret[found++] = alp->p;
    }

    if (found) {
	rpmdsNotify(ds, "(added provide)", 0);
	ret[found] = NULL;
    } else {
	ret = _free(ret);
    }

    return ret;
}