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 >
C/C++ Source or Header  |  2006-06-27  |  12KB  |  648 lines

  1. #include "rar.hpp"
  2.  
  3. char* PointToName(const char *Path)
  4. {
  5.   const char *Found=NULL;
  6.   for (const char *s=Path;*s!=0;s=charnext(s))
  7.     if (IsPathDiv(*s))
  8.       Found=(char*)(s+1);
  9.   if (Found!=NULL)
  10.     return((char*)Found);
  11.   return (char*)((*Path && IsDriveDiv(Path[1]) && charnext(Path)==Path+1) ? Path+2:Path);
  12. }
  13.  
  14.  
  15. wchar* PointToName(const wchar *Path)
  16. {
  17.   for (int I=strlenw(Path)-1;I>=0;I--)
  18.     if (IsPathDiv(Path[I]))
  19.       return (wchar*)&Path[I+1];
  20.   return (wchar*)((*Path && IsDriveDiv(Path[1])) ? Path+2:Path);
  21. }
  22.  
  23.  
  24. char* PointToLastChar(const char *Path)
  25. {
  26.   for (const char *s=Path,*p=Path;;p=s,s=charnext(s))
  27.     if (*s==0)
  28.       return((char *)p);
  29. }
  30.  
  31.  
  32. char* ConvertPath(const char *SrcPath,char *DestPath)
  33. {
  34.   const char *DestPtr=SrcPath;
  35.  
  36.   /* prevents \..\ in any part of path string */
  37.   for (const char *s=DestPtr;*s!=0;s++)
  38.     if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
  39.       DestPtr=s+4;
  40.  
  41.   /* removes any sequence of . and \ in the beginning of path string */
  42.   while (*DestPtr)
  43.   {
  44.     const char *s=DestPtr;
  45.     if (s[0] && IsDriveDiv(s[1]))
  46.       s+=2;
  47.     if (s[0]=='\\' && s[1]=='\\')
  48.     {
  49.       const char *Slash=strchr(s+2,'\\');
  50.       if (Slash!=NULL && (Slash=strchr(Slash+1,'\\'))!=NULL)
  51.         s=Slash+1;
  52.     }
  53.     for (const char *t=s;*t!=0;t++)
  54.       if (IsPathDiv(*t))
  55.         s=t+1;
  56.       else
  57.         if (*t!='.')
  58.           break;
  59.     if (s==DestPtr)
  60.       break;
  61.     DestPtr=s;
  62.   }
  63.  
  64.   /* code above does not remove last "..", doing here */
  65.   if (DestPtr[0]=='.' && DestPtr[1]=='.' && DestPtr[2]==0)
  66.     DestPtr+=2;
  67.  
  68.   if (DestPath!=NULL)
  69.   {
  70.     char TmpStr[NM];
  71.     strncpy(TmpStr,DestPtr,sizeof(TmpStr)-1);
  72.     strcpy(DestPath,TmpStr);
  73.   }
  74.   return((char *)DestPtr);
  75. }
  76.  
  77.  
  78. wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath)
  79. {
  80.   const wchar *DestPtr=SrcPath;
  81.   for (const wchar *s=DestPtr;*s!=0;s++)
  82.     if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
  83.       DestPtr=s+4;
  84.   while (*DestPtr)
  85.   {
  86.     const wchar *s=DestPtr;
  87.     if (s[0] && IsDriveDiv(s[1]))
  88.       s+=2;
  89.     if (s[0]=='\\' && s[1]=='\\')
  90.     {
  91.       const wchar *Slash=strchrw(s+2,'\\');
  92.       if (Slash!=NULL && (Slash=strchrw(Slash+1,'\\'))!=NULL)
  93.         s=Slash+1;
  94.     }
  95.     for (const wchar *t=s;*t!=0;t++)
  96.       if (IsPathDiv(*t))
  97.         s=t+1;
  98.       else
  99.         if (*t!='.')
  100.           break;
  101.     if (s==DestPtr)
  102.       break;
  103.     DestPtr=s;
  104.   }
  105.   if (DestPath!=NULL)
  106.   {
  107.     wchar TmpStr[NM];
  108.     strncpyw(TmpStr,DestPtr,sizeof(TmpStr)/sizeof(TmpStr[0])-1);
  109.     strcpyw(DestPath,TmpStr);
  110.   }
  111.   return((wchar *)DestPtr);
  112. }
  113.  
  114.  
  115. void SetExt(char *Name,const char *NewExt)
  116. {
  117.   char *Dot=GetExt(Name);
  118.   if (NewExt==NULL)
  119.   {
  120.     if (Dot!=NULL)
  121.       *Dot=0;
  122.   }
  123.   else
  124.     if (Dot==NULL)
  125.     {
  126.       strcat(Name,".");
  127.       strcat(Name,NewExt);
  128.     }
  129.     else
  130.       strcpy(Dot+1,NewExt);
  131. }
  132.  
  133.  
  134. #ifndef SFX_MODULE
  135. void SetExt(wchar *Name,const wchar *NewExt)
  136. {
  137.   if (Name==NULL || *Name==0)
  138.     return;
  139.   wchar *Dot=GetExt(Name);
  140.   if (NewExt==NULL)
  141.   {
  142.     if (Dot!=NULL)
  143.       *Dot=0;
  144.   }
  145.   else
  146.     if (Dot==NULL)
  147.     {
  148.       strcatw(Name,(const wchar *)L".");
  149.       strcatw(Name,NewExt);
  150.     }
  151.     else
  152.       strcpyw(Dot+1,NewExt);
  153. }
  154. #endif
  155.  
  156.  
  157. #ifndef SFX_MODULE
  158. void SetSFXExt(char *SFXName)
  159. {
  160. #ifdef _UNIX
  161.   SetExt(SFXName,"sfx");
  162. #endif
  163.  
  164. #if defined(_WIN_32) || defined(_EMX)
  165.   SetExt(SFXName,"exe");
  166. #endif
  167. }
  168. #endif
  169.  
  170.  
  171. #ifndef SFX_MODULE
  172. void SetSFXExt(wchar *SFXName)
  173. {
  174.   if (SFXName==NULL || *SFXName==0)
  175.     return;
  176.  
  177. #ifdef __VMS
  178.   SetExt(SFXName,(const wchar *)L"exe");
  179. #elif defined(_UNIX)
  180.   SetExt(SFXName,L"sfx");
  181. #endif
  182.  
  183. #if defined(_WIN_32) || defined(_EMX)
  184.   SetExt(SFXName,L"exe");
  185. #endif
  186. }
  187. #endif
  188.  
  189.  
  190. char *GetExt(const char *Name)
  191. {
  192.   return(strrchrd(PointToName(Name),'.'));
  193. }
  194.  
  195.  
  196. wchar *GetExt(const wchar *Name)
  197. {
  198.   return(Name==NULL ? (wchar *)L"":strrchrw(PointToName(Name),'.'));
  199. }
  200.  
  201.  
  202. bool CmpExt(const char *Name,const char *Ext)
  203. {
  204.   char *NameExt=GetExt(Name);
  205.   return(NameExt!=NULL && stricomp(NameExt+1,Ext)==0);
  206. }
  207.  
  208.  
  209. bool IsWildcard(const char *Str,const wchar *StrW)
  210. {
  211.   if (StrW!=NULL && *StrW!=0)
  212.     return(strpbrkw(StrW,(const wchar *)L"*?")!=NULL);
  213.   return(Str==NULL ? false:strpbrk(Str,"*?")!=NULL);
  214. }
  215.  
  216.  
  217. bool IsPathDiv(int Ch)
  218. {
  219. #if defined(_WIN_32) || defined(_EMX)
  220.   return(Ch=='\\' || Ch=='/');
  221. #else
  222.   return(Ch==CPATHDIVIDER);
  223. #endif
  224. }
  225.  
  226.  
  227. bool IsDriveDiv(int Ch)
  228. {
  229. #ifdef _UNIX
  230.   return(false);
  231. #else
  232.   return(Ch==':');
  233. #endif
  234. }
  235.  
  236.  
  237. int GetPathDisk(const char *Path)
  238. {
  239.   if (IsDiskLetter(Path))
  240.     return(toupper(*Path)-'A');
  241.   else
  242.     return(-1);
  243. }
  244.  
  245.  
  246. void AddEndSlash(char *Path)
  247. {
  248.   char *LastChar=PointToLastChar(Path);
  249.   if (*LastChar!=0 && *LastChar!=CPATHDIVIDER)
  250.     strcat(LastChar,PATHDIVIDER);
  251. }
  252.  
  253.  
  254. void AddEndSlash(wchar *Path)
  255. {
  256.   int Length=strlenw(Path);
  257.   if (Length>0 && Path[Length-1]!=CPATHDIVIDER)
  258.     strcatw(Path,(const wchar *)PATHDIVIDERW);
  259. }
  260.  
  261.  
  262. void GetFilePath(const char *FullName,char *Path)
  263. {
  264.   int PathLength=PointToName(FullName)-FullName;
  265.   strncpy(Path,FullName,PathLength);
  266.   Path[PathLength]=0;
  267. }
  268.  
  269.  
  270. void GetFilePath(const wchar *FullName,wchar *Path)
  271. {
  272.   const wchar *PathPtr=/*(*FullName && IsDriveDiv(FullName[1])) ? FullName+2:*/FullName;
  273.   int PathLength=PointToName(FullName)-FullName;
  274.   strncpyw(Path,PathPtr,PathLength);
  275.   Path[PathLength]=0;
  276. }
  277.  
  278.  
  279. void RemoveNameFromPath(char *Path)
  280. {
  281.   char *Name=PointToName(Path);
  282.   if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
  283.     Name--;
  284.   *Name=0;
  285. }
  286.  
  287.  
  288. #ifndef SFX_MODULE
  289. void RemoveNameFromPath(wchar *Path)
  290. {
  291.   wchar *Name=PointToName(Path);
  292.   if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
  293.     Name--;
  294.   *Name=0;
  295. }
  296. #endif
  297.  
  298.  
  299. #ifndef SFX_MODULE
  300. bool EnumConfigPaths(char *Path,int Number)
  301. {
  302. #ifdef _EMX
  303.   static char RARFileName[NM];
  304.   if (Number==-1)
  305.     strcpy(RARFileName,Path);
  306.   if (Number!=0)
  307.     return(false);
  308.   if (_osmode==OS2_MODE)
  309.   {
  310.     PTIB ptib;
  311.     PPIB ppib;
  312.     DosGetInfoBlocks(&ptib, &ppib);
  313.     DosQueryModuleName(ppib->pib_hmte,NM,Path);
  314.   }
  315.   else
  316.     strcpy(Path,RARFileName);
  317.   RemoveNameFromPath(Path);
  318.   return(true);
  319. #elif defined(_UNIX)
  320.   if (Number==0)
  321.   {
  322.     char *EnvStr=getenv("HOME");
  323.     if (EnvStr==NULL)
  324.       return(false);
  325.     strncpy(Path,EnvStr,NM);
  326.     Path[NM-1]=0;
  327.     return(true);
  328.   }
  329.   static const char *AltPath[]={
  330.     "/etc","/etc/rar","/usr/lib","/usr/local/lib","/usr/local/etc"
  331.   };
  332.   Number--;
  333.   if (Number<0 || Number>=sizeof(AltPath)/sizeof(AltPath[0]))
  334.     return(false);
  335.   strcpy(Path,AltPath[Number]);
  336.   return(true);
  337. #elif defined(_WIN_32)
  338.   if (Number!=0)
  339.     return(false);
  340.   GetModuleFileName(NULL,Path,NM);
  341.   RemoveNameFromPath(Path);
  342.   return(true);
  343. #else
  344.   return(false);
  345. #endif
  346. }
  347. #endif
  348.  
  349.  
  350. #ifndef SFX_MODULE
  351. void GetConfigName(const char *Name,char *FullName,bool CheckExist)
  352. {
  353.   for (int I=0;EnumConfigPaths(FullName,I);I++)
  354.   {
  355.     AddEndSlash(FullName);
  356.     strcat(FullName,Name);
  357.     if (!CheckExist || WildFileExist(FullName))
  358.       break;
  359.   }
  360. }
  361. #endif
  362.  
  363.  
  364. char* GetVolNumPart(char *ArcName)
  365. {
  366.   char *ChPtr=ArcName+strlen(ArcName)-1;
  367.   while (!isdigit(*ChPtr) && ChPtr>ArcName)
  368.     ChPtr--;
  369.   char *NumPtr=ChPtr;
  370.   while (isdigit(*NumPtr) && NumPtr>ArcName)
  371.     NumPtr--;
  372.   while (NumPtr>ArcName && *NumPtr!='.')
  373.   {
  374.     if (isdigit(*NumPtr))
  375.     {
  376.       char *Dot=strchrd(PointToName(ArcName),'.');
  377.       if (Dot!=NULL && Dot<NumPtr)
  378.         ChPtr=NumPtr;
  379.       break;
  380.     }
  381.     NumPtr--;
  382.   }
  383.   return(ChPtr);
  384. }
  385.  
  386.  
  387. void NextVolumeName(char *ArcName,bool OldNumbering)
  388. {
  389.   char *ChPtr;
  390.   if ((ChPtr=GetExt(ArcName))==NULL)
  391.   {
  392.     strcat(ArcName,".rar");
  393.     ChPtr=GetExt(ArcName);
  394.   }
  395.   else
  396.     if (ChPtr[1]==0 || stricomp(ChPtr+1,"exe")==0 || stricomp(ChPtr+1,"sfx")==0)
  397.       strcpy(ChPtr+1,"rar");
  398.   if (!OldNumbering)
  399.   {
  400.     ChPtr=GetVolNumPart(ArcName);
  401.  
  402.     while ((++(*ChPtr))=='9'+1)
  403.     {
  404.       *ChPtr='0';
  405.       ChPtr--;
  406.       if (ChPtr<ArcName || !isdigit(*ChPtr))
  407.       {
  408.         for (char *EndPtr=ArcName+strlen(ArcName);EndPtr!=ChPtr;EndPtr--)
  409.           *(EndPtr+1)=*EndPtr;
  410.         *(ChPtr+1)='1';
  411.         break;
  412.       }
  413.     }
  414.   }
  415.   else
  416.     if (!isdigit(*(ChPtr+2)) || !isdigit(*(ChPtr+3)))
  417.       strcpy(ChPtr+2,"00");
  418.     else
  419.     {
  420.       ChPtr+=3;
  421.       while ((++(*ChPtr))=='9'+1)
  422.         if (*(ChPtr-1)=='.')
  423.         {
  424.           *ChPtr='A';
  425.           break;
  426.         }
  427.         else
  428.         {
  429.           *ChPtr='0';
  430.           ChPtr--;
  431.         }
  432.     }
  433. }
  434.  
  435.  
  436. bool IsNameUsable(const char *Name)
  437. {
  438. #ifndef _UNIX
  439.   if (Name[0] && Name[1] && strchr(Name+2,':')!=NULL)
  440.     return(false);
  441.   for (const char *s=Name;*s!=0;s=charnext(s))
  442.     if (*s<32)
  443.       return(false);
  444. #endif
  445.   return(*Name!=0 && strpbrk(Name,"?*<>|\"")==NULL);
  446. }
  447.  
  448.  
  449. void MakeNameUsable(char *Name,bool Extended)
  450. {
  451.   for (char *s=Name;*s!=0;s=charnext(s))
  452.   {
  453.     if (strchr(Extended ? "?*<>|\"":"?*",*s)!=NULL || Extended && *s<32)
  454.       *s='_';
  455. #ifdef _EMX
  456.     if (*s=='=')
  457.       *s='_';
  458. #endif
  459. #ifndef _UNIX
  460.     if (s-Name>1 && *s==':')
  461.       *s='_';
  462. #endif
  463.   }
  464. }
  465.  
  466.  
  467. char* UnixSlashToDos(char *SrcName,char *DestName,uint MaxLength)
  468. {
  469.   if (DestName!=NULL && DestName!=SrcName)
  470.     if (strlen(SrcName)>=MaxLength)
  471.     {
  472.       *DestName=0;
  473.       return(DestName);
  474.     }
  475.     else
  476.       strcpy(DestName,SrcName);
  477.   for (char *s=SrcName;*s!=0;s=charnext(s))
  478.   {
  479.     if (*s=='/')
  480.       if (DestName==NULL)
  481.         *s='\\';
  482.       else
  483.         DestName[s-SrcName]='\\';
  484.   }
  485.   return(DestName==NULL ? SrcName:DestName);
  486. }
  487.  
  488.  
  489. char* DosSlashToUnix(char *SrcName,char *DestName,uint MaxLength)
  490. {
  491.   if (DestName!=NULL && DestName!=SrcName)
  492.     if (strlen(SrcName)>=MaxLength)
  493.     {
  494.       *DestName=0;
  495.       return(DestName);
  496.     }
  497.     else
  498.       strcpy(DestName,SrcName);
  499.   for (char *s=SrcName;*s!=0;s=charnext(s))
  500.   {
  501.     if (*s=='\\')
  502.       if (DestName==NULL)
  503.         *s='/';
  504.       else
  505.         DestName[s-SrcName]='/';
  506.   }
  507.   return(DestName==NULL ? SrcName:DestName);
  508. }
  509.  
  510.  
  511. bool IsFullPath(const char *Path)
  512. {
  513.   char PathOnly[NM];
  514.   GetFilePath(Path,PathOnly);
  515.   if (IsWildcard(PathOnly))
  516.     return(true);
  517. #if defined(_WIN_32) || defined(_EMX)
  518.   return(Path[0]=='\\' && Path[1]=='\\' ||
  519.          IsDiskLetter(Path) && IsPathDiv(Path[2]));
  520. #else
  521.   return(IsPathDiv(Path[0]));
  522. #endif
  523. }
  524.  
  525.  
  526. bool IsDiskLetter(const char *Path)
  527. {
  528.   char Letter=toupper(Path[0]);
  529.   return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
  530. }
  531.  
  532.  
  533. void GetPathRoot(const char *Path,char *Root)
  534. {
  535.   *Root=0;
  536.   if (IsDiskLetter(Path))
  537.     sprintf(Root,"%c:\\",*Path);
  538.   else
  539.     if (Path[0]=='\\' && Path[1]=='\\')
  540.     {
  541.       const char *Slash=strchr(Path+2,'\\');
  542.       if (Slash!=NULL)
  543.       {
  544.         int Length;
  545.         if ((Slash=strchr(Slash+1,'\\'))!=NULL)
  546.           Length=Slash-Path+1;
  547.         else
  548.           Length=strlen(Path);
  549.         strncpy(Root,Path,Length);
  550.         Root[Length]=0;
  551.       }
  552.     }
  553. }
  554.  
  555.  
  556. int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate)
  557. {
  558.   int Version=0;
  559.   char *VerText=strrchrd(Name,';');
  560.   if (VerText!=NULL)
  561.   {
  562.     Version=atoi(VerText+1);
  563.     if (Truncate)
  564.       *VerText=0;
  565.   }
  566.   if (NameW!=NULL)
  567.   {
  568.     wchar *VerTextW=strrchrw(NameW,';');
  569.     if (VerTextW!=NULL)
  570.     {
  571.       if (Version==0)
  572.         Version=atoiw(VerTextW+1);
  573.       if (Truncate)
  574.         *VerTextW=0;
  575.     }
  576.   }
  577.   return(Version);
  578. }
  579.  
  580.  
  581. #ifndef SFX_MODULE
  582. char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering)
  583. {
  584.   if (FirstName!=VolName)
  585.     strcpy(FirstName,VolName);
  586.   char *VolNumStart=FirstName;
  587.   if (NewNumbering)
  588.   {
  589.     int N='1';
  590.     for (char *ChPtr=GetVolNumPart(FirstName);ChPtr>FirstName;ChPtr--)
  591.       if (isdigit(*ChPtr))
  592.       {
  593.         *ChPtr=N;
  594.         N='0';
  595.       }
  596.       else
  597.         if (N=='0')
  598.         {
  599.           VolNumStart=ChPtr+1;
  600.           break;
  601.         }
  602.   }
  603.   else
  604.   {
  605.     SetExt(FirstName,"rar");
  606.     VolNumStart=GetExt(FirstName);
  607.   }
  608.   if (!FileExist(FirstName))
  609.   {
  610.     char Mask[NM];
  611.     strcpy(Mask,FirstName);
  612.     SetExt(Mask,"*");
  613.     FindFile Find;
  614.     Find.SetMask(Mask);
  615.     struct FindData FD;
  616.     while (Find.Next(&FD))
  617.     {
  618.       Archive Arc;
  619.       if (Arc.Open(FD.Name,FD.NameW) && Arc.IsArchive(true) && !Arc.NotFirstVolume)
  620.       {
  621.         strcpy(FirstName,FD.Name);
  622.         break;
  623.       }
  624.     }
  625.   }
  626.   return(VolNumStart);
  627. }
  628. #endif
  629.  
  630.  
  631.  
  632.  
  633. wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW)
  634. {
  635.   if (NameW!=NULL && *NameW!=0)
  636.   {
  637.     if (DestW!=NameW)
  638.       strcpyw(DestW,NameW);
  639.   }
  640.   else
  641.     CharToWide(Name,DestW);
  642.   return(DestW);
  643. }
  644.  
  645.  
  646.  
  647.  
  648.