]>
git.saurik.com Git - apt.git/blob - apt-pkg/edsp.cc
1 // -*- mode: cpp; mode: fold -*-
3 /* ######################################################################
4 Set of methods to help writing and reading everything needed for EDSP
5 ##################################################################### */
7 // Include Files /*{{{*/
10 #include <apt-pkg/error.h>
11 #include <apt-pkg/cacheset.h>
12 #include <apt-pkg/depcache.h>
13 #include <apt-pkg/pkgcache.h>
14 #include <apt-pkg/cacheiterators.h>
15 #include <apt-pkg/progress.h>
16 #include <apt-pkg/fileutl.h>
17 #include <apt-pkg/edsp.h>
18 #include <apt-pkg/tagfile.h>
19 #include <apt-pkg/strutl.h>
20 #include <apt-pkg/string_view.h>
21 #include <apt-pkg/pkgsystem.h>
38 // we could use pkgCache::DepType and ::Priority, but these would be localized stringsā¦
39 constexpr char const * const PrioMap
[] = {
40 nullptr , "important" , "required" , "standard" ,
43 constexpr char const * const DepMap
[] = {
44 nullptr , "Depends" , "Pre-Depends" , "Suggests" ,
45 "Recommends" , "Conflicts" , "Replaces" ,
46 "Obsoletes" , "Breaks" , "Enhances"
49 // WriteOkay - varaidic helper to easily Write to a FileFd /*{{{*/
50 static bool WriteOkay_fn ( FileFd
&) { return true ; }
51 template < typename
... Tail
> static bool WriteOkay_fn ( FileFd
& output
, APT :: StringView data
, Tail
... more_data
)
53 return likely ( output
. Write ( data
. data (), data
. length ()) && WriteOkay_fn ( output
, more_data
...));
55 template < typename
... Tail
> static bool WriteOkay_fn ( FileFd
& output
, unsigned int data
, Tail
... more_data
)
58 strprintf ( number
, " %d " , data
);
59 return likely ( output
. Write ( number
. data (), number
. length ()) && WriteOkay_fn ( output
, more_data
...));
61 template < typename
... Data
> static bool WriteOkay ( bool & Okay
, FileFd
& output
, Data
&&... data
)
63 Okay
= likely ( Okay
&& WriteOkay_fn ( output
, std :: forward
< Data
>( data
)...));
66 template < typename
... Data
> static bool WriteOkay ( FileFd
& output
, Data
&&... data
)
68 bool Okay
= likely ( output
. Failed () == false );
69 return WriteOkay ( Okay
, output
, std :: forward
< Data
>( data
)...);
72 // WriteScenarioVersion /*{{{*/
73 static void WriteScenarioVersion ( pkgDepCache
& Cache
, FILE * output
, pkgCache :: PkgIterator
const & Pkg
,
74 pkgCache :: VerIterator
const & Ver
)
76 fprintf ( output
, "Package: %s \n " , Pkg
. Name ());
77 fprintf ( output
, "Source: %s \n " , Ver
. SourcePkgName ());
78 fprintf ( output
, "Architecture: %s \n " , Ver
. Arch ());
79 fprintf ( output
, "Version: %s \n " , Ver
. VerStr ());
80 fprintf ( output
, "Source-Version: %s \n " , Ver
. SourceVerStr ());
81 if ( Pkg
. CurrentVer () == Ver
)
82 fprintf ( output
, "Installed: yes \n " );
83 if ( Pkg
-> SelectedState
== pkgCache :: State :: Hold
||
84 ( Cache
[ Pkg
]. Keep () == true && Cache
[ Pkg
]. Protect () == true ))
85 fprintf ( output
, "Hold: yes \n " );
86 fprintf ( output
, "APT-ID: %d \n " , Ver
-> ID
);
87 if ( PrioMap
[ Ver
-> Priority
] != nullptr )
88 fprintf ( output
, "Priority: %s \n " , PrioMap
[ Ver
-> Priority
]);
89 if (( Pkg
-> Flags
& pkgCache :: Flag :: Essential
) == pkgCache :: Flag :: Essential
)
90 fprintf ( output
, "Essential: yes \n " );
91 if ( Ver
-> Section
!= 0 )
92 fprintf ( output
, "Section: %s \n " , Ver
. Section ());
93 if (( Ver
-> MultiArch
& pkgCache :: Version :: Allowed
) == pkgCache :: Version :: Allowed
)
94 fprintf ( output
, "Multi-Arch: allowed \n " );
95 else if (( Ver
-> MultiArch
& pkgCache :: Version :: Foreign
) == pkgCache :: Version :: Foreign
)
96 fprintf ( output
, "Multi-Arch: foreign \n " );
97 else if (( Ver
-> MultiArch
& pkgCache :: Version :: Same
) == pkgCache :: Version :: Same
)
98 fprintf ( output
, "Multi-Arch: same \n " );
99 std :: set
< string
> Releases
;
100 for ( pkgCache :: VerFileIterator I
= Ver
. FileList (); I
. end () == false ; ++ I
) {
101 pkgCache :: PkgFileIterator File
= I
. File ();
102 if ( File
. Flagged ( pkgCache :: Flag :: NotSource
) == false ) {
103 string Release
= File
. RelStr ();
104 if (! Release
. empty ())
105 Releases
. insert ( Release
);
108 if (! Releases
. empty ()) {
109 fprintf ( output
, "APT-Release: \n " );
110 for ( std :: set
< string
>:: iterator R
= Releases
. begin (); R
!= Releases
. end (); ++ R
)
111 fprintf ( output
, " %s \n " , R
-> c_str ());
113 fprintf ( output
, "APT-Pin: %d \n " , Cache
. GetPolicy (). GetPriority ( Ver
));
114 if ( Cache
. GetCandidateVersion ( Pkg
) == Ver
)
115 fprintf ( output
, "APT-Candidate: yes \n " );
116 if (( Cache
[ Pkg
]. Flags
& pkgCache :: Flag :: Auto
) == pkgCache :: Flag :: Auto
)
117 fprintf ( output
, "APT-Automatic: yes \n " );
119 static bool WriteScenarioVersion ( FileFd
& output
, pkgCache :: PkgIterator
const & Pkg
,
120 pkgCache :: VerIterator
const & Ver
)
122 bool Okay
= WriteOkay ( output
, "Package: " , Pkg
. Name (),
123 " \n Architecture: " , Ver
. Arch (),
124 " \n Version: " , Ver
. VerStr ());
125 WriteOkay ( Okay
, output
, " \n APT-ID: " , Ver
-> ID
);
126 if (( Pkg
-> Flags
& pkgCache :: Flag :: Essential
) == pkgCache :: Flag :: Essential
)
127 WriteOkay ( Okay
, output
, " \n Essential: yes" );
128 if (( Ver
-> MultiArch
& pkgCache :: Version :: Allowed
) == pkgCache :: Version :: Allowed
)
129 WriteOkay ( Okay
, output
, " \n Multi-Arch: allowed" );
130 else if (( Ver
-> MultiArch
& pkgCache :: Version :: Foreign
) == pkgCache :: Version :: Foreign
)
131 WriteOkay ( Okay
, output
, " \n Multi-Arch: foreign" );
132 else if (( Ver
-> MultiArch
& pkgCache :: Version :: Same
) == pkgCache :: Version :: Same
)
133 WriteOkay ( Okay
, output
, " \n Multi-Arch: same" );
137 // WriteScenarioDependency /*{{{*/
138 static void WriteScenarioDependency ( FILE * output
, pkgCache :: VerIterator
const & Ver
)
140 std :: array
< std :: string
, _count ( DepMap
)> dependencies
;
141 bool orGroup
= false ;
142 for ( pkgCache :: DepIterator Dep
= Ver
. DependsList (); Dep
. end () == false ; ++ Dep
)
144 if ( Dep
. IsImplicit () == true )
146 if ( orGroup
== false )
147 dependencies
[ Dep
-> Type
]. append ( ", " );
148 dependencies
[ Dep
-> Type
]. append ( Dep
. TargetPkg (). Name ());
149 if ( Dep
-> Version
!= 0 )
150 dependencies
[ Dep
-> Type
]. append ( " (" ). append ( pkgCache :: CompTypeDeb ( Dep
-> CompareOp
)). append ( " " ). append ( Dep
. TargetVer ()). append ( ")" );
151 if (( Dep
-> CompareOp
& pkgCache :: Dep :: Or
) == pkgCache :: Dep :: Or
)
153 dependencies
[ Dep
-> Type
]. append ( " | " );
159 for ( size_t i
= 1 ; i
< dependencies
. size (); ++ i
)
160 if ( dependencies
[ i
]. empty () == false )
161 fprintf ( output
, " %s : %s \n " , DepMap
[ i
], dependencies
[ i
]. c_str ()+ 2 );
163 for ( pkgCache :: PrvIterator Prv
= Ver
. ProvidesList (); Prv
. end () == false ; ++ Prv
)
165 if ( Prv
. IsMultiArchImplicit () == true )
167 if ( provides
. empty () == false )
168 provides
. append ( ", " );
169 provides
. append ( Prv
. Name ());
170 if ( Prv
-> ProvideVersion
!= 0 )
171 provides
. append ( " (= " ). append ( Prv
. ProvideVersion ()). append ( ")" );
173 if ( provides
. empty () == false )
174 fprintf ( output
, "Provides: %s \n " , provides
. c_str ());
176 static bool WriteScenarioDependency ( FileFd
& output
, pkgCache :: VerIterator
const & Ver
, bool const OnlyCritical
)
178 std :: array
< std :: string
, _count ( DepMap
)> dependencies
;
179 bool orGroup
= false ;
180 for ( pkgCache :: DepIterator Dep
= Ver
. DependsList (); Dep
. end () == false ; ++ Dep
)
182 if ( Dep
. IsImplicit () == true )
184 if ( OnlyCritical
&& Dep
. IsCritical () == false )
186 if ( orGroup
== false && dependencies
[ Dep
-> Type
]. empty () == false )
187 dependencies
[ Dep
-> Type
]. append ( ", " );
188 dependencies
[ Dep
-> Type
]. append ( Dep
. TargetPkg (). Name ());
189 if ( Dep
-> Version
!= 0 )
190 dependencies
[ Dep
-> Type
]. append ( " (" ). append ( pkgCache :: CompTypeDeb ( Dep
-> CompareOp
)). append ( " " ). append ( Dep
. TargetVer ()). append ( ")" );
191 if (( Dep
-> CompareOp
& pkgCache :: Dep :: Or
) == pkgCache :: Dep :: Or
)
193 dependencies
[ Dep
-> Type
]. append ( " | " );
199 bool Okay
= output
. Failed () == false ;
200 for ( size_t i
= 1 ; i
< dependencies
. size (); ++ i
)
201 if ( dependencies
[ i
]. empty () == false )
202 WriteOkay ( Okay
, output
, " \n " , DepMap
[ i
], ": " , dependencies
[ i
]);
204 for ( pkgCache :: PrvIterator Prv
= Ver
. ProvidesList (); Prv
. end () == false ; ++ Prv
)
206 if ( Prv
. IsMultiArchImplicit () == true )
208 if ( provides
. empty () == false )
209 provides
. append ( ", " );
210 provides
. append ( Prv
. Name ());
211 if ( Prv
-> ProvideVersion
!= 0 )
212 provides
. append ( " (= " ). append ( Prv
. ProvideVersion ()). append ( ")" );
214 if ( provides
. empty () == false )
215 WriteOkay ( Okay
, output
, " \n Provides: " , provides
);
216 return WriteOkay ( Okay
, output
, " \n " );
219 // WriteScenarioLimitedDependency /*{{{*/
220 static void WriteScenarioLimitedDependency ( FILE * output
,
221 pkgCache :: VerIterator
const & Ver
,
222 APT :: PackageSet
const & pkgset
)
224 std :: array
< std :: string
, _count ( DepMap
)> dependencies
;
225 bool orGroup
= false ;
226 for ( pkgCache :: DepIterator Dep
= Ver
. DependsList (); Dep
. end () == false ; ++ Dep
)
228 if ( Dep
. IsImplicit () == true )
230 if ( orGroup
== false )
232 if ( pkgset
. find ( Dep
. TargetPkg ()) == pkgset
. end ())
234 if ( dependencies
[ Dep
-> Type
]. empty () == false )
235 dependencies
[ Dep
-> Type
]. append ( ", " );
237 else if ( pkgset
. find ( Dep
. TargetPkg ()) == pkgset
. end ())
239 if (( Dep
-> CompareOp
& pkgCache :: Dep :: Or
) == pkgCache :: Dep :: Or
)
241 dependencies
[ Dep
-> Type
]. erase ( dependencies
[ Dep
-> Type
]. end ()- 3 , dependencies
[ Dep
-> Type
]. end ());
245 dependencies
[ Dep
-> Type
]. append ( Dep
. TargetPkg (). Name ());
246 if ( Dep
-> Version
!= 0 )
247 dependencies
[ Dep
-> Type
]. append ( " (" ). append ( pkgCache :: CompTypeDeb ( Dep
-> CompareOp
)). append ( " " ). append ( Dep
. TargetVer ()). append ( ")" );
248 if (( Dep
-> CompareOp
& pkgCache :: Dep :: Or
) == pkgCache :: Dep :: Or
)
250 dependencies
[ Dep
-> Type
]. append ( " | " );
256 for ( size_t i
= 1 ; i
< dependencies
. size (); ++ i
)
257 if ( dependencies
[ i
]. empty () == false )
258 fprintf ( output
, " %s : %s \n " , DepMap
[ i
], dependencies
[ i
]. c_str ());
260 for ( pkgCache :: PrvIterator Prv
= Ver
. ProvidesList (); Prv
. end () == false ; ++ Prv
)
262 if ( Prv
. IsMultiArchImplicit () == true )
264 if ( pkgset
. find ( Prv
. ParentPkg ()) == pkgset
. end ())
266 if ( provides
. empty () == false )
267 provides
. append ( ", " );
268 provides
. append ( Prv
. Name ());
269 if ( Prv
-> ProvideVersion
!= 0 )
270 provides
. append ( " (= " ). append ( Prv
. ProvideVersion ()). append ( ")" );
272 if ( provides
. empty () == false )
273 fprintf ( output
, "Provides: %s \n " , provides
. c_str ());
275 static bool WriteScenarioLimitedDependency ( FileFd
& output
,
276 pkgCache :: VerIterator
const & Ver
,
277 std :: vector
< bool > const & pkgset
,
278 bool const OnlyCritical
)
280 std :: array
< std :: string
, _count ( DepMap
)> dependencies
;
281 bool orGroup
= false ;
282 for ( pkgCache :: DepIterator Dep
= Ver
. DependsList (); Dep
. end () == false ; ++ Dep
)
284 if ( Dep
. IsImplicit () == true )
286 if ( OnlyCritical
&& Dep
. IsCritical () == false )
288 if ( orGroup
== false )
290 if ( pkgset
[ Dep
. TargetPkg ()-> ID
] == false )
292 if ( dependencies
[ Dep
-> Type
]. empty () == false )
293 dependencies
[ Dep
-> Type
]. append ( ", " );
295 else if ( pkgset
[ Dep
. TargetPkg ()-> ID
] == false )
297 if (( Dep
-> CompareOp
& pkgCache :: Dep :: Or
) == pkgCache :: Dep :: Or
)
299 dependencies
[ Dep
-> Type
]. erase ( dependencies
[ Dep
-> Type
]. end ()- 3 , dependencies
[ Dep
-> Type
]. end ());
303 dependencies
[ Dep
-> Type
]. append ( Dep
. TargetPkg (). Name ());
304 if ( Dep
-> Version
!= 0 )
305 dependencies
[ Dep
-> Type
]. append ( " (" ). append ( pkgCache :: CompTypeDeb ( Dep
-> CompareOp
)). append ( " " ). append ( Dep
. TargetVer ()). append ( ")" );
306 if (( Dep
-> CompareOp
& pkgCache :: Dep :: Or
) == pkgCache :: Dep :: Or
)
308 dependencies
[ Dep
-> Type
]. append ( " | " );
314 bool Okay
= output
. Failed () == false ;
315 for ( size_t i
= 1 ; i
< dependencies
. size (); ++ i
)
316 if ( dependencies
[ i
]. empty () == false )
317 WriteOkay ( Okay
, output
, " \n " , DepMap
[ i
], ": " , dependencies
[ i
]);
319 for ( pkgCache :: PrvIterator Prv
= Ver
. ProvidesList (); Prv
. end () == false ; ++ Prv
)
321 if ( Prv
. IsMultiArchImplicit () == true )
323 if ( pkgset
[ Prv
. ParentPkg ()-> ID
] == false )
325 if ( provides
. empty () == false )
326 provides
. append ( ", " );
327 provides
. append ( Prv
. Name ());
328 if ( Prv
-> ProvideVersion
!= 0 )
329 provides
. append ( " (= " ). append ( Prv
. ProvideVersion ()). append ( ")" );
331 if ( provides
. empty () == false )
332 WriteOkay ( Okay
, output
, " \n Provides: " , provides
);
333 return WriteOkay ( Okay
, output
, " \n " );
336 static bool SkipUnavailableVersions ( pkgDepCache
& Cache
, pkgCache :: PkgIterator
const & Pkg
, pkgCache :: VerIterator
const & Ver
) /*{{{*/
338 /* versions which aren't current and aren't available in
339 any "online" source file are bad, expect if they are the choosen
340 candidate: The exception is for build-dep implementation as it creates
341 such pseudo (package) versions and removes them later on again.
342 We filter out versions at all so packages in 'rc' state only available
343 in dpkg/status aren't passed to solvers as they can't be installed. */
344 if ( Pkg
-> CurrentVer
!= 0 )
346 if ( Cache
. GetCandidateVersion ( Pkg
) == Ver
)
348 for ( pkgCache :: VerFileIterator I
= Ver
. FileList (); I
. end () == false ; ++ I
)
349 if ( I
. File (). Flagged ( pkgCache :: Flag :: NotSource
) == false )
354 static bool WriteScenarioEDSPVersion ( pkgDepCache
& Cache
, FileFd
& output
, pkgCache :: PkgIterator
const & Pkg
, /*{{{*/
355 pkgCache :: VerIterator
const & Ver
)
357 bool Okay
= WriteOkay ( output
, " \n Source: " , Ver
. SourcePkgName (),
358 " \n Source-Version: " , Ver
. SourceVerStr ());
359 if ( PrioMap
[ Ver
-> Priority
] != nullptr )
360 WriteOkay ( Okay
, output
, " \n Priority: " , PrioMap
[ Ver
-> Priority
]);
361 if ( Ver
-> Section
!= 0 )
362 WriteOkay ( Okay
, output
, " \n Section: " , Ver
. Section ());
363 if ( Pkg
. CurrentVer () == Ver
)
364 WriteOkay ( Okay
, output
, " \n Installed: yes" );
365 if ( Pkg
-> SelectedState
== pkgCache :: State :: Hold
||
366 ( Cache
[ Pkg
]. Keep () == true && Cache
[ Pkg
]. Protect () == true ))
367 WriteOkay ( Okay
, output
, " \n Hold: yes" );
368 std :: set
< string
> Releases
;
369 for ( pkgCache :: VerFileIterator I
= Ver
. FileList (); I
. end () == false ; ++ I
) {
370 pkgCache :: PkgFileIterator File
= I
. File ();
371 if ( File
. Flagged ( pkgCache :: Flag :: NotSource
) == false ) {
372 string Release
= File
. RelStr ();
373 if (! Release
. empty ())
374 Releases
. insert ( Release
);
377 if (! Releases
. empty ()) {
378 WriteOkay ( Okay
, output
, " \n APT-Release:" );
379 for ( std :: set
< string
>:: iterator R
= Releases
. begin (); R
!= Releases
. end (); ++ R
)
380 WriteOkay ( Okay
, output
, " \n " , * R
);
382 WriteOkay ( Okay
, output
, " \n APT-Pin: " , Cache
. GetPolicy (). GetPriority ( Ver
));
383 if ( Cache
. GetCandidateVersion ( Pkg
) == Ver
)
384 WriteOkay ( Okay
, output
, " \n APT-Candidate: yes" );
385 if (( Cache
[ Pkg
]. Flags
& pkgCache :: Flag :: Auto
) == pkgCache :: Flag :: Auto
)
386 WriteOkay ( Okay
, output
, " \n APT-Automatic: yes" );
390 // EDSP::WriteScenario - to the given file descriptor /*{{{*/
391 bool EDSP :: WriteScenario ( pkgDepCache
& Cache
, FILE * output
, OpProgress
* Progress
)
393 if ( Progress
!= NULL
)
394 Progress
-> SubProgress ( Cache
. Head (). VersionCount
, _ ( "Send scenario to solver" ));
396 std :: vector
< std :: string
> archs
= APT :: Configuration :: getArchitectures ();
397 for ( pkgCache :: PkgIterator Pkg
= Cache
. PkgBegin (); Pkg
. end () == false ; ++ Pkg
)
399 std :: string
const arch
= Pkg
. Arch ();
400 if ( std :: find ( archs
. begin (), archs
. end (), arch
) == archs
. end ())
402 for ( pkgCache :: VerIterator Ver
= Pkg
. VersionList (); Ver
. end () == false ; ++ Ver
, ++ p
)
404 if ( SkipUnavailableVersions ( Cache
, Pkg
, Ver
))
406 WriteScenarioVersion ( Cache
, output
, Pkg
, Ver
);
407 WriteScenarioDependency ( output
, Ver
);
408 fprintf ( output
, " \n " );
409 if ( Progress
!= NULL
&& p
% 100 == 0 )
410 Progress
-> Progress ( p
);
415 bool EDSP :: WriteScenario ( pkgDepCache
& Cache
, FileFd
& output
, OpProgress
* Progress
)
417 if ( Progress
!= NULL
)
418 Progress
-> SubProgress ( Cache
. Head (). VersionCount
, _ ( "Send scenario to solver" ));
420 bool Okay
= output
. Failed () == false ;
421 std :: vector
< std :: string
> archs
= APT :: Configuration :: getArchitectures ();
422 for ( pkgCache :: PkgIterator Pkg
= Cache
. PkgBegin (); Pkg
. end () == false && likely ( Okay
); ++ Pkg
)
424 std :: string
const arch
= Pkg
. Arch ();
425 if ( std :: find ( archs
. begin (), archs
. end (), arch
) == archs
. end ())
427 for ( pkgCache :: VerIterator Ver
= Pkg
. VersionList (); Ver
. end () == false && likely ( Okay
); ++ Ver
, ++ p
)
429 if ( SkipUnavailableVersions ( Cache
, Pkg
, Ver
))
431 Okay
&= WriteScenarioVersion ( output
, Pkg
, Ver
);
432 Okay
&= WriteScenarioEDSPVersion ( Cache
, output
, Pkg
, Ver
);
433 Okay
&= WriteScenarioDependency ( output
, Ver
, false );
434 WriteOkay ( Okay
, output
, " \n " );
435 if ( Progress
!= NULL
&& p
% 100 == 0 )
436 Progress
-> Progress ( p
);
442 // EDSP::WriteLimitedScenario - to the given file descriptor /*{{{*/
443 bool EDSP :: WriteLimitedScenario ( pkgDepCache
& Cache
, FILE * output
,
444 APT :: PackageSet
const & pkgset
,
445 OpProgress
* Progress
)
447 if ( Progress
!= NULL
)
448 Progress
-> SubProgress ( Cache
. Head (). VersionCount
, _ ( "Send scenario to solver" ));
450 for ( APT :: PackageSet :: const_iterator Pkg
= pkgset
. begin (); Pkg
!= pkgset
. end (); ++ Pkg
, ++ p
)
451 for ( pkgCache :: VerIterator Ver
= Pkg
. VersionList (); Ver
. end () == false ; ++ Ver
)
453 if ( SkipUnavailableVersions ( Cache
, Pkg
, Ver
))
455 WriteScenarioVersion ( Cache
, output
, Pkg
, Ver
);
456 WriteScenarioLimitedDependency ( output
, Ver
, pkgset
);
457 fprintf ( output
, " \n " );
458 if ( Progress
!= NULL
&& p
% 100 == 0 )
459 Progress
-> Progress ( p
);
461 if ( Progress
!= NULL
)
465 bool EDSP :: WriteLimitedScenario ( pkgDepCache
& Cache
, FileFd
& output
,
466 std :: vector
< bool > const & pkgset
,
467 OpProgress
* Progress
)
469 if ( Progress
!= NULL
)
470 Progress
-> SubProgress ( Cache
. Head (). VersionCount
, _ ( "Send scenario to solver" ));
472 bool Okay
= output
. Failed () == false ;
473 for ( auto Pkg
= Cache
. PkgBegin (); Pkg
. end () == false && likely ( Okay
); ++ Pkg
, ++ p
)
475 if ( pkgset
[ Pkg
-> ID
] == false )
477 for ( pkgCache :: VerIterator Ver
= Pkg
. VersionList (); Ver
. end () == false && likely ( Okay
); ++ Ver
)
479 if ( SkipUnavailableVersions ( Cache
, Pkg
, Ver
))
481 Okay
&= WriteScenarioVersion ( output
, Pkg
, Ver
);
482 Okay
&= WriteScenarioEDSPVersion ( Cache
, output
, Pkg
, Ver
);
483 Okay
&= WriteScenarioLimitedDependency ( output
, Ver
, pkgset
, false );
484 WriteOkay ( Okay
, output
, " \n " );
485 if ( Progress
!= NULL
&& p
% 100 == 0 )
486 Progress
-> Progress ( p
);
489 if ( Progress
!= NULL
)
494 // EDSP::WriteRequest - to the given file descriptor /*{{{*/
495 bool EDSP :: WriteRequest ( pkgDepCache
& Cache
, FILE * output
, bool const Upgrade
,
496 bool const DistUpgrade
, bool const AutoRemove
,
497 OpProgress
* Progress
)
499 if ( Progress
!= NULL
)
500 Progress
-> SubProgress ( Cache
. Head (). PackageCount
, _ ( "Send request to solver" ));
503 for ( pkgCache :: PkgIterator Pkg
= Cache
. PkgBegin (); Pkg
. end () == false ; ++ Pkg
, ++ p
)
505 if ( Progress
!= NULL
&& p
% 100 == 0 )
506 Progress
-> Progress ( p
);
508 pkgDepCache :: StateCache
& P
= Cache
[ Pkg
];
509 if ( P
. Delete () == true )
511 else if ( P
. NewInstall () == true || P
. Upgrade () == true || P
. ReInstall () == true ||
512 ( P
. Mode
== pkgDepCache :: ModeKeep
&& ( P
. iFlags
& pkgDepCache :: Protected
) == pkgDepCache :: Protected
))
516 req
-> append ( " " ). append ( Pkg
. FullName ());
518 fprintf ( output
, "Request: EDSP 0.5 \n " );
520 const char * arch
= _config
-> Find ( "APT::Architecture" ). c_str ();
521 std :: vector
< string
> archs
= APT :: Configuration :: getArchitectures ();
522 fprintf ( output
, "Architecture: %s \n " , arch
);
523 fprintf ( output
, "Architectures:" );
524 for ( std :: vector
< string
>:: const_iterator a
= archs
. begin (); a
!= archs
. end (); ++ a
)
525 fprintf ( output
, " %s " , a
-> c_str ());
526 fprintf ( output
, " \n " );
528 if ( del
. empty () == false )
529 fprintf ( output
, "Remove: %s \n " , del
. c_str ()+ 1 );
530 if ( inst
. empty () == false )
531 fprintf ( output
, "Install: %s \n " , inst
. c_str ()+ 1 );
533 fprintf ( output
, "Upgrade: yes \n " );
534 if ( DistUpgrade
== true )
535 fprintf ( output
, "Dist-Upgrade: yes \n " );
536 if ( AutoRemove
== true )
537 fprintf ( output
, "Autoremove: yes \n " );
538 auto const solver
= _config
-> Find ( "APT::Solver" , "internal" );
539 fprintf ( output
, "Solver: %s \n " , solver
. c_str ());
540 auto const solverconf
= std :: string ( "APT::Solver::" ) + solver
+ "::" ;
541 if ( _config
-> FindB ( solverconf
+ "Strict-Pinning" , _config
-> FindB ( "APT::Solver::Strict-Pinning" , true )) == false )
542 fprintf ( output
, "Strict-Pinning: no \n " );
543 auto const solverpref
= _config
-> Find ( solverconf
+ "Preferences" , _config
-> Find ( "APT::Solver::Preferences" , "" ));
544 if ( solverpref
. empty () == false )
545 fprintf ( output
, "Preferences: %s \n " , solverpref
. c_str ());
546 fprintf ( output
, " \n " );
549 bool EDSP :: WriteRequest ( pkgDepCache
& Cache
, FileFd
& output
,
550 unsigned int const flags
,
551 OpProgress
* Progress
)
553 if ( Progress
!= NULL
)
554 Progress
-> SubProgress ( Cache
. Head (). PackageCount
, _ ( "Send request to solver" ));
557 for ( pkgCache :: PkgIterator Pkg
= Cache
. PkgBegin (); Pkg
. end () == false ; ++ Pkg
, ++ p
)
559 if ( Progress
!= NULL
&& p
% 100 == 0 )
560 Progress
-> Progress ( p
);
562 pkgDepCache :: StateCache
& P
= Cache
[ Pkg
];
563 if ( P
. Delete () == true )
565 else if ( P
. NewInstall () == true || P
. Upgrade () == true || P
. ReInstall () == true ||
566 ( P
. Mode
== pkgDepCache :: ModeKeep
&& ( P
. iFlags
& pkgDepCache :: Protected
) == pkgDepCache :: Protected
))
570 req
-> append ( " " ). append ( Pkg
. FullName ());
572 bool Okay
= WriteOkay ( output
, "Request: EDSP 0.5 \n " );
574 const char * arch
= _config
-> Find ( "APT::Architecture" ). c_str ();
575 std :: vector
< string
> archs
= APT :: Configuration :: getArchitectures ();
576 WriteOkay ( Okay
, output
, "Architecture: " , arch
, " \n " ,
578 for ( std :: vector
< string
>:: const_iterator a
= archs
. begin (); a
!= archs
. end (); ++ a
)
579 WriteOkay ( Okay
, output
, " " , * a
);
580 WriteOkay ( Okay
, output
, " \n " );
582 if ( del
. empty () == false )
583 WriteOkay ( Okay
, output
, "Remove:" , del
, " \n " );
584 if ( inst
. empty () == false )
585 WriteOkay ( Okay
, output
, "Install:" , inst
, " \n " );
586 if ( flags
& Request :: AUTOREMOVE
)
587 WriteOkay ( Okay
, output
, "Autoremove: yes \n " );
588 if ( flags
& Request :: UPGRADE_ALL
)
590 WriteOkay ( Okay
, output
, "Upgrade-All: yes \n " );
591 if ( flags
& ( Request :: FORBID_NEW_INSTALL
| Request :: FORBID_REMOVE
))
592 WriteOkay ( Okay
, output
, "Upgrade: yes \n " );
594 WriteOkay ( Okay
, output
, "Dist-Upgrade: yes \n " );
596 if ( flags
& Request :: FORBID_NEW_INSTALL
)
597 WriteOkay ( Okay
, output
, "Forbid-New-Install: yes \n " );
598 if ( flags
& Request :: FORBID_REMOVE
)
599 WriteOkay ( Okay
, output
, "Forbid-Remove: yes \n " );
600 auto const solver
= _config
-> Find ( "APT::Solver" , "internal" );
601 WriteOkay ( Okay
, output
, "Solver: " , solver
, " \n " );
602 if ( _config
-> FindB ( "APT::Solver::Strict-Pinning" , true ) == false )
603 WriteOkay ( Okay
, output
, "Strict-Pinning: no \n " );
604 string
solverpref ( "APT::Solver::" );
605 solverpref
. append ( solver
). append ( "::Preferences" );
606 if ( _config
-> Exists ( solverpref
) == true )
607 WriteOkay ( Okay
, output
, "Preferences: " , _config
-> Find ( solverpref
, "" ), " \n " );
608 return WriteOkay ( Okay
, output
, " \n " );
611 // EDSP::ReadResponse - from the given file descriptor /*{{{*/
612 bool EDSP :: ReadResponse ( int const input
, pkgDepCache
& Cache
, OpProgress
* Progress
) {
613 /* We build an map id to mmap offset here
614 In theory we could use the offset as ID, but then VersionCount
615 couldn't be used to create other versionmappings anymore and it
616 would be too easy for a (buggy) solver to segfault APTā¦ */
617 unsigned long long const VersionCount
= Cache
. Head (). VersionCount
;
618 unsigned long VerIdx
[ VersionCount
];
619 for ( pkgCache :: PkgIterator P
= Cache
. PkgBegin (); P
. end () == false ; ++ P
) {
620 for ( pkgCache :: VerIterator V
= P
. VersionList (); V
. end () == false ; ++ V
)
621 VerIdx
[ V
-> ID
] = V
. Index ();
622 Cache
[ P
]. Marked
= true ;
623 Cache
[ P
]. Garbage
= false ;
627 in
. OpenDescriptor ( input
, FileFd :: ReadOnly
);
628 pkgTagFile
response (& in
, 100 );
629 pkgTagSection section
;
631 std :: set
< decltype ( Cache
. PkgBegin ()-> ID
)> seenOnce
;
632 while ( response
. Step ( section
) == true ) {
634 if ( section
. Exists ( "Install" ) == true )
636 else if ( section
. Exists ( "Remove" ) == true )
638 else if ( section
. Exists ( "Progress" ) == true ) {
639 if ( Progress
!= NULL
) {
640 string msg
= section
. FindS ( "Message" );
641 if ( msg
. empty () == true )
642 msg
= _ ( "Prepare for receiving solution" );
643 Progress
-> SubProgress ( 100 , msg
, section
. FindI ( "Percentage" , 0 ));
646 } else if ( section
. Exists ( "Error" ) == true ) {
647 std :: string msg
= SubstVar ( SubstVar ( section
. FindS ( "Message" ), " \n . \n " , " \n\n " ), " \n " , " \n " );
648 if ( msg
. empty () == true ) {
649 msg
= _ ( "External solver failed without a proper error message" );
650 _error
-> Error ( " %s " , msg
. c_str ());
652 _error
-> Error ( "External solver failed with: %s " , msg
. substr ( 0 , msg
. find ( ' \n ' )). c_str ());
653 if ( Progress
!= NULL
)
655 std :: cerr
<< "The solver encountered an error of type: " << section
. FindS ( "Error" ) << std :: endl
;
656 std :: cerr
<< "The following information might help you to understand what is wrong:" << std :: endl
;
657 std :: cerr
<< msg
<< std :: endl
<< std :: endl
;
659 } else if ( section
. Exists ( "Autoremove" ) == true )
664 size_t const id
= section
. FindULL ( type
. c_str (), VersionCount
);
665 if ( id
== VersionCount
) {
666 _error
-> Warning ( "Unable to parse %s request with id value ' %s '!" , type
. c_str (), section
. FindS ( type
. c_str ()). c_str ());
668 } else if ( id
> Cache
. Head (). VersionCount
) {
669 _error
-> Warning ( "ID value ' %s ' in %s request stanza is to high to refer to a known version!" , section
. FindS ( type
. c_str ()). c_str (), type
. c_str ());
673 pkgCache :: VerIterator
Ver ( Cache
. GetCache (), Cache
. GetCache (). VerP
+ VerIdx
[ id
]);
674 auto const Pkg
= Ver
. ParentPkg ();
675 if ( type
== "Autoremove" ) {
676 Cache
[ Pkg
]. Marked
= false ;
677 Cache
[ Pkg
]. Garbage
= true ;
678 } else if ( seenOnce
. emplace ( Pkg
-> ID
). second
== false ) {
679 _error
-> Warning ( "Ignoring %s stanza received for package %s which already had a previous stanza effecting it!" , type
. c_str (), Pkg
. FullName ( false ). c_str ());
680 } else if ( type
== "Install" ) {
681 if ( Pkg
. CurrentVer () == Ver
) {
682 _error
-> Warning ( "Ignoring Install stanza received for version %s of package %s which is already installed!" ,
683 Ver
. VerStr (), Pkg
. FullName ( false ). c_str ());
685 Cache
. SetCandidateVersion ( Ver
);
686 Cache
. MarkInstall ( Pkg
, false , 0 , false );
688 } else if ( type
== "Remove" ) {
689 if ( Pkg
-> CurrentVer
== 0 )
690 _error
-> Warning ( "Ignoring Remove stanza received for version %s of package %s which isn't installed!" ,
691 Ver
. VerStr (), Pkg
. FullName ( false ). c_str ());
692 else if ( Pkg
. CurrentVer () != Ver
)
693 _error
-> Warning ( "Ignoring Remove stanza received for version %s of package %s which isn't the installed version %s !" ,
694 Ver
. VerStr (), Pkg
. FullName ( false ). c_str (), Pkg
. CurrentVer (). VerStr ());
696 Cache
. MarkDelete ( Ver
. ParentPkg (), false );
702 // ReadLine - first line from the given file descriptor /*{{{*/
703 // ---------------------------------------------------------------------
704 /* Little helper method to read a complete line into a string. Similar to
705 fgets but we need to use the low-level read() here as otherwise the
706 listparser will be confused later on as mixing of fgets and read isn't
707 a supported action according to the manpages and results are undefined */
708 static bool ReadLine ( int const input
, std :: string
& line
) {
713 while (( data
= read ( input
, & one
, sizeof ( one
))) != - 1 ) {
720 if ( line
. empty () == true && isblank ( one
) != 0 )
727 // StringToBool - convert yes/no to bool /*{{{*/
728 // ---------------------------------------------------------------------
729 /* we are not as lazy as we are in the global StringToBool as we really
730 only accept yes/no here */
731 static bool localStringToBool ( std :: string answer
, bool const defValue
) {
732 std :: transform ( answer
. begin (), answer
. end (), answer
. begin (), :: tolower
);
735 else if ( answer
== "no" )
738 _error
-> Warning ( "Value ' %s ' is not a boolean 'yes' or 'no'!" , answer
. c_str ());
742 static bool LineStartsWithAndStrip ( std :: string
& line
, APT :: StringView
const with
) /*{{{*/
744 if ( line
. compare ( 0 , with
. size (), with
. data ()) != 0 )
746 line
= APT :: String :: Strip ( line
. substr ( with
. length ()));
750 static bool ReadFlag ( unsigned int & flags
, std :: string
& line
, APT :: StringView
const name
, unsigned int const setflag
) /*{{{*/
752 if ( LineStartsWithAndStrip ( line
, name
) == false )
754 if ( localStringToBool ( line
, false ))
761 // EDSP::ReadRequest - first stanza from the given file descriptor /*{{{*/
762 bool EDSP :: ReadRequest ( int const input
, std :: list
< std :: string
> & install
,
763 std :: list
< std :: string
> & remove
, unsigned int & flags
)
769 while ( ReadLine ( input
, line
) == true )
771 // Skip empty lines before request
772 if ( line
. empty () == true )
774 // The first Tag must be a request, so search for it
775 if ( LineStartsWithAndStrip ( line
, "Request:" ))
778 while ( ReadLine ( input
, line
) == true )
780 // empty lines are the end of the request
781 if ( line
. empty () == true )
784 std :: list
< std :: string
> * request
= NULL
;
785 if ( LineStartsWithAndStrip ( line
, "Install:" ))
787 else if ( LineStartsWithAndStrip ( line
, "Remove:" ))
789 else if ( ReadFlag ( flags
, line
, "Upgrade:" , ( Request :: UPGRADE_ALL
| Request :: FORBID_REMOVE
| Request :: FORBID_NEW_INSTALL
)) ||
790 ReadFlag ( flags
, line
, "Dist-Upgrade:" , Request :: UPGRADE_ALL
) ||
791 ReadFlag ( flags
, line
, "Upgrade-All:" , Request :: UPGRADE_ALL
) ||
792 ReadFlag ( flags
, line
, "Forbid-New-Install:" , Request :: FORBID_NEW_INSTALL
) ||
793 ReadFlag ( flags
, line
, "Forbid-Remove:" , Request :: FORBID_REMOVE
) ||
794 ReadFlag ( flags
, line
, "Autoremove:" , Request :: AUTOREMOVE
))
796 else if ( LineStartsWithAndStrip ( line
, "Architecture:" ))
797 _config
-> Set ( "APT::Architecture" , line
);
798 else if ( LineStartsWithAndStrip ( line
, "Architectures:" ))
799 _config
-> Set ( "APT::Architectures" , SubstVar ( line
, " " , "," ));
800 else if ( LineStartsWithAndStrip ( line
, "Solver:" ))
801 ; // purely informational line
803 _error
-> Warning ( "Unknown line in EDSP Request stanza: %s " , line
. c_str ());
807 auto const pkgs
= VectorizeString ( line
, ' ' );
808 std :: move ( pkgs
. begin (), pkgs
. end (), std :: back_inserter (* request
));
813 bool EDSP :: ReadRequest ( int const input
, std :: list
< std :: string
> & install
,
814 std :: list
< std :: string
> & remove
, bool & upgrade
,
815 bool & distUpgrade
, bool & autoRemove
)
818 auto const ret
= ReadRequest ( input
, install
, remove
, flags
);
819 autoRemove
= ( flags
& Request :: AUTOREMOVE
);
820 if ( flags
& Request :: UPGRADE_ALL
)
822 if ( flags
& ( Request :: FORBID_NEW_INSTALL
| Request :: FORBID_REMOVE
))
839 // EDSP::ApplyRequest - first stanza from the given file descriptor /*{{{*/
840 bool EDSP :: ApplyRequest ( std :: list
< std :: string
> const & install
,
841 std :: list
< std :: string
> const & remove
,
844 for ( std :: list
< std :: string
>:: const_iterator i
= install
. begin ();
845 i
!= install
. end (); ++ i
) {
846 pkgCache :: PkgIterator P
= Cache
. FindPkg (* i
);
848 _error
-> Warning ( "Package %s is not known, so can't be installed" , i
-> c_str ());
850 Cache
. MarkInstall ( P
, false );
853 for ( std :: list
< std :: string
>:: const_iterator i
= remove
. begin ();
854 i
!= remove
. end (); ++ i
) {
855 pkgCache :: PkgIterator P
= Cache
. FindPkg (* i
);
857 _error
-> Warning ( "Package %s is not known, so can't be installed" , i
-> c_str ());
864 // EDSP::WriteSolutionStanza - to the given file descriptor /*{{{*/
865 bool EDSP :: WriteSolution ( pkgDepCache
& Cache
, FILE * output
)
867 bool const Debug
= _config
-> FindB ( "Debug::EDSP::WriteSolution" , false );
868 for ( pkgCache :: PkgIterator Pkg
= Cache
. PkgBegin (); Pkg
. end () == false ; ++ Pkg
)
870 if ( Cache
[ Pkg
]. Delete () == true )
872 fprintf ( output
, "Remove: %d \n " , _system
-> GetVersionMapping ( Pkg
. CurrentVer ()-> ID
));
874 fprintf ( output
, "Package: %s \n Version: %s \n " , Pkg
. FullName (). c_str (), Pkg
. CurrentVer (). VerStr ());
876 else if ( Cache
[ Pkg
]. NewInstall () == true || Cache
[ Pkg
]. Upgrade () == true )
878 pkgCache :: VerIterator
const CandVer
= Cache
. GetCandidateVersion ( Pkg
);
879 fprintf ( output
, "Install: %d \n " , _system
-> GetVersionMapping ( CandVer
-> ID
));
881 fprintf ( output
, "Package: %s \n Version: %s \n " , Pkg
. FullName (). c_str (), CandVer
. VerStr ());
883 else if ( Cache
[ Pkg
]. Garbage
== true )
885 fprintf ( output
, "Autoremove: %d \n " , _system
-> GetVersionMapping ( Pkg
. CurrentVer ()-> ID
));
887 fprintf ( output
, "Package: %s \n Version: %s \n " , Pkg
. FullName (). c_str (), Pkg
. CurrentVer (). VerStr ());
891 fprintf ( output
, " \n " );
896 bool EDSP :: WriteSolutionStanza ( FileFd
& output
, char const * const Type
, pkgCache :: VerIterator
const & Ver
)
898 bool Okay
= output
. Failed () == false ;
899 WriteOkay ( Okay
, output
, Type
, ": " , _system
-> GetVersionMapping ( Ver
-> ID
));
900 if ( _config
-> FindB ( "Debug::EDSP::WriteSolution" , false ) == true )
901 WriteOkay ( Okay
, output
, " \n Package: " , Ver
. ParentPkg (). FullName (), " \n Version: " , Ver
. VerStr ());
902 return WriteOkay ( Okay
, output
, " \n\n " );
905 // EDSP::WriteProgess - pulse to the given file descriptor /*{{{*/
906 bool EDSP :: WriteProgress ( unsigned short const percent
, const char * const message
, FILE * output
) {
907 fprintf ( output
, "Progress: %s \n " , TimeRFC1123 ( time ( NULL
)). c_str ());
908 fprintf ( output
, "Percentage: %d \n " , percent
);
909 fprintf ( output
, "Message: %s \n\n " , message
);
913 bool EDSP :: WriteProgress ( unsigned short const percent
, const char * const message
, FileFd
& output
) {
914 return WriteOkay ( output
, "Progress: " , TimeRFC1123 ( time ( NULL
)), " \n " ,
915 "Percentage: " , percent
, " \n " ,
916 "Message: " , message
, " \n\n " ) && output
. Flush ();
919 // EDSP::WriteError - format an error message to be send to file descriptor /*{{{*/
920 bool EDSP :: WriteError ( char const * const uuid
, std :: string
const & message
, FILE * output
) {
921 fprintf ( output
, "Error: %s \n " , uuid
);
922 fprintf ( output
, "Message: %s \n\n " , SubstVar ( SubstVar ( message
, " \n\n " , " \n . \n " ), " \n " , " \n " ). c_str ());
925 bool EDSP :: WriteError ( char const * const uuid
, std :: string
const & message
, FileFd
& output
) {
926 return WriteOkay ( output
, "Error: " , uuid
, " \n " ,
927 "Message: " , SubstVar ( SubstVar ( message
, " \n\n " , " \n . \n " ), " \n " , " \n " ),
931 static std :: string
findExecutable ( std :: vector
< std :: string
> const & dirs
, char const * const binary
) { /*{{{*/
932 for ( auto && dir
: dirs
) {
933 std :: string
const file
= flCombine ( dir
, binary
);
934 if ( RealFileExists ( file
) == true )
940 static pid_t
ExecuteExternal ( char const * const type
, char const * const binary
, char const * const configdir
, int * const solver_in
, int * const solver_out
) { /*{{{*/
941 auto const solverDirs
= _config
-> FindVector ( configdir
);
942 auto const file
= findExecutable ( solverDirs
, binary
);
945 dumper
= findExecutable ( solverDirs
, "apt-dump-solver" );
947 dumper
= findExecutable ( solverDirs
, "dump" );
950 if ( file
. empty () == true )
952 _error
-> Error ( "Can't call external %s ' %s ' as it is not in a configured directory!" , type
, binary
);
955 int external
[ 4 ] = {- 1 , - 1 , - 1 , - 1 };
956 if ( pipe ( external
) != 0 || pipe ( external
+ 2 ) != 0 )
958 _error
-> Errno ( "Resolve" , "Can't create needed IPC pipes for EDSP" );
961 for ( int i
= 0 ; i
< 4 ; ++ i
)
962 SetCloseExec ( external
[ i
], true );
964 pid_t Solver
= ExecFork ();
966 dup2 ( external
[ 0 ], STDIN_FILENO
);
967 dup2 ( external
[ 3 ], STDOUT_FILENO
);
968 auto const dumpfile
= _config
-> FindFile (( std :: string ( "Dir::Log::" ) + type
). c_str ());
969 auto const dumpdir
= flNotFile ( dumpfile
);
970 if ( dumper
. empty () || dumpfile
. empty () || dumper
== file
|| CreateAPTDirectoryIfNeeded ( dumpdir
, dumpdir
) == false )
972 char const * const calling
[] = { file
. c_str (), nullptr };
973 execv ( calling
[ 0 ], const_cast < char **>( calling
));
977 char const * const calling
[] = { dumper
. c_str (), dumpfile
. c_str (), file
. c_str (), nullptr };
978 execv ( calling
[ 0 ], const_cast < char **>( calling
));
980 std :: cerr
<< "Failed to execute " << type
<< " '" << binary
<< "'!" << std :: endl
;
986 if ( WaitFd ( external
[ 1 ], true , 5 ) == false )
988 _error
-> Errno ( "Resolve" , "Timed out while Waiting on availability of %s stdin" , type
);
992 * solver_in
= external
[ 1 ];
993 * solver_out
= external
[ 2 ];
997 // EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/
998 pid_t
EDSP :: ExecuteSolver ( const char * const solver
, int * const solver_in
, int * const solver_out
, bool ) {
999 return ExecuteExternal ( "solver" , solver
, "Dir::Bin::Solvers" , solver_in
, solver_out
);
1001 bool EDSP :: ExecuteSolver ( const char * const solver
, int * solver_in
, int * solver_out
) {
1002 if ( ExecuteSolver ( solver
, solver_in
, solver_out
, true ) == 0 )
1007 // EDSP::ResolveExternal - resolve problems by asking external for help {{{*/
1008 bool EDSP :: ResolveExternal ( const char * const solver
, pkgDepCache
& Cache
,
1009 unsigned int const flags
, OpProgress
* Progress
) {
1010 int solver_in
, solver_out
;
1011 pid_t
const solver_pid
= EDSP :: ExecuteSolver ( solver
, & solver_in
, & solver_out
, true );
1012 if ( solver_pid
== 0 )
1016 if ( output
. OpenDescriptor ( solver_in
, FileFd :: WriteOnly
| FileFd :: BufferedWrite
, true ) == false )
1017 return _error
-> Errno ( "ResolveExternal" , "Opening solver %s stdin on fd %d for writing failed" , solver
, solver_in
);
1019 bool Okay
= output
. Failed () == false ;
1020 if ( Progress
!= NULL
)
1021 Progress
-> OverallProgress ( 0 , 100 , 5 , _ ( "Execute external solver" ));
1022 Okay
&= EDSP :: WriteRequest ( Cache
, output
, flags
, Progress
);
1023 if ( Progress
!= NULL
)
1024 Progress
-> OverallProgress ( 5 , 100 , 20 , _ ( "Execute external solver" ));
1025 Okay
&= EDSP :: WriteScenario ( Cache
, output
, Progress
);
1028 if ( Progress
!= NULL
)
1029 Progress
-> OverallProgress ( 25 , 100 , 75 , _ ( "Execute external solver" ));
1030 if ( Okay
&& EDSP :: ReadResponse ( solver_out
, Cache
, Progress
) == false )
1033 return ExecWait ( solver_pid
, solver
);
1035 bool EDSP :: ResolveExternal ( const char * const solver
, pkgDepCache
& Cache
,
1036 bool const upgrade
, bool const distUpgrade
,
1037 bool const autoRemove
, OpProgress
* Progress
) {
1038 unsigned int flags
= 0 ;
1040 flags
|= Request :: AUTOREMOVE
;
1042 flags
|= Request :: UPGRADE_ALL
| Request :: FORBID_REMOVE
| Request :: FORBID_NEW_INSTALL
;
1044 flags
|= Request :: UPGRADE_ALL
;
1045 return ResolveExternal ( solver
, Cache
, flags
, Progress
);