³ò
OÉcIc        
   @   sâ   d  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 Z	 d a d d „ Z d a d Z d „  Z d d „ Z d	 „  Z d d
 „ Z d a d „  Z d „  Z d „  Z d „  Z d S(   s9  Handle long filenames

rdiff-backup sometimes wants to write filenames longer than allowed by
the destination directory.  This can happen in 3 ways:

1)  Because the destination directory has a low maximum length limit.
2)  When the source directory has a filename close to the limit, so
    that its increments would be above the limit.
3)  When quoting is enabled, so that even the mirror filenames are too
    long.

When rdiff-backup would otherwise write a file whose name is too long,
instead it either skips the operation altogether (for non-regular
files), or writes the data to a unique file in the
rdiff-backup-data/long-filename directory.  This file will have an
arbitrary basename, but if it's an increment the suffix will be the
same.  The name will be recorded in the mirror_metadata so we can find
it later.

iÿÿÿÿNt   long_filename_datac         C   sX   t  p1 t i i t ƒ a  t  i ƒ  p t  i ƒ  q8 n |  o t  i |  ƒ Sn t  Sd S(   s6   Return an rpath in long name directory with given baseN(   t   rootrpt   Globalst   rbdirt   appendt   long_name_dirt   lstatt   mkdir(   t   base(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   get_long_rp/   s      t	   next_freec          C   s•   d „  }  d „  } d „  } t  p | ƒ  a  n t  p |  ƒ  a  n t t  ƒ } t | ƒ } | i ƒ  p t d | i f ‚ t  d 7a  | t  ƒ | S(   sB   Return next free filename available in the long filename directoryc          S   s…   t  i d d ƒ d }  xd t ƒ  i ƒ  D]S } y t | i d ƒ d ƒ } Wn t j
 o
 q& n X| |  j o
 | }  q& q& W|  d S(   s>   Return value of free_name_counter by listing long filename dirs)   Setting next free from long filenames diri   i    t   .i   (   t   logt   LogR	   t   listdirt   intt   splitt
   ValueError(   t   cur_hight   filenamet   i(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   scan_next_freeF   s        c          S   s1   t  t ƒ }  |  i ƒ  p d Sn t |  i ƒ  ƒ S(   s;   Return next int free by reading the next_free file, or NoneN(   R	   t   counter_filenameR   t   NoneR   t   get_data(   t   rp(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   read_next_freeP   s     c         S   sH   t  t ƒ } | i ƒ  o | i ƒ  n | i t t ƒ ƒ | i ƒ  d S(   s#   Write value i into the counter fileN(   R	   R   R   t   deletet   write_stringt   strt   free_name_countert   fsync_with_dir(   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   write_next_freeV   s
     s   Unexpected file at %s foundi   (   R   R   R	   R   t   AssertionErrort   path(   R   R   R    R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   get_next_freeC   s    	
		  "

i    c         C   s   d „  } d „  } | |  i  | ƒ } | p | p | i ƒ  o | Sn | | | ƒ } | p d Sn& | d j o | Sn | |  i  | ƒ Sd S(   sË   Return new rpath with given index, or None if that is too long

	If make_dir is True, make any parent directories to assure that
	file is really too long, and not just in directories that don't exist.

	c         W   sf   y |  | Œ  } WnO t  j
 oC } t i i | d ƒ o  t i | d d j o d  Sn ‚  n X| S(   Ni    t   ENAMETOOLONG(   t   EnvironmentErrort   errnot	   errorcodet   has_keyR   (   t   funct   argst   resultt   exc(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt	   wrap_calln   s     c         S   s/   |  i  ƒ  } | i ƒ  o d Sn | i ƒ  d S(   Ni   i   (   t   get_parent_rpR   t   makedirs(   R   t   parent(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   make_parentw   s
     
i   N(   t	   new_indexR   R   (   R   t   indext	   make_dirsR-   R1   R   t   parent_result(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   check_new_indexg   s    			   c         C   sS   | i  ƒ  o t | i ƒ  ƒ Sn/ t |  | i ƒ } | o | Sn |  i t ƒ Sd S(   sÊ   Get the mirror_rp for reading a regular file

	This will just be in the mirror_base, unless rorp has an alt
	mirror name specified.  Use new_rorp, unless it is None or empty,
	and mirror_rorp exists.

	N(   t   has_alt_mirror_nameR	   t   get_alt_mirror_nameR6   R3   t   new_index_empty(   t   mirror_baset   mirror_rorpR   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   get_mirror_rp…   s     c            s	  ˆ p ˆ  i  d ƒ ‰ n ‡  f d †  } ‡  f d †  } d „  } ‡ f d †  } |  \ } } | o/ | i ƒ  o" | | ƒ \ }	 }
 } | i } nC | o | i ƒ  p t | | f ‚ | | ƒ \ }	 }
 } | i } | | |	 |
 | ƒ \ } } | | |
 | ƒ |	 | f S(   s©   Get (mirror_rp, inc_rp) pair, possibly making new longname base

	To test inc_rp, pad incbase with 50 random (non-quoted) characters
	and see if that raises an error.

	s   rdiff-backup-data/incrementsc            sw   |  i  ƒ  o# |  i ƒ  } t | ƒ | d f SnD ˆ  i |  i ƒ } |  i ƒ  o | d |  i ƒ  f Sn | d d f Sd S(   s5   Return (mirror_rp, alt_mirror, alt_inc) from old_rorpN(   R7   R8   R	   R   R2   R3   t   has_alt_inc_namet   get_alt_inc_name(   t   old_rorpt
   alt_mirrort	   mirror_rp(   t   mirror_root(    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   mir_triple_oldž   s    c            sF   t  ˆ  |  i ƒ } | o | d d f Sn t ƒ  } t | ƒ | d f S(   s2   Return (mirror_rp, alt_mirror, None) from new_rorpN(   R6   R3   R   R#   R	   (   t   new_rorpRA   R@   (   RB   (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   mir_triple_new©   s
     	c         S   sR   |  p |  i  ƒ  o d Sn | o |  i | ƒ n | o |  i | ƒ n d S(   s5   Update new_rorp with alternate mirror/inc informationN(   R   t   set_alt_mirror_namet   set_alt_inc_name(   RD   R@   t   alt_inc(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   update_rorp°   s       c            s¨   | o d | f Sn1 | o | t | ƒ f Sn |  p d ˆ  f Sn |  d  |  d d d f } t ˆ  | d d ƒo d ˆ  i |  ƒ f Sn t ƒ  } | t | ƒ f S(   s   Return (alt_inc, inc_rp) pairiÿÿÿÿt   ai2   R4   i   N(   R   R	   R6   R2   R#   (   R3   RA   R@   RH   t   trial_inc_index(   t   inc_root(    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   find_inc_pair¶   s       	(   t   append_pathR   R3   R!   (   t	   rorp_pairRB   RL   RC   RE   RI   RM   RD   R?   RA   R@   RH   R3   t   inc_rp(    (   RB   RL   s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   get_mirror_inc_rps”   s     	$	c          C   sY   h  a  t i t ƒ  t ƒ  g  ƒ }  x1 |  i t ƒ  ƒ D] \ } } | t  | i d <q4 Wd S(   s7   Initialize restore_inc_cache based on long filename diriÿÿÿÿN(   t   restore_inc_cachet   restoret   RestoreFileR	   t   yield_inc_complexesR3   (   t   root_rft
   incbase_rpt   inclist(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   set_restore_cacheØ   s
     c         C   s<   t  p t ƒ  n y t  |  SWn t j
 o g  Sn Xd  S(   N(   RR   RY   t   KeyError(   t   inc_base_name(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   get_inclistà   s       c            s”   ‡ f d †  ‰  ‡  f d †  } ‡  f d †  } ˆ p |  Sn |  o$ ˆ i  ƒ  o ˆ i ƒ  o |  Sn |  o | |  ˆ ƒ |  Sn | ˆ | ƒ Sd S(   s@   Return new or updated restorefile based on alt name info in rorpc            sL   t  i d | ˆ  i ƒ  f d ƒ t | ƒ |  _ t | ƒ |  _ |  i ƒ  d S(   s;   Swap inclist in rf with those with base inc_base and returns,   Restoring with increment base %s for file %si   N(   R   R   t   get_indexpathR	   RP   R\   t   inc_listt   set_relevant_incs(   t   rft   inc_base(   t   rorp(    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   update_incsç   s
    	c            sk   | i  ƒ  o | i ƒ  } t t ƒ |  _ n$ | i ƒ  o | i ƒ  } n d } | o ˆ  |  | ƒ n d S(   s+   Update rf based on rorp, don't make new oneN(   R7   R8   R	   t   mirror_nameRA   R=   R>   R   (   R`   Rb   t   inc_name(   Rc   (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   update_existing_rfï   s      c            s‘   |  i  ƒ  o |  i ƒ  } t | ƒ } nC | i |  i ƒ } |  i ƒ  o |  i ƒ  } n t i | d g  ƒ St i | d g  ƒ } ˆ  | | ƒ | S(   s.   Make a new rf when long name info is availableN(
   R7   R8   R	   R2   R3   R=   R>   RS   RT   R   (   Rb   RB   Re   RA   R`   (   Rc   (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   make_new_rfù   s     N(   R7   R=   (   R`   Rb   RB   Rf   Rg   (    (   Rc   Rb   s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt	   update_rfå   s    
 #c         C   sI   t  |  | | ƒ }  t |  t i ƒ o |  Sn t i |  i |  i |  i ƒ S(   s2   Like update_rf except return a regress file object(   Rh   t
   isinstancet   regresst   RegressFileRA   RP   R^   (   R`   Rb   RB   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pyt   update_regressfile  s     (   t   __doc__t   typesR&   R   R   RS   t   rpatht   FilenameMappingRj   R   R   R   R	   R   R   R#   R6   R<   RQ   RR   RY   R\   Rh   Rl   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/longname.pys   <module>'   s    H	$	B			*