Merge pull request #4857 from t-nelson/Gotham_13.2_backports
[vuplus_xbmc] / xbmc / filesystem / FTPDirectory.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "FTPDirectory.h"
22 #include "FTPParse.h"
23 #include "URL.h"
24 #include "utils/URIUtils.h"
25 #include "CurlFile.h"
26 #include "FileItem.h"
27 #include "utils/StringUtils.h"
28 #include "utils/CharsetConverter.h"
29 #include "climits"
30
31 using namespace XFILE;
32
33 CFTPDirectory::CFTPDirectory(void){}
34 CFTPDirectory::~CFTPDirectory(void){}
35
36 bool CFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
37 {
38   CCurlFile reader;
39
40   CURL url(strPath);
41
42   CStdString path = url.GetFileName();
43   if( !path.empty() && !StringUtils::EndsWith(path, "/") )
44   {
45     path += "/";
46     url.SetFileName(path);
47   }
48
49   if (!reader.Open(url))
50     return false;
51
52   bool serverNotUseUTF8 = url.GetProtocolOption("utf8").Equals("0");
53
54   char buffer[MAX_PATH + 1024];
55   while( reader.ReadString(buffer, sizeof(buffer)) )
56   {
57     CStdString strBuffer = buffer;
58
59     StringUtils::RemoveCRLF(strBuffer);
60
61     CFTPParse parse;
62     if (parse.FTPParse(strBuffer))
63     {
64       if( parse.getName().length() == 0 )
65         continue;
66
67       if( parse.getFlagtrycwd() == 0 && parse.getFlagtryretr() == 0 )
68         continue;
69
70       /* buffer name */
71       CStdString name;
72       name.assign(parse.getName());
73
74       if( name.Equals("..") || name.Equals(".") )
75         continue;
76
77       // server returned filename could in utf8 or non-utf8 encoding
78       // we need utf8, so convert it to utf8 anyway
79       g_charsetConverter.unknownToUTF8(name);
80
81       // convert got empty result, ignore it
82       if (name.empty())
83         continue;
84
85       if (serverNotUseUTF8 || name != parse.getName())
86         // non-utf8 name path, tag it with protocol option.
87         // then we can talk to server with the same encoding in CurlFile according to this tag.
88         url.SetProtocolOption("utf8", "0");
89       else
90         url.RemoveProtocolOption("utf8");
91
92       CFileItemPtr pItem(new CFileItem(name));
93
94       pItem->m_bIsFolder = (bool)(parse.getFlagtrycwd() != 0);
95       CStdString filePath = path + name;
96       if (pItem->m_bIsFolder)
97         URIUtils::AddSlashAtEnd(filePath);
98
99       /* qualify the url with host and all */
100       url.SetFileName(filePath);
101       pItem->SetPath(url.Get());
102
103       pItem->m_dwSize = parse.getSize();
104       pItem->m_dateTime=parse.getTime();
105
106       items.Add(pItem);
107     }
108   }
109
110   return true;
111 }
112
113 bool CFTPDirectory::Exists(const char* strPath)
114 {
115   // make sure ftp dir ends with slash,
116   // curl need to known it's a dir to check ftp directory existence.
117   CStdString file = strPath;
118   URIUtils::AddSlashAtEnd(file);
119
120   CCurlFile ftp;
121   CURL url(file);
122   return ftp.Exists(url);
123 }