ccd3e1aeecf3c77c4cea315fb87822558ad1f638
[platform/upstream/libzypp.git] / zypp / repo / Applydeltarpm.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/source/Applydeltarpm.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/Logger.h"
15 #include "zypp/base/String.h"
16 #include "zypp/repo/Applydeltarpm.h"
17 #include "zypp/ExternalProgram.h"
18 #include "zypp/AutoDispose.h"
19 #include "zypp/PathInfo.h"
20 #include "zypp/TriBool.h"
21
22 using std::endl;
23
24 ///////////////////////////////////////////////////////////////////
25 namespace zypp
26 { /////////////////////////////////////////////////////////////////
27   ///////////////////////////////////////////////////////////////////
28   namespace applydeltarpm
29   { /////////////////////////////////////////////////////////////////
30     ///////////////////////////////////////////////////////////////////
31     namespace
32     { /////////////////////////////////////////////////////////////////
33
34       const Pathname   applydeltarpm_prog( "/usr/bin/applydeltarpm" );
35       const str::regex applydeltarpm_tick ( "([0-9]+) percent finished" );
36
37       /******************************************************************
38        **
39        **       FUNCTION NAME : applydeltarpm
40        **       FUNCTION TYPE : bool
41       */
42       bool applydeltarpm( const char *const argv_r[],
43                           const Progress & report_r  = Progress() )
44       {
45         ExternalProgram prog( argv_r, ExternalProgram::Stderr_To_Stdout );
46         str::smatch what;
47         for ( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
48           {
49             if ( report_r && str::regex_search( line, what, applydeltarpm_tick ) )
50               {
51                 report_r( str::strtonum<unsigned>( what[1] ) );
52               }
53             else
54               DBG << "Applydeltarpm : " << line;
55         }
56         return( prog.close() == 0 );
57       }
58
59       /////////////////////////////////////////////////////////////////
60     } // namespace
61     ///////////////////////////////////////////////////////////////////
62
63     /******************************************************************
64      **
65      ** FUNCTION NAME : haveApplydeltarpm
66      ** FUNCTION TYPE : bool
67     */
68     bool haveApplydeltarpm()
69     {
70       // To track changes in availability of applydeltarpm.
71       static TriBool _last = indeterminate;
72       PathInfo prog( applydeltarpm_prog );
73       bool have = prog.isX();
74       if ( _last == have )
75         ; // TriBool! 'else' is not '_last != have'
76       else
77         {
78           // _last is 'indeterminate' or '!have'
79           if ( (_last = have) )
80             MIL << "Found executable " << prog << endl;
81           else
82             WAR << "No executable " << prog << endl;
83         }
84       return _last;
85     }
86
87     /******************************************************************
88      **
89      ** FUNCTION NAME : check
90      ** FUNCTION TYPE : bool
91     */
92     bool check( const std::string & sequenceinfo_r, bool quick_r )
93     {
94       if ( ! haveApplydeltarpm() )
95         return false;
96
97       const char *const argv[] = {
98         "/usr/bin/applydeltarpm",
99         ( quick_r ? "-C" : "-c" ),
100         "-s", sequenceinfo_r.c_str(),
101         NULL
102       };
103
104       return( applydeltarpm( argv ) );
105     }
106
107     /******************************************************************
108      **
109      ** FUNCTION NAME : check
110      ** FUNCTION TYPE : bool
111     */
112     bool check( const Pathname & delta_r, bool quick_r )
113     {
114       if ( ! haveApplydeltarpm() )
115         return false;
116
117       const char *const argv[] = {
118         "/usr/bin/applydeltarpm",
119         ( quick_r ? "-C" : "-c" ),
120         delta_r.asString().c_str(),
121         NULL
122       };
123
124       return( applydeltarpm( argv ) );
125     }
126
127     /******************************************************************
128      **
129      ** FUNCTION NAME : provide
130      ** FUNCTION TYPE : bool
131     */
132     bool provide( const Pathname & delta_r, const Pathname & new_r,
133                   const Progress & report_r )
134     {
135       // cleanup on error
136       AutoDispose<const Pathname> guard( new_r, filesystem::unlink );
137
138       if ( ! haveApplydeltarpm() )
139         return false;
140
141       const char *const argv[] = {
142         "/usr/bin/applydeltarpm",
143         "-p", "-p", // twice to get percent output one per line
144         delta_r.asString().c_str(),
145         new_r.asString().c_str(),
146         NULL
147       };
148
149       if ( ! applydeltarpm( argv, report_r ) )
150         return false;
151
152       guard.resetDispose(); // no cleanup on success
153       return true;
154     }
155
156     /******************************************************************
157      **
158      ** FUNCTION NAME : provide
159      ** FUNCTION TYPE : bool
160     */
161     bool provide( const Pathname & old_r, const Pathname & delta_r,
162                   const Pathname & new_r,
163                   const Progress & report_r )
164     {
165       // cleanup on error
166       AutoDispose<const Pathname> guard( new_r, filesystem::unlink );
167
168       if ( ! haveApplydeltarpm() )
169         return false;
170
171       const char *const argv[] = {
172         "/usr/bin/applydeltarpm",
173         "-p", "-p", // twice to get percent output one per line
174         "-r", old_r.asString().c_str(),
175         delta_r.asString().c_str(),
176         new_r.asString().c_str(),
177         NULL
178       };
179
180       if ( ! applydeltarpm( argv, report_r ) )
181         return false;
182
183       guard.resetDispose(); // no cleanup on success
184       return true;
185     }
186
187     /////////////////////////////////////////////////////////////////
188   } // namespace applydeltarpm
189   ///////////////////////////////////////////////////////////////////
190   /////////////////////////////////////////////////////////////////
191 } // namespace zypp
192 ///////////////////////////////////////////////////////////////////