1 /* 2 * Copyright (C) 2005-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #include "FTPDirectory.h" 10 11 #include "CurlFile.h" 12 #include "FTPParse.h" 13 #include "FileItem.h" 14 #include "URL.h" 15 #include "utils/CharsetConverter.h" 16 #include "utils/StringUtils.h" 17 #include "utils/URIUtils.h" 18 19 #include <climits> 20 21 using namespace XFILE; 22 23 CFTPDirectory::CFTPDirectory(void) = default; 24 CFTPDirectory::~CFTPDirectory(void) = default; 25 GetDirectory(const CURL & url2,CFileItemList & items)26bool CFTPDirectory::GetDirectory(const CURL& url2, CFileItemList &items) 27 { 28 CCurlFile reader; 29 30 CURL url(url2); 31 32 std::string path = url.GetFileName(); 33 if( !path.empty() && !StringUtils::EndsWith(path, "/") ) 34 { 35 path += "/"; 36 url.SetFileName(path); 37 } 38 39 if (!reader.Open(url)) 40 return false; 41 42 bool serverNotUseUTF8 = url.GetProtocolOption("utf8") == "0"; 43 44 char buffer[MAX_PATH + 1024]; 45 while( reader.ReadString(buffer, sizeof(buffer)) ) 46 { 47 std::string strBuffer = buffer; 48 49 StringUtils::RemoveCRLF(strBuffer); 50 51 CFTPParse parse; 52 if (parse.FTPParse(strBuffer)) 53 { 54 if( parse.getName().length() == 0 ) 55 continue; 56 57 if( parse.getFlagtrycwd() == 0 && parse.getFlagtryretr() == 0 ) 58 continue; 59 60 /* buffer name */ 61 std::string name; 62 name.assign(parse.getName()); 63 64 if( name == ".." || name == "." ) 65 continue; 66 67 // server returned filename could in utf8 or non-utf8 encoding 68 // we need utf8, so convert it to utf8 anyway 69 g_charsetConverter.unknownToUTF8(name); 70 71 // convert got empty result, ignore it 72 if (name.empty()) 73 continue; 74 75 if (serverNotUseUTF8 || name != parse.getName()) 76 // non-utf8 name path, tag it with protocol option. 77 // then we can talk to server with the same encoding in CurlFile according to this tag. 78 url.SetProtocolOption("utf8", "0"); 79 else 80 url.RemoveProtocolOption("utf8"); 81 82 CFileItemPtr pItem(new CFileItem(name)); 83 84 pItem->m_bIsFolder = parse.getFlagtrycwd() != 0; 85 std::string filePath = path + name; 86 if (pItem->m_bIsFolder) 87 URIUtils::AddSlashAtEnd(filePath); 88 89 /* qualify the url with host and all */ 90 url.SetFileName(filePath); 91 pItem->SetPath(url.Get()); 92 93 pItem->m_dwSize = parse.getSize(); 94 pItem->m_dateTime=parse.getTime(); 95 96 items.Add(pItem); 97 } 98 } 99 100 return true; 101 } 102 Exists(const CURL & url)103bool CFTPDirectory::Exists(const CURL& url) 104 { 105 // make sure ftp dir ends with slash, 106 // curl need to known it's a dir to check ftp directory existence. 107 std::string file = url.Get(); 108 URIUtils::AddSlashAtEnd(file); 109 110 CCurlFile ftp; 111 CURL url2(file); 112 return ftp.Exists(url2); 113 } 114