???<!-- GIF89;a -->
123123123123
.....................................................................................................................................???<!-- GIF89;a -->
123123123123
.....................................................................................................................................3
ft`W.                 @   sZ  d Z ddlmZmZ ddlmZ ddlmZmZmZ ddl	T 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ZddlZddlZddlZddlZddlZdgZdadd	 Zdad
d Zdd ZG dd de Z!dd Z"dd Z#d,ddZ$dd Z%dd Z&dd Z'd-ddZ(d d! Z)da*d"d# Z+d.d$d%Z,d&d' Z-d(d) Z.d/d*d+Z/dS )0z%
Assorted utility functions for yum.
    )print_functionabsolute_import)unicode_literals)base64_decodebytes
basestringunicode)*NZsha256c             C   s   t dkrtjdja t | S )z( Tests if a string is a shell wildcard. Nz[*?]|\[.+\])_re_compiled_glob_matchrecompilesearch)s r   /usr/lib/python3.6/misc.pyre_glob.   s    r   c             C   sF   t dkr(tjdj}tjdj}||fa xt D ]}|| r.dS q.W dS )zC Tests if a string needs a full nevra match, instead of just name. Nz.*([-.*?]|\[.+\]).z[0-9]+:TF)_re_compiled_full_matchr
   r   match)r   ZoneZtwoZrecr   r   r   re_full_search_needed6   s    
r   c               C   s   t d S )Nr   )_default_checksumsr   r   r   r   get_default_chksum_typeD   s    r   c               @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )GenericHolderzGeneric Holder class used to hold other objects of known types
       It exists purely to be able to do object.somestuff, object.someotherstuff
       or object[key] and pass object to another function that will
       understand itNc             C   s
   || _ d S )N)_GenericHolder__iter)selfiterr   r   r   __init__M   s    zGenericHolder.__init__c             C   s   | j d k	rt| | j  S d S )N)r   r   )r   r   r   r   __iter__P   s    
zGenericHolder.__iter__c             C   s    t | |rt| |S t|d S )N)hasattrgetattrKeyError)r   itemr   r   r   __getitem__T   s    

zGenericHolder.__getitem__c             C   s   dd t | j D S )z!Return a dictionary of all lists.c             S   s"   i | ]\}}t |tkr||qS r   )typelist).0keyZlist_r   r   r   
<dictcomp>\   s    z+GenericHolder.all_lists.<locals>.<dictcomp>)varsitems)r   r   r   r   	all_listsZ   s    zGenericHolder.all_listsc             C   s4   x.|j  j D ]\}}t| j|g j| qW | S )z7 Concatenate the list attributes from 'other' to ours. )r(   r'   r&   
setdefaultextend)r   otherr$   valr   r   r   merge_lists_   s    zGenericHolder.merge_lists)N)	__name__
__module____qualname____doc__r   r   r    r(   r-   r   r   r   r   r   G   s   
r   c             C   s   t jdd| } tj }d}d}xn| jdD ]`}|jdr>d}q*|rT|j dkrTd}q*|rf|jdrfP q*|rx|jdrxP q*|r*|j|d  q*W t|j	 S )	z,Convert ASCII-armored GPG key to binary
    s   
?   
r   s$   -----BEGIN PGP PUBLIC KEY BLOCK-----       s"   -----END PGP PUBLIC KEY BLOCK-----   =)
r
   subioBytesIOsplit
startswithstripwriter   getvalue)rawkeyblockZinblockZpastheadersliner   r   r   
procgpgkeye   s     
rA   c             C   sP   xJ| j ddD ]:}|d |krt|d d}||kr8dS ||k rDdS dS qW d	S )
ab  
    Return if the GPG key described by the given keyid and timestamp are
    installed in the rpmdb.

    The keyid and timestamp should both be passed as integers.
    The ts is an rpm transaction set object

    Return values:
        - -1      key is not installed
        - 0       key with matching ID and timestamp is installed
        - 1       key with matching ID is installed but has an older timestamp
        - 2       key with matching ID is installed but has a newer timestamp

    No effort is made to handle duplicates. The first matching keyid is used to
    calculate the return result.
    namez
gpg-pubkeyversionrelease   r   r3      )ZdbMatchint)ZtskeyidZ	timestampZhdrZinstalledtsr   r   r   keyInstalled   s    rJ   Tc             C   s  t jj|st j| tjj| tjj }tt jj	|dd}|j
d W d Q R X |j|  |r|d }t jj|st j|dd xFtj|d D ]4}t jj|}|d | }	tj||	 t j|	d qW d	}
tt jj	|dd
d}|j
|
 W d Q R X dS Q R X W d Q R X d S )Nzgpg.confwbr4   z-roi  )modez/*/zlock-never
    no-auto-check-trustdb
    trust-model direct
    no-expensive-trust-checks
    no-permission-warning
    preserve-permissions
    wT)ospathexistsmakedirsdnfZcryptoZpubring_dirZContextopenjoinr<   Z	op_importglobbasenameshutilcopychmod)r>   rI   ZgpgdirZmake_ro_copyZctxfpZrodirfrW   Zro_fZoptsr   r   r   import_key_to_pubring   s&    

r]   c        	      C   s   t j } y.tj| }tjj|d }dtjj|f }W n$ t	k
rZ   dtjj| f }Y nX dtjj
|f }ttj|}xB|D ]:}t j|}t|d rt|d dkr|d | kr|S qW tj|tjj
d}|S )zqreturn a path to a valid and safe cachedir - only used when not running
       as root or when --tempcache is setr   z%s-%s-z%s/%s*i     )prefixdir)rO   geteuidpwdgetpwuidrS   Zi18nZucdconstZPREFIXr   ZTMPDIRsortedrV   lstatS_ISDIRS_IMODEtempfileZmkdtemp)	ZuidZusertupZusernamer_   dirpathZ	cachedirsZthisdirZstatsZcachedirr   r   r   getCacheDir   s    


(rk   c             C   sf   g }t | }t| } d}x6||krN|| }|j| ||  ||7 }||8 }qW |j| |d  |S )zE Given a seq, split into a list of lists of length max_entries each. r   N)lenr"   append)seqZmax_entriesretZnumZbegendr   r   r   seq_max_split   s    
rq   c             C   sD   yt j|  W n0 tk
r> } z|jtjkr. W Y dd}~X nX dS )z| Call os.unlink, but don't die if the file isn't there. This is the main
        difference between "rm -f" and plain "rm". N)rO   unlinkOSErrorerrnoENOENT)filenameer   r   r   unlink_f   s
    rx   Fc             C   s^   y
t j| S  tk
rX } z2|jtjtjfkr2dS |rF|jtjkrFdS  W Y dd}~X nX dS )zF Call os.stat(), but don't die if the file isn't there. Returns None. N)rO   statrs   rt   ru   ENOTDIRZEACCES)rv   Zignore_EACCESrw   r   r   r   stat_f   s    
r{   c              C   sF   y$t d} | j }t|S Q R X W n ttfk
r@   tj S X dS )z Get the audit-uid/login-uid, if available. os.getuid() is returned
        instead if there was a problem. Note that no caching is done here. z/proc/self/loginuidN)rT   readrH   IOError
ValueErrorrO   getuid)fodatar   r   r   _getloginuid   s    
r   c               C   s   t dkrt a t S )z Get the audit-uid/login-uid, if available. os.getuid() is returned
        instead if there was a problem. The value is cached, so you don't
        have to save it. N)_cached_getloginuidr   r   r   r   r   getloginuid  s    r   c       	      C   s   |r
|}nJd}| j d}|dkr@| |d }|dkr@| d| }|dkrTtjjd
|rt| }t|}|r|r|j|jkr|S ytjj| |d W n2 t	k
r } ztjjt
|W Y dd}~X nX |r|rtj||j|jf |S )ztake a filename and decompress it into the same relative location.
       When the compression type is not recognized (or file is not compressed),
       the content of the file is copied to the destinationN.r   .zck.xz.bz2.gz.lzma.zstz(Could not determine destination filenamei  )r   r   r   r   r   r   )rfindrS   
exceptionsZ	MiscErrorr{   st_mtimelibdnfZutils
decompressRuntimeErrorstrrO   utime)	rv   destcheck_timestampsoutZdot_posZextZfir   rw   r   r   r   r     s,    
"r   c             C   s:   t jj| }|d7 }t jj|s.t j|dd |d | S )Nz/geni  )rL   rM   )rO   rP   dirnamerQ   rR   )rv   generated_namer   r   r   r   calculate_repo_gen_dest8  s
    r   c             C   s   t | |}t| |ddS )z This is a wrapper around decompress, where we work out a cached
        generated name, and use check_timestamps. filename _must_ be from
        a repo. and generated_name is the type of the file. T)r   r   )r   r   )rv   r   r   r   r   r   repo_gen_decompress@  s    
r   c             C   s   g }xt j | D ]}t|n}xf|D ]^}tjd|r6q$|j }|j }|sLq$|rx|jdd}|jdd}|j|j  q$|j	| q$W W dQ R X qW |S )a(   Takes a glob of a dir (like /etc/foo.d/\*.foo) returns a list of all
       the lines in all the files matching that glob, ignores comments and blank
       lines, optional paramater 'line_as_list tells whether to treat each line
       as a space or comma-separated list, defaults to True.
    z\s*(#|$)
 ,N)
rV   rT   r
   r   rstriplstripreplacer*   r9   rm   )ZthisglobZline_as_listresultsZfnamer\   r@   r   r   r   read_in_items_from_dot_dirH  s"    

r   )NT)F)NF)T)0r1   Z
__future__r   r   r   Z
dnf.pycompr   r   r   ry   Zlibdnf.utilsr   Z	dnf.constrS   Z
dnf.cryptoZdnf.exceptionsZdnf.i18nrt   rV   r7   rO   Zos.pathrb   r
   rX   ri   r   r	   r   r   r   r   objectr   rA   rJ   r]   rk   rq   rx   r{   r   r   r   r   r   r   r   r   r   r   r   <module>   sN   
#	


#