Imported Upstream version 17.25.4
[platform/upstream/libzypp.git] / zypp / target / rpm / RpmDb.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/RpmDb.h
10  *
11 */
12
13 // -*- C++ -*-
14
15 #ifndef ZYPP_TARGET_RPM_RPMDB_H
16 #define ZYPP_TARGET_RPM_RPMDB_H
17
18 #include <iosfwd>
19 #include <list>
20 #include <vector>
21 #include <string>
22
23 #include <zypp/Pathname.h>
24 #include <zypp/ExternalProgram.h>
25
26 #include <zypp/Package.h>
27 #include <zypp/KeyRing.h>
28
29 #include <zypp/target/rpm/RpmFlags.h>
30 #include <zypp/target/rpm/RpmHeader.h>
31 #include <zypp/target/rpm/RpmCallbacks.h>
32 #include <zypp/ZYppCallbacks.h>
33
34 namespace zypp
35 {
36 namespace target
37 {
38 namespace rpm
39 {
40
41 ///////////////////////////////////////////////////////////////////
42 //
43 //      CLASS NAME : RpmDb
44 /**
45  * @short Interface to the rpm program
46  **/
47 class RpmDb : public base::ReferenceCounted, private base::NonCopyable
48 {
49 public:
50
51   /**
52    * Default error class
53    **/
54   typedef class InstTargetError Error;
55
56   ///////////////////////////////////////////////////////////////////
57   //
58   // INITALISATION
59   //
60   ///////////////////////////////////////////////////////////////////
61 private:
62
63   /**
64    * Root directory for all operations.
65    **/
66   Pathname _root;
67
68   /**
69    * Directory that contains the rpmdb.
70    **/
71   Pathname _dbPath;
72
73 public:
74
75   /**
76    * Constructor. There's no rpmdb access until @ref initDatabase
77    * was called.
78    **/
79   RpmDb();
80
81   /**
82    * Destructor.
83    **/
84   ~RpmDb();
85
86   /**
87    * @return Root directory for all operations (empty if not initialized).
88    **/
89   const Pathname & root() const
90   {
91     return _root;
92   }
93
94   /**
95    * @return Directory that contains the rpmdb (empty if not initialized).
96    **/
97   const Pathname & dbPath() const
98   {
99     return _dbPath;
100   }
101
102   /**
103    * @return Whether we are initialized.
104    **/
105   bool initialized() const
106   {
107     return( ! _root.empty() );
108   }
109
110   /**
111    * Prepare access to the rpm database below \a root_r.
112    *
113    * An optional argument denotes the root directory for all operations. If
114    * an empty Pathname is given the default (\c/) is used.
115    *
116    * Calling initDatabase a second time with different arguments will return
117    * an error but leave the database in it's original state.
118    *
119    * If the  database already exists and \c doRebuild_r is true,
120    * \ref rebuildDatabase is called.
121    *
122    * \throws RpmException
123    **/
124   void initDatabase( Pathname root_r = Pathname(), bool doRebuild_r = false );
125
126   /**
127    * Block further access to the rpm database and go back to uninitialized
128    * state. On update: Decides what to do with any converted database
129    * (see @ref initDatabase).
130    *
131    * \throws RpmException
132    *
133    **/
134   void closeDatabase();
135
136   /**
137    * Rebuild the rpm database (rpm --rebuilddb).
138    *
139    * \throws RpmException
140    *
141    **/
142   void rebuildDatabase();
143
144   /**
145    * Import ascii armored public key in file pubkey_r.
146    *
147    * \throws RpmException
148    *
149    **/
150   void importPubkey( const PublicKey & pubkey_r );
151
152   /**
153    * Remove a public key from the rpm database
154    *
155    * \throws RpmException
156    *
157    **/
158   void removePubkey( const PublicKey & pubkey_r );
159
160   /**
161    * Return the long ids of all installed public keys.
162    **/
163   std::list<PublicKey> pubkeys() const;
164
165   /**
166    * Return the edition of all installed public keys.
167    **/
168   std::set<Edition> pubkeyEditions() const;
169
170   ///////////////////////////////////////////////////////////////////
171   //
172   // Direct RPM database retrieval via librpm.
173   //
174   ///////////////////////////////////////////////////////////////////
175 public:
176
177   /**
178    * return complete file list for installed package name_r (in FileInfo.filename)
179    * if edition_r != Edition::noedition, check for exact edition
180    * if full==true, fill all attributes of FileInfo
181    **/
182   std::list<FileInfo> fileList( const std::string & name_r, const Edition & edition_r ) const;
183
184   /**
185    * Return true if at least one package owns a certain file (name_r empty)
186    * Return true if package name_r owns file file_r (name_r nonempty).
187    **/
188   bool hasFile( const std::string & file_r, const std::string & name_r = "" ) const;
189
190   /**
191    * Return name of package owning file
192    * or empty string if no installed package owns file
193    **/
194   std::string whoOwnsFile( const std::string & file_r ) const;
195
196   /**
197    * Return true if at least one package provides a certain tag.
198    **/
199   bool hasProvides( const std::string & tag_r ) const;
200
201   /**
202    * Return true if at least one package requires a certain tag.
203    **/
204   bool hasRequiredBy( const std::string & tag_r ) const;
205
206   /**
207    * Return true if at least one package conflicts with a certain tag.
208    **/
209   bool hasConflicts( const std::string & tag_r ) const;
210
211   /**
212    * Return true if package is installed.
213    **/
214   bool hasPackage( const std::string & name_r ) const;
215
216   /**
217    * Return true if package is installed in a certain edition.
218    **/
219   bool hasPackage( const std::string & name_r, const Edition & ed_r ) const;
220
221   /**
222    * Get an installed packages data from rpmdb. Package is
223    * identified by name. Data returned via result are NULL,
224    * if packge is not installed (PMError is not set), or RPM database
225    * could not be read (PMError is set).
226    *
227    * \throws RpmException
228    *
229    * FIXME this and following comment
230    *
231    **/
232   void getData( const std::string & name_r,
233                 RpmHeader::constPtr & result_r ) const;
234
235   /**
236    * Get an installed packages data from rpmdb. Package is
237    * identified by name and edition. Data returned via result are NULL,
238    * if packge is not installed (PMError is not set), or RPM database
239    * could not be read (PMError is set).
240    *
241    * \throws RpmException
242    *
243    **/
244   void getData( const std::string & name_r, const Edition & ed_r,
245                 RpmHeader::constPtr & result_r ) const;
246
247   ///////////////////////////////////////////////////////////////////
248   //
249   ///////////////////////////////////////////////////////////////////
250 public:
251   /** Sync mode for \ref syncTrustedKeys */
252   enum SyncTrustedKeyBits
253   {
254     SYNC_TO_KEYRING     = 1<<0, //!< export rpm trusted keys into zypp trusted keyring
255     SYNC_FROM_KEYRING   = 1<<1, //!< import zypp trusted keys into rpm database.
256     SYNC_BOTH           = SYNC_TO_KEYRING | SYNC_FROM_KEYRING
257   };
258   /**
259    * Sync trusted keys stored in rpm database and zypp trusted keyring.
260    */
261   void syncTrustedKeys( SyncTrustedKeyBits mode_r = SYNC_BOTH );
262   /**
263    * iterates through zypp keyring and import all non existant keys
264    * into rpm keyring
265    */
266   void importZyppKeyRingTrustedKeys();
267   /**
268    * insert all rpm trusted keys into zypp trusted keyring
269    */
270   void exportTrustedKeysInZyppKeyRing();
271
272 private:
273   /**
274    * The connection to the rpm process.
275   */
276   ExternalProgram *process;
277
278   typedef std::vector<const char*> RpmArgVec;
279
280   /**
281    * Run rpm with the specified arguments and handle stderr.
282    * @param n_opts The number of arguments
283    * @param options Array of the arguments, @ref n_opts elements
284    * @param stderr_disp How to handle stderr, merged with stdout by default
285    *
286    * \throws RpmException
287    *
288    **/
289   void run_rpm( const RpmArgVec& options,
290                 ExternalProgram::Stderr_Disposition stderr_disp =
291                   ExternalProgram::Stderr_To_Stdout);
292
293
294   /**
295    * Read a line from the general rpm query
296   */
297   bool systemReadLine(std::string &line);
298
299   /**
300    * Return the exit status of the general rpm process,
301    * closing the connection if not already done.
302   */
303   int systemStatus();
304
305   /**
306    * Forcably kill the system process
307   */
308   void systemKill();
309
310   /**
311    * The exit code of the rpm process, or -1 if not yet known.
312   */
313   int exit_code;
314
315   /**
316    * Error message from running rpm as external program.
317    * Use only if something fail.
318    */
319   std::string error_message;
320
321   /** /var/adm/backup */
322   Pathname _backuppath;
323
324   /** create package backups? */
325   bool _packagebackups;
326
327   /**
328    * handle rpm messages like "/etc/testrc saved as /etc/testrc.rpmorig"
329    *
330    * @param line rpm output starting with warning:
331    * @param name name of package, appears in subject line
332    * @param typemsg " saved as " or " created as "
333    * @param difffailmsg what to put into mail if diff failed, must contain two %s for the two files
334    * @param diffgenmsg what to put into mail if diff succeeded, must contain two %s for the two files
335    * */
336   void processConfigFiles(const std::string& line,
337                           const std::string& name,
338                           const char* typemsg,
339                           const char* difffailmsg,
340                           const char* diffgenmsg);
341
342
343 public:
344
345   typedef std::set<std::string> FileList;
346
347   /**
348    * checkPackage result
349    * @see checkPackage
350    * */
351   enum CheckPackageResult
352   {
353     CHK_OK            = 0, /*!< Signature is OK. */
354     CHK_NOTFOUND      = 1, /*!< Signature is unknown type. */
355     CHK_FAIL          = 2, /*!< Signature does not verify. */
356     CHK_NOTTRUSTED    = 3, /*!< Signature is OK, but key is not trusted. */
357     CHK_NOKEY         = 4, /*!< Public key is unavailable. */
358     CHK_ERROR         = 5, /*!< File does not exist or can't be opened. */
359     CHK_NOSIG         = 6, /*!< File has no gpg signature (only digests). */
360   };
361
362   /** Detailed rpm signature check log messages
363    * A single multiline message if \ref CHK_OK. Otherwise each message line
364    * together with it's \ref CheckPackageResult.
365    */
366   struct CheckPackageDetail : std::vector<std::pair<CheckPackageResult,std::string>>
367   {};
368
369   /**
370    * Check signature of rpm file on disk (legacy version returning CHK_OK if file is unsigned, like 'rpm -K')
371    *
372    * @param path_r which file to check
373    * @param detail_r Return detailed rpm log messages
374    *
375    * @return CheckPackageResult (CHK_OK if file is unsigned)
376    *
377    * \see also \ref checkPackageSignature
378    */
379   CheckPackageResult checkPackage( const Pathname & path_r, CheckPackageDetail & detail_r );
380   /** \overload Ignoring the \a details_r */
381   CheckPackageResult checkPackage( const Pathname & path_r );
382
383   /**
384    * Check signature of rpm file on disk (strict check returning CHK_NOSIG if file is unsigned).
385    *
386    * @param path_r which file to check
387    * @param detail_r Return detailed rpm log messages
388    *
389    * @return CheckPackageResult (CHK_NOSIG if file is unsigned)
390    *
391    * \see also \ref checkPackage
392    */
393   CheckPackageResult checkPackageSignature( const Pathname & path_r, CheckPackageDetail & detail_r );
394
395   /** install rpm package
396    *
397    * @param filename file to install
398    * @param flags which rpm options to use
399    *
400    * @return success
401    *
402    * \throws RpmException
403    *
404    * */
405   void installPackage ( const Pathname & filename, RpmInstFlags flags = RPMINST_NONE );
406
407   /** remove rpm package
408    *
409    * @param name_r Name of the rpm package to remove.
410    * @param iflags which rpm options to use
411    *
412    * @return success
413    *
414    * \throws RpmException
415    *
416    * */
417   void removePackage( const std::string & name_r, RpmInstFlags flags = RPMINST_NONE );
418   void removePackage( Package::constPtr package, RpmInstFlags flags = RPMINST_NONE );
419
420   /**
421    * get backup dir for rpm config files
422    *
423    * */
424   Pathname getBackupPath (void)
425   {
426     return _backuppath;
427   }
428
429   /**
430    * create tar.gz of all changed files in a Package
431    *
432    * @param packageName name of the Package to backup
433    *
434    * @see setBackupPath
435    * */
436   bool backupPackage(const std::string& packageName);
437
438   /**
439    * queries file for name and then calls above backupPackage
440    * function. For convenience.
441    *
442    * @param filename rpm file that is about to be installed
443    * */
444   bool backupPackage(const Pathname& filename);
445
446   /**
447    * set path where package backups are stored
448    *
449    * @see backupPackage
450    * */
451   void setBackupPath(const Pathname& path);
452
453   /**
454    * whether to create package backups during install or
455    * removal
456    *
457    * @param yes true or false
458    * */
459   void createPackageBackups(bool yes)
460   {
461     _packagebackups = yes;
462   }
463
464   /**
465    * determine which files of an installed package have been
466    * modified.
467    *
468    * @param fileList (output) where to store modified files
469    * @param packageName name of package to query
470    *
471    * @return false if package couln't be queried for some
472    * reason
473    * */
474   bool queryChangedFiles(FileList & fileList, const std::string& packageName);
475
476 public:
477
478   /**
479    * Dump debug info.
480    **/
481   virtual std::ostream & dumpOn( std::ostream & str ) const;
482
483 protected:
484   void doRemovePackage( const std::string & name_r, RpmInstFlags flags, callback::SendReport<RpmRemoveReport> & report );
485   void doInstallPackage( const Pathname & filename, RpmInstFlags flags, callback::SendReport<RpmInstallReport> & report );
486   void doRebuildDatabase(callback::SendReport<RebuildDBReport> & report);
487 };
488
489 /** \relates RpmDb::CheckPackageResult Stream output */
490 std::ostream & operator<<( std::ostream & str, RpmDb::CheckPackageResult obj );
491
492 /** \relates RpmDb::checkPackageDetail Stream output */
493 std::ostream & operator<<( std::ostream & str, const RpmDb::CheckPackageDetail & obj );
494
495 } // namespace rpm
496 } // namespace target
497 } // namespace zypp
498
499 #endif // ZYPP_TARGET_RPM_RPMDB_H