| 163 | if (kt_stat64(destination.c_str(), &st) == 0 && S_ISDIR(st.st_mode)) |
| 164 | { |
| 165 | // Destination is an existing directory. |
| 166 | if (access(destination.c_str(), W_OK) != 0) |
| 167 | return false; |
| 168 | |
| 169 | size_t pos = memFile.find_last_of("/\\"); |
| 170 | outPath += (outPath.back() == '/' || outPath.back() == '\\') ? "" : "/"; |
| 171 | outPath += (pos == std::string::npos) ? memFile : memFile.substr(pos + 1); |
| 172 | } |
| 173 | else |
| 174 | { |
| 175 | // Destination is a file path. |
| 176 | if (kt_stat64(outPath.c_str(), &st) == 0) |
| 177 | { |
| 178 | // Existing file: must be writable. |
| 179 | if (access(outPath.c_str(), W_OK) != 0) |
| 180 | return false; |
| 181 | } |
| 182 | else |
| 183 | { |
| 184 | // New file: parent directory must be writable. |
| 185 | size_t pos = outPath.find_last_of("/\\"); |
| 186 | std::string parent = (pos == std::string::npos) ? "." : outPath.substr(0, pos); |
| 187 | |
| 188 | if (access(parent.c_str(), W_OK) != 0) |
| 189 | return false; |
| 190 | } |
| 191 | } |
| 192 | |