3
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jdZG dd deZdd Zed	kre  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   zThe 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| jd| _ tjd| j   t	j	t	j
t	j| _	| 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 j 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 jd | jjd tj| 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 jd | jj  | jdk	r0tj| j d| _| jrhytj	| j
 tj| 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OSError)r   r   r   r   stop[   s    


zDebconfProxy.stopc             C   s   | j rtjd dS |j \}}|| _ tjtjB tjB tjB }t	j
dgt	jt	j| j d| _tj|tj|| j| jj tj| 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 jd y*|j }|r2tjd| |j| dS W n2 tjtfk
rf } ztj| W Y dd}~X nX tjd | jj	j
  | jj
  d| _dS )zaCallback to copy data from the stdout of debconf-communicate to
        the passthrough frontend.r/   zFrom debconf: %sTNzStop reading from stdoutF)r   r   readliner   sendr   errorIOErrorr-   r)   r#   r   )r   sourcer0   r1   Zdebconf_datar5   r   r   r   r/   z   s    



zDebconfProxy._copy_stdoutc             C   s   t jd y4|jd}|r<tjd| |j| |j  dS W n2 tjtfk
rp } ztj| W Y dd}~X nX tjd | j	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   r5   r6   r-   r(   r#   )r   r7   r0   r(   Zsocket_datar5   r   r   r   r.      s    



zDebconfProxy._copy_conn)r   N)__name__
__module____qualname____doc__r   r   r"   r'   r!   r/   r.   r   r   r   r   r   +   s   
c              C   sN   t jt jd d} tjj| r(tj|  td| }|j  t	j
 }|j  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MainLoopZrun)r   proxyZloopr   r   r   _test   s    

r@   __main__)r   )r=   __all__r   r   r	   os.pathr   r*   r   sysZgi.repositoryr   Z	getLoggerr   objectr   r@   r:   r   r   r   r   <module>	   s   
u