OLD | NEW |
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 """The CPIO file entry implementation.""" | 2 """The CPIO file entry implementation.""" |
3 | 3 |
| 4 from __future__ import unicode_literals |
| 5 |
4 import stat | 6 import stat |
5 | 7 |
6 from dfvfs.lib import definitions | 8 from dfvfs.lib import definitions |
7 from dfvfs.lib import errors | 9 from dfvfs.lib import errors |
8 from dfvfs.path import cpio_path_spec | 10 from dfvfs.path import cpio_path_spec |
9 from dfvfs.vfs import file_entry | 11 from dfvfs.vfs import file_entry |
10 from dfvfs.vfs import vfs_stat | 12 from dfvfs.vfs import vfs_stat |
11 | 13 |
12 | 14 |
13 class CPIODirectory(file_entry.Directory): | 15 class CPIODirectory(file_entry.Directory): |
14 """Class that implements a directory object using CPIOArchiveFile.""" | 16 """Class that implements a directory object using CPIOArchiveFile.""" |
15 | 17 |
16 def _EntriesGenerator(self): | 18 def _EntriesGenerator(self): |
17 """Retrieves directory entries. | 19 """Retrieves directory entries. |
18 | 20 |
19 Since a directory can contain a vast number of entries using | 21 Since a directory can contain a vast number of entries using |
20 a generator is more memory efficient. | 22 a generator is more memory efficient. |
21 | 23 |
22 Yields: | 24 Yields: |
23 A path specification (instance of path.CPIOPathSpec). | 25 A path specification (instance of path.CPIOPathSpec). |
24 """ | 26 """ |
25 location = getattr(self.path_spec, u'location', None) | 27 location = getattr(self.path_spec, 'location', None) |
26 | 28 |
27 if (location is None or | 29 if (location is None or |
28 not location.startswith(self._file_system.PATH_SEPARATOR)): | 30 not location.startswith(self._file_system.PATH_SEPARATOR)): |
29 return | 31 return |
30 | 32 |
31 cpio_archive_file = self._file_system.GetCPIOArchiveFile() | 33 cpio_archive_file = self._file_system.GetCPIOArchiveFile() |
32 for cpio_archive_file_entry in cpio_archive_file.GetFileEntries( | 34 for cpio_archive_file_entry in cpio_archive_file.GetFileEntries( |
33 path_prefix=location[1:]): | 35 path_prefix=location[1:]): |
34 | 36 |
35 path = cpio_archive_file_entry.path | 37 path = cpio_archive_file_entry.path |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 """Retrieves the link. | 93 """Retrieves the link. |
92 | 94 |
93 Raises: | 95 Raises: |
94 BackEndError: when the CPIO archive file entry is missing in | 96 BackEndError: when the CPIO archive file entry is missing in |
95 a non-virtual file entry. | 97 a non-virtual file entry. |
96 """ | 98 """ |
97 if self._link is None: | 99 if self._link is None: |
98 cpio_archive_file_entry = self.GetCPIOArchiveFileEntry() | 100 cpio_archive_file_entry = self.GetCPIOArchiveFileEntry() |
99 if not self._is_virtual and cpio_archive_file_entry is None: | 101 if not self._is_virtual and cpio_archive_file_entry is None: |
100 raise errors.BackEndError( | 102 raise errors.BackEndError( |
101 u'Missing CPIO archive file entry in non-virtual file entry.') | 103 'Missing CPIO archive file entry in non-virtual file entry.') |
102 | 104 |
103 self._link = u'' | 105 self._link = '' |
104 if stat.S_ISLNK(cpio_archive_file_entry.mode): | 106 if stat.S_ISLNK(cpio_archive_file_entry.mode): |
105 cpio_archive_file = self._file_system.GetCPIOArchiveFile() | 107 cpio_archive_file = self._file_system.GetCPIOArchiveFile() |
106 link_data = cpio_archive_file.ReadDataAtOffset( | 108 link_data = cpio_archive_file.ReadDataAtOffset( |
107 cpio_archive_file_entry.data_offset, | 109 cpio_archive_file_entry.data_offset, |
108 cpio_archive_file_entry.data_size) | 110 cpio_archive_file_entry.data_size) |
109 | 111 |
110 # TODO: should this be ASCII? | 112 # TODO: should this be ASCII? |
111 self._link = link_data.decode(u'ascii') | 113 self._link = link_data.decode('ascii') |
112 | 114 |
113 return self._link | 115 return self._link |
114 | 116 |
115 def _GetStat(self): | 117 def _GetStat(self): |
116 """Retrieves the stat object. | 118 """Retrieves the stat object. |
117 | 119 |
118 Returns: | 120 Returns: |
119 The stat object (instance of vfs.VFSStat). | 121 The stat object (instance of vfs.VFSStat). |
120 | 122 |
121 Raises: | 123 Raises: |
122 BackEndError: when the CPIO archive file entry is missing in | 124 BackEndError: when the CPIO archive file entry is missing in |
123 a non-virtual file entry. | 125 a non-virtual file entry. |
124 """ | 126 """ |
125 cpio_archive_file_entry = self.GetCPIOArchiveFileEntry() | 127 cpio_archive_file_entry = self.GetCPIOArchiveFileEntry() |
126 if not self._is_virtual and cpio_archive_file_entry is None: | 128 if not self._is_virtual and cpio_archive_file_entry is None: |
127 raise errors.BackEndError( | 129 raise errors.BackEndError( |
128 u'Missing CPIO archive file entry in non-virtual file entry.') | 130 'Missing CPIO archive file entry in non-virtual file entry.') |
129 | 131 |
130 stat_object = vfs_stat.VFSStat() | 132 stat_object = vfs_stat.VFSStat() |
131 | 133 |
132 # File data stat information. | 134 # File data stat information. |
133 stat_object.size = getattr(cpio_archive_file_entry, u'data_size', None) | 135 stat_object.size = getattr(cpio_archive_file_entry, 'data_size', None) |
134 | 136 |
135 # Date and time stat information. | 137 # Date and time stat information. |
136 stat_object.mtime = getattr( | 138 stat_object.mtime = getattr( |
137 cpio_archive_file_entry, u'modification_time', None) | 139 cpio_archive_file_entry, 'modification_time', None) |
138 | 140 |
139 # Ownership and permissions stat information. | 141 # Ownership and permissions stat information. |
140 mode = getattr(cpio_archive_file_entry, u'mode', 0) | 142 mode = getattr(cpio_archive_file_entry, 'mode', 0) |
141 stat_object.mode = stat.S_IMODE(mode) | 143 stat_object.mode = stat.S_IMODE(mode) |
142 stat_object.uid = getattr( | 144 stat_object.uid = getattr( |
143 cpio_archive_file_entry, u'user_identifier', None) | 145 cpio_archive_file_entry, 'user_identifier', None) |
144 stat_object.gid = getattr( | 146 stat_object.gid = getattr( |
145 cpio_archive_file_entry, u'group_identifier', None) | 147 cpio_archive_file_entry, 'group_identifier', None) |
146 | 148 |
147 # File entry type stat information. | 149 # File entry type stat information. |
148 | 150 |
149 # The stat info member st_mode can have multiple types e.g. | 151 # The stat info member st_mode can have multiple types e.g. |
150 # LINK and DIRECTORY in case of a symbolic link to a directory | 152 # LINK and DIRECTORY in case of a symbolic link to a directory |
151 # dfVFS currently only supports one type so we need to check | 153 # dfVFS currently only supports one type so we need to check |
152 # for LINK first. | 154 # for LINK first. |
153 if stat.S_ISLNK(mode): | 155 if stat.S_ISLNK(mode): |
154 stat_object.type = stat_object.TYPE_LINK | 156 stat_object.type = stat_object.TYPE_LINK |
155 # The root file entry is virtual and should have type directory. | 157 # The root file entry is virtual and should have type directory. |
(...skipping 11 matching lines...) Expand all Loading... |
167 return stat_object | 169 return stat_object |
168 | 170 |
169 @property | 171 @property |
170 def name(self): | 172 def name(self): |
171 """The name of the file entry, which does not include the full path.""" | 173 """The name of the file entry, which does not include the full path.""" |
172 cpio_archive_file_entry = self.GetCPIOArchiveFileEntry() | 174 cpio_archive_file_entry = self.GetCPIOArchiveFileEntry() |
173 | 175 |
174 # Note that the root file entry is virtual and has no | 176 # Note that the root file entry is virtual and has no |
175 # cpio_archive_file_entry. | 177 # cpio_archive_file_entry. |
176 if cpio_archive_file_entry is None: | 178 if cpio_archive_file_entry is None: |
177 return u'' | 179 return '' |
178 | 180 |
179 return self._file_system.BasenamePath(cpio_archive_file_entry.path) | 181 return self._file_system.BasenamePath(cpio_archive_file_entry.path) |
180 | 182 |
181 @property | 183 @property |
182 def sub_file_entries(self): | 184 def sub_file_entries(self): |
183 """The sub file entries (generator of instance of vfs.FileEntry).""" | 185 """The sub file entries (generator of instance of vfs.FileEntry).""" |
184 if self._directory is None: | 186 if self._directory is None: |
185 self._directory = self._GetDirectory() | 187 self._directory = self._GetDirectory() |
186 | 188 |
187 if self._directory: | 189 if self._directory: |
188 for path_spec in self._directory.entries: | 190 for path_spec in self._directory.entries: |
189 yield CPIOFileEntry( | 191 yield CPIOFileEntry( |
190 self._resolver_context, self._file_system, path_spec) | 192 self._resolver_context, self._file_system, path_spec) |
191 | 193 |
192 def GetCPIOArchiveFileEntry(self): | 194 def GetCPIOArchiveFileEntry(self): |
193 """Retrieves the CPIO archive file entry object. | 195 """Retrieves the CPIO archive file entry object. |
194 | 196 |
195 Returns: | 197 Returns: |
196 The CPIO archive file entry object (instance of | 198 The CPIO archive file entry object (instance of |
197 cpio.CPIOArchiveFileEntry). | 199 cpio.CPIOArchiveFileEntry). |
198 | 200 |
199 Raises: | 201 Raises: |
200 ValueError: if the path specification is incorrect. | 202 ValueError: if the path specification is incorrect. |
201 """ | 203 """ |
202 if not self._cpio_archive_file_entry: | 204 if not self._cpio_archive_file_entry: |
203 location = getattr(self.path_spec, u'location', None) | 205 location = getattr(self.path_spec, 'location', None) |
204 if location is None: | 206 if location is None: |
205 raise ValueError(u'Path specification missing location.') | 207 raise ValueError('Path specification missing location.') |
206 | 208 |
207 if not location.startswith(self._file_system.LOCATION_ROOT): | 209 if not location.startswith(self._file_system.LOCATION_ROOT): |
208 raise ValueError(u'Invalid location in path specification.') | 210 raise ValueError('Invalid location in path specification.') |
209 | 211 |
210 if len(location) == 1: | 212 if len(location) == 1: |
211 return | 213 return |
212 | 214 |
213 cpio_archive_file = self._file_system.GetCPIOArchiveFile() | 215 cpio_archive_file = self._file_system.GetCPIOArchiveFile() |
214 self._cpio_archive_file_entry = cpio_archive_file.GetFileEntryByPath( | 216 self._cpio_archive_file_entry = cpio_archive_file.GetFileEntryByPath( |
215 location[1:]) | 217 location[1:]) |
216 | 218 |
217 return self._cpio_archive_file_entry | 219 return self._cpio_archive_file_entry |
218 | 220 |
219 def GetParentFileEntry(self): | 221 def GetParentFileEntry(self): |
220 """Retrieves the parent file entry.""" | 222 """Retrieves the parent file entry.""" |
221 location = getattr(self.path_spec, u'location', None) | 223 location = getattr(self.path_spec, 'location', None) |
222 if location is None: | 224 if location is None: |
223 return | 225 return |
224 | 226 |
225 parent_location = self._file_system.DirnamePath(location) | 227 parent_location = self._file_system.DirnamePath(location) |
226 if parent_location is None: | 228 if parent_location is None: |
227 return | 229 return |
228 if parent_location == u'': | 230 if parent_location == '': |
229 parent_location = self._file_system.PATH_SEPARATOR | 231 parent_location = self._file_system.PATH_SEPARATOR |
230 | 232 |
231 parent_path_spec = getattr(self.path_spec, u'parent', None) | 233 parent_path_spec = getattr(self.path_spec, 'parent', None) |
232 path_spec = cpio_path_spec.CPIOPathSpec( | 234 path_spec = cpio_path_spec.CPIOPathSpec( |
233 location=parent_location, parent=parent_path_spec) | 235 location=parent_location, parent=parent_path_spec) |
234 return CPIOFileEntry(self._resolver_context, self._file_system, path_spec) | 236 return CPIOFileEntry(self._resolver_context, self._file_system, path_spec) |
OLD | NEW |