o
    +ke}*                     @   sr  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ 	 dZe	edej
ZddlmZ dd	d
dZdd	ddZdd	ddZd0ddZd0ddZzd dlmZ d1ddZW n eyf   d1ddZY nw d1ddZdd Zdd ZG dd dZG d d! d!Zd"d# Zd2d%d&Ze ZeeZe d'd  Zej!"d(Z#e#se d)e$  Z#d*d+ Z%d,d- Z&d.d/ Z'dS )3    N)safe_unlink)is_win32z1.2_05	fdatasync   )ENOATTRF)follow_symlinksc                C   s   g S )a  
    Return xattr names of a file (list of bytes objects).

    *path* can either be a path (bytes) or an open file descriptor (int).
    *follow_symlinks* indicates whether symlinks should be followed
    and only applies when *path* is not an open file descriptor.
     )pathr   r   r   6usr/lib/python3.10/site-packages/borg/platform/base.py	listxattr   s   r   c                C   s   t ttt| )a:  
    Read xattr and return its value (as bytes).

    *path* can either be a path (bytes) or an open file descriptor (int).
    *name* is the name of the xattr to read (bytes).
    *follow_symlinks* indicates whether symlinks should be followed
    and only applies when *path* is not an open file descriptor.
    )OSErrorr   osstrerror)r	   namer   r   r   r
   getxattr'   s   r   c                C      dS )aP  
    Write xattr on *path*.

    *path* can either be a path (bytes) or an open file descriptor (int).
    *name* is the name of the xattr to read (bytes).
    *value* is the value to write (bytes).
    *follow_symlinks* indicates whether symlinks should be followed
    and only applies when *path* is not an open file descriptor.
    Nr   )r	   r   valuer   r   r   r
   setxattr5       r   c                 C   r   )zl
    Saves ACL Entries

    If `numeric_ids` is True the user/group field is not preserved only uid/gid
    Nr   )r	   itemstnumeric_idsfdr   r   r
   acl_getA   r   r   c                 C   r   )zz
    Restore ACL Entries

    If `numeric_ids` is True the stored uid/gid is used instead
    of the user/group names
    Nr   )r	   r   r   r   r   r   r
   acl_setI   r   r   lchflagsc                 C   s   t | | d S Nr   r	   Z	bsd_flagsr   r   r   r
   	set_flagsU   s   r   c                 C   s   d S r   r   r   r   r   r
   r   X      c                 C   s   t |ddS )zHReturn BSD-style file flags for path or stat without following symlinks.st_flagsr   )getattr)r	   r   r   r   r   r
   	get_flags\   s   r#   c              
   C   s   t rd S t| tj}z1zt| W n ty, } z|jtjkr" W Y d }~nd }~ww W t| d S W t| d S t| w r   )	r   r   openO_RDONLYfsyncr   errnoEINVALclose)r	   r   Zos_errorr   r   r
   sync_dira   s   r*   c                 C   sH   t tdr"ttd| }zt| ||| W d S  ty!   Y d S w d S )Nposix_fadviseZPOSIX_FADV_)hasattrr   r"   r+   r   )r   offsetlenZadvicer   r   r
   safe_fadviser   s   
r/   c                   @   sH   e Zd ZdZdddddZdd Zd	d
 Zdd Zdd Zdd Z	dS )SyncFilea(  
    A file class that is supposed to enable write ordering (one way or another) and data durability after close().

    The degree to which either is possible varies with operating system, file system and hardware.

    This fallback implements a naive and slow way of doing this. On some operating systems it can't actually
    guarantee any of the above, since fsync() doesn't guarantee it. Furthermore it may not be possible at all
    to satisfy the above guarantees on some hardware or operating systems. In these cases we hope that the thorough
    checksumming implemented catches any corrupted data due to misordered, delayed or partial writes.

    Note that POSIX doesn't specify *anything* about power failures (or similar failures). A system that
    routinely loses files or corrupts file on power loss is POSIX compliant.

    Calling SyncFile(path) for an existing path will raise FileExistsError, see comment in __init__.

    TODO: Use F_FULLSYNC on OSX.
    TODO: A Windows implementation should use CreateFile with FILE_FLAG_WRITE_THROUGH.
    NFr   binaryc                C   sJ   |rdnd}|| _ |du rt||d| _ntj||d| _| j | _dS )aJ  
        Open a SyncFile.

        :param path: full path/filename
        :param fd: additionally to path, it is possible to give an already open OS-level fd
               that corresponds to path (like from os.open(path, ...) or os.mkstemp(...))
        :param binary: whether to open in binary mode, default is False.
        xbxN)mode)r	   r$   fr   fdopenfilenor   )selfr	   r   r2   r5   r   r   r
   __init__   s   	zSyncFile.__init__c                 C   s   | S r   r   )r9   r   r   r
   	__enter__   r    zSyncFile.__enter__c                 C   s   |    d S r   )r)   )r9   exc_typeexc_valexc_tbr   r   r
   __exit__   s   zSyncFile.__exit__c                 C   s   | j | d S r   )r6   write)r9   datar   r   r
   r@      s   zSyncFile.writec                 C   s6   ddl m} | j  || j t| jddd dS )z
        Synchronize file contents. Everything written prior to sync() must become durable before anything written
        after sync().
           platformr   ZDONTNEEDN) rD   r6   flushr   r   r/   )r9   rD   r   r   r
   sync   s   
zSyncFile.syncc              	   C   sf   ddl m} d}ztj| j}|   W | j  |r#|| dS dS | j  |r2|| w w )zsync() and close.rB   rC   N)	rE   rD   r   r	   dirnamerG   r6   r)   r*   )r9   rD   rH   r   r   r
   r)      s   


zSyncFile.close)
__name__
__module____qualname____doc__r:   r;   r?   r@   rG   r)   r   r   r   r
   r0      s    r0   c                   @   s*   e Zd ZdZd
ddZdd Zdd Zd	S )SaveFilea  
    Update file contents atomically.

    Must be used as a context manager (defining the scope of the transaction).

    On a journaling file system the file contents are always updated
    atomically and won't become corrupted, even on power failures or
    crashes (for caveats see SyncFile).

    SaveFile can safely by used in parallel (e.g. by multiple processes) to write
    to the same target path. Whatever writer finishes last (executes the os.replace
    last) "wins" and has successfully written its content to the target path.
    Internally used temporary files are created in the target directory and are
    named <BASENAME>-<RANDOMCHARS>.tmp and cleaned up in normal and error conditions.
    Fc                 C   sB   || _ || _tj|| _tj|d | _d | _d | _d | _	d S )N-)
r2   r	   r   rH   dirbasename
tmp_prefixtmp_fd	tmp_fnamer6   )r9   r	   r2   r   r   r
   r:      s   
zSaveFile.__init__c                 C   sR   ddl m} ddlm} || jd| jdd\| _| _|j| j| j| j	d| _
| j
S )NrB   rC   )mkstemp_modez.tmpi  )prefixsuffixrO   r5   r1   )rE   rD   Z
helpers.fsrT   rQ   rO   rR   rS   r0   r2   r6   )r9   rD   rT   r   r   r
   r;      s
   zSaveFile.__enter__c              	   C   s   ddl m} | j  d | _|d urt| j d S z!z
t| j| j	 W n t
y1   t| j  w W || j d S || j w )NrB   rC   )rE   rD   r6   r)   rR   r   rS   r   replacer	   r   r*   rO   )r9   r<   r=   r>   rD   r   r   r
   r?      s   


zSaveFile.__exit__N)F)rI   rJ   rK   rL   r:   r;   r?   r   r   r   r
   rM      s
    
	rM   c                 C   s   t | S )z}terminal output width of string <s>

    For western scripts, this is just len(s), but for cjk glyphs, 2 cells are used.
    )r.   )sr   r   r
   swidth   s   rY   rE   c                 C   sr   |   } | r
| dkrt } zt| ddtjdtj}W n
 ty&   Y | S w |D ]}|d r6|d }  | S q)| S )zpGet fully qualified domain name from name.

    An empty argument is interpreted as meaning the local host.
    z0.0.0.0Nr      )stripsocketgethostnamegetaddrinfo
SOCK_DGRAMAI_CANONNAMEr   )r   addrsaddrr   r   r
   getfqdn  s    rc   .ZBORG_HOST_ID@c                  C   s   d} t  }t|| fS )z
    Return identification tuple (hostname, pid, thread_id) for 'us'.
    This always returns the current pid, which might be different from before, e.g. if daemonize() was used.

    Note: Currently thread_id is *always* zero.
    r   )r   getpidhostid)Z	thread_idpidr   r   r
   get_process_id(  s   
ri   c                 C      t )ze
    Check if the (host, pid, thread_id) combination corresponds to a potentially alive process.
    NotImplementedError)hostrh   threadr   r   r
   process_alive4  s   ro   c                 C   rj   )zReturn whether *pid* is alive.rk   )rh   r   r   r
   local_pid_alive;  s   rp   )FNr   )rE   )(r'   r   r\   uuidZborg.helpersr   Zborg.platformflagsr   ZAPI_VERSIONr"   r&   r   Zxattrr   r   r   r   r   r   r   r   ImportErrorr#   r*   r/   r0   rM   rY   rc   r]   hostnameZfqdnsplitenvirongetrg   Zgetnoderi   ro   rp   r   r   r   r
   <module>   sJ    

	
G2
	