15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004--2006, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/unixfilesystem.h" 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <errno.h> 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <fcntl.h> 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <stdlib.h> 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sys/stat.h> 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <unistd.h> 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef OSX 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <Carbon/Carbon.h> 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <IOKit/IOCFBundle.h> 395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sys/statvfs.h> 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/macutils.h" 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // OSX 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(POSIX) && !defined(OSX) 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sys/types.h> 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef ANDROID 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sys/statfs.h> 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sys/statvfs.h> 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // ANDROID 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <pwd.h> 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <stdio.h> 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <unistd.h> 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // POSIX && !OSX 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef LINUX 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <ctype.h> 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <algorithm> 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/fileutils.h" 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/pathutils.h" 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/stream.h" 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/stringutils.h" 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace talk_base { 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if !defined(ANDROID) && !defined(IOS) 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgchar* UnixFilesystem::app_temp_path_ = NULL; 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgchar* UnixFilesystem::provided_app_data_folder_ = NULL; 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgchar* UnixFilesystem::provided_app_temp_folder_ = NULL; 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid UnixFilesystem::SetAppDataFolder(const std::string& folder) { 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete [] provided_app_data_folder_; 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org provided_app_data_folder_ = CopyString(folder); 765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid UnixFilesystem::SetAppTempFolder(const std::string& folder) { 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete [] provided_app_temp_folder_; 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org provided_app_temp_folder_ = CopyString(folder); 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::CreateFolder(const Pathname &path, mode_t mode) { 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string pathname(path.pathname()); 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int len = pathname.length(); 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((len == 0) || (pathname[len - 1] != '/')) 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct stat st; 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int res = ::stat(pathname.c_str(), &st); 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (res == 0) { 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Something exists at this location, check if it is a directory 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return S_ISDIR(st.st_mode) != 0; 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (errno != ENOENT) { 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Unexpected error 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Directory doesn't exist, look up one directory level 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org do { 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org --len; 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } while ((len > 0) && (pathname[len - 1] != '/')); 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!CreateFolder(Pathname(pathname.substr(0, len)), mode)) { 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "Creating folder: " << pathname; 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return (0 == ::mkdir(pathname.c_str(), mode)); 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::CreateFolder(const Pathname &path) { 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return CreateFolder(path, 0755); 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgFileStream *UnixFilesystem::OpenFile(const Pathname &filename, 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string &mode) { 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org FileStream *fs = new FileStream(); 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (fs && !fs->Open(filename.pathname().c_str(), mode.c_str(), NULL)) { 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete fs; 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org fs = NULL; 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return fs; 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::CreatePrivateFile(const Pathname &filename) { 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int fd = open(filename.pathname().c_str(), 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org O_RDWR | O_CREAT | O_EXCL, 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org S_IRUSR | S_IWUSR); 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (fd < 0) { 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERR(LS_ERROR) << "open() failed."; 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Don't need to keep the file descriptor. 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (close(fd) < 0) { 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERR(LS_ERROR) << "close() failed."; 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Continue. 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::DeleteFile(const Pathname &filename) { 1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "Deleting file:" << filename.pathname(); 1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!IsFile(filename)) { 1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(IsFile(filename)); 1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ::unlink(filename.pathname().c_str()) == 0; 1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::DeleteEmptyFolder(const Pathname &folder) { 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "Deleting folder" << folder.pathname(); 1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!IsFolder(folder)) { 1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(IsFolder(folder)); 1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string no_slash(folder.pathname(), 0, folder.pathname().length()-1); 1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ::rmdir(no_slash.c_str()) == 0; 1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetTemporaryFolder(Pathname &pathname, bool create, 1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string *append) { 1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef OSX 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org FSRef fr; 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org kCreateFolder, &fr)) 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org unsigned char buffer[NAME_MAX+1]; 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != FSRefMakePath(&fr, buffer, ARRAY_SIZE(buffer))) 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.SetPathname(reinterpret_cast<char*>(buffer), ""); 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#elif defined(ANDROID) || defined(IOS) 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(provided_app_temp_folder_ != NULL); 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.SetPathname(provided_app_temp_folder_, ""); 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else // !OSX && !ANDROID 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (const char* tmpdir = getenv("TMPDIR")) { 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.SetPathname(tmpdir, ""); 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (const char* tmp = getenv("TMP")) { 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.SetPathname(tmp, ""); 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef P_tmpdir 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.SetPathname(P_tmpdir, ""); 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else // !P_tmpdir 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.SetPathname("/tmp/", ""); 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // !P_tmpdir 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // !OSX && !ANDROID 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (append) { 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(!append->empty()); 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org pathname.AppendFolder(*append); 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return !create || CreateFolder(pathname); 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string UnixFilesystem::TempFilename(const Pathname &dir, 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string &prefix) { 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int len = dir.pathname().size() + prefix.size() + 2 + 6; 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char *tempname = new char[len]; 2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org snprintf(tempname, len, "%s/%sXXXXXX", dir.pathname().c_str(), 2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org prefix.c_str()); 2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int fd = ::mkstemp(tempname); 2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (fd != -1) 2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ::close(fd); 2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string ret(tempname); 2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete[] tempname; 2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ret; 2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::MoveFile(const Pathname &old_path, 2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const Pathname &new_path) { 2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!IsFile(old_path)) { 2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(IsFile(old_path)); 2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_VERBOSE) << "Moving " << old_path.pathname() 2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << " to " << new_path.pathname(); 2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) { 2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (errno != EXDEV) 2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!CopyFile(old_path, new_path)) 2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!DeleteFile(old_path)) 2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::MoveFolder(const Pathname &old_path, 2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const Pathname &new_path) { 2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!IsFolder(old_path)) { 2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(IsFolder(old_path)); 2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_VERBOSE) << "Moving " << old_path.pathname() 2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << " to " << new_path.pathname(); 2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (rename(old_path.pathname().c_str(), new_path.pathname().c_str()) != 0) { 2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (errno != EXDEV) 2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!CopyFolder(old_path, new_path)) 2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!DeleteFolderAndContents(old_path)) 2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::IsFolder(const Pathname &path) { 2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct stat st; 2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (stat(path.pathname().c_str(), &st) < 0) 2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return S_ISDIR(st.st_mode); 2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::CopyFile(const Pathname &old_path, 2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const Pathname &new_path) { 2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_VERBOSE) << "Copying " << old_path.pathname() 2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << " to " << new_path.pathname(); 2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buf[256]; 2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t len; 2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StreamInterface *source = OpenFile(old_path, "rb"); 2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!source) 2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StreamInterface *dest = OpenFile(new_path, "wb"); 2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!dest) { 2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete source; 2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (source->Read(buf, sizeof(buf), &len, NULL) == SR_SUCCESS) 2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dest->Write(buf, len, NULL, NULL); 2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete source; 2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete dest; 2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::IsTemporaryPath(const Pathname& pathname) { 2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(ANDROID) || defined(IOS) 2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(provided_app_temp_folder_ != NULL); 2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* const kTempPrefixes[] = { 2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(ANDROID) || defined(IOS) 2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org provided_app_temp_folder_, 2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "/tmp/", "/var/tmp/", 2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef OSX 2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "/private/tmp/", "/private/var/tmp/", "/private/var/folders/", 2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // OSX 2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // ANDROID || IOS 2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org }; 2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < ARRAY_SIZE(kTempPrefixes); ++i) { 3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 == strncmp(pathname.pathname().c_str(), kTempPrefixes[i], 3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org strlen(kTempPrefixes[i]))) 3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::IsFile(const Pathname& pathname) { 3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct stat st; 3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int res = ::stat(pathname.pathname().c_str(), &st); 3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Treat symlinks, named pipes, etc. all as files. 3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return res == 0 && !S_ISDIR(st.st_mode); 3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::IsAbsent(const Pathname& pathname) { 3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct stat st; 3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int res = ::stat(pathname.pathname().c_str(), &st); 3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Note: we specifically maintain ENOTDIR as an error, because that implies 3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // that you could not call CreateFolder(pathname). 3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return res != 0 && ENOENT == errno; 3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetFileSize(const Pathname& pathname, size_t *size) { 3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct stat st; 3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (::stat(pathname.pathname().c_str(), &st) != 0) 3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *size = st.st_size; 3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetFileTime(const Pathname& path, FileTimeType which, 3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org time_t* time) { 3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct stat st; 3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (::stat(path.pathname().c_str(), &st) != 0) 3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (which) { 3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FTT_CREATED: 3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *time = st.st_ctime; 3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FTT_MODIFIED: 3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *time = st.st_mtime; 3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case FTT_ACCESSED: 3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *time = st.st_atime; 3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org default: 3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetAppPathname(Pathname* path) { 3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef OSX 3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ProcessSerialNumber psn = { 0, kCurrentProcess }; 3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CFDictionaryRef procinfo = ProcessInformationCopyDictionary(&psn, 3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org kProcessDictionaryIncludeAllInformationMask); 3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (NULL == procinfo) 3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CFStringRef cfpath = (CFStringRef) CFDictionaryGetValue(procinfo, 3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org kIOBundleExecutableKey); 3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string path8; 3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool success = ToUtf8(cfpath, &path8); 3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CFRelease(procinfo); 3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (success) 3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(path8); 3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return success; 3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else // OSX 3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buffer[NAME_MAX+1]; 3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t len = readlink("/proc/self/exe", buffer, ARRAY_SIZE(buffer) - 1); 3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (len <= 0) 3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org buffer[len] = '\0'; 3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(buffer); 3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // OSX 3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetAppDataFolder(Pathname* path, bool per_user) { 3785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(!organization_name_.empty()); 3795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(!application_name_.empty()); 3805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // First get the base directory for app data. 3825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef OSX 3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (per_user) { 3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Use ~/Library/Application Support/<orgname>/<appname>/ 3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org FSRef fr; 3865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType, 3875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org kCreateFolder, &fr)) 3885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org unsigned char buffer[NAME_MAX+1]; 3905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != FSRefMakePath(&fr, buffer, ARRAY_SIZE(buffer))) 3915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(reinterpret_cast<char*>(buffer), ""); 3935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 3945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO 3955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 3965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#elif defined(ANDROID) || defined(IOS) // && !OSX 3985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(provided_app_data_folder_ != NULL); 3995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(provided_app_data_folder_, ""); 4005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#elif defined(LINUX) // && !OSX && !defined(ANDROID) && !defined(IOS) 4015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (per_user) { 4025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // We follow the recommendations in 4035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html 4045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // It specifies separate directories for data and config files, but 4055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // GetAppDataFolder() does not distinguish. We just return the config dir 4065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // path. 4075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* xdg_config_home = getenv("XDG_CONFIG_HOME"); 4085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (xdg_config_home) { 4095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(xdg_config_home, ""); 4105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 4115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // XDG says to default to $HOME/.config. We also support falling back to 4125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // other synonyms for HOME if for some reason it is not defined. 4135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const char* homedir; 4145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (const char* home = getenv("HOME")) { 4155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org homedir = home; 4165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (const char* dotdir = getenv("DOTDIR")) { 4175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org homedir = dotdir; 4185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (passwd* pw = getpwuid(geteuid())) { 4195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org homedir = pw->pw_dir; 4205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 4215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 4225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(homedir, ""); 4245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->AppendFolder(".config"); 4255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 4275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // XDG does not define a standard directory for writable global data. Let's 4285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // just use this. 4295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname("/var/cache/", ""); 4305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // !OSX && !defined(ANDROID) && !defined(LINUX) 4325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Now add on a sub-path for our app. 4345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(OSX) || defined(ANDROID) || defined(IOS) 4355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->AppendFolder(organization_name_); 4365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->AppendFolder(application_name_); 4375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#elif defined(LINUX) 4385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // XDG says to use a single directory level, so we concatenate the org and app 4395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // name with a hyphen. We also do the Linuxy thing and convert to all 4405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // lowercase with no spaces. 4415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string subdir(organization_name_); 4425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org subdir.append("-"); 4435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org subdir.append(application_name_); 4445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org replace_substrs(" ", 1, "", 0, &subdir); 4455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::transform(subdir.begin(), subdir.end(), subdir.begin(), ::tolower); 4465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->AppendFolder(subdir); 4475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 4485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!CreateFolder(*path, 0700)) { 4495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 4505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If the folder already exists, it may have the wrong mode or be owned by 4525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // someone else, both of which are security problems. Setting the mode 4535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // avoids both issues since it will fail if the path is not owned by us. 4545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != ::chmod(path->pathname().c_str(), 0700)) { 4555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERR(LS_ERROR) << "Can't set mode on " << path; 4565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 4575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 4595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetAppTempFolder(Pathname* path) { 4625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(ANDROID) || defined(IOS) 4635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(provided_app_temp_folder_ != NULL); 4645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(provided_app_temp_folder_); 4655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 4665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 4675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(!application_name_.empty()); 4685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO: Consider whether we are worried about thread safety. 4695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (app_temp_path_ != NULL && strlen(app_temp_path_) > 0) { 4705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org path->SetPathname(app_temp_path_); 4715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 4725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Create a random directory as /tmp/<appname>-<pid>-<timestamp> 4755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buffer[128]; 4765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org sprintfn(buffer, ARRAY_SIZE(buffer), "-%d-%d", 4775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(getpid()), 4785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<int>(time(0))); 4795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string folder(application_name_); 4805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org folder.append(buffer); 4815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!GetTemporaryFolder(*path, true, &folder)) 4825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 4835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete [] app_temp_path_; 4855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org app_temp_path_ = CopyString(path->pathname()); 4865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO: atexit(DeleteFolderAndContents(app_temp_path_)); 4875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 4885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 4895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool UnixFilesystem::GetDiskFreeSpace(const Pathname& path, int64 *freebytes) { 4925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(NULL != freebytes); 4935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO: Consider making relative paths absolute using cwd. 4945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO: When popping off a symlink, push back on the components of the 4955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // symlink, so we don't jump out of the target disk inadvertently. 4965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Pathname existing_path(path.folder(), ""); 4975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org while (!existing_path.folder().empty() && IsAbsent(existing_path)) { 4985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org existing_path.SetFolder(existing_path.parent_folder()); 4995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#ifdef ANDROID 5015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct statfs vfs; 5025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org memset(&vfs, 0, sizeof(vfs)); 5035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != statfs(existing_path.pathname().c_str(), &vfs)) 5045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 5055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#else 5065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org struct statvfs vfs; 5075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org memset(&vfs, 0, sizeof(vfs)); 5085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (0 != statvfs(existing_path.pathname().c_str(), &vfs)) 5095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 5105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif // ANDROID 5115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#if defined(LINUX) || defined(ANDROID) 5125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *freebytes = static_cast<int64>(vfs.f_bsize) * vfs.f_bavail; 5135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#elif defined(OSX) 5145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *freebytes = static_cast<int64>(vfs.f_frsize) * vfs.f_bavail; 5155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#endif 5165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 5185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgPathname UnixFilesystem::GetCurrentDirectory() { 5215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Pathname cwd; 5225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char buffer[PATH_MAX]; 5235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char *path = getcwd(buffer, PATH_MAX); 5245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!path) { 5265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG_ERR(LS_ERROR) << "getcwd() failed"; 5275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return cwd; // returns empty pathname 5285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cwd.SetFolder(std::string(path)); 5305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return cwd; 5325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgchar* UnixFilesystem::CopyString(const std::string& str) { 5355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t size = str.length() + 1; 5365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org char* buf = new char[size]; 5385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!buf) { 5395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 5405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org strcpyn(buf, size, str.c_str()); 5435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return buf; 5445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} // namespace talk_base 547