]>
git.saurik.com Git - apt.git/blob - apt-pkg/edsp.cc
94cac4eb1564564431fc95e3f51033d1e2f78a42
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 if ( _config
-> FindB ( "APT::Solver::Strict-Pinning" , true ) == false )
601 WriteOkay ( Okay
, output
, "Strict-Pinning: no \n " );
602 string
solverpref ( "APT::Solver::" );
603 solverpref
. append ( _config
-> Find ( "APT::Solver" , "internal" )). append ( "::Preferences" );
604 if ( _config
-> Exists ( solverpref
) == true )
605 WriteOkay ( Okay
, output
, "Preferences: " , _config
-> Find ( solverpref
, "" ), " \n " );
606 return WriteOkay ( Okay
, output
, " \n " );
609 // EDSP::ReadResponse - from the given file descriptor /*{{{*/
610 bool EDSP :: ReadResponse ( int const input
, pkgDepCache
& Cache
, OpProgress
* Progress
) {
611 /* We build an map id to mmap offset here
612 In theory we could use the offset as ID, but then VersionCount
613 couldn't be used to create other versionmappings anymore and it
614 would be too easy for a (buggy) solver to segfault APT⦠*/
615 unsigned long long const VersionCount
= Cache
. Head (). VersionCount
;
616 unsigned long VerIdx
[ VersionCount
];
617 for ( pkgCache :: PkgIterator P
= Cache
. PkgBegin (); P
. end () == false ; ++ P
) {
618 for ( pkgCache :: VerIterator V
= P
. VersionList (); V
. end () == false ; ++ V
)
619 VerIdx
[ V
-> ID
] = V
. Index ();
620 Cache
[ P
]. Marked
= true ;
621 Cache
[ P
]. Garbage
= false ;
625 in
. OpenDescriptor ( input
, FileFd :: ReadOnly
);
626 pkgTagFile
response (& in
, 100 );
627 pkgTagSection section
;
629 std :: set
< decltype ( Cache
. PkgBegin ()-> ID
)> seenOnce
;
630 while ( response
. Step ( section
) == true ) {
632 if ( section
. Exists ( "Install" ) == true )
634 else if ( section
. Exists ( "Remove" ) == true )
636 else if ( section
. Exists ( "Progress" ) == true ) {
637 if ( Progress
!= NULL
) {
638 string msg
= section
. FindS ( "Message" );
639 if ( msg
. empty () == true )
640 msg
= _ ( "Prepare for receiving solution" );
641 Progress
-> SubProgress ( 100 , msg
, section
. FindI ( "Percentage" , 0 ));
644 } else if ( section
. Exists ( "Error" ) == true ) {
645 std :: string msg
= SubstVar ( SubstVar ( section
. FindS ( "Message" ), " \n . \n " , " \n\n " ), " \n " , " \n " );
646 if ( msg
. empty () == true ) {
647 msg
= _ ( "External solver failed without a proper error message" );
648 _error
-> Error ( " %s " , msg
. c_str ());
650 _error
-> Error ( "External solver failed with: %s " , msg
. substr ( 0 , msg
. find ( ' \n ' )). c_str ());
651 if ( Progress
!= NULL
)
653 std :: cerr
<< "The solver encountered an error of type: " << section
. FindS ( "Error" ) << std :: endl
;
654 std :: cerr
<< "The following information might help you to understand what is wrong:" << std :: endl
;
655 std :: cerr
<< msg
<< std :: endl
<< std :: endl
;
657 } else if ( section
. Exists ( "Autoremove" ) == true )
662 size_t const id
= section
. FindULL ( type
. c_str (), VersionCount
);
663 if ( id
== VersionCount
) {
664 _error
-> Warning ( "Unable to parse %s request with id value ' %s '!" , type
. c_str (), section
. FindS ( type
. c_str ()). c_str ());
666 } else if ( id
> Cache
. Head (). VersionCount
) {
667 _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 ());
671 pkgCache :: VerIterator
Ver ( Cache
. GetCache (), Cache
. GetCache (). VerP
+ VerIdx
[ id
]);
672 auto const Pkg
= Ver
. ParentPkg ();
673 if ( type
== "Autoremove" ) {
674 Cache
[ Pkg
]. Marked
= false ;
675 Cache
[ Pkg
]. Garbage
= true ;
676 } else if ( seenOnce
. emplace ( Pkg
-> ID
). second
== false ) {
677 _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 ());
678 } else if ( type
== "Install" ) {
679 if ( Pkg
. CurrentVer () == Ver
) {
680 _error
-> Warning ( "Ignoring Install stanza received for version %s of package %s which is already installed!" ,
681 Ver
. VerStr (), Pkg
. FullName ( false ). c_str ());
683 Cache
. SetCandidateVersion ( Ver
);
684 Cache
. MarkInstall ( Pkg
, false , 0 , false );
686 } else if ( type
== "Remove" ) {
687 if ( Pkg
-> CurrentVer
== 0 )
688 _error
-> Warning ( "Ignoring Remove stanza received for version %s of package %s which isn't installed!" ,
689 Ver
. VerStr (), Pkg
. FullName ( false ). c_str ());
690 else if ( Pkg
. CurrentVer () != Ver
)
691 _error
-> Warning ( "Ignoring Remove stanza received for version %s of package %s which isn't the installed version %s !" ,
692 Ver
. VerStr (), Pkg
. FullName ( false ). c_str (), Pkg
. CurrentVer (). VerStr ());
694 Cache
. MarkDelete ( Ver
. ParentPkg (), false );
700 // ReadLine - first line from the given file descriptor /*{{{*/
701 // ---------------------------------------------------------------------
702 /* Little helper method to read a complete line into a string. Similar to
703 fgets but we need to use the low-level read() here as otherwise the
704 listparser will be confused later on as mixing of fgets and read isn't
705 a supported action according to the manpages and results are undefined */
706 static bool ReadLine ( int const input
, std :: string
& line
) {
711 while (( data
= read ( input
, & one
, sizeof ( one
))) != - 1 ) {
718 if ( line
. empty () == true && isblank ( one
) != 0 )
725 // StringToBool - convert yes/no to bool /*{{{*/
726 // ---------------------------------------------------------------------
727 /* we are not as lazy as we are in the global StringToBool as we really
728 only accept yes/no here */
729 static bool localStringToBool ( std :: string answer
, bool const defValue
) {
730 std :: transform ( answer
. begin (), answer
. end (), answer
. begin (), :: tolower
);
733 else if ( answer
== "no" )
736 _error
-> Warning ( "Value ' %s ' is not a boolean 'yes' or 'no'!" , answer
. c_str ());
740 static bool LineStartsWithAndStrip ( std :: string
& line
, APT :: StringView
const with
) /*{{{*/
742 if ( line
. compare ( 0 , with
. size (), with
. data ()) != 0 )
744 line
= APT :: String :: Strip ( line
. substr ( with
. length ()));
748 static bool ReadFlag ( unsigned int & flags
, std :: string
& line
, APT :: StringView
const name
, unsigned int const setflag
) /*{{{*/
750 if ( LineStartsWithAndStrip ( line
, name
) == false )
752 if ( localStringToBool ( line
, false ))
759 // EDSP::ReadRequest - first stanza from the given file descriptor /*{{{*/
760 bool EDSP :: ReadRequest ( int const input
, std :: list
< std :: string
> & install
,
761 std :: list
< std :: string
> & remove
, unsigned int & flags
)
767 while ( ReadLine ( input
, line
) == true )
769 // Skip empty lines before request
770 if ( line
. empty () == true )
772 // The first Tag must be a request, so search for it
773 if ( LineStartsWithAndStrip ( line
, "Request:" ))
776 while ( ReadLine ( input
, line
) == true )
778 // empty lines are the end of the request
779 if ( line
. empty () == true )
782 std :: list
< std :: string
> * request
= NULL
;
783 if ( LineStartsWithAndStrip ( line
, "Install:" ))
785 else if ( LineStartsWithAndStrip ( line
, "Remove:" ))
787 else if ( ReadFlag ( flags
, line
, "Upgrade:" , ( Request :: UPGRADE_ALL
| Request :: FORBID_REMOVE
| Request :: FORBID_NEW_INSTALL
)) ||
788 ReadFlag ( flags
, line
, "Dist-Upgrade:" , Request :: UPGRADE_ALL
) ||
789 ReadFlag ( flags
, line
, "Upgrade-All:" , Request :: UPGRADE_ALL
) ||
790 ReadFlag ( flags
, line
, "Forbid-New-Install:" , Request :: FORBID_NEW_INSTALL
) ||
791 ReadFlag ( flags
, line
, "Forbid-Remove:" , Request :: FORBID_REMOVE
) ||
792 ReadFlag ( flags
, line
, "Autoremove:" , Request :: AUTOREMOVE
))
794 else if ( LineStartsWithAndStrip ( line
, "Architecture:" ))
795 _config
-> Set ( "APT::Architecture" , line
);
796 else if ( LineStartsWithAndStrip ( line
, "Architectures:" ))
797 _config
-> Set ( "APT::Architectures" , SubstVar ( line
, " " , "," ));
798 else if ( LineStartsWithAndStrip ( line
, "Solver:" ))
799 ; // purely informational line
801 _error
-> Warning ( "Unknown line in EDSP Request stanza: %s " , line
. c_str ());
805 auto const pkgs
= VectorizeString ( line
, ' ' );
806 std :: move ( pkgs
. begin (), pkgs
. end (), std :: back_inserter (* request
));
811 bool EDSP :: ReadRequest ( int const input
, std :: list
< std :: string
> & install
,
812 std :: list
< std :: string
> & remove
, bool & upgrade
,
813 bool & distUpgrade
, bool & autoRemove
)
816 auto const ret
= ReadRequest ( input
, install
, remove
, flags
);
817 autoRemove
= ( flags
& Request :: AUTOREMOVE
);
818 if ( flags
& Request :: UPGRADE_ALL
)
820 if ( flags
& ( Request :: FORBID_NEW_INSTALL
| Request :: FORBID_REMOVE
))
837 // EDSP::ApplyRequest - first stanza from the given file descriptor /*{{{*/
838 bool EDSP :: ApplyRequest ( std :: list
< std :: string
> const & install
,
839 std :: list
< std :: string
> const & remove
,
842 for ( std :: list
< std :: string
>:: const_iterator i
= install
. begin ();
843 i
!= install
. end (); ++ i
) {
844 pkgCache :: PkgIterator P
= Cache
. FindPkg (* i
);
846 _error
-> Warning ( "Package %s is not known, so can't be installed" , i
-> c_str ());
848 Cache
. MarkInstall ( P
, false );
851 for ( std :: list
< std :: string
>:: const_iterator i
= remove
. begin ();
852 i
!= remove
. end (); ++ i
) {
853 pkgCache :: PkgIterator P
= Cache
. FindPkg (* i
);
855 _error
-> Warning ( "Package %s is not known, so can't be installed" , i
-> c_str ());
862 // EDSP::WriteSolutionStanza - to the given file descriptor /*{{{*/
863 bool EDSP :: WriteSolution ( pkgDepCache
& Cache
, FILE * output
)
865 bool const Debug
= _config
-> FindB ( "Debug::EDSP::WriteSolution" , false );
866 for ( pkgCache :: PkgIterator Pkg
= Cache
. PkgBegin (); Pkg
. end () == false ; ++ Pkg
)
868 if ( Cache
[ Pkg
]. Delete () == true )
870 fprintf ( output
, "Remove: %d \n " , _system
-> GetVersionMapping ( Pkg
. CurrentVer ()-> ID
));
872 fprintf ( output
, "Package: %s \n Version: %s \n " , Pkg
. FullName (). c_str (), Pkg
. CurrentVer (). VerStr ());
874 else if ( Cache
[ Pkg
]. NewInstall () == true || Cache
[ Pkg
]. Upgrade () == true )
876 pkgCache :: VerIterator
const CandVer
= Cache
. GetCandidateVersion ( Pkg
);
877 fprintf ( output
, "Install: %d \n " , _system
-> GetVersionMapping ( CandVer
-> ID
));
879 fprintf ( output
, "Package: %s \n Version: %s \n " , Pkg
. FullName (). c_str (), CandVer
. VerStr ());
881 else if ( Cache
[ Pkg
]. Garbage
== true )
883 fprintf ( output
, "Autoremove: %d \n " , _system
-> GetVersionMapping ( Pkg
. CurrentVer ()-> ID
));
885 fprintf ( output
, "Package: %s \n Version: %s \n " , Pkg
. FullName (). c_str (), Pkg
. CurrentVer (). VerStr ());
889 fprintf ( output
, " \n " );
894 bool EDSP :: WriteSolutionStanza ( FileFd
& output
, char const * const Type
, pkgCache :: VerIterator
const & Ver
)
896 bool Okay
= output
. Failed () == false ;
897 WriteOkay ( Okay
, output
, Type
, ": " , _system
-> GetVersionMapping ( Ver
-> ID
));
898 if ( _config
-> FindB ( "Debug::EDSP::WriteSolution" , false ) == true )
899 WriteOkay ( Okay
, output
, " \n Package: " , Ver
. ParentPkg (). FullName (), " \n Version: " , Ver
. VerStr ());
900 return WriteOkay ( Okay
, output
, " \n\n " );
903 // EDSP::WriteProgess - pulse to the given file descriptor /*{{{*/
904 bool EDSP :: WriteProgress ( unsigned short const percent
, const char * const message
, FILE * output
) {
905 fprintf ( output
, "Progress: %s \n " , TimeRFC1123 ( time ( NULL
)). c_str ());
906 fprintf ( output
, "Percentage: %d \n " , percent
);
907 fprintf ( output
, "Message: %s \n\n " , message
);
911 bool EDSP :: WriteProgress ( unsigned short const percent
, const char * const message
, FileFd
& output
) {
912 return WriteOkay ( output
, "Progress: " , TimeRFC1123 ( time ( NULL
)), " \n " ,
913 "Percentage: " , percent
, " \n " ,
914 "Message: " , message
, " \n\n " ) && output
. Flush ();
917 // EDSP::WriteError - format an error message to be send to file descriptor /*{{{*/
918 bool EDSP :: WriteError ( char const * const uuid
, std :: string
const & message
, FILE * output
) {
919 fprintf ( output
, "Error: %s \n " , uuid
);
920 fprintf ( output
, "Message: %s \n\n " , SubstVar ( SubstVar ( message
, " \n\n " , " \n . \n " ), " \n " , " \n " ). c_str ());
923 bool EDSP :: WriteError ( char const * const uuid
, std :: string
const & message
, FileFd
& output
) {
924 return WriteOkay ( output
, "Error: " , uuid
, " \n " ,
925 "Message: " , SubstVar ( SubstVar ( message
, " \n\n " , " \n . \n " ), " \n " , " \n " ),
929 static pid_t
ExecuteExternal ( char const * const type
, char const * const binary
, char const * const configdir
, int * const solver_in
, int * const solver_out
) { /*{{{*/
930 std :: vector
< std :: string
> const solverDirs
= _config
-> FindVector ( configdir
);
932 for ( std :: vector
< std :: string
>:: const_iterator dir
= solverDirs
. begin ();
933 dir
!= solverDirs
. end (); ++ dir
) {
934 file
= flCombine (* dir
, binary
);
935 if ( RealFileExists ( file
. c_str ()) == true )
940 if ( file
. empty () == true )
942 _error
-> Error ( "Can't call external %s ' %s ' as it is not in a configured directory!" , type
, binary
);
945 int external
[ 4 ] = {- 1 , - 1 , - 1 , - 1 };
946 if ( pipe ( external
) != 0 || pipe ( external
+ 2 ) != 0 )
948 _error
-> Errno ( "Resolve" , "Can't create needed IPC pipes for EDSP" );
951 for ( int i
= 0 ; i
< 4 ; ++ i
)
952 SetCloseExec ( external
[ i
], true );
954 pid_t Solver
= ExecFork ();
956 dup2 ( external
[ 0 ], STDIN_FILENO
);
957 dup2 ( external
[ 3 ], STDOUT_FILENO
);
958 const char * calling
[ 2 ] = { file
. c_str (), 0 };
959 execv ( calling
[ 0 ], ( char **) calling
);
960 std :: cerr
<< "Failed to execute " << type
<< " '" << binary
<< "'!" << std :: endl
;
966 if ( WaitFd ( external
[ 1 ], true , 5 ) == false )
968 _error
-> Errno ( "Resolve" , "Timed out while Waiting on availability of %s stdin" , type
);
972 * solver_in
= external
[ 1 ];
973 * solver_out
= external
[ 2 ];
977 // EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/
978 pid_t
EDSP :: ExecuteSolver ( const char * const solver
, int * const solver_in
, int * const solver_out
, bool ) {
979 return ExecuteExternal ( "solver" , solver
, "Dir::Bin::Solvers" , solver_in
, solver_out
);
981 bool EDSP :: ExecuteSolver ( const char * const solver
, int * solver_in
, int * solver_out
) {
982 if ( ExecuteSolver ( solver
, solver_in
, solver_out
, true ) == 0 )
987 // EDSP::ResolveExternal - resolve problems by asking external for help {{{*/
988 bool EDSP :: ResolveExternal ( const char * const solver
, pkgDepCache
& Cache
,
989 unsigned int const flags
, OpProgress
* Progress
) {
990 int solver_in
, solver_out
;
991 pid_t
const solver_pid
= EDSP :: ExecuteSolver ( solver
, & solver_in
, & solver_out
, true );
996 if ( output
. OpenDescriptor ( solver_in
, FileFd :: WriteOnly
| FileFd :: BufferedWrite
, true ) == false )
997 return _error
-> Errno ( "ResolveExternal" , "Opening solver %s stdin on fd %d for writing failed" , solver
, solver_in
);
999 bool Okay
= output
. Failed () == false ;
1000 if ( Progress
!= NULL
)
1001 Progress
-> OverallProgress ( 0 , 100 , 5 , _ ( "Execute external solver" ));
1002 Okay
&= EDSP :: WriteRequest ( Cache
, output
, flags
, Progress
);
1003 if ( Progress
!= NULL
)
1004 Progress
-> OverallProgress ( 5 , 100 , 20 , _ ( "Execute external solver" ));
1005 Okay
&= EDSP :: WriteScenario ( Cache
, output
, Progress
);
1008 if ( Progress
!= NULL
)
1009 Progress
-> OverallProgress ( 25 , 100 , 75 , _ ( "Execute external solver" ));
1010 if ( Okay
&& EDSP :: ReadResponse ( solver_out
, Cache
, Progress
) == false )
1013 return ExecWait ( solver_pid
, solver
);
1015 bool EDSP :: ResolveExternal ( const char * const solver
, pkgDepCache
& Cache
,
1016 bool const upgrade
, bool const distUpgrade
,
1017 bool const autoRemove
, OpProgress
* Progress
) {
1018 unsigned int flags
= 0 ;
1020 flags
|= Request :: AUTOREMOVE
;
1022 flags
|= Request :: UPGRADE_ALL
| Request :: FORBID_REMOVE
| Request :: FORBID_NEW_INSTALL
;
1024 flags
|= Request :: UPGRADE_ALL
;
1025 return ResolveExternal ( solver
, Cache
, flags
, Progress
);