Imported Upstream version 17.0.2
[platform/upstream/libzypp.git] / tools / zypp-CheckAccessDeleted.cc
1 #include <cstdio>
2 #include <iostream>
3 #include <zypp/base/Easy.h>
4 #include <zypp/base/String.h>
5 #include <zypp/base/Exception.h>
6 #include <zypp/Pathname.h>
7 #include <zypp/misc/CheckAccessDeleted.h>
8
9 /** Collect max string size. */
10 struct TableCol
11 {
12   TableCol( size_t size_r = 0 )
13   : size( size_r )
14   {}
15   TableCol( const std::string & header_r )
16   : header( header_r ), size( header_r.size() )
17   {}
18   void operator()( const std::string & val_r )
19   { if ( val_r.size() > size ) size = val_r.size(); }
20
21   std::string header;
22   size_t      size;
23 };
24
25 /** Scan to determine column sizes, then print. */
26 struct ProcInfoTable
27 {
28   ProcInfoTable()
29   : pid         ( "PID" )
30   , ppid        ( "PPID" )
31   , puid        ( "UID" )
32   , login       ( "LOGIN" )
33   , command     ( "COMMAND" )
34   , service     ( "SERVICE" )
35   , files       ( "FILES" )
36   {}
37
38   void scan( const zypp::CheckAccessDeleted::ProcInfo & val_r )
39   {
40     pid( val_r.pid );
41     ppid( val_r.ppid );
42     puid( val_r.puid );
43     login( val_r.login );
44     command( val_r.command );
45     service( val_r.service() );
46   }
47
48   void printHeader() const
49   {
50     printRow( pid.header,
51               ppid.header,
52               puid.header,
53               login.header,
54               command.header,
55               service.header,
56               files.header );
57   }
58
59   void print( const zypp::CheckAccessDeleted::ProcInfo & val_r ) const
60   {
61     printRow( val_r.pid,
62               val_r.ppid,
63               val_r.puid,
64               val_r.login,
65               val_r.command,
66               val_r.service(),
67               zypp::str::join( val_r.files, ", " ) );
68   }
69
70   void printRow( const std::string & pid_r,
71                  const std::string & ppid_r,
72                  const std::string & puid_r,
73                  const std::string & login_r,
74                  const std::string & command_r,
75                  const std::string & service_r,
76                  const std::string & files_r ) const
77   {
78     printf( "%*s %*s %*s  %-*s %-*s %-*s %-s\n",
79             (int)pid.size, pid_r.c_str(),
80             (int)ppid.size, ppid_r.c_str(),
81             (int)puid.size, puid_r.c_str(),
82             (int)login.size, login_r.c_str(),
83             (int)command.size, command_r.c_str(),
84             (int)service.size, (service_r.empty() ? " -" : service_r.c_str()),
85             files_r.c_str() );
86   }
87
88   TableCol pid;
89   TableCol ppid;
90   TableCol puid;
91   TableCol login;
92   TableCol command;
93   TableCol service;
94   TableCol files;
95 };
96
97 int main( int argc, char * argv[] )
98 {
99   if ( argc >= 2 )
100   {
101     std::string progname( zypp::Pathname::basename( argv[0] ) );
102     if ( strcmp( argv[1], "--help" ) == 0 )
103     {
104       std::cout << "Usage: " << progname << " [--help]" << std::endl;
105       std::cout << "List information about all running processe" << std::endl;
106       std::cout << "which access deleted executables or libraries." << std::endl;
107       std::cout << "  PID     " << "process ID" << std::endl;
108       std::cout << "  PPID    " << "parent process ID" << std::endl;
109       std::cout << "  UID     " << "process user ID" << std::endl;
110       std::cout << "  LOGIN   " << "process login name" << std::endl;
111       std::cout << "  COMMAND " << "process command name" << std::endl;
112       std::cout << "  SERVICE " << "/etc/init.d/ script that might be used to restart the command (guessed)" << std::endl;
113       std::cout << "  FILES   " << "list of deleted executables or libraries accessed" << std::endl;
114       return 0;
115     }
116     std::cerr << progname << ": unexpected argument '" << argv[1] << "'" << std::endl;
117     std::cerr << "Try `" << progname << " --help' for more information." << std::endl;
118     return 1;
119   }
120
121   zypp::CheckAccessDeleted checker(false); // wait for explicit call to check()
122   try {
123     checker.check( /*verbose*/true );
124   }
125   catch( const zypp::Exception & err )
126   {
127     std::cerr << err << std::endl << err.historyAsString();
128     return 2;
129   }
130
131   ProcInfoTable table;
132   for_( it, checker.begin(), checker.end() )
133     table.scan( *it );
134
135   table.printHeader();
136   for_( it, checker.begin(), checker.end() )
137     table.print( *it );
138
139   return 0;
140 }