
    )gQ                     (   S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSK	J
r
JrJrJrJrJrJrJrJrJr   SSKJr  SSKJrJrJr  SSKJr  SSKrSrS	r / S
Qr!Sr"/ SQr#Sr$Sr%Sr&Sr' " S S\(5      r) " S S\RT                  5      r+ " S S\5      r, " S S5      r- " S S\-5      r. " S S\-5      r/ " S S\5      r0\1S:X  aE  \0" \Rd                  S    S!9r3\3Rh                  Rk                  5       r5\6" \5Ro                  S5      5        gg! \ a     Nf = f)"zWRepresentation of Debian binary package (.deb) files


Debfile Classes
===============
    N)Path)
AnyBinaryIODictIOIteratorListOptionalTextUnionoverload)Literal)ArFileArErrorArMember)	Changelogzdata.tarzcontrol.tar)gzbz2xzlzmazstzdebian-binary)preinstpostinstprermpostrmconfigcontrolzusr/share/doc/%s/changelog.gzz$usr/share/doc/%s/changelog.Debian.gzmd5sumsc                   *    \ rS rSrSrS\S\4S jrSrg)_NormedFilePathF   a^  File path class for squashing ./ at the start of files for TarFile

This class only replaces the __eq__ method of the file path comparison
so that "./" is always added to the start of the file path
meaning that "is this the right file to extract" will be true when
the code asks for "./control" but the control.tar member contains
the file "control"
valuereturnc                     [        U 5      n[        U5      nUS:X  a  SnOUR                  S5      (       d  SU-   nUS:X  a  SnX#:H  $ UR                  S5      (       d  SU-   nX#:H  $ )N../)str
startswith)selfr"   s1s2s       0/usr/lib/python3/dist-packages/debian/debfile.py__eq___NormedFilePath.__eq__P   sn    YZ9Bt$$B9B x t$$Bx     N)	__name__
__module____qualname____firstlineno____doc__r   boolr-   __static_attributes__r0   r/   r,   r    r    F   s    C D r/   r    c                   f    \ rS rSr% SrSr\\   \S'   S\\   4S jr	S\SS4S jr
\" \	\
5      rS	rg)
_NormedTarInfo^   a  TarInfo replacement that uses file path comparison that squashes ./

This class uses the above _NormedFilePath class for file paths when
iterating or inspecting the members of a TarFile. The _NormedFilePath
normalises the file path when inspecting or extracting from a .deb file.

The class replaces the 'name' member that is normally a str with
a property that addresses a _NormedFilePath.

The control tarball members of the .deb may contain an optional entry
for "." and prefix all entries in the tarball with "./".  Archives
generated by dpkg have this prefix but third party tools might not. The
published spec for the .deb file format, deb(5) from dpkg-dev, explicitly
permits this difference and thus it should be supported here.

See https://bugs.debian.org/1031674 for more detail.
N_namer#   c                     U R                   $ Nr;   r)   s    r,   	_get_name_NormedTarInfo._get_names   s    zzr/   namec                 $    [        U5      U l        g r=   )r    r;   )r)   rB   s     r,   	_set_name_NormedTarInfo._set_namev   s    $T*
r/   r>   )r1   r2   r3   r4   r5   r;   r
   r'   __annotations__r@   rD   propertyrB   r7   r0   r/   r,   r9   r9   ^   sH    $  E8C=8C= +c +d + Iy)Dr/   r9   c                       \ rS rSrSrg)DebError|   r0   Nr1   r2   r3   r4   r7   r0   r/   r,   rI   rI   |   s    r/   rI   c                       \ rS rSrSrS rS r\S 5       rS\	S\
\	   4S jrSS	 jr\SS j5       r\SS j5       rSS jr\   SS j5       r\  SS j5       r   SS jrS rS rS rSS jrSrg
)DebPart   al  'Part' of a .deb binary package.

A .deb package is considered as made of 2 parts: a 'data' part
(corresponding to the possibly compressed 'data.tar' archive embedded
in a .deb) and a 'control' part (the 'control.tar.gz' archive). Each of
them is represented by an instance of this class. Each archive should
be a compressed tar archive although an uncompressed data.tar is permitted;
supported compression formats are: .tar.gz, .tar.bz2, .tar.xz .

When referring to file members of the underlying .tar.gz archive, file
names can be specified in one of 3 formats "file", "./file", "/file". In
all cases the file is considered relative to the root of the archive. For
the control part the preferred mechanism is the first one (as in
deb.control.get_content('control') ); for the data part the preferred
mechanism is the third one (as in deb.data.get_file('/etc/vim/vimrc') ).
c                     Xl         S U l        g r=   )_DebPart__member_DebPart__tgz)r)   members     r,   __init__DebPart.__init__   s    
r/   c                   ^  U 4S jnT R                   c  T R                  R                  n[        R                  R                  U5      S   SS nU[        ;   d  U[        :X  d
  U[        :X  aI  US:X  a  U" SS/5      nOT R                  n [        R                  " US[        S9T l         T R                   $ [        S
U-  5      eT R                   $ ! [        R                  [        R                  4 a  n[        S	U-  5      eSnAff = f)zReturn a TarFile object corresponding to this part of a .deb
package.

Despite the name, this method gives access to various kind of
compressed tar archives, not only gzipped ones.
c                   >^  SS K nSS KmUR                  U UR                  UR                  SU4S jS9nUR                  TR                  R                  5       5      S   nUR                  S:w  a-  [        S	SR                  U 5      < S
UR                  < S35      e[        R                  " U5      $ ! [        [
        4 a(  n[        SSR                  U 5      < SU< S35      eS nAff = f)Nr   Fc                  P   > T R                  T R                  T R                  5      $ r=   )signalSIGPIPESIG_DFL)rX   s   r,   <lambda>9DebPart.tgz.<locals>._custom_decompress.<locals>.<lambda>   s    MM&..&..Ar/   )stdinstdoutuniversal_newlines
preexec_fnzerror while running command ' z' as subprocess: ''z	command 'z' has failed with code ')
subprocessrX   PopenPIPEOSError
ValueErrorrI   joincommunicaterP   read
returncodeioBytesIO)command_listrc   procedatarX   r)   s        @r,   _custom_decompress'DebPart.tgz.<locals>._custom_decompress   s    <! "'' $//*//', B	 (  ##DMM$6$6$89!<D!# # 6 I J J ::d## Z( < # 6 ; < <<s   3B6 6C.#C))C.N   r   unzstdz--stdoutzr:*)fileobjmodetarinfoz#tarfile has returned an error: '%s'z"part '%s' has unexpected extension)rQ   rP   rB   ospathsplitext	PART_EXTS	DATA_PART	CTRL_PARTtarfileopenr9   	ReadErrorCompressionErrorrI   )r)   rr   rB   	extensionbufferrp   s   `     r,   tgzDebPart.tgz   s    	$4 ::==%%D((.q1!"5II%):di>O %/:0FGF!]]FN!(f5R`!aDJ
 zz CdJKKzz	  ))7+C+CD N"#H1#LMMNs   C $D5DDc                     [        U 5      R                  SS5      n U R                  S5      (       a  U $ U R                  S5      (       a  SU -   $ U S:X  a  gSU -   $ )zntry (not so hard) to obtain a member file name in a form that is
stored in the .tar.gz, i.e. starting with ./ \/r&   r%   )r'   replacer(   )fnames    r,   __normalize_memberDebPart.__normalize_member   s_     E
""4-D!!LC  ;C<e|r/   rz   r#   c                     / nUR                  S5      SS  H  nUR                  U5        [        R                  R	                  SR                  U5      5      n[        R                  U5      nU R                  5       R                  U5      nUR                  5       (       d  M  UR                  R                  S5      (       a)  UR                  R                  S5      nUR                  nM  UR                  US'   M     [        R                  [        R                  R	                  W5      5      $ ! [         a     gf = f)zwalk the path following symlinks

returns:
    resolved_path, info

if the path is not found even after following symlinks within the
archive, then None is returned.
r   rt   N)splitappendry   rz   normpathrh   rM   _DebPart__normalize_memberr   	getmemberissymlinknamer(   KeyError)r)   rz   resolved_path_partspathpartcurrpathtinfos         r,   __resolve_symlinksDebPart.__resolve_symlinks   s    	"$ JJsOAB/#**8477++CHH5H,IJ"55h?
,,X6 ;;==~~0055.3nn.B.B3.G+#(>> 38..+B/% 00 ))"''*:*:8*DEE	  		s   BD3 %AD3 3
E ?E c                     [         R                  U5      nU R                  5       R                  5       nX;   a  gU(       a  U R	                  U5      nUSL$ X;   $ )z]Check if this part contains a given file name.

Symlinks within the archive can be followed.
TN)rM   r   r   getnames_DebPart__resolve_symlinks)r)   r   follow_symlinksnames
fname_reals        r,   has_fileDebPart.has_file  sV     **51
##%>007JT))~r/   Nc                     g r=   r0   r)   r   encodingerrorsr   s        r,   get_fileDebPart.get_file       	r/   c                     g r=   r0   r   s        r,   r   r     r   r/   c                 >   [         R                  U5      nU(       a!  U R                  U5      nUc  [        S5      eUn U R	                  5       R                  U5      nUc  [        S5      eUb  [        R                  " XbUS9$ U$ ! [         a    [        S5      ef = f)zReturn a file object corresponding to a given file name.

If encoding is given, then the file object will return Unicode data;
otherwise, it will return binary data.

If follow_symlinks is True, then symlinks within the archive will be
followed.
zFile not found inside packager   r   )	rM   r   r   rI   r   extractfiler   rl   TextIOWrapper)r)   r   r   r   r   r   fobjs          r,   r   r   "  s     **51007J!>??E	<88:))%0D <:;;##DFKK  	<:;;	<s   B Bc                     g r=   r0   r   s        r,   get_contentDebPart.get_contentB       	r/   c                     g r=   r0   r   s        r,   r   r   L  r   r/   c                     U R                  [        U5      X#US9nSnU(       a   UR                  5       nUR                  5         U$ )a  Return the string content of a given file, or None (e.g. for
directories).

If encoding is given, then the content will be a Unicode object;
otherwise, it will contain binary data.

If follow_symlinks is True, then symlinks within the archive will be
followed.
)r   r   r   N)r   r'   rj   close)r)   r   r   r   r   fcontents          r,   r   r   V  sG      MMJ+  

 ffhGGGIr/   c                 P    [        U R                  5       R                  5       5      $ r=   )iterr   r   r?   s    r,   __iter__DebPart.__iter__s  s    DHHJ'')**r/   c                 $    U R                  U5      $ r=   )r   r)   r   s     r,   __contains__DebPart.__contains__w  s    }}U##r/   c                 $    U R                  U5      $ r=   )r   r   s     r,   __getitem__DebPart.__getitem__{  s    &&r/   c                 8    U R                   R                  5         g r=   )rP   r   r?   s    r,   r   DebPart.close  s    r/   )__member__tgz)F)NNF)NFr#   N)r1   r2   r3   r4   r5   rS   r   staticmethodr   r'   r
   r   r   r   r   r   r   r   r   r   r7   r0   r/   r,   rM   rM      s    "
4l  &#Fs #Fx} #FJ$    @  "$)	    $)	  "$)	:+$'r/   rM   c                       \ rS rSrSrg)DebDatai  r0   NrK   r0   r/   r,   r   r     s    r/   r   c            
           \ rS rSrS\\\4   4S jrS\R                  R                  4S jr\SS j5       r\SS\S\\   S\\\4   4S	 jj5       rSS
 jrSrg)
DebControli  r#   c                     0 n[          H5  nU R                  U5      (       d  M  U R                  U5      nUc  M1  X1U'   M7     U$ )zfReturn a dictionary of maintainer scripts (postinst, prerm, ...)
mapping script names to script text. )MAINT_SCRIPTSr   r   )r)   scriptsr   rq   s       r,   r   DebControl.scripts  sF     %'"E}}U##''.#%)EN	 # r/   c                 f    [         R                  R                  U R                  [        5      5      $ )zReturn the debian/control as a deb822.DebControl (a Debian-specific dict-like
class) object.

For a string representation of debian/control try
.get_content('control') )debiandeb822r   r   CONTROL_FILEr?   s    r,   
debcontrolDebControl.debcontrol  s$     }}''(8(8(FGGr/   Nc                     g r=   r0   r)   r   r   s      r,   r   DebControl.md5sums  r   r/   r   r   c                     g r=   r0   r   s      r,   r   r         r/   c                    U R                  [        5      (       d  [        S[        -  5      eU R                  [        XS9n0 nSnUc  SnUR	                  5        HS  nUR                  U5      R                  SS5      u  px[        U[        5      (       a  UR                  5       XH'   MO  XtU'   MU     UR                  5         U$ )a  Return a dictionary mapping filenames (of the data part) to
md5sums. Fails if the control part does not contain a 'md5sum' file.

Keys of the returned dictionary are the left-hand side values of lines
in the md5sums member of control.tar.gz, usually file names relative to
the file system root (without heading '/' or './').

The returned keys are Unicode objects if an encoding is specified,
otherwise binary. The returned values are always Unicode.z('%s' file not found, can't list MD5 sumsr   z
Ns   
rt   )r   MD5_FILErI   r   	readlinesrstripr   
isinstancebytesdecoder   )	r)   r   r   md5_filesumsnewlinelinemd5r   s	            r,   r   r     s     }}X&&:XEG G ==H=L!%+G&&(DW-33D!<JC#u%%!jjl!U ) 	r/   r0   NNr=   )r1   r2   r3   r4   r   r'   r   r   r   r   r   r   r   r   r
   r7   r0   r/   r,   r   r     s~    c5j) HFMM44 H    Xc] d3PS8n  r/   r   c            
       8   \ rS rSrSrSS jrSS jr\S\4S j5       r	\S 5       r
\S	 5       rS\R                  R                  4S
 jrS\\\4   4S jr\SS j5       r\SS\S\\   S\\\4   4S jj5       rSS jrS rSS jrSS jrS\S\S\SS4S jrSrg)DebFilei  a  Representation of a .deb file (a Debian binary package)

DebFile objects have the following (read-only) properties:
    - version       debian .deb file format version (not related with the
                    contained package version), 2.0 at the time of writing
                    for all .deb packages in the Debian archive
    - data          DebPart object corresponding to the data.tar.gz (or
                    other compressed or uncompressed tar) archive contained
                    in the .deb file
    - control       DebPart object corresponding to the control.tar.gz (or
                    other compressed tar) archive contained in the .deb
                    file
Nc                 F  ^ [         R                  " XX#5        [        U R                  5       5      mS[        S[        4U4S jjn[
        T;  a  [        S[
        -  5      e0 U l        [        U R                  U" [        5      5      5      U R                  [        '   [        U R                  U" [        5      5      5      U R                  [        '   S U l        U R                  [
        5      nUR                  5       R                  5       U l        UR#                  5         g )Nbasenamer#   c                 <  > [          Vs/ s H  o< SU< 3PM     nnU [        [        4;   a  UR                  U 5        TR	                  [        U5      5      nU(       d  [        SU-  5      e[        U5      S:  a  [        SU-  5      e[        U5      S   $ s  snf )Nr%   z9missing required part in given .deb (expected one of: %s)rt   z>too many parts in given .deb (was looking for only one of: %s)r   )	r|   r}   r~   r   intersectionsetrI   lenlist)r   ext
candidatespartsactual_namess       r,   compressed_part_name.DebFile.__init__.<locals>.compressed_part_name  s    ?HIyXs3yJIIy11!!(+ --c*o>E-/9:; ; 5zA~9;EFG G ;q>! Js   Bz4missing required part in given .deb (expected: '%s'))r   rS   r   r   r'   	INFO_PARTrI   _DebFile__partsr   r   r~   r   r}   _DebFile__pkgnamerj   strip_DebFile__versionr   )r)   filenamerw   rv   r   r   r   s         @r,   rS   DebFile.__init__  s    64==?+	"3 	"3 	"$ L($&/01 1 ",T^^ +.- #.Y")$.. ++- #.YNN9%)		r/   r#   c                 4    U R                  5       S   U l        g )Npackage)r   r   r?   s    r,   __updatePkgNameDebFile.__updatePkgName  s    *95r/   c                     U R                   $ r=   )r   r?   s    r,   versionDebFile.version  s    ~~r/   c                 (    U R                   [           $ r=   )r   r}   r?   s    r,   rq   DebFile.data	       ||I&&r/   c                 (    U R                   [           $ r=   )r   r~   r?   s    r,   r   DebFile.control  r  r/   c                 6    U R                   R                  5       $ )zSee .control.debcontrol() )r   r   r?   s    r,   r   DebFile.debcontrol  s    ||&&((r/   c                 6    U R                   R                  5       $ )zSee .control.scripts() )r   r   r?   s    r,   r   DebFile.scripts  s    ||##%%r/   c                     g r=   r0   r   s      r,   r   DebFile.md5sums  r   r/   r   r   c                     g r=   r0   r   s      r,   r   r  "  r   r/   c                 4    U R                   R                  XS9$ )zSee .control.md5sums() r   )r   r   r   s      r,   r   r  &  s     ||##X#EEr/   c                    U R                   c  U R                  5         [        U R                   -  [        U R                   -  4 HV  n U R                  R                  USS9n[        R                  " US9 nUR                  5       nSSS5        [        W5      s  $    g! [         a     Mh  f = f! , (       d  f       N/= f)z}Return a Changelog object for the changelog.Debian.gz of the
present .deb package. Return None if no changelog can be found. NT)r   )rv   )r   _DebFile__updatePkgNameCHANGELOG_DEBIANCHANGELOG_NATIVErq   r   rI   gzipGzipFilerj   r   )r)   r   fhr   raw_changelogs        r,   	changelogDebFile.changelog+  s    
 >>!  "&7&79EYY''t'D r*b "	 +]++9    +*s   B6B0
B-,B-0
B>	c                 l    U R                   R                  5         U R                  R                  5         g r=   )r   r   rq   r?   s    r,   r   DebFile.close@  s     		r/   c                     U $ r=   r0   r?   s    r,   	__enter__DebFile.__enter__D  s    r/   exc_typeexc_valexc_tbc                 $    U R                  5         g r=   )r   )r)   r&  r'  r(  s       r,   __exit__DebFile.__exit__G  s    

r/   )__parts	__pkgname	__version)NrNr   r   r=   )r#   r   )r1   r2   r3   r4   r5   rS   r  rG   r   r  rq   r   r   r   r   r   r   r'   r   r   r   r
   r  r   r$  r   r*  r7   r0   r/   r,   r   r     s    %N6    ' ' ' ')FMM44 )&c5j) &    Xc] DcN  F
* s C D r/   r   __main__rt   )r  )8r5   r  rl   r   sysos.pathry   pathlibr   typingr   r   r   r   r   r	   r
   r   r   r   typing_extensionsr   ImportErrordebian.arfiler   r   r   debian.changelogr   debian.deb822r   r}   r~   r|   r   r   r   r  r  r   r'   r    TarInfor9   rI   rM   r   r   r   r1   argvdebr   r   printr   r0   r/   r,   <module>r>     s,  0  	  
    	 4 3 &  		.		D2 9 
c 0*W__ *<	w 	@ @F	g 	
@ @F}f }@ z
388A;
'C
++//
C	#--	
"# w  		s   D DD