
OcIc           @   s  d  Z  d d k l Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d e	 f d     YZ
 d   Z d   Z d   Z d	   Z d
 d d     YZ e i e  d d d     YZ e i e  d d d     YZ d d d     YZ d e i f d     YZ d d d     YZ d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k Z d d k  Z  d d k! Z! d d k" Z" d d k# Z# d S(   s,   Read increment files and restore to originali(   t
   generatorsNt   RestoreErrorc           B   s   e  Z RS(    (   t   __name__t
   __module__(    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR      s    c         C   sw   |  i  i i } | i  i i } | i |  | i |  |  | i |  } | i |  } | i | |  | i	   d S(   s?   Recursively restore mirror and inc_rpath to target at rest_timeN(
   t   connt   restoret   MirrorStructt   TargetStructt   set_mirror_and_rest_timest   initialize_rf_cachet   get_initial_itert	   get_diffst   patcht   close_rf_cache(   t	   mirror_rpt	   inc_rpatht   targett   restore_to_timet   MirrorSt   TargetSt   target_itert	   diff_iter(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   Restore   s    c   	      C   s   |  i    \ } } t i o t i |  } n |  i |  i | d  } | i   p g  Sn |  i } g  } xo | i	   D]a } t
 i |  } | oE | d | j o4 | i |  } | i   p t  | i |  qx qx W| S(   s"   Returns increments with given basei   (    (   t   dirsplitt   Globalst   chars_to_quotet   FilenameMappingt   unquotet	   __class__R   t   isdirt   indext   listdirt   rpatht   get_incfile_infot   appendt	   isincfilet   AssertionError(	   R   t   dirnamet   basenamet
   parent_dirR   t   inc_listt   filenamet   inc_infot   inc(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   get_inclist(   s     
  	 c   
      c   s  |  i  t i j p
 t d  t i |  t i |  |  t i t i d  } t i t i	 d  } t
 i | |  } x | D] \ } } | p
 d } n, | p
 d } n | | j o q} n d } | o | i   p
 | i   }	 t i d | |	 f f  Vq} Wt i   d S(   s2  List the changed files under mirror_rp since rest time

	Notice the output is an iterator of RORPs.  We do this because we
	want to give the remote connection the data in buffered
	increments, and this is done automatically for rorp iterators.
	Encode the lines in the first element of the rorp's index.

	s   Run locally onlyi   t   newt   deletedt   changeds   %-7s %sN(   R   R   t   local_connectionR$   R   R   R	   t   get_mirror_rorp_itert
   _rest_timet   _mirror_timet   rorpitert   Collate2Iterst   get_indexpathR    t   RORPathR   (
   R   t   inc_rpR   t   old_itert   cur_itert   collatedt   old_rorpt   cur_rorpt   changet	   path_desc(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   ListChangedSince9   s&    	  
 
 c         c   s`   |  i  t i j p
 t d  t i |  t i |  |  t i   } x | D] } | VqM Wd S(   su   List the files in archive at the given time

	Output is a RORP Iterator with info in index.  See ListChangedSince.

	s   Run locally onlyN(   R   R   R0   R$   R   R   R	   R1   (   R   R8   t   timeR9   t   rorp(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt
   ListAtTimeS   s      R   c           B   s   e  Z d  Z d Z d Z d Z d   Z d   Z d   Z	 d d  Z
 d   Z d   Z d d d  Z d   Z d	   Z d
   Z d   Z d   Z d   Z RS(   s+   Hold functions to be run on the mirror sidec         C   s%   |  i    t _ |  i |  t _ d S(   s>   Set class variabels _mirror_time and _rest_time on mirror connN(   t   get_mirror_timeR   R3   t   get_rest_timeR2   (   t   clsR   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR   i   s    c         C   sh   t  t i i d   } | p t i i d  n( t |  d j o t i d d  n | d i   S(   s)   Return time (in seconds) of latest mirrort   current_mirrors$   Could not get time of current mirrori   s5   Warning, two different times for current mirror foundi   i    (	   R,   R   t   rbdirR"   t   logt   Logt
   FatalErrort   lent
   getinctime(   RF   t   cur_mirror_incs(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRD   n   s    c            sG   |  i    } t   f d   |  } | o t |  Sn t |  Sd S(   s  Return older time, if restore_to_time is in between two inc times

		There is a slightly tricky reason for doing this: The rest of the
		code just ignores increments that are older than restore_to_time.
		But sometimes we want to consider the very next increment older
		than rest time, because rest_time will be between two increments,
		and what was actually on the mirror side will correspond to the
		older one.

		So if restore_to_time is inbetween two increments, return the
		older one.

		c            s
   |    j S(    (    (   RA   (   R   (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   <lambda>   s    N(   t   get_increment_timest   filtert   maxt   min(   RF   R   t   inctimest   older_times(    (   R   s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRE   w   s
     c         C   s   |  i  p h  d |  i   <} n h  d |  i  <} | p | i o t i i d  } n x$ t |  D] } d | | i   <qk Wx0 t t i i d   D] } d | | i   <q W| i	   } | i
   | S(   s   Return list of times of backups, including current mirror

		Take the total list of times from the increments.<time>.dir
		file and the mirror_metadata file.  Sorted ascending.

		t
   incrementst   mirror_metadataN(   R3   t   NoneRD   R   R   RH   R"   R,   RM   t   keyst   sort(   RF   t   rpt   dR+   t   return_list(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRP      s    
     
c         C   sS   t  |  } t | | t  |   } | | |  _ |  _ | |  _ t |  |  _ d S(   s#   Set cls.rf_cache to CachedRF objectN(   R,   t   RestoreFilet   mirror_baset   inc_baset   root_rft   CachedRFt   rf_cache(   RF   R_   R`   R(   t   rf(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR	      s
    	c         C   s   |  i  i   d S(   s)   Run anything remaining on CachedRF objectN(   Rc   t   close(   RF   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR      s    c         C   s   | d j o |  i } n t i   t i i | |  i i  } | pA | o t i	 i
 d  n t i	 d d  |  i |  i  } n |  i o t i |  i |  } n | S(   s  Return iter of mirror rps at given restore time

		Usually we can use the metadata file, but if this is
		unavailable, we may have to build it from scratch.

		If the cls._select object is set, use it to filter out the
		unwanted files from the metadata_iter.

		s   Mirror metadata not founds:   Warning: Mirror metadata not found, reading from directoryi   N(   RX   R2   t   metadatat
   SetManagert
   ManagerObjt	   GetAtTimeR_   R   RI   RJ   RK   t   get_rorp_iter_from_rfRa   t   _selectt	   selectiont
   FilterIter(   RF   t	   rest_timet   require_metadatat	   rorp_iter(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR1      s    
 
	
c         G   s:   | p
 t  d  t i |  |  _ |  i i | |  d S(   s&   Initialize the mirror selection objects+   If no selection options, don't use selectorN(   R$   Rl   t   SelectRk   t	   ParseArgs(   RF   t	   target_rpt   select_optst	   filelists(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   set_mirror_select   s    c         c   s\   | i    } | V| i   o: x7 | i   D]% } x |  i |  D] } | VqA Wq+ Wn d S(   s&   Recursively yield mirror rorps from rfN(   t   get_attribsR   t   yield_sub_rfsRj   (   RF   Rd   RB   t   sub_rft   attribs(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRj      s      c            s.     d j o  Sn    f d   } |   S(   s   Subtract index from index of each rorp in rorp_iter

		subtract_indicies and add_indicies are necessary because we
		may not be restoring from the root index.

		c          3   s]   xV  D]N }  |  i  t       j p t |  i    f  |  i  t    |  _  |  Vq Wd  S(   N(   R   RL   R$   (   RB   (   R   Rp   (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   get_iter   s
     -(    (    (   RF   R   Rp   R{   (    (   R   Rp   s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   subtract_indicies   s     c         C   s=   |  i  |  i i |  i    } t i | |  } |  i |  S(   s   Given rorp iter of target files, return diffs

		Here the target_iter doesn't contain any actual data, just
		attribute listings.  Thus any diffs we generate will be
		snapshots.

		(   R|   R_   R   R1   R4   R5   t   get_diffs_from_collated(   RF   R   t   mir_iterR;   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR      s    c         c   s   x | D] \ } } t  i o | o t i | |  n | p4 | p, | | j p t  i o* t i | |  o |  i | |  } n d } t  i o | o t i |  n | o	 | Vq q Wd S(   s   Get diff iterator from collatedN(   R   t   preserve_hardlinkst   Hardlinkt   add_rorpt   rorp_eqt   get_diffRX   t   del_rorp(   RF   R;   t   mir_rorpt   target_rorpt   diff(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR}      s     
 c         C   s   | p t  i | i  } n t i o* t i |  o | i t i |   nP | i	   oB |  i
 i | i } |  i i | |  } | i t i |   n | i d  | S(   s   Get a diff for mir_rorp at timet   snapshot(   R    R7   R   R   R   R   t   islinkedt
   flaglinkedt   get_link_indext   isregR_   Rc   t   get_fpt   setfilet   hasht   FileWrappert   set_attached_filetype(   RF   R   R   t   expanded_indext   file_fp(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR      s     N(   R   R   t   __doc__RX   Rk   R3   R2   R   RD   RE   RP   R	   R   R1   Rv   Rj   R|   R   R}   R   (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR   `   s"   												R   c           B   s/   e  Z d  Z d Z d   Z d   Z d   Z RS(   s:   Hold functions to be run on the target side when restoringc         G   s6   t  i |  |  _ |  i i | |  |  i i   d S(   s:   Return a selection object iterating the rorpaths in targetN(   Rl   Rq   Rk   Rr   t   set_iter(   RF   R   Rt   Ru   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   set_target_select  s    c         C   s   |  i  p t i |  i   S(   s4   Return selector previously set with set_initial_iter(   Rk   Rl   Rq   R   (   RF   R   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR
     s    c         C   st   t  i t | g  } xD t  i | |  D]0 } t i d | i   d  | | i |  q( W| i   | i	   d S(   s  Patch target with the diffs from the mirror side

		This function and the associated ITRB is similar to the
		patching code in backup.py, but they have different error
		correction requirements, so it seemed easier to just repeat it
		all in this module.

		s   Processing changed file i   N(
   R4   t   IterTreeReducert	   PatchITRBt
   FillInIterRI   RJ   R6   R   t   Finisht   setdata(   RF   R   R   t   ITRR   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s    	 
N(   R   R   R   RX   Rk   R   R
   R   (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s
   		Rb   c           B   sJ   e  Z d  Z d   Z d   Z d d  Z d   Z d d  Z d   Z	 RS(   s  Store RestoreFile objects until they are needed

	The code above would like to pretend it has random access to RFs,
	making one for a particular index at will.  However, in general
	this involves listing and filtering a directory, which can get
	expensive.

	Thus, when a CachedRF retrieves an RestoreFile, it creates all the
	RFs of that directory at the same time, and doesn't have to
	recalculate.  It assumes the indicies will be in order, so the
	cache is deleted if a later index is requested.

	c         C   s<   | |  _  g  |  _ t i d j o t | i  |  _ n d S(   s*   Initialize CachedRF, self.rf_list variablei    N(   Ra   t   rf_listR   t   process_uidt   PermissionChangerR   t   perm_changer(   t   selfRa   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   __init__:  s    		c         C   s_   d | f } d i  g  } |  i D] } | t | i  q! ~  } d } d i  | | | f  S(   s=   Used for debugging, return indicies of cache rfs for printings!   -------- Cached RF for %s -------t    s   --------------------------s   
(   t   joinR   t   strR   (   R   R   t   s1t   _[1]Rd   t   s2t   s3(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   list_rfs_in_cacheA  s    6c         C   s   x |  i  p |  i | |  p d Sq, n |  i  d } | i | j o, t i d j o |  i | |  n | Sq | i | j o8 | d  | i d  j p |  i | |  o d Sq q |  i  d =q d S(   s*   Get a RestoreFile for given index, or Nonei    iN(   R   t   add_rfsRX   R   R   R   R   (   R   R   R   Rd   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   get_rfH  s    
   c         C   sw   t  i |  i | |  | |  i i  } | p? t i d | o d i |  p d f d  t i	 d  Sn | i
   S(   s3   Return the file object (for reading) of given indexsg   Error: Unable to retrieve data for file %s!
The cause is probably data loss from the backup repository.t   /t   .i   t    (   t   longnamet	   update_rfR   Ra   R   RI   RJ   R   t	   cStringIOt   StringIOt   get_restore_fp(   R   R   R   Rd   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR   Y  s    	%c         C   s   | p |  i  Sn | i   o d Sn | d  } t i d j o |  i |  n t |  i  i i |  |  i  i i |  g   } t	 | i
    } | p d Sn | |  i d d +d S(   s   Given index, add the rfs in that same directory

		Returns false if no rfs are available, which usually indicates
		an error.

		Nii    i   (   Ra   t   has_alt_mirror_nameR   R   R   R^   R   t	   new_indexR8   t   listRx   R   (   R   R   R   t   parent_indext   temp_rft   new_rfs(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR   d  s      
  c         C   s%   t  i d j o |  i i   n d S(   s)   Finish remaining rps in PermissionChangeri    N(   R   R   R   t   finish(   R   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRe   v  s     N(
   R   R   R   R   R   RX   R   R   R   Re   (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRb   ,  s   			R^   c           B   sh   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z RS(   s   Hold data about a single mirror file and its related increments

	self.relevant_incs will be set to a list of increments that matter
	for restoring a regular file.  If the patches are to mirror_rp, it
	will be the first element in self.relevant.incs

	c         C   s6   | i  |  _  | |  _ | | |  _ |  _ |  i   d  S(   N(   R   R   R8   R(   t   set_relevant_incs(   R   R   R8   R(   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s    	c         C   s}   d d i  |  i  f g } | i g  } |  i D]) } | d | i   | i   | i f q0 ~  | i d  d i  |  S(   s<   Return printable string of relevant incs, used for debuggings   ---- Relevant incs for %sR   s   %s %s %ss    --------------------------------s   
(   R   R   t   extendt   relevant_incst
   getinctypet   lstatt   pathR"   (   R   t   lR   R+   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   relevant_incs_string  s
    :c         C   s   d |  i  _ d |  i  _ |  i p t i t i j o |  i  g |  _ d Sn |  i   } d } x> | t	 |  j  o* | | i
   d j o Pn | d } qb W| | d  |  _ |  i p |  i d i
   d j o |  i i |  i   n |  i i   d S(   s   Set self.relevant_incs to increments that matter for restoring

		relevant_incs is sorted newest first.  If mirror_rp matters,
		it will be (first) in relevant_incs.

		R   i    NR   i   i(   R   t   inc_typet   inc_compressedR(   R   R2   R3   R   t   get_newer_incsRL   R   R"   t   reverse(   R   t
   newer_incst   i(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s$      c         C   sz   g  } xD |  i  D]9 } | i   } | t i j o | i | | f  q q W| i   g  } | D] } | | d qb ~ S(   s   Return list of newer incs sorted by time (increasing)

		Also discard increments older than rest_time (rest_time we are
		assuming is the exact time rdiff-backup was run, so no need to
		consider the next oldest increment or any of that)

		i   (   R(   RM   R   R2   R"   RZ   (   R   t   incpairsR+   RA   R   t   pair(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s    
  
c         C   st   |  i  d } | i   d j o t i |  i  Sn | i   } |  i | _ | i   d j o d | i d <n | S(   s   Return RORP with restored attributes, but no data

		This should only be necessary if the metadata file is lost for
		some reason.  Otherwise the file provides all data.  The size
		will be wrong here, because the attribs may be taken from
		diff.

		it   missingt   dirt   type(   R   R   R    R7   R   t
   getRORPatht   data(   R   t   last_incRB   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRw     s    	  c            s     f d   }   f d   }   i  d i   pA t i d   i i     i  d i   f d  t i d  Sn t	 i
 | |  S(   s#   Return file object of restored datac             s     i    }  x   i d D] } t i d | i   f d  | i   d j p t  | i d | i    } t	 i
   } t i |  | |  | i d  | }  q W|  S(   Ni   s   Applying patch %si   R   t   rbi    (   t   get_first_fpR   RI   RJ   R6   R   R$   t   opent   isinccompressedt   tempfilet   TemporaryFilet   Rdifft   write_patched_fpt   seek(   t
   current_fpt   inc_difft   delta_fpt   new_fp(   R   (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s     
c            s*   t  i d   i i f d  t i d  S(   Ns*   Error reading %s, substituting empty file.i   R   (   RI   RJ   R   R   R   R   (   t   exc(   R   (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   error_handler  s    	isf  Warning: Could not restore file %s!

A regular file was indicated by the metadata, but could not be
constructed from existing increments because last increment had type
%s.  Instead of the actual file's data, an empty length file will be
created.  This error is probably caused by data loss in the
rdiff-backup destination directory, or a bug in rdiff-backupi   R   (   R   R   RI   RJ   R   R6   R   R   R   t   robustt   check_common_error(   R   R   R   (    (   R   s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s    'c         C   s   |  i  d } | i   d j p t  | i   p | i d  Sn t i   } | i d d d } t i | |  | i	   p t  | i
 d  | S(   s/   Return first file object from relevant inc listi    R   R   t   compressi   (   R   R   R$   R   R   R   R   R    t   copyfileobjRe   R   (   R   t	   first_incR   t   fp(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s     c         c   s!  |  i  i   o |  i i   o d Sn |  i  i   o |  i |  i   } n t g   } |  i i   o |  i |  i  } n t g   } t i | |  } xz | D]r \ } } | p |  i i | i	  } g  } n | \ } } | p |  i  i
 | i	  } n |  i | | |  Vq Wd S(   s<   Return RestoreFiles under current RestoreFile (which is dir)N(   R   R   R8   t   yield_mirrorrpst   itert   yield_inc_complexesR4   R5   R   R   t   new_index_emptyR   (   R   t   mirror_itert   inc_pair_iterR;   R   t   inc_pairR8   R(   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyRx     s$    "  
c         c   sZ   | i    p t  x? t i |  D]. } | i |  } | i d j o	 | Vq$ q$ Wd S(   s)   Yield mirrorrps underneath given mirrorrps   rdiff-backup-dataN(   s   rdiff-backup-data(   R   R$   R   t   listrpR"   R   (   R   t   mirrorrpR)   R[   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s      c         #   s     i    p d Sn   f d   }   f d   } |   } | i   xC | D]; \ } }   i |  } t i | i | | |  f  VqM Wd S(   s   Yield (sub_inc_rpath, inc_list) IndexedTuples from given inc_rpath

		Finds pairs under directory inc_rpath.  sub_inc_rpath will just be
		the prefix rp, while the rps in inc_list should actually exist.

		Nc             sL   h    t  i   }     f d   } x |  D] } | |  q. W  i   S(   s7   Return unsorted list of (basename, inc_filenames) pairsc            s     i  |   } | i   oB | i   d j o/ | i   }  i | g   } | i  |   n" | i   o  i |  g   n d S(   s(   Add filename to the inc tuple dictionaryR   N(   R"   R#   R   t   getincbase_strt
   setdefaultR   (   R)   R[   R&   t   inc_filename_list(   R   t   inc_dict(    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   add_to_dict!  s      (   R   R   t   items(   t   dirlistR   R)   (   R   (   R   s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   get_inc_pairs  s    	  c            sQ   g  } xD |  D]< }   i  |  } | i   p t | i  | i  |  q W| S(   s(   Map list of filenames into increment rps(   R"   R#   R$   R   (   t	   filenamesR   R)   R[   (   R   (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   inc_filenames2incrps-  s     (   R   RZ   R"   R4   t   IndexedTupleR   (   R   R   R   R   R   R&   t   inc_filenamest   sub_inc_rpath(    (   R   s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s     		
 (   R   R   R   R   R   R   R   Rw   R   R   Rx   R   R   (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR^   {  s   									R   c           B   sh   e  Z d  Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z RS(   s  Patch an rpath with the given diff iters (use with IterTreeReducer)

	The main complication here involves directories.  We have to
	finish processing the directory after what's in the directory, as
	the directory may have inappropriate permissions to alter the
	contents or the dir's mtime could change as we change the
	contents.

	This code was originally taken from backup.py.  However, because
	of different error correction requirements, it is repeated here.

	c         C   sB   | |  _  | i t i j p t  d \ |  _ |  _ d |  _ d S(   s9   Set basis_root_rp, the base of the tree to be incrementedN(   NN(	   t   basis_root_rpR   R   R0   R$   RX   t   dir_replacementt
   dir_updatet	   cached_rp(   R   R   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR   K  s    	c         C   s>   |  i  p |  i  i | j o |  i i |  |  _  n |  i  S(   s2   Return RPath by adding index to self.basis_root_rp(   R   R   R   R   (   R   R   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   get_rp_from_rootR  s    c         C   s(   |  i  |  } | i   o | i   S(   s0   True if diff_rorp and mirror are not directories(   R  R   (   R   R   t	   diff_rorpR[   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   can_fast_processX  s    c         C   sE   |  i  |  } t i |  } |  i | | |  t i | |  d S(   s>   Patch base_rp with diff_rorp (case where neither is directory)N(   R  t   TempFileR-   t   patch_to_tempR    t   rename(   R   R   R  R[   t   tf(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   fast_process]  s    c         C   s   | i    p d Sn | i   p t i d | i   d  nm | i | i   j o* t i d | i   | i   f d  n- t i d | i | i   | i   f d  d S(   s8   Check the hash in the copy_report with hash in diff_rorpNs!   Hash for %s missing, cannot checki   s   Hash %s of %s verifiedi   s6   Warning: Hash %s of %s
doesn't match recorded hash %s!(   R   t   has_sha1RI   RJ   R6   t   sha1_digestt   get_sha1(   R   t   copy_reportR  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt
   check_hashd  s     		!	c         C   s   | i    o t i | | |  i  d Sn | i   d j o t i | |  } n0 | i   d j p t  t i	 | | |  } |  i
 | |  | i   o t i | |  n d S(   s>   Patch basis_rp, writing output in new, which doesn't exist yetNR   R   (   t   isflaglinkedR   t   link_rpR   t   get_attached_filetypeR    t   copyR$   R   t   patch_localR  R   t   copy_attribs(   R   t   basis_rpR  R-   R  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR  r  s     c         C   sw   |  i  |  } |  _ | i   p | i   p | i p t  | i   o |  i | |  n |  i | |  d S(   s9   Start processing directory - record information for laterN(   R  t   base_rpR   R   R$   t   prepare_dirt   set_dir_replacement(   R   R   R  R  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   start_process  s
    , c         C   sa   | i    d j p t  t i |  |  _ t i | |  i  | i   o | i d  n d S(   s   Set self.dir_replacement, which holds data until done with dir

		This is used when base_rp is a dir, and diff_rorp is not.

		R   i  N(	   R  R$   R  R-   R   R    t   copy_with_attribsR   t   chmod(   R   R  R  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR    s
     c         C   sV   | i    |  _ | i   p) | i   o | i   n | i   n | i d  d S(   s(   Prepare base_rp to turn into a directoryi  N(   R   R   R   R   t   deletet   mkdirR  (   R   R  R  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR    s     c         C   s   |  i  o1 |  i i   p t  t i |  i  |  i  nI |  i p t  |  i i   |  i i   o t i	 |  i |  i  n d S(   s   Finish processing directoryN(
   R   R  R   R$   R    R  R   t   rmdirR   R  (   R   (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   end_process  s    
(   R   R   R   R   R  R  R  R  R  R  R  R  R  (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR   >  s   									R   c           B   sG   e  Z d  Z d   Z d d  Z d   Z d   Z d   Z d   Z	 RS(   s"  Change the permission of mirror files and directories

	The problem is that mirror files and directories may need their
	permissions changed in order to be read and listed, and then
	changed back when we are done.  This class hooks into the CachedRF
	object to know when an rp is needed.

	c         C   s   | |  _  d |  _ g  |  _ d  S(   N(    (   t   root_rpt   current_indext   open_index_list(   R   R  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s    		c         C   sl   | o | i    o d Sn |  i } | |  _ | p | | j o d Sn |  i |  |  i | |  d S(   s9   Given rpath, change permissions up to and including indexN(   R   R   t   restore_oldt   add_new(   R   R   R   t	   old_index(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyt   __call__  s     		 c         C   s_   xX |  i  oM |  i  d \ } } } | t |   | j o | i |  n P|  i  d =q Wd S(   s1   Restore permissions for indicies we are done withi    N(   R!  RL   R  (   R   R   R$  t   old_rpt	   old_perms(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR"    s     
 c         C   s   x |  i  | |  D] } | i   o | i   p( | i   o} | i   o
 | i   ob | i   } |  i i d | i | | f  | i   o | i	 d | B q | i	 d | B q q Wd S(   s=   Change permissions of directories between old_index and indexi    i   i  N(
   t   get_new_rp_listR   t   readableR   t
   executablet   getpermsR!  t   insertR   R  (   R   R$  R   R[   R'  (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR#    s     ( c         c   s   xR t  t |  d d d  D]& } | |  | |  j o | } Pq q Wd p t  x: t  | d t |  d  D] } |  i i | |   Vqs Wd S(   s   Return list of new rp's between old_index and index

		Do this lazily so that the permissions on the outer
		directories are fixed before we need the inner dirs.

		i   ii    N(   t   rangeRL   R$   R  R   (   R   R$  R   R   t   common_prefix_lent	   total_len(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR(    s     	 c         C   s.   x' |  i  D] \ } } } | i |  q
 Wd S(   s   Restore any remaining rpsN(   R!  R  (   R   R   R[   t   perms(    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s    
  N(
   R   R   R   R   RX   R%  R"  R#  R(  R   (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pyR     s   				
	(    (    (    (    (    ($   R   t
   __future__R    R   t   osR   t   staticR4   R   t	   ExceptionR   R   R,   R@   RC   R   t	   MakeClassR   Rb   R^   t	   ITRBranchR   R   R   t   TimeR   R   Rl   R    RI   R   Rf   t
   statisticsR  R   R   (    (    (    s9   /var/lib/python-support/python2.5/rdiff_backup/restore.pys   <module>   s"   $$				Og@