Skip to content

Commit dd33635

Browse files
committed
fixed command line handling and file name checking on decompression
1 parent 5704fcb commit dd33635

File tree

3 files changed

+55
-8
lines changed

3 files changed

+55
-8
lines changed

Blazer.Exe/Program.cs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public static int Main(string[] args)
4040
return 0;
4141
}
4242

43+
#if DEBUG
44+
return Process(options);
45+
#else
4346
try
4447
{
4548
return Process(options);
@@ -49,6 +52,7 @@ public static int Main(string[] args)
4952
Console.Error.WriteLine(ex.Message);
5053
return 1;
5154
}
55+
#endif
5256
}
5357

5458
private static int Process(CommandLineParser<BlazerCommandLineOptions> options)
@@ -149,6 +153,11 @@ private static int ProcessCompress(CommandLineParser<BlazerCommandLineOptions> o
149153
BlazerFlags flagsBlockSize;
150154
if (Enum.TryParse("InBlockSize" + opt.MaxBlockSize, true, out flagsBlockSize))
151155
compressionOptions.SetMaxBlockSizeFromFlags(flagsBlockSize);
156+
else
157+
{
158+
Console.Error.WriteLine("Unsupported value for max block size");
159+
return 1;
160+
}
152161
}
153162
}
154163

@@ -216,22 +225,24 @@ private static int ProcessDecompress(CommandLineParser<BlazerCommandLineOptions>
216225

217226
Regex[] customOutFileNames = fileOptions.SourceFiles
218227
.Where(x => !string.IsNullOrWhiteSpace(x)).Select(x => x.Trim())
219-
.Select(x => new Regex(new string(x.SelectMany(y => char.IsLetterOrDigit(y) ? new[] { y } : (y == '*' ? new[] { '.', '*' } : new[] { '\\', y })).ToArray())))
228+
.Select(x => new Regex(new string(x.SelectMany(y => char.IsLetterOrDigit(y) || y == '_' ? new[] { y } : (y == '*' ? new[] { '.', '*' } : new[] { '\\', y })).ToArray())))
220229
.ToArray();
221230

222231
if (customOutFileNames.Length == 0)
223232
customOutFileNames = new[] { new Regex(".*") };
224233

225234
Stream inStreamSource = opt.Stdin ? Console.OpenStandardInput() : File.OpenRead(fileOptions.ArchiveName);
226235

227-
var decOptions = new BlazerDecompressionOptions(opt.Password) { EncyptFull = opt.EncryptFull };
236+
var decOptions = new BlazerDecompressionOptions(opt.Password) { EncyptFull = opt.EncryptFull, DoNotFireInfoCallbackOnOneFile = true };
228237

229238
BlazerOutputStream outBlazerStream = null;
230239
Stream outStream;
231240
BlazerFileInfo prevFile = null;
232241
Stream[] outFile = { null };
233242
bool forceAllOverride = false;
234243
bool forceAllSkip = opt.Stdin && !opt.Force; // nothing to do, just skip
244+
bool hasMultipleFiles = false;
245+
bool doExit = false;
235246
decOptions.FileInfoCallback = fInfo =>
236247
{
237248
if (opt.Stdout)
@@ -269,13 +280,28 @@ private static int ProcessDecompress(CommandLineParser<BlazerCommandLineOptions>
269280
return;
270281
if (!opt.Force && !forceAllOverride)
271282
{
272-
Console.WriteLine("Target " + fInfoFileName + " already exists. Overwrite? (Y)es (N)o (A)ll (S)kip all existing");
283+
// ReSharper disable AccessToModifiedClosure
284+
Console.WriteLine("Target " + fInfoFileName + " already exists. Overwrite? (Y)es (N)o" + (hasMultipleFiles ? " (A)ll (S)kip all existing" : string.Empty));
285+
// ReSharper restore AccessToModifiedClosure
273286
var readLine = Console.ReadLine().Trim().ToLowerInvariant();
274287

275288
forceAllOverride = readLine.IndexOf("a", StringComparison.Ordinal) >= 0;
276289
forceAllSkip = readLine.IndexOf("s", StringComparison.Ordinal) >= 0;
277290
if (!forceAllOverride && readLine.IndexOf("y", StringComparison.Ordinal) < 0)
291+
{
292+
// ReSharper disable AccessToModifiedClosure
293+
if (!hasMultipleFiles)
294+
{
295+
doExit = true;
296+
return;
297+
}
298+
// ReSharper restore AccessToModifiedClosure
299+
300+
var sts = outFile[0] as StatStream;
301+
if (sts != null)
302+
sts.Prefix = "Skipping " + fInfo.FileName + " ";
278303
return;
304+
}
279305
}
280306

281307
new FileStream(fInfoFileName, FileMode.Truncate, FileAccess.Write).Close();
@@ -312,8 +338,14 @@ private static int ProcessDecompress(CommandLineParser<BlazerCommandLineOptions>
312338
outStream = outBlazerStream;
313339
}
314340

341+
if (opt.NoFileName && outBlazerStream.HaveMultipleFiles)
342+
{
343+
Console.Error.WriteLine("Cannot decompress without filename when archive contains multiple files");
344+
return 1;
345+
}
346+
315347
var fileName = Path.GetFileName(fileOptions.ArchiveName ?? "dummy");
316-
if (fileName.EndsWith(".blz")) fileName = fileName.Substring(0, fileName.Length - 5);
348+
if (fileName.EndsWith(".blz")) fileName = fileName.Substring(0, fileName.Length - 4);
317349
else fileName += (fileName.EndsWith(".") ? string.Empty : ".") + "unpacked";
318350

319351
if (outBlazerStream != null && outBlazerStream.FileInfo != null && !opt.NoFileName)
@@ -325,24 +357,30 @@ private static int ProcessDecompress(CommandLineParser<BlazerCommandLineOptions>
325357
if (!outBlazerStream.HaveMultipleFiles && !customOutFileNames.Any(y => y.IsMatch(fileName)))
326358
return 0;
327359

360+
hasMultipleFiles = outBlazerStream.HaveMultipleFiles;
361+
328362
if (opt.Stdout) outFile[0] = Console.OpenStandardOutput();
363+
if (!hasMultipleFiles)
364+
decOptions.FileInfoCallback(new BlazerFileInfo { FileName = fileName, CreationTimeUtc = DateTime.UtcNow, LastWriteTimeUtc = DateTime.UtcNow });
329365
// we haven't received an file info from callback
330-
if (outFile[0] == null && !outBlazerStream.HaveMultipleFiles)
331-
outFile[0] = new StatStream(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read), true);
366+
// if (outFile[0] == null && !outBlazerStream.HaveMultipleFiles)
367+
// outFile[0] = new StatStream(new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read), true);
332368

333369
using (var inFile = outStream)
334370
{
335371
var buf = new byte[81920];
336372
int cnt = 1;
337373
while (cnt > 0)
338374
{
375+
if (doExit)
376+
break;
339377
cnt = inFile.Read(buf, 0, buf.Length);
340378
if (outFile[0] != null)
341379
outFile[0].Write(buf, 0, cnt);
342380
}
343381
}
344382

345-
if (prevFile != null)
383+
if (prevFile != null && outFile[0] != null)
346384
{
347385
outFile[0].Flush();
348386
outFile[0].Close();
@@ -464,7 +502,7 @@ private static int ProcessList(CommandLineParser<BlazerCommandLineOptions> optio
464502
if (fi == null && !outStream.HaveMultipleFiles)
465503
{
466504
var fileName = Path.GetFileName(fileOptions.ArchiveName ?? "dummy");
467-
if (fileName.EndsWith(".blz")) fileName = fileName.Substring(0, fileName.Length - 5);
505+
if (fileName.EndsWith(".blz")) fileName = fileName.Substring(0, fileName.Length - 4);
468506
else fileName += (fileName.EndsWith(".") ? string.Empty : ".") + "unpacked";
469507

470508
decOptions.FileInfoCallback(new BlazerFileInfo

Blazer.Net/BlazerDecompressionOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public void SetDecoderByAlgorithm(BlazerAlgorithm algorithm)
5858
/// </summary>
5959
public Action<BlazerFileInfo> FileInfoCallback { get; set; }
6060

61+
/// <summary>
62+
/// Skip <see cref="FileInfoCallback"/> when archive contains only one file (can be useful, when file name is analyzed manually)
63+
/// </summary>
64+
public bool DoNotFireInfoCallbackOnOneFile { get; set; }
65+
6166
/// <summary>
6267
/// Create default options
6368
/// </summary>

Blazer.Net/BlazerOutputStream.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ public string Comment
206206

207207
private Action<BlazerFileInfo> _fileInfoCallback { get; set; }
208208

209+
private bool _doNotFireInfoCallbackOnOneFile { get; set; }
210+
209211
/// <summary>
210212
/// Constructs Blazer decompression stream
211213
/// </summary>
@@ -220,6 +222,7 @@ public BlazerOutputStream(Stream innerStream, BlazerDecompressionOptions options
220222
var password = options.Password;
221223
_controlDataCallback = options.ControlDataCallback ?? ((b, o, c) => { });
222224
_fileInfoCallback = options.FileInfoCallback ?? (f => { });
225+
_doNotFireInfoCallbackOnOneFile = options.DoNotFireInfoCallbackOnOneFile;
223226
_noSeek = options.NoSeek;
224227

225228
if (options.EncyptFull)
@@ -312,6 +315,7 @@ private void ReadCommonBlocks()
312315
throw new InvalidOperationException("Invalid file info header");
313316

314317
_fileInfo = FileHeaderHelper.ParseFileHeader(fInfo.Buffer, fInfo.Offset, fInfo.Count);
318+
if (!_haveMultipleFiles && !_doNotFireInfoCallbackOnOneFile)
315319
_fileInfoCallback(_fileInfo);
316320
}
317321
}

0 commit comments

Comments
 (0)