Пример #1
0
bool CreatePath(const wchar *Path,bool SkipLastName)
{
  if (Path==NULL || *Path==0)
    return false;

#if defined(_WIN_ALL) || defined(_EMX)
  uint DirAttr=0;
#else
  uint DirAttr=0777;
#endif
  
  bool Success=true;

  for (const wchar *s=Path;*s!=0;s++)
  {
    wchar DirName[NM];
    if (s-Path>=ASIZE(DirName))
      break;

    // Process all kinds of path separators, so user can enter Unix style
    // path in Windows or Windows in Unix. s>Path check avoids attempting
    // creating an empty directory for paths starting from path separator.
    if (IsPathDiv(*s) && s>Path)
    {
#ifdef _WIN_ALL
      // We must not attempt to create "D:" directory, because first
      // CreateDirectory will fail, so we'll use \\?\D:, which forces Wine
      // to create "D:" directory.
      if (s==Path+2 && Path[1]==':')
        continue;
#endif
      wcsncpy(DirName,Path,s-Path);
      DirName[s-Path]=0;

      Success=MakeDir(DirName,true,DirAttr)==MKDIR_SUCCESS;
#ifndef GUI
      if (Success)
      {
        mprintf(St(MCreatDir),DirName);
        mprintf(L" %s",St(MOk));
      }
#endif
    }
  }
  if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
    Success=MakeDir(Path,true,DirAttr)==MKDIR_SUCCESS;
  return Success;
}
Пример #2
0
bool CreatePath(const wchar *Path,bool SkipLastName)
{
  if (Path==NULL || *Path==0)
    return(false);

#if defined(_WIN_ALL) || defined(_EMX)
  uint DirAttr=0;
#else
  uint DirAttr=0777;
#endif
  
  bool Success=true;

  for (const wchar *s=Path;*s!=0;s++)
  {
    if (s-Path>=NM)
      break;

    if (*s==CPATHDIVIDER)
    {
      wchar DirName[NM];
      wcsncpy(DirName,Path,s-Path);
      DirName[s-Path]=0;

      if (MakeDir(NULL,DirName,true,DirAttr)==MKDIR_SUCCESS)
      {
#ifndef GUI
        char DirNameA[NM];
        WideToChar(DirName,DirNameA,ASIZE(DirNameA));
        DirNameA[ASIZE(DirNameA)-1]=0;
        mprintf(St(MCreatDir),DirNameA);
        mprintf(" %s",St(MOk));
#endif
      }
      else
        Success=false;
    }
  }
  if (!SkipLastName)
    if (!IsPathDiv(*PointToLastChar(Path)))
      if (MakeDir(NULL,Path,true,DirAttr)!=MKDIR_SUCCESS)
        Success=false;
  return(Success);
}
Пример #3
0
MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr)
{
#ifdef _WIN_ALL
  // Windows automatically removes dots and spaces in the end of directory
  // name. So we detect such names and process them with \\?\ prefix.
  wchar *LastChar=PointToLastChar(Name);
  bool Special=*LastChar=='.' || *LastChar==' ';
  BOOL RetCode=Special ? FALSE : CreateDirectory(Name,NULL);
  if (RetCode==0 && !FileExist(Name))
  {
    wchar LongName[NM];
    if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
      RetCode=CreateDirectory(LongName,NULL);
  }
  if (RetCode!=0) // Non-zero return code means success for CreateDirectory.
  {
    if (SetAttr)
      SetFileAttr(Name,Attr);
    return MKDIR_SUCCESS;
  }
  int ErrCode=GetLastError();
  if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND)
    return MKDIR_BADPATH;
  return MKDIR_ERROR;
#elif defined(_UNIX)
  char NameA[NM];
  WideToChar(Name,NameA,ASIZE(NameA));
  mode_t uattr=SetAttr ? (mode_t)Attr:0777;
  int ErrCode=mkdir(NameA,uattr);
#ifdef _ANDROID
  if (ErrCode==-1 && errno!=ENOENT)
    ErrCode=JniMkdir(Name) ? 0 : -1;  // If external card is read-only for usual file API.
  if (ErrCode!=-1)
    JniFileNotify(Name,false);
#endif
  if (ErrCode==-1)
    return errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR;
  return MKDIR_SUCCESS;
#else
  return MKDIR_ERROR;
#endif
}
Пример #4
0
// Return 'true' if we need to exclude the directory from archiving as result
// of -x switch. We do not want -x*. switch to exclude all directories,
// so when archiving we process exclusion arguments for directories specially.
bool CommandData::ExclCheckDir(char *CheckName)
{
  // If exclusion mask and directory name match exactly, return true.
  if (ExclCheckArgs(ExclArgs,CheckName,true,MATCH_EXACT))
    return(true);

  // Now we want to allow wildcards in exclusion mask only if it has
  // '\' at the end. So 'dir*\' will exclude all dir* directories.
  // We append '\' to directory name, so it will match only masks having
  // '\' at the end.
  char DirName[NM+1];
  ConvertPath(CheckName,DirName);
  AddEndSlash(DirName);

  char *CurMask;
  ExclArgs->Rewind();
  while ((CurMask=ExclArgs->GetString())!=NULL)
    if (IsPathDiv(*PointToLastChar(CurMask)))
      if (CmpName(CurMask,DirName,MATCH_SUBPATH))
        return(true);
  
  return(false);
}
Пример #5
0
void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize)
{
  wcsncpyz(DestName,Cmd->ExtrPath,DestSize);

  // We need IsPathDiv check here to correctly handle Unix forward slash
  // in the end of destination path in Windows: rar x arc dest/
  if (*Cmd->ExtrPath!=0 && !IsPathDiv(*PointToLastChar(Cmd->ExtrPath)))
  {
    // Destination path can be without trailing slash if it come from GUI shell.
    AddEndSlash(DestName,DestSize);
  }

#ifndef SFX_MODULE
  if (Cmd->AppendArcNameToPath)
  {
    wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
    SetExt(DestName,NULL,DestSize);
    AddEndSlash(DestName,DestSize);
  }
#endif

#ifndef SFX_MODULE
  size_t ArcPathLength=wcslen(Cmd->ArcPath);
  if (ArcPathLength>0)
  {
    size_t NameLength=wcslen(ArcFileName);
    ArcFileName+=Min(ArcPathLength,NameLength);
    while (*ArcFileName==CPATHDIVIDER)
      ArcFileName++;
    if (*ArcFileName==0) // Excessive -ap switch.
    {
      *DestName=0;
      return;
    }
  }
#endif

  wchar Command=Cmd->Command[0];
  // Use -ep3 only in systems, where disk letters are exist, not in Unix.
  bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':');

  // We do not use any user specified destination paths when extracting
  // absolute paths in -ep3 mode.
  if (AbsPaths)
    *DestName=0;

  if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
    wcsncatz(DestName,PointToName(ArcFileName),DestSize);
  else
    wcsncatz(DestName,ArcFileName,DestSize);

  wchar DiskLetter=toupperw(DestName[0]);

  if (AbsPaths)
  {
    if (DestName[1]=='_' && IsPathDiv(DestName[2]) &&
        DiskLetter>='A' && DiskLetter<='Z')
      DestName[1]=':';
    else
      if (DestName[0]=='_' && DestName[1]=='_')
      {
        // Convert __server\share to \\server\share.
        DestName[0]=CPATHDIVIDER;
        DestName[1]=CPATHDIVIDER;
      }
  }
}
Пример #6
0
bool CommandData::ExclCheckArgs(StringList *Args,bool Dir,char *CheckName,bool CheckFullPath,int MatchMode)
{
  char *Name=ConvertPath(CheckName,NULL);
  char FullName[NM];
  char CurMask[NM+1]; // We reserve the space to append "*" to mask.
  *FullName=0;
  Args->Rewind();
  while (Args->GetString(CurMask,ASIZE(CurMask)-1))
  {
    char *LastMaskChar=PointToLastChar(CurMask);
    bool DirMask=IsPathDiv(*LastMaskChar); // Mask for directories only.

    if (Dir)
    {
      // CheckName is a directory.
      if (DirMask)
      {
        // We process the directory and have the directory exclusion mask.
        // So let's convert "mask\" to "mask" and process it normally.
        
        *LastMaskChar=0;
      }
      else
      {
        // If mask has wildcards in name part and does not have the trailing
        // '\' character, we cannot use it for directories.
      
        if (IsWildcard(PointToName(CurMask)))
          continue;
      }
    }
    else
    {
      // If we process a file inside of directory excluded by "dirmask\".
      // we want to exclude such file too. So we convert "dirmask\" to
      // "dirmask\*". It is important for operations other than archiving.
      // When archiving, directory matched by "dirmask\" is excluded
      // from further scanning.

      if (DirMask)
        strcat(CurMask,"*");
    }

#ifndef SFX_MODULE
    if (CheckFullPath && IsFullPath(CurMask))
    {
      // We do not need to do the special "*\" processing here, because
      // onlike the "else" part of this "if", now we convert names to full
      // format, so they all include the path, which is matched by "*\"
      // correctly. Moreover, removing "*\" from mask would break
      // the comparison, because now all names have the path.

      if (*FullName==0)
        ConvertNameToFull(CheckName,FullName);
      if (CmpName(CurMask,FullName,MatchMode))
        return(true);
    }
    else
#endif
    {
      char NewName[NM+2],*CurName=Name;
      if (CurMask[0]=='*' && IsPathDiv(CurMask[1]))
      {
        // We want "*\name" to match 'name' not only in subdirectories,
        // but also in the current directory. We convert the name
        // from 'name' to '.\name' to be matched by "*\" part even if it is
        // in current directory.
        NewName[0]='.';
        NewName[1]=CPATHDIVIDER;
        strncpyz(NewName+2,Name,ASIZE(NewName)-2);
        CurName=NewName;
      }

      if (CmpName(ConvertPath(CurMask,NULL),CurName,MatchMode))
        return(true);
    }
  }
  return(false);
}
Пример #7
0
void AddEndSlash(char *Path)
{
  char *LastChar=PointToLastChar(Path);
  if (*LastChar!=0 && *LastChar!=CPATHDIVIDER)
    strcat(LastChar,PATHDIVIDER);
}
Пример #8
0
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
{
#if defined(_WIN_32) || defined(_EMX)
  uint DirAttr=0;
#else
  uint DirAttr=0777;
#endif
#ifdef UNICODE_SUPPORTED
  bool Wide=PathW!=NULL && *PathW!=0 && UnicodeEnabled();
#else
  bool Wide=false;
#endif
  bool IgnoreAscii=false;
  bool Success=true;

  const char *s=Path;
  for (int PosW=0;;PosW++)
  {
    if (s==NULL || s-Path>=NM || *s==0)
      IgnoreAscii=true;
    if (Wide && (PosW>=NM || PathW[PosW]==0) || !Wide && IgnoreAscii)
      break;
    if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER)
    {
      wchar *DirPtrW=NULL,DirNameW[NM];
      if (Wide)
      {
        strncpyw(DirNameW,PathW,PosW);
        DirNameW[PosW]=0;
        DirPtrW=DirNameW;
      }
      char DirName[NM];
      if (IgnoreAscii)
        WideToChar(DirPtrW,DirName);
      else
      {
#ifndef DBCS_SUPPORTED
        if (*s!=CPATHDIVIDER)
          for (const char *n=s;*n!=0 && n-Path<NM;n++)
            if (*n==CPATHDIVIDER)
            {
              s=n;
              break;
            }
#endif
        strncpy(DirName,Path,s-Path);
        DirName[s-Path]=0;
      }
      if (MakeDir(DirName,DirPtrW,true,DirAttr)==MKDIR_SUCCESS)
      {
#ifndef GUI
        mprintf(St(MCreatDir),DirName);
        mprintf(" %s",St(MOk));
#endif
      }
      else
        Success=false;
    }
    if (!IgnoreAscii)
      s=charnext(s);
  }
  if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
    if (MakeDir(Path,PathW,true,DirAttr)!=MKDIR_SUCCESS)
      Success=false;
  return(Success);
}