
    J                        d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlZddl	Z	ddl
Z
ddlZddlZddlZddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ esddlZddlZej6                  reZdZdZdZ dZ!dZ"dZ#dZ$dZ% ejL                  d      Z'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0da1 e2       a3 G d de4      Z5 G d  d!e4      Z6d" Z7d# Z8	 d1d$Z9d% Z:d& Z;d' Z<e$e$e%fd(Z=	 	 d2d)Z>d* Z?d+ Z@d, ZAd- ZBd. ZCd/ ZDd0 ZEy)3zHelper file for POSIX methods.    )absolute_import)print_function)division)unicode_literals)timegmN)CommandException)UTC)CreateCustomMetadata) GetValueFromObjectCustomMetadata)
IS_WINDOWS)SECONDS_PER_DAYzgoog-reserved-file-atimezgoog-reserved-posix-gidzgoog-reserved-posix-modezgoog-reserved-file-mtimezgoog-reserved-posix-uidz
^[0-7]{3}$      @                      c                   "    e Zd ZdZeeeedfdZy)POSIXAttributesz1Class to hold POSIX attributes for a file/object.Nc                     || _         || _        || _        || _        t	        |r|      | _        yt
              | _        y)a6  Constructor for POSIXAttributes class which holds relevant data.

    Args:
      atime: The access time of the file/object.
      mtime: The modification time of the file/object.
      uid: The user ID that owns the file.
      gid: The group ID that the user is in.
      mode: An instance of POSIXMode.
    N)atimemtimeuidgid	POSIXModeNA_MODEmode)selfr   r   r   r   r!   s         )platform/gsutil/gslib/utils/posix_util.py__init__zPOSIXAttributes.__init__V   s7     DJDJDHDH$$4DIG4DI    )__name__
__module____qualname____doc__NA_TIMENA_IDr$    r%   r#   r   r   S   s    9 5r%   r   c                       e Zd Zd Zy)r   c                     || _         y )N)permissions)r"   r/   s     r#   r$   zPOSIXMode.__init__n   s
    "Dr%   N)r&   r'   r(   r$   r,   r%   r#   r   r   l   s    #r%   r   c                 0    t        t        |       dd       S )z7Converts a base-10 mode integer from os.stat to base-8.N)intoctr!   s    r#   ConvertModeToBase8r5   r   s     
SYrs^	r%   c                 v   t               }t        | t        t              \  }}	 t	        |      }|r|t        k  rt        d|       t        }n9|t	        t        j                               t        z   kD  rt        d|       t        }||_        t        | t        ||       t        | t        ||       t        | t        t               \  }}|r1t"        j%                  |      r	 t'        t)        |            |_        |S |S # t        $ r t        d|       t        }Y w xY w# t        $ r t        d|       Y |S w xY w)aA  Parses the POSIX attributes from the supplied metadata.

  Args:
    obj_metadata: The metadata for an object.
    url_str: File/object path that provides context if a warning is thrown.

  Returns:
    A POSIXAttribute object with the retrieved values or a default value for
    any attribute that could not be found.
  r   r!   )r   r   
ATIME_ATTRr*   longWarnNegativeAttributetimer   WarnFutureTimestamp
ValueErrorWarnInvalidValuer   DeserializeIDAttributeGID_ATTRUID_ATTR	MODE_ATTRr    
MODE_REGEXmatchr   r2   r!   )obj_metadataurl_strposix_attrsfoundr   r!   s         r#   +DeserializeFileAttributesFromObjectMetadatarH   y   s     !+1,
29;,%
KE'!GW-e	diik"_4	4'7+e +x+Fx+F0y18:+%
z%("3t9-k 
! 
 Wg&E  (vw'	(s$   A"C> !D >DDD87D8c                    | j                   t        k7  rt        t        | j                   i|       |r| j                  t        k7  rt        t
        | j                  i|       | j                  t        k7  rt        t        | j                  i|       | j                  t        k7  rt        t        | j                  i|       | j                  j                  t        k7  r(t        t        | j                  j                  i|       yyy)a+  Takes a POSIXAttributes object and serializes it into custom metadata.

  Args:
    posix_attrs: A POSIXAttributes object.
    custom_metadata: A custom metadata object to serialize values into.
    preserve_posix: Whether or not to preserve POSIX attributes other than
                    mtime.
  )entriescustom_metadataN)r   r*   r
   
MTIME_ATTRr   r7   r   r+   r@   r   r?   r!   r/   r    rA   )rF   rK   preserve_posixs      r#   'SerializeFileAttributesToObjectMetadatarN      s     '!*k.?.?!@)8: G#J0A0A#B+:<%Hkoo#>+:<%Hkoo#>+:<##w.I{/?/?/K/K#L+:< / r%   c                    |j                  d      d   }t        | |t              \  }}	 t        |      }|r|t        k  rt	        ||       t        }t        |||       y# t
        $ r t        ||       t        }Y +w xY w)a  Parses the POSIX attributes from the supplied metadata into posix_attrs.

  Args:
    obj_metadata: The metadata for an object.
    attr: Either GID_ATTR or UID_ATTR.
    url_str: File/object path that provides context if a warning is thrown.
    posix_attrs: POSIXAttribute object.
  -r   N)splitr   r+   r2   r9   r<   r=   setattr)rD   attrrE   rF   	attr_namerG   vals          r#   r>   r>      s|     jjob!)/dEJ*%
c(CIw/c 
+y#& 
 Y(
Cs   (A   A>=A>c
                    t               }
| t        kD  }|t        kD  }|t        kD  }|t        kD  }|t        kD  }|t        kD  }|t        kD  }|t        kD  }|t        kD  }|	t        kD  }|r	|s| |
_        |r	|s||
_        |r	|s||
_        |r	|s||
_        |r|s||
j                  _	        |
|xr | xs" |xr | xs |xr | xs |xr | xs |xr | fS )a;  Checks whether an update for any POSIX attribute is needed.

  Args:
    src_atime: The source access time.
    dst_atime: The destination access time.
    src_mtime: The source modification time.
    dst_mtime: The destination modification time.
    src_uid: The source user ID.
    dst_uid: The destination user ID.
    src_gid: The source group ID.
    dst_gid: The destination group ID.
    src_mode: The source mode.
    dst_mode: The destination mode.

  Returns:
    A tuple containing a POSIXAttribute object and a boolean for whether an
    update was needed.
  )
r   r*   r+   r    r   r   r   r   r!   r/   )	src_atime	dst_atime	src_mtime	dst_mtimesrc_uiddst_uidsrc_giddst_gidsrc_modedst_moderF   has_src_atimehas_dst_atimehas_src_mtimehas_dst_mtimehas_src_uidhas_dst_uidhas_src_gidhas_dst_gidhas_src_modehas_dst_modes                        r#   NeedsPOSIXAttributeUpdaterk      s
   *  !+g%-g%-g%-g%-%+%+%+%+G#,G#,=!K=!KKOKO,#+K 	;m*; ;%;m*;;#7K; $7K; %9\)9	
< <r%   c                     t         j                  t        |       dd       xr | t        z  xs | t        z  xs	 | t
        z  S )zValidates whether the mode is valid.

  In order for the mode to be valid either the user, group, or other byte must
  be >= 4.

  Args:
    mode: The mode as a 3-digit, base-8 integer.

  Returns:
    True/False
  r1   N)rB   rC   r3   U_RG_RO_Rr4   s    r#   ValidatePOSIXModerp   	  sC     
		#d)BC.	) 
;tcz 0:TCZ 0:/3cz;r%   c                    t         ry|t        kD  }t        |      t        kD  }|t        kD  }|s|s|syt	        j
                         dk(  ryt        t        t        |      d            }|r	|sdd| z  fS t        t              }|r	 t        j                  |       |r	 t        j                  |       |t	        j                         k(  }t        t        |      d      }|s,|r*|r(t!        |t"        z        sdd| |t%        |      d	d
 fz  fS |r-t!        |t"        z        }	|	|	rdfS d| |t%        |      d	d
 fz  fS t        |      t&        v r-t!        |t(        z        }	|	|	rdfS d| |t%        |      d	d
 fz  fS |t*        z  ry|s|s|rydd| z  fS # t        t        f$ r dd| |fz  fcY S w xY w# t        t        f$ r dd| |fz  fcY S w xY w)a  Validates that the user has file access if uid, gid, and mode are applied.

  Args:
    url_str: The path to the object for which this is validating.
    uid: A POSIX user ID.
    gid: A POSIX group ID.
    mode: A 3-digit, number representing POSIX permissions, must be in base-8.

  Returns:
    A (bool, str) tuple, True if and only if it's safe to copy the file, and a
    string containing details for the error.
  )T r   r   Fz$Mode for %s won't allow read access.z3UID for %s doesn't exist on current system. uid: %dz3GID for %s doesn't exist on current system. gid: %dz?Insufficient access with uid/gid/mode for %s, gid: %d, mode: %sr1   Nrr   z?Insufficient access with uid/gid/mode for %s, uid: %d, mode: %sz"There was a problem validating %s.)r   r+   r2   r    osgeteuidrp   strSYSTEM_POSIX_MODEpwdgetpwuidKeyErrorOverflowErrorgrpgetgrgidgetuidboolrm   r3   USER_GROUPSrn   ro   )
rE   r   r   r!   uid_presentgid_presentmode_present
mode_validuid_is_current_uservalids
             r#   ValidateFilePermissionAccessr     s8    e+C5 +,
 ZZ\Q SY!23*;gEEE  !D	ll3 	ll3 ryy{* 
SY	$ 
d4#:>N !3D	"#78 9 9E2 9 9!3D	"#789 9 3x;E2 9 9!3D	"#789 9 cz{z	4w>	>>S m$ Kn   m$ Kn  s$   F F0 F-,F-0G
Gc                    |t        d| z        	 t        |t        t              \  }}t        |t        t              \  }}t        |t
        t              \  }}	t        |t        t              \  }
}t        |t        t              \  }}|rEt        |      }|sgt        j                  |       j                  }t        j                  | ||f       y|r-t        |j                         }t        j                  | ||f       |sy|rt        |      }|t        kD  r"|t        kD  rt        j                  | ||f       n|t        kD  rA|t        k  r8t        j                  |       j"                  }t        j                  | ||f       nI|t        k  r@|t        kD  r7t        j                  |       j                  }t        j                  | ||f       t$        ry|r#t        j&                         dk(  rt)        |	      }	nt        }	|
rt)        |      }|	t        kD  r!|t        kD  rt        j*                  | |	|       nS|	t        kD  r!|t        k  rt        j*                  | |	d       n)|	t        k  r |t        kD  rt        j*                  | d|       |r,t)        t-        |      d      }t        j.                  | |       yy# t0        $ r t        d|j2                  z        w xY w)a  Parses POSIX attributes from obj_metadata and sets them.

  Attributes will only be set if they exist in custom metadata. This function
  should only be called after ValidateFilePermissionAccess has been called for
  the specific file/object so as not to orphan files.

  Args:
    path: The local filesystem path for the file. Valid metadata attributes will
          be set for the file located at path, some attributes will only be set
          if preserve_posix is set to True.
    obj_metadata: The metadata for the file/object.
    is_rsync: Whether or not the caller is the rsync command. Used to determine
              if timeCreated should be used.
    preserve_posix: Whether or not all POSIX attributes should be set.
  Nz"obj_metadata cannot be None for %s)default_valuer   r   r   z#Check POSIX attribute values for %s)r   r   r7   r*   rL   r@   r+   r?   rA   r    r8   rs   statst_atimeutimeConvertDatetimeToPOSIXtimeCreatedst_mtimer   rt   r2   chownru   chmodr<   name)pathrD   is_rsyncrM   found_atr   found_mtr   	found_uidr   	found_gidr   
found_moder!   	atime_tmp	mtime_tmps                   r#   ParseAndSetPOSIXAttributesr   o  su   &  ?$F
GGE.6|7AELNOHe 7|7AELNOHe 6l6>DIKNIs 6l6>DIKNIs 88AFMOJ 5keGGDM**	
	5)*	$\%=%=>ehhteU^$5kew57?hhteU^$	Ug-''$-((ihhteY'(	'	ego''$-((ihhti'( RZZ\Q&HccHc
U{sU{hhtS#	uhhtS"	#+hhtRTAdhhtT  
 .
@',,- . ..s    CJ> 1J> CJ> C"J> >"K c                 N    t        j                         j                  d||        y)zLogs if an attribute has a negative value.

  Args:
    attr_name: The name of the attribute to log.
    url_str: The path of the file for context.
  z$%s has a negative %s in its metadataNlogging	getLoggerwarnrT   rE   s     r#   r9   r9     #     
A7$&r%   c                 N    t        j                         j                  d||        y)Logs if an attribute has an invalid value.

  Args:
    attr_name: The name of the attribute to log.
    url_str: The path of the file for context.
  z$%s has an invalid %s in its metadataNr   r   s     r#   r=   r=     r   r%   c                 N    t        j                         j                  d||        y)r   z5%s has an %s more than 1 day from current system timeNr   r   s     r#   r;   r;     s%     
	#r%   c                 v    t        t        | j                  t                     j	                                     S )a  Converts a datetime object to UTC and formats as POSIX.

  Sanitize the timestamp returned in dt, and put it in UTC format. For more
  information see the UTC class.

  Args:
    dt: A Python datetime object.

  Returns:
    A POSIX timestamp according to UTC.
  )tzinfo)r8   r   replacer	   	timetuple)dts    r#   r   r     s*     
fRZZsuZ-779:	;;r%   c                      t         rdayd} t        j                  d      }t        j                  |       | |z
  }t	        |dz        dd ay)z.Records the default POSIX mode using os.umask.666Ni     i  r1   )r   rv   rs   umaskr3   )max_permissionscurrent_umaskr!   s      r#   InitializeDefaultModer     sR     
 /((5/-((=	=	($ $,',r%   c                  L   t         ryt        j                         } t        j                  |       j
                  }t        t        j                  |       j                  gt        j                         D cg c]  }||j                  v s|j                   c}z         ayc c}w )zInitializes the set of groups that the user is in.

  Should only be called if the flag for preserving POSIX attributes is set.
  N)r   rs   r}   rw   rx   pw_namesetpw_gidr{   getgrallgr_memgr_gidr   )user_id	user_namegs      r#   InitializeUserGroupsr     s|     
IIK'll7#++)
||G##$AA9+@qxxABC+ Bs   5B!
	B!
c                  ,    t                t                y)z<Initializes POSIX data. Run once at the beginning of a copy.N)r   r   r,   r%   r#   InitializePreservePosixDatar   "  s    r%   )F)FF)Fr)   
__future__r   r   r   r   calendarr   getpassr   rs   rer:   sixgslib.exceptionr   gslib.tz_utcr	   gslib.utils.metadata_utilr
   r   gslib.utils.system_utilr   gslib.utils.unit_utilr   r{   rw   PY3r2   r8   r7   r?   rA   rL   r@   r*   r+   r    compilerB   rm   U_WU_Xrn   G_WG_Xro   O_WO_Xrv   r   r   objectr   r   r5   rH   rN   r>   rk   rp   r   r   r9   r=   r;   r   r   r   r   r,   r%   r#   <module>r      sQ   % & %  '    	 	  
 ,  : F . 1 77	$ (
$&	'
$


RZZ%
     e5f 52# #'X <A<>',.<b;  /4W S?p )..3\.~&&	#<-$C"r%   