
WS3                 @   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 Gd d   d e
  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e  Z Gd d   d e	  Z e d  k rd  d l Z e d! e j 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               @   s   e  Z d  Z d Z d d   Z d d   Z e d d    Z d d	   Z d
 d
 d d  Z	 d
 d
 d d  Z
 d d   Z d d   Z e j d k  r 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)N)_DebPart__member_DebPart__tgz)selfZmemberr   r   r   __init__?   s    	zDebPart.__init__c       	         s  |  j  d k r|  j j } t j j |  d d d  } | t k sS | t k rt j	 d k  rc| d k rcyg d d l
 } d d l   d d l } | j d d g d | j d	 | j d
 d d   f d d   } Wn; t t f k
 r} z t d |   WYd d } ~ Xn X| j |  j j    d } | j d k rQt d | j   | j |  } n	 |  j } y t j d | d d  |  _  Wqt j t j f k
 r} z t d |   WYd d } ~ XqXn 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--stdoutstdinstdoutZuniversal_newlinesFZ
preexec_fnc                  s     j    j   j  S)N)signalSIGPIPESIG_DFLr   )r   r   r   <lambda>Y   s    zDebPart.tgz.<locals>.<lambda>z%sz!command has failed with code '%s'fileobjmodezr:*z#tarfile has returned an error: '%s'z"part '%s' has unexpected extension)r   r   )r   r   nameospathsplitext	PART_EXTS	DATA_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   sE   |  j  d  r" |  d d  }  n |  j  d  rA |  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   r?   namesr   r   r   has_file   s    zDebPart.has_fileNc             C   s   t  j |  } y |  j   j d |  } Wn' t k
 rU |  j   j |  } Yn X| d k	 r t j d k r d d l } t | d  s d d   | _	 | j
 | d | d	 | Sd d l } | d k r d
 } | j | | d	 | Sn | Sd 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)r   r@   r;   ZextractfileKeyErrorr)   versionr,   hasattrrE   TextIOWrappercodecsEncodedFile)r   r?   rF   rG   Zfobjr,   rM   r   r   r   get_file   s     zDebPart.get_filec             C   sA   |  j  | d | 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.
        rF   rG   N)rO   r1   close)r   r?   rF   rG   fZcontentr   r   r   get_content   s    
zDebPart.get_contentc             C   s   t  |  j   j    S)N)iterr;   rA   )r   r   r   r   __iter__   s    zDebPart.__iter__c             C   s   |  j  |  S)N)rC   )r   r?   r   r   r   __contains__   s    zDebPart.__contains__rD   c             C   s   |  j  |  S)N)rC   )r   r?   r   r   r   has_key   s    zDebPart.has_keyc             C   s   |  j  |  S)N)rR   )r   r?   r   r   r   __getitem__   s    zDebPart.__getitem__c             C   s   |  j  j   d  S)N)r   rP   )r   r   r   r   rP      s    zDebPart.close)r   r   r   __doc__r   r;   staticmethodr@   rC   rO   rR   rT   rU   r)   rJ   rV   rW   rP   r   r   r   r   r   -   s   ,r   c               @   s   e  Z d  Z d S)DebDataN)r   r   r   r   r   r   r   rZ      s   rZ   c               @   s:   e  Z d  Z d d   Z d d   Z d d d d  Z d S)
DebControlc             C   s=   i  } x0 t  D]( } |  j |  r |  j |  | | <q W| S)zo Return a dictionary of maintainer scripts (postinst, prerm, ...)
        mapping script names to script text. )MAINT_SCRIPTSrC   rR   )r   scriptsr?   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   rR   CONTROL_FILE)r   r   r   r   
debcontrol   s    zDebControl.debcontrolNc       	      C   s   |  j  t  s t d t   |  j t d | d | } i  } | d k rU d } n d } xp | j   D]b } | j |  j d d  \ } } t j d k r t	 | t
  r | j   | | <qh | | | <qh W| 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 sumsrF   rG   Ns   
z
r   rD   )rC   MD5_FILEr   rO   	readlinesrstripsplitr)   rJ   
isinstancebytesdecoderP   )	r   rF   rG   Zmd5_fileZsumsnewlinelineZmd5r?   r   r   r   r      s    
	!
zDebControl.md5sums)r   r   r   r]   r_   r   r   r   r   r   r[      s   	r[   c               @   s   e  Z d  Z d Z d d 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 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 rV t d t   i  |  _ t |  j | t	    |  j t	 <t
 |  j | t    |  j t <d  |  _ |  j t  } | j   j   |  _ | j   d  S)Nc                s     f d d   t  D }   t k r2 | j     j t |   } | s` t d |   n3 t |  d k r t d |   n t |  d Sd  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(   appendintersectionsetr   lenlist)rl   Z
candidatesparts)actual_names)rl   r   compressed_part_name  s    z.DebFile.__init__.<locals>.compressed_part_namez4missing required part in given .deb (expected: '%s'))r   r   rp   rA   	INFO_PARTr   _DebFile__partsr[   	getmember	CTRL_PARTrZ   r(   _DebFile__pkgnamer1   strip_DebFile__versionrP   )r   filenamer"   r!   ru   rQ   r   )rt   r   r     s    
				zDebFile.__init__c             C   s   |  j    d |  _ d  S)Npackage)r_   rz   )r   r   r   r   Z__updatePkgName0  s    zDebFile.__updatePkgNamec             C   s   |  j  S)N)r|   )r   r   r   r   r    3  s    zDebFile.<lambda>c             C   s   |  j  t S)N)rw   r(   )r   r   r   r   r    4  s    c             C   s   |  j  t S)N)rw   ry   )r   r   r   r   r    5  s    c             C   s   |  j  j   S)z See .control.debcontrol() )r   r_   )r   r   r   r   r_   9  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 | d |  S)z See .control.md5sums() rF   rG   )r   r   )r   rF   rG   r   r   r   r   A  s    zDebFile.md5sumsc             C   s   |  j  d k r |  j   xr t |  j  t |  j  g D]V } |  j j |  r4 t j d |  j j |   } | j	   } | j
   t |  Sq4 Wd S)z Return a Changelog object for the changelog.Debian.gz of the
        present .deb package. Return None if no changelog can be found. Nr!   )rz   _DebFile__updatePkgNameCHANGELOG_DEBIANCHANGELOG_NATIVEr9   rC   gzipZGzipFilerO   r1   rP   r   )r   r?   r   Zraw_changelogr   r   r   	changelogE  s    

zDebFile.changelogc             C   s   |  j  j   |  j j   d  S)N)r   rP   r9   )r   r   r   r   rP   U  s    zDebFile.close)r   r   r   rX   r   r   propertyrJ   r9   r   r_   r]   r   r   rP   r   r   r   r   ri      s   !ri   __main__r}   r   )%Z
__future__r   r   r   r4   r)   os.pathr$   Zdebian.arfiler   r   Zdebian.changelogr   Zdebian.deb822r   r(   ry   r'   rv   r\   r^   r   r   r`   r   objectr   rZ   r[   ri   r   argvZdebr   r;   printrx   r   r   r   r   <module>   s4   6Z