#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"
{ /////////////////////////////////////////////////////////////////
//
// 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
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 )
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;
}
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
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();
}
/******************************************************************