#NEWLINE# def VFSOpen( pathspec , progress_callback = None ) : #NEWLINE# #INDENT# 'Expands pathspec to return an expanded Path.\n\n  A pathspec is a specification of how to access the file by recursively opening\n  each part of the path by different drivers. For example the following\n  pathspec:\n\n  pathtype: OS\n  path: "/dev/sda1"\n  nested_path {\n    pathtype: TSK\n    path: "/home/image2.img"\n    nested_path {\n      pathtype: TSK\n      path: "/home/a.txt"\n    }\n  }\n\n  Instructs the system to:\n  1) open /dev/sda1 using the OS driver.\n  2) Pass the obtained filelike object to the TSK driver to open\n  "/home/image2.img".\n  3) The obtained filelike object should be passed to the TSK driver to open\n  "/home/a.txt".\n\n  The problem remains how to get to this expanded path specification. Since the\n  server is not aware of all the files on the client, the server may request\n  this:\n\n  pathtype: OS\n  path: "/dev/sda1"\n  nested_path {\n    pathtype: TSK\n    path: "/home/image2.img/home/a.txt"\n  }\n\n  Or even this:\n\n  pathtype: OS\n  path: "/dev/sda1/home/image2.img/home/a.txt"\n\n  This function converts the pathspec requested by the server into an expanded\n  pathspec required to actually open the file. This is done by expanding each\n  component of the pathspec in turn.\n\n  Expanding the component is done by opening each leading directory in turn and\n  checking if it is a directory of a file. If its a file, we examine the file\n  headers to determine the next appropriate driver to use, and create a nested\n  pathspec.\n\n  Note that for some clients there might be a virtual root specified. This\n  is a directory that gets prepended to all pathspecs of a given\n  pathtype. For example if there is a virtual root defined as\n  ["os:/virtualroot"], a path specification like\n\n  pathtype: OS\n  path: "/home/user/*"\n\n  will get translated into\n\n  pathtype: OS\n  path: "/virtualroot"\n  is_virtualroot: True\n  nested_path {\n    pathtype: OS\n    path: "/dev/sda1"\n  }\n\n  Args:\n    pathspec: A Path() protobuf to normalize.\n    progress_callback: A callback to indicate that the open call is still\n                       working but needs more time.\n\n  Returns:\n    The open filelike object. This will contain the expanded Path() protobuf as\n    the member fd.pathspec.\n\n  Raises:\n    IOError: if one of the path components can not be opened.\n\n  ' #NEWLINE# fd = None #NEWLINE# vroot = VFS_VIRTUALROOTS . get ( pathspec . pathtype ) #NEWLINE# if ( ( not vroot ) or pathspec . is_virtualroot or pathspec . CollapsePath ( ) . startswith ( vroot . CollapsePath ( ) ) ) : #NEWLINE# #INDENT# working_pathspec = pathspec . Copy ( ) #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# working_pathspec = vroot . Copy ( ) #NEWLINE# working_pathspec . last . nested_path = pathspec . Copy ( ) #NEWLINE# #UNINDENT# while working_pathspec : #NEWLINE# #INDENT# component = working_pathspec . Pop ( ) #NEWLINE# try : #NEWLINE# #INDENT# handler = VFS_HANDLERS [ component . pathtype ] #NEWLINE# #UNINDENT# except KeyError : #NEWLINE# #INDENT# raise IOError ( ( 'VFS handler %d not supported.' % component . pathtype ) ) #NEWLINE# #UNINDENT# try : #NEWLINE# #INDENT# fd = handler . Open ( fd , component , pathspec = working_pathspec , full_pathspec = pathspec , progress_callback = progress_callback ) #NEWLINE# #UNINDENT# except IOError as e : #NEWLINE# #INDENT# raise IOError ( ( '%s: %s' % ( e , pathspec ) ) ) #NEWLINE# #UNINDENT# #UNINDENT# return fd