1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/target/rpm/RpmDb.h
15 #ifndef ZYPP_TARGET_RPM_RPMDB_H
16 #define ZYPP_TARGET_RPM_RPMDB_H
23 #include "zypp/Pathname.h"
24 #include "zypp/ExternalProgram.h"
26 #include "zypp/Package.h"
27 #include "zypp/Source.h"
28 #include "zypp/KeyRing.h"
30 #include "zypp/target/rpm/RpmHeader.h"
31 #include "zypp/target/rpm/RpmCallbacks.h"
32 #include "zypp/ZYppCallbacks.h"
41 ///////////////////////////////////////////////////////////////////
45 * @short Interface to the rpm program
47 class RpmDb : public base::ReferenceCounted, private base::NonCopyable
54 typedef class InstTargetError Error;
56 ///////////////////////////////////////////////////////////////////
60 ///////////////////////////////////////////////////////////////////
63 enum DbStateInfoBits {
64 DbSI_NO_INIT = 0x0000,
65 DbSI_HAVE_V4 = 0x0001,
66 DbSI_MADE_V4 = 0x0002,
67 DbSI_MODIFIED_V4 = 0x0004,
68 DbSI_HAVE_V3 = 0x0008,
69 DbSI_HAVE_V3TOV4 = 0x0010,
70 DbSI_MADE_V3TOV4 = 0x0020
73 friend std::ostream & operator<<( std::ostream & str, const DbStateInfoBits & obj );
75 void dbsi_set( DbStateInfoBits & val_r, const unsigned & bits_r ) const
77 val_r = (DbStateInfoBits)(val_r | bits_r);
79 void dbsi_clr( DbStateInfoBits & val_r, const unsigned & bits_r ) const
81 val_r = (DbStateInfoBits)(val_r & ~bits_r);
83 bool dbsi_has( const DbStateInfoBits & val_r, const unsigned & bits_r ) const
85 return( (val_r & bits_r) == bits_r );
91 DbStateInfoBits _dbStateInfo;
94 * Root directory for all operations.
99 * Directory that contains the rpmdb.
104 * Internal helper for @ref initDatabase.
106 * \throws RpmException
109 void internal_initDatabase( const Pathname & root_r, const Pathname & dbPath_r,
110 DbStateInfoBits & info_r );
113 * Remove the rpm4 database in dbdir_r and optionally any backup created
116 static void removeV4( const Pathname & dbdir_r, bool v3backup_r );
119 * Remove the rpm3 database in dbdir_r. Create a backup copy named
120 * packages.rpm3 if it does not already exist.
122 static void removeV3( const Pathname & dbdir_r, bool v3backup_r );
125 * Called before the database is modified by installPackage/removePackage.
126 * Invalidates Packages list and moves away any old database.
128 void modifyDatabase();
133 * Constructor. There's no rpmdb access until @ref initDatabase
144 * timestamp of the rpm database (last modification)
146 Date timestamp() const;
149 * @return Root directory for all operations (empty if not initialized).
151 const Pathname & root() const
157 * @return Directory that contains the rpmdb (empty if not initialized).
159 const Pathname & dbPath() const
165 * @return Whether we are initialized.
167 bool initialized() const
169 return( ! _root.empty() );
173 * Prepare access to the rpm database. Optional arguments may denote the
174 * root directory for all operations and the directory (below root) that
175 * contains the rpmdb (usg. you won't need to set this).
177 * On empty Pathnames the default is used:
180 * dbPath: /var/lib/rpm
183 * Calling initDatabase a second time with different arguments will return
184 * an error but leave the database in it's original state.
186 * Converting an old batabase is done if necessary. On update: The converted
187 * database will be removed by @ref closeDatabase, if it was not modified
188 * (no packages were installed or deleted). Otherwise the new database
189 * is kept, and the old one is removed.
191 * \throws RpmException
194 void initDatabase( Pathname root_r = Pathname(),
195 Pathname dbPath_r = Pathname() );
198 * Block further access to the rpm database and go back to uninitialized
199 * state. On update: Decides what to do with any converted database
200 * (see @ref initDatabase).
202 * \throws RpmException
205 void closeDatabase();
208 * Rebuild the rpm database (rpm --rebuilddb).
210 * \throws RpmException
213 void rebuildDatabase();
216 * Import ascii armored public key in file pubkey_r.
218 * \throws RpmException
221 void importPubkey( const Pathname & pubkey_r );
224 * Return the long ids of all installed public keys.
226 std::list<PublicKey> pubkeys() const;
229 * Return the edition of all installed public keys.
231 std::set<Edition> pubkeyEditions() const;
233 ///////////////////////////////////////////////////////////////////
235 // Cached RPM database retrieval via librpm.
237 ///////////////////////////////////////////////////////////////////
242 Packages & _packages;
244 std::set<std::string> _filerequires;
249 * @return Whether the list of installed packages is valid, or
250 * you'd better reread it. (<B>NOTE:</B> returns valid, if not
253 bool packagesValid() const;
256 * If necessary build, and return the list of all installed packages.
258 const std::list<Package::Ptr> & getPackages();
260 ///////////////////////////////////////////////////////////////////
262 // Direct RPM database retrieval via librpm.
264 ///////////////////////////////////////////////////////////////////
268 * return complete file list for installed package name_r (in FileInfo.filename)
269 * if edition_r != Edition::noedition, check for exact edition
270 * if full==true, fill all attributes of FileInfo
272 std::list<FileInfo> fileList( const std::string & name_r, const Edition & edition_r ) const;
275 * Return true if at least one package owns a certain file (name_r empty)
276 * Return true if package name_r owns file file_r (name_r nonempty).
278 bool hasFile( const std::string & file_r, const std::string & name_r = "" ) const;
281 * Return name of package owning file
282 * or empty string if no installed package owns file
284 std::string whoOwnsFile( const std::string & file_r ) const;
287 * Return true if at least one package provides a certain tag.
289 bool hasProvides( const std::string & tag_r ) const;
292 * Return true if at least one package requires a certain tag.
294 bool hasRequiredBy( const std::string & tag_r ) const;
297 * Return true if at least one package conflicts with a certain tag.
299 bool hasConflicts( const std::string & tag_r ) const;
302 * Return true if package is installed.
304 bool hasPackage( const std::string & name_r ) const;
307 * Return true if package is installed in a certain edition.
309 bool hasPackage( const std::string & name_r, const Edition & ed_r ) const;
312 * Get an installed packages data from rpmdb. Package is
313 * identified by name. Data returned via result are NULL,
314 * if packge is not installed (PMError is not set), or RPM database
315 * could not be read (PMError is set).
317 * \throws RpmException
319 * FIXME this and following comment
322 void getData( const std::string & name_r,
323 RpmHeader::constPtr & result_r ) const;
326 * Get an installed packages data from rpmdb. Package is
327 * identified by name and edition. Data returned via result are NULL,
328 * if packge is not installed (PMError is not set), or RPM database
329 * could not be read (PMError is set).
331 * \throws RpmException
334 void getData( const std::string & name_r, const Edition & ed_r,
335 RpmHeader::constPtr & result_r ) const;
339 * Create a package from RpmHeader
340 * return NULL on error
343 static Package::Ptr makePackageFromHeader( const RpmHeader::constPtr header, std::set<std::string> * filerequires, const Pathname & location, Source_Ref source );
345 ///////////////////////////////////////////////////////////////////
347 ///////////////////////////////////////////////////////////////////
350 * iterates through zypp keyring and import all non existant keys
353 void importZyppKeyRingTrustedKeys();
355 * insert all rpm trusted keys into zypp trusted keyring
357 void exportTrustedKeysInZyppKeyRing();
360 * The connection to the rpm process.
362 ExternalProgram *process;
364 typedef std::vector<const char*> RpmArgVec;
367 * Run rpm with the specified arguments and handle stderr.
368 * @param n_opts The number of arguments
369 * @param options Array of the arguments, @ref n_opts elements
370 * @param stderr_disp How to handle stderr, merged with stdout by default
372 * \throws RpmException
375 void run_rpm( const RpmArgVec& options,
376 ExternalProgram::Stderr_Disposition stderr_disp =
377 ExternalProgram::Stderr_To_Stdout);
381 * Read a line from the general rpm query
383 bool systemReadLine(std::string &line);
386 * Return the exit status of the general rpm process,
387 * closing the connection if not already done.
392 * Forcably kill the system process
397 * The exit code of the rpm process, or -1 if not yet known.
401 /** /var/adm/backup */
402 Pathname _backuppath;
404 /** create package backups? */
405 bool _packagebackups;
407 /** whether <_root>/<WARNINGMAILPATH> was already created */
411 * handle rpm messages like "/etc/testrc saved as /etc/testrc.rpmorig"
413 * @param line rpm output starting with warning:
414 * @param name name of package, appears in subject line
415 * @param typemsg " saved as " or " created as "
416 * @param difffailmsg what to put into mail if diff failed, must contain two %s for the two files
417 * @param diffgenmsg what to put into mail if diff succeeded, must contain two %s for the two files
419 void processConfigFiles(const std::string& line,
420 const std::string& name,
422 const char* difffailmsg,
423 const char* diffgenmsg);
428 typedef std::set<std::string> FileList;
431 * Bits representing rpm installation options, useable as or
434 * @see installPackage(), removePackage()
438 RPMINST_NONE = 0x0000,
439 RPMINST_NODOCS = 0x0001,
440 RPMINST_NOSCRIPTS = 0x0002,
441 RPMINST_FORCE = 0x0004,
442 RPMINST_NODEPS = 0x0008,
443 RPMINST_IGNORESIZE = 0x0010,
444 RPMINST_JUSTDB = 0x0020,
445 RPMINST_NODIGEST = 0x0040,
446 RPMINST_NOSIGNATURE= 0x0080,
447 RPMINST_NOUPGRADE = 0x0100,
448 RPMINST_TEST = 0x0200
452 * checkPackage result
455 enum checkPackageResult
457 CHK_OK = 0, /*!< Signature is OK. */
458 CHK_NOTFOUND = 1, /*!< Signature is unknown type. */
459 CHK_FAIL = 2, /*!< Signature does not verify. */
460 CHK_NOTTRUSTED = 3, /*!< Signature is OK, but key is not trusted. */
461 CHK_NOKEY = 4, /*!< Public key is unavailable. */
462 CHK_ERROR = 5 /*!< File does not exist or can't be opened. */
466 * Check signature of rpm file on disk.
468 * @param filename which file to check
470 * @return checkPackageResult
472 checkPackageResult checkPackage( const Pathname & path_r );
474 /** install rpm package
476 * @param filename file to install
477 * @param flags which rpm options to use
481 * \throws RpmException
484 void installPackage (const Pathname& filename, unsigned flags = 0 );
486 /** remove rpm package
488 * @param name_r Name of the rpm package to remove.
489 * @param iflags which rpm options to use
493 * \throws RpmException
496 void removePackage(const std::string & name_r, unsigned flags = 0);
497 void removePackage(Package::constPtr package, unsigned flags = 0);
500 * get backup dir for rpm config files
503 Pathname getBackupPath (void)
509 * create tar.gz of all changed files in a Package
511 * @param packageName name of the Package to backup
515 bool backupPackage(const std::string& packageName);
518 * queries file for name and then calls above backupPackage
519 * function. For convenience.
521 * @param filename rpm file that is about to be installed
523 bool backupPackage(const Pathname& filename);
526 * set path where package backups are stored
530 void setBackupPath(const Pathname& path);
533 * whether to create package backups during install or
536 * @param yes true or false
538 void createPackageBackups(bool yes)
540 _packagebackups = yes;
544 * determine which files of an installed package have been
547 * @param fileList (output) where to store modified files
548 * @param packageName name of package to query
550 * @return false if package couln't be queried for some
553 bool queryChangedFiles(FileList & fileList, const std::string& packageName);
560 virtual std::ostream & dumpOn( std::ostream & str ) const;
563 void doRemovePackage( const std::string & name_r, unsigned flags, callback::SendReport<RpmRemoveReport> & report );
564 void doInstallPackage( const Pathname & filename, unsigned flags, callback::SendReport<RpmInstallReport> & report );
565 const std::list<Package::Ptr> & doGetPackages(callback::SendReport<ScanDBReport> & report);
566 void doRebuildDatabase(callback::SendReport<RebuildDBReport> & report);
572 } // namespace target
575 #endif // ZYPP_TARGET_RPM_RPMDB_H