libzypp  10.5.0
Applydeltarpm.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/String.h"
00016 #include "zypp/base/Regex.h"
00017 #include "zypp/repo/Applydeltarpm.h"
00018 #include "zypp/ExternalProgram.h"
00019 #include "zypp/AutoDispose.h"
00020 #include "zypp/PathInfo.h"
00021 #include "zypp/TriBool.h"
00022 
00023 using std::endl;
00024 
00026 namespace zypp
00027 { 
00028 
00029   namespace applydeltarpm
00030   { 
00031 
00032     namespace
00033     { 
00034 
00035       const Pathname   applydeltarpm_prog( "/usr/bin/applydeltarpm" );
00036       const str::regex applydeltarpm_tick ( "([0-9]+) percent finished" );
00037 
00038       /******************************************************************
00039        **
00040        **       FUNCTION NAME : applydeltarpm
00041        **       FUNCTION TYPE : bool
00042       */
00043       bool applydeltarpm( const char *const argv_r[],
00044                           const Progress & report_r  = Progress() )
00045       {
00046         ExternalProgram prog( argv_r, ExternalProgram::Stderr_To_Stdout );
00047         str::smatch what;
00048         for ( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
00049           {
00050             if ( report_r && str::regex_match( line, what, applydeltarpm_tick ) )
00051               {
00052                 report_r( str::strtonum<unsigned>( what[1] ) );
00053               }
00054             else
00055               DBG << "Applydeltarpm : " << line;
00056         }
00057         return( prog.close() == 0 );
00058       }
00059 
00061     } // namespace
00063 
00064     /******************************************************************
00065      **
00066      ** FUNCTION NAME : haveApplydeltarpm
00067      ** FUNCTION TYPE : bool
00068     */
00069     bool haveApplydeltarpm()
00070     {
00071       // To track changes in availability of applydeltarpm.
00072       static TriBool _last = indeterminate;
00073       PathInfo prog( applydeltarpm_prog );
00074       bool have = prog.isX();
00075       if ( _last == have )
00076         ; // TriBool! 'else' is not '_last != have'
00077       else
00078         {
00079           // _last is 'indeterminate' or '!have'
00080           if ( (_last = have) )
00081             MIL << "Found executable " << prog << endl;
00082           else
00083             WAR << "No executable " << prog << endl;
00084         }
00085       return _last;
00086     }
00087 
00088     /******************************************************************
00089      **
00090      ** FUNCTION NAME : check
00091      ** FUNCTION TYPE : bool
00092     */
00093     bool check( const std::string & sequenceinfo_r, bool quick_r )
00094     {
00095       if ( ! haveApplydeltarpm() )
00096         return false;
00097 
00098       const char *const argv[] = {
00099         "/usr/bin/applydeltarpm",
00100         ( quick_r ? "-C" : "-c" ),
00101         "-s", sequenceinfo_r.c_str(),
00102         NULL
00103       };
00104 
00105       return( applydeltarpm( argv ) );
00106     }
00107 
00108     /******************************************************************
00109      **
00110      ** FUNCTION NAME : check
00111      ** FUNCTION TYPE : bool
00112     */
00113     bool check( const Pathname & delta_r, bool quick_r )
00114     {
00115       if ( ! haveApplydeltarpm() )
00116         return false;
00117 
00118       const char *const argv[] = {
00119         "/usr/bin/applydeltarpm",
00120         ( quick_r ? "-C" : "-c" ),
00121         delta_r.asString().c_str(),
00122         NULL
00123       };
00124 
00125       return( applydeltarpm( argv ) );
00126     }
00127 
00128     /******************************************************************
00129      **
00130      ** FUNCTION NAME : provide
00131      ** FUNCTION TYPE : bool
00132     */
00133     bool provide( const Pathname & delta_r, const Pathname & new_r,
00134                   const Progress & report_r )
00135     {
00136       // cleanup on error
00137       AutoDispose<const Pathname> guard( new_r, filesystem::unlink );
00138 
00139       if ( ! haveApplydeltarpm() )
00140         return false;
00141 
00142       const char *const argv[] = {
00143         "/usr/bin/applydeltarpm",
00144         "-p", "-p", // twice to get percent output one per line
00145         delta_r.asString().c_str(),
00146         new_r.asString().c_str(),
00147         NULL
00148       };
00149 
00150       if ( ! applydeltarpm( argv, report_r ) )
00151         return false;
00152 
00153       guard.resetDispose(); // no cleanup on success
00154       return true;
00155     }
00156 
00157     /******************************************************************
00158      **
00159      ** FUNCTION NAME : provide
00160      ** FUNCTION TYPE : bool
00161     */
00162     bool provide( const Pathname & old_r, const Pathname & delta_r,
00163                   const Pathname & new_r,
00164                   const Progress & report_r )
00165     {
00166       // cleanup on error
00167       AutoDispose<const Pathname> guard( new_r, filesystem::unlink );
00168 
00169       if ( ! haveApplydeltarpm() )
00170         return false;
00171 
00172       const char *const argv[] = {
00173         "/usr/bin/applydeltarpm",
00174         "-p", "-p", // twice to get percent output one per line
00175         "-r", old_r.asString().c_str(),
00176         delta_r.asString().c_str(),
00177         new_r.asString().c_str(),
00178         NULL
00179       };
00180 
00181       if ( ! applydeltarpm( argv, report_r ) )
00182         return false;
00183 
00184       guard.resetDispose(); // no cleanup on success
00185       return true;
00186     }
00187 
00189   } // namespace applydeltarpm
00192 } // namespace zypp