Current File : //usr/lib64/python3.6/site-packages/borg/__pycache__/helpers.cpython-36.pyc
3

up�d=y�@s�ddlZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZ
ddlZddl
Z
ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddlmZmZmZmZddlmZmZm Z ddl!m"Z"m#Z#ddl$m%Z%ddl&m'Z'ddl
m(Z(dd	l)m*Z*dd
l+m,Z,dZ-y&e-�rTe.�ddl/j0j1Z1ddl/m2Z3Wn*e.k
�r�ddl1Z1ddl1m2Z3YnXd
dl4m5Z5e5�Z4ddl6Z7d
dl8m9Z:d
dl8m;Z<d
dl8m=Z=d
dl8m>Z>d
dl8m?Z?d
dl@TeAe
jBjCdd�jDd��ZEeFaGdd�ZHGdd�deI�ZJGdd�deJ�ZKGdd�deK�ZLGd d!�d!eL�ZMGd"d#�d#eJ�ZNGd$d%�d%eJ�ZOGd&d'�d'eJ�ZPGd(d)�d)eP�ZQGd*d+�d+eJ�ZRd,d-�ZSGd.d/�d/eJ�ZTd0d1�ZUd2d3�ZVed4d5�ZWGd6d7�d7ejX�ZYGd8d9�d9�ZZd:d;�Z[d<d=�Z\d>d?�Z]gfd@dA�Z^ej_ej`BejaBdBfdCdD�ZbdEdF�ZcdGdH�Zd�d*dIdJ�ZedKdL�ZfdMdN�ZgdOdP�ZhejifdQdR�ZjdSdT�ZkdUdV�ZldWdX�ZmdYdZ�Znd[d\�Zod]d^�ZpGd_d`�d`�Zqdadb�Zrifdcdd�ZsesZtesZuesZvdTgeweWjx�Zyeyjzde�dfdg�Z{dBZ|e|�r�d.Z}e}dlZ~n�d5Z~e~dlZ}dndo�Zdpdq�Z�drds�Z��d6edt�dudv�Z�edt�dwdx�Z�dydz�Z�Gd{d|�d|�Z��d7d}d~�Z�Gdd��d�e��Z�d�d��Z��d8d�d��Z��d9d�d��Z��d:d�d��Z�d�d��Z�Gd�d��d��Z�e#dd���d;d�d���Z�e#dd���d<d�d���Z�e#dd���d=d�d���Z�e#dd���d>d�d���Z�d�d��Z��d?d�d��Z��d@d�d��Z�d�d��Z�d�d��Z�Gd�d��d��Z��dAd�d��Z�d�d��Z��dBd�d��Z�d�d��Z��dCd�d��Z�ej�d��Z�d�d��Z�d�d��Z�Gd�d��d�e��Z�d�d��Z�d�d��Z�d�d��Z�d�d��Z��dDZ��dEZ��dFZ�ddddddd�e�e�e�ddBdde�dBdfd�dDŽZ�d�dӄZ�d�dՄZ�Gd�dׄd׃Z�d�dلZ�Gd�dۄd�e��Z�Gd�d݄d�e��Z�Gd�d߄d߃Z�d�d�Z�ej�e4d�d�d�Z�Gd�d�d�Z�Gd�d�d�e��Z�Gd�d�d�e��Z�Gd�d�d�Z�d�d�Z�d�d�Z�d�d�Z�d�d�Z��dGd�d��Z�d�d��Z��dHd�d��Z��dId�d��Z�Gd�d��d�ejÃZ�G�d�d��deŃZ�G�d�d��deƃZ�G�d�d��deƃZ�ejɐd�d��Zʐd�d	�Zːd
�d�Z�G�d�d
��d
e	j̓Z�dd�d��d�d�Zϐd�d�ZАd�d�Zѐd�d�ZҐd�d�ZӐdJeԐd��d�d�ZՐdK�d�d�Z֐d�d�Z�ej�f�d �d!�Zِd"�d#�Z�ddl
Z�ddlZ�ddlZ�d�d$l�m�Z�m�Z�m�Z�m�Z�m�Z��dL�d&�d'�Z�dM�d(�d)�Z�dS(N�N)�hexlify)�
namedtuple�deque�abc�Counter)�datetime�timezone�	timedelta)�partial�	lru_cache)�islice)�
attrgetter)�scandir)�	Formatter)�get_terminal_sizeF)�fallback�)�
create_logger)�__version__)�__version_tuple__)�chunker)�	hashindex)�shellpattern)�*ZBORG_WORKAROUNDS��,cCstt|�atS)z�
    Sets the exit code of the program, if an exit code higher or equal than this is set, this does nothing. This
    makes EXIT_ERROR override EXIT_WARNING, etc..

    ec: exit code to set
    )�max�	exit_code)Zec�r�/usr/lib64/python3.6/helpers.py�set_eccs
r cs4eZdZdZeZdZ�fdd�Zdd�ZeZ	�Z
S)�Errorz	Error: {}Fcst�j|�||_dS)N)�super�__init__�args)�selfr$)�	__class__rrr#zszError.__init__cCst|�jj|j�S)N)�type�__doc__�formatr$)r%rrr�get_message~szError.get_message)�__name__�
__module__�__qualname__r(Z
EXIT_ERRORr�	tracebackr#r*�__str__�
__classcell__rr)r&rr!osr!c@seZdZdZdZdS)�ErrorWithTracebackz	Error: {}TN)r+r,r-r(r.rrrrr1�sr1c@seZdZdZdS)�IntegrityErrorzData integrity error: {}N)r+r,r-r(rrrrr2�sr2c@seZdZdZdS)�DecompressionErrorzDecompression error: {}N)r+r,r-r(rrrrr3�sr3c@seZdZdZdS)�ExtensionModuleErrorzFThe Borg binary extension modules do not seem to be properly installedN)r+r,r-r(rrrrr4�sr4c@seZdZdZdS)�NoManifestErrorzRepository has no manifest.N)r+r,r-r(rrrrr5�sr5c@seZdZdZdS)�PlaceholderErrorz)Formatting Error: "{}".format({}): {}({})N)r+r,r-r(rrrrr6�sr6c@seZdZdZdS)�InvalidPlaceholderz&Invalid placeholder "{}" in string: {}N)r+r,r-r(rrrrr7�sr7c@seZdZdZdS)�PythonLibcTooOldzXFATAL: this Python was compiled for a too old (g)libc and misses required functionality.N)r+r,r-r(rrrrr8�sr8cCs$tjtjtjh}tjj|�s t�dS)N)�os�stat�utime�chown�supports_follow_symlinks�
issupersetr8)Zrequired_funcsrrr�check_python�sr?c@seZdZdZdS)�MandatoryFeatureUnsupportedzdUnsupported repository feature(s) {}. A newer version of borg is required to access this repository.N)r+r,r-r(rrrrr@�sr@cCs|ddlm}m}m}tjdkr"t�tjdkr0t�|jdkr>t�tj	j
jdkrPt�|j|jksf|jdkrjt�|jdkrxt�dS)	Nr)�platform�compress�itemz1.1_07z1.1_01z1.1_06z1.1_02z1.1_04z1.1_03)rrArBrCrZAPI_VERSIONr4r�borgZcryptoZ	low_levelZOS_API_VERSION)rArBrCrrr�check_extension_modules�s



rEc	Cs�tddddttt�td�}|dkr8|jtddd��n�|dkrT|jttdd��np|d	krx|jtd
dtdtdd
��nL|dkr�|jtd
ddtd��n,|dkr�|jtd
dddtdd
��ntd��t	j
f|�S)zWreturn a limited Unpacker because we should not trust msgpack data received from remoteFr�)�use_listZmax_bin_lenZmax_ext_lenZmax_buffer_size�max_str_lenZserver�d)�
max_array_len�max_map_lenZclient�manifestT��surrogateescape)rGrJrKrH�object_hookZunicode_errors�archivei')rGrKrHrO�key�
i�z4kind must be "server", "client", "manifest" or "key")�dictrZBUFSIZEZMAX_OBJECT_SIZE�updateZLIST_SCAN_LIMIT�MAX_ARCHIVES�
StableDict�
ValueError�msgpackZUnpacker)Zkindr$rrr�get_limited_unpacker�s@rY�ArchiveInfoz
name id tsc@speZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	ddfdddd�dd�Z
dd�Zdd�Zdd�Z
dS)�Archivesz�
    Nice wrapper around the archives dict, making sure only valid types/values get in
    and we can deal with str keys (and it internally encodes to byte keys) and either
    str timestamps or datetime timestamps.
    cCs
i|_dS)N)�	_archives)r%rrrr#�szArchives.__init__cCs
t|j�S)N)�lenr\)r%rrr�__len__�szArchives.__len__cCstdd�|jD��S)Ncss|]}t|�VqdS)N)�safe_decode)�.0�namerrr�	<genexpr>�sz$Archives.__iter__.<locals>.<genexpr>)�iterr\)r%rrr�__iter__�szArchives.__iter__cCsRt|t�st�t|�}|jj|�}|dkr.t�t|djd��}t	||d|d�S)Nstimezutf-8sid)ra�id�ts)
�
isinstance�str�AssertionError�safe_encoder\�get�KeyError�parse_timestamp�decoderZ)r%ra�_name�valuesrfrrr�__getitem__�szArchives.__getitem__cCs�t|t�st�t|�}t|t�s$t�|\}}t|t�s:t�t|t�rV|jdd�jt	�}t|t�sdt�|j
�}||d�|j|<dS)N)�tzinfo)sidstime)rgrhrirj�tuple�bytesr�replace�strftime�
ISO_FORMAT�encoder\)r%ra�inforerfrrr�__setitem__s
zArchives.__setitem__cCs"t|t�st�t|�}|j|=dS)N)rgrhrirjr\)r%rarrr�__delitem__szArchives.__delitem__Nz\ZF)�glob�	match_end�sort_by�first�last�reversec	s�t|ttf�rtd��tjtj|p$d|d����fdd�|j�D�}x t	|�D]}|j
t|�d�qNW|rx|d|�}n|r�|tt
|�|d�d�}|r�|j�|S)	aH
        Return list of ArchiveInfo instances according to the parameters.

        First match *glob* (considering *match_end*), then *sort_by*.
        Apply *first* and *last* filters, and then possibly *reverse* the list.

        *sort_by* is a list of sort keys applied in reverse order.

        Note: for better robustness, all filtering / limiting parameters must default to
              "not limit / not filter", so a FULL archive list is produced by a simple .list().
              some callers EXPECT to iterate over all archives in a repo for correct operation.
        z!sort_by must be a sequence of strr)r}cs g|]}�j|j�dk	r|�qS)N)�matchra)r`�x)�regexrr�
<listcomp>(sz!Archives.list.<locals>.<listcomp>)rQNr)rgrhrt�	TypeError�re�compiler�	translaterp�reversed�sortr
rr]r�)	r%r|r}r~rr�r��archivesZsortkeyr)r�r�lists
z
Archives.listcCsF|jjrtd��|jdk	r&|jd|_|j|jjd�|j|j|j	d�S)zi
        get a list of archives, considering --first/last/prefix/glob-archives/sort cmdline args
        zaThe options --first, --last, --prefix and --glob-archives can only be used on repository targets.Nrr)r~r|rr�)
�locationrPr!�prefixZ
glob_archivesr�r~�splitrr�)r%r$rrr�list_considering3s

zArchives.list_consideringcCsPxJ|j�D]>\}}t|t�s t�t|t�r:d|kr:d|ks>t�||j|<q
WdS)z-set the dict we get from the msgpack unpackersidstimeN)�itemsrgrtrirSr\)r%�d�k�vrrr�set_raw_dict=szArchives.set_raw_dictcCs|jS)z.get the dict we can give to the msgpack packer)r\)r%rrr�get_raw_dictDszArchives.get_raw_dict)r+r,r-r(r#r^rdrqrzr{r�r�r�r�rrrrr[�s	
r[c@s�eZdZejGdd�dej��Ze�Ze	g�Z
ddZddd�Ze
dd	��Ze
d
d��Zedd
d��Zdd�Zdd�Zdd�ZdS)�Manifestc@seZdZdZdZdZdZdS)zManifest.Operation�readZcheck�write�deleteN)r+r,r-ZREADZCHECKZWRITEZDELETErrrr�	OperationKs
r��� NcCs@t�|_i|_||_||_|dk	r*t|�nt|_d|_d|_	dS)NF)
r[r��configrQ�
repository�	frozenset�	ITEM_KEYS�	item_keys�tam_verified�	timestamp)r%rQr�r�rrrr#iszManifest.__init__cCs
t|j�S)N)�
bin_to_hexre)r%rrr�id_strrszManifest.id_strcCst|jdd�S)N)rr)rmr�)r%rrr�last_timestampvszManifest.last_timestampFcCs�ddlm}ddlm}m}m}ddlm}	y|j|j	�}
Wn|	j
k
rVt�YnX|sf|||
�}|||�}|jd|
�}|j
||d�\}
|_||
d�}|j|�|_|jd�dkr�td	��|jj|j�|jd
�|_|j|_ttdd�|jd
g�D��B|_|j�rp|jjdd�}||�}|�rJ|�rJtjd�||�}t|d�j�|�rp|�rptjd�tj||��|j|�||fS)Nr)�ManifestItem)�key_factory�tam_required_file�tam_required)�
Repository)�force_tam_not_required)Z
internal_dict�version�zInvalid manifest versionr�css|]}|j�VqdS)N)rn)r`rQrrrrb�sz Manifest.load.<locals>.<genexpr>r�stam_requiredFzPManifest is TAM verified and says TAM is required, updating security database...�wzVManifest is TAM verified and says TAM is *not* required, updating security database...)rr�) rCr�Z
crypto.keyr�r�r�r�r�rk�MANIFEST_IDZObjectNotFoundr5ZdecryptZunpack_and_verify_manifestr��id_hashrerWr�r�r�r�r�r�r��logger�debug�open�closer9�unlink�check_repository_compatibility)�clsr��
operationsrQr�r�r�r�r�r�ZcdatarL�dataZ
manifest_dict�mZmanifest_requiredZsecurity_required�filerrr�loadzs@



 


z
Manifest.loadcCs�x�|D]|}t||j�st�|jjdd�}|dkr4dS|jj�|krDq||jj�}d|krt|d�|j}|rt	dd�|D���qWdS)Ns
feature_flagss	mandatorycSsg|]}|j��qSr)rn)r`�frrrr��sz;Manifest.check_repository_compatibility.<locals>.<listcomp>)
rgr�rir�rk�valuerx�set�SUPPORTED_REPO_FEATURESr@)r%r��	operation�
feature_flags�requirementsZunsupportedrrrr��s
z'Manifest.check_repository_compatibilitycCs^i}|jjdd�}|dkr|Sx:|j�D].\}}d|kr(tdd�|dD��||j�<q(W|S)Ns
feature_flagss	mandatorycSsg|]}|j��qSr)rn)r`Zfeaturerrrr��sz7Manifest.get_all_mandatory_features.<locals>.<listcomp>)r�rkr�r�rn)r%�resultr�r�r�rrr�get_all_mandatory_features�s"z#Manifest.get_all_mandatory_featurescCsddlm}|jjrd|jd<|jdkr:tj�jt	�|_n0|j
}|tdd�jt	�}t|tj�jt	��|_t
|j�tks|t�tdd�|jD��s�t�t
|j�dks�t�|dt|jj��|jt|j�tt|j��d	�}d|_|jj|j��}|jj|�|_|jj|j|jj|��dS)
Nr)r�Tstam_required)Zmicrosecondscss|]}t|�dkVqdS)rMN)r])r`rarrrrb�sz!Manifest.write.<locals>.<genexpr>rI)r�r�r�r�r�) rCr�rQr�r�r�r�utcnowrvrwr�r	rr]r�rUri�allr�rVr�rs�sortedr�Zpack_and_authenticate_metadataZas_dictr�rer�Zputr�Zencrypt)r%r�Zprev_tsZincrementedrLr�rrrr��s*

zManifest.write)N)NF)r+r,r-�enum�unique�Enumr�rsZNO_OPERATION_CHECKr�r�r�r#�propertyr�r��classmethodr�r�r�r�rrrrr�Is

	$r�cCs"t|�}|dkrtjd|��|S)z#argparse type for positive integersrz"A positive integer is required: %s)�int�argparse�ArgumentTypeError)r�Z	int_valuerrr�positive_int_validator�sr�cCs�dddddd�}|jt|j���r8|dd�}|d}n4dd	�t|j�d
d�d�D�}tjd
|d|f��yt|�||}Wntk
r�d}YnX|dkr�tjd|��|S)zDConvert a string representing a valid interval to a number of hours.r���im)�Hr�r�r��yNcSsg|]\}}|�qSrr)r`r�r�rrrr��szinterval.<locals>.<listcomp>cSs|dS)Nrr)�trrr�<lambda>�szinterval.<locals>.<lambda>)rQz6Unexpected interval time unit "%s": expected one of %rrzCUnexpected interval number "%s": expected an integer greater than 0�i�i8"���r�r�r�)	�endswithrs�keysr�r�r�r�r�rW)�sZ
multiplierZnumber�suffixZranges�hoursrrr�interval�s


r�cs,tjtj�t|dd���fdd�|D�S)Ni)Zsecondscsg|]}|j�kr|�qSr)rf)r`�a)�targetrrr��sz prune_within.<locals>.<listcomp>)r�nowr�utcr	)r�r�r)r�r�prune_within�sr�cCspd}g}|dkr|SxVt|td�dd�D]@}t|j�j|�}||kr(|}||kr(|j|�t|�|kr(Pq(W|S)NrrfT)rQr�)r�r
�to_localtimerfrv�appendr])r��pattern�n�skipr�Zkeepr�Zperiodrrr�prune_split�s
r�TcCsPytj||dd�Wn6tk
rJ}z|r8tt|���n�WYdd}~XnXdS)a
    Ensures that the dir exists with the right permissions.
    1) Make sure the directory exists in a race-free operation
    2) If mode is not None and the directory has been created, give the right
    permissions to the leaf directory. The current umask value is masked out first.
    3) If pretty_deadly is True, catch exceptions, reraise them with a pretty
    message.
    Returns if the directory has been created and has the right permissions,
    An exception otherwise. If a deadly exception happened it is reraised.
    T)�mode�exist_okN)r9�makedirs�OSErrorr!rh)�pathr�Z
pretty_deadly�errr�
ensure_dir
sr�cCs:tjjd�ptjjd�}|s6tjjdtjjdd��}|S)z�Get home directory / base directory for borg:

    - BORG_BASE_DIR, if set
    - HOME, if set
    - ~$USER, if USER is set
    - ~
    �
BORG_BASE_DIR�HOMEz~%sZUSERr)r9�environrkr��
expanduser)Zbase_dirrrr�get_base_dirsr�cCs0tjjd�}|dkr$tjjt�d�}t|�|S)z,Determine where to repository keys and cacheZ
BORG_KEYS_DIRNr�)r9r�rkr��join�get_config_dirr�)Zkeys_dirrrr�get_keys_dir0s
r�cCsBtjjd�}|dkr$tjjt�d�}|r6tjj||�}t|�|S)z4Determine where to store local security information.ZBORG_SECURITY_DIRNZsecurity)r9r�rkr�r�r�r�)Z
repository_idZsecurity_dirrrr�get_security_dir:sr�c	Cs�tjjt�d�}tjjd�s*tjjd|�}tjjdtjj|d��}t|�tjj|t�}tjj|�s�t	t
jd�jd�}dd	l
m}||d
d��}|j|�WdQRX|S)
z,Determine where to repository keys and cachez.cacher�ZXDG_CACHE_HOMEZBORG_CACHE_DIRrDz�
        # This file is a cache directory tag created by Borg.
        # For information about cache directory tags, see:
        #       http://www.bford.info/cachedir/spec.html
        �asciir)�SaveFileT)�binaryN)r9r�r�r�r�rkr��CACHE_TAG_NAME�exists�CACHE_TAG_CONTENTS�textwrap�dedentrxrArr�)Z
cache_home�	cache_dirZcache_tag_fnZcache_tag_contentsr�fdrrr�
get_cache_dirFsr	cCsNtjjt�d�}tjjd�s*tjjd|�}tjjdtjj|d��}t|�|S)z%Determine where to store whole configz.configr�ZXDG_CONFIG_HOMEZBORG_CONFIG_DIRrD)r9r�r�r�r�rkr�)Zconfig_homeZ
config_dirrrrr�^sr�c	Cs,ttj|tdddtjd�j��dd��S)z3Convert datetime object from UTC to local time zonei�r)rrN�)r�timeZ	localtimerr��
total_seconds)rfrrrr�lsr�cCs4d|krtnt}tj||�}|dk	r0|j|d�}|S)z!Parse a ISO 8601 timestamp string�.N)rr)rw�ISO_FORMAT_NO_USECSr�strptimeru)r�rrZfmt�dtrrrrmqs
rmcCszy ttj|�j�}tj|tjd�Stk
rtx:dD]2}ytj	||�j
tjd
�Stk
rfw6Yq6Xq6Wt�YnXdS)
z5Convert a --timestamp=s argument to a datetime object)Ztz�%Y-%m-%dT%H:%M:%SZ�%Y-%m-%dT%H:%M:%S+00:00�%Y-%m-%dT%H:%M:%S�%Y-%m-%d %H:%M:%S�%Y-%m-%dT%H:%M�%Y-%m-%d %H:%M�%Y-%m-%d�%Y-%j)rrN)rrrrrrrr)�safe_sr9r:�st_mtimer�
fromtimestamprr�r�rrurW)r�rfr)rrrr�zsr�cCsV|j�j�dkrtS|jd�\}}}}t|�dkr:td��t|�t|�t|�t|�fS)N�defaultr�zOmax. chunk size exponent must not be more than 23 (2^23 = 8MiB max. chunk size))�strip�lowerZCHUNKER_PARAMSr�r�rW)r�Z	chunk_minZ	chunk_maxZ
chunk_maskZwindow_sizerrr�
ChunkerParams�sr cs�tddddddd��d}t|j�jd��}|t��ksLtddjt������fdd�|D�}djt|��}||kr�tddj|���|S)N�cr�r��i�rr�)�ctime�mtime�size�inodeZrechunkZdisabled�cis�ims�cs�ms�cr�mrrz0cache mode must be a comma-separated list of: %scsh|]}�|�qSrr)r`�entry)�ENTRIES_MAPrr�	<setcomp>�sz!FilesCacheMode.<locals>.<setcomp>rz#cache mode short must be one of: %s)r(r)r*r+r,r-r�r�)rSr�rr�rWr�r�)r�ZVALID_MODES�entriesZ
short_entriesr�r)r/r�FilesCacheMode�sr2cCshtjj|t�}y@tjj|�rLt|d�� }|jtt��}|tkrBdSWdQRXWnt	k
rbYnXdS)z�Determines whether the specified path is a cache directory (and
    therefore should potentially be excluded from the backup) according to
    the CACHEDIR.TAG protocol
    (http://www.bford.info/cachedir/spec.html).
    �rbTNF)
r9r�r�rrr�r�r]rr�)r��tag_pathZtag_fileZtag_datarrr�dir_is_cachedir�sr5cCsbg}|r$t|�r$|jtjj|t��|dk	r^x0|D](}tjj||�}tjj|�r2|j|�q2W|S)aDetermines whether the specified path is excluded by being a cache
    directory or containing user-specified tag files/directories. Returns a
    list of the paths of the tag files/directories (either CACHEDIR.TAG or the
    matching user-specified files/directories).
    N)r5r�r9r�r�rr)r�Zexclude_cachesZexclude_if_presentZ	tag_paths�tagr4rrr�
dir_is_tagged�s
r7csBx<�j�D]0\}}tj|�}tjd||f�fdd�|�}q
W|S)z�
    Apply format.format_map(mapping) while preserving unknown keys

    Does not support attribute access, indexing and ![rsa] conversions
    z!(?<!\{)((\{%s\})|(\{%s:[^\}]*\}))cs|jd�j��S)Nr)�group�
format_map)r�)�mappingrrr��sz partial_format.<locals>.<lambda>)r�r��escape�sub)r)r:rQr�r)r:r�partial_format�s


r=c@seZdZdd�Zdd�ZdS)�DatetimeWrappercCs
||_dS)N)r)r%rrrrr#�szDatetimeWrapper.__init__cCs|dkrt}|jj|�S)Nr)rr�
__format__)r%�format_specrrrr?�szDatetimeWrapper.__format__N)r+r,r-r#r?rrrrr>�sr>cCs�x8t�j|�D](\}}}}|s q|s,||krt||��qWy
|j|�Stk
r|}zt|||jjt|���WYdd}~XnXdS)N)	r�parser7r9�	Exceptionr6r&r+rh)r)r��_rQZ
conversionr�rrr�format_line�s
rDcCs�ddlm}m}tjtj�}tj�|dj	t
|jd���|t|j
d��t|�ttj�tj��ttj��tdtdd�dtdd�dtdd	�d
�|�}t||�S)z/Replace placeholders in text with their values.r)�fqdn�hostnamer
Nz%dz%d.%dr�z%d.%d.%drF)�pidrEzreverse-fqdnrFr�r��user�uuid4ZborgversionZ	borgmajorZ	borgminorZ	borgpatch)rArErFrr�rr�r9�getpidr�r�r�r>�
astimezone�uid2user�getuidrh�uuidrI�borg_version�borg_version_tuplerD)�text�	overridesrErFZcurrent_timer�rrr�replace_placeholders�s 
rSrfcCs4x&|jd�D]}|tkrtd|��qW|jdd�S)NrzInvalid sort key: %sr�rf)r��HUMAN_SORT_KEYSrWru)rQ�tokenrrr�
SortBySpecsrVr�r��0iiʚ;�?cCs0d|kotknr|S|dkr(dStSdS)Nr)�MAX_S)rfrrrr.s
rcCs0d|kotknr|S|dkr(dStSdS)Nr)�MAX_NS)rfrrr�safe_ns7s
r[cCst|�}tj|d�S)Nge��A)r[rr)Zitem_timestamp_nsZt_nsrrr�safe_timestamp@sr\)rfcCs|j|dkrdn|�S)zG
    Convert *ts* to a human-friendly format with textual weekday.
    rz%a, %Y-%m-%d %H:%M:%S)rv)rfr@rrr�format_timeEsr]cCs
|jt�S)z,
    Format *ts* according to ISO 8601.
    )rvrw)rfrrr�isoformat_timeLsr^cCsp|j�}|d}t|d�d}t|d�d}d|}|rHd||f}|rXd||f}|jrld|j|f}|S)z0Format timedelta in a human friendly format
    �<ir�z%.2f secondsz
%d minutes %sz%d hours %sz
%d days %s)rr�Zdays)Ztdrfr�r��hZtxtrrr�format_timedeltaTsrac@s6eZdZed�dd�Zdd�Zdd�Zdd	�ZeZd
S)�OutputTimestamp)rfcCs|jtjkrt|�}||_dS)N)rrrr�r�rf)r%rfrrrr#fszOutputTimestamp.__init__cCst|j|d�S)N)r@)r]rf)r%r@rrrr?kszOutputTimestamp.__format__cCs
dj|�S)Nz{})r))r%rrrr/nszOutputTimestamp.__str__cCs
t|j�S)N)r^rf)r%rrr�	isoformatqszOutputTimestamp.isoformatN)	r+r,r-rr#r?r/rc�to_jsonrrrrrbes
rbcCst|dd||d�S)z2Format file size into a human friendly format
    �B� )r��sep�	precision�sign)�sizeof_fmt_decimal)r�rhrirrr�format_file_sizewsrkc@seZdZdd�ZdS)�FileSizecCstt|��j|�S)N)rkr�r?)r%r@rrrr?~szFileSize.__format__N)r+r,r-r?rrrrrl}srlcCsv|st|�S|d	}d}y4||d|d|d|dd�|}|dd
�}Wntk
rdd}YnXtt|�|�S)z,Return int from file size (1234, 55G, 1.7T).ri�r�rF��)�K�M�G�T�PNr�r�)r�rl�float)r�r��powerZfactorrrr�parse_file_size�s

rvrec	Cs�|r|dkrdnd}xb|dd�D]R}tt||��|krht|t�rTdj|||||�Sdj||||||�S|t|�}q"Wdj|||||d	|�S)
Nr�+rrz
{}{}{}{}{}z{}{:3.{}f}{}{}{}z{}{:.{}f}{}{}{}r�r�)�abs�roundrgr�r)rt)	�numr��unitsrurgrhrir�Zunitrrr�
sizeof_fmt�s
r|cCs(t|||||ddddddddd	g	d
d�S)NrZKiZMiZGiZTiZPiZEiZZiZYii)r�rgrhrir{ru)r|)rzr�rgrhrirrr�sizeof_fmt_iec�sr}cCs(t|||||ddddddddd	g	d
d�S)Nrr�rprqrrrs�E�Z�Yi�)r�rgrhrir{ru)r|)rzr�rgrhrirrrrj�srjcCs d|jtt|j��t|j�fS)Nz
%-36s %s [%s])rar]r�rfr�re)rPrrr�format_archive�sr�c@sHeZdZdZGdd�dee�Zddd�Zdd	�Zddd�Z	dd
d�Z
dS)�Bufferz5
    managed buffer (like a resizable bytearray)
    c@seZdZdZdS)zBuffer.MemoryLimitExceededz2Requested buffer size {} is above the limit of {}.N)r+r,r-r(rrrr�MemoryLimitExceeded�sr��NcCsFt|�std��|dks(||ks(td��||_||_|j|dd�dS)z�
        Initialize the buffer: use allocator(size) call to allocate a buffer.
        Optionally, set the upper <limit> for the buffer size.
        z-must give alloc(size) function as first paramNzinitial size must be <= limitT)�init)�callableri�	allocator�limit�resize)r%r�r&r�rrrr#�s
zBuffer.__init__cCs
t|j�S)N)r]�buffer)r%rrrr^�szBuffer.__len__FcCsJt|�}|jdk	r*||jkr*tj||j��|s:t|�|krF|j|�|_dS)a$
        resize the buffer - to avoid frequent reallocation, we usually always grow (if needed).
        giving init=True it is possible to first-time initialize or shrink the buffer.
        if a buffer size beyond the limit is requested, raise Buffer.MemoryLimitExceeded (OSError).
        N)r�r�r�r�r]r�r�)r%r&r�rrrr��s
z
Buffer.resizecCs|dk	r|j||�|jS)z�
        return a buffer of at least the requested size (None: any current size).
        init=True can be given to trigger shrinking of the buffer to the given size.
        N)r�r�)r%r&r�rrrrk�sz
Buffer.get)r�N)F)NF)r+r,r-r(r!r�r�r#r^r�rkrrrrr��s

r�)�maxsizecCs&ytj|�jStk
r |SXdS)N)�pwd�getpwuidZpw_namerl)�uidrrrrrL�srLcCs*y|otj|�jStk
r$|SXdS)N)r��getpwnamZpw_uidrl)rHrrrr�user2uid�sr�cCs&ytj|�jStk
r |SXdS)N)�grpZgetgrgidZgr_namerl)�gidrrrr�	gid2group�sr�cCs*y|otj|�jStk
r$|SXdS)N)r�ZgetgrnamZgr_gidrl)r8rrrr�	group2gid�sr�cCsrg}x^t|�jd�D]L}|r|jd�}t|�dkrV|jdj|d|d|dg��q|j|�qWtdj|��S)z9Replace the user/group field with the stored uid/gid
    �
�:rmrrFr�)r_r�r]r�r�rj)Zaclr1r.Zfieldsrrr�posix_acl_use_stored_uid_gids
$r��utf-8rNcCs|dkrdS|j||�S)z8decode bytes to str, with round-tripping "invalid" bytesN)rn)r��coding�errorsrrrr_sr_cCs|dkrdS|j||�S)z8encode str to bytes, with round-tripping "invalid" bytesN)rx)r�r�r�rrrrjsrjcCst|�jd�S)Nr�)rrn)rrrrr�sr�cCstjd|�}dd�|D�S)Nz *, *cSsg|]}|dkr|�qS)rr)r`rCrrrr�#sz*parse_stringified_list.<locals>.<listcomp>)r�r�)r��lrrr�parse_stringified_list!sr�c@s
eZdZdZdZZZZZZ	dZ
dZdZdZ
dZdZejd	e
ed
e
eej�Zejdeeej�Zejde
ed
eeej�Zejdeej�Zdifdd�Zifdd�Zdd�Zdd�Zdd�Zdd�Zedd��Zdd�Zd d!�Z d"d#�Z!dS)$�Locationz8Object representing a repository / archive location
    Nz%
        (?:(?P<user>[^@:/]+)@)?
    z�
        (?!(:|//|ssh://))                                   # not starting with ":" or // or ssh://
        (?P<path>([^:]|(:(?!:)))+)                          # any chars, but no "::"
        z�
        (?P<path>(([^/]*)/([^:]|(:(?!:)))+))                # start opt. servername, then /, then any chars, but no "::"
        zq
        (?P<path>(/([^:]|(:(?!:)))+))                       # start with /, then any chars, but no "::"
        z�
        (?:
            ::                                              # "::" as separator
            (?P<archive>[^/]+)                              # archive name must not contain "/"
        )?$z�
        (?P<host>(
            (?!\[)[^:/]+(?<!\])     # hostname or v4 addr, not containing : or / (does not match v6 addr: no brackets!)
            |
            \[[0-9a-fA-F:.]+\])     # ipv6 address in brackets
        )
    zR
        (?P<proto>ssh)://                                       # ssh://
        z�                 # user@  (optional), host name or address
        (?::(?P<port>\d+))?                                     # :port (optional)
        zO
        (?P<proto>file)://                                  # file://
        z
        (
            z�             # user@  (optional), host name or address
            :                                                   # : (required!)
        )?                                                      # user@host: part is optional
        a                                # the repo part is fetched from BORG_REPO
        (?:::$)                                             # just "::" is ok (when a pos. arg is required, no archive)
        |                                                   # or
        rcCs|j||�std|j��dS)NzInvalid location format: "%s")rArW�	processed)r%rQrRrrrr#wszLocation.__init__cCs�||_t||�|_}|j|�}|r(dS|jj|�}|s<dStjjd�}|dkrTdSt||�}|j|�}|j	d�|_
|j
s~|n||j|_|j
s�|nd||j
f|_|S)NTFZ	BORG_REPOrPz%s::%s)�rawrSr��_parse�env_rer�r9r�rkr8rP)r%rQrRZvalidr�Zrepo_rawZreporrrrA{s"


zLocation.parsecCsdd�}|jj|�}|rz|jd�|_|jd�|_|jd�|_|jd�rTt|jd��pVd|_||jd��|_|jd�|_	d	S|j
j|�}|r�|jd�|_||jd��|_|jd�|_	d	S|jj|�}|�r|jd�|_|jd�|_||jd��|_|jd�|_	|j�r
d
�pd|_d	SdS)
NcSs&|jd�}tjj|�}|r"d|S|S)Nz/./z/.)�
startswithr9r��normpath)�pZrelativerrr�normpath_special�s
z)Location._parse.<locals>.normpath_special�protorH�host�portr�rPTZsshr�F)�ssh_rer�r8r�rH�_hostr�r�r�rP�file_re�scp_re)r%rQr�r�rrrr��s2zLocation._parsecCs>d|jd|jd|jd|jd|jd|jg}dj|�S)Nzproto=%rzuser=%rzhost=%rzport=%rzpath=%rz
archive=%rz, )r�rHr�r�r�rPr�)r%r�rrrr/�szLocation.__str__cCs`tjdd|j�jd�}|jdkr8tjdd|j�d|}t|�dkrP|dd�}tjjt	�|�S)Nz[^\w]rCr��__rI)
r�r<r�rr�r�r]r9r�r�)r%rarrr�to_key_filename�s
zLocation.to_key_filenamecCsd|S)NzLocation(%s)r)r%rrr�__repr__�szLocation.__repr__cCs |jdk	r|jjd�jd�SdS)N�[�])r��lstrip�rstrip)r%rrrr��s
z
Location.hostcCs�|jdkr|jS|jr.|jjd�r.d|j}n&|jrN|jjd�rNd|j}n|j}dj|jrjdj|j�nd|j|jr�dj|j�nd|�SdS)	Nr��~�/z/./zssh://{}{}{}{}z{}@rz:{})r�r�r�r)rHr�r�)r%r�rrr�canonical_path�s
zLocation.canonical_pathcCs"t|jt|jd��t|�d�d�S)N)r�r�)rR)r�r�r>rK)r%r�rrr�with_timestamp�szLocation.with_timestampcCs8t|j�}d|_|jjd�d|_|jjd�d|_|S)Nz::r)r�r�rPr�r�)r%�locrrr�omit_archive�s

zLocation.omit_archive)"r+r,r-r(r�rHr�r�r�rPZoptional_user_reZscp_path_reZfile_path_reZabs_path_reZoptional_archive_reZhost_rer�r��VERBOSEr�r�r�r�r#rAr�r/r�r�r�r�r�r�r�rrrrr�&s4		 r�cs��fdd�}|S)Ncs�yt|�}Wn2tk
r>}ztjt|��d�WYdd}~XnX�dkr`|jr`tjd|��n�dkr||jr|tjd|���dk	r�|j�kr��dkr�tjd|��ntjd|��|S)NTz"%s": No archive specifiedFz!"%s": No archive can be specifiedr�z"%s": Repository must be localz"%s": Repository must be remote)r�rWr�r�rhrPr�)rQr��err)rPr�rr�	validator�s"z%location_validator.<locals>.validatorr)rPr�r�r)rPr�r�location_validator�sr�cCsdd�}|S)NcSs0t|�}d|ksd|ks|r,tjd|��|S)Nr�z::zInvalid archive name: "%s")rSr�r�)rQrrrr��sz(archivename_validator.<locals>.validatorr)r�rrr�archivename_validator�sr�cCs6x0|D](}t|j|�t�r||j||�||<qW|S)N)rgrkrtrn)r�r��encodingr�rQrrr�decode_dicts
r�cs0dd�����fdd�����fdd���|�S)NcSs8|jd�s,y|j�}|Stk
r*YnXdt|�S)N��)r�rn�UnicodeDecodeErrorr�)r�rrr�decode_bytess
z'prepare_dump_dict.<locals>.decode_bytescsdg}xZ|D]R}t|t�r"�|�}n0t|t�s6t|t�r@�|�}nt|t�rR�|�}|j|�q
W|S)N)rgrSrsr�rtr�)r��resr�)rnr��decode_tuplerrr�s




z'prepare_dump_dict.<locals>.decode_tuplecsztj�}xl|j�D]`\}}t|t�r.�|�}n*t|ttf�rF�|�}nt|t�rX�|�}t|t�rj|j�}|||<qW|S)N)	�collections�OrderedDictr�rgrSrsr�rtrn)r�r�rQr�)rnr�r�rrrn's




z!prepare_dump_dict.<locals>.decoder)r�r)rnr�r�r�prepare_dump_dict
s
r�rucCs|jd|�jd�S)z6Replace surrogates generated by fsdecode with '?'
    zutf-8)rxrn)r�r�rrr�remove_surrogates8sr�z
^((\.\.)?/+)+cCstjd|�pdS)z3Make path safe by making it relative and local
    rr
)�_safe_rer<)r�rrr�make_path_safeAsr�cCs�ddlm}|�}tj�}|r(tjd�tj�tj�}|rFtjd�tjd�tjd�tjd�tjd�tjtj	tj
�}tj|d�tj|d�tj|d�|�}||fS)zsDetach process from controlling terminal and run in background

    Returns: old and new get_process_id tuples
    r)�get_process_idrr�r�)rAr�r9�fork�_exit�setsid�chdirr�r��devnull�O_RDWR�dup2)r�Zold_idrGrZnew_idrrr�	daemonizeGs&





r�cs eZdZdZ�fdd�Z�ZS)rVz,A dict subclass with stable items() orderingcstt�j��S)N)r�r"r�)r%)r&rrr�cszStableDict.items)r+r,r-r(r�r0rr)r&rrVasrVcCst|t�rtj|ddd�S|S)zConvert bytearray to int
    �littleT)�signed)rgrtr��
from_bytes)r%rrr�
bigint_to_intgs
r�cCs,|j�dkr(|j|j�ddddd�S|S)z[Convert integers larger than 64 bits to bytearray

    Smaller integers are left alone
    rX�	�r�T)r�)�
bit_length�to_bytes)r�rrr�
int_to_bigintosr�cCstjtjkS)N)rXZPacker�msgpack_fallbackrrrr�is_slow_msgpackysr�cCs.tjdd�}d|ko dkno,|d
kS)NrFrrmr
rnr�)rrmr
)rrnr
�rrnr�rrnr��rrnrF�rrnrn)r�r�r�r�)rXr�)r�rrr�is_supported_msgpack}sr��No�NO�no�Nr��0�Yes�YES�yesr�r��1�Default�DEFAULTr�Dr�z{} (from {})c
sVd��fdd�	}�p|��dkr&tj�|
dkr6td��|rH||ddd��xd}|r�tjj|�}|dk	r�|r�||j||�d	|d
�|dkr�|s�|
Sy
|�}Wn(tk
r�|
r�|dn|d}YnX||	kr�|r�||d�|
S||k�r�|�r�||d
�dS||k�r|�r||d�dS|�r,||d�|�s6|
S|�rJ||ddd�d}qLWdS)abOutput <msg> (usually a question) and let user input an answer.
    Qualifies the answer according to falsish, truish and defaultish as True, False or <default>.
    If it didn't qualify and retry is False (no retries wanted), return the default [which
    defaults to False]. If retry is True let user retry answering until answer is qualified.

    If env_var_override is given and this var is present in the environment, do not ask
    the user, but just use the env var contents as answer as if it was typed in.
    Otherwise read input from stdin and proceed as normal.
    If EOF is received instead an input or an invalid input without retry possibility,
    return default.

    :param msg: introducing message to output on ofile, no 
 is added [None]
    :param retry_msg: retry message to output on ofile, no 
 is added [None]
    :param false_msg: message to output before returning False [None]
    :param true_msg: message to output before returning True [None]
    :param default_msg: message to output before returning a <default> [None]
    :param invalid_msg: message to output after a invalid answer was given [None]
    :param env_msg: message to output when using input from env_var_override ['{} (from {})'],
           needs to have 2 placeholders for answer and env var name
    :param falsish: sequence of answers qualifying as False
    :param truish: sequence of answers qualifying as True
    :param defaultish: sequence of answers qualifying as <default>
    :param default: default return value (defaultish answer was given or no-answer condition) [False]
    :param retry: if True and input is incorrect, retry. Otherwise return default. [True]
    :param env_var_override: environment variable name [None]
    :param ofile: output stream [sys.stderr]
    :param input: input function [input from builtins]
    :return: boolean answer value, True or False
    Fcsjttjd�dd�}|rD|jtd|�|d��ttj|�tj	d�n"|rZt|�ddd	�nt|�d�dS)
NrD�jsonFzquestion_%s)r'�msgid�message)r�rT)r��end�flush)
�getattr�logging�	getLoggerrTrS�printr��dumps�sys�stderr)�msgZmsg_type�	is_prompt�kwargsZjson_output)r��ofilerr�output�s
zyes.<locals>.outputNTz,invalid default value, must be True or False�prompt)r�Z
env_answer)Zenv_varrZaccepted_defaultZ
accepted_trueZaccepted_falseZinvalid_answerZprompt_retry)F)TF)r�r�rWr9r�rkr)�EOFError)r�Z	false_msgZtrue_msgZdefault_msgZ	retry_msgZinvalid_msg�env_msgZfalsishZtruishZ
defaultishrZretry�env_var_overrider�inputrr�rZanswerr)r�rrr��sP"






cCstddddd�S)NZBORG_HOSTNAME_IS_UNIQUEFT)rrrr)r�rrrr�hostname_is_unique�srcCsvddlm}|d�}||�}|dkr4dd||S|||krfdt||d|�t||d�fS|d||S)z�
    shorten a long string by adding ellipsis between it and return it, example:
    this_is_a_very_long_string -------> this_is..._string
    r)�swidthz...r�rfz%s...%sr�)rAr	�swidth_slice)r��spacer	Zellipsis_widthZ	msg_widthrrr�ellipsis_truncate�src@sPeZdZdZdZdZdZedd��Zddd�Z	d	d
�Z
dd�dd
�Zdd�ZdS)�ProgressIndicatorBasezborg.output.progressNFrcCs|jd7_|jS)zYUnique number, can be used by receiving applications to distinguish different operations.r)�operation_id_counter)r�rrr�operation_idsz"ProgressIndicatorBase.operation_idcCs�d|_tj|j�|_|j�|_||_|jjs�tj	t
jd�|_|jjtj
�tjd�}y |j}|jrfdnd}|j|_Wntk
r�d}YnX|jj|�||j_|jj|j�|jjtjkr�|jjtj�d|j_|jj�tj
k|_dS)N)�streamrDr��
F)�handlerr�r��LOGGERr�rrer�ZhandlersZ
StreamHandlerr�r�ZsetLevel�INFO�	formatterr��AttributeErrorZsetFormatter�
terminatorZ
addHandler�levelZNOTSETZWARNZ	propagateZgetEffectiveLevel�emit)r%r�r�rrrrrr#
s*


	zProgressIndicatorBase.__init__cCs&|jdk	r"|jj|j�|jj�dS)N)rr�Z
removeHandlerr�)r%rrr�__del__1s
zProgressIndicatorBase.__del__)�finishedcKsP|js
t�|jsdS|jt|j|j|j|tj�d��t	tj
|�tjdd�dS)N)r�r�r'rrT)r�r�)
r�rirrTrSrer��	JSON_TYPErr�r�r�r�)r%rrrrr�output_json6s
z!ProgressIndicatorBase.output_jsoncCs"|jr|jdd�n
|jd�dS)NT)rr)r�rr)r%rrr�finishCszProgressIndicatorBase.finish)N)
r+r,r-rrr�rr�rr#rrrrrrrr
�s
'
r
cCs$tdd�d}|dkr |j|�S|S)Nr)rrr�r�)r�r�r�)r�ljust)r��terminal_spacerrr�justify_to_terminal_sizeJs
r!c@seZdZdZdd�ZdS)�ProgressIndicatorMessageZprogress_messagecCs(|jr|j|d�n|jjt|��dS)N)r�)r�rr�ryr!)r%r�rrrrUszProgressIndicatorMessage.outputN)r+r,r-rrrrrrr"Rsr"cs@eZdZdZd�fdd�	Zdd	d
�Zddd�Zddd�Z�ZS)�ProgressIndicatorPercentZprogress_percentrrn�%3.0f%%Ncs0d|_||_||_||_||_t�j|d�dS)a
        Percentage-based progress indicator

        :param total: total amount of items
        :param step: step size in percent
        :param start: at which percent value to start
        :param msg: output message, must contain one %f placeholder for the percentage
        r)r�N)�counter�total�
trigger_at�stepr�r"r#)r%r&r(�startr�r�)r&rrr#_s	z!ProgressIndicatorPercent.__init__rcCsN|dk	r||_|jd|j}|j|7_||jkrJ|j|j7_|SdS)NrI)r%r&r'r()r%�current�increase�pctrrr�progressps
z!ProgressIndicatorPercent.progresscCs�|j||�}|dk	r�|dk	r�|jsttd
d�d}|dkrt|t|jt|g|dd�dg��}t|d
|�|d<|j|jt|g|�d|d�S|j|j|�SdS)z�
        Show and output the progress message

        :param current: set the current percentage [None]
        :param increase: increase the current percentage [None]
        :param info: array of strings to be formatted with msg [None]
        Nr)rrrF)�justifyryr�r�)r�r�r�r�r�r�)r-r�rr]r�rsrr)r%r*r+ryr,r rrrr�showys* zProgressIndicatorPercent.showTcCs:|jr|j||j|j|d�n|r*t|�}|jj|�dS)N)r�r*r&ry)r�rr%r&r!r�ry)r%r�r.ryrrrr�s
zProgressIndicatorPercent.output)rrnrr$N)Nr)NrN)TN)	r+r,r-rr#r-r/rr0rr)r&rr#\s

	
r#c@s6eZdZd
dd�Zdd�Zdd�Zd	d
�Zdd�ZdS)�ProgressIndicatorEndlessrRNcCs*d|_d|_||_|dkr tj}||_dS)z�
        Progress indicator (long row of dots)

        :param step: every Nth call, call the func
        :param file: output file, default: sys.stderr
        rN)r%�	triggeredr(r�r�r�)r%r(r�rrrr#�sz!ProgressIndicatorEndless.__init__cCs4|jd7_|j|jdk}|r0|jd7_|S)Nrr)r%r(r1)r%�triggerrrrr-�s
z!ProgressIndicatorEndless.progresscCs|j�}|r|j|j�SdS)N)r-rr1)r%r2rrrr/�szProgressIndicatorEndless.showcCstdd|jdd�dS)Nr
rT)r�r�r�)r�r�)r%r1rrrr�szProgressIndicatorEndless.outputcCst|jd�dS)N)r�)r�r�)r%rrrr�szProgressIndicatorEndless.finish)rRN)r+r,r-r#r-r/rrrrrrr0�s

r0cCsRtjjdd�j�}|dkrdStj�}tj�}ytj�}Wntk
rRd}YnXt	jj
d�r�ytj�}Wq�d}Yq�Xnd}ydjdd	�t
jD��}Wnd
}YnXg}|dk	r�|jddj|�f�|dk	r�|jd
|�|jdt|||f�|jdtj�tj�f�|jdt	j�|jdtjjd��|jd�dj|�S)NZBORG_SHOW_SYSINFOr�r�r�linux�
Unknown Linuxr
css|]}t|�VqdS)N)rh)r`r�rrrrb�szsysinfo.<locals>.<genexpr>�unknownzPlatform: %srfzLinux: %s %s %sz#Borg: %s  Python: %s %s msgpack: %szPID: %d  CWD: %szsys.argv: %rzSSH_ORIGINAL_COMMAND: %rZSSH_ORIGINAL_COMMANDr�)r4rr)r9r�rkrrA�python_implementation�python_version�unamerr�r��linux_distributionr�rXr�r�rOrJ�getcwd�argv)Zshow_sysinfor6r7r8r9Zmsgpack_versionryrrr�sysinfo�s>


r<)rr�cGs>g}x|D]}|j|j��q
Wx|D]}|j||�q&WdS)z�
    log multiple lines of text, each line by a separate logging call for cosmetic reasons

    each positional argument may be a single or multiple lines (separated by newlines) of text.
    N)�extend�
splitlines�log)rr�Zmsgs�linesr��linerrr�	log_multi�s


rBc@s@eZdZdddddejejd�Zdd�Zd	d
�Zedd��Z	d
S)�
BaseFormatterr�rf�	r�)ZLFZSPACEZTABZCRZNUL�NEWLINE�NLcCst�dS)N)�NotImplementedError)r%rCrrr�
get_item_data�szBaseFormatter.get_item_datacCs|jj|j|��S)N)r)r9rI)r%rCrrr�format_item�szBaseFormatter.format_itemcCsdS)Nz�- NEWLINE: OS dependent line separator
- NL: alias of NEWLINE
- NUL: NUL character for creating print0 / xargs -0 like output, see barchive and bpath keys below
- SPACE
- TAB
- CR
- LFrrrrr�	keys_helpszBaseFormatter.keys_helpN)
r+r,r-r9�linesep�
FIXED_KEYSrIrJ�staticmethodrKrrrrrC�s
rCc@s�eZdZddddddddd	d
ddd
d�
Zd8Zedd��Zedd��Zd d!�d"d#�Zd$d%�Z	d&d'�Z
ed(d)��Zd*d+�Z
d,d-�Zd.d/�Zd0d1�Zd2d3�Zd4S)9�ArchiveFormatterzUarchive name interpreted as text (might be missing non-text characters, see barchive)zalias of "archive"z;verbatim archive name, can contain any character except NULzXarchive comment interpreted as text (might be missing non-text characters, see bcomment)z>verbatim archive comment, can contain any character except NULz'time (start) of creation of the archivezalias of "start"z%time (end) of creation of the archivez1command line which was used to create the archivezinternal ID of the archivez2hostname of host on which this archive was createdz)username of user who created this archivez(TAM authentication state of this archive)
rPra�barchive�comment�bcommentr)rr��command_linererF�username�tamrPrarPrQrRrerUr)rr�rSrFrTc	CsXtdddtdddtjd��}|dddd�}g}|j|jj��|j|j|�j��|S)N�archivename�r�i�r)rrr)rZrrr�r=�	call_keysr�rI)r�Zfake_archive_inforr�rrr�available_keys"szArchiveFormatter.available_keyscCs�g}|j�}x|jD]}|j|�qWx^|jD]T}xD|D]<}|j|�d|}||jkrj|d|j|7}|j|�q8W|jd�q.W|s�tt|���dj|�S)Nz- z: rr�)	rYrM�remove�
KEY_GROUPS�KEY_DESCRIPTIONSr�rirhr�)r��helpr�rQr8rQrrrrK+s


zArchiveFormatter.keys_helpF)r�cCs�||_||_||_d|_d|_d|_||_i}|j|j�t	||�|_
dd�t�j|�D�|_
t|jddd�t|jddd�t|jddd�t|jddd�|j|j|jd	�|_t|j�|j
@|_|jr�i|_|j|_n||_dS)
NcSsh|]}|d�qS)rr)r`r�rrrr0Hsz,ArchiveFormatter.__init__.<locals>.<setcomp>rFT)�rsrTrQF)rFrTrQrRr�rSrU)r�rLrQrare�_archiver�rTrMr=r)rrA�format_keysr
�get_meta�
get_ts_end�get_cmdline�get_tamrXr��used_call_keys�	item_data�format_item_jsonrJ)r%r)r�rLrQr��static_keysrrrr#=s.
zArchiveFormatter.__init__cCstj|j|�td�dS)N)r�r�)r�r�rI�BorgJsonEncoder)r%rCrrrrgYsz!ArchiveFormatter.format_item_jsoncCs�|j|_|j|_i}|j|j�|jt|j�t|j�|jt|j�|j|j�|j|j�d��x|jD]}|j	|�||<qdW|S)N)rarPrPrerr))
rarerTrfr�r�r]rfrerX)r%Zarchive_inforfrQrrrrI\s
zArchiveFormatter.get_item_datacCsB|jdks|jj|jkr<ddlm}||j|j|j|j�|_|jS)z!lazy load / update loaded archiveNr)�Archive)r_rerPrjr�rQrLra)r%rjrrrrPmszArchiveFormatter.archivecCs |jjj|d�}|rt|�S|S)Nr)rP�metadatarkr�)r%rQr^r�rrrrauszArchiveFormatter.get_metacCs:tt|jjjdg��}|jr$t|�Sdjttj	|��SdS)N�cmdlinerf)
�mapr�rPrkrkr�r�r��shlexZquote)r%rlrrrrcyszArchiveFormatter.get_cmdlinecCs|j|jj�S)N)r]rPZts_end)r%rrrrb�szArchiveFormatter.get_ts_endcCs|jjrdSdS)NZverifiedZnone)rPr�)r%rrrrd�szArchiveFormatter.get_tamcCst|�S)N)rb)r%rfrrrr]�szArchiveFormatter.format_timeN�rPrarPrQrRrerU�r)rr�rS�rFrT)rorprq)r+r,r-r\r[r�rYrKr#rgrIr�rPrarcrbrdr]rrrrrOs6	rOc@s�eZdZejjddh�Zddddddd	d
ddd
�
ZdHdIdJee	e��dKdLfZ
dMZed)d*��Z
ed+d,��Zed-d.��Zd/d0�d1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Zd=d>�Zd?d@�ZdAdB�ZdCdD�ZdEdF�ZdGS)N�
ItemFormatterZ	shake_128Z	shake_256z9verbatim POSIX path, can contain any character except NULzJpath interpreted as text (might be missing non-text characters, see bpath)z/link target for links (identical to linktarget)zKprepends {source} with " -> " for soft links and " link to " for hard linkszcompressed sizezdeduplicated sizezdeduplicated compressed sizeznumber of chunks in this filez$number of unique chunks in this filezPeither "healthy" (file ok) or "broken" (if file has all-zero replacement chunks))
�bpathr��source�extra�csize�dsize�dcsize�
num_chunks�
unique_chunks�healthr'r�r�r�rHr8r�rsrt�
linktarget�flagsr&rvrwrxryrzr%r$�atime�isomtime�isoctime�isoatime�	archiveidrVrur{c	CsfGdd�d�}ddlm}|dddddddd�}||d�}g}|j|jj��|j|j|�j��|S)Nc@seZdZdZZdS)z1ItemFormatter.available_keys.<locals>.FakeArchiverN)r+r,r-�fprrarrrr�FakeArchive�sr�r)�Itemrr)r�r�rHr8r%r�r�)rCr�r=rXr�rI)r�r�r�Z	fake_itemrr�rrrrY�s
zItemFormatter.available_keyscCs�g}|j�}x|jD]}|j|�qWx^|jD]T}xD|D]<}|j|�d|}||jkrj|d|j|7}|j|�q8W|jd�q.W|s�tt|���dj|�S)Nz- z: rr�)	rYrMrZr[r\r�rirhr�)r�r]r�rQr8rQrrrrK�s


zItemFormatter.keys_helpcs,dd�t�j|�D�}t�fdd�|D��S)NcSsh|]}|d�qS)rr)r`r�rrrr0�sz3ItemFormatter.format_needs_cache.<locals>.<setcomp>c3s|]}|�jkVqdS)N)�KEYS_REQUIRING_CACHE)r`rQ)r�rrrb�sz3ItemFormatter.format_needs_cache.<locals>.<genexpr>)rrA�any)r�r)r`r)r�r�format_needs_cache�sz ItemFormatter.format_needs_cacheF)�
json_linescCs||_||_|j|jd�}|j|j�|jr<i|_|j|_n||_t	||�|_
dd�t�j|�D�|_
|j|jt|jdd��t|jdd��|jt|jdd��t|jd�t|jd	�t|jd
�t|jd�t|jd	�t|jd
�d�|_x"|jD]}|j|t|j|��q�Wt|j�|j
@|_dS)N)rVr�cSsh|]}|d�qS)rr)r`r�rrrr0�sz)ItemFormatter.__init__.<locals>.<setcomp>cSs|jS)N)r&)�chunkrrrr��sz(ItemFormatter.__init__.<locals>.<lambda>cSs|jS)N)rv)r�rrrr��scSsdS)Nrr)r�rrrr��sr%r$r~)r&rvrwrxryrzrr�r�r%r$r~)rPr�rar�rTrMrfrgrJr=r)rrAr`�calculate_size�calculate_csizer
�sum_unique_chunks_metadata�calculate_num_chunks�format_iso_timer]rX�hash_algorithms�add_key�	hash_itemr�re)r%rPr)r�rh�
hash_functionrrrr#�s4






zItemFormatter.__init__cCstj|j|�td�dS)N)r�r�)r�r�rIri)r%rCrrrrg�szItemFormatter.format_item_jsoncCs ||j|<t|j�|j@|_dS)N)rXr�r`re)r%rQZcallable_with_itemrrrr��s
zItemFormatter.add_keycCs>i}|j|j�tj|j�}|d}|jdd�}d}|rjt|�}|dkrRd|}nd|dd�}d|}||d	<||d
<|jp�|j|d<|j	p�|j
|d<|j|d
<|j
|d<t|j�|d<|jr�d|k|d<n&|j|d<||d<d|kr�dnd|d<||d<||d<|jdd�|d<x"|j
D]}|j||�||<�qW|S)Nrrtrr�z -> %sr`rz link to %sr'r�rHr8r�r�r�Zchunks_healthyZhealthyrsruZbrokenr{r|Zbsdflagsr})rTrfr:�filemoder�rkr�rHr�r8r�r�r�rerX)r%rCrfr�Z	item_typertrurQrrrrI�s<



zItemFormatter.get_item_datacsB|jjj�|jdg�}tdd�|D���t���fdd�|D��S)au
        sum unique chunks metadata, a unique chunk is a chunk which is referenced globally as often as it is in the
        item

        item: The item to sum its unique chunks' metadata
        metadata_func: A function that takes a parameter of type ChunkIndexEntry and returns a number, used to return
                       the metadata needed from the chunk
        �chunkscss|]}|jVqdS)N)re)r`r!rrrrb!sz;ItemFormatter.sum_unique_chunks_metadata.<locals>.<genexpr>c3s,|]$}�|jj�|jkr�|�VqdS)N)reZrefcount)r`r!)�chunk_index�chunks_counter�
metadata_funcrrrb"s)rP�cacher�rkr�sum)r%r�rCr�r)r�r�r�rr�s	
z(ItemFormatter.sum_unique_chunks_metadatacCst|jdg��S)Nr�)r]rk)r%rCrrrr�$sz"ItemFormatter.calculate_num_chunkscCs|jdd�S)NF)�
compressed)�get_size)r%rCrrrr�'szItemFormatter.calculate_sizecCs|jdd�S)NT)r�)r�)r%rCrrrr�+szItemFormatter.calculate_csizecCsZ||jkst�d|krdStj|�}x,|jjjdd�|jD��D]}|j|�q@W|j	�S)Nr�rcSsg|]
}|j�qSr)re)r`r!rrrr�4sz+ItemFormatter.hash_item.<locals>.<listcomp>)
r�ri�hashlib�newrP�pipeline�
fetch_manyr�rTZ	hexdigest)r%r�rC�hashr�rrrr�/s
 zItemFormatter.hash_itemcCstt|j|�p|j��S)N)rbr\rkr%)r%rQrCrrrr]8szItemFormatter.format_timecCs|j||�j�S)N)r]rc)r%rQrCrrrr�;szItemFormatter.format_iso_timeN)r'r�r�r�rHr8r�rsrtr|r})r&rvrwrxryrz)r%r$r~rr�r�)r�rVru)r{)rwrxrz)r+r,r-r�Zalgorithms_guaranteed�
differencer�r\rsr�r[r�r�rYrKr�r#rgr�rIr�r�r�r�r�r]r�rrrrrr�s@

!#	rrc@s2eZdZdZddd�Zdd�Zdd�Zd	d
�ZdS)�ChunkIteratorFileWrapperz%File-like wrapper for chunk iteratorsNcCs"||_d|_d|_d|_||_dS)at
        *chunk_iterator* should be an iterator yielding bytes. These will be buffered
        internally as necessary to satisfy .read() calls.

        *read_callback* will be called with one argument, some byte string that has
        just been read and will be subsequently returned to a caller of .read().
        It can be used to update a progress display.
        r�FN)�chunk_iterator�chunk_offsetr��	exhausted�
read_callback)r%r�r�rrrr#Bs
	z!ChunkIteratorFileWrapper.__init__cCs\t|j�|j}|sXyt|j�}t|�|_Wntk
rFd|_dSXd|_t|j�}|S)NTr)r]r�r��nextr��
memoryview�
StopIterationr�)r%�	remainingr�rrr�_refillQs

z ChunkIteratorFileWrapper._refillcCs>|sdS|j�}t||�}|j|7_|j|j||j�S)Nr�)r��minr�r�)r%�nbytesr�Z	will_readrrr�_read^s
zChunkIteratorFileWrapper._readcCsPg}x@|rD|jrD|j|�}|t|�8}|j|�|jr|j|�qWdj|�S)Nr�)r�r�r]r�r�r�)r%r��partsZ	read_datarrrr�fs

zChunkIteratorFileWrapper.read)N)r+r,r-r(r#r�r�r�rrrrr�?s


r�cCs |jjdd�|jD��}t|�S)z8Return file-like object for archived item (with chunks).cSsg|]
}|j�qSr)re)r`r!rrrr�sszopen_item.<locals>.<listcomp>)r�r�r�r�)rPrCr�rrr�	open_itemqsr�cCsXtj|�rdStj|�rdStj|�r*dStj|�r8dStj|�rFdStj|�rTdSdS)N�Ar��br!r�r��?)r:�S_ISREG�S_ISDIR�S_ISBLK�S_ISCHR�S_ISLNK�S_ISFIFO)r�rrr�file_statusws





r�cCs(tj|�p&tj|�p&tj|�p&tj|�S)z7return True if we support hardlinked items of this type)r:r�r�r�r�)r�rrr�hardlinkable�sr�cst|��t��fdd�g�S)z�
    Chunk an iterator <it> into pieces of <size>.

    >>> list(chunker('ABCDEFG', 3))
    [['A', 'B', 'C'], ['D', 'E', 'F'], ['G']]
    cstt����S)N)r�rr)�iterabler&rrr��szchunkit.<locals>.<lambda>)rc)�itr&r)r�r&r�chunkit�sr�cCs,|dkrt|dd�ntt|||�d�dS)zCAdvance the iterator n-steps ahead. If n is none, consume entirely.Nr)�maxlen)rr�r)�iteratorr�rrr�consume�sr�cCsHyd|j�fStk
rB}ztjd|j|�d|jfSd}~XnXdS)Nrz&scandir_inorder: Unable to stat %s: %sr)r'r�r�r�r�ra)Zdirentr�rrr�scandir_keyfunc�s
r�r
cCstt|�td�S)N)rQ)r�rr�)r�rrr�scandir_inorder�sr�ccsXxR|D]J}|dk	r|j|�}|dk	r.|j|�}|r:|r:q|rJ|jd�rJq|VqWdS)a�
    clean lines (usually read from a config file):

    1. strip whitespace (left and right), 2. remove empty lines, 3. remove comments.

    note: only "pure comment lines" are supported, no support for "trailing comments".

    :param lines: input line iterator (e.g. list or open text file) that gives unclean input lines
    :param lstrip: lstrip call arguments or False, if lstripping is not desired
    :param rstrip: rstrip call arguments or False, if rstripping is not desired
    :param remove_comments: remove comment lines (lines starting with "#")
    :param remove_empty: remove empty lines
    :return: yields processed lines
    F�#N)r�r�r�)r@r�r�Zremove_emptyZremove_commentsrArrr�clean_lines�s



r�cs(eZdZ�fdd�Z�fdd�Z�ZS)�ErrorIgnoringTextIOWrappercsP|jsLyt�j|�Stk
rJyt�j�Wntk
rDYnXYnXdS)Nr)�closedr"r��BrokenPipeErrorr�r�)r%r�)r&rrr��szErrorIgnoringTextIOWrapper.readcsT|jsLyt�j|�Stk
rJyt�j�Wntk
rDYnXYnXt|�S)N)r�r"r�r�r�r�r])r%r�)r&rrr��sz ErrorIgnoringTextIOWrapper.write)r+r,r-r�r�r0rr)r&rr��sr�c@seZdZdZdS)�SignalExceptionz*base class for all signal-based exceptionsN)r+r,r-r(rrrrr��sr�c@seZdZdZdS)�SigHupzraised on SIGHUP signalN)r+r,r-r(rrrrr��sr�c@seZdZdZdS)�SigTermzraised on SIGTERM signalN)r+r,r-r(rrrrr��sr�ccsPt|t�rtt|d�}|dk	r*tj||�}z
dVWd|dk	rJtj||�XdS)a�
    when entering context, set up signal handler <handler> for signal <sig>.
    when leaving context, restore original signal handler.

    <sig> can bei either a str when giving a signal.SIGXXX attribute name (it
    won't crash if the attribute name does not exist as some names are platform
    specific) or a int, when giving a signal number.

    <handler> is any handler value as accepted by the signal.signal(sig, handler).
    N)rgrhr��signal)ZsigrZorig_handlerrrr�signal_handler�s

r�cs�fdd�}|S)Ncstj|tj���dS)N)r��SIG_IGN)Zsig_no�frame)�exc_clsrrr
	sz'raising_signal_handler.<locals>.handlerr)r�rr)r�r�raising_signal_handler		sr�cCstddlm}|dk}t|�}|r(t|�}d}g}x,|D]$}|||�7}||krPP|j|�q6W|rj|j�dj|�S)a
    Return a slice of *max_width* cells from *string*.

    Negative *max_width* means from the end of string.

    *max_width* is in units of character cells (or "columns").
    Latin characters are usually one cell wide, many CJK characters are two cells wide.
    r)r	rr)rAr	rxr�r�r�r�)�stringZ	max_widthr	r�Zcurrent_swidthr��	characterrrrr
	s	
r
cseZdZ�fdd�Z�ZS)rics�ddlm}ddlm}ddlm}ddlm}m}t	||�sHt	||�r^t
|j�|jj
�d�St	||�rp|j�St	||�r�|j|j�d�St	||�r�d|j�iStt|d	d��r�|j�St�j|�S)
Nr)r�)�RemoteRepository)rj)�
LocalCache�
AdHocCache)rer�)r��statsr�rd)r�r�Zremoter�rPrjr�r�r�rgr�reZ	_locationr�ryr�r�r�r�rdr"r)r%�or�r�rjr�r�)r&rrr/	s"


zBorgJsonEncoder.default)r+r,r-rr0rr)r&rri.	sri)r�rucCsv|j}|pi}|jt�j|j�d|jid��t|jjt	j
d��|dd<|jjd�rf|j
�|dd<|rr||d	<|S)
Nr�)r��
encryption)rrr�Z
last_modifiedzkey filer�Zkeyfiler�)rQrTrirr�ZARG_NAMErbr�rurr��NAMEr�Zfind_key)rLr�rurQr�rrr�basic_json_dataI	sr�cCstj|ddtd�S)zDump using BorgJSONEncoder.Trm)Z	sort_keys�indentr�)r�r�ri)�objrrr�	json_dumpZ	sr�cCstt|��dS)N)r�r�)r�rrr�
json_print_	sr�c
Csht|d��J}tj|j��}|jdko&|sP|jtj|j��|j�tj	|j��WdQRXtj
|�dS)a�Attempt to securely erase a file by writing random data over it before deleting it.

    If avoid_collateral_damage is True, we only secure erase if the total link count is 1,
    otherwise we just do a normal "delete" (unlink) without first overwriting it with random.
    This avoids other hardlinks pointing to same inode as <path> getting damaged, but might be less secure.
    A typical scenario where this is useful are quick "hardlink copies" of bigger directories.

    If avoid_collateral_damage is False, we always secure erase.
    If there are hardlinks pointing to the same inode as <path>, they will contain random garbage afterwards.
    zr+brN)r�r9r:�fileno�st_nlinkr��urandom�st_sizer��fsyncr�)r�Zavoid_collateral_damager�strrr�secure_erasec	sr�cCs�ytj|�Wn�tk
r�}zp|jtjkr.�tj|�}|jdkrD�y"t|d��}|j�WdQRXWntk
r~|�YnXtj|�WYdd}~XnXdS)a�
    Safely unlink (delete) *path*.

    If we run out of space while deleting the file, we try truncating it first.
    BUT we truncate only if path is the only hardlink referring to this content.

    Use this when deleting potentially large files when recovering
    from a VFS error such as ENOSPC. It can help a full file system
    recover. Refer to the "File system interaction" section
    in repository.py for further explanations.
    rzr+bN)	r9r�r��errnoZENOSPCr:r�r��truncate)r�Z
unlink_errr�rrrr�safe_unlinkw	s


r�)�cmd_linecKs�|jd�std��ytj|�}|s,td��Wn.tk
r\}ztjd||�dSd}~XnXtjd||�ytj	|f|�St
k
r�tjd||d�dStk
r�tjd	||d�dSXdS)
as
    Handle typical errors raised by subprocess.Popen. Return None if an error occurred,
    otherwise return the Popen object.

    *cmd_line* is split using shlex (e.g. 'gzip -9' => ['gzip', '-9']).

    Log messages will be prefixed with *log_prefix*; if set, it should end with a space
    (e.g. log_prefix='--some-option: ').

    Does not change the exit code.
    �shellz Sorry pal, shell mode is a no-noz&an empty command line is not permittedz%s%sNz%scommand line: %sz%sexecutable not found: %srz%spermission denied: %s)rkrirnr�rWr��errorr��
subprocess�Popen�FileNotFoundError�PermissionError)r�Z
log_prefixrZcommandZverrr�popen_with_error_handling�	s"
r�cCs�t|dk	r|ntj�}|rpd}|j|d�}|dk	r>|||<n2|j|�}|dk	rpttdd�rpttd�rp|j|�|jdd�t|d<|S)	a
    Prepare the environment for a subprocess we are going to create.

    :param system: True for preparing to invoke system-installed binaries,
                   False for stuff inside the pyinstaller environment (like borg, python).
    :param env: optionally give a environment dict here. if not given, default to os.environ.
    :return: a modified copy of the environment
    NZLD_LIBRARY_PATHZ_ORIG�frozenFZ_MEIPASSZBORG_PASSPHRASEZBORG_VERSION)	rSr9r�rkr�r��hasattr�poprO)�system�envZlp_keyZlp_origZlprrr�prepare_subprocess_env�	s	



r�cCsHd|kst�|dkr:d|kr"tjntj}d|kr6|jS|St||�SdS)Nrw�-r#r�)rir��stdin�stdoutr�r�)r�r�rrrr�	dash_open�	s
r�cCs&t|d�o$|j�o$tjdkp$dtjkS)N�isattyZwin32ZANSICON)r�r�r�rAr9r�)rrrr�is_terminal�	sr�cCsFtdd�}ytjdd|g|d�Stk
r@tjd|g|d�SXdS)NT)r�Z
fusermountz-u)r��umount)r�r�Zcallr�)Z
mountpointr�rrrr�	s

r)�_sanitize_params�_get_candidate_names�TMP_MAX�_text_openflags�_bin_openflags�cCs�tjj|�}t�}|tkr&ttj|�}x�tt�D]�}t	|�}tjj
||||�}	ytj|	||�}
WnRtk
rzw0Yn>t
k
r�tjdkr�tjj|�r�tj|tj�r�w0n�YnX|
|	fSWttjd��dS)z>Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.�ntz#No usable temporary file name foundN)�_osr��abspathrrtrm�fsencode�rangerr�r�r��FileExistsErrorr�ra�isdir�access�W_OK�_errnoZEEXIST)�dirZpreZsufr}�output_typer��names�seqrar�rrrr�_mkstemp_inner�	s"$
rcCs4t|||�\}}}}|rt}nt}t||||||�S)a�User-callable function to create and return a unique temporary
    file.  The return value is a pair (fd, name) where fd is the
    file descriptor returned by os.open, and name is the filename.
    If 'suffix' is not None, the file name will end with that suffix,
    otherwise there will be no suffix.
    If 'prefix' is not None, the file name will begin with that prefix,
    otherwise a default prefix is used.
    If 'dir' is not None, the file will be created in that directory,
    otherwise a default directory is used.
    If 'text' is specified and true, the file is opened in text
    mode.  Else (the default) the file is opened in binary mode.
    If any of 'suffix', 'prefix' and 'dir' are not None, they must be the
    same type.  If they are bytes, the returned name will be bytes; str
    otherwise.
    The file is readable and writable only by the creating user ID.
    If the operating system uses permission bits to indicate whether a
    file is executable, the file is executable by no one. The file
    descriptor is not inherited by children of this process.
    Caller is responsible for deleting the file when done with it.
    )rrrr)r�r�rrQr�rr}rrr�mkstemp_mode
s
r)Nli���i�i�\�ll����i�l<E�tl��:[�lZ}Kl(�TZ�)r)r�F)reNNrr�F)rerr�F)rerr�F)N)N)N)N)r�rN)r�rN)NN)r�rN)ru)r�r�r�r�r�r�)r�r�r�r�r�r�)r�r�rr�r�r)N)r
)NNTT)r)N)r)NNNFr)�r��
contextlibr�r�r�r�r�r��ior�r9Zos.pathrAr�r�rnr�Zsocketr:r�r�rrrNZbinasciirrrrrrrr	�	functoolsr
r�	itertoolsr�operatorr
rr�rZshutilrZprefer_system_msgpack�ImportErrorZborg.algorithms.msgpackZ
algorithmsrXrr�r�rZborg.crypto.low_levelrDrrrOrrPrrrZ	constantsrsr�rkr�ZworkaroundsZEXIT_SUCCESSrr rBr!r1r2r3r4r5r6r7r8r?r@rErYrZ�MutableMappingr[r�r�r�r�r��S_IRWXU�S_IRWXG�S_IRWXOr�r�r�r�r	r�r�r�rmr�r r2r5r7r=r>rDrSZ
PrefixSpecZGlobSpecZCommentSpecr��_fieldsrTrZrVZSUPPORT_32BIT_PLATFORMSrYrZrr[r\r]r^rarbrkr�rlrvr|r}rjr�r�rLr�r�r�r�r_rjr�r�r�r�r�r�r�r�r�r�r�r�rSrVr�r�r�r�ZFALSISHZTRUISHZ
DEFAULTISHrr�rrr
r!r"r#r0r<rrBrCrOrrr�r�r�r�r�r�r�r�r��
TextIOWrapperr��
BaseExceptionr�r�r��contextmanagerr�r�r
ZJSONEncoderrir�r�r�r�r�rhr�r�r�r�r�rr�_sysrZtempfilerrrrrrrrrrr�<module>s�+
[
		



		
,E	+

[M
<"'
62
$&