U
    ƒìõSö  ã                   @   sˆ   d Z d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Zddl	Z	ddl
mZ e d¡ZG dd„ deƒZdd	„ Zed
kr„eƒ  dS )zÞ
Integration of debconf on the client side

Provides the DebconfProxy class which allows to run the debconf frontend
as normal user by connecting to the root running debconf through the
socket of the passthrough frontend.
)ÚDebconfProxyé    N)ÚGLibzAptClient.DebconfProxyc                   @   sJ   e Zd ZdZddd„Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dS )r   z§The DebconfProxy class allows to run the debconf frontend
    as normal user by connecting to the root debconf through the socket of the
    passthrough frontend.
    ÚgnomeNc                 C   s€   || _ d| _|dkr4tjdd| _tj | jd¡| _ t d| j  ¡ t	 	t	j
t	j¡| _	| j	 | j ¡ || _d| _d| _g | _dS )a  Initialize a new DebconfProxy instance.

        Keyword arguments:
        frontend -- the to be used debconf frontend (defaults to gnome)
        socket_path -- the path to the socket of the passthrough frontend.
            Will be created if not specified
        Nz
aptdaemon-)Úprefixzdebconf.socketzdebconf socket: %s)Úsocket_pathÚtemp_dirÚtempfileZmkdtempÚosÚpathÚjoinÚlogÚdebugÚsocketZAF_UNIXZSOCK_STREAMZbindÚfrontendÚ_listener_idÚ_active_connZ
_watch_ids)Úselfr   r   © r   ú3/usr/lib/python3/dist-packages/aptdaemon/debconf.pyÚ__init__2   s    zDebconfProxy.__init__c                 C   s>   t   tj¡}d|d< d|d< | j|d< tjtjkr:d|d< |S )zcReturns a dictonary of the environment variables required by
        the debconf frontend.
        ZconfigdbZDEBCONF_DB_REPLACEzPipe{infd:none outfd:none}ZDEBCONF_DB_OVERRIDEZDEBIAN_FRONTENDÚ.ZDEBCONF_DEBUG)Úcopyr	   Úenvironr   r   ÚlevelÚloggingÚDEBUG)r   Úenvr   r   r   Ú_get_debconf_envG   s    
zDebconfProxy._get_debconf_envc                 C   s4   t  d¡ | j d¡ t | jtjtj| j¡| _	dS )zStart listening on the socket.zdebconf.start()é   N)
r   r   r   Zlistenr   Úio_add_watchZPRIORITY_DEFAULT_IDLEÚIO_INÚ_accept_connectionr   ©r   r   r   r   ÚstartS   s    
  þzDebconfProxy.startc                 C   sl   t  d¡ | j ¡  | jdk	r0t | j¡ d| _| jrhzt 	| j
¡ t | j¡ W n tk
rf   Y nX dS )zStop listening on the socket.zdebconf.stop()N)r   r   r   Úcloser   r   Zsource_remover   r	   Úremover   ÚrmdirÚOSErrorr"   r   r   r   Ústop[   s    


zDebconfProxy.stopc                 C   s”   | j rt d¡ dS | ¡ \}}|| _ tjtjB tjB tjB }t	j
dgt	jt	j|  ¡ d| _t |tj|| j| jj¡ t | jjtj|| j|¡ dS )NzDelaying connectionTzdebconf-communicate)ÚstdinÚstdoutr   )r   r   r   Zacceptr   r    ZIO_ERRZIO_HUPZIO_NVALÚ
subprocessÚPopenÚPIPEr   Úhelperr   ZPRIORITY_HIGH_IDLEÚ
_copy_connr)   r*   Ú_copy_stdout)r   r   Ú	conditionÚconnZaddrÚmaskr   r   r   r!   i   s,    
ý
  ÿ  ÿzDebconfProxy._accept_connectionc              
   C   s”   t  d¡ z,| ¡ }|r4t d|¡ | |¡ W dS W n2 tjtfk
rh } zt |¡ W 5 d}~X Y nX t d¡ | jj	 
¡  | j 
¡  d| _dS )zaCallback to copy data from the stdout of debconf-communicate to
        the passthrough frontend.r0   zFrom debconf: %sTNzStop reading from stdoutF)r   r   Úreadliner   Úsendr   ÚerrorÚIOErrorr.   r*   r$   r   )r   Úsourcer1   r2   Zdebconf_datar6   r   r   r   r0   z   s    




zDebconfProxy._copy_stdoutc              
   C   sŽ   t  d¡ z6| d¡}|r>t d|¡ | |¡ | ¡  W dS W n2 tjtfk
rr } zt |¡ W 5 d}~X Y nX t d¡ | j	j
 ¡  dS )z\Callback to copy data from the passthrough frontend to stdin of
        debconf-communicate.r/   i   zFrom socket: %sTNzStop reading from connF)r   r   Zrecvr   ÚwriteÚflushr   r6   r7   r.   r)   r$   )r   r8   r1   r)   Zsocket_datar6   r   r   r   r/      s    




zDebconfProxy._copy_conn)r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r#   r(   r!   r0   r/   r   r   r   r   r   +   s   
r   c                  C   sN   t jt jd d} tj | ¡r(t | ¡ td| ƒ}| ¡  t	 
¡ }| ¡  dS )a4  Run the DebconfProxy from the command line for testing purposes.

    You have to execute the following commands before in a separate terminal:
    $ echo "fset debconf/frontend seen false" | debconf-communicate
    $ export DEBCONF_PIPE=/tmp/debconf.socket
    $ dpkg-reconfigure debconf -f passthrough
    )r   z/tmp/debconf.socketr   N)r   ZbasicConfigr   r	   r
   Úexistsr%   r   r#   r   ZMainLoopÚrun)r   ÚproxyZloopr   r   r   Ú_test    s    

rB   Ú__main__)r>   Ú__all__r   r   r	   Úos.pathr   r+   r   ÚsysZgi.repositoryr   Z	getLoggerr   Úobjectr   rB   r;   r   r   r   r   Ú<module>   s   
u