Imported Upstream version 17.23.7
[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 void usage ( const std::string &appname )
98 {
99   std::cout << "Usage: " << appname << " [--help] [--debugFile <file>] [--zypper]" << std::endl;
100   std::cout << "List information about all running processe" << std::endl;
101   std::cout << "which access deleted executables or libraries." << std::endl;
102   std::cout << std::endl;
103   std::cout << "GLOBALOPTS:" << std::endl;
104   std::cout << "  --debugFile <file> Use information from <file> instead" << std::endl;
105   std::cout << "                     of inspecting the host system." << std::endl;
106   std::cout << "  --zypper           Disable verbose checking like zypper does." << std::endl;
107   std::cout << std::endl;
108   std::cout << "TABLEHEADERS:" << std::endl;
109   std::cout << "  PID     " << "process ID" << std::endl;
110   std::cout << "  PPID    " << "parent process ID" << std::endl;
111   std::cout << "  UID     " << "process user ID" << std::endl;
112   std::cout << "  LOGIN   " << "process login name" << std::endl;
113   std::cout << "  COMMAND " << "process command name" << std::endl;
114   std::cout << "  SERVICE " << "/etc/init.d/ script that might be used to restart the command (guessed)" << std::endl;
115   std::cout << "  FILES   " << "list of deleted executables or libraries accessed" << std::endl;
116 }
117
118 int main( int argc, char * argv[] )
119 {
120
121   std::string progname( zypp::Pathname::basename( argv[0] ) );
122   std::string debugInputFile;
123   bool verbose = true;
124   argv++;
125   argc--;
126
127   while( argc > 0 ) {
128     if ( strcmp( argv[0], "--help" ) == 0 )
129     {
130       usage( progname );
131       return 0;
132     } else if ( strcmp( argv[0], "--debugFile" ) == 0 ) {
133       if ( argc < 2 ) {
134         std::cerr << progname << ": debugFile requires a argument" << std::endl;
135         return 1;
136       }
137
138       argv++;
139       argc--;
140       debugInputFile = argv[0];
141
142     } else if ( strcmp( argv[0], "--zypper" ) == 0 ) {
143       verbose = false;
144     } else {
145       std::cerr << progname << ": unexpected argument '" << argv[0] << "'" << std::endl;
146       std::cerr << "Try `" << progname << " --help' for more information." << std::endl;
147       return 1;
148     }
149
150     argv++;
151     argc--;
152   }
153
154   zypp::CheckAccessDeleted checker(false); // wait for explicit call to check()
155   try {
156     if ( debugInputFile.empty() )
157       checker.check( verbose );
158     else
159       checker.check( debugInputFile, verbose );
160   }
161   catch( const zypp::Exception & err )
162   {
163     std::cerr << err << std::endl << err.historyAsString();
164     return 2;
165   }
166
167   ProcInfoTable table;
168   for_( it, checker.begin(), checker.end() )
169     table.scan( *it );
170
171   table.printHeader();
172   for_( it, checker.begin(), checker.end() )
173     table.print( *it );
174
175   return 0;
176 }