Ick, but whatever is needed to get the code checked in.

Getting rid of find-provides/find-requires *FOREVER* is far more important
than whatever needs to be done with Mandriva peculier devel(...) name spacing
for the moment.

73 de Jeff


On Apr 10, 2011, at 1:23 AM, Per Øyvind Karlsen wrote:

>  RPM Package Manager, CVS Repository
>  http://rpm5.org/cvs/
>  ____________________________________________________________________________
> 
>  Server: rpm5.org                         Name:   Per Øyvind Karlsen
>  Root:   /v/rpm/cvs                       Email:  pkarl...@rpm5.org
>  Module: rpm                              Date:   10-Apr-2011 07:23:52
>  Branch: rpm-5_4                          Handle: 2011041005235101
> 
>  Modified files:           (Branch: rpm-5_4)
>    rpm                     CHANGES
>    rpm/lib                 librpm.vers rpmds.c rpmds.h rpmfc.c
> 
>  Log:
>    implement devel(libfoo) symlink dependencies from Mandriva, but with
>    proper ELF SONAME checking
> 
>  Summary:
>    Revision    Changes     Path
>    1.3501.2.106+2  -0      rpm/CHANGES
>    1.77.2.1    +1  -0      rpm/lib/librpm.vers
>    2.170.2.3   +171 -12    rpm/lib/rpmds.c
>    2.81.4.1    +13 -0      rpm/lib/rpmds.h
>    1.75.2.5    +17 -1      rpm/lib/rpmfc.c
>  ____________________________________________________________________________
> 
>  patch -p0 <<'@@ .'
>  Index: rpm/CHANGES
>  ============================================================================
>  $ cvs diff -u -r1.3501.2.105 -r1.3501.2.106 CHANGES
>  --- rpm/CHANGES      8 Apr 2011 16:13:14 -0000       1.3501.2.105
>  +++ rpm/CHANGES      10 Apr 2011 05:23:51 -0000      1.3501.2.106
>  @@ -1,4 +1,6 @@
>   5.4.0 -> 5.4.1:
>  +    - proyvind: rpmds: implement devel(libfoo) symlink dependencies from
>  +    Mandriva, but with proper ELF SONAME checking.
>       - jbj: mongo: stub-in a /usr/lib/rpm/bin mongo shell wrapper.
>       - jbj: spewage: fix: rework sql/json markup to use the EVRD parser.
>       - jbj: build: fix: resurrect %description -l XY yet again.
>  @@ .
>  patch -p0 <<'@@ .'
>  Index: rpm/lib/librpm.vers
>  ============================================================================
>  $ cvs diff -u -r1.77 -r1.77.2.1 librpm.vers
>  --- rpm/lib/librpm.vers      27 Sep 2010 23:12:48 -0000      1.77
>  +++ rpm/lib/librpm.vers      10 Apr 2011 05:23:52 -0000      1.77.2.1
>  @@ -125,6 +125,7 @@
>       rpmdsSetRefs;
>       rpmdsSetResult;
>       rpmdsSingle;
>  +    rpmdsSymlink;
>       rpmdsSysinfo;
>       rpmdsTagN;
>       rpmdsThis;
>  @@ .
>  patch -p0 <<'@@ .'
>  Index: rpm/lib/rpmds.c
>  ============================================================================
>  $ cvs diff -u -r2.170.2.2 -r2.170.2.3 rpmds.c
>  --- rpm/lib/rpmds.c  25 Jan 2011 14:47:47 -0000      2.170.2.2
>  +++ rpm/lib/rpmds.c  10 Apr 2011 05:23:52 -0000      2.170.2.3
>  @@ -2890,19 +2890,37 @@
>    * @param isElf64   is this an ELF64 symbol?
>    */
>   #if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
>  -static char * sonameDep(/*@returned@*/ char * t, const char * s, int 
> isElf64)
>  +static char * sonameDep(/*@returned@*/ char * t, const char * s, int 
> isElf64, int devel)
>       /*@modifies t @*/
>   {
>  +    char *tmp = t;
>       *t = '\0';
>  +    if (devel) {
>  +    tmp = stpcpy(t, "devel(");
>  +    }
>   #if !defined(__alpha__) && !defined(__sun)
>  -    if (isElf64) {
>  -    if (s[strlen(s)-1] != ')')
>  -    (void) stpcpy( stpcpy(t, s), "()(64bit)");
>  -    else
>  -        (void) stpcpy( stpcpy(t, s), "(64bit)");
>  +    if (!isElf64) {
>  +    /* XXX: eehhk, would've been nice with consistency, mandriva legacy... 
> :| */
>  +    if (!devel && s[strlen(s)-1] != ')')
>  +    (void) stpcpy( stpcpy(tmp, s), "()(64bit)");
>  +    else {
>  +        char *suffix;
>  +        tmp = stpcpy(tmp, s);
>  +        if (devel && (suffix = strstr(t, ".so")))
>  +            tmp = suffix;
>  +        tmp = stpcpy(tmp, "(64bit)");
>  +        }
>       }else
>   #endif
>  -    (void) stpcpy(t, s);
>  +    tmp = stpcpy(tmp, s);
>  +    if (devel) {
>  +    char *suffix;
>  +    tmp = stpcpy(tmp, s);
>  +    if (devel && (suffix = strstr(t, ".so")))
>  +        tmp = suffix;
>  +    (void) stpcpy(tmp, ")");
>  +    }
>  +
>       return t;
>   }
>   #endif
>  @@ -3074,7 +3092,7 @@
> 
>                           /* Add next provide dependency. */
>                           ds = rpmdsSingle(RPMTAG_PROVIDES,
>  -                                    sonameDep(t, buf, isElf64),
>  +                                    sonameDep(t, buf, isElf64, 0),
>                                       "", RPMSENSE_FIND_PROVIDES);
>                           xx = add(context, ds);
>                           (void)rpmdsFree(ds);
>  @@ -3127,7 +3145,7 @@
> 
>                           /* Add next require dependency. */
>                           ds = rpmdsSingle(RPMTAG_REQUIRENAME,
>  -                                    sonameDep(t, buf, isElf64),
>  +                                    sonameDep(t, buf, isElf64, 0),
>                                       "", RPMSENSE_FIND_REQUIRES);
>                           xx = add(context, ds);
>                           (void)rpmdsFree(ds);
>  @@ -3169,7 +3187,7 @@
>   assert(s != NULL);
>                       buf[0] = '\0';
>                       ds = rpmdsSingle(RPMTAG_REQUIRENAME,
>  -                            sonameDep(buf, s, isElf64),
>  +                            sonameDep(buf, s, isElf64, 0),
>                               "", RPMSENSE_FIND_REQUIRES);
>                       xx = add(context, ds);
>                       (void)rpmdsFree(ds);
>  @@ -3184,7 +3202,7 @@
>                       /* Add next provide dependency. */
>                       buf[0] = '\0';
>                       ds = rpmdsSingle(RPMTAG_PROVIDENAME,
>  -                            sonameDep(buf, s, isElf64),
>  +                            sonameDep(buf, s, isElf64, 0),
>                               "", RPMSENSE_FIND_PROVIDES);
>                       xx = add(context, ds);
>                       (void)rpmdsFree(ds);
>  @@ -3220,7 +3238,7 @@
>       /* Add next provide dependency. */
>       buf[0] = '\0';
>       ds = rpmdsSingle(RPMTAG_PROVIDENAME,
>  -            sonameDep(buf, s, isElf64), "", RPMSENSE_FIND_PROVIDES);
>  +            sonameDep(buf, s, isElf64, 0), "", RPMSENSE_FIND_PROVIDES);
>       xx = add(context, ds);
>       (void)rpmdsFree(ds);
>       ds = NULL;
>  @@ -3238,6 +3256,147 @@
>   }
>   /*@=moduncon =noeffectuncon @*/
> 
>  +
>  +int rpmdsSymlink(const char * fn, int flags,
>  +            int (*add) (void * context, rpmds ds), void * context)
>  +{
>  +#if defined(HAVE_GELF_H) && defined(HAVE_LIBELF) && !defined(__FreeBSD__)
>  +    Elf * elf;
>  +    Elf_Scn * scn;
>  +    Elf_Data * data;
>  +    GElf_Ehdr ehdr_mem, * ehdr;
>  +    GElf_Shdr shdr_mem, * shdr;
>  +    GElf_Dyn dyn_mem, * dyn;
>  +    int fdno;
>  +    int cnt;
>  +    int i;
>  +    char buf[BUFSIZ];
>  +    const char * s;
>  +    int is_executable;
>  +    const char * soname = NULL;
>  +    rpmds ds;
>  +    int xx;
>  +    int isElf64;
>  +    int gotSONAME = 0;
>  +    int skipP = (flags & RPMELF_FLAG_SKIPPROVIDES);
>  +    int skipR = (flags & RPMELF_FLAG_SKIPREQUIRES);
>  +    int lnklen;
>  +    char path[MAXPATHLEN];
>  +    ARGV_t deps = NULL;
>  +
>  +    if ((lnklen = readlink(fn, path, MAXPATHLEN - 1)) == -1) {
>  +    warn("%s", fn);
>  +    return RPMRC_FAIL;
>  +    }
>  +    path[lnklen] = '\0';
>  +
>  +/*@-castfcnptr@*/
>  +if (_rpmds_debug < 0)
>  +fprintf(stderr, "*** rpmdsELF(%s, %d, %p, %p)\n", fn, flags, (void *)add, 
> context);
>  +/*@=castfcnptr@*/
>  +
>  +    /* Extract dependencies only from files with executable bit set. */
>  +    {       struct stat sb, * st = &sb;
>  +    if (lstat(fn, st) != 0)
>  +        return -1;
>  +    is_executable = (int)(st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH));
>  +    }
>  +
>  +    fdno = open(fn, O_RDONLY);
>  +    if (fdno < 0)
>  +    return fdno;
>  +
>  +    (void) elf_version(EV_CURRENT);
>  +
>  +/*@-evalorder@*/
>  +    elf = NULL;
>  +    if ((elf = elf_begin (fdno, ELF_C_READ, NULL)) == NULL
>  +     || elf_kind(elf) != ELF_K_ELF
>  +     || (ehdr = gelf_getehdr(elf, &ehdr_mem)) == NULL
>  +     || !(ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC))
>  +    goto exit;
>  +/*@=evalorder@*/
>  +
>  +    isElf64 = ehdr->e_ident[EI_CLASS] == ELFCLASS64;
>  +
>  +    /*@-uniondef @*/
>  +    scn = NULL;
>  +    while ((scn = elf_nextscn(elf, scn)) != NULL) {
>  +    shdr = gelf_getshdr(scn, &shdr_mem);
>  +    if (shdr == NULL)
>  +        break;
>  +
>  +    soname = _free(soname);
>  +    switch (shdr->sh_type) {
>  +    default:
>  +        continue;
>  +        /*@notreached@*/ /*@switchbreak@*/ break;
>  +    case SHT_DYNAMIC:
>  +        data = NULL;
>  +        while ((data = elf_getdata (scn, data)) != NULL) {
>  +            for (cnt = 0; cnt < (int)(shdr->sh_size / shdr->sh_entsize); 
> ++cnt) {
>  +                dyn = gelf_getdyn (data, cnt, &dyn_mem);
>  +                if (dyn == NULL)
>  +                    /*@innerbreak@*/ break;
>  +                s = NULL;
>  +                switch (dyn->d_tag) {
>  +                default:
>  +                    /*@innercontinue@*/ continue;
>  +                    /*@notreached@*/ /*@switchbreak@*/ break;
>  +                case DT_NEEDED:
>  +                    /* Only from files with executable bit set. */
>  +                    if (skipR || !is_executable)
>  +                        /*@innercontinue@*/ continue;
>  +                    /* Add next require dependency. */
>  +                    s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
>  +assert(s != NULL);
>  +                    buf[0] = '\0';
>  +                    argvAdd(&deps, s);
>  +                    /*@switchbreak@*/ break;
>  +                case DT_SONAME:
>  +                    gotSONAME = 1;
>  +                    s = elf_strptr(elf, shdr->sh_link, dyn->d_un.d_val);
>  +assert(s != NULL);
>  +                    /* Add next provide dependency. */
>  +                    buf[0] = '\0';
>  +                    if (!skipP) {
>  +                        ds = rpmdsSingle(RPMTAG_PROVIDENAME,
>  +                                sonameDep(buf, s, isElf64, 1),
>  +                                "", RPMSENSE_FIND_PROVIDES);
>  +                        xx = add(context, ds);
>  +                        (void)rpmdsFree(ds);
>  +                        ds = NULL;
>  +                    }
>  +                    /*@switchbreak@*/ break;
>  +                }
>  +            }
>  +        }
>  +        /*@switchbreak@*/ break;
>  +    }
>  +    }
>  +    /*@=uniondef @*/
>  +
>  +exit:
>  +    if (gotSONAME)
>  +    for (i = 0, cnt = argvCount(deps); i < cnt; i++) {
>  +        ds = rpmdsSingle(RPMTAG_REQUIRENAME,
>  +                sonameDep(buf, deps[i], isElf64, 1),
>  +                "", RPMSENSE_FIND_REQUIRES);
>  +        xx = add(context, ds);
>  +        (void)rpmdsFree(ds);
>  +        ds = NULL;
>  +    }
>  +
>  +    deps = argvFree(deps);
>  +    if (elf) (void) elf_end(elf);
>  +    if (fdno > 0)
>  +    xx = close(fdno);
>  +    return 0;
>  +#else
>  +    return -1;
>  +#endif
>  +}
>  +
>   #define     _SBIN_LDCONFIG_P        "/sbin/ldconfig -p"
>   /*@unchecked@*/ /*@observer@*/ /*@owned@*/ /*@relnull@*/
>   static const char * _ldconfig_cmd = _SBIN_LDCONFIG_P;
>  @@ .
>  patch -p0 <<'@@ .'
>  Index: rpm/lib/rpmds.h
>  ============================================================================
>  $ cvs diff -u -r2.81 -r2.81.4.1 rpmds.h
>  --- rpm/lib/rpmds.h  6 Mar 2010 15:31:29 -0000       2.81
>  +++ rpm/lib/rpmds.h  10 Apr 2011 05:23:52 -0000      2.81.4.1
>  @@ -616,6 +616,19 @@
>   #define RPMELF_FLAG_SKIPREQUIRES    0x2     /*<! rpmdsELF: skip requires */
> 
>   /** \ingroup rpmds
>  + * Extract dependencies from a symlink.
>  + * @param fn                file name
>  + * @param flags             1: skip provides 2: skip requires
>  + * @param *add              add(arg, ds) saves next provide/require symlink 
> dependency.
>  + * @param context   add() callback context
>  + * @return          0 on success
>  + */
>  +int rpmdsSymlink(const char * fn, int flags,
>  +            int (*add) (void * context, rpmds ds), void * context)
>  +    /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
>  +    /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/;
>  +
>  +/** \ingroup rpmds
>    * Load /etc/ld.so.cache provides into a dependency set.
>    * @todo Add dependency colors, and attach to file.
>    * @retval *PRCO    provides/requires/conflicts/obsoletes depedency set(s)
>  @@ .
>  patch -p0 <<'@@ .'
>  Index: rpm/lib/rpmfc.c
>  ============================================================================
>  $ cvs diff -u -r1.75.2.4 -r1.75.2.5 rpmfc.c
>  --- rpm/lib/rpmfc.c  1 Apr 2011 12:27:47 -0000       1.75.2.4
>  +++ rpm/lib/rpmfc.c  10 Apr 2011 05:23:52 -0000      1.75.2.5
>  @@ -987,6 +987,21 @@
>       return rpmdsELF(fn, flags, rpmfcMergePR, fc);
>   }
> 
>  +static int rpmfcSYMLINK(rpmfc fc)
>  +    /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
>  +    /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
>  +{
>  +    const char * fn = fc->fn[fc->ix];
>  +    int flags = 0;
>  +
>  +    if (fc->skipProv)
>  +    flags |= RPMELF_FLAG_SKIPPROVIDES;
>  +    if (fc->skipReq)
>  +    flags |= RPMELF_FLAG_SKIPREQUIRES;
>  +
>  +    return rpmdsSymlink(fn, flags, rpmfcMergePR, fc);
>  +}
>  +
>   typedef struct rpmfcApplyTbl_s {
>       int (*func) (rpmfc fc);
>       int colormask;
>  @@ -999,7 +1014,8 @@
>   /*@unchecked@*/
>   static struct rpmfcApplyTbl_s rpmfcApplyTable[] = {
>       { rpmfcELF,             RPMFC_ELF },
>  -    { rpmfcSCRIPT,  
> (RPMFC_SCRIPT|RPMFC_PERL|RPMFC_PYTHON|RPMFC_LIBTOOL|RPMFC_PKGCONFIG|RPMFC_BOURNE|RPMFC_JAVA|RPMFC_PHP|RPMFC_MONO|RPMFC_RUBY)
>  },
>  +    { rpmfcSCRIPT,  
> (RPMFC_SCRIPT|RPMFC_PERL|RPMFC_PYTHON|RPMFC_LIBTOOL|RPMFC_PKGCONFIG|RPMFC_BOURNE|RPMFC_JAVA|RPMFC_PHP|RPMFC_MONO)
>  },
>  +    { rpmfcSYMLINK, RPMFC_SYMLINK },
>       { NULL, 0 }
>   };
>   /*@=nullassign@*/
>  @@ .
> ______________________________________________________________________
> RPM Package Manager                                    http://rpm5.org
> CVS Sources Repository                                rpm-...@rpm5.org

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to