1 #include <iostream>
2 #include <pthread.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <sstream>
6 #include <stdarg.h>
7 #include "string.h"
8 #include "rartypes.hpp"
9 #include "rardefs.hpp"
10 #include "system.hpp"
11 #include "timefn.hpp"
12 #include "errhnd.hpp"
13 #include "strfn.hpp"
14 #include "os.hpp"
15 #include "array.hpp"
16 #include "global.hpp"
17 
18 #include "file.hpp"
19 
20 static const File *CreatedFiles[256];
21 //char *_i64toa( int64 value, char *string, int radix );
22 /**
23 File constructor - After this is called, one <b>must</b> call the <code>InitFile(...)</code> function
24 */
File()25 File::File() :
26     ptrlocation(), initptrlocation(), ptrlength(), hFile(), LastWrite(),
27     HandleType(), SkipClose(), IgnoreReadErrors(), NewFile(), AllowDelete(),
28     AllowExceptions(), OpenShared(), ErrorType(), CloseCount()
29 { //Constructor
30   hFile=BAD_HANDLE;
31   *FileName=0;
32   *FileNameW=0;
33   NewFile=false;
34   LastWrite=false;
35   HandleType=FILE_HANDLENORMAL;
36   SkipClose=false;
37   IgnoreReadErrors=false;
38   ErrorType=FILE_SUCCESS;
39   OpenShared=false;
40   AllowDelete=true;
41   CloseCount=0;
42   AllowExceptions=true;
43   initptrlocation = 0; //set the pointer location to null. The Init function will set this.
44   ptrlocation = 0; //set the pointer location to null. The Init function will set this.
45 #ifdef _WIN_ALL
46   NoSequentialRead=false;
47 #endif
48 }
49 
File(const File & copy)50 File::File(const File &copy) :
51     ptrlocation(), initptrlocation(), ptrlength(), hFile(), LastWrite(),
52     HandleType(), SkipClose(), IgnoreReadErrors(), NewFile(), AllowDelete(),
53     AllowExceptions(), OpenShared(), ErrorType(), CloseCount()
54 {
55     *this = copy;
56 }
57 
58 
~File()59 File::~File()
60 {//Destructor class
61     if (hFile!=BAD_HANDLE && !SkipClose)
62     {
63         if (NewFile)
64         {
65             Delete();
66         }
67         else
68         {
69             Close();
70         }
71     }
72 }
73 
74 /**
75 This function initializes the file class to read information from memory.
76 
77 @param ptr - a pointer to the location in memory where the RAR file lives
78 @param length - The length of the location in memory where the RAR file lives
79 */
InitFile(void * ptr,int64 length)80 void File::InitFile(void* ptr, int64 length)
81 {//initialize the data to point to the RAR pointer in memory
82 	//set the pointer to the right place so we can read from it later on.
83 	//also, store the initial location in case we have to go back there later on.
84 	initptrlocation = (byte*)ptr; //initialize the initial pointer location
85 	ptrlocation = (byte*)ptr; //initialize the current pointer location
86 	ptrlength = length; //set the length of the file
87 	return;
88 }
89 
90 /**
91 This function is not called in bulk_extractor
92 */
operator =(const File & SrcFile)93 const File& File::operator=(const File &SrcFile)
94 {//This is not called in bulk_extractor
95   hFile=SrcFile.hFile;
96   strcpy(FileName,SrcFile.FileName);
97   NewFile=SrcFile.NewFile;
98   LastWrite=SrcFile.LastWrite;
99   HandleType=SrcFile.HandleType;
100   //SrcFile.SkipClose=true;
101   initptrlocation = SrcFile.initptrlocation; //save the initial ptr location
102   ptrlocation = SrcFile.ptrlocation; //save the ptr location
103 
104   return *this;
105 }
106 
107 
Open(const char * Name,const wchar * NameW,bool OpenShared_,bool Update)108 bool File::Open(const char *Name,const wchar *NameW,bool OpenShared_,bool Update)
109 { //This function does nothing. It simply complies with the File class.
110   //This class should utilize the Init(void* ptr) function to open a file.
111 	//hFile = hNewFile;
112 	return true;
113 /*  ErrorType=FILE_SUCCESS;
114   FileHandle hNewFile;
115   if (BenFile::OpenShared_)
116     OpenShared_=true;
117 #ifdef _WIN_ALL
118   uint Access=GENERIC_READ;
119   if (Update)
120     Access|=GENERIC_WRITE;
121   uint ShareMode=FILE_SHARE_READ;
122   if (OpenShared_)
123     ShareMode|=FILE_SHARE_WRITE;
124   uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
125   if (WinNT() && NameW!=NULL && *NameW!=0)
126     hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
127   else
128     hNewFile=CreateFileA(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
129 
130   if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND)
131     ErrorType=FILE_NOTFOUND;
132 #else
133   int flags=Update ? O_RDWR:O_RDONLY;
134 #ifdef O_BINARY
135   flags|=O_BINARY;
136 #if defined(_AIX) && defined(_LARGE_FILE_API)
137   flags|=O_LARGEFILE;
138 #endif
139 #endif
140 #if defined(_EMX) && !defined(_DJGPP)
141   int sflags=OpenShared_ ? SH_DENYNO:SH_DENYWR;
142   int handle=sopen(Name,flags,sflags);
143 #else
144   int handle=open(Name,flags);
145 #ifdef LOCK_EX
146 
147 #ifdef _OSF_SOURCE
148   extern "C" int flock(int, int);
149 #endif
150 
151   if (!OpenShared_ && Update && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)
152   {
153     close(handle);
154     return(false);
155   }
156 #endif
157 #endif
158   hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,Update ? UPDATEBINARY:READBINARY);
159   if (hNewFile==BAD_HANDLE && errno==ENOENT)
160     ErrorType=FILE_NOTFOUND;
161 #endif
162   NewFile=false;
163   HandleType=FILE_HANDLENORMAL;
164   SkipClose=false;
165   bool Success=hNewFile!=BAD_HANDLE;
166   if (Success)
167   {
168     hFile=hNewFile;
169 
170     // We use memove instead of strcpy and wcscpy to avoid problems
171     // with overlapped buffers. While we do not call this function with
172     // really overlapped buffers yet, we do call it with Name equal to
173     // FileName like Arc.Open(Arc.FileName,Arc.FileNameW).
174     if (NameW!=NULL)
175       memmove(FileNameW,NameW,(wcslen(NameW)+1)*sizeof(*NameW));
176     else
177       *FileNameW=0;
178     if (Name!=NULL)
179       memmove(FileName,Name,strlen(Name)+1);
180     else
181       WideToChar(NameW,FileName);
182     AddFileToList(hFile);
183   }
184   return(Success);*/
185 }
186 
187 
188 #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
189 /**
190 This function is not called in bulk_extractor
191 */
TOpen(const char * Name,const wchar * NameW)192 void File::TOpen(const char *Name,const wchar *NameW)
193 { //Nothing to do for this function
194   if (!WOpen(Name,NameW))
195     ErrHandler.Exit(OPEN_ERROR);
196 }
197 #endif
198 
199 /**
200 This function does nothing. It simply complies with the <code>File</code> class.
201 */
WOpen(const char * Name,const wchar * NameW)202 bool File::WOpen(const char *Name,const wchar *NameW)
203 { //This class should utilize the Init(void* ptr) function to open a file.
204 	bool result = true;
205 	if(ptrlocation == NULL || ptrlength == 0)
206 		result = false;
207 //	else
208 	//	hFile = FileHandle.;
209 	return result;
210  /* if (Open(Name,NameW))
211     return(true);
212   ErrHandler.OpenErrorMsg(Name,NameW);
213   return(false);*/
214 }
215 
216 /**
217 This function does nothing. It simply complies with the File class.
218 */
Create(const char * Name,const wchar * NameW,bool ShareRead)219 bool File::Create(const char *Name,const wchar *NameW,bool ShareRead)
220 {
221 	return true;
222 	/*
223 #ifdef _WIN_ALL
224   DWORD ShareMode=(ShareRead || BenFile::OpenShared) ? FILE_SHARE_READ:0;
225   if (WinNT() && NameW!=NULL && *NameW!=0)
226     hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
227                       CREATE_ALWAYS,0,NULL);
228   else
229     hFile=CreateFileA(Name,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
230                      CREATE_ALWAYS,0,NULL);
231 #else
232   hFile=fopen(Name,CREATEBINARY);
233 #endif
234   NewFile=true;
235   HandleType=FILE_HANDLENORMAL;
236   SkipClose=false;
237   if (NameW!=NULL)
238     wcscpy(FileNameW,NameW);
239   else
240     *FileNameW=0;
241   if (Name!=NULL)
242     strcpy(FileName,Name);
243   else
244     WideToChar(NameW,FileName);
245   AddFileToList(hFile);
246   return(hFile!=BAD_HANDLE);*/
247 }
248 
249 /**
250 This is not called in bulk_extractor
251 */
AddFileToList(FileHandle hFile_)252 void File::AddFileToList(FileHandle hFile_)
253 {
254   if (hFile_!=BAD_HANDLE)
255     for (unsigned I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
256       if (CreatedFiles[I]==NULL)
257       {
258         CreatedFiles[I]=this;
259         break;
260       }
261 }
262 
263 
264 #if !defined(SHELL_EXT) && !defined(SFX_MODULE)
265 /**
266 This is not called in bulk_extractor
267 */
TCreate(const char * Name,const wchar * NameW,bool ShareRead)268 void File::TCreate(const char *Name,const wchar *NameW,bool ShareRead)
269 {
270   if (!WCreate(Name,NameW,ShareRead))
271     ErrHandler.Exit(FATAL_ERROR);
272 }
273 #endif
274 
275 /**
276 This is not called in bulk_extractor
277 */
WCreate(const char * Name,const wchar * NameW,bool ShareRead)278 bool File::WCreate(const char *Name,const wchar *NameW,bool ShareRead)
279 {
280   if (Create(Name,NameW,ShareRead))
281     return(true);
282   ErrHandler.SetErrorCode(CREATE_ERROR);
283   ErrHandler.CreateErrorMsg(Name,NameW);
284   return(false);
285 }
286 
287 /**
288 This function does nothing. It simply complies with the File class.
289 */
Close()290 bool File::Close()
291 {
292 	ptrlocation = initptrlocation; //reset Pointer location to the initial spot
293 	return true;
294   /*bool Success=true;
295   if (HandleType!=FILE_HANDLENORMAL)
296     HandleType=FILE_HANDLENORMAL;
297   else
298     if (hFile!=BAD_HANDLE)
299     {
300       if (!SkipClose)
301       {
302 #ifdef _WIN_ALL
303         Success=CloseHandle(hFile)==TRUE;
304 #else
305         Success=fclose(hFile)!=EOF;
306 #endif
307         if (Success || !RemoveCreatedActive)
308           for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
309             if (CreatedFiles[I]==this)
310             {
311               CreatedFiles[I]=NULL;
312               break;
313             }
314       }
315       hFile=BAD_HANDLE;
316       if (!Success && AllowExceptions)
317         ErrHandler.CloseError(FileName,FileNameW);
318     }
319   CloseCount++;
320   return(Success);*/
321 }
322 
323 /**
324 This is not called in bulk_extractor.
325 */
Flush()326 void File::Flush()
327 {
328 #ifdef _WIN_ALL
329   FlushFileBuffers(hFile);
330 #else
331   fflush(hFile);
332 #endif
333 }
334 
335 /**
336 This is not called in bulk_extractor.
337 */
Delete()338 bool File::Delete()
339 {
340 if (HandleType!=FILE_HANDLENORMAL)
341     return(false);
342   if (hFile!=BAD_HANDLE)
343     Close();
344   if (!AllowDelete)
345     return(false);
346   return(DelFile(FileName,FileNameW));
347 }
348 
349 /**
350 This function should never be called since the file name should never be changed
351 */
Rename(const char * NewName,const wchar * NewNameW)352 bool File::Rename(const char *NewName,const wchar *NewNameW)
353 {
354   // we do not need to rename if names are already same
355   bool Success=strcmp(FileName,NewName)==0;
356   if (Success && *FileNameW!=0 && *NullToEmpty(NewNameW)!=0)
357     Success=wcscmp(FileNameW,NewNameW)==0;
358 
359   if (!Success)
360     Success=RenameFile(FileName,FileNameW,NewName,NewNameW);
361 
362   if (Success)
363   {
364     // renamed successfully, storing the new name
365     strcpy(FileName,NewName);
366     wcscpy(FileNameW,NullToEmpty(NewNameW));
367   }
368   return(Success);
369 }
370 
371 /**
372 This is not called in bulk_extractor
373 */
Write(const void * Data,size_t Size)374 void File::Write(const void *Data,size_t Size)
375 { //This is not called in bulk_extractor
376   if (Size==0)
377     return;
378 #ifndef _WIN_CE
379   if (HandleType!=FILE_HANDLENORMAL)
380     switch(HandleType)
381     {
382       case FILE_HANDLESTD:
383 #ifdef _WIN_ALL
384         hFile=GetStdHandle(STD_OUTPUT_HANDLE);
385 #else
386         hFile=stdout;
387 #endif
388         break;
389       case FILE_HANDLEERR:
390 #ifdef _WIN_ALL
391         hFile=GetStdHandle(STD_ERROR_HANDLE);
392 #else
393         hFile=stderr;
394 #endif
395         break;
396       default:
397         break;
398     }
399 #endif
400   while (1)
401   {
402     bool Success=false;
403 #ifdef _WIN_ALL
404     DWORD Written=0;
405     if (HandleType!=FILE_HANDLENORMAL)
406     {
407       // writing to stdout can fail in old Windows if data block is too large
408       const size_t MaxSize=0x4000;
409       for (size_t I=0;I<Size;I+=MaxSize)
410       {
411         Success=WriteFile(hFile,(byte *)Data+I,(DWORD)Min(Size-I,MaxSize),&Written,NULL)==TRUE; //Writing happens here
412         if (!Success)
413           break;
414       }
415     }
416     else
417       Success=WriteFile(hFile,Data,(DWORD)Size,&Written,NULL)==TRUE;
418 #else
419     size_t Written=fwrite(Data,1,Size,hFile);
420     Success=Written==Size && !ferror(hFile);
421 #endif
422     if (!Success && AllowExceptions && HandleType==FILE_HANDLENORMAL)
423     {
424 #if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(RARDLL)
425       int ErrCode=GetLastError();
426       int64 FilePos=Tell();
427       uint64 FreeSize=GetFreeDisk(FileName);
428       SetLastError(ErrCode);
429       if (FreeSize>Size && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff)
430         ErrHandler.WriteErrorFAT(FileName,FileNameW);
431 #endif
432       if (ErrHandler.AskRepeatWrite(FileName,FileNameW,false))
433       {
434 #ifndef _WIN_ALL
435         clearerr(hFile);
436 #endif
437         if (Written<Size && Written>0)
438           Seek(Tell()-Written,SEEK_SET);
439         continue;
440       }
441       ErrHandler.WriteError(NULL,NULL,FileName,FileNameW);
442     }
443     break;
444   }
445   LastWrite=true;
446 }
447 
448 /**
449 Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
450 @param Data - a pointer to the memory location of the RAR file to be extracted
451 @param Size - the length, in bytes, of the <code>Data</code> variable
452 @return the size that was read from the memory location
453 */
Read(void * Data,size_t Size)454 int File::Read(void *Data,size_t Size)
455 { //Read data from memory of size 'Size'
456 
457 	//call directRead
458 	int readsize = DirectRead(Data, Size);
459 
460 	return readsize;
461 
462 /*int64 FilePos=0; // Initialized only to suppress some compilers warning.
463 
464   if (IgnoreReadErrors)
465     FilePos=Tell();
466   int ReadSize;
467   while (true)
468   {
469     ReadSize=DirectRead(Data,Size);
470     if (ReadSize==-1)
471     {
472       ErrorType=FILE_READERROR;
473       if (AllowExceptions)
474         if (IgnoreReadErrors)
475         {
476           ReadSize=0;
477           for (size_t I=0;I<Size;I+=512)
478           {
479             Seek(FilePos+I,SEEK_SET);
480             size_t SizeToRead=Min(Size-I,512);
481             int ReadCode=DirectRead(Data,SizeToRead);
482             ReadSize+=(ReadCode==-1) ? 512:ReadCode;
483           }
484         }
485         else
486         {
487           if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName,FileNameW))
488             continue;
489           ErrHandler.ReadError(FileName,FileNameW);
490         }
491     }
492     break;
493   }
494   return(ReadSize);*/
495 }
496 
497 /**
498 Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
499 @param Data - a pointer to the memory location of the RAR file to be extracted
500 @param Size - the length, in bytes, of the <code>Data</code> variable
501 @return the size that was read from the memory location
502 */
DirectRead(void * Data,size_t Size)503 int File::DirectRead(void *Data,size_t Size)
504 { //Calls DirectRead function
505 	return DirectRead((byte*)Data, Size);
506 }
507 
508 
509 /**
510 Read data from memory of size <code>Size</code>. Calls the <code>DirectRead(Data,Size)</code> function.
511 @param Data - a pointer to the memory location of the RAR file to be extracted
512 @param Size - the length, in bytes, of the <code>Data</code> variable
513 @return the size that was read from the memory location. If a '-1' is returned, an error has occurred.
514 */
DirectRead(byte * Data,size_t Size)515 int File::DirectRead(byte *Data,size_t Size)
516 { //Reads from memory the size as spcified by 'Size'
517 
518 	//read the amount of information from memory
519 	//set the pointers to the correct location
520 	//send off results
521 
522 	//int result = -1;
523 	int result = 0;
524 	if(Tell(ptrlocation + Size) <= ptrlength)
525 	{ //verifies that we will be in bounds
526 		result = Size;
527 		memcpy(Data, ptrlocation, Size);
528 
529 
530 		ptrlocation += Size; //adjust the pointer location
531 
532 		//Tell(); //for debugging purposes
533 		/*for(int i = 0; i < result; i++)
534 		{
535 			Data = ptrlocation;
536 			Data++;
537 			ptrlocation++;
538 		}*/
539 	}
540 
541 
542 	return result;
543 
544 	/*
545 #ifdef _WIN_ALL
546   const size_t MaxDeviceRead=20000;
547 #endif
548 #ifndef _WIN_CE
549   if (HandleType==FILE_HANDLESTD)
550   {
551 #ifdef _WIN_ALL
552     if (Size>MaxDeviceRead)
553       Size=MaxDeviceRead;
554     hFile=GetStdHandle(STD_INPUT_HANDLE);
555 #else
556     hFile=stdin;
557 #endif
558   }
559 #endif
560 #ifdef _WIN_ALL
561   DWORD Read;
562   if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL))
563   {
564     if (IsDevice() && Size>MaxDeviceRead)
565       return(DirectRead(Data,MaxDeviceRead));
566     if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)
567       return(0);
568     return(-1);
569   }
570   return(Read);
571 #else
572   if (LastWrite)no
573   {
574     fflush(hFile);
575     LastWrite=false;
576   }
577   clearerr(hFile);
578   size_t ReadSize=fread(Data,1,Size,hFile);
579   if (ferror(hFile))
580     return(-1);
581   return((int)ReadSize);
582 #endif*/
583 }
584 
585 /**
586 Moves the pointer in the file to a specified location. Calls the <code>RawSeek</code> function.
587 @param Offset - the length from the current position
588 @param Method - the method to move the pointer.
589 If <code>SEEK_SET</code>, move the pointer <code>Offset</code> number of bytes to the new location in memory.
590 If <code>SEEK_END</code>, move the pointer to the end of the file (NOT IMPLEMENTED)
591 If <code>SEEK_CUR</code>, move the pointer (NOT IMPLEMENTED).
592 */
Seek(int64 Offset,int Method)593 void File::Seek(int64 Offset,int Method)
594 { //Calls RawSeek function
595 	RawSeek(Offset,Method);
596   /*if (!RawSeek(Offset,Method) && AllowExceptions)
597     ErrHandler.SeekError(FileName,FileNameW);*/
598 }
599 
600 /**
601 Moves the pointer in the file to a specified location
602 @param Offset - the length from the current position
603 @param Method - the method to move the pointer.
604 If <code>SEEK_SET</code>, move the pointer <code>Offset</code> number of bytes to the new location in memory.
605 If <code>SEEK_END</code>, move the pointer to the end of the file (NOT IMPLEMENTED)
606 If <code>SEEK_CUR</code>, move the pointer (NOT IMPLEMENTED).
607 */
RawSeek(int64 Offset,int Method)608 bool File::RawSeek(int64 Offset,int Method)
609 { //Seeks file location
610  /* if (hFile==BAD_HANDLE)
611     return(true);*/  //we will assume all is well if we have gone this far.
612 
613 
614 	if(Method == SEEK_SET)
615 	{
616 		/*if(&ptrlocation + Offset > &initptrlocation + ptrlength)
617 			return(false); //we have overun the bounds
618 
619 		if(&ptrlocation + Offset < &initptrlocation)
620 			return(false); //we have overrun the bounds*/
621 
622 		//ptrlocation = (byte*)Offset;
623 
624 		bool result = true;
625 		byte * tempptrlocation = ptrlocation;
626 
627 		if(Offset > Tell())
628 		{
629 			byte newdiff = (byte)Offset - Tell();
630 			tempptrlocation += newdiff;
631 			//int64 telldebugging = Tell();
632 			//int64 telldebugging2 = Tell(tempptrlocation);
633 			//ptrlocation += newdiff;
634 			if(Tell(tempptrlocation)  > ptrlength )
635 			{//the new pointer length is farther than the length of the RAR file
636 				result = false;
637 			}
638 			else
639 			{// the new pointer length is within range of the length of the RAR file
640 				ptrlocation += newdiff;
641 				result = true;
642 			}
643 		}
644 		else if(Offset < Tell())
645 		{
646 			byte newdiff = Tell() - (byte)Offset;
647 			tempptrlocation -= newdiff;
648 
649 			//ptrlocation -= newdiff;
650 			if(Tell(tempptrlocation)  < Tell(initptrlocation))
651 			{//the new pointer length is before the range of the RAR file
652 				result = false;
653 			}
654 			else{//the new pointer is within range of the length of the file
655 				ptrlocation -= newdiff;
656 				result = true;
657 			}
658 
659 		}
660 
661 		//Tell(); //debugging function
662 		return(result);
663 	}
664 
665 	else if(Method == SEEK_END)
666 	{
667 		//we should go to the end of the file
668 		ptrlocation = initptrlocation; 	//reset the pointer location to the beginning of the RAR file
669 		ptrlocation += ptrlength;	//set the pointer to the end of the RAR file
670 		return true;
671 	}
672 	else if(Method == SEEK_CUR)
673 	{
674 		//we should do something else
675 		return false;
676 	}
677 
678 	else
679 	{//unknown method...
680 		return false;
681 	}
682 
683 /*  if (Offset<0 && Method!=SEEK_SET)
684   {
685     Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset;
686     Method=SEEK_SET;
687   }
688 #ifdef _WIN_ALL
689   LONG HighDist=(LONG)(Offset>>32);
690   if (SetFilePointer(hFile,(LONG)Offset,&HighDist,Method)==0xffffffff &&
691       GetLastError()!=NO_ERROR)
692     return(false);
693 #else
694   LastWrite=false;
695 #if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) && !defined(__VMS)
696   if (fseeko(hFile,Offset,Method)!=0)
697 #else
698   if (fseek(hFile,(long)Offset,Method)!=0)
699 #endif
700     return(false);
701 #endif
702   return(true);*/
703 }
704 
705 /**
706 @param ptrlocation - location that should be used to find the offset from the beginning of the file class
707 @return the location of the pointer offset that has been supplied in a <code>int64</code> format.
708 */
Tell(byte * theptrlocation)709 int64 File::Tell(byte* theptrlocation)
710 {
711 	return ((int64)theptrlocation - (int64)initptrlocation);
712 }
713 
714 /**
715 @return the location of the pointer offset in a <code>int64</code> format.
716 */
Tell()717 int64 File::Tell()
718 {//returns the offset value where the iterator lies
719 
720 	return ((int64)ptrlocation - (int64)initptrlocation);
721 /*  if (hFile==BAD_HANDLE)
722     if (AllowExceptions)
723       ErrHandler.SeekError(FileName,FileNameW);
724     else
725       return(-1);
726 #ifdef _WIN_ALL
727   LONG HighDist=0;
728   uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT);
729   if (LowDist==0xffffffff && GetLastError()!=NO_ERROR)
730     if (AllowExceptions)
731       ErrHandler.SeekError(FileName,FileNameW);
732     else
733       return(-1);
734   return(INT32TO64(HighDist,LowDist));
735 #else
736 #if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE)
737   return(ftello(hFile));
738 #else
739   return(ftell(hFile));
740 #endif
741 #endif*/
742 }
743 
744 /**
745 this is not needed for bulk_extractor
746 */
Prealloc(int64 Size)747 void File::Prealloc(int64 Size)
748 {
749 #ifdef _WIN_ALL
750   if (RawSeek(Size,SEEK_SET))
751   {
752     Truncate();
753     Seek(0,SEEK_SET);
754   }
755 #endif
756 
757 #if defined(_UNIX) && defined(USE_FALLOCATE)
758   // fallocate is rather new call. Only latest kernels support it.
759   // So we are not using it by default yet.
760   int fd = fileno(hFile);
761   if (fd >= 0)
762     fallocate(fd, 0, 0, Size);
763 #endif
764 }
765 
766 /**
767 Obtain a byte worth of data from the memory space
768 */
GetByte()769 byte File::GetByte()
770 {
771   byte Byte=0;
772   Read(&Byte,1);
773   return(Byte);
774 }
775 
776 /**
777 this is not needed for bulk_extractor
778 */
PutByte(byte Byte)779 void File::PutByte(byte Byte)
780 {
781   Write(&Byte,1);
782 }
783 
784 /**
785 this is not needed for bulk_extractor
786 */
Truncate()787 bool File::Truncate()
788 {
789 #ifdef _WIN_ALL
790   return(SetEndOfFile(hFile)==TRUE);
791 #else
792   return(false);
793 #endif
794 }
795 
796 /**
797 this is not needed for bulk_extractor
798 */
SetOpenFileTime(RarTime * ftm,RarTime * ftc,RarTime * fta)799 void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta)
800 { //We probably don't need to worry about this at all
801 #ifdef _WIN_ALL
802   bool sm=ftm!=NULL && ftm->IsSet();
803   bool sc=ftc!=NULL && ftc->IsSet();
804   bool sa=fta!=NULL && fta->IsSet();
805   FILETIME fm,fc,fa;
806   if (sm)
807     ftm->GetWin32(&fm);
808   if (sc)
809     ftc->GetWin32(&fc);
810   if (sa)
811     fta->GetWin32(&fa);
812   SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
813 #endif
814 }
815 
816 /**
817 this is not needed for bulk_extractor
818 */
SetCloseFileTime(RarTime * ftm,RarTime * fta)819 void File::SetCloseFileTime(RarTime *ftm,RarTime *fta)
820 { //We probably don't need to worry about this at all.
821 	//int i = 1+1;
822 #if defined(_UNIX) || defined(_EMX)
823   SetCloseFileTimeByName(FileName,ftm,fta);
824 #endif
825 }
826 
827 /**
828 this is not needed for bulk_extractor
829 */
SetCloseFileTimeByName(const char * Name,RarTime * ftm,RarTime * fta)830 void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta)
831 { //We probably don't need to worry about this at all.
832 	//int i = 1+1;
833 
834 #if defined(_UNIX) || defined(_EMX)
835   bool setm=ftm!=NULL && ftm->IsSet();
836   bool seta=fta!=NULL && fta->IsSet();
837   if (setm || seta)
838   {
839     utimbuf ut;
840     if (setm)
841       ut.modtime=ftm->GetUnix();
842     else
843       ut.modtime=fta->GetUnix();
844     if (seta)
845       ut.actime=fta->GetUnix();
846     else
847       ut.actime=ut.modtime;
848     utime(Name,&ut);
849   }
850 #endif
851 }
852 
853 /**
854 this is not needed for bulk_extractor
855 */
GetOpenFileTime(RarTime * ft)856 void File::GetOpenFileTime(RarTime *ft)
857 { //We probably don't need to worry about this at all.
858 #ifdef _WIN_ALL
859   FILETIME FileTime;
860   GetFileTime(hFile,NULL,NULL,&FileTime);
861   *ft=FileTime;
862 #endif
863 #if defined(_UNIX) || defined(_EMX)
864   struct stat st;
865   fstat(fileno(hFile),&st);
866   *ft=st.st_mtime;
867 #endif
868 }
869 
870 /**
871 @return the length of the memory, in bytes, that has been allocated for the <code>File</code> class.
872 */
FileLength()873 int64 File::FileLength()
874 { //returns length of file
875   return ptrlength;
876 
877 /*  SaveFilePos SavePos(*this);
878   Seek(0,SEEK_END);
879   return(Tell());*/
880   //Tell();
881 }
882 
883 /**
884 this is not needed for bulk_extractor
885 */
SetHandleType(FILE_HANDLETYPE Type)886 void File::SetHandleType(FILE_HANDLETYPE Type)
887 {
888   HandleType=Type;
889 }
890 
891 /**
892 Always returns false as we are never reading from a device
893 */
IsDevice()894 bool File::IsDevice()
895 { //This really doesn't have to be called
896 	return false; //No, we are not reading from a device
897 /*  if (hFile==BAD_HANDLE)
898     return(false);
899 #ifdef _WIN_ALL
900   uint Type=GetFileType(hFile);
901   return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE);
902 #else
903   return(isatty(fileno(hFile)));
904 #endif*/
905 }
906 
907 
908 #ifndef SFX_MODULE
909 /**
910 this is not needed for bulk_extractor
911 */
fprintf(const char * fmt,...)912 void File::fprintf(const char *fmt,...)
913 { //This function is not called in bulk_extractor
914   va_list argptr;
915   va_start(argptr,fmt);
916   safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024];
917   vsprintf(Msg,fmt,argptr);
918 #ifdef _WIN_ALL
919   for (int Src=0,Dest=0;;Src++)
920   {
921     char CurChar=Msg[Src];
922     if (CurChar=='\n')
923       OutMsg[Dest++]='\r';
924     OutMsg[Dest++]=CurChar;
925     if (CurChar==0)
926       break;
927   }
928 #else
929   strcpy(OutMsg,Msg);
930 #endif
931   Write(OutMsg,strlen(OutMsg));
932   va_end(argptr);
933 }
934 #endif
935 
936 /**
937 this is not needed for bulk_extractor
938 */
RemoveCreated()939 bool File::RemoveCreated()
940 { //This file is not called in bulk_extractor
941     return false;
942 }
943 
944 
945 #ifndef SFX_MODULE
946 /**
947 this is not needed for bulk_extractor
948 */
Copy(File & Dest,int64 Length)949 int64 File::Copy(File &Dest,int64 Length)
950 { //This file is not called in bulk_extractor
951   Array<char> Buffer(0x10000);
952   int64 CopySize=0;
953   bool CopyAll=(Length==INT64NDF);
954 
955   while (CopyAll || Length>0)
956   {
957     Wait();
958     size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size();
959     int ReadSize=Read(&Buffer[0],SizeToRead);
960     if (ReadSize==0)
961       break;
962     Dest.Write(&Buffer[0],ReadSize);
963     CopySize+=ReadSize;
964     if (!CopyAll)
965       Length-=ReadSize;
966   }
967   return(CopySize);
968 }
969 
970 /**
971 @return the current pointer location as a <code>void*</code> type pointer
972 */
GetPtrLocation()973 void* File::GetPtrLocation()
974 {
975 	return ptrlocation;
976 }
977 
978 /**
979 @return the initial pointer location when the <code>File</code> object was created
980 */
GetInitPtrLocation()981 void * File::GetInitPtrLocation()
982 {
983 	return initptrlocation;
984 }
985 
986 #endif
987