HEX
Server: LiteSpeed
System: Linux shams.tasjeel.ae 5.14.0-611.5.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 11 08:09:09 EST 2025 x86_64
User: infowars (1469)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: //lib64/python3.9/site-packages/borg/__pycache__/archive.cpython-39.pyc
a

HZ�h���@sddlZddlZddlZddlZddlZddlZddlmZddlm	Z	ddl
mZmZddl
mZddlmZddlmZddlmZmZdd	lmZd
dlmZmZmZmZd
dlmZe�Zd
d
lm Z d
dl!m"Z"m#Z#d
dl$m%Z%d
dl&m'Z'm(Z(d
dl)m*Z*m+Z+d
dl,Td
dl-m.Z/d
dl0m1Z1m2Z2m3Z3d
dl4m5Z5d
dl4m6Z6d
dl4m7Z7m8Z8m9Z9d
dl4m:Z:m.Z.m;Z;d
dl<m=Z=m>Z>m?Z?m@Z@d
dl4mAZAmBZBd
dl4mCZCmDZDmEZEmFZFmGZGd
dl4mHZHmIZImJZJmKZKd
dl4mLZLd
dl4mMZMd
dl4mNZNd
d l4mOZOmPZPmQZQd
d!l4mRZRmSZSmTZTd
d"l4mUZUd
d#l4mVZVd
d$l4mWZWd
d%l4mXZXd
d&lYmZZZd
d'l[m\Z\m]Z]m^Z^d
d(l_m`Z`maZambZbd
d)l<mcZcmdZdmeZemfZfmgZgmhZhd
d*limjZjd
d+lkmlZlmmZmened,�ZoGd-d.�d.�Zpd/d0�ZqGd1d2�d2er�ZsGd3d4�d4er�ZtGd5d6�d6�Zueu�Zvd7d8�Zwd9d:�Zxe	dddd;d<d=�d>d?��ZyGd@dA�dA�ZzGdBdC�dC�Z{GdDdE�dEe{�Z|dddddF�dGdH�Z}GdIdJ�dJ�Z~GdKdL�dL�ZeZdMdNdO�dP�Z�dQdR�Z�GdSdT�dT�Z�GdUdV�dV�Z�GdWdX�dX�Z�dYdZ�Z�Gd[d\�d\�Z�Gd]d^�d^�Z�Gd_d`�d`�Z�dS)a�N)�OrderedDict)�contextmanager)�timezone�	timedelta)�partial)�getuser)�BytesIO)�groupby�zip_longest)�get_terminal_size�)�is_win32�is_linux�
is_freebsd�	is_darwin)�
create_logger)�xattr)�get_chunker�Chunk��ChunkListEntry)�key_factory�UnsupportedPayloadError)�
Compressor�CompressionSpec)�*)�IntegrityError)�
ChunkIndex�ChunkIndexEntry�CacheSynchronizer)�Manifest��hardlinkable)�ChunkIteratorFileWrapper�normalize_chunker_params�	open_item)�Errorr�set_ec)�uid2user�user2uid�	gid2group�	group2gid)�parse_timestamp�to_localtime)�OutputTimestamp�format_timedelta�format_file_size�file_status�FileSize)�safe_encode�safe_decode�make_path_safe�remove_surrogates)�
StableDict)�
bin_to_hex)�safe_ns)�ellipsis_truncate�ProgressIndicatorPercent�	log_multi)�os_open�flags_normal�	flags_dir)�os_stat)�msgpack)�sig_int)�utcnow)�LRUCache)�PathPrefixPattern�FnmatchPattern�	IECommand)�Item�ArchiveItem�ItemDiff)�acl_get�acl_set�	set_flags�	get_flags�swidth�hostname)�cache_if_remote)�
Repository�LIST_SCAN_LIMIT�linkc@s�eZdZddd�Zddd�Zdd�ZdZd	d
�Zdd�Zd
d�Z	dd�Z
edd��Ze
dd��Ze
dd��Ze
dd��Zddd�ZdS)�
StatisticsFcCsF||_||_d|_|_|_|_d|_|_|_|_	d|_
dS�Nr)�output_json�iec�osize�csize�usize�nfiles�osize_parts�csize_parts�usize_parts�nfiles_parts�
last_progress)�selfrWrX�rc�2/usr/lib64/python3.9/site-packages/borg/archive.py�__init__:s
zStatistics.__init__cCsf|s4|j|7_|j|7_|rb|j|7_n.|j|7_|j|7_|rb|j|7_dS�N)rYrZr[r]r^r_)rb�sizerZ�unique�partrcrcrd�updateAszStatistics.updatecCs�t|t�std��t|j|j�}|j|j|_|j|j|_|j|j|_|j|j|_|j	|j	|_	|j
|j
|_
|j|j|_|j|j|_|S)Nzcan only add Statistics objects)
�
isinstancerU�	TypeErrorrWrXrYrZr[r\r]r^r_r`)rb�other�statsrcrcrd�__add__Ms
zStatistics.__add__zO{label:15} {stats.osize_fmt:>20s} {stats.csize_fmt:>20s} {stats.usize_fmt:>20s}cCs|jj|dd�S)Nz
This archive:)rnZlabel)�summary�format�rbrcrcrd�__str__]szStatistics.__str__cCsdjt|�jt|�|d�S)NzF<{cls} object at {hash:#x} ({self.osize}, {self.csize}, {self.usize})>)�cls�hashrb)rq�type�__name__�idrrrcrcrd�__repr__`s�zStatistics.__repr__cCs4t|j|jd�t|j|jd�t|j|jd�|jd�S)N�rX)Z
original_sizeZcompressed_sizeZdeduplicated_sizer\)r2rYrXrZr[r\rrrcrcrd�as_dictds
�zStatistics.as_dictcCs|j|j|j|j|j|jd�S)N�rgrZr\�
size_partsr^r`�rYrZr\r]r^r`rrrcrcrd�as_raw_dictls�zStatistics.as_raw_dictcKsF|�}|d|_|d|_|d|_|d|_|d|_|d|_|S)NrgrZr\r}r^r`r~)rt�kwrbrcrcrd�
from_raw_dictvs





zStatistics.from_raw_dictcCst|j|jd�S�Nrz)r0rYrXrrrcrcrd�	osize_fmt�szStatistics.osize_fmtcCst|j|jd�Sr�)r0r[rXrrrcrcrd�	usize_fmt�szStatistics.usize_fmtcCst|j|jd�Sr�)r0rZrXrrrcrcrd�	csize_fmt�szStatistics.csize_fmtNc
Cst��}|dus ||j|k�r||_|jrz|sP|��}t|rD|jnd�|d<ni}|�t��d|d��t�	|�}d}nrt
�\}	}
|s�d�|�}|r�t|j�nd}|	t|�}|dkr�d}|	t|�}|dkr�|t
||�7}nd	|	}d
}t|||p�tjdd�dS)
N��pathZarchive_progress)�timerv�finished�
z={0.osize_fmt} O {0.csize_fmt} C {0.usize_fmt} D {0.nfiles} N ��� �
T)�end�file�flush)r��	monotonicrarWr{r6r�rj�json�dumpsrrqrOr:�print�sys�stderr)
rb�item�final�stream�dtZnow�data�msgr��columns�linesr��spacercrcrd�
show_progress�s8�


zStatistics.show_progress)FF)F)NFNN)rw�
__module__�__qualname__rerjrorprsryr{r�classmethodr��propertyr�r�r�r�rcrcrcrdrU8s"







rUcCst�|�pt�|�pt�|�Srf)�stat�S_ISBLK�S_ISCHR�S_ISFIFO)�modercrcrd�
is_special�sr�c@seZdZdZdS)�BackupErrorzY
    Exception raised for non-OSError-based exceptions while accessing backup files.
    N�rwr�r��__doc__rcrcrcrdr��sr�c@s eZdZdZdd�Zdd�ZdS)�
BackupOSErrora�
    Wrapper for OSError raised while accessing backup files.

    Borg does different kinds of IO, and IO failures have different consequences.
    This wrapper represents failures of input file or extraction IO.
    These are non-critical and are only reported (exit code = 1, warning).

    Any unwrapped IO error is critical and aborts execution (for example repository IO failure).
    cCs(||_||_|j|_|j|_|j|_dSrf)�op�os_error�errno�strerror�filename)rbr�r�rcrcrdre�s
zBackupOSError.__init__cCs&|jr|j�d|j��St|j�SdS)N�: )r�r��strrrrcrcrdrs�szBackupOSError.__str__N)rwr�r�r�rersrcrcrcrdr��s	r�c@s*eZdZdZd	dd�Zdd�Zdd�ZdS)
�BackupIOr�cCs
||_|Srf)r�)rbr�rcrcrd�__call__�szBackupIO.__call__cCsdSrfrcrrrcrcrd�	__enter__�szBackupIO.__enter__cCs |rt|t�rt|j|�|�dSrf)�
issubclass�OSErrorr�r�)rb�exc_typeZexc_valZexc_tbrcrcrd�__exit__�szBackupIO.__exit__N)r�)rwr�r�r�r�r�r�rcrcrcrdr��s
r�c	csddt_t�>zt|�}Wn ty8YWd�dS0Wd�n1sN0Y|VqdS)N�read)�	backup_ior��next�
StopIteration)�iteratorr�rcrcrd�backup_io_iter�s2r�cCs8t�|j�t�|j�kr td��|j|jkr4td��|S)aX
    this checks for some race conditions between the first filename-based stat()
    we did before dispatching to the (hopefully correct) file type backup handler
    and the (hopefully) fd-based fstat() we did in the handler.

    if there is a problematic difference (e.g. file type changed), we rather
    skip the file than being tricked into a security problem.

    such races should only happen if:
    - we are backing up a live filesystem (no snapshot, not inactive)
    - if files change due to normal fs activity at an unfortunate time
    - if somebody is doing an attack against us
    z1file type changed (race condition), skipping filez2file inode changed (race condition), skipping file)r��S_IFMT�st_moder��st_ino)Zst_oldZst_currrcrcrd�stat_update_check�s
r�F�open)r��	parent_fd�name�noatimer�c	cspt|��"t|||||d�}Wd�n1s00Yz|VW|durlt�|�n|durjt�|�0dS)N�r�r�r��flagsr�)r�r=�os�close)r�r�r�r�r�r��fdrcrcrd�OsOpen	s
0�r�c@s(eZdZdd�Zd	dd�Zd
dd�ZdS)�DownloadPipelinecCs||_||_dSrf)�
repository�key)rbr�r�rcrcrdreszDownloadPipeline.__init__NFc#sN�fdd�}t�}tjdd�}��|�D�]}	|�|	�dd�|D�}
|
D]}d|vrJdd�|jD�|_qJ�r��fd	d�|
D�}
|�r6��r|�r|
D]|}t|j�r�|�d
�}|dur�d|vr�||j�|�dd
�r�|�	|j
�q�||vr�||\}
}|
du�r||
�|�	|�q�n |
D]}d|v�r||j��q|
D]}|V�q:q(dS)a�
        Return iterator of items.

        *ids* is a chunk ID list of an item stream. *filter* is a callable
        to decide whether an item will be yielded. *preload* preloads the data chunks of every yielded item.

        Warning: if *preload* is True then all data chunks of every yielded item have to be retrieved,
        otherwise preloaded chunks will accumulate in RemoteRepository and create a memory leak.
        cs�j�dd�|D��dS)NcSsg|]
}|j�qSrc�rx��.0�crcrcrd�
<listcomp>&�zBDownloadPipeline.unpack_many.<locals>._preload.<locals>.<listcomp>)r��preload)�chunksrrrcrd�_preload%sz.DownloadPipeline.unpack_many.<locals>._preloadF�Zuse_listcSsg|]}t|d��qS)�Z
internal_dict)rH�r�r�rcrcrdr�,r�z0DownloadPipeline.unpack_many.<locals>.<listcomp>r�cSsg|]}t|��qSrcr)r��ercrcrdr�/r�csg|]}�|�r|�qSrcrcr���filterrcrdr�2r��sourceN�hardlink_masterT)�setrA�Unpacker�
fetch_many�feedr�r"r��get�addr�)rb�idsr��partial_extractr��hardlink_mastersr�Zmasters_preloaded�unpackerr��itemsr�r�r��_rc�r�rbrd�unpack_manys>






zDownloadPipeline.unpack_manyccs4t||jj||d��D]\}}|j�||�VqdS)N��is_preloaded)�zipr��get_manyr��decrypt)rbr�r��id_r�rcrcrdr�TszDownloadPipeline.fetch_many)NFFN)F)rwr�r�rer�r�rcrcrcrdr�s
9r�c@s>eZdZdZefdd�Zdd�Zdd�Zdd	d
�Zdd�Z	d
S)�ChunkBufferi�cCs8t�|_t��|_g|_||_t||jjdd��|_	dS)NF�Zseed�sparse)
r�bufferrAZPacker�packerr�r�r�
chunk_seed�chunker)rbr��chunker_paramsrcrcrdre\s

zChunkBuffer.__init__cCs,|j�|j�|����|��r(|��dSrf)r��writer��packr{�is_fullr�)rbr�rcrcrdr�cszChunkBuffer.addcCst�dSrf)�NotImplementedError)rb�chunkrcrcrd�write_chunkhszChunkBuffer.write_chunkFcCs�|j��dkrdS|j�d�g}|j�|j�D]X}|jd}|tkrRt|j�}n,|t	t
fvrrtd|jd�}ntd|��|�
|�q0|j�d�|j�d�|s�t|�dkr�dnd}|d|�D]}|j�
|�|��q�|dkr�|j�|d�dS)Nr�
allocationrgz,chunk allocation has unsupported value of %rr���)r��tell�seekr�chunkify�meta�CH_DATA�bytesr��CH_ALLOC�CH_HOLE�zeros�
ValueError�append�truncate�lenr�rr)rbr�r�rZallocr�r�rcrcrdr�ks&
zChunkBuffer.flushcCs|j��|jkSrf)r�r
�BUFFER_SIZErrrcrcrdr�szChunkBuffer.is_fullN)F)
rwr�r�r�ITEMS_CHUNKER_PARAMSrer�rr�rrcrcrcrdr�Ys
r�cs(eZdZef�fdd�	Zdd�Z�ZS)�CacheChunkBuffercst��||�||_||_dSrf)�superre�cachern)rbrr�rnr��	__class__rcrdre�szCacheChunkBuffer.__init__cCs8|jj|j�|�||jdd�\}}}|jjjdd�|S�NF��wait)r�	add_chunkr��id_hashrnr��async_response)rbrr�r�rcrcrdr�s$zCacheChunkBuffer.write_chunk)rwr�r�rrer�
__classcell__rcrcrrdr�sr)�
uid_forced�
gid_forced�uid_default�gid_defaultcCs�|dur|}n0|rdnt|j�}|dur.|jn|}|dkr>|}|durL|}n0|rTdnt|j�}|durl|jn|}|dkr||}||fSrV)r)�user�uidr+�group�gid)r��numericr%r&r'r(r*r,rcrcrd�get_item_uid_gid�sr.c@sXeZdZGdd�de�ZGdd�de�ZGdd�de�Zddd	dddddddeddddddfd
d�Zdd
�Z	dd�Z
edd��Zedd��Z
edd��Zedd��Zedd��Zdd�Zdd�Zdd�Zd>d d!�Zd?d"d#�Zd@d%d&�Zd'd(�ZdAd)d*�ZdBd+d,�ZdCd-d.�Zed/d0��ZdDd2d3�ZdEd4d5�Zd6d7�Zd8d9�Z dFd:d;�Z!e"dGd<d=��Z#dS)H�Archivec@seZdZdZdS)zArchive.DoesNotExistzArchive {} does not existNr�rcrcrcrd�DoesNotExist�sr0c@seZdZdZdS)zArchive.AlreadyExistszArchive {} already existsNr�rcrcrcrd�
AlreadyExists�sr1c@seZdZdZdS)z+Archive.IncompatibleFilesystemEncodingErrorzrFailed to encode filename "{}" into file system encoding "{}". Consider configuring the LANG environment variable.Nr�rcrcrcrd�#IncompatibleFilesystemEncodingError�sr2NF�cCs�t��|_||_||_||_||_i|_t||d�|_	||_
||_||_||_
d|_d|_||_||_|	|_|
|_||_||_|
|_|du|duks�Jd��|dur�t�}t��}||_||_||_|dur�t�}||_||_t|j|j�|_ ||_!|j!�rht"|j|j|j	�|_#||j$v�r&|�%|��d}d�&||�r@d|�pBd�|_'|j'|j$v�rZ�q�|d7}�q*n.|jj$�(|�}|du�r�|�)|��|�*|j+�dS)	N�rWrXFzULogic error: if start is given, start_monotonic must be given as well and vice versa.rz{}.checkpoint{}z.%dr�r),r��getcwd�cwdr�r�r�manifest�
hard_linksrUrnrXr�r�Zname_in_manifest�comment�tam_verified�checkpoint_interval�numeric_idsr��noctime�noflags�noacls�noxattrsrCr�r�r�start�start_monotonicr��consider_part_filesr��pipeline�creater�items_buffer�archivesr1rq�checkpoint_namer�r0�loadrx)rbr�r�r7r�rrEr;r<r�r=r>r?r@�progressrrArBr�rC�log_jsonrX�i�inforcrcrdre�s\



zArchive.__init__cCsN|j�||j�|��}|jj|dd�\}|_}t|d�}|jdkrJtd��|S)NT�Zforce_tam_not_requiredr�r� Unknown archive metadata version)	r�r�r�r��unpack_and_verify_archiver:rI�version�	Exception)rbrxr��archiver��metadatarcrcrd�
_load_meta�s

zArchive._load_metacCsH||_|�|j�|_dd�|jjD�|j_|jj|_|j�dd�|_dS)NcSsg|]}t|��qSrc�r4�r��argrcrcrdr��r�z Archive.load.<locals>.<listcomp>r9r�)rxrUrT�cmdliner�r�r9)rbrxrcrcrdrI�s

zArchive.loadcCs|jj}t|�S)z,Timestamp of archive creation (start) in UTC)rTr�r,�rb�tsrcrcrdr[�sz
Archive.tscCs|j�d�p|jj}t|�S)z*Timestamp of archive creation (end) in UTC�time_end)rTr�r�r,rZrcrcrd�ts_endszArchive.ts_endcCs
t|j�Srf)r8rxrrrcrcrd�fprszArchive.fprcCst|j|j�Srf)r/r�rArrrcrcrd�durationszArchive.durationcCst|j|j�Srf)r/r]r[rrrcrcrd�duration_from_metaszArchive.duration_from_metac	Cs�|jr.|j}|jjtjd�}|jjtjd�}n|�|j�}|j	}|j
}|j|jt
|�t
|�||��|��d|jj|jjtid�}|jr�tj|d<nL|j�d�}|dur�t|�nd}|�|jj|jj|jj|j�dd�|d��|S)	N�ZtzinfoZmax_archive_size)r�rxrAr�r_rnZlimits�command_linerr�r9)rbrP�usernamer9r)rErnrA�replacer�utcr��
calc_statsrr[r]r�r^r.Z
total_secondsr{r�rxrZ�
MAX_DATA_SIZEr��argvrTr�r$rjrYrPrc)rbrnrAr�rMZcprcrcrdrMs8
���zArchive.infocCsLdj|t|jjtjd��t|jjtjd��|jj|j	j
t|jj
��d�S)Nz�Repository: {location}
Archive name: {0.name}
Archive fingerprint: {0.fpr}
Time (start): {start}
Time (end):   {end}
Duration: {0.duration}
Number of files: {0.stats.nfiles}
Utilization of max. archive size: {csize_max:.0%}
ra)rAr�Z	csize_max�location)rqr.rArdrrer�rr�rxrZrgr�Z	_locationZcanonical_pathrrrcrcrdrs5s

�zArchive.__str__cCs
d|jS)NzArchive(%r))r�rrrcrcrdryGszArchive.__repr__cCs"|jsd|vrdS|r||�SdS)NriFT)rC)rbr�r�rcrcrd�item_filterJszArchive.item_filterc#sL�r|r|r|dusJ��jj�jj|||��fdd�d�D]
}|Vq<dS)Ncs��|��Srf)rj�r�r�rcrd�<lambda>Vr�z$Archive.iter_items.<locals>.<lambda>)r�r�r�r�)rDr�rTr�)rbr�r�r�r�r�rcr�rd�
iter_itemsPs�
zArchive.iter_itemsTcCs6|r&|jr&|dur|j}|j|dd�|j�|�dS)N皙�����?�r�r�)r�rnrFr�)rbr�r�rnrcrcrd�add_itemYs

zArchive.add_itemcCs.|�|j�|jj|j=|j�|j|j�dSrf)�saverHr7rGr�chunk_decrefrxrnrrrcrcrd�write_checkpoint`szArchive.write_checkpointc
Cs�|p|j}||jjvr |�|��|jjdd�tt��|j	d�}|durZt
�}||}n||}|}||_||_d||p|d|jj
tjtt�|�t�|�t�|jd�
}	|p�|j}|	�|j|j|j|j|j|jd��|	�|p�i�t|	�}	|jj|	� �dd	�}
|j�!|
�|_"z|j#�$|j"|
|j�WnHt%�yl}z.t&|�}d
|v�rVt'd|��n�WYd}~n
d}~00|j(j)dd�du�r��qn|j"|	jf|jj|<|j�*�|j(j+d
d�|j#�+�dS)NT�r�)Zsecondsrr�)
rQr�r9r�rYrPrcr�r\rr|�archive��contextzMore than allowed put dataz#%s - archive too big (issue #1473)!rF)�compact),r�r7rGr1rFr�rr�r�rBrCrAr�r�r�rhrPr�strftimeZ
ISO_FORMATrrnrjrYrZr\r]r^r`rIr��pack_and_authenticate_metadatar{r"rxrr!rr�r&r�r#r�commit)
rbr�r9�	timestamprn�additional_metadatar_r�rArTr��err�err_msgrcrcrdrqesb


�
�

zArchive.savecCsn|j�d�du}z$|rt�tjfi|j|j��}Wn4tyh|j||d�}|sd|��|j|j<Yn0|S)Nr\)�want_unique)	rTr��KeyErrorrUr�Z
pre12_metar^�_calc_statsr)rbrr��have_borg12_metarnrcrcrdrf�szArchive.calc_statsc
s�|j�d�du}|r|sd}n���fdd�}t��t��}||j�|j�dd�}tt|jj	�d|dd	�}t
|jj	|j�|jj	��D]4\}	}
|j
d
d�||	�|j�|	|
�}|�|�q����j�d}|��t|jd
�}||_|�s:|j�r|j|_|j|_|j|_n*|j|j|_|j|j|_|j|j |_n^|j�rz|jj!|jj|_|jj|jj"|_|jj |jj|_n|jj|_|jj"|_|jj|_|S)Nr\rcs"�j|}��|d|j|j�dS)Nr)r�r�rgrZ)rx�entry�Z
archive_indexrrcrdr��s
z Archive._calc_stats.<locals>.add�%z%%z4Calculating statistics for archive %s ... %%3.0f%%%%zarchive.calc_stats��totalr��msgidr)�increase�rz)#rTr�rrrxr�rdr;rr�r�r�r��showr�r�r�Z
stats_againstr��finishrUrXr[rCZnum_files_totalsr\Zsize_totalsrYZcsize_totalsrZZnum_files_partsr}r^r`rg)
rbrr�r�Zunique_csizer��syncZarch_name_escd�pirxrr�rnrcr�rdr��sJ
�"



zArchive._calc_statsccs�d}d|vr�tjj|g|j�tj�|d��R�}|�|jd|f�\}	}
|
r�tr�td�� t�	|
|�d}Wd�q�1s~0Yn|	dur�|	|_
|V|s�|r�tr�d|f||�d�p�|<ndS)NFr�rTT)r�r��joinr��split�sepr��has_linkr�rTr�)rb�destr�r��stripped_components�
original_pathr��hardlink_setr�r�Zlink_targetrcrcrd�extract_helper�s&
$zArchive.extract_helperrc
Cs�|pi}d|v}
|s|r�d|vr�d}|jjdd�|jD�dd�D]@}|	rb|	jt|�t|j�gd�|rttjj	�
|�|t|�7}q@|r�tjj	��d	|vr�|j}
|
|kr�t
d
�|
|���|
r�t
d��dS|p�|j}|j}|j�d
�r�td��tj�||j�}z6tj|dd�}t�|j��r&t�|�n
t�|�Wn8t�yX|�|t���d�Ynt�yjYn0dd�}|j}t�|��r�td��||�Wd�n1�s�0Y|� ||||||����}|�r�Wd�dStd��t!|d�}Wd�n1�s0Y|��dd�|jD�}|jj|dd�D]~}|	�rf|	jt|�t|j�gd�td��>|�r�t"�|��r�|�#t|�d�n
|�
|�Wd�n1�s�0Y�qBtd��B|�$�}}|�%|�|��|j&|||�'�d�Wd�n1�s0YWd�n1�s40Yd	|v�rh|j}
|
|k�rht
d
�|
|���|
�rvt
d��Wd�n1�s�0YdSt���t�|��r�||�tj�(|��s�t�)|�|�rt|�&||��n�t�*|��rJ||�|j+}zt�,||�Wn&t�y4|�|t���d�Yn0|j&||dd��n*t�-|��r�||�|� ||||||��H}|�r�Wd�Wd�dSt�.|�|�&||�Wd�n1�s�0Yn�t�/|��s�t�0|��rf||�|� ||||||��P}|�r&Wd�Wd�dSt�1||j|j2�|�&||�Wd�n1�sZ0Yntd|j��Wd�n1�s�0YdS)a�
        Extract archive item.

        :param item: the item to extract
        :param restore_attrs: restore file attributes
        :param dry_run: do not write any data
        :param stdout: write extracted data to stdout
        :param sparse: write sparse files (chunk-granularity, independent of the original being sparse)
        :param hardlink_masters: maps paths to (chunks, link_target) for extracting subtrees with hardlinks correctly
        :param stripped_components: stripped leading path components to correct hard link extraction
        :param original_path: 'path' key as stored in archive
        :param pi: ProgressIndicatorPercent (or similar) for file extraction progress (in bytes)
        �chunks_healthyr�rcSsg|]
}|j�qSrcr�r�rcrcrdr�
r�z(Archive.extract_item.<locals>.<listcomp>Tr�)r�rMrgz4Size inconsistency detected: size {}, chunks size {}zDFile has damaged (all-zero) chunks. Try running borg check --repair.N)�/z../z!Path should be relative and localF��follow_symlinkscSs&tj�|�}tj�|�s"t�|�dSrf)r�r��dirname�exists�makedirs)r�Z
parent_dirrcrcrd�make_parent/sz)Archive.extract_item.<locals>.make_parentr�r��wbcSsg|]
}|j�qSrcr�r�rcrcrdr�?r�rrZtruncate_and_attrs�r�)�symlinkzUnknown archive item type %r)3rDr�r�r�rr6r�r��stdoutr�rr�rgr�rqr6�
startswithrRr�r�r��S_ISDIRr��rmdir�unlink�UnicodeEncodeErrorr2�getfilesystemencodingr�r��S_ISREGr�r�r�rrr
r�
restore_attrs�filenor��mkdir�S_ISLNKr�r�r��mkfifor�r��mknod�rdev)rbr�r��dry_runr�r�r�r�r�r�Zhas_damaged_chunks�item_chunks_sizer��	item_sizer�r��str�r�r�r�r��posr�rcrcrd�extract_item�s� �

(�
*
.

T

�(
�
.�.zArchive.extract_itemcCs�dt_t||jd�\}}t�s�z*|r4t�|||�ntj|||dd�WntyZYn0|rpt�	||j
�n<ztj||j
dd�Wn$ty�|s�t�||j
�Yn0|j
s�t|||j|d�|js�tj|p�||�di�dd�}|r�tt�|j}d|v�r
|j}	n|}	d|v�rj|j}
z6|�r<tj|d	|	|
fd
�ntj|d	|	|
fdd�Wnt�yhYn0z6|�r�tj|d	|	|fd
�ntj|d	|	|fdd�Wnt�y�Yn0|j�s�d|v�r�zt||j|d�Wnt�y�Yn0d	S)
zv
        Restore filesystem attributes on *path* (*fd*) from *item*.

        Does not access the repository.
        �attrs)r-Fr�r��xattrs�atime�	birthtimeN)�ns)r�r��bsdflags)r�r�r.r<r
r��fchown�chownr��fchmodr��chmodrr?rLr@rZset_allr�r'ZEXIT_WARNING�mtimer�r��utimer>rMr�)rbr�r�r�r�r*r,�warningr�r�r�rcrcrdr�ysZ

zArchive.restore_attrscCsz|�|j�}t|||�|jj|��dd�}|j�|�}|j�|||j	�||j
f|jj|j
<|j�|j|j	�||_dS)Nrurv)rUrx�setattrr�rzr{r"rr!rnr�r7rGr�rr)rbr��valuerTr�Znew_idrcrcrd�set_meta�szArchive.set_metacCs<||jjvr|�|��|j}||_|�d|�|jj|=dS)Nr�)r7rGr1r�r�)rbr�Zoldnamercrcrd�rename�s
zArchive.renamec
s�Gdd�dt��t��d����fdd�	�d���fdd�	}d��ztjdd	�}�jj}tt|�d
dd�}tt	|�j
�|���D]�\}\}	}
|r�|�|��j
�|	|
�}
|�|
�||	|�zP|D]F}t|d
�}d|vrˆjo�d|v}|jD]\}
}}||
||d�q�q�Wq�ttf�y4�dk�r,�d�Yq�0q�|�rF|��Wn,tjtjf�yt�dk�rl�d�Yn0|�j|��jj�j=�dd�du�r��q���r�t�d�t�d�dS)Nc@seZdZdZdS)z(Archive.delete.<locals>.ChunksIndexErrorzUChunk ID {} missing from chunks index, corrupted chunks index - aborting transaction.Nr�rcrcrcrd�ChunksIndexError�sr�Tcs<z�jj|d�WStjy6�dkr*�d��YS0dS)NrrT)r�r#rR�ObjectNotFoundr)�error�exception_ignored�forcedrbrcrd�fetch_async_response�sz,Archive.delete.<locals>.fetch_async_responseFcsJz�jj||d|d�Wn"ty:t|�}�|��Yn0�dd�dS)NF)r rir)rrrr�r8)rxrnri�cid)r�r�rbrcrdrr�sz$Archive.delete.<locals>.chunk_decrefr�zDecrementing references %3.0f%%zarchive.deleter�r�r�ri)rirrzAforced deletion succeeded, but the deleted archive was corrupted.z2borg check --repair is required to free all space.)T)F)r&�objectrAr�rTr�r;r�	enumerater�r�r�r�r�r�r�rHrCr�rlrr��UnpackExceptionrRr�rxr7rGr��loggerr�)rbrnrJr�rrr�Z	items_idsr�rLZitems_idr�r�ri�chunk_idrgrZrc)r�r�r�r�r�rbrd�delete�sN	"







zArchive.deletec#s�fdd��dd����fdd��
dd��������fd	d
�}���
fdd�}t�}t�}g�i�t���	fd
d�����	fdd���D]�\}	}
|	r�|
r�|	j|
jkr�||	|
�s�|	j||	|
�fVq�|	�r|�|	jd�}|r�||	|�s�|	j||	|�fVn
|	||	j<|
r�|�|
jd�}|�r<|||
��sF|j|||
�fVq�|
||
j<q�|��D]0}|j}
t�|
�}�
||�|
|||�fV�qP|��D]0}|j}
t�|
�}�
||�|
|||�fV�q��D]N\}	}
�|	��s�J��|
��s�J�|	j|
jk�s�Jd��|	j||	|
�fV�q�dS)a%
        Yields tuples with a path and an ItemDiff instance describing changes/indicating equality.

        :param matcher: PatternMatcher class to restrict results to only matching paths.
        :param can_compare_chunk_ids: Whether --chunker-params are the same for both archives.
        csd|vpt|j�p|j�vS�Nr�)r"r�r�rk)r�rcrd�hardlink_master_seen#sz;Archive.compare_archives_iter.<locals>.hardlink_master_seencSs|�dd�od|vot|j�S�Nr�Tr�)r�r"r�rkrcrcrd�is_hardlink_master&sz9Archive.compare_archives_iter.<locals>.is_hardlink_mastercs"�|�s�|�r||f�|j<dSrf�r���item1�item2)r�r�rcrd�update_hardlink_masters)sz>Archive.compare_archives_iter.<locals>.update_hardlink_masterscSst|j�o|�d�|vSr��r"r�r�)r�r�rcrcrd�has_hardlink_master-sz:Archive.compare_archives_iter.<locals>.has_hardlink_mastercsx�|��r�|jd}�|��r0�|jd}t||�j�dd�|�dg�D���j�dd�|�dg�D����d�S)NrrcSsg|]
}|j�qSrcr�r�rcrcrdr�6r�zHArchive.compare_archives_iter.<locals>.compare_items.<locals>.<listcomp>r�cSsg|]
}|j�qSrcr�r�rcrcrdr�7r�)�can_compare_chunk_ids�content_only)r�rJrDr�r�r�)�archive1�archive2r�r�r�r�rcrd�
compare_items0s

�z4Archive.compare_archives_iter.<locals>.compare_itemscs4�||��|�p�|�}|r0��||f�|S)zQAdds item tuple to deferred if necessary and returns True, if items were deferred)r)r�r�Zdefer)�deferredr�r�rcrd�defer_if_necessary;s

z9Archive.compare_archives_iter.<locals>.defer_if_necessarycs��|j�Srf��matchr�rk��matcherrcrdrlIr�z/Archive.compare_archives_iter.<locals>.<lambda>cs��|j�Srfr�rkr�rcrdrlJr�Nz#Deferred items have different paths)rr
rmr��pop�valuesrHZcreate_deleted)r�r�r�r�r�r�r�Zorphans_archive1Zorphans_archive2r�r�Zmatching_orphanZaddedr�Zdeleted_itemZdeletedrc)r�r�r�r�r�r�r�r�r�r�r�rd�compare_archives_itersZ	�






zArchive.compare_archives_iter)N)NFFN)TN)NNNNN)T)T)TFFFNrNN)FN)FF)NFF)$rwr�r�r&r0r1r2�CHUNKER_PARAMSrerUrIr�r[r]r^r_r`rMrsryrjrmrprsrqrfr�rr�r�r�r�r�r��staticmethodr�rcrcrcrdr/�sV
�
6	




"

	

9

0
�

I

Fr/c@s0eZdZdd�Zdd�Zd
dd�Zddd	�ZdS)�MetadataCollectorcCs.||_||_||_||_||_||_||_dSrf)r�r=r<r>r?r@�nobirthtime)rbr�r=r�r<r>r?r@rcrcrdreqszMetadataCollector.__init__cCs�t|j|j|jt|j�d�}|js0t|j�|d<|jsDt|j	�|d<|j
sjt|d�rjtt|j
d��|d<|jr�d|d<|d<nt|j�|d<t|j�|d<|S)	N)r�r*r,r�r��ctime�st_birthtime�ʚ;r�r)r+)�dictr��st_uid�st_gidr9�st_mtime_nsr��st_atime_nsr=�st_ctime_nsr��hasattr�intr�r<r(r*)rbr�r�rcrcrd�stat_simple_attrszs"�	z#MetadataCollector.stat_simple_attrsNcCs�i}|jsLtd��t|||d�}Wd�n1s60Y|rL||d<|js�td��"tj|pf|dd�}Wd�n1s�0Y|r�t|�|d<|js�td��$t||||j	|d�Wd�n1s�0Y|S)	Nzextended stat (flags)r�r�zextended stat (xattrs)Fr�r�zextended stat (ACLs))
r>r�rNr@rZget_allr7r?rKr<)rbr�r�r�r�r�r�rcrcrd�stat_ext_attrs�s
,
0
2z MetadataCollector.stat_ext_attrscCs$|�|�}|�|j|||d��|S)Nr�)r�rjr)rbr�r�r�r�rcrcrd�
stat_attrs�s
zMetadataCollector.stat_attrs)N)N)rwr�r�rer�rrrcrcrcrdr�ps	
r��
cCsdSrfrc)r�rcrcrdrl�r�rl)ZdisposecCs�|jd}|tkr"|j}||�}nx|ttfvr�|jd}|tt�ksHJ�tt�d|�}zt||f}Wq�t	y�||�}|t||f<Yq�0nt
d��||fS)Nrrgzunexpected allocation type)r
rr�rrrr�
memoryview�zero_chunk_idsr�r)rr"rr�r�rgrcrcrd�cached_hash�s


rc@s0eZdZdd�Zdd�Zddd�Zdd	d
�ZdS)
�ChunksProcessorcCs2||_||_||_||_||_t��|_||_dSrf)	r�rrprsr;r�r��last_checkpoint�
rechunkify)rbr�rrprsr;rrcrcrdre�s
zChunksProcessor.__init__cCstt|��d�}t|j�}|j|d�|_|jddd�|jd|7_||_|d7}|j|dd�|��||fS)Nr�T)�memorize�from_chunksz
.borg_part_%drF)r�)	rHr{rr��get_sizer�rirprs)rbr��
from_chunk�number�lengthrcrcrd�write_part_file�s
zChunksProcessor.write_part_fileFcCsvto
t��}|s.|s.|jrnt��|j|jkrn|r<t�d�|�|||�\}}t��|_|rnt�	�t�d�||fS)Nz5checkpoint requested: starting checkpoint creation...z3checkpoint requested: finished checkpoint creation!)
rBZaction_triggeredr;r�r�rr�rMrZaction_completed)rbr�r�part_numberr�Zsig_int_triggeredrcrcrd�maybe_checkpoint�s��


z ChunksProcessor.maybe_checkpointNc
s�|s���fdd�}g|_�jr,d|vr,|`d}d}|D]<}	|j�||	��|r^�j|dd��j|||dd	�\}}q8|dkr�|j|d�r��j|||d
d	�\}}|jD]}	�j|	j�|	jd
d�q��j	|d7_	dS)Ncs8t|�jj�\}}�j||�dd�}�jjjdd�|Sr)rr�r"r!rr�r#)rr�r��chunk_entry�rrbrnrcrd�chunk_processor�sz<ChunksProcessor.process_file_chunks.<locals>.chunk_processorr�rrrnroF)r�T)rgri)
r�rr�rr�r�chunk_increfrxrgr`)
rbr�rrnr�Z
chunk_iterrrrrrcrrd�process_file_chunks�s$
z#ChunksProcessor.process_file_chunks)F)N)rwr�r�rerrrrcrcrcrdr�s

rc@sfeZdZdd�dd�Zeddd��Zdd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zed�dd�Z
dS)�FilesystemObjectProcessorsN��file_status_printercCsh||_||_||_||_||_||_|p.dd�|_i|_t|	|
d�|_	t
��|_t
||j|d��|_dS)NcWsdSrfrc��argsrcrcrdrlr�z5FilesystemObjectProcessors.__init__.<locals>.<lambda>r4r�)�metadata_collectorrr�rprr��print_file_statusr8rUrnr�r5r6rr�r)rbrrr�rprrr�r�rKrXrrcrcrdres
z#FilesystemObjectProcessors.__init__Tc
cs�t|�}t|d�}d}|o"|jdk}|rT|j�|j|jf�}	|	durP|	|_d}nd}||||fV|j||j	d�|r�||j|j|jf<dS)Nr�Fr�hT�rn)
r5rH�st_nlinkr8r�r��st_devr�rprn)
rbr�r��statusr"Z	safe_pathr�r��
hardlinkedr�rcrcrd�
create_helper&s
z(FilesystemObjectProcessors.create_helpercCsZ|j||ddd��4\}}}}|�|jj|||d��|Wd�S1sL0YdS)N�dFr!r�)r$rjrr)rbr�r�r�r�r"r#r�rcrcrd�process_dir_with_fd:sz.FilesystemObjectProcessors.process_dir_with_fdc

Cs�|j||ddd���\}}}}t|||tddd��z}	|	durrtd�� t|t�|	��}Wd�n1sh0Y|�|jj	|||	d��|Wd�Wd�S1s�0YWd�n1s�0YdS)	Nr%Fr!TZdir_open)r�r�r�r�r�r��fstatr�)
r$r�r?r�r�r�r'rjrr�
rbr�r�r�r�r�r"r#r�r�rcrcrd�process_dir?s
�
.z&FilesystemObjectProcessors.process_dirc

Cs�|�||d���\}}}}t|||tdd���}	td�� t|t�|	��}Wd�n1sZ0Y|rl|rr||_|�|j	j
|||	d��|Wd�Wd�S1s�0YWd�n1s�0YdS)N�fTr�r'r�)r$r�r>r�r�r�r'r�rjrrr(rcrcrd�process_fifoJs
.z'FilesystemObjectProcessors.process_fifoc

Cs�|�|||���\}}}}	td��&t|t|||dd��}Wd�n1sL0Y|j|_|rf|	rl||_|�|j�	||��|Wd�S1s�0YdS)Nr�F)r�r�r�r�)
r$r�r�r@�st_rdevr�r�rjrr)
rbr�r�r�r�Zdev_typer�r"r#r�rcrcrd�process_devTs
4z&FilesystemObjectProcessors.process_devc	Cs�|j||ddd���\}}}}|dur0|dur0|n|}	td��tj|	|d�}
Wd�n1s`0Y|
|_|�|j�||��|Wd�S1s�0YdS)N�sFr!�readlink)�dir_fd)r$r�r�r/r�rjrr)rbr�r�r�r�r�r"r#r��fnamer�rcrcrd�process_symlink_s
,z*FilesystemObjectProcessors.process_symlinkcCs�d}|�||�d}t|�}|dur0td|��t|�}	|	durLtd|��tt���d}
t||d@dB|||	||
|
|
d�	}|�|||j|j	t
|j�|���|j
dd	�|jjd
7_d|_|j||jd�|S)
NrLzno such user: %szno such group: %sr�i��i�)	r�r�r*r)r,r+r�r�r�T�r	rFr)rr)r&r+r�r�rHrrnr�r�rrrr\r�rp)rbr�rr�r�r)r+r"r*r,�tr�rcrcrd�process_pipeks.
�"z'FilesystemObjectProcessors.process_pipe)r�cs���||d����\}}}	}
t||||dd���h}td�� t|t�|��}Wd�n1s^0Y|��j�|��t	|j
�}|r�tjt�
|j�B|_|	r�|
�rR|s�ttj��j|��}
�j�|
�}��|
||�\}}nd}
}d\}}d}|du�r8|D]}��|��sd}�qF�q��fdd�|D�}d}n|�rBdnd	}��||�d}|	|_|du�rn||_n�td
��4��|��j�jt�j�d|���Wd�n1�s�0Yt �r�d}nHtd��t�|�}Wd�n1�s�0Y|�o|j!|j!k}|�rd
}|�sB|�sB��"|
||dd�|jD���jj#d7_#|��jj$|||d��|j%dd�|Wd�Wd�S1�s�0YWd�n1�s�0YdS)NTr�r')FN�Mcsg|]}��|�j��qSrc)rrn)r�r��rrbrcrdr��r�z;FilesystemObjectProcessors.process_file.<locals>.<listcomp>�U�Ar�FZfstat2�CcSsg|]
}|j�qSrcr�r�rcrcrdr��r�rr�r3)&r$r�r�r�r�r'rjrr�r�r�r��S_IFREG�S_IMODEr�r3r�r�r6r�r"Zfile_known_and_unchangedZ
seen_chunkrr�r�rrnr�r�rrr
r�Z
memorize_filer\rr)rbr�r�r�r�rr�r�r"r#r�r�Zis_special_fileZhashed_pathZ	path_hashZknownr�r�r�Zchanged_while_backupZst2rcr7rd�process_file�sX
.





D
*z'FilesystemObjectProcessors.process_file)NT)rwr�r�rerr$r&r)r+r-r2r5r>r=rcrcrcrdrs�
rc@sPeZdZdd�dd�Zeddd��Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dS)�TarfileObjectProcessorsNrc	
CsR||_||_||_||_||_|	p(dd�|_t||d�|_t||j	dd��|_
dS)NcWsdSrfrcrrcrcrdrl�r�z2TarfileObjectProcessors.__init__.<locals>.<lambda>r4Fr�)rr�rprr�rrUrnrr�r)
rbrr�rprrr�rKrXrrcrcrdre�sz TarfileObjectProcessors.__init__ccsjtj�|j�}tt|�|j|B|j|j|j	p.d|j
p6dtt|j
d��d�}||fV|j||jd�dS)Nr�)r�r�r*r,r)r+r�r)r�r��normpathr�rHr5r�r*r,�uname�gnamer9r�r�rprn)rb�tarinfor"rvZnormalized_pathr�rcrcrdr$�s�
z%TarfileObjectProcessors.create_helpercCs:|�|||��\}}|Wd�S1s,0YdSrf�r$�rbrBr"rvr�rcrcrdr)�sz#TarfileObjectProcessors.process_dircCs:|�|||��\}}|Wd�S1s,0YdSrfrCrDrcrcrdr+�sz$TarfileObjectProcessors.process_fifocCsL|�|||��*\}}t�|j|j�|_|Wd�S1s>0YdSrf)r$r��makedevZdevmajorZdevminorr�rDrcrcrdr-�sz#TarfileObjectProcessors.process_devcCsB|�|||�� \}}|j|_|Wd�S1s40YdSrf)r$Zlinknamer�rDrcrcrd�process_link�sz$TarfileObjectProcessors.process_linkcCs�|�|||��t\}}|�||j�d}|�|�}|�||j|j|jt|j	�
|���|jdd�|jjd7_|Wd�S1s�0YdS)NTr3r)
r$rr�Zextractfilerrrnr�r�rrrr\)rbrBr"rv�tarr�r�rcrcrdr=�s
�z$TarfileObjectProcessors.process_file)NN)rwr�r�rerr$r)r+r-rFr=rcrcrcrdr>�s�r>cs�t|�}|dkrdS|dd@dkr*d}n|ddkr<d}ndS||krLdS||d@d	kr^n||d
vrlndS||d��t�fdd
�|D��S)z1check if the data <d> looks like a msgpacked dictrF���r��r����)������Nc3s|]}��|�VqdSrf)r�)r��pattern�Zkey_serializedrcrd�	<genexpr>r�z'valid_msgpacked_dict.<locals>.<genexpr>)r�any)r%Zkeys_serializedZd_lenZoffsrcrQrd�valid_msgpacked_dicts"rTcs@eZdZdZ�fdd�Zdd�Zdd�Zdd	�Zd
d�Z�Z	S)�RobustUnpackerzCA restartable/robust version of the streaming msgpack unpacker
    cs>t���dd�|D�|_||_g|_d|_tjtd�|_	dS)NcSsg|]}t�|����qSrc�rAZpackb�encode�r�r�rcrcrdr�!r�z+RobustUnpacker.__init__.<locals>.<listcomp>F�Zobject_hook)
rre�	item_keys�	validator�_buffered_data�_resyncrAr�r7�	_unpacker)rbr[rZrrcrdres
zRobustUnpacker.__init__cCsg|_d|_dS)NT)r\r]rrrcrcrd�resync'szRobustUnpacker.resynccCs$|jr|j�|�n|j�|�dSrf)r]r\rr^r�)rbr�rcrcrdr�+szRobustUnpacker.feedcCs|Srfrcrrrcrcrd�__iter__1szRobustUnpacker.__iter__c	Cs�|jr�d�|j�}|jr�|s t�t||j�s:|dd�}qtjtd�|_	|j	�
|�zt|j	�}WntjtfyzYn0|�
|�r�d|_|S|dd�}qn
t|j	�SdS)Nr�rrYF)r]r�r\r�rTrZrAr�r7r^r�r�r�r[)rbr�r�rcrcrd�__next__4s&
zRobustUnpacker.__next__)
rwr�r�r�rer_r�r`rar$rcrcrrdrUsrUc@sZeZdZdd�Zddd�Zd	d
�Zdd�Zd
d�Zdd�Zddd�Z	dd�Z
ddd�ZdS)�ArchiveCheckercCsd|_t�|_dS�NF)�error_foundr��possibly_supersededrrrcrcrdrePszArchiveChecker.__init__FNrr�c

CsPt�d�|duo t|||f�|_||_||_|��|jsLt�d�dS|�	|�|_
|rd|��tj
|jvr�t�d�d|_|��|_nnz"tj|tjjf|j
d�\|_}
WnJty�}z2t�d|�d|_|jtj
=|��|_WYd}~n
d}~00|j|||||d	�|��|j|	d
�|j�r6t�d�n
t�d�|j�pN|jS)
a�Perform a set of checks on 'repository'

        :param repair: enable repair mode, write updated or corrected data into repository
        :param archive: only check this archive
        :param first/last/sort_by: only check this number of first/last archives ordered by sort_by
        :param glob: only check archives matching this glob
        :param verify_data: integrity verification of data referenced by archives
        :param save_space: Repository.commit(save_space)
        z%Starting archive consistency check...NzJRepository contains no apparent data at all, cannot continue check/repair.FzRepository manifest not found!T)r�z$Repository manifest is corrupted: %s)rS�first�last�sort_by�glob)�
save_spacez3Archive consistency check complete, problems found.z6Archive consistency check complete, no problems found.)r�rMrS�	check_all�repairr��init_chunksr�r��make_keyr��verify_datar �MANIFEST_IDrd�rebuild_manifestr7rIZ	OperationZCHECK�IntegrityErrorBase�rebuild_refcounts�orphan_chunks_checkr�)rbr�rlrSrfrgrhrirorjr��excrcrcrd�checkTs:


"
 
zArchiveChecker.checkcCs`tt|j�dd�|_d}|jjt|d�}|s0q\|d}tdddd�}|D]}||j|<qJqdS)z8Fetch a list of all object keys from repository
        g�������?)ZusableN��limit�markerr	r��refcountrgrZ)rrr�r��listrSr)rbry�resultZ
init_entryr�rcrcrdrmszArchiveChecker.init_chunksc	Cs|d}|j��D]J\}}|d7}|dkr*qZ|�|�}zt||�WStyVYq0q|dkrhd}nd|}t|��dS)Nrri�z*make_key: repository has no chunks at all!z4make_key: failed to create the key (tried %d chunks))r��	iteritemsr�rrr)rbr�ZattemptZchunkidr��cdatar�rcrcrdrn�s
zArchiveChecker.make_keyc
Cs�t�d�t|j�}d}d}g}t|dddd�}d}|jjd|d�}|sL�q�|t|�7}|d	}|j�|�}tt	|��}	|	r4|�
�|	�d	�}
zt|�}Wn~t
jtf�y}z^d
|_|d7}t�dt|
�|�t|t�r�|�|
�|	�rtt	|	��}|j�|�}WYd}~qxd}~00|
tjk�r*dn|
}
z|j�|
|�Wqxt�y�}z6d
|_|d7}t�d
t|
�|�|�|
�WYd}~qxd}~00qxq4|��||k�r�t�d�t�d||�|�r�|j�rbt�d�|D]�}z2|j�|�}|tjk�r�dn|}
|j�|
|�Wn8t�yJ|j|=|j�|�t�dt|��Yn0t�dt|���q�n&t�d�|D]}t�dt|���qp|�r�tjntj}|d||�dS)Nz5Starting cryptographic data integrity verification...rzVerifying data %6.2f%%�{�G�z�?zcheck.verify_data�r�r��stepr��drwr	Trzchunk %s: %szchunk %s, integrity error: %szGRepo/Chunks index object count vs. segment files object count mismatch.z:Repo/Chunks index: %d objects != segment files: %d objectszmFound defect chunks. They will be deleted now, so affected files can get repaired now and maybe healed later.zchunk %s deleted.z0chunk %s not deleted, did not consistently fail.z}Found defect chunks. With --repair, they would get deleted, so affected files could get repaired then and maybe healed later.zchunk %s is defect.z`Finished cryptographic data integrity verification, verified %d chunks with %d integrity errors.)r�rMrr�r;r��scanr�r|�reversedr�r�r�rRr�rrrdr�r8rkrr rpr�r�r�rlr�r�r��debug)rbZchunks_count_indexZchunks_count_segments�errorsZ
defect_chunksr�ryZ	chunk_idsZchunk_data_iterZchunk_ids_revdr�Zencrypted_datar~Z	_chunk_id�integrity_errorZdefect_chunk�logrcrcrdro�s�

�


"$

�

�zArchiveChecker.verify_datacs6tdd�tD����fdd�}t�d�t|j|j�}dd�tD�}tt	|j
�dd	d
d�}|j
��D�]�\}}|��|j�
|�}z|j�||�}WnBty�}	z*t�d|	�d
|_WYd}	~	qdWYd}	~	n
d}	~	00t||�s�qdd|vsdd|vr�qdzt�|�}
Wntj�yYqdYn0||
�rdz|jj|dd�\}
}}Wndt�y�}zJ|
�
dd��dd�}
t�d|
|�t�d�d
|_WYd}~qdWYd}~n
d}~00t|
d�}
|
j}
t�d|
�|
|jv�rd}d|
|f}||jv�r�q�|d7}�q�t�d|
|�|}
||
jf|j|
<qd|��t�d�|S)z�Rebuild the manifest object if it is missing

        Iterates through all objects in the repository looking for archive metadata blocks.
        css|]}|��VqdSrf�rW�r�r�rcrcrdrR�r�z2ArchiveChecker.rebuild_manifest.<locals>.<genexpr>cs t|t�sdSt|�}��|�Src)rkr�r��issubset��obj�keys�Zrequired_archive_keysrcrd�
valid_archive�s
z6ArchiveChecker.rebuild_manifest.<locals>.valid_archivez9Rebuilding missing manifest, this might take some time...cSsg|]}t�|����qSrcrVrXrcrcrdr�r�z3ArchiveChecker.rebuild_manifest.<locals>.<listcomp>zRebuilding manifest %6.2f%%r�zcheck.rebuild_manifestr�zSkipping corrupted chunk: %sTNscmdlines	�versionFrNsnames	<unknown>�asciird�3Archive TAM authentication issue for archive %s: %szMThis archive will *not* be added to the rebuilt manifest! It will be deleted.r�zFound archive %srz%s.%dz(Duplicate archive name %s, storing as %szManifest rebuild complete.)�	frozensetZREQUIRED_ARCHIVE_KEYSr�rMr r�r�ZARCHIVE_KEYSr;rr�r~r�r�r�rrr�rdrTrAZunpackbr�rPr�decoderIr�rGr�r�r�)rbr�r7Zarchive_keys_serializedr�r�r�rr�rurS�verifiedr�r�rL�new_namercr�rdrq�sb
�"


"

zArchiveChecker.rebuild_manifestcs��j�tjd��fdd����fdd�}d+�fdd�	����fdd	�}��fd
d�}|dur�|�d�}t|||f�r�jjj||||d
�}	|r�|	s�t	�
d|�|r�t|	�|kr�t	�
d|t|	��|r�t|	�|kr�t	�
d|t|	��n�jjj|d�}	n<z�jj|g}	Wn(t�y2t	�
d|�d�_YdS0t|	�}
t|
dddd�}t�j�����t|	�D�]^\}}
|�|�t	�d|
j�d|d�d|
�d��|
j}|�jv�r�t	�
dt|��d�_�jj|
j=�qb�|��j�|�}z�j�||�}WnXt�yP}z>t	�
dt|�|�d�_�jj|
j=WYd}~�qbWYd}~n
d}~00z�jj|dd �\}}}Wn`t�y�}zFt	�
d!|
j|�t	�
d"�d�_�jj|
j=WYd}~�qbWYd}~n
d}~00t|d#�}|jdk�r�td$��d%d&�|j D�|_ t!�j�}||_"||�D]&}d'|v�r0||
j|�|�#|��q|j$dd(�|j%D]}�|��qP|j|_%�jj&|�'�d)|d*�}�j�(|�}�j�)|�}�|t|�t|�|�||
j*f�jj|
j<�qb|�+�Wd�n1�s�0YdS),z�Rebuild object reference counts by walking the metadata

        Missing and/or incorrect data is repaired when detected
        Ncs,�j�|tddd��jdkr(�j�|�dSrV)r�r�rr{rer�)r�rrrcrd�mark_as_possibly_supersededHszEArchiveChecker.rebuild_refcounts.<locals>.mark_as_possibly_supersededcs2�j�|�}�j�|�}�|t|�t|�|�|Srf)r�r"�encryptr)rr�r)�
add_referencerbrcrd�add_callbackLsz6ArchiveChecker.rebuild_refcounts.<locals>.add_callbackcs\z�j�|�WnFtyV|dus*J�td||d��j|<�jrR�j�||�Yn0dS)Nrrz)r�Zincrefr�rrlr�Zput)r�rgrZrrrrcrdr�Rsz7ArchiveChecker.rebuild_refcounts.<locals>.add_referencecsr�fdd�}d}g}d}d|v}|j}|r0|jn|}|rlt|�t|�krlt�|�d|j�d��|`d}|}t||�D�]n\}	}
|
\}}}
|�jv�r||	|
kr�t�d�||j|||t	|���d	�_
}||�\}}}
}�|||
|�n�t�d
�||j|||t	|���|	\}}}
|�jv�r0�|||
�nJt�d�||j|||t	|���d	�_
}||�\}}}
}�|||
|�nR|	|
k�r��|||
�n:t�d�||j|||t	|����|||
��|	d�|�|||
g�||7}qv|�r�|�s�|j|_|�r(||k�r(t�|�d|j�d
��|`||_d|v�rn|j
}|jdd	d�}||k�rnt�d�||j||��dS)aVerifies that all file chunks are present.

            Missing file chunks will be replaced with new chunks of the same length containing all zeros.
            If a previously missing file chunk re-appears, the replacement chunk is replaced by the correct one.
            cs@tdt|d�}t|�jj�\}}�j�|�}t|�}||||fS)N)rrg)rrrr�r"r�r)rgrr�r�rrZrrrcrd�replacement_chunkas
zWArchiveChecker.rebuild_refcounts.<locals>.verify_file_chunks.<locals>.replacement_chunkrFr�r�z*: Invalid chunks_healthy metadata removed!z^{}: {}: New missing file chunk detected (Byte {}-{}, Chunk {}). Replacing with all-zero chunk.Tz|{}: {}: Previously missing file chunk is still missing (Byte {}-{}, Chunk {}). It has an all-zero replacement chunk already.zm{}: {}: Missing all-zero replacement chunk detected (Byte {}-{}, Chunk {}). Generating new replacement chunk.zE{}: {}: Healed previously missing file chunk! (Byte {}-{}, Chunk {}).z,: Completely healed previously damaged file!rg)�
compressedr
z<{}: {}: size inconsistency detected: size {}, chunks size {}N)r�r�rr�r�r�r�r�rqr8rdrMrrgr)�archive_namer�r��offsetZ
chunk_listZchunks_replacedZhas_chunks_healthyZchunks_currentr�Z
chunk_currentZ
chunk_healthyr�rgrZrr�r�)r�r�rbrcrd�verify_file_chunks[sp
�
�
�

�



�z<ArchiveChecker.rebuild_refcounts.<locals>.verify_file_chunksc3s�tdd��jjD���tdd�tD���tdd��jj�}d���fdd�}�fd	d
�}dd�����fd
d�}d}t|j|�D�]B\}}t|�}|dr�|D]}|d||�|d7}q�q�|dkr�|��t	|��
|��D]�\}}	zX�j�||	�}
|�
|
�|D]6}||�\}}
|�r$t|d�Vn|d|
||��qWn~t�yp}z|t|�||�WYd}~nRd}~0tj�y�|d||�|��Yn"t�y�|d||��Yn0|d7}q�q�dS)z�Iterates through all archive items

            Missing item chunks will be skipped and the msgpack stream will be restarted
            css|]}|��VqdSrfr�r�rcrcrdrR�r�zLArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.<genexpr>css|]}|��VqdSrfr�r�rcrcrdrR�r�cSst|t�od|vS)Nspath)rkr7rkrcrcrdrl�r�zKArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.<lambda>rcs"�dt|�jv�kr�d7��S)N�r)r�r�)r�)�_staterbrcrd�missing_chunk_detector�szYArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.missing_chunk_detectorcs,t|�}|d||f7}d�_t�|�dS)Nz [chunk: %06d_%s]T)r8rdr�r�)r�r�Zchunk_nor�rrrcrd�report�szIArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.reportcSsd�dd�|D��S)Nz, css,|]$}t|t�r|jdd�nt|�VqdS)rd)r�N)rkrr�r�)r��krcrcrdrR�r�zdArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.list_keys_safe.<locals>.<genexpr>)r�)r�rcrcrd�list_keys_safe�szQArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.list_keys_safecsbt|t�sdS|�dd�t|�}��|�s@dd��|�fS|���s^dd�|��fSdS)N)Fznot a dictionarysaclFzmissing required keys: zinvalid keys: )Tr�)rkr7r�r�r�r�)rZr��required_item_keysrcrd�
valid_item�s


zMArchiveChecker.rebuild_refcounts.<locals>.robust_iterator.<locals>.valid_itemr�zitem metadata chunk missingrr�zDDid not get expected metadata dict when unpacking item metadata (%s)NzCUnpacker crashed while unpacking item metadata, trying to resync...z5Exception while decrypting or unpacking item metadata)r�r7rZZREQUIRED_ITEM_KEYSrUr	r�r|r_r�r�r�r�r�rHrr�rAr�rR)rSr�r�r�r�rL�stater�r�rr�r�Zvalid�reasonr�)r�rb)r�rZr�r�rd�robust_iterator�sL�


$z9ArchiveChecker.rebuild_refcounts.<locals>.robust_iterator�,)rhrirfrgz.--glob-archives %s does not match any archivesz+--first %d archives: only found %d archivesz*--last %d archives: only found %d archives)rhzArchive '%s' not found.TzChecking archives %3.1f%%g�������?zcheck.rebuild_refcountsr�zAnalyzing archive z (rr��)z%Archive metadata block %s is missing!z*Archive metadata block %s is corrupted: %sFrNr�zEThis archive will be *removed* from the manifest! It will be deleted.r�rOcSsg|]}t|��qSrcrVrWrcrcrdr�(r�z4ArchiveChecker.rebuild_refcounts.<locals>.<listcomp>r�rtru)rw�salt)N),r�r�r rpr�rSr7rGr|r�r�rr�r�rdr;rQr�r�r�rMr�rxr8r�r�r�rrPrIrQrRrYr�rr�r�r�rzr{r"r�r[r�)rbrSrfrgrhrir�r�r�Z
archive_infosZnum_archivesr�rLrMZ
archive_idrr�r�r�r�rFr�Zprevious_item_idZnew_archive_idrc)r�r�r�rbrdrs@s�	LH
�
$$
$



z ArchiveChecker.rebuild_refcountscCs�|jr�dd�|j��D�}||j}|rBt�t|��d��d|_|jr�|r�t�	dt|�t|j�f�|D]}|j
�|�qlt�	d�n
t�	d�dS)NcSsh|]\}}|jdkr|�qS)r)r{)r�r�r�rcrcrd�	<setcomp><r�z5ArchiveChecker.orphan_chunks_check.<locals>.<setcomp>z orphaned objects found!Tz1Deleting %d orphaned and %d superseded objects...z.Finished deleting orphaned/superseded objects.z<Orphaned objects check skipped (needs all archives checked).)rkr�r~rer�r�rrdrlrMr�r�)rbZunusedZorphanedr�rcrcrdrt:s

�z"ArchiveChecker.orphan_chunks_checkcCs8|jr4t�d�|j��t�d�|jjd|d�dS)NzWriting Manifest.zCommitting repo.F)rxrj)rlr�rMr7rr�r{)rbrjrcrcrdr�Js



zArchiveChecker.finish)FNrrr�NFF)Nrrr�N)F)rwr�r�rervrmrnrorqrsrtr�rcrcrcrdrbNs�
+QL
{rbc
@s�eZdZGdd�de�Zedd��Zd!dd	�Zd"d
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
d#dd�Zdd�Zd$dd�Zdd�Zdd �ZdS)%�ArchiveRecreaterc@seZdZddd�ZdS)zArchiveRecreater.InterruptedNcCs|pi|_dSrf)rT)rbrTrcrcrdreTsz%ArchiveRecreater.Interrupted.__init__)N)rwr�r�rercrcrcrd�InterruptedSsr�cCs
|�d�S)N�	.recreate)�endswith)r�rcrcrd�is_temporary_archiveWsz%ArchiveRecreater.is_temporary_archiveFNr3cCs�||_||_||_||_||_||_|p*g|_||_|	du|_|jrPt	�
d|	�|	pVt|_||_
||_|
pptd�|_t�|_||_|
|_||_||_|p�dd�|_|
r�dn||_dS)NzRechunking archives to %sZnonecWsdSrfrcrrcrcrdrlwr�z+ArchiveRecreater.__init__.<locals>.<lambda>)r�r�r7rr��exclude_caches�exclude_if_present�keep_exclude_tagsrr�r�r�r�
recompress�always_recompressr�compressionr��seen_chunksr|r�rnrJrr;)rbr�r7r�rr�r�r�r�rr�r�r�r�rnrJrr|r;rcrcrdre[s,


zArchiveRecreater.__init__cCs�|�|�rJ�|�|�}|�||�}|js0|jr:|�|�|j��rd|jsd|j	sd|durd|durddS|�
||�|du}|j||||d�dS)NF)�replace_originalT)r��open_archive�
create_targetr�r��matcher_add_tagged_dirsr��emptyr��recreate_rechunkify�
process_itemsrq)rbr�r9�target_namerS�targetr�rcrcrd�recreatezs(

�����zArchiveRecreater.recreatec
s|j}|����rind}�fdd�}|��D]�}|�|j�st|�d|j�||�r0|�d�|�d�df||j<q0�r�t|j�r�|�d�|vr�||j	\}}}	|	dur�||_
|dur�||_dd|jf||j	<|`	n|	|_	|jr�|�d|j�q0|�
|||�q0|j�r|jjdd	�dS)
Ncs"�o t|j�o |�dd�o d|vSr�r�rk�Ztarget_is_subsetrcrd�item_is_hardlink_master�s�
��z?ArchiveRecreater.process_items.<locals>.item_is_hardlink_master�xr�r�r��-T)r�)r�r�rmr�r�rr�r"r�r�r�r�r��process_itemrJrnr�)
rbrSr�r�r�r�r�r�r�Z
new_sourcercr�rdr��s0
zArchiveRecreater.process_itemscCsdt|j�}d|vrB|�||j�d}|�|||�|jjd7_|j||jd�|�||j�dS)Nr�rr)r1r�rr��process_chunksrnr\rp)rbrSr�r�r"rcrcrdr��s
zArchiveRecreater.process_itemc	Csr|js4|js4|jD]\}}}|j�||j�q|jS|�||t|j��}t|j	|�}|�
||j|j|j||�dSrf)r�r�r�rrrn�iter_chunksr|rrrrJ)	rbrSr�r�r�rgrZ�chunk_iteratorrrcrcrdr��szArchiveRecreater.process_chunkscCs�t||jj�\}}||jvr,|j�||j�S|j}|jr�|js�||jj	vr�|jj
d|j�|�dd�}t
�|�j|jj�|�jkr�d}|jj|||j|dd�}|jjjdd�|j�|j�|S)NF)�
decompress)�	overwriter r)rr�r"r�rrrnr�r�r�r�r�r�rZdetectr�Z
compressorZdecider!r#r�rx)rbr�rr�r�r�Z	old_chunkrrcrcrdr�s
z ArchiveRecreater.chunk_processorccsZ|j�dd�|D��}|jr8t|�}|j�|�EdHn|D]}t|t|�td�Vq<dS)NcSsg|]\}}}|�qSrcrc)r�r�r�rcrcrdr��r�z0ArchiveRecreater.iter_chunks.<locals>.<listcomp>)rgr)	rDr�r�r#rrrrr)rbrSr�r�r�r�rrcrcrdr��szArchiveRecreater.iter_chunksTcCs�|jr
dS|dur |j�dd�}|jr,|j}|jdur`|jj|j�d�pN|jj|jjtj	d�}n|jjtj	d�}|j
||j|d�|r�|jt�|j
d�|�|j�|jr�||_t�|_ttt|�tt|j�t|j�t�dS)Nr9r�r\)r�r\rY�recreate_cmdline)rYr�)r9r|r})rJ)r�rTr�rnrAr|r�rYr�rhrqr�rUrJr�r�rCr�r<ZDASHESr�r)rbrSr�r9r�Z_startr}rcrcrdrq�s:
�	��zArchiveRecreater.savec	s6���fdd�}�j�g�g�i}�jrd|jdd�d�D]*}t�|j�r8d|vr8d|vr8d||j<q8|j�fd	d�d�D]�}�jr�|j|vr�|||j<tj�	|j�\}}|�j
vr�|||�qx�jrx|tkrxt�|j�rxd|vr�|n||j}t||�}|�
tt��tkrx|||�qx���tj����tj�dS)
zLAdd excludes to the matcher created by exclude_cache and exclude_if_present.csH�jr2��t|jdd����t|ddd��n��t|dd��dS)NF)Zrecurse_dirr�)r�rrEr�rF)�dirZtag_item)rb�	tag_files�tagged_dirsrcrd�exclude
	sz9ArchiveRecreater.matcher_add_tagged_dirs.<locals>.excludecSstj�|j�tkSrf)r�r��basename�CACHE_TAG_NAMErkrcrcrdrl	r�z:ArchiveRecreater.matcher_add_tagged_dirs.<locals>.<lambda>r�r�r�Ncstj�|j�tkp��|j�Srf)r�r�r�r�r�rkr�rcrdrl$	r�)r�r�rmr�r�r�r�r�r�r�r�r�r%r�rZCACHE_TAG_CONTENTSr�rGZIncludeZExcludeNoRecurse)	rbrSr�Zcachedir_mastersr�r�Ztag_fileZcontent_itemr�rc)r�rbr�r�rdr�	s0
�



z(ArchiveRecreater.matcher_add_tagged_dirscCs�|p|jd}|�|�}|j�d�}|dur4t|�nd}|j}|joJ||k|_|jrft�	d|p`d|�t
|j|j|j
|j|j|jd�j|_t|j|jjdd��|_|S)	zCreate target archive.r�rNz Rechunking archive from %s to %sz	(unknown))rr�rprsr;rFr�)r��create_target_archiverTr�r$rrr�r�r�rrr�rprsr;rrr�r)rbrSr�r�Zsrc_cpZdst_cprcrcrdr�2	s
�
zArchiveRecreater.create_targetcCs,t|j|j|j|d|j|j|j|jd�	}|S)NT)rErJrrr;)r/r�r�r7rJrrr;)rbr�r�rcrcrdr�D	s
�z&ArchiveRecreater.create_target_archivecKs"t|j|j|j|fd|ji|��S)Nr)r/r�r�r7r)rbr��kwargsrcrcrdr�J	szArchiveRecreater.open_archive)
FNFNNFFFFFNNr3)NN)NT)N)rwr�r�rRr�r�r�rer�r�r�r�rr�rqr�r�r�r�rcrcrcrdr�Rs&
�

%
	
'*
r�)�r�r�Zsocketr�r�r��collectionsr�
contextlibrZdatetimerr�	functoolsrZgetpassr�ior�	itertoolsr	r
�shutilrZ
platformflagsr
rrrr�rr�rrrrrrZ
crypto.keyrr�compressrrZ	constantsZcrypto.low_levelrrrZ	hashindexrrrZhelpersr r"r#r$r%r&r'�platformr(r)r*r+r,r-r.r/r0r1r2r3r4r5r6r7r8r9r:r;r<r=r>r?r@rArBrCZlrucacherD�patternsrErFrGr�rHrIrJrKrLrMrNrOrPZremoterQr�rRrSr�r�rUr�rRr�r�r�r�r�r�r�r�r�rr.r/r�rrrrr>rTrUrbr�rcrcrcrd�<module>s� 
wD1
L=M892