unArchive static method
Unarchives file to targetDir.
Symmetric to archive method.
Implementation
static void unArchive(UnArchiveOptions options) {
_log(options.logBuffer,
'--- Unarchive Started: ${p.basename(options.file.path)} ---');
final extName = p.extension(options.file.path);
final isCompressed = extName.endsWith('.gz') || extName.endsWith('.tgz');
final inputStream = options.file.openRead();
final input =
isCompressed ? inputStream.transform(gzip.decoder) : inputStream;
TarReader.forEach(input, (tarEntry) async {
final location =
p.normalize(p.join(options.targetDir.path, tarEntry.name));
if (!p.isWithin(options.targetDir.path, location)) {
_log(options.logBuffer,
'Warning: Skipping insecure entry: ${tarEntry.name}');
return;
}
if (tarEntry.type == TypeFlag.dir) {
_log(options.logBuffer, 'Creating dir: ${tarEntry.name}');
Directory(location).createSync(recursive: true);
return;
}
if (tarEntry.type == TypeFlag.reg) {
final targetFile = File(location);
targetFile.parent.createSync(recursive: true);
_log(options.logBuffer, 'Extracting file: ${tarEntry.name}');
try {
await tarEntry.contents.pipe(targetFile.openWrite());
targetFile.setLastModifiedSync(tarEntry.modified);
options.onFileExtracted?.call(targetFile);
} catch (e) {
_log(options.logBuffer, 'Pipe failed for ${tarEntry.name}: $e');
rethrow;
}
}
}).then((_) {
_log(options.logBuffer, '--- Unarchive Completed Successfully ---');
options.onSuccess?.call();
}).catchError((e, st) {
_log(options.logBuffer, '!!! Unarchive Failed: $e');
options.onError?.call(e, st);
});
}