
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 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 e i d	 e i  Z d
   Z e i d  Z d   Z d   Z d   Z d d d     YZ d e f d     YZ d d d     YZ d e f d     YZ d d  d     YZ  d d! d     YZ! d e! f d     YZ" d a$ d   Z% d d k& Z& d d k' Z' d S("   sa  Store and retrieve metadata in destination directory

The plan is to store metadata information for all files in the
destination directory in a special metadata file.  There are two
reasons for this:

1)  The filesystem of the mirror directory may not be able to handle
    types of metadata that the source filesystem can.  For instance,
    rdiff-backup may not have root access on the destination side, so
    cannot set uid/gid.  Or the source side may have ACLs and the
    destination side doesn't.

	Hopefully every file system can store binary data.  Storing
	metadata separately allows us to back up anything (ok, maybe
	strange filenames are still a problem).

2)  Metadata can be more quickly read from a file than it can by
    traversing the mirror directory over and over again.  In many
    cases most of rdiff-backup's time is spent compaing metadata (like
    file size and modtime), trying to find differences.  Reading this
    data sequentially from a file is significantly less taxing than
    listing directories and statting files all over the mirror
    directory.

The metadata is stored in a text file, which is a bunch of records
concatenated together.  Each record has the format:

File <filename>
  <field_name1> <value>
  <field_name2> <value>
  ...

Where the lines are separated by newlines.  See the code below for the
field names and values.

i(   t
   generatorsNt   ParsingErrorc           B   s   e  Z d  Z RS(   s6   This is raised when bad or unparsable data is received(   t   __name__t
   __module__t   __doc__(    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR   =   s   c         C   s   |  p d Sn g  } | i  d t i |  d   | i  d t i |  d   | i  d |  d  | i  d |  d	  y | i  d
 |  d  Wn# t j
 o t i d d  n Xd i |  S(   s9   Convert CarbonFile data to a string suitable for storing.t   Nones
   creator:%st   creators   type:%st   types   location:%d,%dt   locations   flags:%dt   flagss   createDate:%dt
   createDates7   Writing pre-1.1.6 style metadata, without creation datei	   t   |(   t   appendt   binasciit   hexlifyt   KeyErrort   logt   Logt   join(   t   cfilet   retvalparts(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   carbonfile2stringA   s       c         C   s  h  } x |  i  d  D] } | i  d  \ } } | d j o t i |  | d <q | d j o t i |  | d <q | d j o5 | i  d  \ } } t |  t |  f | d <q | d j o t |  | d <q | d j o t |  | d <q q W| S(	   sJ   Re-constitute CarbonFile data from a string stored by 
	carbonfile2string.R   t   :R   R   R   t   ,R	   R
   (   t   splitR   t	   unhexlifyt   int(   t   datat   retvalt	   componentt   keyt   valuet   at   b(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   string2carbonfileM   s       c         C   s  d t  |  i    g } |  i   } | d! j o
 d } n | i d |  | d j o;| i d |  i    |  i   oD |  i   p
 d } n t i	 |  i    } | i d | f  n |  i
   o* t |  i    } | i d | f  n t i d j o` |  i   } | d	 j oC | i d
 |  | i d |  i    | i d |  i    qin |  i   o | i d |  i    qzn | d j o d i |  Sn | d j p | d j p | d j o n | d j o! | i d t  |  i     no | d j oa |  i   \ } } |  i   o
 d } n |  i   p t  d } | i d | | | f  n | d j o( | d j o | i d |  i    n |  i   \ }	 }
 | i d |	  | i d |  i   p d  | i d |
  | i d |  i   p d  | i d |  i    |  i   o | i d |  i    f  n, |  i!   o | i d  |  i"   f  n d i |  S("   s3   From RORPath, return text record of file's metadatas   File %s
R   s
     Type %s
t   regs
     Size %s
s     ResourceFork %s
s     CarbonFile %s
i    i   s     NumHardLinks %s
s     Inode %s
s     DeviceLoc %s
s     SHA1Digest %s
t    t   dirt   sockt   fifot   syms     SymData %s
t   devR!   t   cs     DeviceNum %s %s %s
s     ModTime %s
s	     Uid %s
s     Uname %s
R   s	     Gid %s
s     Gname %s
s     Permissions %s
s     AlternateMirrorName %s
s     AlternateIncrementName %s
N(#   t
   quote_patht   get_indexpatht   gettypeR   R   t   getsizet   has_resource_forkt   get_resource_forkR   R   t   has_carbonfileR   t   get_carbonfilet   Globalst   preserve_hardlinkst   getnumlinkst   getinodet	   getdevloct   has_sha1t   get_sha1R   t   readlinkt
   getdevnumst   isblkdevt	   ischardevt   AssertionErrort   getmtimet	   getuidgidt   getunamet   getgnamet   getpermst   has_alt_mirror_namet   get_alt_mirror_namet   has_alt_inc_namet   get_alt_inc_name(   t   rorpatht   str_listR   t   rfR   t   numlinkst   majort   minort   devchart   uidt   gid(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   RORP2Record`   sf     
 
 ' ! 
		s   ^ *([A-Za-z0-9]+) (.+)$c         C   sf  h  } xMt  i |   D]<\ } } | d j o t |  } q | d j o) | d j o d, | d <qR| | d <q | d j o t |  | d <q | d j o2 | d j o d | d	 <qRt i |  | d	 <q | d
 j o/ | d j o d, | d <qRt |  | d <q | d j o | | d <q | d j o t |  | d <q | d j o t |  | d <q | d j o t |  | d <q | d j o t	 |  | d <q | d j o; | i
 d  \ } } } | t |  t |  f | d <q | d j o t |  | d <q | d j o t |  | d <q | d j o t |  | d <q | d j o6 | d  j p | d j o d, | d! <qR| | d! <q | d" j o6 | d  j p | d j o d, | d# <qR| | d# <q | d$ j o t |  | d% <q | d& j o | | d' <q | d( j o | | d) <q t i d* | | f d+  q Wt i | |  S(-   s   Given record_string, return RORPath

	For speed reasons, write the RORPath data dictionary directly
	instead of calling rorpath functions.  Profiling has shown this to
	be a time critical function.

	t   Filet   TypeR   R   t   Sizet   sizet   ResourceForkR$   t   resourceforkt
   CarbonFilet
   carbonfilet
   SHA1Digestt   sha1t   NumHardLinkst   nlinkt   Inodet   inodet	   DeviceLoct   devloct   SymDatat   linknamet	   DeviceNumt    t   devnumst   ModTimet   mtimet   UidRO   t   GidRP   t   UnameR   t   unamet   Gnamet   gnamet   Permissionst   permst   AlternateMirrorNamet
   mirrornamet   AlternateIncrementNamet   incnames   Unknown field in line '%s %s'i   N(   t   line_parsing_regexpt   findallt   quoted_filename_to_indexR   t   longR   R   R"   R   t   unquote_pathR   R   R   t   rpatht   RORPath(   t   record_stringt	   data_dictt   fieldR   t   indexRN   t	   major_strt	   minor_str(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   Record2RORP   sl               #        s   \n|\\c         C   s   d   } t  i | |   S(   s   Return quoted verson of path_string

	Because newlines are used to separate fields in a record, they are
	replaced with 
.  Backslashes become \ and everything else is
	left the way it is.

	c         S   sR   |  i  d  } | d j o d Sn | d j o d Sn d p t d |  d S(   s>   This is called on the match obj of any char that needs quotingi    s   
s   \ns   \s   \\s   Bad char %s needs quotingN(   t   groupR>   (   t	   match_objt   char(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   replacement_func   s      (   t   chars_to_quotet   sub(   t   path_stringR   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR+      s    	c         C   s   d   } t  i d | |   S(   s#   Reverse what was done by quote_pathc         S   sQ   |  i  d  } | d j o d Sn | d j o d Sn t i d | d  | S(   s+   Unquote match obj of two character sequencei    s   \ns   
s   \\s   \s)   Warning, unknown quoted sequence %s foundi   (   R   R   R   (   R   t	   two_chars(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR      s      s   \\n|\\\\(   t   reR   (   t   quoted_stringR   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyRy      s    	c         C   s2   |  d j o d Sn t  t |   i d   Sd S(   s(   Return tuple index given quoted filenamet   .t   /N(    (   t   tupleRy   R   (   t   quoted_filename(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyRw      s     t   FlatExtractorc           B   sY   e  Z d  Z d Z d Z d   Z d   Z d   Z d   Z	 d   Z
 d   Z d   Z RS(	   s)   Controls iterating objects from flat filec         C   s(   | |  _  d |  _ d |  _ d |  _ d  S(   NR$   i    i    i   i   (   t   fileobjt   buft   at_endt	   blocksize(   t   selfR   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   __init__   s    			c         C   s   xx |  i  i |  i d  } | o | i d  Sq |  i i |  i  } | p d |  _ t |  i  Sq |  i | 7_ q d S(   s<   Return position of next record in buffer, or end pos if nonei   N(	   t   record_boundary_regexpt   searchR   t   startR   t   readR   R   t   len(   R   t   mt   newbuf(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_next_pos  s     	c         c   sq   xj |  i    D]\ } y |  i |  VWq t t f j
 o/ } |  i o Pn t i d | f d  q Xq Wd S(   s4   Return iterator that yields all objects with recordss   Error parsing flat file: %si   N(   t   iterate_recordst   record_to_objectR   t
   ValueErrorR   R   R   (   R   t   recordt   e(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   iterate  s      
 c         c   sp   xQ |  i    } |  i o | o |  i |  Vn Pn |  i |  V|  i | |  _ q |  i i   p t  d S(   s   Yield all text records in orderN(   R   R   R   R   t   closeR>   (   R   t   next_pos(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    
 c         C   s   |  i  p |  i  i d  p t  x |  i i |  i  |  _  |  i  |  i i   7_  |  i  p d |  _ d Sn x |  i i	 |  i   } | p Pn |  i
 | i d   } | | j o! |  i  | i d  |  _  d Sqv |  i  | i d  |  _  qv q( d S(   s   Scan through the file, set buffer to beginning of index record

		Here we make sure that the buffer always ends in a newline, so
		we will not be splitting lines in half.

		s   
i   Ni   (   R   t   endswithR>   R   R   R   t   readlineR   R   R   t   filename_to_indexR   R   t   end(   R   R   R   t	   cur_index(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   skip_to_index#  s     %
	 c         c   s   |  i  |  |  i o d Sn x |  i   } y |  i |  i |   } Wn2 t t f j
 o  } t i d | f d  n& X| i	 t
 |   | j o Pn | V|  i o Pn |  i | |  _ q" |  i i   p t  d S(   s3   Iterate objects whose index starts with given indexNs   Error parsing metadata file: %si   (   R   R   R   R   R   R   R   R   R   R   R   R   R   R>   (   R   R   R   t   objR   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   iterate_starting_with:  s     
   
 c         C   s   d p t   d S(   s   Translate filename, possibly quoted, into an index tuple

		The filename is the first group matched by
		regexp_boundary_regexp.

		i    N(   R>   (   R   t   filename(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR   J  s    N(   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR      s   						t   RorpExtractorc           B   s5   e  Z d  Z e i d  Z e e  Z e e	  Z
 RS(   s    Iterate rorps from metadata files   (?:\n|^)(File (.*?))\n(   R   R   R   R   t   compileR   t   staticmethodR   R   Rw   R   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR   T  s   t   FlatFilec           B   s   e  Z d  Z d
 \ Z Z Z d Z d \ Z Z	 e
 Z d	 Z d	 Z d d d	 d  Z d   Z d   Z d	 d  Z d   Z d   Z RS(   s  Manage a flat (probably text) file containing info on various files

	This is used for metadata information, and possibly EAs and ACLs.
	The main read interface is as an iterator.  The storage format is
	a flat, probably compressed file, so random access is not
	recommended.

	i   id   c            s)  |   _  |   _ g    _ | o7 | i   o | i     i j p
 t |  d } n | d j o% |   _   i i d |    _	 n | d j p t  | o= | o6 | i
   o(   f d   } t i | |    _	 nC |   _   i i   p t   i    i i d d |   _	 d S(	   s   Open rp (or rp+'.gz') for reading ('r') or writing ('w')

		If callback is available, it will be called on the rp upon
		closing (because the rp may not be known in advance).

		i   t   rt   rbt   wc            s   |    _  d  S(   N(   t   rp(   R   (   R   (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   callback  s    t   wbt   compressN(   t   modeR   t   _record_buffert	   isincfilet   getincbase_strt   _prefixR>   R   t   openR   t   isinccompressedRz   t	   MaybeGzipt   lstat(   R   t   rp_baseR   t
   check_pathR   R   (    (   R   s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR   j  s"    			 
		c         C   st   |  i  oV |  i i |  t |  i  |  i j o) |  i i d i |  i   g  |  _ qp n |  i i |  d S(   s#   Write a (text) record into the fileR$   N(   t   _buffering_onR   R   R   t   _max_buffer_sizeR   t   writeR   (   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   write_record  s    
c         C   s   |  i  |  i |   d S(   s.   Convert one object to record and write to fileN(   R   t   _object_to_record(   R   t   object(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   write_object  s    c         C   s@   | p |  i  |  i  i   Sn |  i  |  i  } | i |  S(   s/   Return iterator of objects records from file rp(   t
   _extractorR   R   R   (   R   t   restrict_indext	   extractor(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_objects  s     c         C   s   |  i  |  i  i   S(   s   Return iterator of text records(   R   R   R   (   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_records  s    c         C   s   |  i  p
 t d  |  i o3 |  i o) |  i  i d i |  i   g  |  _ n |  i  i   } d |  _  |  i i	   |  i i
   |  i o |  i |  i  n | S(   s(   Close file, for when any writing is dones   File already closedR$   N(   R   R>   R   R   R   R   R   R   R   t   fsync_with_dirt   setdataR   (   R   t   result(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    	
 N(   NNN(   Nid   (   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR   [  s   				t   MetadataFilec           B   s&   e  Z d  Z d Z e Z e e  Z RS(   s5   Store/retrieve metadata from mirror_metadata as rorpst   mirror_metadata(	   R   R   R   R   R   R   R   RQ   R   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s   t   CombinedWriterc           B   s)   e  Z d  Z d   Z d   Z d   Z RS(   s8   Used for simultaneously writting metadata, eas, and aclsc         C   s*   | |  _  | | | |  _ |  _ |  _ d  S(   N(   t
   metawritert   eawritert	   aclwritert   winaclwriter(   R   R   R   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    	c         C   s   |  i  i |  |  i o. | i   i   o |  i i | i    n |  i o. | i   i   o |  i i | i    n |  i o |  i i | i	    n d S(   s,   Write information in rorp to all the writersN(
   R   R   R   t   get_eat   emptyR   t   get_aclt   is_basicR   t   get_win_acl(   R   t   rorp(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    
c         C   sb   |  i  i   |  i o |  i i   n |  i o |  i i   n |  i o |  i i   n d  S(   N(   R   R   R   R   R   (   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    
 
 
 (   R   R   R   R   R   R   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s   		
t   Managerc           B   s   e  Z d  Z d Z d Z d Z d Z d   Z d   Z d   Z	 d   Z
 d	   Z d
   Z d   Z d d  Z d   Z d   Z d   Z d   Z d   Z d d d  Z RS(   s)   Read/Combine/Write metadata files by timeR   t   access_control_listst   extended_attributest   win_access_control_listsc         C   sj   g  |  _  h  h  |  _ |  _ xG t i i   D]6 } t i i |  } | i   o |  i |  q, q, Wd S(   s$   Set listing of rdiff-backup-data dirN(	   t   rplistt	   timerpmapt	   prefixmapR3   t   rbdirt   listdirR   R   t	   add_incrp(   R   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    	  c         C   s   | i    p
 t |  |  i i |  | i   } |  i i |  o |  i | i |  n | g |  i | <| i   } |  i i |  o |  i | i |  n | g |  i | <d S(   s&   Add rp to list of inc rps in the rbdirN(	   R   R>   R   R   t
   getinctimeR   t   has_keyR   R   (   R   R   t   timet   incbase(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s     c         C   sd   |  i  i |  p d Sn xB |  i  | D]3 } | i   | j o | | d  i |  Sq) q) Wd S(   s1   Used below to find the right kind of file by timeR   N(   R   R   R   R   R   (   R   t   prefixt   flatfileclassR   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   _iter_helper  s      c         C   s   |  i  |  i t | |  S(   s5   Return iter of metadata rorps at given time (or None)(   R   t   meta_prefixR   (   R   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_meta_at_time  s    c         C   s   |  i  |  i t i | |  S(   s7   Return Extended Attributes iter at given time (or None)(   R   t	   ea_prefixt   eas_aclst   ExtendedAttributesFile(   R   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_eas_at_time  s    c         C   s   |  i  |  i t i | |  S(   s8   Return ACLs iter at given time from recordfile (or None)(   R   t
   acl_prefixR   t   AccessControlListFile(   R   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_acls_at_time  s    c         C   s   |  i  |  i t i | |  S(   s9   Return WACLs iter at given time from recordfile (or None)(   R   t   wacl_prefixt   win_aclst   WinAccessControlListFile(   R   R   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_win_acls_at_time  s    c         C   s@  |  i  | |  } | p t i d d  d Sn t i oO |  i | |  } | p  t i d d  t g   } n t i	 | |  } n t i
 oO |  i | |  } | p  t i d d  t g   } n t i | |  } n t i oO |  i | |  } | p  t i d d  t g   } n t i | |  } n | S(   s;   Return combined metadata iter with ea/acl info if necessarys\   Warning, could not find mirror_metadata file.
Metadata will be read from filesystem instead.i   s+   Warning: Access Control List file not founds+   Warning: Extended Attributes file not founds4   Warning: Windows Access Control List file not found.N(   R   R   R   R   R3   t   acls_activeR   t   iterR   t   join_acl_itert
   eas_activeR   t   join_ea_itert   win_acls_activeR   R   t   join_wacl_iter(   R   R   R   t   cur_itert   acl_itert   ea_itert	   wacl_iter(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt	   GetAtTime  s2    	


	c         C   s   | d j o t i } n t i |  } d | | | f } t i i |  } | i   p t d | i	 f  | i
   p t  | | d d |  i S(   s;   Used in the get_xx_writer functions, returns a writer classs   %s.%s.%ss   File %s already exists!R   R   N(   R   t   Timet
   curtimestrt   timetostringR3   R   R   R   R>   t   pathR   R   (   R   R   R   t   typestrR   t   timestrR   R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   _writer_helper  s     "c         C   s   |  i  |  i t | |  S(   s;   Return MetadataFile object opened for writing at given time(   R  R   R   (   R   R  R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_meta_writer)  s    c         C   s   |  i  |  i t i | |  S(   s0   Return ExtendedAttributesFile opened for writing(   R  R   R   R   (   R   R  R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_ea_writer.  s    c         C   s   |  i  |  i t i | |  S(   s/   Return AccessControlListFile opened for writing(   R  R   R   R   (   R   R  R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_acl_writer3  s    c         C   s   |  i  |  i t i | |  S(   s2   Return WinAccessControlListFile opened for writing(   R  R   R   R   (   R   R  R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_win_acl_writer8  s    t   snapshotc         C   s   |  i  | |  } t i o t i o t i o | Sn t i o |  i | |  } n d } t i o |  i | |  } n d } t i o |  i | |  } n d } t	 | | | |  S(   s=   Get a writer object that can write meta and possibly acls/easN(
   R  R3   R  R  R  R  R   R  R  R   (   R   R  R   R   t	   ea_writert
   acl_writert   win_acl_writer(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt	   GetWriter=  s    
 
 
N(   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R  R  R  R  R  R  R  (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s&   								
				t   PatchDiffManc           B   sV   e  Z d  Z d Z d   Z d d  Z d   Z d   Z d   Z d   Z	 d	   Z
 RS(
   s  Contains functions for patching and diffing metadata

	To save space, we can record a full list of only the most recent
	metadata, using the normal rdiff-backup reverse increment
	strategy.  Instead of using librsync to compute diffs, though, we
	use our own technique so that the diff files are still
	hand-editable.

	A mirror_metadata diff has the same format as a mirror_metadata
	snapshot.  If the record for an index is missing from the diff, it
	indicates no change from the original.  If it is present it
	replaces the mirror_metadata entry, unless it has Type None, which
	indicates the record should be deleted from the original.

	i	   c         c   sg   x` t  i | |  D]L \ } } | p t i | i  Vq | p | i | i j o	 | Vq q Wd S(   s*   Iterate meta diffs of new_iter -> old_iterN(   t   rorpitert   Collate2ItersRz   R{   R   R   (   R   t   new_itert   old_itert   new_rorpt   old_rorp(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   get_diffiter_  s      i    c         C   s   |  i  i |  p g  Sn g  } |  i  | D] } | | i   | f q- ~ } | i   | i   g  } | D]$ \ } } | | j o | | qn qn ~ S(   s>   Return reverse sorted (by time) list of incs with given prefix(   R   R   R   t   sortt   reverse(   R   R   t   min_timet   _[1]R   t   sortlistt   _[2]R   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   sorted_prefix_inclistg  s     4

c         C   s   |  i  d  } t |  d j p t  t |  d j o d Sn | d  \ } } | i   | i   j o
 d j n p t  d } x4 | d D]( } | i   d j o Pn | d 7} q W| |  i j o d Sn | | f S(	   s@   Check if we should diff, returns (new, old) rps, or (None, None)R   i   i   R  t   diffN(   NN(   NN(   R+  R   R>   R   t
   getinctypet   max_diff_chain(   R   t   inclistt   newrpt   oldrpt   chainlenR   (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   check_needs_diffo  s     1   c         C   s   |  i    \ } } | p d Sn t i d d  |  i d | i    } t | d  i   } t | d  i   } x' |  i | |  D] } | i |  q W| i	   | i
   d S(   s9   Replace a mirror snapshot with a diff if it's appropriateNs   Writing mirror_metadata diffi   R,  R   (   R3  R   R   R  R   R   R   R$  R   R   t   delete(   R   R0  R1  t   diff_writerR   R!  t	   diff_rorp(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt   ConvertMetaToDiff~  s      
c         C   sw   g  } |  i  |  D] } | t | d  i |  q ~ } | p d Sn t |  d j o | d Sn |  i |  S(   s7   Get metadata rorp iter, possibly by patching with diffsR   i   i    N(   t   relevant_meta_incsR   R   R   R   t   iterate_patched_meta(   R   R   R   R(  R   t
   meta_iters(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR     s    5  c         C   s   |  i  d d | } | p | Sn | d i   | j p t | d  xG t t |  d d d  D]) } | | i   d j o | | Sqf qf Wd p t d | f  d S(	   s1   Return list [snapshotrp, diffrps ...] time sortedR   R'  ii   R  i    s    Inclist %s contains no snapshotsN(   R+  R   R>   t   rangeR   R-  (   R   R   R/  t   i(    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR8    s     % c         c   s   x} t  i |   D]l } xc t t |  d d d  D]4 } | | o# | | i   o | | Vn Pq3 q3 Wd p
 t d  q Wd S(   s   Return an iter of metadata rorps by combining the given iters

		The iters should be given as a list/tuple in reverse
		chronological order.  The earliest rorp in each iter will
		supercede all the later ones.

		i   ii    s   No valid rorpsN(   R  t   CollateIteratorsR;  R   R   R>   (   R   t   meta_iter_listt
   meta_tupleR<  (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR9    s       	(   R   R   R   R.  R$  R+  R3  R7  R   R8  R9  (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyR  M  s   					
c           C   s   t    a t S(   N(   R  t
   ManagerObj(    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pyt
   SetManager  s    	(    (    (    (    ((   R   t
   __future__R    R   t   gzipt   osR   R   R3   Rz   R  t   robustt	   incrementt   staticR  t	   ExceptionR   R   R"   RQ   R   t   MRu   R   R   R+   Ry   Rw   R   R   R   R   R   R   R  R   R@  RA  R   R   (    (    (    s:   /var/lib/python-support/python2.5/rdiff_backup/metadata.pys   <module>7   s.   0`			D	,			bO`	