LCOV - code coverage report
Current view: top level - mnt/wasteland/wcohen/systemtap_write/systemtap - rpm_finder.cxx (source / functions) Hit Total Coverage
Test: stap.info Lines: 48 80 60.0 %
Date: 2013-03-08 Functions: 4 6 66.7 %
Branches: 26 98 26.5 %

           Branch data     Line data    Source code
       1                 :            : // systemtap debuginfo rpm finder
       2                 :            : // Copyright (C) 2009-2011 Red Hat Inc.
       3                 :            : //
       4                 :            : // This file is part of systemtap, and is free software.  You can
       5                 :            : // redistribute it and/or modify it under the terms of the GNU General
       6                 :            : // Public License (GPL); either version 2, or (at your option) any
       7                 :            : // later version.
       8                 :            : 
       9                 :            : #include "config.h"
      10                 :            : #include "session.h"
      11                 :            : #include "rpm_finder.h"
      12                 :            : 
      13                 :            : #include <iostream>
      14                 :            : #include <fstream>
      15                 :            : #include <sstream>
      16                 :            : #include <cerrno>
      17                 :            : #include <cstdlib>
      18                 :            : 
      19                 :            : using namespace std;
      20                 :            : 
      21                 :            : #ifdef HAVE_LIBRPM
      22                 :            : 
      23                 :            : extern "C" {
      24                 :            : 
      25                 :            : #define _RPM_4_4_COMPAT
      26                 :            : #include <string.h>
      27                 :            : #include <rpm/rpmlib.h>
      28                 :            : #include <rpm/rpmts.h>
      29                 :            : #include <rpm/rpmdb.h>
      30                 :            : #include <rpm/header.h>
      31                 :            : 
      32                 :            : #ifndef xfree
      33                 :            : #define xfree free
      34                 :            : #endif
      35                 :            : 
      36                 :            : }
      37                 :            : 
      38                 :            : #if ! HAVE_LIBRPMIO && HAVE_NSS
      39                 :            : extern "C" {
      40                 :            : #include <nss.h>
      41                 :            : }
      42                 :            : #include "nsscommon.h"
      43                 :            : #endif
      44                 :            : 
      45                 :            : /* Returns the count of newly added rpms.  */
      46                 :            : /* based on the code in F11 gdb-6.8.50.20090302 source rpm */
      47                 :            : /* Added in the rpm_type parameter to specify what rpm to look for */
      48                 :            : 
      49                 :            : static int
      50                 :         10 : missing_rpm_enlist (systemtap_session& sess, const char *filename, const char *rpm_type)
      51                 :            : {
      52                 :            :   static int rpm_init_done = 0;
      53                 :            :   rpmts ts;
      54                 :            :   rpmdbMatchIterator mi;
      55                 :         10 :   int count = 0;
      56                 :            : 
      57         [ -  + ]:         10 :   if (filename == NULL)
      58                 :          0 :     return 0;
      59                 :            : 
      60         [ +  + ]:         10 :   if (!rpm_init_done)
      61                 :            :     {
      62                 :            :       static int init_tried;
      63                 :            : 
      64                 :            :       /* Already failed the initialization before?  */
      65         [ -  + ]:          6 :       if (init_tried)
      66                 :          0 :         return 0;
      67                 :          6 :       init_tried = 1;
      68                 :            : 
      69         [ -  + ]:          6 :       if (rpmReadConfigFiles(NULL, NULL) != 0)
      70                 :            :         {
      71                 :          0 :           cerr << _("Error reading the rpm configuration files") << endl;
      72                 :          0 :           return 0;
      73                 :            :         }
      74                 :            : 
      75                 :          6 :       rpm_init_done = 1;
      76                 :            :     }
      77                 :            : 
      78                 :         10 :   ts = rpmtsCreate(); 
      79                 :            : 
      80                 :         10 :   mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, filename, 0);
      81         [ +  + ]:         10 :   if (mi != NULL)
      82                 :            :     {
      83                 :          8 :       for (;;)
      84                 :            :         {
      85                 :            :           Header h;
      86                 :            :           char *rpminfo, *s, *s2;
      87                 :         16 :           char header[31] = {};
      88                 :         16 :           const char* arch = ".%{arch}";
      89                 :         16 :           sprintf(header, "%%{sourcerpm}%s%s", rpm_type, arch);
      90                 :            :           errmsg_t err;
      91                 :         16 :           size_t rpminfolen = strlen(rpm_type);
      92                 :         16 :           size_t srcrpmlen = sizeof (".src.rpm") - 1;
      93                 :            :           rpmdbMatchIterator mi_rpminfo;
      94         [ +  - ]:         16 :           h = rpmdbNextIterator(mi);
      95         [ +  + ]:         16 :           if (h == NULL)
      96                 :            :             break;
      97                 :            :           /* Verify the kernel file is not already installed.  */
      98                 :            : 
      99                 :            :           rpminfo = headerSprintf(h, header,
     100         [ +  - ]:          8 :                               rpmTagTable, rpmHeaderFormats, &err);
     101                 :            : 
     102         [ -  + ]:          8 :           if (!rpminfo)
     103                 :            :             {
     104 [ #  # ][ #  # ]:          0 :               cerr << _("Error querying the rpm file `") << filename << "': "
                 [ #  # ]
     105 [ #  # ][ #  # ]:          0 :                    << err << endl;
     106                 :          0 :               continue;
     107                 :            :             }
     108                 :            :           /* s = `.src.rpm-debuginfo.%{arch}' */
     109                 :          8 :           s = strrchr (rpminfo, '-') - srcrpmlen;
     110                 :          8 :           s2 = NULL;
     111 [ +  - ][ +  - ]:          8 :           if (s > rpminfo && memcmp (s, ".src.rpm", srcrpmlen) == 0)
     112                 :            :             {
     113                 :            :               /* s2 = `-%{release}.src.rpm-debuginfo.%{arch}' */
     114                 :          8 :               s2 = (char *) memrchr (rpminfo, '-', s - rpminfo);
     115                 :            :             }
     116         [ +  - ]:          8 :           if (s2)
     117                 :            :             {
     118                 :            :               /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
     119                 :          8 :               s2 = (char *) memrchr (rpminfo, '-', s2 - rpminfo);
     120                 :            :             }
     121         [ -  + ]:          8 :           if (!s2)
     122                 :            :             {
     123 [ #  # ][ #  # ]:          0 :               cerr << _("Error querying the rpm file `") << filename 
     124 [ #  # ][ #  # ]:          0 :                    << "': " << rpminfo << endl;
                 [ #  # ]
     125                 :          0 :               xfree (rpminfo);
     126                 :          0 :               continue;
     127                 :            :             }
     128                 :            :           /* s = `.src.rpm-debuginfo.%{arch}' */
     129                 :            :           /* s2 = `-%{version}-%{release}.src.rpm-debuginfo.%{arch}' */
     130                 :          8 :           memmove (s2 + rpminfolen, s2, s - s2);
     131                 :          8 :           memcpy (s2, rpm_type, rpminfolen);
     132                 :            :           /* s = `XXXX.%{arch}' */
     133                 :            :           /* strlen ("XXXX") == srcrpmlen + debuginfolen */
     134                 :            :           /* s2 = `-debuginfo-%{version}-%{release}XX.%{arch}' */
     135                 :            :           /* strlen ("XX") == srcrpmlen */
     136                 :          8 :           memmove (s + rpminfolen, s + srcrpmlen + rpminfolen,
     137                 :          8 :                    strlen (s + srcrpmlen + rpminfolen) + 1);
     138                 :            :           /* s = `-debuginfo-%{version}-%{release}.%{arch}' */
     139                 :            : 
     140                 :            :           /* RPMDBI_PACKAGES requires keylen == sizeof (int).  */
     141                 :            :           /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel().  */
     142                 :            :           mi_rpminfo = rpmtsInitIterator(ts, (rpmTag)  RPMDBI_LABEL,
     143         [ +  - ]:          8 :                                               rpminfo, 0);
     144         [ -  + ]:          8 :           if (mi_rpminfo)
     145                 :            :             {
     146         [ #  # ]:          0 :               rpmdbFreeIterator(mi_rpminfo);
     147                 :          0 :               count = 0;
     148                 :            :               break;
     149                 :            :             }
     150                 :            :           /* The allocated memory gets utilized below for MISSING_RPM_HASH.  */
     151         [ +  - ]:          8 :           if(strcmp(rpm_type,"-debuginfo")==0){
     152                 :          8 :             xfree(rpminfo);
     153                 :            :             rpminfo = headerSprintf(h,
     154                 :            :                       "%{name}-%{version}-%{release}.%{arch}",
     155         [ +  - ]:          8 :                       rpmTagTable, rpmHeaderFormats, &err);
     156                 :            :           }
     157         [ -  + ]:          8 :           if (!rpminfo)
     158                 :            :             {
     159 [ #  # ][ #  # ]:          0 :               cerr << _("Error querying the rpm file `") << filename 
     160 [ #  # ][ #  # ]:          0 :                    << "': " << err << endl;
                 [ #  # ]
     161                 :          0 :               continue;
     162                 :            :             }
     163                 :            : 
     164                 :            :           /* Base package name for `debuginfo-install'.  We do not use the
     165                 :            :           `yum' command directly as the line
     166                 :            :           yum --enablerepo='*-debuginfo' install NAME-debuginfo.ARCH
     167                 :            :           would be more complicated than just:
     168                 :            :           debuginfo-install NAME-VERSION-RELEASE.ARCH
     169                 :            :           Do not supply the rpm base name (derived from .src.rpm name) as
     170                 :            :           debuginfo-install is unable to install the debuginfo package if
     171                 :            :           the base name PKG binary rpm is not installed while for example
     172                 :            :           PKG-libs would be installed (RH Bug 467901).
     173                 :            :           FUTURE: After multiple debuginfo versions simultaneously installed
     174                 :            :           get supported the support for the VERSION-RELEASE tags handling
     175                 :            :           may need an update.  */
     176 [ +  - ][ +  - ]:          8 :           sess.rpms_to_install.insert(rpminfo);
                 [ +  - ]
     177                 :            :         }
     178                 :          8 :       count++;
     179                 :          8 :       rpmdbFreeIterator(mi);
     180                 :            :     }
     181                 :            : 
     182                 :         10 :   rpmtsFree(ts);
     183                 :            : 
     184                 :            : #if HAVE_NSS
     185                 :            :   // librpm uses NSS cryptography but doesn't shut down NSS when it is done.
     186                 :            :   // If NSS is available, it will be used by the compile server client on
     187                 :            :   // specific certificate databases and thus, it must be shut down first.
     188                 :            :   // Get librpm to do it if we can. Otherwise do it ourselves.
     189                 :            : #if HAVE_LIBRPMIO
     190                 :         10 :   rpmFreeCrypto (); // Shuts down NSS within librpm
     191                 :            : #else
     192                 :            :   nssCleanup (NULL); // Shut down NSS ourselves
     193                 :            : #endif
     194                 :            : #endif
     195                 :            : 
     196                 :         10 :   return count;
     197                 :            : }
     198                 :            : #endif  /* HAVE_LIBRPM */
     199                 :            : 
     200                 :            : void
     201                 :          0 : missing_rpm_list_print (systemtap_session &sess, const char* rpm_type)
     202                 :            : {
     203                 :            : #ifdef HAVE_LIBRPM
     204 [ #  # ][ #  # ]:          0 :   if (sess.rpms_to_install.size() > 0 && ! sess.suppress_warnings) {
                 [ #  # ]
     205                 :            : 
     206         [ #  # ]:          0 :     if(strcmp(rpm_type,"-devel")==0)
     207                 :          0 :         cerr << _("Incorrect version or missing kernel-devel package, use: yum install ");
     208                 :            : 
     209         [ #  # ]:          0 :     else if(strcmp(rpm_type,"-debuginfo")==0)
     210                 :          0 :         cerr << _("Missing separate debuginfos, use: debuginfo-install ");
     211                 :            : 
     212                 :            :     else{
     213                 :          0 :         cerr << _("Incorrect parameter passed, please report this error.") << endl;
     214                 :          0 :         _exit(1);
     215                 :            :         }
     216                 :            : 
     217 [ #  # ][ #  # ]:          0 :     for (set<std::string>::iterator it=sess.rpms_to_install.begin();
     218         [ #  # ]:          0 :          it !=sess.rpms_to_install.end(); it++)
     219                 :            :     {
     220 [ #  # ][ #  # ]:          0 :       cerr <<  *it << " ";
     221                 :            :     }
     222                 :          0 :     cerr << endl;
     223                 :            :   }
     224                 :            : #endif
     225                 :          0 : }
     226                 :            : 
     227                 :            : int
     228                 :         10 : find_debug_rpms (systemtap_session &sess, const char * filename)
     229                 :            : {
     230                 :            : #ifdef HAVE_LIBRPM
     231                 :         10 :   const char *rpm_type = "-debuginfo";
     232                 :         10 :   return missing_rpm_enlist(sess, filename, rpm_type);
     233                 :            : #else
     234                 :            :   return 0;
     235                 :            : #endif
     236                 :            : }
     237                 :            : 
     238                 :          0 : int find_devel_rpms(systemtap_session &sess, const char * filename)
     239                 :            : {
     240                 :            : #ifdef HAVE_LIBRPM
     241                 :          0 :   const char *rpm_type = "-devel";
     242                 :          0 :   return missing_rpm_enlist(sess, filename, rpm_type);
     243                 :            : #else
     244                 :            :   return 0;
     245                 :            : #endif
     246 [ +  - ][ +  - ]:       7242 : }

Generated by: LCOV version 1.9