1 #include "rar.hpp"
2 
3 static void GetFirstNewVolName(const char *ArcName,char *VolName,
4   Int64 VolSize,Int64 TotalSize);
5 
6 
7 
MergeArchive(Archive & Arc,ComprDataIO * DataIO,bool ShowFileName,char Command)8 bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Command)
9 {
10   RAROptions *Cmd=Arc.GetRAROptions();
11 
12   int HeaderType=Arc.GetHeaderType();
13   FileHeader *hd=HeaderType==NEWSUB_HEAD ? &Arc.SubHead:&Arc.NewLhd;
14   bool SplitHeader=(HeaderType==FILE_HEAD || HeaderType==NEWSUB_HEAD) &&
15                    (hd->Flags & LHD_SPLIT_AFTER)!=0;
16 
17   if (DataIO!=NULL && SplitHeader && hd->UnpVer>=20 &&
18       hd->FileCRC!=0xffffffff && DataIO->PackedCRC!=~hd->FileCRC)
19   {
20     Log(Arc.FileName,St(MDataBadCRC),hd->FileName,Arc.FileName);
21   }
22 
23   Int64 PosBeforeClose=Arc.Tell();
24   Arc.Close();
25 
26   char NextName[NM];
27   strcpy(NextName,Arc.FileName);
28   NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
29 
30 #if !defined(SFX_MODULE) && !defined(RARDLL)
31   bool RecoveryDone=false;
32 #endif
33   bool FailedOpen=false,OldSchemeTested=false;
34 
35   while (!Arc.Open(NextName))
36   {
37     if (!OldSchemeTested)
38     {
39       char AltNextName[NM];
40       strcpy(AltNextName,Arc.FileName);
41       NextVolumeName(AltNextName,true);
42       OldSchemeTested=true;
43       if (Arc.Open(AltNextName))
44       {
45         strcpy(NextName,AltNextName);
46         break;
47       }
48     }
49 #ifdef RARDLL
50     if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL ||
51         Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1)
52     {
53       Cmd->DllError=ERAR_EOPEN;
54       FailedOpen=true;
55       break;
56     }
57     if (Cmd->ChangeVolProc!=NULL)
58     {
59 //#ifdef _WIN_32
60 //      _EBX=_ESP;
61 //#endif
62       int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_ASK);
63 //#ifdef _WIN_32
64 //      _ESP=_EBX;
65 //#endif
66       if (RetCode==0)
67       {
68         Cmd->DllError=ERAR_EOPEN;
69         FailedOpen=true;
70         break;
71       }
72     }
73 #else
74 
75 #if !defined(SFX_MODULE) && !defined(_WIN_CE)
76     if (!RecoveryDone)
77     {
78       RecVolumes RecVol;
79       RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true);
80       RecoveryDone=true;
81       continue;
82     }
83 #endif
84 
85 #ifndef GUI
86     if (!Cmd->VolumePause && !IsRemovable(NextName))
87     {
88       Log(Arc.FileName,St(MAbsNextVol),NextName);
89       FailedOpen=true;
90       break;
91     }
92 #endif
93 #ifndef SILENT
94     if (Cmd->AllYes || !AskNextVol(NextName))
95 #endif
96     {
97       FailedOpen=true;
98       break;
99     }
100 #endif
101   }
102   if (FailedOpen)
103   {
104     Arc.Open(Arc.FileName,Arc.FileNameW);
105     Arc.Seek(PosBeforeClose,SEEK_SET);
106     return(false);
107   }
108   Arc.CheckArc(true);
109 #ifdef RARDLL
110   if (Cmd->Callback!=NULL &&
111       Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1)
112     return(false);
113   if (Cmd->ChangeVolProc!=NULL)
114   {
115 //#ifdef _WIN_32
116 //    _EBX=_ESP;
117 //#endif
118     int RetCode=Cmd->ChangeVolProc(NextName,RAR_VOL_NOTIFY);
119 //#ifdef _WIN_32
120 //    _ESP=_EBX;
121 //#endif
122     if (RetCode==0)
123       return(false);
124   }
125 #endif
126 
127   if (Command=='T' || Command=='X' || Command=='E')
128     mprintf(St(Command=='T' ? MTestVol:MExtrVol),Arc.FileName);
129   if (SplitHeader)
130     Arc.SearchBlock(HeaderType);
131   else
132     Arc.ReadHeader();
133   if (Arc.GetHeaderType()==FILE_HEAD)
134   {
135     Arc.ConvertAttributes();
136     Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);
137   }
138 #ifndef GUI
139   if (ShowFileName)
140   {
141     mprintf(St(MExtrPoints),IntNameToExt(Arc.NewLhd.FileName));
142     if (!Cmd->DisablePercentage)
143       mprintf("     ");
144   }
145 #endif
146   if (DataIO!=NULL)
147   {
148     if (HeaderType==ENDARC_HEAD)
149       DataIO->UnpVolume=false;
150     else
151     {
152       DataIO->UnpVolume=(hd->Flags & LHD_SPLIT_AFTER);
153       DataIO->SetPackedSizeToRead(hd->FullPackSize);
154     }
155 #ifdef SFX_MODULE
156     DataIO->UnpArcSize=Arc.FileLength();
157     DataIO->CurUnpRead=0;
158 #endif
159     DataIO->PackedCRC=0xffffffff;
160 //    DataIO->SetFiles(&Arc,NULL);
161   }
162   return(true);
163 }
164 
165 
166 
167 
168 
169 
170 #ifndef SILENT
AskNextVol(char * ArcName)171 bool AskNextVol(char *ArcName)
172 {
173   eprintf(St(MAskNextVol),ArcName);
174   if (Ask(St(MContinueQuit))==2)
175     return(false);
176   return(true);
177 }
178 #endif
179