3
	`_{                 @   s   d Z ddlmZ ddl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 G dd deZG dd	 d	eZG d
d deZdd Zedkre  dS )z;Classes for working with locally available Debian packages.    )print_functionN)gettext)BytesIOc               @   s   e Zd ZdZdS )NoDebArchiveExceptionz9Exception which is raised if a file is no Debian archive.N)__name__
__module____qualname____doc__ r
   r
   -/usr/lib/python3/dist-packages/apt/debfile.pyr   !   s   r   c               @   sP  e Zd ZdZed\ZZZZdZ	dEddZ
dd Zd	d
 Zdd Zedd Zedd ZdFddZdd Zdd Zdd Zdd Zedd Zedd Zed d! Zed"d# Zd$d% Zd&d' Zd(d) ZdGd+d,ZdHd-d.Zd/d0 Zd1d2 Z ed3d4 Z!ed5d6 Z"e#d7d8 Z$e#d9d: Z%dId;d<Z&d=d> Z'd?d@ Z(dAdB Z)dJdCdDZ*dS )K
DebPackagezA Debian Package (.deb file).   r   Nc             C   sR   |d krt j }|| _d | _d| _i | _g | _d| _d| _d | _	|rN| j
| d S )N F)aptCache_cache_debfilepkgname	_sections
_need_pkgs_check_was_run_failure_string
_multiarchopen)selffilenamecacher
   r
   r   __init__1   s    zDebPackage.__init__c             C   sh   | j dd|  g | _t | _d| _|| _tj| j| _| jj	j
d}tj|| _| jd | _d| _dS )z open given debfile    z	open '%s'r   controlPackageFN)_dbgr   set_installed_conflictsr   r   apt_instZDebFiler   r   extractdataapt_pkgZ
TagSectionr   r   r   )r   r   r   r
   r
   r   r   ?   s    zDebPackage.openc             C   s
   | j | S )N)r   )r   keyr
   r
   r   __getitem__L   s    zDebPackage.__getitem__c             C   s
   || j kS )N)r   )r   r'   r
   r
   r   __contains__O   s    zDebPackage.__contains__c                sD   g  y| j jj fdd W n  tk
r>   td| j gS X  S )z$return the list of files in the deb.c                s    j | jS )N)appendname)itemdata)filesr
   r   <lambda>W   s    z%DebPackage.filelist.<locals>.<lambda>z(List of files for '%s' could not be read)r   r-   goSystemError_r   )r   r
   )r.   r   filelistR   s    zDebPackage.filelistc                sH   g  y| j jj fdd W n  tk
r>   td| j gS X t S )z, return the list of files in control.tar.gz c                s    j | jS )N)r*   r+   )r,   r-   )r   r
   r   r/   c   s    z-DebPackage.control_filelist.<locals>.<lambda>z0List of control files for '%s' could not be read)r   r   r0   r1   r2   r   sorted)r   r
   )r   r   control_filelist]   s    zDebPackage.control_filelistFc             C   s   d|kr|S | j s|S | jj|r&|S || jkrR| j| jrR| j| jjdkrR|S d|| j f }|| jkrn|S | j| jj}|j|j@ r|S |r|j|j@  r|S |S )N:allz%s:%s)	r   r   is_virtual_package	candidatearchitectureZ_candZ
multi_archZMULTI_ARCH_FOREIGNZMULTI_ARCH_SAME)r   r   in_conflict_checkingZmultiarch_pkgnamecandr
   r
   r   _maybe_append_multiarch_suffixj   s(    

z)DebPackage._maybe_append_multiarch_suffixc       	      C   s   | j dd|  x|D ]}|d }|d }|d }| j|}|| jkr| jj|r| j dd|  x| jj|D ]}|jrpdS qpW q| j| j}|dk	rtj|j	||rdS |sx8| jj|dd	D ]$}|jr| j dd
|j
|f  dS qW qW dS )zReturn True if at least one dependency of the or-group is satisfied.

        This method gets an 'or_group' and analyzes if at least one dependency
        of this group is already satisfied.
           z_checkOrGroup(): %s r      r   z+_is_or_group_satisfied(): %s is virtual depTN)Zinclude_nonvirtualz'found installed '%s' that provides '%s'F)r!   r=   r   r8   get_providing_packagesis_installed	installedr&   	check_depversionr+   )	r   or_groupdepdepnameveroperpkgZinstZppkgr
   r
   r   _is_or_group_satisfied   s6    


z!DebPackage._is_or_group_satisfiedc       
      C   s"  x|D ]}|\}}}| j |}|| jkrZ| jj|s6q| jj|}t|dkrPq|d j}| j| }| jjj|j}|szqt	j
|j||sq| jdd|  | jj| dS W d}	xT|D ]L}|	|d 7 }	|r|r|	d|d |d f 7 }	||t|d  kr|	d7 }	qW |  jtd	|	 7  _d
S )zTry to satisfy the or_group.r?   r   r>   zNeed to get: %sTr   z (%s %s)|z"Dependency is not satisfiable: %s
F)r=   r   r8   r@   lenr+   	_depcacheZget_candidate_ver_pkgr&   rC   Zver_strr!   r   r*   r   r2   )
r   rE   rF   rG   rH   rI   	providersrJ   r<   Zor_strr
   r
   r   _satisfy_or_group   s:    






zDebPackage._satisfy_or_groupc             C   s   | j dd|||f  | j| }|jr0|jj}n|jr@|jj}ndS tj|||r| j	||| r|  j
td|j 7  _
| j dd|j  dS dS )z@Return True if a pkg conflicts with a real installed/marked pkg.r   z8_check_single_pkg_conflict() pkg='%s' ver='%s' oper='%s'Fz)Conflicts with the installed package '%s'z!conflicts with installed pkg '%s'T)r!   r   rA   rB   rD   marked_installr9   r&   rC   replaces_real_pkgr   r2   r+   )r   r   rH   rI   rJ   pkgverr
   r
   r   _check_single_pkg_conflict   s     


z%DebPackage._check_single_pkg_conflictc             C   s   | j dd|  x|D ]}|d }|d }|d }| j|dd}|| jkr| jj|rx^| jj|D ]N}| j dd|j  | j|jkr| j dd	 qd| j|j||rd| jj	|j qdW q| j|||r| jj	| qW t
| jS )
z5Check the or-group for conflicts with installed pkgs.r>   z _check_conflicts_or_group(): %s r   r?   T)r;   r   zconflicts virtual check: %szconflict on self, ignoring)r!   r=   r   r8   r@   r+   r   rU   r#   addbool)r   rE   rF   rG   rH   rI   rJ   r
   r
   r   _check_conflicts_or_group   s*    


z$DebPackage._check_conflicts_or_groupc             C   s0   d}yt j| j| dS  tk
r*   g S X dS )z4List of package names conflicting with this package.	ConflictsFN)r&   parse_dependsr   KeyError)r   r'   r
   r
   r   	conflicts  s
    zDebPackage.conflictsc             C   sH   g }x>dD ]6}y|j tj| j| d W q
 tk
r>   Y q
X q
W |S )z7List of package names on which this package depends on.DependsPre-DependsF)r]   r^   )extendr&   rZ   r   r[   )r   dependsr'   r
   r
   r   r`   (  s    

zDebPackage.dependsc             C   s0   d}yt j| j| dS  tk
r*   g S X dS )z<List of virtual packages which are provided by this package.ZProvidesFN)r&   rZ   r   r[   )r   r'   r
   r
   r   provides5  s
    zDebPackage.providesc             C   s0   d}yt j| j| dS  tk
r*   g S X dS )z4List of packages which are replaced by this package.ZReplacesFN)r&   rZ   r   r[   )r   r'   r
   r
   r   replaces>  s
    zDebPackage.replacesc             C   s   | j dd|||f  | j| }|jr0|jj}n|jr@|jj}nd}xL| jD ]B}x<|D ]4\}}}||krVtj	|||rV| j dd|  dS qVW qLW dS )zReturn True if a given non-virtual package is replaced.

        Return True if the deb packages replaces a real (not virtual)
        packages named (pkgname, oper, ver).
        r   zreplaces_real_pkg() %s %s %sNz?we have a replaces in our package for the conflict against '%s'TF)
r!   r   rA   rB   rD   rR   r9   rb   r&   rC   )r   r   rI   rH   rJ   rT   rE   r+   r
   r
   r   rS   G  s    


zDebPackage.replaces_real_pkgc             C   s&   d}x| j D ]}| j|rd}qW |S )zCheck if there are conflicts with existing or selected packages.

        Check if the package conflicts with a existing or to be installed
        package. Return True if the pkg is OK.
        TF)r\   rX   )r   resrE   r
   r
   r   check_conflicts]  s
    
zDebPackage.check_conflictsc             C   sJ  t t| j}tt|d d}| jd }| jd }dd | jD }xt| jD ]\}}|| dkr| jjj	t || d  |j
sqR|jj}x|jjD ]|}	xv|	jD ]l}
|
j| jkrtj||
j|
js| jd	d
|j  |  jtd|j|
j|
j|
jd 7  _| jjj  dS qW qW d|jkrRx|jd D ]}x|D ]}|jj| jkr|jj|krtj||j|jr| jd	d|j  |  jtd|j|jj|j|jd 7  _| jjj  dS |jj|kr>| j|jkr>| jd	d|  |  jtddj|| j |jj|jd 7  _| jjj  dS q>W q4W qRW | jjj  dS )z
        check if installing the package would break exsisting
        package on the system, e.g. system has:
        smc depends on smc-data (= 1.4)
        and user tries to installs smc-data 1.6
        2   r?   VersionArchitecturec             S   s   g | ]}|d  d  qS )r   r
   ).0xr
   r
   r   
<listcomp>x  s    z=DebPackage.check_breaks_existing_packages.<locals>.<listcomp>r   g      Y@r>   zwould break (depends) %sz]Breaks existing package '%(pkgname)s' dependency %(depname)s (%(deprelation)s %(depversion)s))r   rG   ZdeprelationZ
depversionFrY   zwould break (conflicts) %szZBreaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s %(targetver)s))r   	targetpkgZcomptypeZ	targetverz{Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But the '%(debfile)s' provides it via: '%(provides)s',)ra   Zdebfilerk   r   T)!floatrM   r   maxintr   ra   	enumerateZop_progressupdaterA   rO   Zcurrent_verrB   ZdependenciesZor_dependenciesr+   r   r&   rC   ZrelationrD   r!   r   r2   doneZdepends_listZ
target_pkgr:   Z	comp_typeZ
target_verjoinr   )r   sizeZstepsdebverZdebarchra   irJ   rH   Zdep_orrF   Zconflicts_ver_listZc_orr
   r
   r   check_breaks_existing_packagesk  sp    



z)DebPackage.check_breaks_existing_packagesTc             C   s   | j dd | jd }| jd }dj||g}| jd }| j dd|  || jkr|rr| j| jrr| j| jj}n(| r| j| jr| j| jj}n| jS |d	k	rtj	||}| j dd
|  |dkr| j
S |dk r| jS |dkr| jS | jS )a	  Compare the package to the version available in the cache.

        Checks if the package is already installed or availabe in the cache
        and if so in what version, returns one of (VERSION_NONE,
        VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER).
        r   compare_to_version_in_cacher    rg   r6   rf   r?   z
debver: %sNz"CompareVersion(debver,instver): %sr   )r!   r   rs   r   rB   rD   r9   VERSION_NONEr&   Zversion_compareVERSION_SAMEVERSION_NEWERVERSION_OUTDATED)r   Zuse_installedr   r:   ru   ZcacheverZcmpr
   r
   r   rx     s,    



z&DebPackage.compare_to_version_in_cachec             C   sF  | j dd d| _d| jkr6| j dd td| _dS | jd }|d	kr|tjjd
kr|tj kr|| _	d| j
| j	f | _
| j dd|  n| j dd td| | _dS | r| j | jkr| j| j
 jrtd| _dS d| _| j sdS | j sdS | j| jsdS | j sdS | jjjdkrBtd| _| jj  dS dS )z$Check if the package is installable.r   checkTrg   r?   zERROR: no architecture fieldz$No Architecture field in the packageFr7   zAPT::Architecturez%s:%szFound multiarch arch: '%s'zERROR: Wrong architecture dude!zVWrong architecture '%s' -- Run dpkg --add-architecture to add it and update afterwardsz$A later version is already installedr   r   z1Failed to satisfy all dependencies (broken cache))r!   r   r   r2   r   r&   configfindZget_architecturesr   r   rx   r|   r   rB   rd   rw   _satisfy_dependsr`   rN   Zbroken_countclear)r   Zallow_downgradeZarchr
   r
   r   r}     sH    





zDebPackage.checkc             C   s   | j tj|dS )z-Satisfy the dependencies in the given string.F)r   r&   rZ   )r   Z
dependsstrr
   r
   r   satisfy_depends_str"  s    zDebPackage.satisfy_depends_strc             C   s   yt j| jj}| W n tk
r*   Y nX x$|D ]}| j|s2| j|s2dS q2W xR| jD ]H}y| j| jdd W qZ t	k
r   t
d| | _| jj  dS X qZW dS )zSatisfy the dependencies.F)Z	from_userzCannot install '%s'T)r&   ZActionGroupr   rN   AttributeErrorrK   rQ   r   Zmark_installr1   r2   r   r   )r   r`   Z_actiongrouprE   rJ   r
   r
   r   r   &  s"    




zDebPackage._satisfy_dependsc             C   s&   | j dd| j  | js td| jS )zReturn missing dependencies.r?   zInstalling: %sz-property only available after check() was run)r!   r   r   r   )r   r
   r
   r   missing_deps=  s
    zDebPackage.missing_depsc             C   s   g }g }g }| j stdxh| jD ]^}|js2|jrn|j|j d}x|jjD ]}||j	O }qLW |sn|j|j |j
r"|j|j q"W |||fS )zGet the changes required to satisfy the dependencies.

        Returns: a tuple with (install, remove, unauthenticated)
        z-property only available after check() was runF)r   r   r   rR   Zmarked_upgrader*   r+   r9   ZoriginsZtrustedZmarked_delete)r   installremoveZunauthenticatedrJ   Zauthenticatedoriginr
   r
   r   required_changesF  s"    zDebPackage.required_changesc             C   sB   d}x8t | D ],\}}|d dkr*|d7 }|dt| 7 }qW |S )Nr   P   r   
z%2.2x )rp   ord)in_datahexrv   cr
   r
   r   to_hex`  s    zDebPackage.to_hexc             C   s   d}t | tkrJxl| D ].}t|dk s2t|dkr<|d7 }q||7 }qW n4x2| D ]*}|dk sd|dkrn|d7 }qP|t|7 }qPW |S )Nr   
       )typestrr   chr)r   sr   br
   r
   r   	to_strishi  s    



zDebPackage.to_strishc       	      C   s   |j dr|dd  }|j|}|jdr\|r\t|}tj|d}tdjd}||j 7 }y|j	d}W n* t
k
r   td}|| j|7 }|S X |S )Nz./r>   z.gz)ZfileobjzAutomatically decompressed:

zutf-8z,Automatically converted to printable ascii:
)
startswithr%   endswithr   gzipZGzipFiler2   encodereaddecode	Exceptionr   )	r   partr+   Zauto_decompressZauto_hexr-   ioZgzZnew_datar
   r
   r   _get_content|  s    

zDebPackage._get_contentc             C   s*   y| j | jj|S  tk
r$   dS X dS )z6 return the content of a specific control.tar.gz file r   N)r   r   r   LookupError)r   r+   r
   r
   r   control_content  s    zDebPackage.control_contentc             C   s*   y| j | jj|S  tk
r$   dS X dS )z6 return the content of a specific control.tar.gz file r   N)r   r   r-   r   )r   r+   r
   r
   r   data_content  s    zDebPackage.data_contentc             C   s   || j krt|tjd dS )z%Write debugging output to sys.stderr.)fileN)debugprintsysstderr)r   levelmsgr
   r
   r   r!     s    
zDebPackage._dbgc             C   s   |dkrt jt jddd| jS y|j  W n tk
rF   |j  Y nX |j| j}y|j  W n tk
r|   |j	  Y nX |S dS )zInstall the package.NZdpkgz-i)
osspawnlpP_WAITr   Zstart_updater   ZstartUpdateZrunZfinish_updateZfinishUpdate)r   Zinstall_progressrc   r
   r
   r   r     s    zDebPackage.install)NN)F)T)F)TT)N)+r   r   r   r	   rangery   r|   rz   r{   r   r   r   r(   r)   propertyr3   r5   r=   rK   rQ   rU   rX   r\   r`   ra   rb   rS   rd   rw   rx   r}   r   r   r   r   staticmethodr   r   r   r   r   r!   r   r
   r
   r
   r   r   %   sD   

.- 			W
"
>		
r   c               @   sN   e Zd ZdZdddZedd Zedd Zed	d
 Zdd Z	dd Z
dS )DscSrcPackagez#A locally available source package.Nc             C   sN   t j| d | || _g | _g | _t | _d| _g | _| jd k	rJ| j	| j d S )Nr   )
r   r   r   _depends
_conflictsr"   r#   r   binariesr   )r   r   r   r
   r
   r   r     s    
zDscSrcPackage.__init__c             C   s   | j S )z&Return the dependencies of the package)r   )r   r
   r
   r   r`     s    zDscSrcPackage.dependsc             C   s   | j S )z&Return the dependencies of the package)r   )r   r
   r
   r   r\     s    zDscSrcPackage.conflictsc             C   s   | j d j ddd S )z6Return the list of files associated with this dsc fileZFilesr>   Nr   )r   split)r   r
   r
   r   r3     s    zDscSrcPackage.filelistc       
      C   s4  ddg}ddg}t j|}tj|}t j|}zx|D ]}x,|D ]$}||krNq@| jjt j||  q@W x,|D ]$}||kr|qn| jjt j||  qnW d|kr|d | _	d|krdd |d j
d	D | _x&|j D ]}||kr|| | j|< qW q6W W d
~|j  X td| j	dj| jf }	|	| jd< d| _d
S )zOpen the package.zBuild-DependszBuild-Depends-IndepzBuild-ConflictszBuild-Conflicts-IndepZSourceZBinaryc             S   s   g | ]}|j  qS r
   )strip)rh   r   r
   r
   r   rj     s    z&DscSrcPackage.open.<locals>.<listcomp>rl   NzBInstall Build-Dependencies for source package '%s' that builds %s
r   ZDescriptionF)r&   Zopen_maybe_clear_signed_filer   fdopenZTagFiler   r_   Zparse_src_dependsr   r   r   r   keysr   closer2   rs   r   )
r   r   Zdepends_tagsZconflicts_tagsfdZfobjZtagfileZsectagr   r
   r
   r   r     s<    








zDscSrcPackage.openc             C   sR   | j  s@x6| jD ],}| j| jjr.ttd| j| j  qW d| _| j	| j
S )z%Check if the package is installable..z%An essential package would be removedT)rd   r#   r   rO   Z	essentialr   r2   Zmark_deleter   r   r`   )r   r   r
   r
   r   r}     s    zDscSrcPackage.check)NN)r   r   r   r	   r   r   r`   r\   r3   r   r}   r
   r
   r
   r   r     s   
#r   c        	      C   s  ddl m}  ddlm} |  }d}td||j|f  |j|}td|  x|D ]}td|j  qTW tt	j
d |}td	|j  |j std
 t|j td|j  t|j t|j td |j| }t| t|d}d}t|jtj|d dS )zTest functionr   )r   )InstallProgresszwww-browserz%s virtual: %szProviders for %s :z %sr?   zDeb: %szcan't be satifiedzmissing deps: %szInstalling ...)r   z:libc6 (>= 2.3.2), libaio (>= 0.3.96) | libaio1 (>= 0.3.96)FN)Z	apt.cacher   Zapt.progress.baser   r   r8   r@   r+   r   r   argvr   r}   r   r   r   r3   r   r   r   r&   rZ   )	r   r   r   ZvprP   rJ   dZretr   r
   r
   r   _test  s.    





r   __main__)r	   Z
__future__r   r   r$   r&   r   r   r   r   r2   r   r   IOErrorr   objectr   r   r   r   r
   r
   r
   r   <module>   s(        O&