From a7cc09981b667283e86d7ed73aee3a4732e10ae7 Mon Sep 17 00:00:00 2001 From: Michael Liebmann Date: Sun, 21 Oct 2012 17:50:04 +0200 Subject: [PATCH] Add file/directory functions to src/system/helpers.cpp - Required for 'update with settings' Origin commit data ------------------ Commit: https://github.com/neutrino-images/ni-neutrino/commit/690786c37c1e21cfd15f31b786484899be50656f Author: Michael Liebmann Date: 2012-10-21 (Sun, 21 Oct 2012) Origin message was: ------------------ * Add file/directory functions to src/system/helpers.cpp - Required for 'update with settings' --- src/system/helpers.cpp | 229 +++++++++++++++++++++++++++++++++++++++++ src/system/helpers.h | 22 ++++ 2 files changed, 251 insertions(+) diff --git a/src/system/helpers.cpp b/src/system/helpers.cpp index a564982e6..df2d2e880 100644 --- a/src/system/helpers.cpp +++ b/src/system/helpers.cpp @@ -33,6 +33,7 @@ #include /* or */ #include #include +#include #include #include @@ -235,3 +236,231 @@ bool get_mem_usage(unsigned long &kbtotal, unsigned long &kbfree) printf("mem: total %ld cached %ld free %ld\n", kbtotal, cached, kbfree); return true; } + +std::string trim(std::string &str, const std::string &trimChars /*= " \n\r\t"*/) +{ + std::string result = str.erase(str.find_last_not_of(trimChars) + 1); + return result.erase(0, result.find_first_not_of(trimChars)); +} + +CFileHelpers::CFileHelpers() +{ + FileBufSize = 0xFFFF; + FileBuf = (char*)malloc(FileBufSize); + doCopyFlag = true; +} + +CFileHelpers::~CFileHelpers() +{ + if (FileBuf != NULL) + free(FileBuf); +} + +CFileHelpers* CFileHelpers::getInstance() +{ + static CFileHelpers* FileHelpers = NULL; + if(!FileHelpers) + FileHelpers = new CFileHelpers(); + return FileHelpers; +} + +bool CFileHelpers::copyFile(const char *Src, const char *Dst, mode_t mode) +{ + doCopyFlag = true; + unlink(Dst); + if ((fd1 = open(Src, O_RDONLY)) < 0) + return false; + if ((fd2 = open(Dst, O_WRONLY | O_CREAT)) < 0) { + close(fd2); + return false; + } + + long block; + off64_t fsizeSrc64 = lseek64(fd1, 0, SEEK_END); + lseek64(fd1, 0, SEEK_SET); + if (fsizeSrc64 > 0x7FFFFFF0) { // > 2GB + off64_t fsize64 = fsizeSrc64; + block = FileBufSize; + //printf("#####[%s] fsizeSrc64: %lld 0x%010llX - large file\n", __FUNCTION__, fsizeSrc64, fsizeSrc64); + while(fsize64 > 0) { + if(fsize64 < (off64_t)FileBufSize) + block = (long)fsize64; + read(fd1, FileBuf, block); + write(fd2, FileBuf, block); + fsize64 -= block; + if (!doCopyFlag) + break; + } + if (doCopyFlag) { + lseek64(fd2, 0, SEEK_SET); + off64_t fsizeDst64 = lseek64(fd2, 0, SEEK_END); + if (fsizeSrc64 != fsizeDst64) + return false; + } + } + else { // < 2GB + long fsizeSrc = lseek(fd1, 0, SEEK_END); + lseek(fd1, 0, SEEK_SET); + long fsize = fsizeSrc; + block = FileBufSize; + //printf("#####[%s] fsizeSrc: %ld 0x%08lX - normal file\n", __FUNCTION__, fsizeSrc, fsizeSrc); + while(fsize > 0) { + if(fsize < (long)FileBufSize) + block = fsize; + read(fd1, FileBuf, block); + write(fd2, FileBuf, block); + fsize -= block; + if (!doCopyFlag) + break; + } + if (doCopyFlag) { + lseek(fd2, 0, SEEK_SET); + long fsizeDst = lseek(fd2, 0, SEEK_END); + if (fsizeSrc != fsizeDst) + return false; + } + } + close(fd1); + close(fd2); + + if (!doCopyFlag) { + sync(); + unlink(Dst); + return false; + } + + chmod(Dst, mode); + return true; +} + +bool CFileHelpers::copyDir(const char *Src, const char *Dst) +{ + DIR *Directory; + struct dirent *CurrentFile; + static struct stat FileInfo; + char srcPath[PATH_MAX]; + char dstPath[PATH_MAX]; + char buf[PATH_MAX]; + + //open directory + if ((Directory = opendir(Src)) == NULL) + return false; + if (lstat(Src, &FileInfo) == -1) { + closedir(Directory); + return false; + } + // create directory + // is symlink + if (S_ISLNK(FileInfo.st_mode)) { + int len = readlink(Src, buf, sizeof(buf)-1); + if (len != -1) { + buf[len] = '\0'; + symlink(buf, Dst); + } + } + else { + // directory + if (createDir(Dst, FileInfo.st_mode & 0x0FFF) == false) { + if (errno != EEXIST) { + closedir(Directory); + return false; + } + } + } + + // read directory + while ((CurrentFile = readdir(Directory)) != NULL) { + // ignore '.' and '..' + if (strcmp(CurrentFile->d_name, ".") && strcmp(CurrentFile->d_name, "..")) { + strcpy(srcPath, Src); + strcat(srcPath, "/"); + strcat(srcPath, CurrentFile->d_name); + if (lstat(srcPath, &FileInfo) == -1) { + closedir(Directory); + return false; + } + strcpy(dstPath, Dst); + strcat(dstPath, "/"); + strcat(dstPath, CurrentFile->d_name); + // is symlink + if (S_ISLNK(FileInfo.st_mode)) { + int len = readlink(srcPath, buf, sizeof(buf)-1); + if (len != -1) { + buf[len] = '\0'; + symlink(buf, dstPath); + } + } + // is directory + else if (S_ISDIR(FileInfo.st_mode)) { + copyDir(srcPath, dstPath); + } + // is file + else if (S_ISREG(FileInfo.st_mode)) { + copyFile(srcPath, dstPath, FileInfo.st_mode & 0x0FFF); + } + } + } + closedir(Directory); + return true; +} + +bool CFileHelpers::createDir(const char *Dir, mode_t mode) +{ + char dirPath[PATH_MAX]; + DIR *dir; + if ((dir = opendir(Dir)) != NULL) { + closedir(dir); + errno = EEXIST; + return false; + } + + int ret = -1; + while (ret == -1) { + strcpy(dirPath, Dir); + ret = mkdir(dirPath, mode); + if ((errno == ENOENT) && (ret == -1)) { + char * pos = strrchr(dirPath,'/'); + if (pos != NULL) { + pos[0] = '\0'; + createDir(dirPath, mode); + } + } + else { + if (ret == 0) + return true; + if (errno == EEXIST) + return true; + else + return false; + } + } + errno = 0; + return true; +} + +bool CFileHelpers::removeDir(const char *Dir) +{ + DIR *dir; + struct dirent *entry; + char path[PATH_MAX]; + + dir = opendir(Dir); + if (dir == NULL) { + printf("Error opendir()\n"); + return false; + } + while ((entry = readdir(dir)) != NULL) { + if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { + snprintf(path, (size_t) PATH_MAX, "%s/%s", Dir, entry->d_name); + if (entry->d_type == DT_DIR) + removeDir(path); + else + unlink(path); + } + } + closedir(dir); + rmdir(Dir); + + errno = 0; + return true; +} diff --git a/src/system/helpers.h b/src/system/helpers.h index c14938527..b3393a0d3 100644 --- a/src/system/helpers.h +++ b/src/system/helpers.h @@ -34,4 +34,26 @@ int check_dir(const char * dir); bool get_fs_usage(const char * dir, long &total, long &used); bool get_mem_usage(unsigned long &total, unsigned long &free); +std::string trim(std::string &str, const std::string &trimChars = " \n\r\t"); + +class CFileHelpers +{ + private: + int FileBufSize; + char *FileBuf; + int fd1, fd2; + + public: + CFileHelpers(); + ~CFileHelpers(); + static CFileHelpers* getInstance(); + bool doCopyFlag; + + bool copyFile(const char *Src, const char *Dst, mode_t mode); + bool copyDir(const char *Src, const char *Dst); + bool createDir(const char *Dir, mode_t mode); + bool removeDir(const char *Dir); + +}; + #endif