Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / misc / CheckAccessDeleted.cc
index 8f666c4..0efb181 100644 (file)
@@ -18,9 +18,6 @@
 
 #include "zypp/PathInfo.h"
 #include "zypp/ExternalProgram.h"
-#include "zypp/base/Regex.h"
-#include "zypp/base/IOStream.h"
-#include "zypp/base/InputStream.h"
 
 #include "zypp/misc/CheckAccessDeleted.h"
 
@@ -38,7 +35,7 @@ namespace zypp
   { /////////////////////////////////////////////////////////////////
     //
     // lsof output lines are a sequence of NUL terminated fields,
-    // where the 1st char determines the fields type.
+    // where the 1st char determines the fiels type.
     //
     // (pcuL) pid command userid loginname
     // (ftkn).filedescriptor type linkcount filename
@@ -65,7 +62,6 @@ namespace zypp
       pinfo.files.insert( pinfo.files.begin(), filelist.begin(), filelist.end() );
 
       const std::string & pline( cache_r.first );
-      std::string commandname; // pinfo.command if still needed...
       for_( ch, pline.begin(), pline.end() )
       {
         switch ( *ch )
@@ -83,21 +79,21 @@ namespace zypp
             pinfo.login = &*(ch+1);
             break;
           case 'c':
-           if ( pinfo.command.empty() )
-             commandname = &*(ch+1);
-           break;
+            pinfo.command = &*(ch+1);
+            break;
         }
         if ( *ch == '\n' ) break;              // end of data
         do { ++ch; } while ( *ch != '\0' );    // skip to next field
       }
 
-      if ( pinfo.command.empty() )
+      if ( pinfo.command.size() == 15 )
       {
-       // the lsof command name might be truncated, so we prefer /proc/<pid>/exe
-       pinfo.command = filesystem::readlink( Pathname("/proc")/pinfo.pid/"exe" ).basename();
-       if ( pinfo.command.empty() )
-         pinfo.command = std::move(commandname);
+        // the command name might be truncated, so we check against /proc/<pid>/exe
+        Pathname command( filesystem::readlink( Pathname("/proc")/pinfo.pid/"exe" ) );
+        if ( ! command.empty() )
+          pinfo.command = command.basename();
       }
+      //MIL << " Take " << pinfo << endl;
     }
 
 
@@ -256,12 +252,20 @@ namespace zypp
     return _data.size();
   }
 
-  std::string CheckAccessDeleted::findService( pid_t pid_r )
+  std::string CheckAccessDeleted::findService( const Pathname & command_r )
   {
     ProcInfo p;
-    p.pid = str::numstring( pid_r );
+    p.command = command_r.basename();
     return p.service();
   }
+  std::string CheckAccessDeleted::findService( const char * command_r )
+  { return findService( Pathname( command_r ) ); }
+
+  std::string CheckAccessDeleted::findService( const std::string & command_r )
+  { return findService( Pathname( command_r ) ); }
+
+  std::string CheckAccessDeleted::findService( pid_t pid_r )
+  { return findService( filesystem::readlink( Pathname("/proc")/str::numstring(pid_r)/"exe" ) ); }
 
   ///////////////////////////////////////////////////////////////////
   namespace
@@ -272,20 +276,33 @@ namespace zypp
 
   std::string CheckAccessDeleted::ProcInfo::service() const
   {
-    static const str::regex rx( "[0-9]+:name=systemd:/system.slice/(.*/)?(.*).service$" );
-    str::smatch what;
-    std::string ret;
-    iostr::simpleParseFile( InputStream( Pathname("/proc")/pid/"cgroup" ),
-                           [&]( int num_r, std::string line_r )->bool
-                           {
-                             if ( str::regex_match( line_r, what, rx ) )
-                             {
-                               ret = what[2];
-                               return false;   // stop after match
-                             }
-                             return true;
-                           } );
-    return ret;
+    if ( command.empty() )
+      return std::string();
+    // TODO: This needs to be implemented smarter... be carefull
+    // as we don't know whether the target is up.
+
+    static const Pathname initD( "/etc/init.d" );
+    { // init.d script with same name
+      PathInfo pi( initD/command );
+      if ( pi.isFile() && pi.isX() )
+        return command;
+    }
+    { // init.d script with name + 'd'
+      std::string alt( command+"d" );
+      PathInfo pi( initD/alt );
+      if ( pi.isFile() && pi.isX() )
+        return alt;
+    }
+    if ( *command.rbegin() == 'd' )
+    { // init.d script with name - trailing'd'
+      std::string alt( command );
+      alt.erase( alt.size()-1 );
+      PathInfo pi( initD/alt );
+      WAR <<pi << endl;
+      if ( pi.isFile() && pi.isX() )
+        return alt;
+    }
+    return std::string();
   }
 
   /******************************************************************