~ubuntu-branches/ubuntu/quantal/unrar-nonfree/quantal

1 by Chris Anderson
Import upstream version 3.3.6
1
#include "rar.hpp"
2
3
CmdExtract::CmdExtract()
4
{
5
  TotalFileCount=0;
6
  *Password=0;
7
  Unp=new Unpack(&DataIO);
8
  Unp->Init(NULL);
9
}
10
11
12
CmdExtract::~CmdExtract()
13
{
14
  delete Unp;
15
  memset(Password,0,sizeof(Password));
16
}
17
18
19
void CmdExtract::DoExtract(CommandData *Cmd)
20
{
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
21
  PasswordCancelled=false;
1 by Chris Anderson
Import upstream version 3.3.6
22
  DataIO.SetCurrentCommand(*Cmd->Command);
23
1.2.10 by Martin Meredith
Import upstream version 4.0.2
24
  FindData FD;
25
  while (Cmd->GetArcName(ArcName,ArcNameW,ASIZE(ArcName)))
1 by Chris Anderson
Import upstream version 3.3.6
26
    if (FindFile::FastFind(ArcName,ArcNameW,&FD))
27
      DataIO.TotalArcSize+=FD.Size;
1.2.1 by Martin Meredith
Import upstream version 3.8.2
28
1 by Chris Anderson
Import upstream version 3.3.6
29
  Cmd->ArcNames->Rewind();
1.2.10 by Martin Meredith
Import upstream version 4.0.2
30
  while (Cmd->GetArcName(ArcName,ArcNameW,ASIZE(ArcName)))
1 by Chris Anderson
Import upstream version 3.3.6
31
  {
1.1.4 by Martin Meredith
Import upstream version 3.6.8
32
    while (true)
33
    {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
34
      wchar PrevCmdPassword[MAXPASSWORD];
35
      wcscpy(PrevCmdPassword,Cmd->Password);
1.1.4 by Martin Meredith
Import upstream version 3.6.8
36
37
      EXTRACT_ARC_CODE Code=ExtractArchive(Cmd);
38
1.2.4 by Martin Meredith
Import upstream version 3.9.3
39
      // Restore Cmd->Password, which could be changed in IsArchive() call
40
      // for next header encrypted archive.
1.2.10 by Martin Meredith
Import upstream version 4.0.2
41
      wcscpy(Cmd->Password,PrevCmdPassword);
1.1.4 by Martin Meredith
Import upstream version 3.6.8
42
43
      if (Code!=EXTRACT_ARC_REPEAT)
44
        break;
45
    }
1 by Chris Anderson
Import upstream version 3.3.6
46
    if (FindFile::FastFind(ArcName,ArcNameW,&FD))
47
      DataIO.ProcessedArcSize+=FD.Size;
48
  }
49
50
  if (TotalFileCount==0 && *Cmd->Command!='I')
51
  {
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
52
    if (!PasswordCancelled)
53
    {
54
      mprintf(St(MExtrNoFiles));
55
    }
1.2.10 by Martin Meredith
Import upstream version 4.0.2
56
    ErrHandler.SetErrorCode(NO_FILES_ERROR);
1 by Chris Anderson
Import upstream version 3.3.6
57
  }
58
#ifndef GUI
59
  else
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
60
    if (!Cmd->DisableDone)
61
      if (*Cmd->Command=='I')
62
        mprintf(St(MDone));
1 by Chris Anderson
Import upstream version 3.3.6
63
      else
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
64
        if (ErrHandler.GetErrorCount()==0)
65
          mprintf(St(MExtrAllOk));
66
        else
67
          mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount());
1 by Chris Anderson
Import upstream version 3.3.6
68
#endif
69
}
70
71
72
void CmdExtract::ExtractArchiveInit(CommandData *Cmd,Archive &Arc)
73
{
74
  DataIO.UnpArcSize=Arc.FileLength();
75
76
  FileCount=0;
77
  MatchedArgs=0;
78
#ifndef SFX_MODULE
79
  FirstFile=true;
80
#endif
81
82
  if (*Cmd->Password!=0)
1.2.10 by Martin Meredith
Import upstream version 4.0.2
83
    wcscpy(Password,Cmd->Password);
1 by Chris Anderson
Import upstream version 3.3.6
84
  PasswordAll=(*Cmd->Password!=0);
85
86
  DataIO.UnpVolume=false;
87
88
  PrevExtracted=false;
89
  SignatureFound=false;
90
  AllMatchesExact=true;
91
  ReconstructDone=false;
1.2.10 by Martin Meredith
Import upstream version 4.0.2
92
  AnySolidDataUnpackedWell=false;
1.2.1 by Martin Meredith
Import upstream version 3.8.2
93
94
  StartTime.SetCurrentTime();
1 by Chris Anderson
Import upstream version 3.3.6
95
}
96
97
98
EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd)
99
{
100
  Archive Arc(Cmd);
101
  if (!Arc.WOpen(ArcName,ArcNameW))
102
  {
103
    ErrHandler.SetErrorCode(OPEN_ERROR);
104
    return(EXTRACT_ARC_NEXT);
105
  }
106
107
  if (!Arc.IsArchive(true))
108
  {
109
#ifndef GUI
110
    mprintf(St(MNotRAR),ArcName);
111
#endif
112
    if (CmpExt(ArcName,"rar"))
113
      ErrHandler.SetErrorCode(WARNING);
114
    return(EXTRACT_ARC_NEXT);
115
  }
116
1.2.12 by Martin Meredith
Import upstream version 4.1.4
117
  // Archive with corrupt encrypted header can be closed in IsArchive() call.
118
//  if (!Arc.IsOpened())
119
//    return(EXTRACT_ARC_NEXT);
1 by Chris Anderson
Import upstream version 3.3.6
120
121
#ifndef SFX_MODULE
122
  if (Arc.Volume && Arc.NotFirstVolume)
123
  {
124
    char FirstVolName[NM];
1.2.4 by Martin Meredith
Import upstream version 3.9.3
125
    VolNameToFirstName(ArcName,FirstVolName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0);
1.2.1 by Martin Meredith
Import upstream version 3.8.2
126
127
    // If several volume names from same volume set are specified
128
    // and current volume is not first in set and first volume is present
129
    // and specified too, let's skip the current volume.
1 by Chris Anderson
Import upstream version 3.3.6
130
    if (stricomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) &&
131
        Cmd->ArcNames->Search(FirstVolName,NULL,false))
132
      return(EXTRACT_ARC_NEXT);
133
  }
134
#endif
1.2.1 by Martin Meredith
Import upstream version 3.8.2
135
1.2.4 by Martin Meredith
Import upstream version 3.9.3
136
  int64 VolumeSetSize=0; // Total size of volumes after the current volume.
137
1.2.1 by Martin Meredith
Import upstream version 3.8.2
138
  if (Arc.Volume)
139
  {
140
    // Calculate the total size of all accessible volumes.
141
    // This size is necessary to display the correct total progress indicator.
142
143
    char NextName[NM];
144
    wchar NextNameW[NM];
145
146
    strcpy(NextName,Arc.FileName);
1.2.10 by Martin Meredith
Import upstream version 4.0.2
147
    wcscpy(NextNameW,Arc.FileNameW);
1.2.1 by Martin Meredith
Import upstream version 3.8.2
148
149
    while (true)
150
    {
151
      // First volume is already added to DataIO.TotalArcSize 
152
      // in initial TotalArcSize calculation in DoExtract.
153
      // So we skip it and start from second volume.
154
      NextVolumeName(NextName,NextNameW,ASIZE(NextName),(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
155
      struct FindData FD;
156
      if (FindFile::FastFind(NextName,NextNameW,&FD))
1.2.4 by Martin Meredith
Import upstream version 3.9.3
157
        VolumeSetSize+=FD.Size;
1.2.1 by Martin Meredith
Import upstream version 3.8.2
158
      else
159
        break;
160
    }
1.2.4 by Martin Meredith
Import upstream version 3.9.3
161
    DataIO.TotalArcSize+=VolumeSetSize;
1.2.1 by Martin Meredith
Import upstream version 3.8.2
162
  }
163
1 by Chris Anderson
Import upstream version 3.3.6
164
  ExtractArchiveInit(Cmd,Arc);
165
166
  if (*Cmd->Command=='T' || *Cmd->Command=='I')
167
    Cmd->Test=true;
168
1.2.12 by Martin Meredith
Import upstream version 4.1.4
169
1 by Chris Anderson
Import upstream version 3.3.6
170
#ifndef GUI
171
  if (*Cmd->Command=='I')
172
    Cmd->DisablePercentage=true;
173
  else
174
    if (Cmd->Test)
175
      mprintf(St(MExtrTest),ArcName);
176
    else
177
      mprintf(St(MExtracting),ArcName);
178
#endif
179
180
  Arc.ViewComment();
181
1.1.7 by Martin Meredith
Import upstream version 3.7.8
182
  // RAR can close a corrupt encrypted archive
1.2.12 by Martin Meredith
Import upstream version 4.1.4
183
//  if (!Arc.IsOpened())
184
//    return(EXTRACT_ARC_NEXT);
1.1.7 by Martin Meredith
Import upstream version 3.7.8
185
186
1 by Chris Anderson
Import upstream version 3.3.6
187
  while (1)
188
  {
1.2.4 by Martin Meredith
Import upstream version 3.9.3
189
    size_t Size=Arc.ReadHeader();
1 by Chris Anderson
Import upstream version 3.3.6
190
    bool Repeat=false;
191
    if (!ExtractCurrentFile(Cmd,Arc,Size,Repeat))
192
      if (Repeat)
193
      {
1.2.4 by Martin Meredith
Import upstream version 3.9.3
194
        // If we started extraction from not first volume and need to
195
        // restart it from first, we must correct DataIO.TotalArcSize
196
        // for correct total progress display. We subtract the size
197
        // of current volume and all volumes after it and add the size
198
        // of new (first) volume.
1.2.10 by Martin Meredith
Import upstream version 4.0.2
199
        FindData OldArc,NewArc;
1.2.4 by Martin Meredith
Import upstream version 3.9.3
200
        if (FindFile::FastFind(Arc.FileName,Arc.FileNameW,&OldArc) &&
201
            FindFile::FastFind(ArcName,ArcNameW,&NewArc))
202
          DataIO.TotalArcSize-=VolumeSetSize+OldArc.Size-NewArc.Size;
1 by Chris Anderson
Import upstream version 3.3.6
203
        return(EXTRACT_ARC_REPEAT);
204
      }
205
      else
206
        break;
207
  }
1.1.4 by Martin Meredith
Import upstream version 3.6.8
208
1 by Chris Anderson
Import upstream version 3.3.6
209
  return(EXTRACT_ARC_NEXT);
210
}
211
212
1.2.4 by Martin Meredith
Import upstream version 3.9.3
213
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat)
1 by Chris Anderson
Import upstream version 3.3.6
214
{
215
  char Command=*Cmd->Command;
1.2.4 by Martin Meredith
Import upstream version 3.9.3
216
  if (HeaderSize==0)
1 by Chris Anderson
Import upstream version 3.3.6
217
    if (DataIO.UnpVolume)
218
    {
219
#ifdef NOVOLUME
220
      return(false);
221
#else
1.2.1 by Martin Meredith
Import upstream version 3.8.2
222
      if (!MergeArchive(Arc,&DataIO,false,Command))
1 by Chris Anderson
Import upstream version 3.3.6
223
      {
224
        ErrHandler.SetErrorCode(WARNING);
225
        return(false);
226
      }
227
      SignatureFound=false;
228
#endif
229
    }
230
    else
231
      return(false);
232
  int HeadType=Arc.GetHeaderType();
233
  if (HeadType!=FILE_HEAD)
234
  {
235
    if (HeadType==AV_HEAD || HeadType==SIGN_HEAD)
236
      SignatureFound=true;
237
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
238
    if (HeadType==SUB_HEAD && PrevExtracted)
239
      SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
240
#endif
241
    if (HeadType==NEWSUB_HEAD)
242
    {
243
      if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV))
244
        SignatureFound=true;
245
#if !defined(NOSUBBLOCKS) && !defined(_WIN_CE)
246
      if (PrevExtracted)
247
        SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
248
#endif
249
    }
250
    if (HeadType==ENDARC_HEAD)
251
      if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)
252
      {
253
#ifndef NOVOLUME
1.2.1 by Martin Meredith
Import upstream version 3.8.2
254
        if (!MergeArchive(Arc,&DataIO,false,Command))
1 by Chris Anderson
Import upstream version 3.3.6
255
        {
256
          ErrHandler.SetErrorCode(WARNING);
257
          return(false);
258
        }
259
        SignatureFound=false;
260
#endif
261
        Arc.Seek(Arc.CurBlockPos,SEEK_SET);
262
        return(true);
263
      }
264
      else
265
        return(false);
266
    Arc.SeekToNext();
267
    return(true);
268
  }
269
  PrevExtracted=false;
270
271
  if (SignatureFound ||
272
      !Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() &&
273
      AllMatchesExact)
274
    return(false);
275
276
  char ArcFileName[NM];
277
  IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
278
  strcpy(ArcFileName,Arc.NewLhd.FileName);
279
280
  wchar ArcFileNameW[NM];
281
  *ArcFileNameW=0;
282
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
283
  int MatchType=MATCH_WILDSUBPATH;
284
1 by Chris Anderson
Import upstream version 3.3.6
285
  bool EqualNames=false;
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
286
  int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType);
1 by Chris Anderson
Import upstream version 3.3.6
287
  bool ExactMatch=MatchNumber!=0;
288
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
289
  if (Cmd->ExclPath==EXCL_BASEPATH)
290
  {
291
    *Cmd->ArcPath=0;
292
    if (ExactMatch)
293
    {
294
      Cmd->FileArgs->Rewind();
295
      if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1))
296
        *PointToName(Cmd->ArcPath)=0;
297
    }
298
  }
299
#endif
300
  if (ExactMatch && !EqualNames)
301
    AllMatchesExact=false;
302
303
#ifdef UNICODE_SUPPORTED
1.1.1 by Chris Anderson
Import upstream version 3.4.3
304
  bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled();
1 by Chris Anderson
Import upstream version 3.3.6
305
#else
306
  bool WideName=false;
307
#endif
308
309
#ifdef _APPLE
310
  if (WideName)
311
  {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
312
    // Prepare UTF-8 name for OS X. Since we are sure that destination
313
    // is UTF-8, we can avoid calling the less reliable WideToChar function.
314
    WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,ASIZE(ArcFileName));
1 by Chris Anderson
Import upstream version 3.3.6
315
    WideName=false;
316
  }
317
#endif
318
319
  wchar *DestNameW=WideName ? DestFileNameW:NULL;
320
321
#ifdef UNICODE_SUPPORTED
322
  if (WideName)
323
  {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
324
    // Prepare the name in single byte native encoding (typically UTF-8
325
    // for Unix-based systems). Windows does not really need it,
326
    // but Unix system will use this name instead of Unicode.
1 by Chris Anderson
Import upstream version 3.3.6
327
    ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW);
328
    char Name[NM];
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
329
    if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name))
1 by Chris Anderson
Import upstream version 3.3.6
330
      strcpy(ArcFileName,Name);
331
  }
332
#endif
333
334
  ConvertPath(ArcFileName,ArcFileName);
335
336
  if (Arc.IsArcLabel())
337
    return(true);
338
339
  if (Arc.NewLhd.Flags & LHD_VERSION)
340
  {
341
    if (Cmd->VersionControl!=1 && !EqualNames)
342
    {
343
      if (Cmd->VersionControl==0)
344
        ExactMatch=false;
345
      int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false);
346
      if (Cmd->VersionControl-1==Version)
347
        ParseVersionFileName(ArcFileName,ArcFileNameW,true);
348
      else
349
        ExactMatch=false;
350
    }
351
  }
352
  else
353
    if (!Arc.IsArcDir() && Cmd->VersionControl>1)
354
      ExactMatch=false;
355
356
  Arc.ConvertAttributes();
357
358
#ifndef SFX_MODULE
1.2.11 by Martin Meredith
Import upstream version 4.0.3
359
  if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 && FirstFile)
1 by Chris Anderson
Import upstream version 3.3.6
360
  {
361
    char CurVolName[NM];
362
    strcpy(CurVolName,ArcName);
363
1.2.10 by Martin Meredith
Import upstream version 4.0.2
364
    bool NewNumbering=(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0;
365
    VolNameToFirstName(ArcName,ArcName,NewNumbering);
366
    if (*ArcNameW!=0)
367
      VolNameToFirstName(ArcNameW,ArcNameW,NewNumbering);
368
369
    if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName,ArcNameW))
1 by Chris Anderson
Import upstream version 3.3.6
370
    {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
371
      // If first volume name does not match the current name and if
372
      // such volume name really exists, let's unpack from this first volume.
1 by Chris Anderson
Import upstream version 3.3.6
373
      Repeat=true;
374
      return(false);
375
    }
376
#if !defined(RARDLL) && !defined(_WIN_CE)
377
    if (!ReconstructDone)
378
    {
379
      ReconstructDone=true;
380
381
      RecVolumes RecVol;
382
      if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true))
383
      {
384
        Repeat=true;
385
        return(false);
386
      }
387
    }
388
#endif
389
    strcpy(ArcName,CurVolName);
390
  }
391
#endif
1.2.4 by Martin Meredith
Import upstream version 3.9.3
392
  DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0;
1 by Chris Anderson
Import upstream version 3.3.6
393
  DataIO.NextVolumeMissing=false;
394
395
  Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);
396
397
  bool TestMode=false;
398
  bool ExtrFile=false;
399
  bool SkipSolid=false;
400
401
#ifndef SFX_MODULE
402
  if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0)
403
  {
404
    if (ExactMatch)
405
    {
406
      Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName);
407
#ifdef RARDLL
408
      Cmd->DllError=ERAR_BAD_DATA;
409
#endif
1.2.1 by Martin Meredith
Import upstream version 3.8.2
410
      ErrHandler.SetErrorCode(OPEN_ERROR);
1 by Chris Anderson
Import upstream version 3.3.6
411
    }
412
    ExactMatch=false;
413
  }
414
415
  FirstFile=false;
416
#endif
417
418
  if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
419
  {
1.1.5 by Martin Meredith
Import upstream version 3.7.2
420
    if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0)
1 by Chris Anderson
Import upstream version 3.3.6
421
#ifndef RARDLL
422
      if (*Password==0)
423
#endif
424
      {
425
#ifdef RARDLL
426
        if (*Cmd->Password==0)
1.2.10 by Martin Meredith
Import upstream version 4.0.2
427
        {
428
          char PasswordA[MAXPASSWORD];
429
1 by Chris Anderson
Import upstream version 3.3.6
430
          if (Cmd->Callback==NULL ||
1.2.10 by Martin Meredith
Import upstream version 4.0.2
431
              Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1)
1 by Chris Anderson
Import upstream version 3.3.6
432
            return(false);
1.2.10 by Martin Meredith
Import upstream version 4.0.2
433
          GetWideName(PasswordA,NULL,Cmd->Password,ASIZE(Cmd->Password));
434
        }
435
        wcscpy(Password,Cmd->Password);
1 by Chris Anderson
Import upstream version 3.3.6
436
437
#else
1.2.10 by Martin Meredith
Import upstream version 4.0.2
438
        if (!GetPassword(PASSWORD_FILE,ArcFileName,ArcFileNameW,Password,ASIZE(Password)))
1 by Chris Anderson
Import upstream version 3.3.6
439
        {
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
440
          PasswordCancelled=true;
1 by Chris Anderson
Import upstream version 3.3.6
441
          return(false);
442
        }
443
#endif
444
      }
445
#if !defined(GUI) && !defined(SILENT)
446
      else
447
        if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0))
448
        {
449
          eprintf(St(MUseCurPsw),ArcFileName);
450
          switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll)))
451
          {
452
            case -1:
453
              ErrHandler.Exit(USER_BREAK);
454
            case 2:
1.2.10 by Martin Meredith
Import upstream version 4.0.2
455
              if (!GetPassword(PASSWORD_FILE,ArcFileName,ArcFileNameW,Password,ASIZE(Password)))
1 by Chris Anderson
Import upstream version 3.3.6
456
              {
457
                return(false);
458
              }
459
              break;
460
            case 3:
461
              PasswordAll=true;
462
              break;
463
          }
464
        }
465
#endif
466
467
#ifndef SFX_MODULE
468
    if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0)
469
      WideToChar(Cmd->ExtrPathW,DestFileName);
470
    else
471
#endif
472
      strcpy(DestFileName,Cmd->ExtrPath);
473
474
475
#ifndef SFX_MODULE
476
    if (Cmd->AppendArcNameToPath)
477
    {
1.1.5 by Martin Meredith
Import upstream version 3.7.2
478
      strcat(DestFileName,PointToName(Arc.FirstVolumeName));
1 by Chris Anderson
Import upstream version 3.3.6
479
      SetExt(DestFileName,NULL);
480
      AddEndSlash(DestFileName);
481
    }
482
#endif
483
484
    char *ExtrName=ArcFileName;
485
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
486
    bool EmptyName=false;
1 by Chris Anderson
Import upstream version 3.3.6
487
#ifndef SFX_MODULE
1.2.4 by Martin Meredith
Import upstream version 3.9.3
488
    size_t Length=strlen(Cmd->ArcPath);
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
489
    if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) &&
490
        strlen(ArcFileName)==Length-1)
491
      Length--;
1 by Chris Anderson
Import upstream version 3.3.6
492
    if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0)
493
    {
494
      ExtrName+=Length;
495
      while (*ExtrName==CPATHDIVIDER)
496
        ExtrName++;
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
497
      if (*ExtrName==0)
498
        EmptyName=true;
1 by Chris Anderson
Import upstream version 3.3.6
499
    }
500
#endif
501
1.2.11 by Martin Meredith
Import upstream version 4.0.3
502
    // Use -ep3 only in systems, where disk letters are exist, not in Unix.
1.1.1 by Chris Anderson
Import upstream version 3.4.3
503
    bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':');
1.2.11 by Martin Meredith
Import upstream version 4.0.3
504
505
    // We do not use any user specified destination paths when extracting
506
    // absolute paths in -ep3 mode.
1.1.1 by Chris Anderson
Import upstream version 3.4.3
507
    if (AbsPaths)
508
      *DestFileName=0;
509
1 by Chris Anderson
Import upstream version 3.3.6
510
    if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
511
      strcat(DestFileName,PointToName(ExtrName));
512
    else
513
      strcat(DestFileName,ExtrName);
514
1.1.5 by Martin Meredith
Import upstream version 3.7.2
515
    char DiskLetter=etoupper(DestFileName[0]);
1.1.4 by Martin Meredith
Import upstream version 3.6.8
516
1.2.11 by Martin Meredith
Import upstream version 4.0.3
517
    if (AbsPaths)
518
    {
519
      if (DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) &&
520
          DiskLetter>='A' && DiskLetter<='Z')
521
        DestFileName[1]=':';
522
      else
523
        if (DestFileName[0]=='_' && DestFileName[1]=='_')
524
        {
525
          // Convert __server\share to \\server\share.
526
          DestFileName[0]=CPATHDIVIDER;
527
          DestFileName[1]=CPATHDIVIDER;
528
        }
529
    }
1.1.1 by Chris Anderson
Import upstream version 3.4.3
530
1 by Chris Anderson
Import upstream version 3.3.6
531
#ifndef SFX_MODULE
532
    if (!WideName && *Cmd->ExtrPathW!=0)
533
    {
534
      DestNameW=DestFileNameW;
535
      WideName=true;
536
      CharToWide(ArcFileName,ArcFileNameW);
537
    }
538
#endif
539
540
    if (WideName)
541
    {
542
      if (*Cmd->ExtrPathW!=0)
1.2.10 by Martin Meredith
Import upstream version 4.0.2
543
        wcscpy(DestFileNameW,Cmd->ExtrPathW);
1 by Chris Anderson
Import upstream version 3.3.6
544
      else
545
        CharToWide(Cmd->ExtrPath,DestFileNameW);
546
547
#ifndef SFX_MODULE
548
      if (Cmd->AppendArcNameToPath)
549
      {
550
        wchar FileNameW[NM];
1.1.5 by Martin Meredith
Import upstream version 3.7.2
551
        if (*Arc.FirstVolumeNameW!=0)
1.2.10 by Martin Meredith
Import upstream version 4.0.2
552
          wcscpy(FileNameW,Arc.FirstVolumeNameW);
1 by Chris Anderson
Import upstream version 3.3.6
553
        else
1.1.5 by Martin Meredith
Import upstream version 3.7.2
554
          CharToWide(Arc.FirstVolumeName,FileNameW);
1.2.10 by Martin Meredith
Import upstream version 4.0.2
555
        wcscat(DestFileNameW,PointToName(FileNameW));
1 by Chris Anderson
Import upstream version 3.3.6
556
        SetExt(DestFileNameW,NULL);
557
        AddEndSlash(DestFileNameW);
558
      }
559
#endif
560
      wchar *ExtrNameW=ArcFileNameW;
561
#ifndef SFX_MODULE
562
      if (Length>0)
563
      {
564
        wchar ArcPathW[NM];
1.2.10 by Martin Meredith
Import upstream version 4.0.2
565
        GetWideName(Cmd->ArcPath,Cmd->ArcPathW,ArcPathW,ASIZE(ArcPathW));
566
        Length=wcslen(ArcPathW);
1 by Chris Anderson
Import upstream version 3.3.6
567
      }
568
      ExtrNameW+=Length;
569
      while (*ExtrNameW==CPATHDIVIDER)
570
        ExtrNameW++;
571
#endif
572
1.1.1 by Chris Anderson
Import upstream version 3.4.3
573
      if (AbsPaths)
574
        *DestFileNameW=0;
575
1 by Chris Anderson
Import upstream version 3.3.6
576
      if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
1.2.10 by Martin Meredith
Import upstream version 4.0.2
577
        wcscat(DestFileNameW,PointToName(ExtrNameW));
1 by Chris Anderson
Import upstream version 3.3.6
578
      else
1.2.10 by Martin Meredith
Import upstream version 4.0.2
579
        wcscat(DestFileNameW,ExtrNameW);
1.1.1 by Chris Anderson
Import upstream version 3.4.3
580
581
      if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2]))
582
        DestFileNameW[1]=':';
1 by Chris Anderson
Import upstream version 3.3.6
583
    }
584
    else
585
      *DestFileNameW=0;
586
1.1.5 by Martin Meredith
Import upstream version 3.7.2
587
    ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0;
588
1 by Chris Anderson
Import upstream version 3.3.6
589
    if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X'))
590
    {
591
      struct FindData FD;
592
      if (FindFile::FastFind(DestFileName,DestNameW,&FD))
593
      {
594
        if (FD.mtime >= Arc.NewLhd.mtime)
1.2.1 by Martin Meredith
Import upstream version 3.8.2
595
        {
596
          // If directory already exists and its modification time is newer 
597
          // than start of extraction, it is likely it was created 
598
          // when creating a path to one of already extracted items. 
599
          // In such case we'll better update its time even if archived 
600
          // directory is older.
601
602
          if (!FD.IsDir || FD.mtime<StartTime)
603
            ExtrFile=false;
604
        }
1 by Chris Anderson
Import upstream version 3.3.6
605
      }
606
      else
607
        if (Cmd->FreshFiles)
608
          ExtrFile=false;
609
    }
610
1.2.4 by Martin Meredith
Import upstream version 3.9.3
611
    // Skip encrypted file if no password is specified.
1.1.5 by Martin Meredith
Import upstream version 3.7.2
612
    if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && *Password==0)
613
    {
614
      ErrHandler.SetErrorCode(WARNING);
615
#ifdef RARDLL
616
      Cmd->DllError=ERAR_MISSING_PASSWORD;
617
#endif
618
      ExtrFile=false;
619
    }
620
1 by Chris Anderson
Import upstream version 3.3.6
621
#ifdef RARDLL
622
    if (*Cmd->DllDestName)
623
    {
1.1.5 by Martin Meredith
Import upstream version 3.7.2
624
      strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
1 by Chris Anderson
Import upstream version 3.3.6
625
      *DestFileNameW=0;
626
      if (Cmd->DllOpMode!=RAR_EXTRACT)
627
        ExtrFile=false;
628
    }
629
    if (*Cmd->DllDestNameW)
630
    {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
631
      wcsncpyz(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW));
1 by Chris Anderson
Import upstream version 3.3.6
632
      DestNameW=DestFileNameW;
633
      if (Cmd->DllOpMode!=RAR_EXTRACT)
634
        ExtrFile=false;
635
    }
636
#endif
637
638
#ifdef SFX_MODULE
1.1.4 by Martin Meredith
Import upstream version 3.6.8
639
    if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) &&
640
        Arc.NewLhd.Method!=0x30)
1 by Chris Anderson
Import upstream version 3.3.6
641
#else
642
    if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER)
643
#endif
644
    {
645
#ifndef SILENT
646
      Log(Arc.FileName,St(MUnknownMeth),ArcFileName);
647
#ifndef SFX_MODULE
648
      Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10);
649
#endif
650
#endif
651
      ExtrFile=false;
652
      ErrHandler.SetErrorCode(WARNING);
653
#ifdef RARDLL
654
      Cmd->DllError=ERAR_UNKNOWN_FORMAT;
655
#endif
656
    }
657
658
    File CurFile;
659
660
    if (!IsLink(Arc.NewLhd.FileAttr))
661
      if (Arc.IsArcDir())
662
      {
663
        if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
664
          return(true);
665
        if (SkipSolid)
666
        {
667
#ifndef GUI
668
          mprintf(St(MExtrSkipFile),ArcFileName);
669
#endif
670
          return(true);
671
        }
672
        TotalFileCount++;
673
        if (Cmd->Test)
674
        {
675
#ifndef GUI
676
          mprintf(St(MExtrTestFile),ArcFileName);
677
          mprintf(" %s",St(MOk));
678
#endif
679
          return(true);
680
        }
1.2.4 by Martin Meredith
Import upstream version 3.9.3
681
        MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr);
1 by Chris Anderson
Import upstream version 3.3.6
682
        bool DirExist=false;
683
        if (MDCode!=MKDIR_SUCCESS)
684
        {
685
          DirExist=FileExist(DestFileName,DestNameW);
686
          if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW)))
687
          {
688
            bool UserReject;
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
689
            FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime);
1 by Chris Anderson
Import upstream version 3.3.6
690
            DirExist=false;
691
          }
692
          CreatePath(DestFileName,DestNameW,true);
1.2.4 by Martin Meredith
Import upstream version 3.9.3
693
          MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr);
1 by Chris Anderson
Import upstream version 3.3.6
694
        }
695
        if (MDCode==MKDIR_SUCCESS)
696
        {
697
#ifndef GUI
698
          mprintf(St(MCreatDir),DestFileName);
699
          mprintf(" %s",St(MOk));
700
#endif
701
          PrevExtracted=true;
702
        }
703
        else
704
          if (DirExist)
705
          {
1.2.4 by Martin Meredith
Import upstream version 3.9.3
706
            if (!Cmd->IgnoreGeneralAttr)
707
              SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
1 by Chris Anderson
Import upstream version 3.3.6
708
            PrevExtracted=true;
709
          }
710
          else
711
          {
712
            Log(Arc.FileName,St(MExtrErrMkDir),DestFileName);
1.2.12 by Martin Meredith
Import upstream version 4.1.4
713
            ErrHandler.CheckLongPathErrMsg(DestFileName,DestNameW);
1 by Chris Anderson
Import upstream version 3.3.6
714
            ErrHandler.SysErrMsg();
715
#ifdef RARDLL
716
            Cmd->DllError=ERAR_ECREATE;
717
#endif
718
            ErrHandler.SetErrorCode(CREATE_ERROR);
719
          }
720
        if (PrevExtracted)
1.1.1 by Chris Anderson
Import upstream version 3.4.3
721
        {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
722
#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined(SFX_MODULE)
1.1.1 by Chris Anderson
Import upstream version 3.4.3
723
          if (Cmd->SetCompressedAttr &&
724
              (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
1.2.1 by Martin Meredith
Import upstream version 3.8.2
725
            SetFileCompression(DestFileName,DestNameW,true);
1.1.1 by Chris Anderson
Import upstream version 3.4.3
726
#endif
1.2.1 by Martin Meredith
Import upstream version 3.8.2
727
          SetDirTime(DestFileName,DestNameW,
1 by Chris Anderson
Import upstream version 3.3.6
728
            Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
729
            Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
730
            Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
1.1.1 by Chris Anderson
Import upstream version 3.4.3
731
        }
1 by Chris Anderson
Import upstream version 3.3.6
732
        return(true);
733
      }
734
      else
735
      {
736
        if (Cmd->Test && ExtrFile)
737
          TestMode=true;
738
#if !defined(GUI) && !defined(SFX_MODULE)
739
        if (Command=='P' && ExtrFile)
740
          CurFile.SetHandleType(FILE_HANDLESTD);
741
#endif
742
        if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test)
743
        {
744
          bool UserReject;
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
745
          if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
1 by Chris Anderson
Import upstream version 3.3.6
746
          {
747
            ExtrFile=false;
748
            if (!UserReject)
749
            {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
750
              ErrHandler.CreateErrorMsg(Arc.FileName,Arc.FileNameW,DestFileName,DestFileNameW);
1 by Chris Anderson
Import upstream version 3.3.6
751
              ErrHandler.SetErrorCode(CREATE_ERROR);
752
#ifdef RARDLL
753
              Cmd->DllError=ERAR_ECREATE;
754
#endif
755
              if (!IsNameUsable(DestFileName))
756
              {
757
                Log(Arc.FileName,St(MCorrectingName));
1.1.4 by Martin Meredith
Import upstream version 3.6.8
758
                char OrigName[sizeof(DestFileName)];
1.1.5 by Martin Meredith
Import upstream version 3.7.2
759
                strncpyz(OrigName,DestFileName,ASIZE(OrigName));
1.1.4 by Martin Meredith
Import upstream version 3.6.8
760
1 by Chris Anderson
Import upstream version 3.3.6
761
                MakeNameUsable(DestFileName,true);
762
                CreatePath(DestFileName,NULL,true);
763
                if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
1.1.4 by Martin Meredith
Import upstream version 3.6.8
764
                {
765
#ifndef SFX_MODULE
766
                  Log(Arc.FileName,St(MRenaming),OrigName,DestFileName);
767
#endif
1 by Chris Anderson
Import upstream version 3.3.6
768
                  ExtrFile=true;
1.1.4 by Martin Meredith
Import upstream version 3.6.8
769
                }
1 by Chris Anderson
Import upstream version 3.3.6
770
                else
1.2.10 by Martin Meredith
Import upstream version 4.0.2
771
                  ErrHandler.CreateErrorMsg(Arc.FileName,Arc.FileNameW,DestFileName,DestFileNameW);
1 by Chris Anderson
Import upstream version 3.3.6
772
              }
773
            }
774
          }
775
        }
776
      }
777
778
    if (!ExtrFile && Arc.Solid)
779
    {
780
      SkipSolid=true;
781
      TestMode=true;
782
      ExtrFile=true;
1.2.4 by Martin Meredith
Import upstream version 3.9.3
783
1 by Chris Anderson
Import upstream version 3.3.6
784
    }
785
    if (ExtrFile)
786
    {
1.2.12 by Martin Meredith
Import upstream version 4.1.4
787
1 by Chris Anderson
Import upstream version 3.3.6
788
      if (!SkipSolid)
789
      {
790
        if (!TestMode && Command!='P' && CurFile.IsDevice())
791
        {
792
          Log(Arc.FileName,St(MInvalidName),DestFileName);
1.2.10 by Martin Meredith
Import upstream version 4.0.2
793
          ErrHandler.WriteError(Arc.FileName,Arc.FileNameW,DestFileName,DestFileNameW);
1 by Chris Anderson
Import upstream version 3.3.6
794
        }
795
        TotalFileCount++;
796
      }
797
      FileCount++;
798
#ifndef GUI
799
      if (Command!='I')
800
        if (SkipSolid)
801
          mprintf(St(MExtrSkipFile),ArcFileName);
802
        else
803
          switch(Cmd->Test ? 'T':Command)
804
          {
805
            case 'T':
806
              mprintf(St(MExtrTestFile),ArcFileName);
807
              break;
808
#ifndef SFX_MODULE
809
            case 'P':
810
              mprintf(St(MExtrPrinting),ArcFileName);
811
              break;
812
#endif
813
            case 'X':
814
            case 'E':
815
              mprintf(St(MExtrFile),DestFileName);
816
              break;
817
          }
818
      if (!Cmd->DisablePercentage)
819
        mprintf("     ");
820
#endif
821
      DataIO.CurUnpRead=0;
822
      DataIO.CurUnpWrite=0;
823
      DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff;
824
      DataIO.PackedCRC=0xffffffff;
1.2.10 by Martin Meredith
Import upstream version 4.0.2
825
826
      wchar FilePassword[MAXPASSWORD];
827
#ifdef _WIN_ALL
828
      if (Arc.NewLhd.HostOS==HOST_MSDOS/* && Arc.NewLhd.UnpVer<=25*/)
829
      {
830
        // We need the password in OEM encoding if file was encrypted by
831
        // native RAR/DOS (not extender based). Let's make the conversion.
832
        char PswA[MAXPASSWORD];
833
        CharToOemBuffW(Password,PswA,ASIZE(PswA));
834
        CharToWide(PswA,FilePassword,ASIZE(FilePassword));
835
        FilePassword[ASIZE(FilePassword)-1]=0;
836
      }
837
      else
838
#endif
839
        wcscpy(FilePassword,Password);
840
      
1 by Chris Anderson
Import upstream version 3.3.6
841
      DataIO.SetEncryption(
1.2.10 by Martin Meredith
Import upstream version 4.0.2
842
        (Arc.NewLhd.Flags & LHD_PASSWORD)!=0 ? Arc.NewLhd.UnpVer:0,FilePassword,
843
        (Arc.NewLhd.Flags & LHD_SALT)!=0 ? Arc.NewLhd.Salt:NULL,false,
1.1.4 by Martin Meredith
Import upstream version 3.6.8
844
        Arc.NewLhd.UnpVer>=36);
1 by Chris Anderson
Import upstream version 3.3.6
845
      DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize);
846
      DataIO.SetFiles(&Arc,&CurFile);
847
      DataIO.SetTestMode(TestMode);
848
      DataIO.SetSkipUnpCRC(SkipSolid);
849
#ifndef _WIN_CE
850
      if (!TestMode && !Arc.BrokenFileHeader &&
851
          (Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize &&
852
          (Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize))
853
        CurFile.Prealloc(Arc.NewLhd.FullUnpSize);
854
#endif
855
856
      CurFile.SetAllowDelete(!Cmd->KeepBroken);
857
1.1.3 by Christoph Berg
Import upstream version 3.5.4
858
      bool LinkCreateMode=!Cmd->Test && !SkipSolid;
859
      if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode))
860
        PrevExtracted=LinkCreateMode;
861
      else
862
        if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0)
863
          if (Arc.NewLhd.Method==0x30)
864
            UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize);
865
          else
866
          {
867
            Unp->SetDestSize(Arc.NewLhd.FullUnpSize);
1 by Chris Anderson
Import upstream version 3.3.6
868
#ifndef SFX_MODULE
1.1.3 by Christoph Berg
Import upstream version 3.5.4
869
            if (Arc.NewLhd.UnpVer<=15)
870
              Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
871
            else
1 by Chris Anderson
Import upstream version 3.3.6
872
#endif
1.2.4 by Martin Meredith
Import upstream version 3.9.3
873
              Unp->DoUnpack(Arc.NewLhd.UnpVer,(Arc.NewLhd.Flags & LHD_SOLID)!=0);
1.1.3 by Christoph Berg
Import upstream version 3.5.4
874
          }
1 by Chris Anderson
Import upstream version 3.3.6
875
1.2.12 by Martin Meredith
Import upstream version 4.1.4
876
//      if (Arc.IsOpened())
1 by Chris Anderson
Import upstream version 3.3.6
877
        Arc.SeekToNext();
878
1.2.10 by Martin Meredith
Import upstream version 4.0.2
879
      bool ValidCRC=Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) ||
880
                   !Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff);
881
882
      // We set AnySolidDataUnpackedWell to true if we found at least one
883
      // valid non-zero solid file in preceding solid stream. If it is true
884
      // and if current encrypted file is broken, we do not need to hint
885
      // about a wrong password and can report CRC error only.
886
      if ((Arc.NewLhd.Flags & LHD_SOLID)==0)
887
        AnySolidDataUnpackedWell=false; // Reset the flag, because non-solid file is found.
888
      else
889
        if (Arc.NewLhd.Method!=0x30 && Arc.NewLhd.FullUnpSize>0 && ValidCRC)
890
          AnySolidDataUnpackedWell=true;
891
 
1 by Chris Anderson
Import upstream version 3.3.6
892
      bool BrokenFile=false;
893
      if (!SkipSolid)
894
      {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
895
        if (ValidCRC)
1 by Chris Anderson
Import upstream version 3.3.6
896
        {
897
#ifndef GUI
898
          if (Command!='P' && Command!='I')
899
            mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk));
900
#endif
901
        }
902
        else
903
        {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
904
          if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && !AnySolidDataUnpackedWell)
1 by Chris Anderson
Import upstream version 3.3.6
905
          {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
906
            Log(Arc.FileName,St(MEncrBadCRC),ArcFileName);
1 by Chris Anderson
Import upstream version 3.3.6
907
          }
908
          else
909
          {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
910
            Log(Arc.FileName,St(MCRCFailed),ArcFileName);
1 by Chris Anderson
Import upstream version 3.3.6
911
          }
912
          BrokenFile=true;
913
          ErrHandler.SetErrorCode(CRC_ERROR);
914
#ifdef RARDLL
915
          Cmd->DllError=ERAR_BAD_DATA;
916
#endif
917
          Alarm();
918
        }
919
      }
920
#ifndef GUI
921
      else
922
        mprintf("\b\b\b\b\b     ");
923
#endif
924
925
      if (!TestMode && (Command=='X' || Command=='E') &&
926
          !IsLink(Arc.NewLhd.FileAttr))
927
      {
1.2.10 by Martin Meredith
Import upstream version 4.0.2
928
#if defined(_WIN_ALL) || defined(_EMX)
1 by Chris Anderson
Import upstream version 3.3.6
929
        if (Cmd->ClearArc)
930
          Arc.NewLhd.FileAttr&=~FA_ARCH;
931
#endif
932
        if (!BrokenFile || Cmd->KeepBroken)
933
        {
934
          if (BrokenFile)
935
            CurFile.Truncate();
1.2.4 by Martin Meredith
Import upstream version 3.9.3
936
          CurFile.SetOpenFileTime(
1 by Chris Anderson
Import upstream version 3.3.6
937
            Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
938
            Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
939
            Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
940
          CurFile.Close();
1.2.10 by Martin Meredith
Import upstream version 4.0.2
941
#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined(SFX_MODULE)
1.1.1 by Chris Anderson
Import upstream version 3.4.3
942
          if (Cmd->SetCompressedAttr &&
943
              (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
944
            SetFileCompression(CurFile.FileName,CurFile.FileNameW,true);
945
#endif
1.2.4 by Martin Meredith
Import upstream version 3.9.3
946
          CurFile.SetCloseFileTime(
1 by Chris Anderson
Import upstream version 3.3.6
947
            Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
1.2.4 by Martin Meredith
Import upstream version 3.9.3
948
            Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
949
          if (!Cmd->IgnoreGeneralAttr)
950
            SetFileAttr(CurFile.FileName,CurFile.FileNameW,Arc.NewLhd.FileAttr);
1 by Chris Anderson
Import upstream version 3.3.6
951
          PrevExtracted=true;
952
        }
953
      }
954
    }
955
  }
956
  if (ExactMatch)
957
    MatchedArgs++;
1.2.12 by Martin Meredith
Import upstream version 4.1.4
958
  if (DataIO.NextVolumeMissing/* || !Arc.IsOpened()*/)
1 by Chris Anderson
Import upstream version 3.3.6
959
    return(false);
960
  if (!ExtrFile)
961
    if (!Arc.Solid)
962
      Arc.SeekToNext();
963
    else
964
      if (!SkipSolid)
965
        return(false);
966
  return(true);
967
}
968
969
1.2.4 by Martin Meredith
Import upstream version 3.9.3
970
void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize)
1 by Chris Anderson
Import upstream version 3.3.6
971
{
972
  Array<byte> Buffer(0x10000);
973
  while (1)
974
  {
1.2.4 by Martin Meredith
Import upstream version 3.9.3
975
    uint Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
1 by Chris Anderson
Import upstream version 3.3.6
976
    if (Code==0 || (int)Code==-1)
977
      break;
1.2.4 by Martin Meredith
Import upstream version 3.9.3
978
    Code=Code<DestUnpSize ? Code:(uint)DestUnpSize;
1 by Chris Anderson
Import upstream version 3.3.6
979
    DataIO.UnpWrite(&Buffer[0],Code);
980
    if (DestUnpSize>=0)
981
      DestUnpSize-=Code;
982
  }
983
}
1.1.2 by Jeroen van Wolffelaar
Import upstream version 3.5.2
984