Пример #1
0
static VALUE
version_new_from_EVR(const char* evr)
{
	char *e = NULL;
	char *vr = NULL;
	char *end = NULL;
	char *tmp_evr = NULL;
	VALUE version = Qnil;

	tmp_evr = strdup(evr);
	if (tmp_evr==NULL) { return Qnil; }

	e = tmp_evr;
	if ( (end=strchr(e, ':')) ) {
		/* epoch is found */
		*end = '\0';
		vr = end+1;
	} else {
		/* no epoch */
		vr = e;
		e = NULL;
	}

	if ( e ) {
		version = rpm_version_new2(vr, atoi(e));
	} else {
		version = rpm_version_new(vr);
	}

	free(tmp_evr);
	return version;
}
Пример #2
0
/*
 * Create a spec file object from a spec file
 * @param [String] filename Spec file path
 * @return [Spec]
 */
static VALUE
spec_s_open(VALUE klass, VALUE filename)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
	Spec rspec;
#else
	rpmts ts = NULL;
#endif

	if (TYPE(filename) != T_STRING) {
		rb_raise(rb_eTypeError, "illegal argument type");
	}

#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
	switch (parseSpec(&rspec, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
	case 0:
		if (rspec != NULL) {
			break;
		}

	default:
		rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
	}
	return Data_Wrap_Struct(klass, NULL, spec_free, rspec);
#else
	ts = rpmtsCreate();
#if RPM_VERSION_CODE < RPM_VERSION(4,4,8)
	switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
#elif RPM_VERSION_CODE < RPM_VERSION(4,5,90)
	switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) {
#elif RPM_VERSION_CODE < RPM_VERSION(5,0,0)
	switch (parseSpec(ts, RSTRING_PTR(filename), "/", NULL, 0, "", NULL, 1, 1)) {
#else
	switch (parseSpec(ts, RSTRING_PTR(filename), "/", 0, "", NULL, 1, 1, 0)) {
#endif
	case 0:
		if (ts != NULL) {
			break;
		}

	default:
		rb_raise(rb_eRuntimeError, "specfile `%s' parsing failed", RSTRING_PTR(filename));
	}
	return Data_Wrap_Struct(klass, NULL, ts_free, ts);
#endif
}

/*
 *
 * Alias for Spec#open
 */
VALUE
rpm_spec_open(const char* filename)
{
	return spec_s_open(rpm_cSpec, rb_str_new2(filename));
}

/*
 * @return [String] Return Build root defined in the spec file
 */
VALUE
rpm_spec_get_buildroot(VALUE spec)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,5,90)
	if (RPM_SPEC(spec)->buildRootURL) {
		return rb_str_new2(RPM_SPEC(spec)->buildRootURL);
	}
#elif RPM_VERSION_CODE < RPM_VERSION(4,5,90)
	if (RPM_SPEC(spec)->rootURL) {
		return rb_str_new2(RPM_SPEC(spec)->rootURL);
	}
#elif RPM_VERSION_CODE < RPM_VERSION(5,0,0)
	if (RPM_SPEC(spec)->buildRoot) {
		return rb_str_new2(RPM_SPEC(spec)->buildRoot);
	}
#else
	const char *buildRootURL = rpmGenPath(RPM_SPEC(spec)->rootURL, "%{?buildroot}", NULL);
	VALUE result = rb_str_new2(buildRootURL);
	buildRootURL = _free(buildRootURL);
	return result;
#endif
	return Qnil;
}

/*
 * @return [String] Return Build subdirectory defined in the spec file
 */
VALUE
rpm_spec_get_buildsubdir(VALUE spec)
{
	if (RPM_SPEC(spec)->buildSubdir) {
		return rb_str_new2(RPM_SPEC(spec)->buildSubdir);
	}
	return Qnil;
}

/*
 * @return [Array<String>] Return Build architectures defined in the spec file
 */
VALUE
rpm_spec_get_buildarchs(VALUE spec)
{
	VALUE ba = rb_ivar_get(spec, id_ba);

	if (NIL_P(ba)) {
		register int i;
		ba = rb_ary_new();
		for (i = 0; i < RPM_SPEC(spec)->BACount; i++) {
			rb_ary_push(ba, rb_str_new2(RPM_SPEC(spec)->BANames[i]));
		}
		rb_ivar_set(spec, id_ba, ba);
	}

	return ba;
}

/*
 * @return [Array<RPM::Require>] Return Build requires defined in the spec file
 */
VALUE
rpm_spec_get_buildrequires(VALUE spec)
{
	VALUE br = rb_ivar_get(spec, id_br);

#if RPM_VERSION_CODE < RPM_VERSION(4,6,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
	if (NIL_P(br)) {
		const char** names;
		const char** vers;
		int_32* flags;
		int_32 count;
		rpmTagType nt, vt, type;
		register int i;

		br = rb_ary_new();
		if (!headerGetEntryMinMemory(RPM_SPEC(spec)->buildRestrictions,
									 RPMTAG_REQUIRENAME, (hTYP_t)&nt,
									 (hPTR_t*)&names, (hCNT_t)&count)) {
			goto leave;
		}

		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREVERSION,
				  &vt, (void*)&vers);
		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREFLAGS,
				  &type, (void*)&flags);

		for (i = 0; i < count; i++) {
			rb_ary_push(br, rpm_require_new(names[i], rpm_version_new(vers[i]),
											flags[i], spec));
		}

		release_entry(nt, names);
		release_entry(vt, vers);

		rb_ivar_set(spec, id_br, br);
	}

 leave:
	return br;
#else
	rpmtd nametd = rpmtdNew();
	rpmtd versiontd = rpmtdNew();
	rpmtd flagtd = rpmtdNew();

	if (NIL_P(br)) {
		br = rb_ary_new();
		if (!headerGet(RPM_SPEC(spec)->buildRestrictions,
                       RPMTAG_REQUIRENAME, nametd, HEADERGET_MINMEM)) {
			goto leave;
		}

		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREVERSION,
				  versiontd);
		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_REQUIREFLAGS,
				  flagtd);

		rpmtdInit(nametd);
        while ( rpmtdNext(nametd) != -1 ) {
			rb_ary_push(br, rpm_require_new(rpmtdGetString(nametd), rpm_version_new(rpmtdNextString(versiontd)), *rpmtdNextUint32(flagtd), spec));
		}
		rb_ivar_set(spec, id_br, br);
	}

 leave:
	rpmtdFree(nametd);
	rpmtdFree(versiontd);
	rpmtdFree(flagtd);

	return br;
#endif
}

/*
 * @return [Array<RPM::Conflict>] Return Build conflicts defined in the spec file
 */
VALUE
rpm_spec_get_buildconflicts(VALUE spec)
{
	VALUE bc = rb_ivar_get(spec, id_bc);
#if RPM_VERSION_CODE < RPM_VERSION(4,6,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
	if (NIL_P(bc)) {
		const char** names;
		const char** vers;
		int_32* flags;
		int_32 count;
		rpmTagType nt, vt, type;
		register int i;

		bc = rb_ary_new();
		if (!headerGetEntryMinMemory(RPM_SPEC(spec)->buildRestrictions,
									 RPMTAG_CONFLICTNAME, (hTYP_t)&nt,
									 (hPTR_t*)&names, (hCNT_t)&count)) {
			goto leave;
		}

		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTVERSION,
				  &vt, (void*)&vers);
		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTFLAGS,
				  &type, (void*)&flags);

		for (i = 0; i < count; i++) {
			rb_ary_push(bc, rpm_conflict_new(names[i], rpm_version_new(vers[i]),
											 flags[i], spec));
		}

		release_entry(nt, names);
		release_entry(vt, vers);

		rb_ivar_set(spec, id_bc, bc);
	}
 leave:
	return bc;
#else
	rpmtd nametd = rpmtdNew();
	rpmtd versiontd = rpmtdNew();
	rpmtd flagtd = rpmtdNew();

	if (NIL_P(bc)) {
		bc = rb_ary_new();
		if (!headerGet(RPM_SPEC(spec)->buildRestrictions,
                       RPMTAG_CONFLICTNAME, nametd, HEADERGET_MINMEM)) {

			goto leave;
		}

		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTVERSION,
				  versiontd);
		get_entry(RPM_SPEC(spec)->buildRestrictions, RPMTAG_CONFLICTFLAGS,
				  flagtd);

		rpmtdInit(nametd);
		while ( rpmtdNext(nametd) != -1) {
			rb_ary_push(bc, rpm_conflict_new(rpmtdGetString(nametd), rpm_version_new(rpmtdNextString(versiontd)), *rpmtdNextUint32(flagtd), spec));
		}

		rb_ivar_set(spec, id_bc, bc);
	}
 leave:
	rpmtdFree(nametd);
	rpmtdFree(versiontd);
	rpmtdFree(flagtd);

	return bc;
#endif
}
Пример #3
0
/*
 * Check the dependencies.
 * @return [Array<Dependency>, +nil+] If dependencies are not met returns an
 *    array with dependencies. Otherwise +nil+.
 */
VALUE
rpm_transaction_check(VALUE trans)
{
#if RPM_VERSION_CODE < RPM_VERSION(4,1,0)
	rpmDependencyConflict conflicts;
	int num;

	rpmdepCheck(RPM_TRANSACTION(trans), &conflicts, &num);
	if (num) {
		VALUE list = rb_ary_new();
		register int i;

		for (i = 0; i < num; i++) {
			VALUE dep;
			switch (conflicts[i].sense) {
			case RPMDEP_SENSE_REQUIRES:
				dep = rpm_require_new(conflicts[i].needsName,
									  rpm_version_new(conflicts[i].needsVersion),
									  conflicts[i].needsFlags,
									  rpm_package_new_from_header(conflicts[i].byHeader));
				break;

			case RPMDEP_SENSE_CONFLICTS:
				dep = rpm_conflict_new(conflicts[i].needsName,
									   rpm_version_new(conflicts[i].needsVersion),
									   conflicts[i].needsFlags,
									   rpm_package_new_from_header(conflicts[i].byHeader));
				break;
			}
			rb_ary_push(list, dep);
		}

		rpmdepFreeConflicts(conflicts, num);
		return list;
	}

	return Qnil;
#else
	int rc;
	rpmps ps;
	int num;
	VALUE list = Qnil;

	rc = rpmtsCheck(RPM_TRANSACTION(trans));
	ps = rpmtsProblems(RPM_TRANSACTION(trans));
#if RPM_VERSION_CODE < RPM_VERSION(4,9,0) || RPM_VERSION_CODE >= RPM_VERSION(5,0,0)
	/* get rid of duplicate problems */
	rpmpsTrim(ps, RPMPROB_FILTER_NONE);
#endif
	num = rpmpsNumProblems(ps);

#ifdef RPMPS_OPAQUE
	rpmpsi psi = rpmpsInitIterator(ps);
	if (num > 0) {
		list = rb_ary_new();
	}
	while (rpmpsNextIterator(psi) >= 0) {
		rpmProblem p = rpmpsGetProblem(psi);
		VALUE dep;
		switch (rpmProblemGetType(p)) {
		case RPMPROB_REQUIRES: {
			char *buf = strdup (rpmProblemGetAltNEVR(p));
			/* TODO: zaki: NULL check*/
			char *end;

			char *name = buf+2;
			char *relation = NULL;
			char *evr = NULL;
			rpmsenseFlags sense_flags = 0;

			end = strchr ( name, ' ');
			if ( end ) {
				*end = '\0';
				relation = end + 1;
				end = strchr ( relation, ' ');
				if ( end ) {
					*end = '\0';
					evr = end + 1;
				}
				for ( ; (*relation) != '\0'; relation++ ) {
					if ( (*relation) == '=' ) {
						sense_flags |= RPMSENSE_EQUAL;
					} else if ( (*relation) == '>' ) {
						sense_flags |= RPMSENSE_GREATER;
					} else if ( (*relation) == '<' ) {
						sense_flags |= RPMSENSE_LESS;
					}
				}
			}

			dep = rpm_require_new(name,
                                  rpm_version_new(evr ? evr : ""),
					  sense_flags,
					  package_new_from_NEVR(
						rpmProblemGetPkgNEVR(p)
					  ));
			free ( buf );
			rb_ary_push(list, dep);
			break;
		}
		default:
			break;
		}
	}
#else
	if (ps != NULL && 0 < num) {
		rpmProblem p;
		int i;
		list = rb_ary_new();

		for (i = 0; i < num; i++) {
			const char *altNEVR;
			VALUE dep;

			p = ps->probs + i;
			altNEVR = (p->altNEVR ? p->altNEVR : "? ?altNEVR?");

			if (p->ignoreProblem)
				continue;

#if 0 /* XXX shouldn't be needed at all due to rpmpsTrim() */
			/* Filter already appended problems. */
			for (j = 0; j < i; j++) {
				if (!sameProblem(p, ps->probs + j))
					break;
			}
			if (j < i)
				continue;
#endif

			if ( p->type == RPMPROB_REQUIRES ) {
				char *buf = strdup ( altNEVR );
				/* TODO: zaki: NULL check*/
				char *end;

				char *name = buf+2;
				char *relation = NULL;
				char *evr = "";
				rpmsenseFlags sense_flags = 0;

				end = strchr ( name, ' ');
				if ( end ) {
					*end = '\0';
					relation = end + 1;
					end = strchr ( relation, ' ');
					if ( end ) {
						*end = '\0';
						evr = end + 1;
					}
					for ( ; (*relation) != '\0'; relation++ ) {
						if ( (*relation) == '=' ) {
							sense_flags |= RPMSENSE_EQUAL;
						} else if ( (*relation) == '>' ) {
							sense_flags |= RPMSENSE_GREATER;
						} else if ( (*relation) == '<' ) {
							sense_flags |= RPMSENSE_LESS;
						}
					}
				}

				dep = rpm_require_new(name,
									  rpm_version_new(evr),
									  sense_flags,
									  package_new_from_NEVR(p->pkgNEVR)
									  );
				free ( buf );
				rb_ary_push(list, dep);
			} else {
#if 0
			RPMPROB_CONFLICT:
			RPMPROB_BADARCH:
			RPMPROB_BADOS:
			RPMPROB_PKG_INSTALLED:
			RPMPROB_BADRELOCATE:
			RPMPROB_NEW_FILE_CONFLICT:
			RPMPROB_FILE_CONFLICT:
			RPMPROB_OLDPACKAGE:
			RPMPROB_DISKSPACE:
			RPMPROB_DISKNODES:
			RPMPROB_BADPRETRANS:
#endif
				break;
			}

#if 0
			printf ("%d, type=%d, ignoreProblem=%d, str1=%s pkgNEVR=%s, %s\n",
					i, p->type, p->ignoreProblem, p->str1, p->pkgNEVR, altNEVR);
#endif
        }
	}
#endif /* RPMPS_OPAQUE */
	ps = rpmpsFree(ps);

	return list;
#endif
}