home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.rarlab.com
/
2014.05.ftp.rarlab.com.tar
/
ftp.rarlab.com
/
rar
/
unrar_vms_alpha-3.6.5.zip
/
pathfn.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
2006-06-27
|
12KB
|
648 lines
#include "rar.hpp"
char* PointToName(const char *Path)
{
const char *Found=NULL;
for (const char *s=Path;*s!=0;s=charnext(s))
if (IsPathDiv(*s))
Found=(char*)(s+1);
if (Found!=NULL)
return((char*)Found);
return (char*)((*Path && IsDriveDiv(Path[1]) && charnext(Path)==Path+1) ? Path+2:Path);
}
wchar* PointToName(const wchar *Path)
{
for (int I=strlenw(Path)-1;I>=0;I--)
if (IsPathDiv(Path[I]))
return (wchar*)&Path[I+1];
return (wchar*)((*Path && IsDriveDiv(Path[1])) ? Path+2:Path);
}
char* PointToLastChar(const char *Path)
{
for (const char *s=Path,*p=Path;;p=s,s=charnext(s))
if (*s==0)
return((char *)p);
}
char* ConvertPath(const char *SrcPath,char *DestPath)
{
const char *DestPtr=SrcPath;
/* prevents \..\ in any part of path string */
for (const char *s=DestPtr;*s!=0;s++)
if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
DestPtr=s+4;
/* removes any sequence of . and \ in the beginning of path string */
while (*DestPtr)
{
const char *s=DestPtr;
if (s[0] && IsDriveDiv(s[1]))
s+=2;
if (s[0]=='\\' && s[1]=='\\')
{
const char *Slash=strchr(s+2,'\\');
if (Slash!=NULL && (Slash=strchr(Slash+1,'\\'))!=NULL)
s=Slash+1;
}
for (const char *t=s;*t!=0;t++)
if (IsPathDiv(*t))
s=t+1;
else
if (*t!='.')
break;
if (s==DestPtr)
break;
DestPtr=s;
}
/* code above does not remove last "..", doing here */
if (DestPtr[0]=='.' && DestPtr[1]=='.' && DestPtr[2]==0)
DestPtr+=2;
if (DestPath!=NULL)
{
char TmpStr[NM];
strncpy(TmpStr,DestPtr,sizeof(TmpStr)-1);
strcpy(DestPath,TmpStr);
}
return((char *)DestPtr);
}
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath)
{
const wchar *DestPtr=SrcPath;
for (const wchar *s=DestPtr;*s!=0;s++)
if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
DestPtr=s+4;
while (*DestPtr)
{
const wchar *s=DestPtr;
if (s[0] && IsDriveDiv(s[1]))
s+=2;
if (s[0]=='\\' && s[1]=='\\')
{
const wchar *Slash=strchrw(s+2,'\\');
if (Slash!=NULL && (Slash=strchrw(Slash+1,'\\'))!=NULL)
s=Slash+1;
}
for (const wchar *t=s;*t!=0;t++)
if (IsPathDiv(*t))
s=t+1;
else
if (*t!='.')
break;
if (s==DestPtr)
break;
DestPtr=s;
}
if (DestPath!=NULL)
{
wchar TmpStr[NM];
strncpyw(TmpStr,DestPtr,sizeof(TmpStr)/sizeof(TmpStr[0])-1);
strcpyw(DestPath,TmpStr);
}
return((wchar *)DestPtr);
}
void SetExt(char *Name,const char *NewExt)
{
char *Dot=GetExt(Name);
if (NewExt==NULL)
{
if (Dot!=NULL)
*Dot=0;
}
else
if (Dot==NULL)
{
strcat(Name,".");
strcat(Name,NewExt);
}
else
strcpy(Dot+1,NewExt);
}
#ifndef SFX_MODULE
void SetExt(wchar *Name,const wchar *NewExt)
{
if (Name==NULL || *Name==0)
return;
wchar *Dot=GetExt(Name);
if (NewExt==NULL)
{
if (Dot!=NULL)
*Dot=0;
}
else
if (Dot==NULL)
{
strcatw(Name,(const wchar *)L".");
strcatw(Name,NewExt);
}
else
strcpyw(Dot+1,NewExt);
}
#endif
#ifndef SFX_MODULE
void SetSFXExt(char *SFXName)
{
#ifdef _UNIX
SetExt(SFXName,"sfx");
#endif
#if defined(_WIN_32) || defined(_EMX)
SetExt(SFXName,"exe");
#endif
}
#endif
#ifndef SFX_MODULE
void SetSFXExt(wchar *SFXName)
{
if (SFXName==NULL || *SFXName==0)
return;
#ifdef __VMS
SetExt(SFXName,(const wchar *)L"exe");
#elif defined(_UNIX)
SetExt(SFXName,L"sfx");
#endif
#if defined(_WIN_32) || defined(_EMX)
SetExt(SFXName,L"exe");
#endif
}
#endif
char *GetExt(const char *Name)
{
return(strrchrd(PointToName(Name),'.'));
}
wchar *GetExt(const wchar *Name)
{
return(Name==NULL ? (wchar *)L"":strrchrw(PointToName(Name),'.'));
}
bool CmpExt(const char *Name,const char *Ext)
{
char *NameExt=GetExt(Name);
return(NameExt!=NULL && stricomp(NameExt+1,Ext)==0);
}
bool IsWildcard(const char *Str,const wchar *StrW)
{
if (StrW!=NULL && *StrW!=0)
return(strpbrkw(StrW,(const wchar *)L"*?")!=NULL);
return(Str==NULL ? false:strpbrk(Str,"*?")!=NULL);
}
bool IsPathDiv(int Ch)
{
#if defined(_WIN_32) || defined(_EMX)
return(Ch=='\\' || Ch=='/');
#else
return(Ch==CPATHDIVIDER);
#endif
}
bool IsDriveDiv(int Ch)
{
#ifdef _UNIX
return(false);
#else
return(Ch==':');
#endif
}
int GetPathDisk(const char *Path)
{
if (IsDiskLetter(Path))
return(toupper(*Path)-'A');
else
return(-1);
}
void AddEndSlash(char *Path)
{
char *LastChar=PointToLastChar(Path);
if (*LastChar!=0 && *LastChar!=CPATHDIVIDER)
strcat(LastChar,PATHDIVIDER);
}
void AddEndSlash(wchar *Path)
{
int Length=strlenw(Path);
if (Length>0 && Path[Length-1]!=CPATHDIVIDER)
strcatw(Path,(const wchar *)PATHDIVIDERW);
}
void GetFilePath(const char *FullName,char *Path)
{
int PathLength=PointToName(FullName)-FullName;
strncpy(Path,FullName,PathLength);
Path[PathLength]=0;
}
void GetFilePath(const wchar *FullName,wchar *Path)
{
const wchar *PathPtr=/*(*FullName && IsDriveDiv(FullName[1])) ? FullName+2:*/FullName;
int PathLength=PointToName(FullName)-FullName;
strncpyw(Path,PathPtr,PathLength);
Path[PathLength]=0;
}
void RemoveNameFromPath(char *Path)
{
char *Name=PointToName(Path);
if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
Name--;
*Name=0;
}
#ifndef SFX_MODULE
void RemoveNameFromPath(wchar *Path)
{
wchar *Name=PointToName(Path);
if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
Name--;
*Name=0;
}
#endif
#ifndef SFX_MODULE
bool EnumConfigPaths(char *Path,int Number)
{
#ifdef _EMX
static char RARFileName[NM];
if (Number==-1)
strcpy(RARFileName,Path);
if (Number!=0)
return(false);
if (_osmode==OS2_MODE)
{
PTIB ptib;
PPIB ppib;
DosGetInfoBlocks(&ptib, &ppib);
DosQueryModuleName(ppib->pib_hmte,NM,Path);
}
else
strcpy(Path,RARFileName);
RemoveNameFromPath(Path);
return(true);
#elif defined(_UNIX)
if (Number==0)
{
char *EnvStr=getenv("HOME");
if (EnvStr==NULL)
return(false);
strncpy(Path,EnvStr,NM);
Path[NM-1]=0;
return(true);
}
static const char *AltPath[]={
"/etc","/etc/rar","/usr/lib","/usr/local/lib","/usr/local/etc"
};
Number--;
if (Number<0 || Number>=sizeof(AltPath)/sizeof(AltPath[0]))
return(false);
strcpy(Path,AltPath[Number]);
return(true);
#elif defined(_WIN_32)
if (Number!=0)
return(false);
GetModuleFileName(NULL,Path,NM);
RemoveNameFromPath(Path);
return(true);
#else
return(false);
#endif
}
#endif
#ifndef SFX_MODULE
void GetConfigName(const char *Name,char *FullName,bool CheckExist)
{
for (int I=0;EnumConfigPaths(FullName,I);I++)
{
AddEndSlash(FullName);
strcat(FullName,Name);
if (!CheckExist || WildFileExist(FullName))
break;
}
}
#endif
char* GetVolNumPart(char *ArcName)
{
char *ChPtr=ArcName+strlen(ArcName)-1;
while (!isdigit(*ChPtr) && ChPtr>ArcName)
ChPtr--;
char *NumPtr=ChPtr;
while (isdigit(*NumPtr) && NumPtr>ArcName)
NumPtr--;
while (NumPtr>ArcName && *NumPtr!='.')
{
if (isdigit(*NumPtr))
{
char *Dot=strchrd(PointToName(ArcName),'.');
if (Dot!=NULL && Dot<NumPtr)
ChPtr=NumPtr;
break;
}
NumPtr--;
}
return(ChPtr);
}
void NextVolumeName(char *ArcName,bool OldNumbering)
{
char *ChPtr;
if ((ChPtr=GetExt(ArcName))==NULL)
{
strcat(ArcName,".rar");
ChPtr=GetExt(ArcName);
}
else
if (ChPtr[1]==0 || stricomp(ChPtr+1,"exe")==0 || stricomp(ChPtr+1,"sfx")==0)
strcpy(ChPtr+1,"rar");
if (!OldNumbering)
{
ChPtr=GetVolNumPart(ArcName);
while ((++(*ChPtr))=='9'+1)
{
*ChPtr='0';
ChPtr--;
if (ChPtr<ArcName || !isdigit(*ChPtr))
{
for (char *EndPtr=ArcName+strlen(ArcName);EndPtr!=ChPtr;EndPtr--)
*(EndPtr+1)=*EndPtr;
*(ChPtr+1)='1';
break;
}
}
}
else
if (!isdigit(*(ChPtr+2)) || !isdigit(*(ChPtr+3)))
strcpy(ChPtr+2,"00");
else
{
ChPtr+=3;
while ((++(*ChPtr))=='9'+1)
if (*(ChPtr-1)=='.')
{
*ChPtr='A';
break;
}
else
{
*ChPtr='0';
ChPtr--;
}
}
}
bool IsNameUsable(const char *Name)
{
#ifndef _UNIX
if (Name[0] && Name[1] && strchr(Name+2,':')!=NULL)
return(false);
for (const char *s=Name;*s!=0;s=charnext(s))
if (*s<32)
return(false);
#endif
return(*Name!=0 && strpbrk(Name,"?*<>|\"")==NULL);
}
void MakeNameUsable(char *Name,bool Extended)
{
for (char *s=Name;*s!=0;s=charnext(s))
{
if (strchr(Extended ? "?*<>|\"":"?*",*s)!=NULL || Extended && *s<32)
*s='_';
#ifdef _EMX
if (*s=='=')
*s='_';
#endif
#ifndef _UNIX
if (s-Name>1 && *s==':')
*s='_';
#endif
}
}
char* UnixSlashToDos(char *SrcName,char *DestName,uint MaxLength)
{
if (DestName!=NULL && DestName!=SrcName)
if (strlen(SrcName)>=MaxLength)
{
*DestName=0;
return(DestName);
}
else
strcpy(DestName,SrcName);
for (char *s=SrcName;*s!=0;s=charnext(s))
{
if (*s=='/')
if (DestName==NULL)
*s='\\';
else
DestName[s-SrcName]='\\';
}
return(DestName==NULL ? SrcName:DestName);
}
char* DosSlashToUnix(char *SrcName,char *DestName,uint MaxLength)
{
if (DestName!=NULL && DestName!=SrcName)
if (strlen(SrcName)>=MaxLength)
{
*DestName=0;
return(DestName);
}
else
strcpy(DestName,SrcName);
for (char *s=SrcName;*s!=0;s=charnext(s))
{
if (*s=='\\')
if (DestName==NULL)
*s='/';
else
DestName[s-SrcName]='/';
}
return(DestName==NULL ? SrcName:DestName);
}
bool IsFullPath(const char *Path)
{
char PathOnly[NM];
GetFilePath(Path,PathOnly);
if (IsWildcard(PathOnly))
return(true);
#if defined(_WIN_32) || defined(_EMX)
return(Path[0]=='\\' && Path[1]=='\\' ||
IsDiskLetter(Path) && IsPathDiv(Path[2]));
#else
return(IsPathDiv(Path[0]));
#endif
}
bool IsDiskLetter(const char *Path)
{
char Letter=toupper(Path[0]);
return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
}
void GetPathRoot(const char *Path,char *Root)
{
*Root=0;
if (IsDiskLetter(Path))
sprintf(Root,"%c:\\",*Path);
else
if (Path[0]=='\\' && Path[1]=='\\')
{
const char *Slash=strchr(Path+2,'\\');
if (Slash!=NULL)
{
int Length;
if ((Slash=strchr(Slash+1,'\\'))!=NULL)
Length=Slash-Path+1;
else
Length=strlen(Path);
strncpy(Root,Path,Length);
Root[Length]=0;
}
}
}
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate)
{
int Version=0;
char *VerText=strrchrd(Name,';');
if (VerText!=NULL)
{
Version=atoi(VerText+1);
if (Truncate)
*VerText=0;
}
if (NameW!=NULL)
{
wchar *VerTextW=strrchrw(NameW,';');
if (VerTextW!=NULL)
{
if (Version==0)
Version=atoiw(VerTextW+1);
if (Truncate)
*VerTextW=0;
}
}
return(Version);
}
#ifndef SFX_MODULE
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering)
{
if (FirstName!=VolName)
strcpy(FirstName,VolName);
char *VolNumStart=FirstName;
if (NewNumbering)
{
int N='1';
for (char *ChPtr=GetVolNumPart(FirstName);ChPtr>FirstName;ChPtr--)
if (isdigit(*ChPtr))
{
*ChPtr=N;
N='0';
}
else
if (N=='0')
{
VolNumStart=ChPtr+1;
break;
}
}
else
{
SetExt(FirstName,"rar");
VolNumStart=GetExt(FirstName);
}
if (!FileExist(FirstName))
{
char Mask[NM];
strcpy(Mask,FirstName);
SetExt(Mask,"*");
FindFile Find;
Find.SetMask(Mask);
struct FindData FD;
while (Find.Next(&FD))
{
Archive Arc;
if (Arc.Open(FD.Name,FD.NameW) && Arc.IsArchive(true) && !Arc.NotFirstVolume)
{
strcpy(FirstName,FD.Name);
break;
}
}
}
return(VolNumStart);
}
#endif
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW)
{
if (NameW!=NULL && *NameW!=0)
{
if (DestW!=NameW)
strcpyw(DestW,NameW);
}
else
CharToWide(Name,DestW);
return(DestW);
}