Imported Upstream version 17.23.7
[platform/upstream/libzypp.git] / tools / zypp-pubkey.cc
1 #define INCLUDE_TESTSETUP_WITHOUT_BOOST
2 #include "../tests/lib/TestSetup.h"
3 #undef  INCLUDE_TESTSETUP_WITHOUT_BOOST
4 #define message cout
5 using std::flush;
6
7 #include <boost/program_options.hpp>
8 namespace opt = boost::program_options;
9
10 #include <zypp/target/rpm/RpmDb.h>
11 #include <zypp/base/String.h>
12
13 static std::string appname( "unknown" );
14
15 int errexit( const std::string & msg_r = std::string(), int exit_r = 100 )
16 {
17   if ( ! msg_r.empty() )
18   {
19     cerr << endl << msg_r << endl << endl;
20   }
21   return exit_r;
22 }
23
24 bool byTTL( const PublicKey & lhs, const PublicKey & rhs )
25 {
26   int cmp = lhs.gpgPubkeyVersion().compare( rhs.gpgPubkeyVersion() );
27   if ( cmp ) return cmp < 0;
28   return lhs.gpgPubkeyRelease() > rhs.gpgPubkeyRelease(); // intentionally reverse cdate
29 }
30
31 std::ostream & dumpPubkeyOn( std::ostream & str, const PublicKey & key_r )
32 {
33   std::vector<std::string> art( key_r.asciiArt().asLines( " ", PublicKey::AsciiArt::USE_COLOR ) );
34
35   std::vector<std::string> info;
36   str::split( (str::Str() << dump(key_r)).str(), std::back_inserter( info ), "\n" );
37
38   for ( unsigned i = 1; i < info.size(); ++i )
39     art[i] += info[i];
40
41   str << info[0] << endl;
42   for ( const auto & line : art )
43     str << line << endl;
44   return str << endl;
45 }
46
47 /******************************************************************
48 **
49 **      FUNCTION NAME : main
50 **      FUNCTION TYPE : int
51 */
52 int main( int argc, char * argv[] )
53 {
54   appname = Pathname::basename( argv[0] );
55   ///////////////////////////////////////////////////////////////////
56
57   opt::options_description options( "Options" );
58   options.add_options()
59       ( "key-file",     opt::value<std::vector<std::string> >(),
60                         "ASCII ascii armored public key file")
61       ( "root",         opt::value<std::string>()->default_value( "/" ),
62                         "Use the rmp database from system rooted at ARG")
63       ( "help,?",       "Produce this help message")
64       ;
65
66   opt::positional_options_description positional;
67   positional.add( "key-file", -1 );
68
69   opt::variables_map vm;
70   opt::store( opt::command_line_parser( argc, argv ).options( options ).positional( positional ).run(), vm );
71   opt::notify( vm );
72
73   if ( vm.count( "help" ) )
74   {
75     cerr << "Usage: " << appname << " [OPTIONS] [key-files...]" << endl;
76     cerr << "If no key files are given, list info about all gpg-pubkeys in the rpm database." << endl;
77     cerr << "Otherwise print info about each key and wheter it is present in the rpm database. " << endl;
78     cerr << options << endl;
79     return 1;
80   }
81   ///////////////////////////////////////////////////////////////////
82
83   if ( ! PathInfo( vm["root"].as<std::string>() ).isDir() )
84       return errexit("--root requires a directory");
85
86   target::rpm::RpmDb rpmdb;
87   rpmdb.initDatabase( vm["root"].as<std::string>() );
88   std::list<PublicKey> rpmpubkeys( rpmdb.pubkeys() );
89   rpmpubkeys.sort( byTTL );
90
91
92
93   if ( ! vm.count( "key-file" ) )
94   {
95     std::string last;
96     for_each_( it, rpmpubkeys )
97     {
98       if ( last == it->gpgPubkeyVersion() )
99         cout << *it << endl;
100       else
101       {
102         dumpPubkeyOn( cout, *it );
103         last = it->gpgPubkeyVersion();
104       }
105     }
106     return 0;
107   }
108
109   ///////////////////////////////////////////////////////////////////
110
111   for_each_( it, vm["key-file"].as< std::vector<std::string> >() )
112   {
113     cout << "=== " << PathInfo(*it) << endl;
114     PublicKey pubkey( *it );
115     dumpPubkeyOn( cout, pubkey );
116
117     std::string pubkeyV( pubkey.gpgPubkeyVersion() );
118     std::string pubkeyR( pubkey.gpgPubkeyRelease() );
119     unsigned count = 0;
120     for_each_( rpmpub, rpmpubkeys )
121     {
122       if ( rpmpub->gpgPubkeyVersion() == pubkeyV )
123       {
124         int cmp = rpmpub->gpgPubkeyRelease().compare( pubkeyR );
125         if ( cmp < 0 )
126           cout << "<<< ";
127         else if ( cmp > 0 )
128           cout << ">>> ";
129         else
130         {
131           ++count;
132           cout << "*** ";
133         }
134         cout << "gpg-pubkey-" << rpmpub->gpgPubkeyVersion() << "-" << rpmpub->gpgPubkeyRelease() << " " << rpmpub->daysToLive() << endl;
135       }
136     }
137     if ( ! count )
138     {
139       cout << "*** Not in rpm database." << endl;
140     }
141     cout << endl;
142   }
143
144   ///////////////////////////////////////////////////////////////////
145   return 0;
146 }