1 /*
   2  * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #include "PlatformDefs.h"
  27 #include "FilePath.h"
  28 
  29 #include <algorithm>
  30 #include <list>
  31 #include <sys/stat.h>
  32 
  33 bool FilePath::FileExists(const TString FileName) {
  34     bool result = false;
  35     struct stat buf;
  36 
  37     if ((stat(StringToFileSystemString(FileName), &buf) == 0) &&
  38             (S_ISREG(buf.st_mode) != 0)) {
  39         result = true;
  40     }
  41 
  42     return result;
  43 }
  44 
  45 bool FilePath::DirectoryExists(const TString DirectoryName) {
  46     bool result = false;
  47 
  48     struct stat buf;
  49 
  50     if ((stat(StringToFileSystemString(DirectoryName), &buf) == 0) &&
  51             (S_ISDIR(buf.st_mode) != 0)) {
  52         result = true;
  53     }
  54 
  55     return result;
  56 }
  57 
  58 bool FilePath::DeleteFile(const TString FileName) {
  59     bool result = false;
  60 
  61     if (FileExists(FileName) == true) {
  62         if (unlink(StringToFileSystemString(FileName)) == 0) {
  63             result = true;
  64         }
  65     }
  66 
  67     return result;
  68 }
  69 
  70 bool FilePath::DeleteDirectory(const TString DirectoryName) {
  71     bool result = false;
  72 
  73     if (DirectoryExists(DirectoryName) == true) {
  74         if (unlink(StringToFileSystemString(DirectoryName)) == 0) {
  75             result = true;
  76         }
  77     }
  78 
  79     return result;
  80 }
  81 
  82 TString FilePath::IncludeTrailingSeparator(const TString value) {
  83     TString result = value;
  84 
  85     if (value.size() > 0) {
  86         TString::iterator i = result.end();
  87         i--;
  88 
  89         if (*i != TRAILING_PATHSEPARATOR) {
  90             result += TRAILING_PATHSEPARATOR;
  91         }
  92     }
  93 
  94     return result;
  95 }
  96 
  97 TString FilePath::IncludeTrailingSeparator(const char* value) {
  98     TString lvalue = PlatformString(value).toString();
  99     return IncludeTrailingSeparator(lvalue);
 100 }
 101 
 102 TString FilePath::IncludeTrailingSeparator(const wchar_t* value) {
 103     TString lvalue = PlatformString(value).toString();
 104     return IncludeTrailingSeparator(lvalue);
 105 }
 106 
 107 TString FilePath::ExtractFilePath(TString Path) {
 108     return dirname(StringToFileSystemString(Path));
 109 }
 110 
 111 TString FilePath::ExtractFileExt(TString Path) {
 112     TString result;
 113     size_t dot = Path.find_last_of('.');
 114 
 115     if (dot != TString::npos) {
 116         result = Path.substr(dot, Path.size() - dot);
 117     }
 118 
 119     return result;
 120 }
 121 
 122 TString FilePath::ExtractFileName(TString Path) {
 123     return basename(StringToFileSystemString(Path));
 124 }
 125 
 126 TString FilePath::ChangeFileExt(TString Path, TString Extension) {
 127     TString result;
 128     size_t dot = Path.find_last_of('.');
 129 
 130     if (dot != TString::npos) {
 131         result = Path.substr(0, dot) + Extension;
 132     }
 133 
 134     if (result.empty() == true) {
 135         result = Path;
 136     }
 137 
 138     return result;
 139 }
 140 
 141 TString FilePath::FixPathForPlatform(TString Path) {
 142     TString result = Path;
 143     std::replace(result.begin(), result.end(),
 144             BAD_TRAILING_PATHSEPARATOR, TRAILING_PATHSEPARATOR);
 145     return result;
 146 }
 147 
 148 TString FilePath::FixPathSeparatorForPlatform(TString Path) {
 149     TString result = Path;
 150     std::replace(result.begin(), result.end(),
 151             BAD_PATH_SEPARATOR, PATH_SEPARATOR);
 152     return result;
 153 }
 154 
 155 TString FilePath::PathSeparator() {
 156     TString result;
 157     result = PATH_SEPARATOR;
 158     return result;
 159 }
 160 
 161 bool FilePath::CreateDirectory(TString Path, bool ownerOnly) {
 162     bool result = false;
 163 
 164     std::list<TString> paths;
 165     TString lpath = Path;
 166 
 167     while (lpath.empty() == false && DirectoryExists(lpath) == false) {
 168         paths.push_front(lpath);
 169         lpath = ExtractFilePath(lpath);
 170     }
 171 
 172     for (std::list<TString>::iterator iterator = paths.begin();
 173             iterator != paths.end(); iterator++) {
 174         lpath = *iterator;
 175 
 176         mode_t mode = S_IRWXU;
 177         if (!ownerOnly) {
 178             mode |= S_IRWXG | S_IROTH | S_IXOTH;
 179         }
 180         if (mkdir(StringToFileSystemString(lpath), mode) == 0) {
 181             result = true;
 182         } else {
 183             result = false;
 184             break;
 185         }
 186     }
 187 
 188     return result;
 189 }
 190 
 191 void FilePath::ChangePermissions(TString FileName, bool ownerOnly) {
 192     mode_t mode = S_IRWXU;
 193     if (!ownerOnly) {
 194         mode |= S_IRWXG | S_IROTH | S_IXOTH;
 195     }
 196     chmod(FileName.data(), mode);
 197 }