4f79a1305058a2036fb177530227f5fbc95397c9
[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
36       /******************************************************************
37        **
38        **       FUNCTION NAME : applydeltarpm
39        **       FUNCTION TYPE : bool
40       */
41       bool applydeltarpm( const char *const argv_r[],
42                           const Progress & report_r  = Progress() )
43       {
44         ExternalProgram prog( argv_r, ExternalProgram::Stderr_To_Stdout );
45         for ( std::string line = prog.receiveLine(); ! line.empty(); line = prog.receiveLine() )
46           {
47             if ( report_r )
48               report_r( str::strtonum<unsigned>( line ));
49             else
50               DBG << "Applydeltarpm : " << line;
51           }
52         return( prog.close() == 0 );
53       }
54
55       /////////////////////////////////////////////////////////////////
56     } // namespace
57     ///////////////////////////////////////////////////////////////////
58
59     /******************************************************************
60      **
61      ** FUNCTION NAME : haveApplydeltarpm
62      ** FUNCTION TYPE : bool
63     */
64     bool haveApplydeltarpm()
65     {
66       // To track changes in availability of applydeltarpm.
67       static TriBool _last = indeterminate;
68       PathInfo prog( applydeltarpm_prog );
69       bool have = prog.isX();
70       if ( _last == have )
71         ; // TriBool! 'else' is not '_last != have'
72       else
73         {
74           // _last is 'indeterminate' or '!have'
75           if ( (_last = have) )
76             MIL << "Found executable " << prog << endl;
77           else
78             WAR << "No executable " << prog << endl;
79         }
80       return _last;
81     }
82
83     /******************************************************************
84      **
85      ** FUNCTION NAME : check
86      ** FUNCTION TYPE : bool
87     */
88     bool check( const std::string & sequenceinfo_r, bool quick_r )
89     {
90       if ( ! haveApplydeltarpm() )
91         return false;
92
93       const char *const argv[] = {
94         "/usr/bin/applydeltarpm",
95         ( quick_r ? "-C" : "-c" ),
96         "-s", sequenceinfo_r.c_str(),
97         NULL
98       };
99
100       return( applydeltarpm( argv ) );
101     }
102
103     /******************************************************************
104      **
105      ** FUNCTION NAME : check
106      ** FUNCTION TYPE : bool
107     */
108     bool check( const Pathname & delta_r, bool quick_r )
109     {
110       if ( ! haveApplydeltarpm() )
111         return false;
112
113       const char *const argv[] = {
114         "/usr/bin/applydeltarpm",
115         ( quick_r ? "-C" : "-c" ),
116         delta_r.asString().c_str(),
117         NULL
118       };
119
120       return( applydeltarpm( argv ) );
121     }
122
123     /******************************************************************
124      **
125      ** FUNCTION NAME : provide
126      ** FUNCTION TYPE : bool
127     */
128     bool provide( const Pathname & delta_r, const Pathname & new_r,
129                   const Progress & report_r )
130     {
131       // cleanup on error
132       AutoDispose<const Pathname> guard( new_r, filesystem::unlink );
133
134       if ( ! haveApplydeltarpm() )
135         return false;
136
137       const char *const argv[] = {
138         "/usr/bin/applydeltarpm",
139         "-p", "-p", // twice to get percent output one per line
140         delta_r.asString().c_str(),
141         new_r.asString().c_str(),
142         NULL
143       };
144
145       if ( ! applydeltarpm( argv, report_r ) )
146         return false;
147
148       guard.resetDispose(); // no cleanup on success
149       return true;
150     }
151
152     /******************************************************************
153      **
154      ** FUNCTION NAME : provide
155      ** FUNCTION TYPE : bool
156     */
157     bool provide( const Pathname & old_r, const Pathname & delta_r,
158                   const Pathname & new_r,
159                   const Progress & report_r )
160     {
161       // cleanup on error
162       AutoDispose<const Pathname> guard( new_r, filesystem::unlink );
163
164       if ( ! haveApplydeltarpm() )
165         return false;
166
167       const char *const argv[] = {
168         "/usr/bin/applydeltarpm",
169         "-p", "-p", // twice to get percent output one per line
170         "-r", old_r.asString().c_str(),
171         delta_r.asString().c_str(),
172         new_r.asString().c_str(),
173         NULL
174       };
175
176       if ( ! applydeltarpm( argv, report_r ) )
177         return false;
178
179       guard.resetDispose(); // no cleanup on success
180       return true;
181     }
182
183     /////////////////////////////////////////////////////////////////
184   } // namespace applydeltarpm
185   ///////////////////////////////////////////////////////////////////
186   /////////////////////////////////////////////////////////////////
187 } // namespace zypp
188 ///////////////////////////////////////////////////////////////////