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/KeyRing.h"
29 #include "zypp/target/rpm/RpmHeader.h"
30 #include "zypp/target/rpm/RpmCallbacks.h"
31 #include "zypp/ZYppCallbacks.h"
40 ///////////////////////////////////////////////////////////////////
44 * @short Interface to the rpm program
46 class RpmDb : public base::ReferenceCounted, private base::NonCopyable
53 typedef class InstTargetError Error;
55 ///////////////////////////////////////////////////////////////////
59 ///////////////////////////////////////////////////////////////////
62 enum DbStateInfoBits {
63 DbSI_NO_INIT = 0x0000,
64 DbSI_HAVE_V4 = 0x0001,
65 DbSI_MADE_V4 = 0x0002,
66 DbSI_MODIFIED_V4 = 0x0004,
67 DbSI_HAVE_V3 = 0x0008,
68 DbSI_HAVE_V3TOV4 = 0x0010,
69 DbSI_MADE_V3TOV4 = 0x0020
72 friend std::ostream & operator<<( std::ostream & str, const DbStateInfoBits & obj );
74 void dbsi_set( DbStateInfoBits & val_r, const unsigned & bits_r ) const
76 val_r = (DbStateInfoBits)(val_r | bits_r);
78 void dbsi_clr( DbStateInfoBits & val_r, const unsigned & bits_r ) const
80 val_r = (DbStateInfoBits)(val_r & ~bits_r);
82 bool dbsi_has( const DbStateInfoBits & val_r, const unsigned & bits_r ) const
84 return( (val_r & bits_r) == bits_r );
90 DbStateInfoBits _dbStateInfo;
93 * Root directory for all operations.
98 * Directory that contains the rpmdb.
103 * Internal helper for @ref initDatabase.
105 * \throws RpmException
108 void internal_initDatabase( const Pathname & root_r, const Pathname & dbPath_r,
109 DbStateInfoBits & info_r );
112 * Remove the rpm4 database in dbdir_r and optionally any backup created
115 static void removeV4( const Pathname & dbdir_r, bool v3backup_r );
118 * Remove the rpm3 database in dbdir_r. Create a backup copy named
119 * packages.rpm3 if it does not already exist.
121 static void removeV3( const Pathname & dbdir_r, bool v3backup_r );
124 * Called before the database is modified by installPackage/removePackage.
125 * Invalidates Packages list and moves away any old database.
127 void modifyDatabase();
132 * Constructor. There's no rpmdb access until @ref initDatabase
143 * timestamp of the rpm database (last modification)
145 Date timestamp() const;
148 * @return Root directory for all operations (empty if not initialized).
150 const Pathname & root() const
156 * @return Directory that contains the rpmdb (empty if not initialized).
158 const Pathname & dbPath() const
164 * @return Whether we are initialized.
166 bool initialized() const
168 return( ! _root.empty() );
172 * Prepare access to the rpm database. Optional arguments may denote the
173 * root directory for all operations and the directory (below root) that
174 * contains the rpmdb (usg. you won't need to set this).
176 * On empty Pathnames the default is used:
179 * dbPath: /var/lib/rpm
182 * Calling initDatabase a second time with different arguments will return
183 * an error but leave the database in it's original state.
185 * Converting an old batabase is done if necessary. On update: The converted
186 * database will be removed by @ref closeDatabase, if it was not modified
187 * (no packages were installed or deleted). Otherwise the new database
188 * is kept, and the old one is removed.
190 * \throws RpmException
193 void initDatabase( Pathname root_r = Pathname(),
194 Pathname dbPath_r = Pathname() );
197 * Block further access to the rpm database and go back to uninitialized
198 * state. On update: Decides what to do with any converted database
199 * (see @ref initDatabase).
201 * \throws RpmException
204 void closeDatabase();
207 * Rebuild the rpm database (rpm --rebuilddb).
209 * \throws RpmException
212 void rebuildDatabase();
215 * Import ascii armored public key in file pubkey_r.
217 * \throws RpmException
220 void importPubkey( const PublicKey & pubkey_r );
223 * Return the long ids of all installed public keys.
225 std::list<PublicKey> pubkeys() const;
228 * Return the edition of all installed public keys.
230 std::set<Edition> pubkeyEditions() const;
232 ///////////////////////////////////////////////////////////////////
234 // Cached RPM database retrieval via librpm.
236 ///////////////////////////////////////////////////////////////////
241 Packages & _packages;
243 std::set<std::string> _filerequires;
248 * @return Whether the list of installed packages is valid, or
249 * you'd better reread it. (<B>NOTE:</B> returns valid, if not
252 bool packagesValid() const;
255 * If necessary build, and return the list of all installed packages.
257 const std::list<Package::Ptr> & getPackages();
259 ///////////////////////////////////////////////////////////////////
261 // Direct RPM database retrieval via librpm.
263 ///////////////////////////////////////////////////////////////////
267 * return complete file list for installed package name_r (in FileInfo.filename)
268 * if edition_r != Edition::noedition, check for exact edition
269 * if full==true, fill all attributes of FileInfo
271 std::list<FileInfo> fileList( const std::string & name_r, const Edition & edition_r ) const;
274 * Return true if at least one package owns a certain file (name_r empty)
275 * Return true if package name_r owns file file_r (name_r nonempty).
277 bool hasFile( const std::string & file_r, const std::string & name_r = "" ) const;
280 * Return name of package owning file
281 * or empty string if no installed package owns file
283 std::string whoOwnsFile( const std::string & file_r ) const;
286 * Return true if at least one package provides a certain tag.
288 bool hasProvides( const std::string & tag_r ) const;
291 * Return true if at least one package requires a certain tag.
293 bool hasRequiredBy( const std::string & tag_r ) const;
296 * Return true if at least one package conflicts with a certain tag.
298 bool hasConflicts( const std::string & tag_r ) const;
301 * Return true if package is installed.
303 bool hasPackage( const std::string & name_r ) const;
306 * Return true if package is installed in a certain edition.
308 bool hasPackage( const std::string & name_r, const Edition & ed_r ) const;
311 * Get an installed packages data from rpmdb. Package is
312 * identified by name. Data returned via result are NULL,
313 * if packge is not installed (PMError is not set), or RPM database
314 * could not be read (PMError is set).
316 * \throws RpmException
318 * FIXME this and following comment
321 void getData( const std::string & name_r,
322 RpmHeader::constPtr & result_r ) const;
325 * Get an installed packages data from rpmdb. Package is
326 * identified by name and edition. Data returned via result are NULL,
327 * if packge is not installed (PMError is not set), or RPM database
328 * could not be read (PMError is set).
330 * \throws RpmException
333 void getData( const std::string & name_r, const Edition & ed_r,
334 RpmHeader::constPtr & result_r ) const;
338 * Create a package from RpmHeader
339 * return NULL on error
342 static Package::Ptr makePackageFromHeader( const RpmHeader::constPtr header,
343 std::set<std::string> * filerequires,
344 const Pathname & location, Repository repo );
346 ///////////////////////////////////////////////////////////////////
348 ///////////////////////////////////////////////////////////////////
351 * iterates through zypp keyring and import all non existant keys
354 void importZyppKeyRingTrustedKeys();
356 * insert all rpm trusted keys into zypp trusted keyring
358 void exportTrustedKeysInZyppKeyRing();
361 * The connection to the rpm process.
363 ExternalProgram *process;
365 typedef std::vector<const char*> RpmArgVec;
368 * Run rpm with the specified arguments and handle stderr.
369 * @param n_opts The number of arguments
370 * @param options Array of the arguments, @ref n_opts elements
371 * @param stderr_disp How to handle stderr, merged with stdout by default
373 * \throws RpmException
376 void run_rpm( const RpmArgVec& options,
377 ExternalProgram::Stderr_Disposition stderr_disp =
378 ExternalProgram::Stderr_To_Stdout);
382 * Read a line from the general rpm query
384 bool systemReadLine(std::string &line);
387 * Return the exit status of the general rpm process,
388 * closing the connection if not already done.
393 * Forcably kill the system process
398 * The exit code of the rpm process, or -1 if not yet known.
402 /** /var/adm/backup */
403 Pathname _backuppath;
405 /** create package backups? */
406 bool _packagebackups;
408 /** whether <_root>/<WARNINGMAILPATH> was already created */
412 * handle rpm messages like "/etc/testrc saved as /etc/testrc.rpmorig"
414 * @param line rpm output starting with warning:
415 * @param name name of package, appears in subject line
416 * @param typemsg " saved as " or " created as "
417 * @param difffailmsg what to put into mail if diff failed, must contain two %s for the two files
418 * @param diffgenmsg what to put into mail if diff succeeded, must contain two %s for the two files
420 void processConfigFiles(const std::string& line,
421 const std::string& name,
423 const char* difffailmsg,
424 const char* diffgenmsg);
429 typedef std::set<std::string> FileList;
432 * Bits representing rpm installation options, useable as or
435 * @see installPackage(), removePackage()
439 RPMINST_NONE = 0x0000,
440 RPMINST_NODOCS = 0x0001,
441 RPMINST_NOSCRIPTS = 0x0002,
442 RPMINST_FORCE = 0x0004,
443 RPMINST_NODEPS = 0x0008,
444 RPMINST_IGNORESIZE = 0x0010,
445 RPMINST_JUSTDB = 0x0020,
446 RPMINST_NODIGEST = 0x0040,
447 RPMINST_NOSIGNATURE= 0x0080,
448 RPMINST_NOUPGRADE = 0x0100,
449 RPMINST_TEST = 0x0200
453 * checkPackage result
456 enum checkPackageResult
458 CHK_OK = 0, /*!< Signature is OK. */
459 CHK_NOTFOUND = 1, /*!< Signature is unknown type. */
460 CHK_FAIL = 2, /*!< Signature does not verify. */
461 CHK_NOTTRUSTED = 3, /*!< Signature is OK, but key is not trusted. */
462 CHK_NOKEY = 4, /*!< Public key is unavailable. */
463 CHK_ERROR = 5 /*!< File does not exist or can't be opened. */
467 * Check signature of rpm file on disk.
469 * @param filename which file to check
471 * @return checkPackageResult
473 checkPackageResult checkPackage( const Pathname & path_r );
475 /** install rpm package
477 * @param filename file to install
478 * @param flags which rpm options to use
482 * \throws RpmException
485 void installPackage (const Pathname& filename, unsigned flags = 0 );
487 /** remove rpm package
489 * @param name_r Name of the rpm package to remove.
490 * @param iflags which rpm options to use
494 * \throws RpmException
497 void removePackage(const std::string & name_r, unsigned flags = 0);
498 void removePackage(Package::constPtr package, unsigned flags = 0);
501 * get backup dir for rpm config files
504 Pathname getBackupPath (void)
510 * create tar.gz of all changed files in a Package
512 * @param packageName name of the Package to backup
516 bool backupPackage(const std::string& packageName);
519 * queries file for name and then calls above backupPackage
520 * function. For convenience.
522 * @param filename rpm file that is about to be installed
524 bool backupPackage(const Pathname& filename);
527 * set path where package backups are stored
531 void setBackupPath(const Pathname& path);
534 * whether to create package backups during install or
537 * @param yes true or false
539 void createPackageBackups(bool yes)
541 _packagebackups = yes;
545 * determine which files of an installed package have been
548 * @param fileList (output) where to store modified files
549 * @param packageName name of package to query
551 * @return false if package couln't be queried for some
554 bool queryChangedFiles(FileList & fileList, const std::string& packageName);
561 virtual std::ostream & dumpOn( std::ostream & str ) const;
564 void doRemovePackage( const std::string & name_r, unsigned flags, callback::SendReport<RpmRemoveReport> & report );
565 void doInstallPackage( const Pathname & filename, unsigned flags, callback::SendReport<RpmInstallReport> & report );
566 const std::list<Package::Ptr> & doGetPackages(callback::SendReport<ScanDBReport> & report);
567 void doRebuildDatabase(callback::SendReport<RebuildDBReport> & report);
573 } // namespace target
576 #endif // ZYPP_TARGET_RPM_RPMDB_H