summaryrefslogtreecommitdiffstats
path: root/mmc_updater/src/FileUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mmc_updater/src/FileUtils.cpp')
-rw-r--r--mmc_updater/src/FileUtils.cpp517
1 files changed, 0 insertions, 517 deletions
diff --git a/mmc_updater/src/FileUtils.cpp b/mmc_updater/src/FileUtils.cpp
deleted file mode 100644
index 712c0c5d..00000000
--- a/mmc_updater/src/FileUtils.cpp
+++ /dev/null
@@ -1,517 +0,0 @@
-#include "FileUtils.h"
-
-#include "DirIterator.h"
-#include "Log.h"
-#include "Platform.h"
-#include "StringUtils.h"
-
-#include <algorithm>
-#include <assert.h>
-#include <string.h>
-#include <fstream>
-#include <iostream>
-// this actually works with mingw32, which we use.
-#include <libgen.h>
-
-#ifdef PLATFORM_UNIX
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <errno.h>
-#endif
-
-FileUtils::IOException::IOException(const std::string& error)
-{
- init(errno,error);
-}
-
-FileUtils::IOException::IOException(int errorCode, const std::string& error)
-{
- init(errorCode,error);
-}
-
-void FileUtils::IOException::init(int errorCode, const std::string& error)
-{
- m_error = error;
-
-#ifdef PLATFORM_UNIX
- m_errorCode = errorCode;
-
- if (m_errorCode > 0)
- {
- m_error += " details: " + std::string(strerror(m_errorCode));
- }
-#endif
-
-#ifdef PLATFORM_WINDOWS
- m_errorCode = 0;
- m_error += " GetLastError returned: " + intToStr(GetLastError());
-#endif
-}
-
-FileUtils::IOException::~IOException() throw ()
-{
-}
-
-FileUtils::IOException::Type FileUtils::IOException::type() const
-{
-#ifdef PLATFORM_UNIX
- switch (m_errorCode)
- {
- case 0:
- return NoError;
- case EROFS:
- return ReadOnlyFileSystem;
- case ENOSPC:
- return DiskFull;
- default:
- return Unknown;
- }
-#else
- return Unknown;
-#endif
-}
-
-bool FileUtils::fileExists(const char* path) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- struct stat fileInfo;
- if (lstat(path,&fileInfo) != 0)
- {
- if (errno == ENOENT)
- {
- return false;
- }
- else
- {
- throw IOException("Error checking for file " + std::string(path));
- }
- }
- return true;
-#else
- DWORD result = GetFileAttributes(path);
- if (result == INVALID_FILE_ATTRIBUTES)
- {
- return false;
- }
- return true;
-#endif
-}
-
-int FileUtils::fileMode(const char* path) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- struct stat fileInfo;
- if (stat(path,&fileInfo) != 0)
- {
- throw IOException("Error reading file permissions for " + std::string(path));
- }
- return fileInfo.st_mode;
-#else
- // not implemented for Windows
- return 0;
-#endif
-}
-
-void FileUtils::chmod(const char* path, int mode) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (::chmod(path,static_cast<mode_t>(mode)) != 0)
- {
- throw IOException("Failed to set permissions on " + std::string(path) + " to " + intToStr(mode));
- }
-#else
- // TODO - Not implemented under Windows - all files
- // get default permissions
-#endif
-}
-
-void FileUtils::moveFile(const char* src, const char* dest) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (rename(src,dest) != 0)
- {
- throw IOException("Unable to rename " + std::string(src) + " to " + std::string(dest));
- }
-#else
- if (!MoveFile(src,dest))
- {
- throw IOException("Unable to rename " + std::string(src) + " to " + std::string(dest));
- }
-#endif
-}
-
-void FileUtils::mkpath(const char* dir) throw (IOException)
-{
- std::string currentPath;
- std::istringstream stream(dir);
- while (!stream.eof())
- {
- std::string segment;
- std::getline(stream,segment,'/');
- currentPath += segment;
- if (!currentPath.empty() && !fileExists(currentPath.c_str()))
- {
- mkdir(currentPath.c_str());
- }
- currentPath += '/';
- }
-}
-
-void FileUtils::mkdir(const char* dir) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (::mkdir(dir,S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0)
- {
- throw IOException("Unable to create directory " + std::string(dir));
- }
-#else
- if (!CreateDirectory(dir,0 /* default security attributes */))
- {
- throw IOException("Unable to create directory " + std::string(dir));
- }
-#endif
-}
-
-void FileUtils::rmdir(const char* dir) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (::rmdir(dir) != 0)
- {
- throw IOException("Unable to remove directory " + std::string(dir));
- }
-#else
- if (!RemoveDirectory(dir))
- {
- throw IOException("Unable to remove directory " + std::string(dir));
- }
-#endif
-}
-
-void FileUtils::createSymLink(const char* link, const char* target) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (symlink(target,link) != 0)
- {
- throw IOException("Unable to create symlink " + std::string(link) + " to " + std::string(target));
- }
-#else
- // symlinks are not supported under Windows (at least, not universally.
- // Windows Vista and later do actually support symlinks)
- LOG(Warn,"Skipping symlink creation - not implemented in Windows");
-#endif
-}
-
-void FileUtils::removeFile(const char* src) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (unlink(src) != 0)
- {
- if (errno != ENOENT)
- {
- throw IOException("Unable to remove file " + std::string(src));
- }
- }
-#else
- if (!DeleteFile(src))
- {
- if (GetLastError() == ERROR_ACCESS_DENIED)
- {
- // if another process is using the file, try moving it to
- // a temporary directory and then
- // scheduling it for deletion on reboot
- std::string tempDeletePathBase = tempPath();
- tempDeletePathBase += '/';
- tempDeletePathBase += fileName(src);
-
- int suffix = 0;
- std::string tempDeletePath = tempDeletePathBase;
- while (fileExists(tempDeletePath.c_str()))
- {
- ++suffix;
- tempDeletePath = tempDeletePathBase + '_' + intToStr(suffix);
- }
-
- LOG(Warn,"Unable to remove file " + std::string(src) + " - it may be in use. Moving to "
- + tempDeletePath + " and scheduling delete on reboot.");
- moveFile(src,tempDeletePath.c_str());
- MoveFileEx(tempDeletePath.c_str(),0,MOVEFILE_DELAY_UNTIL_REBOOT);
- }
- else if (GetLastError() != ERROR_FILE_NOT_FOUND)
- {
- throw IOException("Unable to remove file " + std::string(src));
- }
- }
-#endif
-}
-
-std::string FileUtils::fileName(const char* path)
-{
- char* pathCopy = strdup(path);
- std::string basename = ::basename(pathCopy);
- free(pathCopy);
- return basename;
-}
-
-std::string FileUtils::dirname(const char* path)
-{
- char* pathCopy = strdup(path);
- std::string dirname = ::dirname(pathCopy);
- free(pathCopy);
- return dirname;
-}
-
-void FileUtils::touch(const char* path) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- // see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html
- //
- // we use utimes/futimes instead of utimensat/futimens for compatibility
- // with older Linux and Mac
-
- if (fileExists(path))
- {
- utimes(path,0 /* use current date/time */);
- }
- else
- {
- int fd = creat(path,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
- if (fd != -1)
- {
- futimes(fd,0 /* use current date/time */);
- close(fd);
- }
- else
- {
- throw IOException("Unable to touch file " + std::string(path));
- }
- }
-#else
- HANDLE result = CreateFile(path,GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- 0,
- CREATE_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- if (result == INVALID_HANDLE_VALUE)
- {
- throw IOException("Unable to touch file " + std::string(path));
- }
- else
- {
- CloseHandle(result);
- }
-#endif
-}
-
-void FileUtils::rmdirRecursive(const char* path) throw (IOException)
-{
- // remove dir contents
- DirIterator dir(path);
- while (dir.next())
- {
- std::string name = dir.fileName();
- if (name != "." && name != "..")
- {
- if (dir.isDir())
- {
- rmdir(dir.filePath().c_str());
- }
- else
- {
- removeFile(dir.filePath().c_str());
- }
- }
- }
-
- // remove the directory itself
- rmdir(path);
-}
-
-std::string FileUtils::canonicalPath(const char* path)
-{
-#ifdef PLATFORM_UNIX
- // on Linux and Mac OS 10.6, realpath() can allocate the required
- // amount of memory automatically, however Mac OS 10.5 does not support
- // this, so we used a fixed-sized buffer on all platforms
- char canonicalPathBuffer[PATH_MAX+1];
- if (realpath(path,canonicalPathBuffer) != 0)
- {
- return std::string(canonicalPathBuffer);
- }
- else
- {
- throw IOException("Error reading canonical path for " + std::string(path));
- }
-#else
- throw IOException("canonicalPath() not implemented");
-#endif
-}
-
-std::string FileUtils::toWindowsPathSeparators(const std::string& str)
-{
- std::string result = str;
- std::replace(result.begin(),result.end(),'/','\\');
- return result;
-}
-
-std::string FileUtils::toUnixPathSeparators(const std::string& str)
-{
- std::string result = str;
- std::replace(result.begin(),result.end(),'\\','/');
- return result;
-}
-
-std::string FileUtils::tempPath()
-{
-#ifdef PLATFORM_UNIX
- std::string tmpDir(notNullString(getenv("TMPDIR")));
- if (tmpDir.empty())
- {
- tmpDir = "/tmp";
- }
- return tmpDir;
-#else
- char buffer[MAX_PATH+1];
- GetTempPath(MAX_PATH+1,buffer);
- return toUnixPathSeparators(buffer);
-#endif
-}
-
-bool startsWithDriveLetter(const char* path)
-{
- return strlen(path) >= 2 &&
- (isalpha(path[0])) &&
- path[1] == ':';
-}
-
-bool FileUtils::isRelative(const char* path)
-{
-#ifdef PLATFORM_UNIX
- return strlen(path) == 0 || path[0] != '/';
-#else
- // on Windows, a path is relative if it does not start with:
- // - '\\' (a UNC name)
- // - '[Drive Letter]:\'
- // - A single backslash
- //
- // the input path is assumed to have already been converted to use
- // Unix-style path separators
-
- std::string pathStr(path);
-
- if ((!pathStr.empty() && pathStr.at(0) == '/') ||
- (startsWith(pathStr,"//")) ||
- (startsWithDriveLetter(pathStr.c_str())))
- {
- return false;
- }
- else
- {
- return true;
- }
-#endif
-}
-
-void FileUtils::writeFile(const char* path, const char* data, int length) throw (IOException)
-{
- std::ofstream stream(path,std::ios::binary | std::ios::trunc);
- stream.write(data,length);
-}
-
-std::string FileUtils::readFile(const char* path) throw (IOException)
-{
- std::ifstream inputFile(path, std::ios::in | std::ios::binary);
- std::string content;
- inputFile.seekg(0, std::ios::end);
- content.resize(static_cast<unsigned int>(inputFile.tellg()));
- inputFile.seekg(0, std::ios::beg);
- inputFile.read(&content[0], static_cast<int>(content.size()));
- return content;
-}
-
-void FileUtils::copyFile(const char* src, const char* dest) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- std::ifstream inputFile(src,std::ios::binary);
- std::ofstream outputFile(dest,std::ios::binary | std::ios::trunc);
-
- if (!inputFile.good())
- {
- throw IOException("Failed to read file " + std::string(src));
- }
- if (!outputFile.good())
- {
- throw IOException("Failed to write file " + std::string(dest));
- }
-
- outputFile << inputFile.rdbuf();
-
- if (inputFile.bad())
- {
- throw IOException("Error reading file " + std::string(src));
- }
- if (outputFile.bad())
- {
- throw IOException("Error writing file " + std::string(dest));
- }
-
- chmod(dest,fileMode(src));
-#else
- if (!CopyFile(src,dest,FALSE))
- {
- throw IOException("Failed to copy " + std::string(src) + " to " + std::string(dest));
- }
-#endif
-}
-
-std::string FileUtils::makeAbsolute(const char* path, const char* basePath)
-{
- if (isRelative(path))
- {
- assert(!isRelative(basePath));
- return std::string(basePath) + '/' + std::string(path);
- }
- else
- {
- return path;
- }
-}
-
-void FileUtils::chdir(const char* path) throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- if (::chdir(path) != 0)
- {
- throw FileUtils::IOException("Unable to change directory");
- }
-#else
- if (!SetCurrentDirectory(path))
- {
- throw FileUtils::IOException("Unable to change directory");
- }
-#endif
-}
-
-std::string FileUtils::getcwd() throw (IOException)
-{
-#ifdef PLATFORM_UNIX
- char path[PATH_MAX];
- if (!::getcwd(path,PATH_MAX))
- {
- throw FileUtils::IOException("Failed to get current directory");
- }
- return std::string(path);
-#else
- char path[MAX_PATH];
- if (GetCurrentDirectory(MAX_PATH,path) == 0)
- {
- throw FileUtils::IOException("Failed to get current directory");
- }
- return toUnixPathSeparators(std::string(path));
-#endif
-}
-