3
Z3                 @   s  d dl mZmZ d dlZd dlZd dlZd dlZd dlm	Z	m
Z
 d dlmZ d dlmZ dZdZdd	d
dgZdZdddddg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d dlZeejd! d"Z e j!j" Z"e#e"j$d dS )#    )absolute_importprint_functionN)ArFileArError)	Changelog)Deb822zdata.tarzcontrol.targzbz2xzZlzmazdebian-binaryZpreinstZpostinstZprermZpostrmconfigcontrolzusr/share/doc/%s/changelog.gzz$usr/share/doc/%s/changelog.Debian.gzmd5sumsc               @   s   e Zd ZdS )DebErrorN)__name__
__module____qualname__ r   r   0/usr/lib/python3/dist-packages/debian/debfile.pyr   )   s   r   c               @   sz   e Zd ZdZdd Zdd Zedd Zdd	 ZdddZ	dddZ
dd Zdd Zejdk rfd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 )N)_DebPart__member_DebPart__tgz)selfmemberr   r   r   __init__?   s    zDebPart.__init__c       	         sn  | j dkrh| jj}tjj|d dd }|tksF|tksF|tkr\t	j
dk oV|dkry@ddl}ddl ddl}|jddg|j|jd fd	d
d}W n2 ttfk
r } ztd| W Y dd}~X nX |j| jj d }|jdkrtd|j |j|}n| j}ytj|dd| _ W n8 tjtjfk
rX } ztd| W Y dd}~X nX n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.
        N      r
   r   Zunxzz--stdoutFc                  s    j  j jS )N)signalSIGPIPESIG_DFLr   )r   r   r   <lambda>Y   s    zDebPart.tgz.<locals>.<lambda>)stdinstdoutZuniversal_newlinesZ
preexec_fnz%sz!command has failed with code '%s'zr:*)fileobjmodez#tarfile has returned an error: '%s'z"part '%s' has unexpected extension)r   r   )r   r   nameospathsplitext	PART_EXTS	DATA_PART	CTRL_PARTsysversion_info
subprocessr   ioPopenPIPEOSError
ValueErrorr   Zcommunicateread
returncodeBytesIOtarfileopenZ	ReadErrorZCompressionError)	r   r$   	extensionr-   r.   procedatabufferr   )r   r   tgzC   s6    


 zDebPart.tgzc             C   s2   | j dr| dd } n| j 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 '.' z./   N/r   )
startswith)fnamer   r   r   Z__normalize_membero   s
    

zDebPart.__normalize_memberc             C   s*   t j|}| j j }d| |kp(||kS )z.Check if this part contains a given file name.z./)r   _DebPart__normalize_memberr=   getnames)r   rA   namesr   r   r   has_file   s    
zDebPart.has_fileNc             C   s   t j|}y| j jd| }W n" tk
rB   | j j|}Y nX |dk	rtjdkrddl}t|dsrdd |_	|j
|||dS ddl}|dkrd	}|j|||d
S n|S d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.
        z./N3r   flushc               S   s   d S )Nr   r   r   r   r   r      s    z"DebPart.get_file.<locals>.<lambda>)encodingerrorsstrict)rI   )r   rB   r=   ZextractfileKeyErrorr+   versionr.   hasattrrG   TextIOWrappercodecsEncodedFile)r   rA   rH   rI   Zfobjr.   rO   r   r   r   get_file   s     



zDebPart.get_filec             C   s,   | j |||d}d}|r(|j }|j  |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.
        )rH   rI   N)rQ   r3   close)r   rA   rH   rI   fZcontentr   r   r   get_content   s    zDebPart.get_contentc             C   s   t | j j S )N)iterr=   rC   )r   r   r   r   __iter__   s    zDebPart.__iter__c             C   s
   | j |S )N)rE   )r   rA   r   r   r   __contains__   s    zDebPart.__contains__rF   c             C   s
   | j |S )N)rE   )r   rA   r   r   r   has_key   s    zDebPart.has_keyc             C   s
   | j |S )N)rT   )r   rA   r   r   r   __getitem__   s    zDebPart.__getitem__c             C   s   | j j  d S )N)r   rR   )r   r   r   r   rR      s    zDebPart.close)NN)NN)r   r   r   __doc__r   r=   staticmethodrB   rE   rQ   rT   rV   rW   r+   rL   rX   rY   rR   r   r   r   r   r   -   s   ,


r   c               @   s   e Zd ZdS )DebDataN)r   r   r   r   r   r   r   r\      s   r\   c               @   s&   e Zd Zdd Zdd ZdddZdS )	
DebControlc             C   s.   i }x$t D ]}| j|r
| j|||< q
W |S )zo Return a dictionary of maintainer scripts (postinst, prerm, ...)
        mapping script names to script text. )MAINT_SCRIPTSrE   rT   )r   scriptsrA   r   r   r   r_      s
    

zDebControl.scriptsc             C   s   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   rT   CONTROL_FILE)r   r   r   r   
debcontrol   s    zDebControl.debcontrolNc       	      C   s   | j tstdt | jt||d}i }|dkr8d}nd}xP|j D ]D}|j|jdd\}}tjdkrt	|t
r|j ||< qF|||< qFW |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 sums)rH   rI   Ns   
z
r   rF   )rE   MD5_FILEr   rQ   	readlinesrstripsplitr+   rL   
isinstancebytesdecoderR   )	r   rH   rI   Zmd5_fileZsumsnewlinelineZmd5rA   r   r   r   r      s    
zDebControl.md5sums)NN)r   r   r   r_   ra   r   r   r   r   r   r]      s   	r]   c               @   sp   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d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 j| ||| t| j   fdd}t kr<tdt i | _t| j|t	| jt	< t
| j|t| jt< d | _| jt}|j j | _|j  d S )Nc                sv    fddt D } tks" tkr,|j  jt|}|sLtd| n&t|dkrftd| nt|d S d S )Nc                s   g | ]}d  |f qS )z%s.%sr   ).0Zext)basenamer   r   
<listcomp>  s    zBDebFile.__init__.<locals>.compressed_part_name.<locals>.<listcomp>z9missing required part in given .deb (expected one of: %s)r   z>too many parts in given .deb (was looking for only one of: %s)r   )	r(   r)   r*   appendintersectionsetr   lenlist)rn   Z
candidatesparts)actual_names)rn   r   compressed_part_name  s    


z.DebFile.__init__.<locals>.compressed_part_namez4missing required part in given .deb (expected: '%s'))r   r   rr   rC   	INFO_PARTr   _DebFile__partsr]   	getmemberr*   r\   r)   _DebFile__pkgnamer3   strip_DebFile__versionrR   )r   filenamer#   r"   rw   rS   r   )rv   r   r     s    
zDebFile.__init__c             C   s   | j  d | _d S )Npackage)ra   r{   )r   r   r   r   Z__updatePkgName1  s    zDebFile.__updatePkgNamec             C   s   | j S )N)r}   )r   r   r   r   r   4  s    zDebFile.<lambda>c             C   s
   | j t S )N)ry   r)   )r   r   r   r   r   5  s    c             C   s
   | j t S )N)ry   r*   )r   r   r   r   r   6  s    c             C   s
   | j j S )z See .control.debcontrol() )r   ra   )r   r   r   r   ra   :  s    zDebFile.debcontrolc             C   s
   | j j S )z See .control.scripts() )r   r_   )r   r   r   r   r_   >  s    zDebFile.scriptsc             C   s   | j j||dS )z See .control.md5sums() )rH   rI   )r   r   )r   rH   rI   r   r   r   r   B  s    zDebFile.md5sumsc             C   sl   | j dkr| j  xTt| j  t| j  gD ]<}| jj|r(tj| jj|d}|j	 }|j
  t|S q(W 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)r"   )r{   _DebFile__updatePkgNameCHANGELOG_DEBIANCHANGELOG_NATIVEr;   rE   gzipZGzipFilerQ   r3   rR   r   )r   rA   r   Zraw_changelogr   r   r   	changelogF  s    

zDebFile.changelogc             C   s   | j j  | jj  d S )N)r   rR   r;   )r   r   r   r   rR   V  s    
zDebFile.close)Nrl   N)NN)r   r   r   rZ   r   r   propertyrL   r;   r   ra   r_   r   r   rR   r   r   r   r   rk      s   
"
rk   __main__r   )r~   )%Z
__future__r   r   r   r6   r+   os.pathr%   Zdebian.arfiler   r   Zdebian.changelogr   Zdebian.deb822r   r)   r*   r(   rx   r^   r`   r   r   rb   r   objectr   r\   r]   rk   r   argvZdebr   r=   printrz   r   r   r   r   <module>   s6    6[

