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re-ej/d dZ0e0j12 Z2e3e24d 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 )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   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 )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.
        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 )zReturn 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 
