
    CfcK                        d Z ddlZddlZddlZddlZddlZddlmZ 	 ddl	m
Z
mZmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZmZmZ dd	lmZ dd
lm Z  dZ!dZ"g dZ#dZ$g dZ%dZ&dZ'dZ(dZ) G d de      Z* G d de+      Z, G d de,      Z- G d de,      Z. G d de      Z/e0dk(  rH e/ejb                  d          Z2e2jf                  ji                         Z4 e5e4jm                  d             yy# e$ r
 dZesd ZY w xY w)!zX Representation of Debian binary package (.deb) files


Debfile Classes
===============
    N)Path)AnyBinaryIODictIOIteratorListOptionalTextTypeVarUnionoverloadTYPE_CHECKING)LiteralFc                      y N )fs    0/usr/lib/python3/dist-packages/debian/debfile.py<lambda>r   9   s        )ArFileArErrorArMember)	Changelog)Deb822z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                       e Zd Zy)DebErrorN__name__
__module____qualname__r   r   r   r*   r*   M   s    r   r*   c                       e Zd ZdZd Zd Zed        Zd ZddZ	e
dd       Ze
dd	       Zdd
Ze
	 	 	 dd       Ze
	 	 dd       Z	 	 	 ddZd Zd Zd Zd Zy)DebParta  '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                      || _         d | _        y r   )_DebPart__member_DebPart__tgz)selfmembers     r   __init__zDebPart.__init__c   s    
r   c                       fd} j                    j                  j                  }t        j                  j                  |      d   dd }|t        v s|t        k(  s	|t        k(  rE|dk(  r |ddg      }n j                  }	 t        j                  |d       _          j                   S t        d
|z         j                   S # t        j                  t        j                  f$ r}t        d	|z        d}~ww xY w)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                    	 dd l }dd l|j                  | |j                  |j                  dfd      }|j                  j                  j                               d   }|j                  dk7  r+t        d	dj                  |       d
|j                  d      t        j                  |      S # t        t
        f$ r&}t        ddj                  |       d|d      d }~ww xY w)Nr   Fc                  P     j                   j                   j                        S r   )signalSIGPIPESIG_DFL)r:   s   r   r   z9DebPart.tgz.<locals>._custom_decompress.<locals>.<lambda>}   s    MM&..&..A r   )stdinstdoutuniversal_newlines
preexec_fnzerror while running command ' z' as subprocess: ''z	command 'z' has failed with code ')
subprocessr:   PopenPIPEOSError
ValueErrorr*   joincommunicater2   read
returncodeioBytesIO)command_listrC   procedatar:   r4   s        @r   _custom_decompressz'DebPart.tgz.<locals>._custom_decompressq   s    <! "'' $//*//', B	 (  ##DMM$6$6$89!<D!# # 6 I J J ::d## Z( < # 6 ; < <<s   5B4 4C)!C$$C)N   r!   unzstdz--stdoutzr:*)fileobjmodez#tarfile has returned an error: '%s'z"part '%s' has unexpected extension)r3   r2   nameospathsplitext	PART_EXTS	DATA_PART	CTRL_PARTtarfileopen	ReadErrorCompressionErrorr*   )r4   rR   rW   	extensionbufferrP   s   `     r   tgzzDebPart.tgzh   s    	$4 ::==%%D((.q1!"5II%):di>O %/:0FGF!]]FN!(f5!IDJ
 zz CdJKKzz	  ))7+C+CD N"#H1#LMMNs   C #C=*C88C=c                     t        |       j                  dd      } | j                  d      r| S | j                  d      rd| z   S d| z   S )zw try (not so hard) to obtain a member file name in a form that is
        stored in the .tar.gz, i.e. starting with ./ \/z./.)strreplace
startswith)fnames    r   __normalize_memberzDebPart.__normalize_member   sO     E
""4-D!LC ;e|r   c                 j   	 g }|j                  d      dd D ]  }|j                  |       t        j                  j	                  dj                  |            }t        j                  |      }| j                         j                  |      }|j                         s|j                  j                  d      r(|j                  j                  d      }|j                  }|j                  |d<    	 t        j                  t        j                  j	                              S # t        $ r Y yw xY w)z walk 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.
        rg   rS   N)splitappendrX   rY   normpathrH   r0   _DebPart__normalize_memberrd   	getmemberissymlinknamerk   KeyError)r4   rY   resolved_path_partspathpartcurrpathtinfos         r   __resolve_symlinkszDebPart.__resolve_symlinks   s   	"$ JJsOAB/ A#**8477++CHH5H,IJ"55h?
,,X6 ;;=~~005.3nn.B.B3.G+#(>> 38..+B/%A0 ))"''*:*:8*DEE	  		s   BD& AD& &	D21D2c                     t         j                  |      }| j                         j                         }||v ry|r| j	                  |      }|duS ||v S )zmCheck if this part contains a given file name.

        Symlinks within the archive can be followed.
        TN)r0   rs   rd   getnames_DebPart__resolve_symlinks)r4   rl   follow_symlinksnames
fname_reals        r   has_filezDebPart.has_file   sZ     **51
##%E>007JT))~r   Nc                      y r   r   r4   rl   encodingerrorsr   s        r   get_filezDebPart.get_file        	r   c                      y r   r   r   s        r   r   zDebPart.get_file   r   r   c                 2   t         j                  |      }|r | j                  |      }|t        d      |}	 | j	                         j                  |      }|t        d      |t        j                  |||      S |S # t        $ r t        d      w xY w)a  Return 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   )	r0   rs   r   r*   rd   extractfilerw   rL   TextIOWrapper)r4   rl   r   r   r   r   fobjs          r   r   zDebPart.get_file   s     **51007J!>??E	<88:))%0D <:;;##D8FKK  	<:;;	<s   B Bc                      y r   r   r   s        r   get_contentzDebPart.get_content       	r   c                      y r   r   r   s        r   r   zDebPart.get_content  r   r   c                     | j                  t        |      |||      }d}|r |j                         }|j                          |S )a5  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   ri   rJ   close)r4   rl   r   r   r   r   contents          r   r   zDebPart.get_content$  sI      MMJf+  

 ffhGGGIr   c                 P    t        | j                         j                               S r   )iterrd   r~   r4   s    r   __iter__zDebPart.__iter__A  s    DHHJ'')**r   c                 $    | j                  |      S r   )r   r4   rl   s     r   __contains__zDebPart.__contains__E  s    }}U##r   c                 $    | j                  |      S r   )r   r   s     r   __getitem__zDebPart.__getitem__I  s    &&r   c                 8    | j                   j                          y r   )r2   r   r   s    r   r   zDebPart.closeM  s    r   )F)NNF)NF)r,   r-   r.   __doc__r6   rd   staticmethodrs   r   r   r   r   r   r   r   r   r   r   r   r   r0   r0   Q   s    "
4l  $FL$    @  "$)	    $)	  "$)	:+$'r   r0   c                       e Zd Zy)DebDataNr+   r   r   r   r   r   R  s    r   r   c                   D    e Zd Zd Zd Zedd       Zedd       ZddZy)	
DebControlc                 v    i }t         D ]-  }| j                  |      s| j                  |      }|)|||<   / |S )zo Return a dictionary of maintainer scripts (postinst, prerm, ...)
        mapping script names to script text. )MAINT_SCRIPTSr   r   )r4   scriptsrl   rQ   s       r   r   zDebControl.scriptsY  sJ    
 " 	*E}}U#''.#%)GEN		* r   c                 >    t        | j                  t                    S )z Return the debian/control as a Deb822 (a Debian-specific dict-like
        class) object.

        For a string representation of debian/control try
        .get_content('control') )r   r   CONTROL_FILEr   s    r   
debcontrolzDebControl.debcontrolg  s     d&&|455r   Nc                      y r   r   r4   r   r   s      r   r(   zDebControl.md5sumsq  r   r   c                      y r   r   r   s      r   r(   zDebControl.md5sumsv  r   r   c                 x   | j                  t              st        dt        z        | j                  t        ||      }i }d}|d}|j	                         D ]O  }|j                  |      j                  dd      \  }}t        |t              r|j                         ||<   K|||<   Q |j                          |S )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   
rS   )r   MD5_FILEr*   r   	readlinesrstriprp   
isinstancebytesdecoder   )	r4   r   r   md5_filesumsnewlinelinemd5rl   s	            r   r(   zDebControl.md5sums{  s     }}X&:XEG G ==HV=LG&&( 	"DW-33D!<JC#u%!jjlU!U	" 	r   NNr   )r,   r-   r.   r   r   r   r(   r   r   r   r   r   W  s9    6    r   r   c                       e Zd ZdZddZd Zed        Zed        Zed        Z	d Z
d	 Zedd
       Zedd       ZddZd Zd Zd Zd Zy)DebFilea  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                 &   t        j                  | |||       t        | j                               fd}t        vrt        dt        z        i | _        t        | j                   |t                          | j                  t        <   t        | j                   |t                          | j                  t        <   d | _        | j                  t              }|j                         j                         | _        |j!                          y )Nc                 $   t         D cg c]	  }| d| }}| t        t        fv r|j                  |        j	                  t        |            }|st        d|z        t        |      dkD  rt        d|z        t        |      d   S c c}w )Nrh   z9missing required part in given .deb (expected one of: %s)rS   z>too many parts in given .deb (was looking for only one of: %s)r   )	r[   r\   r]   rq   intersectionsetr*   lenlist)basenameext
candidatespartsactual_namess       r   compressed_part_namez.DebFile.__init__.<locals>.compressed_part_name  s    ?HIXs3IJ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   r6   r   r~   	INFO_PARTr*   _DebFile__partsr   rt   r]   r   r\   _DebFile__pkgnamerJ   strip_DebFile__versionr   )r4   filenamerV   rU   r   r   r   s         @r   r6   zDebFile.__init__  s    hg64==?+	"& L($&/01 1 ",T^^ +.- #.Y")$.. ++- #.YNN9%)		r   c                 4    | j                         d   | _        y )Npackage)r   r   r   s    r   __updatePkgNamezDebFile.__updatePkgName  s    *95r   c                     | j                   S r   )r   r   s    r   versionzDebFile.version  s     ~~r   c                 (    | j                   t           S r   )r   r\   r   s    r   rQ   zDebFile.data       ||I&&r   c                 (    | j                   t           S r   )r   r]   r   s    r   r'   zDebFile.control  r   r   c                 6    | j                   j                         S )z See .control.debcontrol() )r'   r   r   s    r   r   zDebFile.debcontrol  s     ||&&((r   c                 6    | j                   j                         S )z See .control.scripts() )r'   r   r   s    r   r   zDebFile.scripts  s     ||##%%r   c                      y r   r   r   s      r   r(   zDebFile.md5sums  r   r   c                      y r   r   r   s      r   r(   zDebFile.md5sums  r   r   c                 <    | j                   j                  ||      S )z See .control.md5sums() r   )r'   r(   r   s      r   r(   zDebFile.md5sums  s     ||##Xf#EEr   c                 z   | j                   | j                          t        | j                   z  t        | j                   z  fD ][  }	 | j                  j                  |d      }t        j                  |      5 }|j                         }ddd       t              c S  y# t        $ r Y jw xY w# 1 sw Y   'xY w)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   )rU   )r   _DebFile__updatePkgNameCHANGELOG_DEBIANCHANGELOG_NATIVErQ   r   r*   gzipGzipFilerJ   r   )r4   rl   fhr   raw_changelogs        r   	changelogzDebFile.changelog  s    
 >>!  "&7&79 		,EYY''t'D r* *b "	*]++		,   * *s   B":B1"	B.-B.1B:	c                 l    | j                   j                          | j                  j                          y r   )r'   r   rQ   r   s    r   r   zDebFile.close  s     		r   c                     | S r   r   r   s    r   	__enter__zDebFile.__enter__  s    r   c                 $    | j                          y r   )r   )r4   exc_typeexc_valexc_tbs       r   __exit__zDebFile.__exit__!  s    

r   )NrNr   r   )r,   r-   r.   r   r6   r   propertyr   rQ   r'   r   r   r   r(   r   r   r   r   r   r   r   r   r     s    &P6   ' ' ' ')
&
    F
*
r   r   __main__rS   )r   )7r   r   rL   r^   sysos.pathrX   pathlibr   typingr   r   r   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*   objectr0   r   r   r   r,   argvdebr'   rd   printrt   r   r   r   <module>r      s$  .  	  
  "    4 3 &   		.		D2 9 	w 	~f ~B	g 	
C CLFf FR z
388A;
'C
++//
C	#--	
"# i  "M ""s   "C1 1D ?D 