rpm/rpm-5.4.5-patchset_16022.patch

223 lines
6.3 KiB
Diff
Raw Normal View History

2012-03-08 04:55:15 +04:00
--- rpm-5.4.5/lib/rpmds.c.16022~ 2012-02-24 14:17:17.278202493 +0100
+++ rpm-5.4.5/lib/rpmds.c 2012-02-24 14:19:52.416279821 +0100
@@ -2916,7 +2916,7 @@ static char * sonameDep(/*@returned@*/ c
if (isElf64) {
/* XXX: eehhk, would've been nice with consistency, mandriva legacy... :| */
if (!devel && s[strlen(s)-1] != ')')
- (void) stpcpy( stpcpy(tmp, s), "()(64bit)");
+ tmp = stpcpy( stpcpy(tmp, s), "()(64bit)");
else {
tmp = stpcpy(tmp, s);
if (devel)
@@ -2995,8 +2995,11 @@ foo:
scn = gelf_offscn (elf, phdr->p_offset);
shdr = gelf_getshdr(scn, &shdr_mem);
data = elf_getdata (scn, data);
- interp_name = strdup(data->d_buf);
- goto end;
+ if (data && data->d_buf) {
+ interp_name = strdup(data->d_buf);
+ goto end;
+ }
+ /* no 'data' most likely implies that this is an elf interpreter itself */
}
if (elf_getshdrstrndx (elf, &shstrndx) >= 0)
@@ -3016,6 +3019,15 @@ foo:
for (cnt = 0; cnt <= dynsize; ++cnt) {
dyn = gelf_getdyn (data, cnt, &dyn_mem);
+ /* if this an elf interpeter, the only thing we want is to find SONAME
+ * and return it
+ */
+ if (phdr) {
+ if (dyn->d_tag != DT_SONAME)
+ continue;
+ interp_name = strdup(elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val));
+ goto end;
+ }
if (rpath == NULL) {
if (dyn->d_tag == DT_RPATH)
rpath = elf_strptr (elf, shdr->sh_link, dyn->d_un.d_val);
@@ -3025,7 +3037,7 @@ foo:
cnt = -1;
continue;
}
- else if (rpath && DT_NEEDED == dyn->d_tag) {
+ else if (rpath && dyn->d_tag == DT_NEEDED) {
char *tmp, *tmp2;
char buf[1024];
char path[1024] = "";
@@ -3083,6 +3095,7 @@ foo:
strcpy(tmp, path_n);
strcat(tmp, "/");
strcat(tmp, libpath);
+
if (stat(tmp, &statbuf) == 0 && statbuf.st_mode & S_IRUSR) {
path[0] = '\0';
break;
@@ -3514,6 +3527,7 @@ int rpmdsSymlink(const char * fn, int fl
char buf[BUFSIZ];
const char * s;
int is_executable;
+ int is_symlink;
const char * soname = NULL;
rpmds ds;
int xx;
@@ -3539,12 +3553,6 @@ int rpmdsSymlink(const char * fn, int fl
if ((s = strrchr(fn, '.')) && strcmp(s, ".so"))
return 0;
- if ((lnklen = readlink(fn, path, MAXPATHLEN - 1)) == -1) {
- warn("%s", fn);
- return -1;
- }
- path[lnklen] = '\0';
-
/*@-castfcnptr@*/
if (_rpmds_debug < 0)
fprintf(stderr, "*** rpmdsELF(%s, %d, %p, %p)\n", fn, flags, (void *)add, context);
@@ -3555,6 +3563,62 @@ fprintf(stderr, "*** rpmdsELF(%s, %d, %p
if (lstat(fn, st) != 0)
return -1;
is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
+ is_symlink = S_ISLNK(st->st_mode);
+ }
+
+ if (is_symlink) {
+#ifdef NOT_YET
+ if ((lnklen = readlink(fn, path, MAXPATHLEN - 1)) == -1) {
+ warn("%s", fn);
+ return -1;
+ }
+ /* XXX: unused, path should expand to absolute path... */
+ path[lnklen] = '\0';
+#endif
+ } else {
+ FILE *fp = fopen(fn, "r");
+ char buf[BUFSIZ];
+ char *in;
+ stpcpy(path, fn);
+ fn = NULL;
+ if (fp == NULL || ferror(fp)) {
+ if (fp) (void) fclose(fp);
+ return -1;
+ }
+ /* try resolve ld scripts
+ * certainly *not* state of the art, but should in practice work
+ * everywhere where relevant...
+ */
+ while ((in = fgets(buf, sizeof(buf) - 1, fp))) {
+ in[sizeof(buf)-1] = '\0';
+ if ((in = strstr(in, "GROUP")) &&
+ (in = strchr(in, '(')) &&
+ (fn = strchr(in, '/')) &&
+ (in = strchr(fn, ' '))) {
+ *in = '\0';
+ break;
+ }
+ if (ferror(fp) || feof(fp))
+ break;
+ }
+ fclose(fp);
+ if (!fn)
+ return -1;
+ else {
+ /* XXX: try determine relative root */
+ struct stat sb, * st = &sb;
+
+ while((in = strrchr(path, '/'))) {
+ stpcpy(in, fn);
+ if (stat(path, st) == 0) {
+ fn = path;
+ break;
+ }
+ *in = 0;
+ }
+ if (!fn)
+ return -1;
+ }
}
fdno = open(fn, O_RDONLY);
@@ -3644,8 +3708,10 @@ assert(s != NULL);
/*@=uniondef @*/
exit:
- if (gotSONAME && !skipR)
+ if (gotSONAME && !skipR) {
for (i = 0, cnt = argvCount(deps); i < cnt; i++) {
+ if (deps[i][0] == 'l' && deps[i][1] == 'd')
+ continue;
ds = rpmdsSingle(RPMTAG_REQUIRENAME,
sonameDep(buf, deps[i], isElf64, 1, isuClibc),
"", RPMSENSE_FIND_REQUIRES);
@@ -3653,6 +3719,7 @@ exit:
(void)rpmdsFree(ds);
ds = NULL;
}
+ }
deps = argvFree(deps);
if (elf) (void) elf_end(elf);
--- rpm-5.4.5/lib/rpmfc.c.16022~ 2012-02-24 13:46:30.693282090 +0100
+++ rpm-5.4.5/lib/rpmfc.c 2012-02-24 14:20:56.062311544 +0100
@@ -518,7 +518,7 @@ assert(EVR != NULL);
* build/reqprov.c:addReqProv()
*/
int overlap = 0, res = 0;
- if (*depsp) {
+ if (*depsp && rpmExpandNumeric("%{?_use_internal_dependency_generator}")) {
int ix = rpmdsSearch(*depsp, ds);
if (ix >= 0) {
/* do not consider dependency ranges like R: foo > 1, R: foo < 3
@@ -1045,6 +1045,11 @@ static int rpmfcSYMLINK(rpmfc fc)
flags |= RPMELF_FLAG_SKIPPROVIDES;
if (fc->skipReq)
flags |= RPMELF_FLAG_SKIPREQUIRES;
+ /* XXX: Remove symlink classifier from linker scripts now that we've been
+ * able to feed it to the generator.
+ */
+ if (fc->fcolor->vals[fc->ix] == (RPMFC_WHITE|RPMFC_INCLUDE|RPMFC_TEXT|RPMFC_SYMLINK))
+ fc->fcolor->vals[fc->ix] &= ~RPMFC_SYMLINK;
return rpmdsSymlink(fn, flags, rpmfcMergePR, fc);
}
@@ -1362,6 +1367,36 @@ if (_rpmfc_debug) /* XXX noisy */
/* Add (filtered) entry to sorted class dictionary. */
fcolor = rpmfcColoring(se);
+
+ /* Quick&dirty hack for linker scripts replacing regular
+ * symlinks. Better *really* needs to be done ASAP.
+ */
+#if defined(RPM_VENDOR_MANDRIVA)
+ if (fcolor == (RPMFC_WHITE|RPMFC_INCLUDE|RPMFC_TEXT)) {
+ char * fn;
+
+ if ((fn = strrchr(s, '.')) && !strcmp(fn, ".so")) {
+ FILE * fp = fopen(s, "r");
+ char buf[BUFSIZ];
+ char * in;
+ if (fp == NULL || ferror(fp)) {
+ if (fp) (void) fclose(fp);
+ }
+ while ((in = fgets(buf, sizeof(buf) - 1, fp))) {
+ in[sizeof(buf)-1] = '\0';
+ if (ferror(fp) || feof(fp))
+ break;
+ if ((fn = strstr(in, "GROUP")) &&
+ (fn = strchr(fn, '(')) && (fn = strchr(in, '/'))) {
+ fcolor |= RPMFC_SYMLINK;
+ break;
+ }
+ }
+ if (fp)
+ fclose(fp);
+ }
+ }
+#endif
xx = argiAdd(&fc->fcolor, (int)fc->ix, fcolor);
if (fcolor != RPMFC_WHITE && (fcolor & RPMFC_INCLUDE))