o
    a~bM>  ã                   @   st  d Z ddlZddlZddlZddlZddlZ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 W n eyI   esGdd„ ZY nw 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„ deƒZ(G dd„ de)ƒZ*G dd„ de*ƒZ+G dd„ de*ƒZ,G dd„ deƒZ-e.dkr¸e-ej/d d�Z0e0j1 2¡ Z2e3e2 4d¡ƒ dS dS ) zX Representation of Debian binary package (.deb) files


Debfile Classes
===============
é    N)ÚAnyÚBinaryIOÚDictÚIOÚIteratorÚListÚOptionalÚTextÚTypeVarÚUnionÚoverloadÚTYPE_CHECKING)ÚLiteralc                 C   ó   d S ©N© )Úfr   r   ú0/usr/lib/python3/dist-packages/debian/debfile.pyÚ<lambda>4   s    r   )Ú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dS )ÚDebErrorN©Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r'   H   s    r'   c                   @   sª   e Zd ZdZdd„ Zdd„ Zedd„ ƒZdd	„ Ze	ddd„ƒZ
e	ddd„ƒZ
ddd„Z
e		
	
ddd„ƒZe		
ddd„ƒZ	
	
ddd„Zdd„ Zdd„ Zdd„ Zdd„ Zd
S )Ú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                 C   s   || _ d | _d S r   )Ú_DebPart__memberÚ_DebPart__tgz)ÚselfÚmemberr   r   r   Ú__init__^   s   
zDebPart.__init__c              
      sÂ   ‡ fdd„}ˆ j du r^ˆ jj}tj |¡d dd… }|tv s'|tks'|tkrX|dkr2|ddgƒ}nˆ j}zt	j
|dd	�ˆ _ W ˆ j S  t	jt	jfyW } ztd
| ƒ‚d}~ww td| ƒ‚ˆ j S )zÕReturn 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œ   zdd l }dd l‰ dd l}|j| |j|jd‡ fdd„d�}W n ttfy2 } ztd| ƒ‚d }~ww | ˆj	 
¡ ¡d }|jdkrItd|j ƒ‚| |¡S )Nr   Fc                      s   ˆ   ˆ jˆ j¡S r   )ÚsignalÚSIGPIPEÚSIG_DFLr   ©r2   r   r   r   x   s   z9DebPart.tgz.<locals>._custom_decompress.<locals>.<lambda>)ÚstdinÚstdoutÚuniversal_newlinesÚ
preexec_fnz%sz!command has failed with code '%s')Ú
subprocessr2   ÚioÚPopenÚPIPEÚOSErrorÚ
ValueErrorr'   Úcommunicater-   ÚreadÚ
returncodeÚBytesIO)Úcommand_listr:   r;   ÚprocÚeÚdata©r/   r5   r   Ú_custom_decompressl   s(   

ü€ÿ
ÿ
z'DebPart.tgz.<locals>._custom_decompressNé   r   Úunzstdz--stdoutzr:*)ÚfileobjÚmodez#tarfile has returned an error: '%s'z"part '%s' has unexpected extension)r.   r-   ÚnameÚosÚpathÚsplitextÚ	PART_EXTSÚ	DATA_PARTÚ	CTRL_PARTÚtarfileÚopenÚ	ReadErrorÚCompressionErrorr'   )r/   rI   rN   Ú	extensionÚbufferrF   r   rH   r   Útgzc   s"   	
ü€ÿzDebPart.tgzc                 C   s4   |   d¡r| dd… } | S |   d¡r| dd… } | S )zw try (not so hard) to obtain a member file name in a form relative
        to the .tar.gz root and with no heading '.' ú./é   Nú/rJ   )Ú
startswith)Úfnamer   r   r   Ú__normalize_member˜   s   

þzDebPart.__normalize_memberc                 C   s"   t  |¡}|  ¡  ¡ }d| |v S )z.Check if this part contains a given file name.r\   )r,   Ú_DebPart__normalize_memberr[   Úgetnames)r/   r`   Únamesr   r   r   Úhas_file¤   s   
zDebPart.has_fileNc                 C   r   r   r   ©r/   r`   ÚencodingÚerrorsr   r   r   Úget_file¬   ó   zDebPart.get_filec                 C   r   r   r   rf   r   r   r   ri   ±   rj   c                 C   sH   t  |¡}|  ¡  d| ¡}|du rtdƒ‚|dur"tj|||d�S |S )z¾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.
        r\   NzFile not found inside package©rg   rh   )r,   rb   r[   Úextractfiler'   r;   ÚTextIOWrapper)r/   r`   rg   rh   Úfobjr   r   r   ri   ¶   s   
c                 C   r   r   r   rf   r   r   r   Úget_contentÇ   ó   zDebPart.get_contentc                 C   r   r   r   rf   r   r   r   ro   Ð   rp   c                 C   s,   | j |||d�}d}|r| ¡ }| ¡  |S )zÕ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.
        rk   N)ri   rA   Úclose)r/   r`   rg   rh   r   Úcontentr   r   r   ro   Ù   s   c                 C   s   t |  ¡  ¡ ƒS r   )Úiterr[   rc   rH   r   r   r   Ú__iter__ï   s   zDebPart.__iter__c                 C   ó
   |   |¡S r   )re   ©r/   r`   r   r   r   Ú__contains__ó   ó   
zDebPart.__contains__c                 C   ru   r   )ro   rv   r   r   r   Ú__getitem__÷   rx   zDebPart.__getitem__c                 C   s   | j  ¡  d S r   )r-   rq   rH   r   r   r   rq   û   s   zDebPart.close©NNr   )r)   r*   r+   Ú__doc__r1   r[   Ústaticmethodrb   re   r   ri   ro   rt   rw   ry   rq   r   r   r   r   r,   L   s4    5

ýý

ýr,   c                   @   r&   )ÚDebDataNr(   r   r   r   r   r}      s    r}   c                   @   sB   e Zd Zdd„ Zdd„ Zed
dd„ƒZeddd„ƒZd
d	d„ZdS )Ú
DebControlc                 C   s6   i }t D ]}|  |¡r|  |¡}|dur|||< q|S )zo Return a dictionary of maintainer scripts (postinst, prerm, ...)
        mapping script names to script text. N)ÚMAINT_SCRIPTSre   ro   )r/   Úscriptsr`   rG   r   r   r   r€     s   

€zDebControl.scriptsc                 C   s   t |  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   ro   ÚCONTROL_FILErH   r   r   r   Ú
debcontrol  s   zDebControl.debcontrolNc                 C   r   r   r   ©r/   rg   rh   r   r   r   r%     rj   zDebControl.md5sumsc                 C   r   r   r   rƒ   r   r   r   r%   $  rj   c           	      C   sŠ   |   t¡stdt ƒ‚| jt||d�}i }d}|du rd}| ¡ D ]}| |¡ dd¡\}}t|tƒr:| 	¡ ||< q!|||< q!| 
¡  |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 sumsrk   z
Ns   
rJ   )re   ÚMD5_FILEr'   ri   Ú	readlinesÚrstripÚsplitÚ
isinstanceÚbytesÚdecoderq   )	r/   rg   rh   Úmd5_fileÚsumsÚnewlineÚlineÚmd5r`   r   r   r   r%   )  s    
ÿ

rz   r   )r)   r*   r+   r€   r‚   r   r%   r   r   r   r   r~     s    
r~   c                   @   sœ   e Zd ZdZddd„Zdd„ Zedd	„ ƒZed
d„ ƒZedd„ ƒZ	dd„ Z
dd„ Zeddd„ƒZed dd„ƒZddd„Zdd„ Zdd„ Zdd„ Zdd„ ZdS )!Ú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
    NÚrc                    sœ   t  | |||¡ t|  ¡ ƒ‰ ‡ fdd„}tˆ vrtdt ƒ‚i | _t|  |t	ƒ¡ƒ| jt	< t
|  |tƒ¡ƒ| jt< d | _|  t¡}| ¡  ¡ | _| ¡  d S )Nc                    sj   ‡ fdd„t D ƒ}ˆ ttfv r| ˆ ¡ ˆ t|ƒ¡}|s#td| ƒ‚t|ƒdkr/td| ƒ‚t|ƒd S )Nc                    s   g | ]}d ˆ |f ‘qS )z%s.%sr   )Ú.0Úext©Úbasenamer   r   Ú
<listcomp>b  s    zBDebFile.__init__.<locals>.compressed_part_name.<locals>.<listcomp>z9missing required part in given .deb (expected one of: %s)rJ   z>too many parts in given .deb (was looking for only one of: %s)r   )	rR   rS   rT   ÚappendÚintersectionÚsetr'   ÚlenÚlist)r•   Ú
candidatesÚparts©Úactual_namesr”   r   Úcompressed_part_name`  s"   
ÿÿÿÿz.DebFile.__init__.<locals>.compressed_part_namez4missing required part in given .deb (expected: '%s'))r   r1   r™   rc   Ú	INFO_PARTr'   Ú_DebFile__partsr~   Ú	getmemberrT   r}   rS   Ú_DebFile__pkgnamerA   ÚstripÚ_DebFile__versionrq   )r/   ÚfilenamerM   rL   r    r   r   rž   r   r1   [  s(   ÿÿÿÿ
zDebFile.__init__c                 C   s   |   ¡ d | _d S )NÚpackage)r‚   r¤   rH   r   r   r   Ú__updatePkgNameƒ  s   zDebFile.__updatePkgNamec                 C   s   | j S r   )r¦   rH   r   r   r   Úversion‡  s   zDebFile.versionc                 C   ó
   | j t S r   )r¢   rS   rH   r   r   r   rG   Œ  ó   
zDebFile.datac                 C   r«   r   )r¢   rT   rH   r   r   r   r$   ‘  r¬   zDebFile.controlc                 C   ó
   | j  ¡ S )z See .control.debcontrol() )r$   r‚   rH   r   r   r   r‚   ˜  r¬   zDebFile.debcontrolc                 C   r­   )z See .control.scripts() )r$   r€   rH   r   r   r   r€   �  r¬   zDebFile.scriptsc                 C   r   r   r   rƒ   r   r   r   r%   ¢  rj   zDebFile.md5sumsc                 C   r   r   r   rƒ   r   r   r   r%   §  rj   c                 C   s   | j j||d�S )z See .control.md5sums() rk   )r$   r%   rƒ   r   r   r   r%   ¬  s   c                 C   sl   | j du r	|  ¡  t| j  t| j  fD ] }| j |¡r3tj| j |¡d�}| 	¡ }| 
¡  t|ƒ  S qdS )z† Return a Changelog object for the changelog.Debian.gz of the
        present .deb package. Return None if no changelog can be found. N)rL   )r¤   Ú_DebFile__updatePkgNameÚCHANGELOG_DEBIANÚCHANGELOG_NATIVErG   re   ÚgzipÚGzipFileri   rA   rq   r   )r/   r`   r   Úraw_changelogr   r   r   Ú	changelog±  s   
ÿüzDebFile.changelogc                 C   s   | j  ¡  | j ¡  d S r   )r$   rq   rG   rH   r   r   r   rq   Â  s   
zDebFile.closec                 C   s   | S r   r   rH   r   r   r   Ú	__enter__Ç  s   zDebFile.__enter__c                 C   s   |   ¡  d S r   )rq   )r/   Úexc_typeÚexc_valÚexc_tbr   r   r   Ú__exit__Ë  s   zDebFile.__exit__)Nr‘   Nrz   r   )r)   r*   r+   r{   r1   r®   Úpropertyrª   rG   r$   r‚   r€   r   r%   r´   rq   rµ   r¹   r   r   r   r   r�   K  s*    
(



r�   Ú__main__rJ   )r§   )5r{   r±   r;   rU   ÚsysÚos.pathrO   Útypingr   r   r   r   r   r   r   r	   r
   r   r   r   Útyping_extensionsr   ÚImportErrorÚdebian.arfiler   r   r   Údebian.changelogr   Údebian.deb822r   rS   rT   rR   r¡   r   r�   r°   r¯   r„   r'   Úobjectr,   r}   r~   r�   r)   ÚargvÚdebr$   r[   Úprintr£   r   r   r   r   Ú<module>   sL    8€ý 5F 
ý