]>
git.saurik.com Git - apt.git/blob - apt-private/private-show.cc
4 #include <apt-pkg/cachefile.h>
5 #include <apt-pkg/cacheset.h>
6 #include <apt-pkg/cmndline.h>
7 #include <apt-pkg/error.h>
8 #include <apt-pkg/fileutl.h>
9 #include <apt-pkg/indexfile.h>
10 #include <apt-pkg/pkgrecords.h>
11 #include <apt-pkg/pkgsystem.h>
12 #include <apt-pkg/sourcelist.h>
13 #include <apt-pkg/strutl.h>
14 #include <apt-pkg/tagfile.h>
15 #include <apt-pkg/cacheiterators.h>
16 #include <apt-pkg/configuration.h>
17 #include <apt-pkg/depcache.h>
18 #include <apt-pkg/macros.h>
19 #include <apt-pkg/pkgcache.h>
20 #include <apt-pkg/policy.h>
22 #include <apt-private/private-cacheset.h>
23 #include <apt-private/private-output.h>
24 #include <apt-private/private-show.h>
33 static bool OpenPackagesFile ( pkgCacheFile
& CacheFile
, pkgCache :: VerIterator
const & V
, /*{{{*/
34 FileFd
& PkgF
, pkgCache :: VerFileIterator
& Vf
)
36 pkgCache
const * const Cache
= CacheFile
. GetPkgCache ();
37 if ( unlikely ( Cache
== NULL
))
40 // Find an appropriate file
42 for (; Vf
. end () == false ; ++ Vf
)
43 if (( Vf
. File ()-> Flags
& pkgCache :: Flag :: NotSource
) == 0 )
48 // Check and load the package list file
49 pkgCache :: PkgFileIterator I
= Vf
. File ();
50 if ( I
. IsOk () == false )
51 return _error
-> Error ( _ ( "Package file %s is out of sync." ), I
. FileName ());
54 return PkgF
. Open ( I
. FileName (), FileFd :: ReadOnly
, FileFd :: Extension
);
57 static APT_PURE
unsigned char const * skipDescriptionFields ( unsigned char const * DescP
) /*{{{*/
59 char const * const TagName
= " \n Description" ;
60 size_t const TagLen
= strlen ( TagName
);
61 while (( DescP
= ( unsigned char *) strchr (( char *) DescP
, ' \n ' )) != NULL
)
65 else if ( strncmp (( char *) DescP
, TagName
, TagLen
) == 0 )
75 bool DisplayRecordV1 ( pkgCacheFile
& CacheFile
, pkgCache :: VerIterator
const & V
, /*{{{*/
79 pkgCache :: VerFileIterator Vf
;
80 if ( OpenPackagesFile ( CacheFile
, V
, PkgF
, Vf
) == false )
83 pkgCache
* const Cache
= CacheFile
. GetPkgCache ();
84 if ( unlikely ( Cache
== NULL
))
87 // Read the record (and ensure that it ends with a newline and NUL)
88 unsigned char * Buffer
= new unsigned char [ Cache
-> HeaderP
-> MaxVerFileSize
+ 2 ];
89 Buffer
[ Vf
-> Size
] = ' \n ' ;
90 Buffer
[ Vf
-> Size
+ 1 ] = '\0' ;
91 if ( PkgF
. Seek ( Vf
-> Offset
) == false ||
92 PkgF
. Read ( Buffer
, Vf
-> Size
) == false )
98 // Get a pointer to start of Description field
99 const unsigned char * DescP
= ( unsigned char *) strstr (( char *) Buffer
, " \n Description" );
103 DescP
= Buffer
+ Vf
-> Size
;
105 // Write all but Description
106 size_t const length
= DescP
- Buffer
;
107 if ( length
!= 0 && FileFd :: Write ( STDOUT_FILENO
, Buffer
, length
) == false )
113 // Show the right description
114 pkgRecords
Recs (* Cache
);
115 pkgCache :: DescIterator Desc
= V
. TranslatedDescription ();
116 if ( Desc
. end () == false )
118 pkgRecords :: Parser
& P
= Recs
. Lookup ( Desc
. FileList ());
119 out
<< "Description" << ( ( strcmp ( Desc
. LanguageCode (), "" ) != 0 ) ? "-" : "" ) << Desc
. LanguageCode () << ": " << P
. LongDesc ();
120 out
<< std :: endl
<< "Description-md5: " << Desc
. md5 () << std :: endl
;
122 // Find the first field after the description (if there is any)
123 DescP
= skipDescriptionFields ( DescP
);
125 // else we have no translation, so we found a lonely Description-md5 -> don't skip it
127 // write the rest of the buffer, but skip mixed in Descriptions* fields
128 while ( DescP
!= NULL
)
130 const unsigned char * const Start
= DescP
;
131 const unsigned char * End
= ( unsigned char *) strstr (( char *) DescP
, " \n Description" );
134 End
= & Buffer
[ Vf
-> Size
];
139 ++ End
; // get the newline into the output
140 DescP
= skipDescriptionFields ( End
+ strlen ( "Description" ));
142 size_t const length
= End
- Start
;
143 if ( length
!= 0 && FileFd :: Write ( STDOUT_FILENO
, Start
, length
) == false )
149 // write a final newline after the last field
156 static bool DisplayRecordV2 ( pkgCacheFile
& CacheFile
, pkgCache :: VerIterator
const & V
, /*{{{*/
160 pkgCache :: VerFileIterator Vf
;
161 if ( OpenPackagesFile ( CacheFile
, V
, PkgF
, Vf
) == false )
164 // Check and load the package list file
165 pkgCache :: PkgFileIterator I
= Vf
. File ();
166 if ( I
. IsOk () == false )
167 return _error
-> Error ( _ ( "Package file %s is out of sync." ), I
. FileName ());
169 // find matching sources.list metaindex
170 pkgSourceList
* SrcList
= CacheFile
. GetSourceList ();
172 if ( SrcList
-> FindIndex ( I
, Index
) == false &&
173 _system
-> FindIndex ( I
, Index
) == false )
174 return _error
-> Error ( "Can not find indexfile for Package %s ( %s )" ,
175 V
. ParentPkg (). Name (), V
. VerStr ());
176 std :: string source_index_file
= Index
-> Describe ( true );
180 pkgTagFile
TagF (& PkgF
);
182 if ( TagF
. Jump ( Tags
, V
. FileList ()-> Offset
) == false )
183 return _error
-> Error ( "Internal Error, Unable to parse a package record" );
186 std :: string installed_size
;
187 if ( Tags
. FindI ( "Installed-Size" ) > 0 )
188 strprintf ( installed_size
, " %s B" , SizeToStr ( Tags
. FindI ( "Installed-Size" )* 1024 ). c_str ());
190 installed_size
= _ ( "unknown" );
191 std :: string package_size
;
192 if ( Tags
. FindI ( "Size" ) > 0 )
193 strprintf ( package_size
, " %s B" , SizeToStr ( Tags
. FindI ( "Size" )). c_str ());
195 package_size
= _ ( "unknown" );
197 const char * manual_installed
= nullptr ;
198 if ( V
. ParentPkg (). CurrentVer () == V
)
200 pkgDepCache
* depCache
= CacheFile
. GetDepCache ();
201 if ( unlikely ( depCache
== nullptr ))
203 pkgDepCache :: StateCache
& state
= (* depCache
)[ V
. ParentPkg ()];
204 manual_installed
= !( state
. Flags
& pkgCache :: Flag :: Auto
) ? "yes" : "no" ;
207 // FIXME: add verbose that does not do the removal of the tags?
208 std :: vector
< pkgTagSection :: Tag
> RW
;
209 // delete, apt-cache show has this info and most users do not care
210 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "MD5sum" ));
211 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "SHA1" ));
212 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "SHA256" ));
213 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "SHA512" ));
214 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Filename" ));
215 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Multi-Arch" ));
216 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Architecture" ));
217 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Conffiles" ));
218 // we use the translated description
219 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Description" ));
220 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Description-md5" ));
222 RW
. push_back ( pkgTagSection :: Tag :: Rewrite ( "Installed-Size" , installed_size
));
223 RW
. push_back ( pkgTagSection :: Tag :: Remove ( "Size" ));
224 RW
. push_back ( pkgTagSection :: Tag :: Rewrite ( "Download-Size" , package_size
));
226 if ( manual_installed
!= nullptr )
227 RW
. push_back ( pkgTagSection :: Tag :: Rewrite ( "APT-Manual-Installed" , manual_installed
));
228 RW
. push_back ( pkgTagSection :: Tag :: Rewrite ( "APT-Sources" , source_index_file
));
231 if ( stdoutfd
. OpenDescriptor ( STDOUT_FILENO
, FileFd :: WriteOnly
, false ) == false ||
232 Tags
. Write ( stdoutfd
, TFRewritePackageOrder
, RW
) == false || stdoutfd
. Close () == false )
233 return _error
-> Error ( "Internal Error, Unable to parse a package record" );
235 // write the description
236 pkgCache
* const Cache
= CacheFile
. GetPkgCache ();
237 if ( unlikely ( Cache
== NULL
))
239 pkgRecords
Recs (* Cache
);
240 // FIXME: show (optionally) all available translations(?)
241 pkgCache :: DescIterator Desc
= V
. TranslatedDescription ();
242 if ( Desc
. end () == false )
244 pkgRecords :: Parser
& P
= Recs
. Lookup ( Desc
. FileList ());
245 out
<< "Description: " << P
. LongDesc ();
248 // write a final newline (after the description)
249 out
<< std :: endl
<< std :: endl
;
254 bool ShowPackage ( CommandLine
& CmdL
) /*{{{*/
256 pkgCacheFile CacheFile
;
257 CacheSetHelperVirtuals
helper ( true , GlobalError :: NOTICE
);
258 APT :: CacheSetHelper :: VerSelector
const select
= _config
-> FindB ( "APT::Cache::AllVersions" , true ) ?
259 APT :: CacheSetHelper :: ALL
: APT :: CacheSetHelper :: CANDIDATE
;
260 APT :: VersionList
const verset
= APT :: VersionList :: FromCommandLine ( CacheFile
, CmdL
. FileList
+ 1 , select
, helper
);
261 int const ShowVersion
= _config
-> FindI ( "APT::Cache::Show::Version" , 1 );
262 for ( APT :: VersionList :: const_iterator Ver
= verset
. begin (); Ver
!= verset
. end (); ++ Ver
)
263 if ( ShowVersion
<= 1 )
265 if ( DisplayRecordV1 ( CacheFile
, Ver
, std :: cout
) == false )
269 if ( DisplayRecordV2 ( CacheFile
, Ver
, c1out
) == false )
272 if ( select
== APT :: CacheSetHelper :: CANDIDATE
)
274 APT :: VersionList
const verset_all
= APT :: VersionList :: FromCommandLine ( CacheFile
, CmdL
. FileList
+ 1 , APT :: CacheSetHelper :: ALL
, helper
);
275 int const records
= verset_all
. size () - verset
. size ();
277 _error
-> Notice ( P_ ( "There is %i additional record. Please use the '-a' switch to see it" , "There are %i additional records. Please use the '-a' switch to see them." , records
), records
);
280 if ( _config
-> FindB ( "APT::Cache::ShowVirtuals" , false ) == true )
281 for ( APT :: PackageSet :: const_iterator Pkg
= helper
. virtualPkgs
. begin ();
282 Pkg
!= helper
. virtualPkgs
. end (); ++ Pkg
)
284 c1out
<< "Package: " << Pkg
. FullName ( true ) << std :: endl
;
285 c1out
<< "State: " << _ ( "not a real package (virtual)" ) << std :: endl
;
286 // FIXME: show providers, see private-cacheset.h
287 // CacheSetHelperAPTGet::showVirtualPackageErrors()
290 if ( verset
. empty () == true )
292 if ( helper
. virtualPkgs
. empty () == true )
293 return _error
-> Error ( _ ( "No packages found" ));
295 _error
-> Notice ( _ ( "No packages found" ));
301 bool ShowSrcPackage ( CommandLine
& CmdL
) /*{{{*/
303 pkgCacheFile CacheFile
;
304 pkgSourceList
* List
= CacheFile
. GetSourceList ();
305 if ( unlikely ( List
== NULL
))
308 // Create the text record parsers
309 pkgSrcRecords
SrcRecs (* List
);
310 if ( _error
-> PendingError () == true )
314 for ( const char ** I
= CmdL
. FileList
+ 1 ; * I
!= 0 ; I
++)
318 pkgSrcRecords :: Parser
* Parse
;
319 bool found_this
= false ;
320 while (( Parse
= SrcRecs
. Find (* I
, false )) != 0 ) {
321 // SrcRecs.Find() will find both binary and source names
322 if ( _config
-> FindB ( "APT::Cache::Only-Source" , false ) == true )
323 if ( Parse
-> Package () != * I
)
325 std :: cout
<< Parse
-> AsStr () << std :: endl
;;
329 if ( found_this
== false ) {
330 _error
-> Warning ( _ ( "Unable to locate package %s " ),* I
);
335 _error
-> Notice ( _ ( "No packages found" ));
339 // Policy - Show the results of the preferences file /*{{{*/
340 bool Policy ( CommandLine
& CmdL
)
342 pkgCacheFile CacheFile
;
343 pkgCache
* Cache
= CacheFile
. GetPkgCache ();
344 pkgPolicy
* Plcy
= CacheFile
. GetPolicy ();
345 pkgSourceList
* SrcList
= CacheFile
. GetSourceList ();
346 if ( unlikely ( Cache
== NULL
|| Plcy
== NULL
|| SrcList
== NULL
))
349 bool OldPolicy
= _config
-> FindI ( "APT::Policy" , 1 ) < 1 ;
351 // Print out all of the package files
352 if ( CmdL
. FileList
[ 1 ] == 0 )
354 std :: cout
<< _ ( "Package files:" ) << std :: endl
;
355 for ( pkgCache :: PkgFileIterator F
= Cache
-> FileBegin (); F
. end () == false ; ++ F
)
357 if ( F
. Flagged ( pkgCache :: Flag :: NoPackages
))
359 // Locate the associated index files so we can derive a description
361 if ( SrcList
-> FindIndex ( F
, Indx
) == false &&
362 _system
-> FindIndex ( F
, Indx
) == false )
363 return _error
-> Error ( _ ( "Cache is out of sync, can't x-ref a package file" ));
366 Plcy
-> GetPriority ( F
), Indx
-> Describe ( true ). c_str ());
368 // Print the reference information for the package
369 std :: string Str
= F
. RelStr ();
370 if ( Str
. empty () == false )
371 printf ( " release %s \n " , F
. RelStr (). c_str ());
372 if ( F
. Site () != 0 && F
. Site ()[ 0 ] != 0 )
373 printf ( " origin %s \n " , F
. Site ());
376 // Show any packages have explicit pins
377 std :: cout
<< _ ( "Pinned packages:" ) << std :: endl
;
378 pkgCache :: PkgIterator I
= Cache
-> PkgBegin ();
379 for (; I
. end () != true ; ++ I
)
381 // Old code for debugging
384 if ( Plcy
-> GetPriority ( I
) == 0 )
387 // Print the package name and the version we are forcing to
388 std :: cout
<< " " << I
. FullName ( true ) << " -> " ;
390 pkgCache :: VerIterator V
= Plcy
-> GetMatch ( I
);
392 std :: cout
<< _ ( "(not found)" ) << std :: endl
;
394 std :: cout
<< V
. VerStr () << std :: endl
;
399 for ( pkgCache :: VerIterator V
= I
. VersionList (); ! V
. end (); ++ V
) {
400 auto Prio
= Plcy
-> GetPriority ( V
, false );
405 // Print the package name and the version we are forcing to
406 ioprintf ( std :: cout
, _ ( " %s -> %s with priority %d \n " ), I
. FullName ( true ). c_str (), V
. VerStr (), Prio
);
412 char const * const msgInstalled
= _ ( " Installed: " );
413 char const * const msgCandidate
= _ ( " Candidate: " );
414 short const InstalledLessCandidate
=
415 mbstowcs ( NULL
, msgInstalled
, 0 ) - mbstowcs ( NULL
, msgCandidate
, 0 );
416 short const deepInstalled
=
417 ( InstalledLessCandidate
< 0 ? ( InstalledLessCandidate
*- 1 ) : 0 ) - 1 ;
418 short const deepCandidate
=
419 ( InstalledLessCandidate
> 0 ? ( InstalledLessCandidate
) : 0 ) - 1 ;
421 // Print out detailed information for each package
422 APT :: CacheSetHelper
helper ( true , GlobalError :: NOTICE
);
423 APT :: PackageList pkgset
= APT :: PackageList :: FromCommandLine ( CacheFile
, CmdL
. FileList
+ 1 , helper
);
424 for ( APT :: PackageList :: const_iterator Pkg
= pkgset
. begin (); Pkg
!= pkgset
. end (); ++ Pkg
)
426 std :: cout
<< Pkg
. FullName ( true ) << ":" << std :: endl
;
429 std :: cout
<< msgInstalled
<< OutputInDepth ( deepInstalled
, " " );
430 if ( Pkg
-> CurrentVer
== 0 )
431 std :: cout
<< _ ( "(none)" ) << std :: endl
;
433 std :: cout
<< Pkg
. CurrentVer (). VerStr () << std :: endl
;
436 std :: cout
<< msgCandidate
<< OutputInDepth ( deepCandidate
, " " );
437 pkgCache :: VerIterator V
= Plcy
-> GetCandidateVer ( Pkg
);
439 std :: cout
<< _ ( "(none)" ) << std :: endl
;
441 std :: cout
<< V
. VerStr () << std :: endl
;
444 if ( OldPolicy
&& Plcy
-> GetPriority ( Pkg
) != 0 )
446 std :: cout
<< _ ( " Package pin: " );
447 V
= Plcy
-> GetMatch ( Pkg
);
449 std :: cout
<< _ ( "(not found)" ) << std :: endl
;
451 std :: cout
<< V
. VerStr () << std :: endl
;
454 // Show the priority tables
455 std :: cout
<< _ ( " Version table:" ) << std :: endl
;
456 for ( V
= Pkg
. VersionList (); V
. end () == false ; ++ V
)
458 if ( Pkg
. CurrentVer () == V
)
459 std :: cout
<< " *** " << V
. VerStr ();
461 std :: cout
<< " " << V
. VerStr ();
462 if ( _config
-> FindI ( "APT::Policy" , 1 ) < 1 )
463 std :: cout
<< " " << Plcy
-> GetPriority ( Pkg
) << std :: endl
;
465 std :: cout
<< " " << Plcy
-> GetPriority ( V
) << std :: endl
;
466 for ( pkgCache :: VerFileIterator VF
= V
. FileList (); VF
. end () == false ; ++ VF
)
468 // Locate the associated index files so we can derive a description
470 if ( SrcList
-> FindIndex ( VF
. File (), Indx
) == false &&
471 _system
-> FindIndex ( VF
. File (), Indx
) == false )
472 return _error
-> Error ( _ ( "Cache is out of sync, can't x-ref a package file" ));
473 printf ( " %4 i %s \n " , Plcy
-> GetPriority ( VF
. File ()),
474 Indx
-> Describe ( true ). c_str ());