/* * Copyright (C) 2005-2013 Team XBMC * http://xbmc.org * * This Program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This Program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with XBMC; see the file COPYING. If not, see * . * */ /* * know bugs: * - when opening a server for the first time with ip adres and the second time * with server name, access to the server is denied. * - when browsing entire network, user can't go back one step * share = smb://, user selects a workgroup, user selects a server. * doing ".." will go back to smb:// (entire network) and not to workgroup list. * * debugging is set to a max of 10 for release builds (see local.h) */ #include "utils/log.h" #include "SMBDirectory.h" #include "utils/URIUtils.h" #include "LocalizeStrings.h" #include "lib/libsmb/xbLibSmb.h" #include "GUIWindowManager.h" #include "dialogs/GUIDialogOK.h" #include "settings/GUISettings.h" #include "FileItem.h" #include "settings/AdvancedSettings.h" #include "PasswordManager.h" #include "Application.h" #include "utils/SingleLock.h" struct CachedDirEntry { unsigned int type; CStdString name; }; using namespace XFILE; using namespace std; CSMBDirectory::CSMBDirectory(void) { } CSMBDirectory::~CSMBDirectory(void) { } bool CSMBDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { // We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] /* samba isn't thread safe with old interface, always lock */ CSingleLock lock(smb); smb.Init(); /* we need an url to do proper escaping */ CURL url(strPath); //Separate roots for the authentication and the containing items to allow browsing to work correctly CStdString strRoot = strPath; CStdString strAuth; lock.Leave(); // OpenDir is locked int fd = OpenDir(url, strAuth); if (fd < 0) return false; if (!URIUtils::HasSlashAtEnd(strRoot)) strRoot += "/"; if (!URIUtils::HasSlashAtEnd(strAuth)) strAuth += "/"; CStdString strFile; // need to keep the samba lock for as short as possible. // so we first cache all directory entries and then go over them again asking for stat // "stat" is locked each time. that way the lock is freed between stat requests vector vecEntries; struct smbc_dirent* dirEnt; lock.Enter(); while ((dirEnt = smbc_readdir(fd))) { CachedDirEntry aDir; aDir.type = dirEnt->smbc_type; aDir.name = dirEnt->name; vecEntries.push_back(aDir); } smbc_closedir(fd); lock.Leave(); for (size_t i=0; i