bool CServerPath::DoChangePath(std::wstring &subdir, bool isFile) { std::wstring dir = subdir; std::wstring file; if (dir.empty()) { if (empty() || isFile) { return false; } else { return true; } } bool const was_empty = empty(); CServerPathData& data = m_data.get(); switch (m_type) { case VMS: { size_t pos1 = dir.find(traits[m_type].left_enclosure); if (pos1 == std::wstring::npos) { size_t pos2 = dir.rfind(traits[m_type].right_enclosure); if (pos2 != std::wstring::npos) { return false; } if (isFile) { if (was_empty) { return false; } file = dir; break; } } else { size_t pos2 = dir.rfind(traits[m_type].right_enclosure); if (pos2 == std::wstring::npos || pos2 <= pos1 + 1) { return false; } bool enclosure_is_last = pos2 == (dir.size() - 1); if (isFile == enclosure_is_last) { return false; } if (isFile) { file = dir.substr(pos2 + 1); } dir = dir.substr(0, pos2); if (pos1) { data.m_prefix = fz::sparse_optional<std::wstring>(dir.substr(0, pos1)); } dir = dir.substr(pos1 + 1); data.m_segments.clear(); } if (!Segmentize(dir, data.m_segments)) { return false; } if (data.m_segments.empty() && was_empty) { return false; } } break; case DOS: case DOS_FWD_SLASHES: { bool is_absolute = false; size_t sep = dir.find_first_of(traits[m_type].separators); if (sep == std::wstring::npos) { sep = dir.size(); } size_t colon = dir.find(':'); if (colon != std::wstring::npos && colon > 0 && colon == sep - 1) { is_absolute = true; } if (is_absolute) { data.m_segments.clear(); } else if (IsSeparator(dir[0])) { // Drive-relative path if (data.m_segments.empty()) { return false; } std::wstring first = data.m_segments.front(); data.m_segments.clear(); data.m_segments.push_back(first); dir = dir.substr(1); } // else: Any other relative path if (isFile && !ExtractFile(dir, file)) { return false; } if (!Segmentize(dir, data.m_segments)) { return false; } if (data.m_segments.empty() && was_empty) { return false; } } break; case MVS: { // Remove the double quoation some servers send in PWD reply size_t i = 0; wchar_t c = dir[i]; while (c == FTP_MVS_DOUBLE_QUOTE) { c = dir[++i]; } dir.erase(0, i); while (!dir.empty()) { c = dir.back(); if (c != FTP_MVS_DOUBLE_QUOTE) { break; } else { dir.pop_back(); } } } if (dir.empty()) { return false; } if (dir[0] == traits[m_type].left_enclosure) { if (dir.back() != traits[m_type].right_enclosure) { return false; } dir = dir.substr(1, dir.size() - 2); data.m_segments.clear(); } else if (dir.back() == traits[m_type].right_enclosure) { return false; } else if (was_empty) { return false; } if (!dir.empty() && dir.back() == ')') { // Partitioned dataset member if (!isFile) { return false; } size_t pos = dir.find('('); if (pos == std::wstring::npos) { return false; } dir.pop_back(); file = dir.substr(pos + 1); dir = dir.substr(0, pos); if (!was_empty && !data.m_prefix && !dir.empty()) { return false; } data.m_prefix.clear(); } else { if (!was_empty && !data.m_prefix) { if (dir.find('.') != std::wstring::npos || !isFile) { return false; } } if (isFile) { if (!ExtractFile(dir, file)) { return false; } data.m_prefix = fz::sparse_optional<std::wstring>(L"."); } else if (!dir.empty() && dir.back() == '.') { data.m_prefix = fz::sparse_optional<std::wstring>(L"."); } else { data.m_prefix.clear(); } } if (!Segmentize(dir, data.m_segments)) { return false; } break; case HPNONSTOP: if (dir[0] == '\\') { data.m_segments.clear(); } if (isFile && !ExtractFile(dir, file)) { return false; } if (!Segmentize(dir, data.m_segments)) { return false; } if (data.m_segments.empty() && was_empty) { return false; } break; case VXWORKS: { if (dir[0] != ':') { if (was_empty) { return false; } } else { size_t colon2 = dir.find(':', 1); if (colon2 == std::wstring::npos || colon2 == 1) { return false; } data.m_prefix = fz::sparse_optional<std::wstring>(dir.substr(0, colon2 + 1)); dir = dir.substr(colon2 + 1); data.m_segments.clear(); } if (isFile && !ExtractFile(dir, file)) { return false; } if (!Segmentize(dir, data.m_segments)) { return false; } } break; case CYGWIN: { if (IsSeparator(dir[0])) { data.m_segments.clear(); data.m_prefix.clear(); } else if (was_empty) { return false; } if (dir[0] == '/' && dir[1] == '/') { data.m_prefix = fz::sparse_optional<std::wstring>(std::wstring(1, traits[m_type].separators[0])); dir = dir.substr(1); } if (isFile && !ExtractFile(dir, file)) { return false; } if (!Segmentize(dir, data.m_segments)) { return false; } } break; default: { if (IsSeparator(dir[0])) { data.m_segments.clear(); } else if (was_empty) { return false; } if (isFile && !ExtractFile(dir, file)) { return false; } if (!Segmentize(dir, data.m_segments)) { return false; } } break; } if (!traits[m_type].has_root && data.m_segments.empty()) { return false; } if (isFile) { if (traits[m_type].has_dots) { if (file == L".." || file == L".") { return false; } } subdir = file; } return true; }
bool CServerPath::ChangePath(wxString &subdir, bool isFile) { wxString dir = subdir; wxString file; dir.Trim(true); dir.Trim(false); if (dir == _T("")) { if (IsEmpty() || isFile) return false; else return true; } CServerPathData& data = m_data.Get(); switch (m_type) { case VMS: { int pos1 = dir.Find(traits[m_type].left_enclosure); if (pos1 == -1) { int pos2 = dir.Find(traits[m_type].right_enclosure, true); if (pos2 != -1) return false; if (isFile) { if (IsEmpty()) return false; file = dir; break; } } else { int pos2 = dir.Find(traits[m_type].right_enclosure, true); if (pos2 == -1 || pos2 <= pos1 + 1) return false; bool enclosure_is_last = static_cast<size_t>(pos2) == (dir.Length() - 1); if (isFile == enclosure_is_last) return false; if (isFile) file = dir.Mid(pos2 + 1); dir = dir.Left(pos2); if (pos1) data.m_prefix = dir.Left(pos1); dir = dir.Mid(pos1 + 1); data.m_segments.clear(); } if (!Segmentize(dir, data.m_segments)) return false; if (data.m_segments.empty() && m_bEmpty) return false; } break; case DOS: { bool is_relative = false; int sep = dir.Find(traits[m_type].separator); if (sep == -1) sep = dir.Len(); int colon = dir.Find(':'); if (colon > 0 && colon == sep - 1) is_relative = true; if (is_relative) data.m_segments.clear(); else if (dir[0] == traits[m_type].separator) { if (data.m_segments.empty()) return false; wxString first = data.m_segments.front(); data.m_segments.clear(); data.m_segments.push_back(first); dir = dir.Mid(1); } if (isFile && !ExtractFile(dir, file)) return false; if (!Segmentize(dir, data.m_segments)) return false; if (data.m_segments.empty() && m_bEmpty) return false; } break; case MVS: { // Remove the double quoation some servers send in PWD reply int i = 0; wxChar c = dir.c_str()[i]; while (c == FTP_MVS_DOUBLE_QUOTE) c = dir.c_str()[++i]; dir.Remove(0, i); while (dir != _T("")) { c = dir.Last(); if (c != FTP_MVS_DOUBLE_QUOTE) break; else dir.RemoveLast(); } } if (dir == _T("")) return false; if (dir.c_str()[0] == traits[m_type].left_enclosure) { if (dir.Last() != traits[m_type].right_enclosure) return false; dir.RemoveLast(); dir = dir.Mid(1); data.m_segments.clear(); } else if (dir.Last() == traits[m_type].right_enclosure) return false; else if (m_bEmpty) return false; if (dir.Last() == ')') { // Partitioned dataset member if (!isFile) return false; int pos = dir.Find('('); if (pos == -1) return false; dir.RemoveLast(); file = dir.Mid(pos + 1); dir = dir.Left(pos); if (!m_bEmpty && data.m_prefix == _T("") && !dir.empty()) return false; data.m_prefix.clear(); } else { if (!m_bEmpty && data.m_prefix == _T("")) { if (dir.Find('.') != -1 || !isFile) return false; } if (isFile) { if (!ExtractFile(dir, file)) return false; data.m_prefix = _T("."); } else if (dir.Last() == '.') data.m_prefix = _T("."); else data.m_prefix.clear(); } if (!Segmentize(dir, data.m_segments)) return false; break; case HPNONSTOP: if (dir[0] == '\\') data.m_segments.clear(); if (isFile && !ExtractFile(dir, file)) return false; if (!Segmentize(dir, data.m_segments)) return false; if (data.m_segments.empty() && m_bEmpty) return false; break; case VXWORKS: { if (dir[0] != ':') { if (IsEmpty()) return false; } else { int colon2; if ((colon2 = dir.Mid(1).Find(':')) < 1) return false; data.m_prefix = dir.Left(colon2 + 2); dir = dir.Mid(colon2 + 2); data.m_segments.clear(); } if (isFile && !ExtractFile(dir, file)) return false; if (!Segmentize(dir, data.m_segments)) return false; } break; case CYGWIN: { if (dir[0] == traits[m_type].separator) { data.m_segments.clear(); data.m_prefix.clear(); } else if (m_bEmpty) return false; if (dir.Left(2) == _T("//")) { data.m_prefix = traits[m_type].separator; dir = dir.Mid(1); } if (isFile && !ExtractFile(dir, file)) return false; if (!Segmentize(dir, data.m_segments)) return false; } break; default: { if (dir[0] == traits[m_type].separator) data.m_segments.clear(); else if (m_bEmpty) return false; if (isFile && !ExtractFile(dir, file)) return false; if (!Segmentize(dir, data.m_segments)) return false; } break; } if (!traits[m_type].has_root && data.m_segments.empty()) return false; if (isFile) { if (traits[m_type].has_dots) { if (file == _T("..") || file == _T(".")) return false; } subdir = file; } m_bEmpty = false; return true; }