2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
/*
|
|
|
|
* "$Id: rsdir.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $"
|
|
|
|
*
|
|
|
|
* RetroShare C++ Interface.
|
|
|
|
*
|
|
|
|
* Copyright 2004-2007 by Robert Fernie.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License Version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Includes for directory creation.
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "util/rsdir.h"
|
2010-06-04 19:39:33 -04:00
|
|
|
#include "pqi/pqinotify.h"
|
2010-08-06 05:40:23 -04:00
|
|
|
#include "retroshare/rstypes.h"
|
2011-03-03 18:30:08 -05:00
|
|
|
#include "rsthreads.h"
|
2007-11-14 22:18:48 -05:00
|
|
|
#include <string>
|
|
|
|
#include <iostream>
|
2008-05-30 06:36:47 -04:00
|
|
|
#include <algorithm>
|
2009-05-11 10:30:53 -04:00
|
|
|
#include <stdio.h>
|
2010-02-09 09:11:03 -05:00
|
|
|
#include <dirent.h>
|
2010-07-06 01:04:11 -04:00
|
|
|
#include <openssl/sha.h>
|
|
|
|
#include <iomanip>
|
|
|
|
#include <sstream>
|
2010-02-09 09:11:03 -05:00
|
|
|
|
2010-03-10 09:08:52 -05:00
|
|
|
#include <fstream>
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2009-03-29 09:58:28 -04:00
|
|
|
#if defined(WIN32) || defined(__CYGWIN__)
|
2010-05-16 19:26:45 -04:00
|
|
|
#include "util/rswin.h"
|
2009-03-29 09:58:28 -04:00
|
|
|
#include "wtypes.h"
|
|
|
|
#include <winioctl.h>
|
|
|
|
#else
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
|
|
|
|
2008-07-09 05:55:09 -04:00
|
|
|
/****
|
|
|
|
* #define RSDIR_DEBUG 1
|
|
|
|
****/
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
std::string RsDirUtil::getTopDir(const std::string& dir)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
std::string top;
|
|
|
|
|
|
|
|
/* find the subdir: [/][dir1.../]<top>[/]
|
|
|
|
*/
|
|
|
|
int i,j;
|
|
|
|
int len = dir.length();
|
2011-06-29 14:02:44 -04:00
|
|
|
for(j = len - 1; (j > 0) && (dir[j] == '/'); j--) ;
|
|
|
|
for(i = j; (i > 0) && (dir[i] != '/'); i--) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
if (dir[i] == '/')
|
|
|
|
i++;
|
|
|
|
|
|
|
|
for(; i <= j; i++)
|
|
|
|
{
|
|
|
|
top += dir[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return top;
|
|
|
|
}
|
|
|
|
|
2010-07-06 01:04:11 -04:00
|
|
|
class CRC32Table
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
inline uint32_t operator[](unsigned char i) const { return _data[i] ; }
|
|
|
|
|
|
|
|
CRC32Table()
|
|
|
|
{
|
|
|
|
_data = new uint32_t[256] ;
|
|
|
|
uint32_t polynmial = 0x04c11db7 ;
|
|
|
|
|
|
|
|
for(uint32_t i=0;i<256;++i)
|
|
|
|
{
|
|
|
|
uint32_t a = reflect(i,8)<<24 ;
|
|
|
|
|
|
|
|
for(uint32_t j=0;j<8;++j)
|
|
|
|
a = (a << 1)^ ( (a&(1<<31))?polynmial:0) ;
|
|
|
|
|
|
|
|
_data[i] = reflect(a,32) ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Swap bits 0-7, 1-6, etc.
|
|
|
|
//
|
|
|
|
uint32_t reflect(uint32_t ref,unsigned char ch)
|
|
|
|
{
|
|
|
|
uint32_t val = 0 ;
|
|
|
|
for(int i=1;i<ch+1;i++,ref>>=1)
|
|
|
|
if(ref & 1)
|
|
|
|
val |= (1 << (ch-i)) ;
|
|
|
|
return val ;
|
|
|
|
}
|
|
|
|
~CRC32Table() { delete[] _data ; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
uint32_t *_data ;
|
|
|
|
};
|
|
|
|
|
2010-07-21 19:14:10 -04:00
|
|
|
static const CRC32Table crc32_table ;
|
|
|
|
|
|
|
|
uint32_t RsDirUtil::rs_CRC32(const unsigned char *data,uint32_t _len)
|
2010-07-06 01:04:11 -04:00
|
|
|
{
|
|
|
|
uint32_t a = 0xffffffff ;
|
2010-07-21 19:14:10 -04:00
|
|
|
int64_t len = _len ;
|
2010-07-06 01:04:11 -04:00
|
|
|
|
2010-09-30 17:44:31 -04:00
|
|
|
for(const unsigned char *buf=data;len>0;len--)
|
2010-07-06 01:04:11 -04:00
|
|
|
a = (a >> 8) ^ crc32_table[ (a & 0xff) ^ *buf++] ;
|
|
|
|
|
|
|
|
return a ^ 0xffffffff ;
|
|
|
|
}
|
|
|
|
|
2010-07-21 19:14:10 -04:00
|
|
|
bool RsDirUtil::crc32File(FILE *fd, uint64_t file_size,uint32_t chunk_size, CRC32Map& crc_map)
|
|
|
|
{
|
2011-02-24 17:19:04 -05:00
|
|
|
if(fseeko64(fd,0,SEEK_SET) != 0)
|
2010-07-21 19:14:10 -04:00
|
|
|
{
|
|
|
|
std::cerr << "crc32File(): cannot fseek to beginnign of the file !!" << std::endl ;
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
|
|
|
crc_map = CRC32Map(file_size,chunk_size) ;
|
|
|
|
|
|
|
|
unsigned char *buff = new unsigned char[chunk_size] ;
|
|
|
|
int len ;
|
|
|
|
uint64_t total_size = 0 ;
|
|
|
|
uint32_t nb_chunk = 0;
|
|
|
|
|
|
|
|
while((len = fread(buff,(size_t)1, (size_t)chunk_size, fd)) > 0)
|
|
|
|
{
|
|
|
|
crc_map.set(nb_chunk++,rs_CRC32(buff,len)) ;
|
|
|
|
total_size += len ;
|
|
|
|
}
|
|
|
|
delete[] buff ;
|
|
|
|
|
|
|
|
if(file_size != total_size)
|
|
|
|
{
|
|
|
|
std::cerr << "RsDirUtil::crc32File(): ERROR. The file size does not match the announced size." << std::endl ;
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
std::string RsDirUtil::removeTopDir(const std::string& dir)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
std::string rest;
|
|
|
|
|
|
|
|
/* remove the subdir: [/][dir1.../]<top>[/]
|
|
|
|
*/
|
|
|
|
int i,j;
|
|
|
|
int len = dir.length();
|
2011-06-29 14:02:44 -04:00
|
|
|
for(j = len - 1; (j > 0) && (dir[j] == '/'); j--) ;
|
|
|
|
for(i = j; (i >= 0) && (dir[i] != '/'); i--) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
/* remove any more slashes */
|
2011-06-29 14:02:44 -04:00
|
|
|
for(; (i >= 0) && (dir[i] == '/'); i--) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
for(j = 0; j <= i; j++)
|
|
|
|
{
|
|
|
|
rest += dir[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
return rest;
|
|
|
|
}
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
std::string RsDirUtil::getRootDir(const std::string& dir)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
std::string root;
|
|
|
|
|
|
|
|
/* find the subdir: [/]root[/...]
|
|
|
|
*/
|
|
|
|
int i,j;
|
|
|
|
int len = dir.length();
|
2011-06-29 14:02:44 -04:00
|
|
|
for(i = 0; (i < len) && (dir[i] == '/'); i++) ;
|
|
|
|
for(j = i; (j < len) && (dir[j] != '/'); j++) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
if (i == j)
|
|
|
|
return root; /* empty */
|
|
|
|
for(; i < j; i++)
|
|
|
|
{
|
|
|
|
root += dir[i];
|
|
|
|
}
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
std::string RsDirUtil::removeRootDir(const std::string& path)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
unsigned int i, j;
|
|
|
|
unsigned int len = path.length();
|
|
|
|
std::string output;
|
|
|
|
|
|
|
|
/* chew leading '/'s */
|
2011-06-29 14:02:44 -04:00
|
|
|
for(i = 0; (i < len) && (path[i] == '/'); i++) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
if (i == len)
|
|
|
|
return output; /* empty string */
|
|
|
|
|
2011-06-29 14:02:44 -04:00
|
|
|
for(j = i; (j < len) && (path[j] != '/'); j++) ; /* run to next '/' */
|
|
|
|
for(; (j < len) && (path[j] == '/'); j++) ; /* chew leading '/'s */
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
for(; j < len; j++)
|
|
|
|
{
|
|
|
|
output += path[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
std::string RsDirUtil::removeRootDirs(const std::string& path, const std::string& root)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
/* too tired */
|
|
|
|
std::string notroot;
|
|
|
|
|
|
|
|
unsigned int i = 0, j = 0;
|
|
|
|
|
|
|
|
/* catch empty data */
|
|
|
|
if ((root.length() < 1) || (path.length() < 1))
|
|
|
|
return notroot;
|
|
|
|
|
|
|
|
if ((path[0] == '/') && (root[0] != '/'))
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2011-06-29 14:02:44 -04:00
|
|
|
for(; (i < path.length()) && (j < root.length()) && (path[i] == root[j]); i++, j++) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
/* should have consumed root. */
|
|
|
|
if (j == root.length())
|
|
|
|
{
|
|
|
|
//std::cerr << "matched root!" << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//std::cerr << "failed i: " << i << ", j: " << j << std::endl;
|
|
|
|
//std::cerr << "root: " << root << " path: " << path << std::endl;
|
|
|
|
return notroot;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path[i] == '/')
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(; i < path.length(); i++)
|
|
|
|
{
|
|
|
|
notroot += path[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
//std::cerr << "Found NotRoot: " << notroot << std::endl;
|
|
|
|
|
|
|
|
return notroot;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
int RsDirUtil::breakupDirList(const std::string& path,
|
2007-11-14 22:18:48 -05:00
|
|
|
std::list<std::string> &subdirs)
|
|
|
|
{
|
|
|
|
int start = 0;
|
|
|
|
unsigned int i;
|
|
|
|
for(i = 0; i < path.length(); i++)
|
|
|
|
{
|
|
|
|
if (path[i] == '/')
|
|
|
|
{
|
|
|
|
if (i - start > 0)
|
|
|
|
{
|
|
|
|
subdirs.push_back(path.substr(start, i-start));
|
|
|
|
}
|
|
|
|
start = i+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// get the final one.
|
|
|
|
if (i - start > 0)
|
|
|
|
{
|
|
|
|
subdirs.push_back(path.substr(start, i-start));
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-28 18:59:46 -04:00
|
|
|
/**** Copied and Tweaked from ftcontroller ***/
|
|
|
|
bool RsDirUtil::copyFile(const std::string& source,const std::string& dest)
|
|
|
|
{
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring sourceW;
|
|
|
|
std::wstring destW;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(source,sourceW);
|
|
|
|
librs::util::ConvertUtf8ToUtf16(dest,destW);
|
|
|
|
|
|
|
|
return (CopyFileW(sourceW.c_str(), destW.c_str(), FALSE) != 0);
|
|
|
|
|
|
|
|
#else
|
2011-02-24 17:44:41 -05:00
|
|
|
FILE *in = fopen64(source.c_str(),"rb") ;
|
2010-10-28 18:59:46 -04:00
|
|
|
|
|
|
|
if(in == NULL)
|
|
|
|
{
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
2011-02-24 17:44:41 -05:00
|
|
|
FILE *out = fopen64(dest.c_str(),"wb") ;
|
2010-10-28 18:59:46 -04:00
|
|
|
|
|
|
|
if(out == NULL)
|
|
|
|
{
|
|
|
|
fclose (in);
|
|
|
|
return false ;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t s=0;
|
|
|
|
size_t T=0;
|
|
|
|
|
|
|
|
static const int BUFF_SIZE = 10485760 ; // 10 MB buffer to speed things up.
|
|
|
|
void *buffer = malloc(BUFF_SIZE) ;
|
|
|
|
|
|
|
|
bool bRet = true;
|
|
|
|
|
|
|
|
while( (s = fread(buffer,1,BUFF_SIZE,in)) > 0)
|
|
|
|
{
|
|
|
|
size_t t = fwrite(buffer,1,s,out) ;
|
|
|
|
T += t ;
|
|
|
|
|
|
|
|
if(t != s)
|
|
|
|
{
|
|
|
|
bRet = false ;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(in) ;
|
|
|
|
fclose(out) ;
|
|
|
|
|
|
|
|
free(buffer) ;
|
|
|
|
|
|
|
|
return true ;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool RsDirUtil::checkFile(const std::string& filename)
|
|
|
|
{
|
|
|
|
int val;
|
|
|
|
mode_t st_mode;
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring wfilename;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(filename, wfilename);
|
|
|
|
struct _stat buf;
|
|
|
|
val = _wstat(wfilename.c_str(), &buf);
|
|
|
|
st_mode = buf.st_mode;
|
|
|
|
#else
|
|
|
|
struct stat buf;
|
|
|
|
val = stat(filename.c_str(), &buf);
|
|
|
|
st_mode = buf.st_mode;
|
|
|
|
#endif
|
|
|
|
if (val == -1)
|
|
|
|
{
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "RsDirUtil::checkFile() ";
|
|
|
|
std::cerr << filename << " doesn't exist" << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (!S_ISREG(st_mode))
|
|
|
|
{
|
|
|
|
// Some other type - error.
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "RsDirUtil::checkFile() ";
|
|
|
|
std::cerr << filename << " is not a Regular File" << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
bool RsDirUtil::checkDirectory(const std::string& dir)
|
2008-07-23 18:01:59 -04:00
|
|
|
{
|
2010-09-17 14:27:30 -04:00
|
|
|
int val;
|
|
|
|
mode_t st_mode;
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring wdir;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(dir, wdir);
|
|
|
|
struct _stat buf;
|
|
|
|
val = _wstat(wdir.c_str(), &buf);
|
|
|
|
st_mode = buf.st_mode;
|
|
|
|
#else
|
2008-07-23 18:01:59 -04:00
|
|
|
struct stat buf;
|
2010-09-17 14:27:30 -04:00
|
|
|
val = stat(dir.c_str(), &buf);
|
|
|
|
st_mode = buf.st_mode;
|
|
|
|
#endif
|
2008-07-23 18:01:59 -04:00
|
|
|
if (val == -1)
|
|
|
|
{
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "RsDirUtil::checkDirectory() ";
|
|
|
|
std::cerr << dir << " doesn't exist" << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
2010-09-17 14:27:30 -04:00
|
|
|
else if (!S_ISDIR(st_mode))
|
2008-07-23 18:01:59 -04:00
|
|
|
{
|
|
|
|
// Some other type - error.
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "RsDirUtil::checkDirectory() ";
|
|
|
|
std::cerr << dir << " is not Directory" << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
bool RsDirUtil::checkCreateDirectory(const std::string& dir)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2010-02-09 09:11:03 -05:00
|
|
|
#ifdef RSDIR_DEBUG
|
2011-03-06 15:19:16 -05:00
|
|
|
std::cerr << "RsDirUtil::checkCreateDirectory() dir: " << dir << std::endl;
|
2010-02-09 09:11:03 -05:00
|
|
|
#endif
|
2011-03-06 15:19:16 -05:00
|
|
|
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring wdir;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(dir, wdir);
|
|
|
|
_WDIR *direc = _wopendir(wdir.c_str());
|
|
|
|
if (!direc)
|
|
|
|
#else
|
|
|
|
DIR *direc = opendir(dir.c_str());
|
|
|
|
if (!direc)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
// directory don't exist. create.
|
2007-11-14 22:18:48 -05:00
|
|
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
|
|
#ifndef WINDOWS_SYS // UNIX
|
2011-03-06 15:19:16 -05:00
|
|
|
if (-1 == mkdir(dir.c_str(), 0777))
|
2007-11-14 22:18:48 -05:00
|
|
|
#else // WIN
|
2011-03-06 15:19:16 -05:00
|
|
|
if (-1 == _wmkdir(wdir.c_str()))
|
2007-11-14 22:18:48 -05:00
|
|
|
#endif
|
|
|
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
|
|
|
2011-03-06 15:19:16 -05:00
|
|
|
{
|
2010-02-09 09:11:03 -05:00
|
|
|
#ifdef RSDIR_DEBUG
|
2011-03-06 15:19:16 -05:00
|
|
|
std::cerr << "check_create_directory() Fatal Error et oui--";
|
|
|
|
std::cerr <<std::endl<< "\tcannot create:" <<dir<<std::endl;
|
2008-07-09 05:55:09 -04:00
|
|
|
#endif
|
2011-03-06 15:19:16 -05:00
|
|
|
return 0;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2010-02-09 09:11:03 -05:00
|
|
|
#ifdef RSDIR_DEBUG
|
2011-03-06 15:19:16 -05:00
|
|
|
std::cerr << "check_create_directory()";
|
|
|
|
std::cerr <<std::endl<< "\tcreated:" <<dir<<std::endl;
|
2008-07-09 05:55:09 -04:00
|
|
|
#endif
|
2011-03-04 22:43:40 -05:00
|
|
|
|
|
|
|
return 1;
|
2011-03-06 15:19:16 -05:00
|
|
|
}
|
2010-02-09 09:11:03 -05:00
|
|
|
|
|
|
|
#ifdef RSDIR_DEBUG
|
2011-03-06 15:19:16 -05:00
|
|
|
std::cerr << "check_create_directory()";
|
|
|
|
std::cerr <<std::endl<< "\tDir Exists:" <<dir<<std::endl;
|
2008-07-09 05:55:09 -04:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
_wclosedir(direc);
|
|
|
|
#else
|
|
|
|
closedir(direc) ;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2010-12-21 08:30:45 -05:00
|
|
|
bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::list<std::string> &keepFiles)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
/* check for the dir existance */
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring wcleandir;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(cleandir, wcleandir);
|
|
|
|
_WDIR *dir = _wopendir(wcleandir.c_str());
|
|
|
|
#else
|
2007-11-14 22:18:48 -05:00
|
|
|
DIR *dir = opendir(cleandir.c_str());
|
2011-03-06 15:19:16 -05:00
|
|
|
#endif
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
std::list<std::string>::const_iterator it;
|
|
|
|
|
|
|
|
if (!dir)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
struct _wdirent *dent;
|
|
|
|
struct _stat buf;
|
|
|
|
|
|
|
|
while(NULL != (dent = _wreaddir(dir)))
|
|
|
|
#else
|
2007-11-14 22:18:48 -05:00
|
|
|
struct dirent *dent;
|
|
|
|
struct stat buf;
|
|
|
|
|
|
|
|
while(NULL != (dent = readdir(dir)))
|
2011-03-06 15:19:16 -05:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
/* check entry type */
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
const std::wstring &wfname = dent -> d_name;
|
|
|
|
std::wstring wfullname = wcleandir + L"/" + wfname;
|
|
|
|
#else
|
2010-12-21 08:30:45 -05:00
|
|
|
const std::string &fname = dent -> d_name;
|
2007-11-14 22:18:48 -05:00
|
|
|
std::string fullname = cleandir + "/" + fname;
|
2011-03-06 15:19:16 -05:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
if (-1 != _wstat(wfullname.c_str(), &buf))
|
|
|
|
#else
|
|
|
|
if (-1 != stat(fullname.c_str(), &buf))
|
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
/* only worry about files */
|
|
|
|
if (S_ISREG(buf.st_mode))
|
|
|
|
{
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::string fname;
|
|
|
|
librs::util::ConvertUtf16ToUtf8(wfname, fname);
|
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
/* check if we should keep it */
|
|
|
|
if (keepFiles.end() == (it = std::find(keepFiles.begin(), keepFiles.end(), fname)))
|
|
|
|
{
|
|
|
|
/* can remove */
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
_wremove(wfullname.c_str());
|
|
|
|
#else
|
2007-11-14 22:18:48 -05:00
|
|
|
remove(fullname.c_str());
|
2011-03-06 15:19:16 -05:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-03-06 15:19:16 -05:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
/* close directory */
|
2011-03-06 15:19:16 -05:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
_wclosedir(dir);
|
|
|
|
#else
|
2007-11-14 22:18:48 -05:00
|
|
|
closedir(dir);
|
2011-03-06 15:19:16 -05:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2008-03-17 09:51:04 -04:00
|
|
|
|
2008-07-23 18:01:59 -04:00
|
|
|
/* slightly nicer helper function */
|
2010-10-01 16:05:09 -04:00
|
|
|
bool RsDirUtil::hashFile(const std::string& filepath,
|
2008-07-23 18:01:59 -04:00
|
|
|
std::string &name, std::string &hash, uint64_t &size)
|
|
|
|
{
|
|
|
|
if (getFileHash(filepath, hash, size))
|
|
|
|
{
|
|
|
|
/* extract file name */
|
|
|
|
name = RsDirUtil::getTopDir(filepath);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-17 09:51:04 -04:00
|
|
|
#include <openssl/sha.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
|
|
/* Function to hash, and get details of a file */
|
2011-03-03 18:30:08 -05:00
|
|
|
bool RsDirUtil::getFileHash(const std::string& filepath, std::string &hash, uint64_t &size, RsThread *thread /*= NULL*/)
|
2008-03-17 09:51:04 -04:00
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
int len;
|
|
|
|
SHA_CTX *sha_ctx = new SHA_CTX;
|
|
|
|
unsigned char sha_buf[SHA_DIGEST_LENGTH];
|
|
|
|
unsigned char gblBuf[512];
|
|
|
|
|
2011-04-03 19:11:38 -04:00
|
|
|
if (NULL == (fd = RsDirUtil::rs_fopen(filepath.c_str(), "rb")))
|
2008-03-17 09:51:04 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/* determine size */
|
2011-02-24 17:19:04 -05:00
|
|
|
fseeko64(fd, 0, SEEK_END);
|
|
|
|
size = ftello64(fd);
|
|
|
|
fseeko64(fd, 0, SEEK_SET);
|
2008-03-17 09:51:04 -04:00
|
|
|
|
2011-03-03 18:30:08 -05:00
|
|
|
/* check if thread is running */
|
|
|
|
bool isRunning = thread ? thread->isRunning() : true;
|
|
|
|
int runningCheckCount = 0;
|
|
|
|
|
2008-03-17 09:51:04 -04:00
|
|
|
SHA1_Init(sha_ctx);
|
2011-03-03 18:30:08 -05:00
|
|
|
while(isRunning && (len = fread(gblBuf,1, 512, fd)) > 0)
|
2008-03-17 09:51:04 -04:00
|
|
|
{
|
|
|
|
SHA1_Update(sha_ctx, gblBuf, len);
|
2011-03-03 18:30:08 -05:00
|
|
|
|
|
|
|
if (thread && ++runningCheckCount > (10 * 1024)) {
|
|
|
|
/* check all 50MB if thread is running */
|
|
|
|
isRunning = thread->isRunning();
|
|
|
|
runningCheckCount = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Thread has ended */
|
|
|
|
if (isRunning == false)
|
|
|
|
{
|
|
|
|
delete sha_ctx;
|
|
|
|
fclose(fd);
|
|
|
|
return false;
|
2008-03-17 09:51:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* reading failed for some reason */
|
2011-03-03 18:30:08 -05:00
|
|
|
if (ferror(fd))
|
2008-03-17 09:51:04 -04:00
|
|
|
{
|
|
|
|
delete sha_ctx;
|
|
|
|
fclose(fd);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
SHA1_Final(&sha_buf[0], sha_ctx);
|
|
|
|
|
2011-03-03 18:30:08 -05:00
|
|
|
std::ostringstream tmpout;
|
2008-03-17 09:51:04 -04:00
|
|
|
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
|
|
|
|
{
|
|
|
|
tmpout << std::setw(2) << std::setfill('0') << std::hex << (unsigned int) (sha_buf[i]);
|
|
|
|
}
|
|
|
|
hash = tmpout.str();
|
|
|
|
|
|
|
|
delete sha_ctx;
|
|
|
|
fclose(fd);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-29 09:58:28 -04:00
|
|
|
bool RsDirUtil::renameFile(const std::string& from, const std::string& to)
|
|
|
|
{
|
2011-04-03 19:11:38 -04:00
|
|
|
int loops = 0;
|
2009-03-29 09:58:28 -04:00
|
|
|
|
2011-04-03 19:11:38 -04:00
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring f;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(from, f);
|
|
|
|
std::wstring t;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(to, t);
|
|
|
|
|
|
|
|
while (!MoveFileEx(f.c_str(), t.c_str(), MOVEFILE_REPLACE_EXISTING))
|
2009-09-03 16:51:12 -04:00
|
|
|
#else
|
2009-03-29 09:58:28 -04:00
|
|
|
std::string f(from),t(to) ;
|
2011-04-03 19:11:38 -04:00
|
|
|
|
2009-03-29 09:58:28 -04:00
|
|
|
while (rename(from.c_str(), to.c_str()) < 0)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
|
|
if (GetLastError() != ERROR_ACCESS_DENIED)
|
|
|
|
#else
|
|
|
|
if (errno != EACCES)
|
|
|
|
#endif
|
|
|
|
/* set errno? */
|
|
|
|
return false ;
|
|
|
|
#ifdef WIN32
|
|
|
|
Sleep(100000); /* us */
|
|
|
|
#else
|
|
|
|
usleep(100000); /* us */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (loops >= 30)
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
loops++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
|
2010-10-01 16:05:09 -04:00
|
|
|
bool RsDirUtil::createBackup (const std::string& sFilename, unsigned int nCount)
|
2010-06-04 19:39:33 -04:00
|
|
|
{
|
|
|
|
#ifdef WINDOWS_SYS
|
2010-06-26 20:18:33 -04:00
|
|
|
if (GetFileAttributesA (sFilename.c_str ()) == -1) {
|
2010-06-04 19:39:33 -04:00
|
|
|
// file doesn't exist
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// search last backup
|
|
|
|
int nLast;
|
|
|
|
for (nLast = nCount; nLast >= 1; nLast--) {
|
|
|
|
std::ostringstream sStream;
|
|
|
|
sStream << sFilename << nLast << ".bak";
|
|
|
|
|
2010-06-26 20:18:33 -04:00
|
|
|
if (GetFileAttributesA (sStream.str ().c_str ()) != -1) {
|
2010-06-04 19:39:33 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// delete max backup
|
|
|
|
if (nLast == nCount) {
|
|
|
|
std::ostringstream sStream;
|
|
|
|
sStream << sFilename << nCount << ".bak";
|
2010-06-26 20:18:33 -04:00
|
|
|
if (DeleteFileA (sStream.str ().c_str ()) == FALSE) {
|
2010-06-04 19:39:33 -04:00
|
|
|
getPqiNotify()->AddSysMessage (0, RS_SYS_WARNING, "File delete error", "Error while deleting file " + sStream.str ());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
nLast--;
|
|
|
|
}
|
|
|
|
|
|
|
|
// rename backups
|
|
|
|
for (int nIndex = nLast; nIndex >= 1; nIndex--) {
|
|
|
|
std::ostringstream sStream;
|
|
|
|
sStream << sFilename << nIndex << ".bak";
|
|
|
|
std::ostringstream sStream1;
|
|
|
|
sStream1 << sFilename << nIndex + 1 << ".bak";
|
|
|
|
|
|
|
|
if (renameFile (sStream.str (), sStream1.str ()) == false) {
|
|
|
|
getPqiNotify()->AddSysMessage (0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + sStream.str () + " to " + sStream1.str ());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy backup
|
|
|
|
std::ostringstream sStream;
|
|
|
|
sStream << sFilename << 1 << ".bak";
|
2010-06-26 20:18:33 -04:00
|
|
|
if (CopyFileA (sFilename.c_str (), sStream.str ().c_str (), FALSE) == FALSE) {
|
2010-06-04 19:39:33 -04:00
|
|
|
getPqiNotify()->AddSysMessage (0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + sFilename + " to " + sStream.str ());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2011-04-03 19:11:38 -04:00
|
|
|
FILE *RsDirUtil::rs_fopen(const char* filename, const char* mode)
|
|
|
|
{
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
std::wstring wfilename;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(filename, wfilename);
|
|
|
|
std::wstring wmode;
|
|
|
|
librs::util::ConvertUtf8ToUtf16(mode, wmode);
|
|
|
|
|
|
|
|
return _wfopen(wfilename.c_str(), wmode.c_str());
|
|
|
|
#else
|
2011-04-03 19:27:36 -04:00
|
|
|
return fopen64(filename, mode);
|
2011-04-03 19:11:38 -04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2011-05-15 08:42:55 -04:00
|
|
|
std::string RsDirUtil::convertPathToUnix(std::string path)
|
|
|
|
{
|
|
|
|
for (unsigned int i = 0; i < path.length(); i++)
|
|
|
|
{
|
|
|
|
if (path[i] == '\\')
|
|
|
|
path[i] = '/';
|
|
|
|
}
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string RsDirUtil::makePath(const std::string &path1, const std::string &path2)
|
|
|
|
{
|
|
|
|
std::string path = path1;
|
|
|
|
|
|
|
|
if (path.empty() == false && *path.rbegin() != '/') {
|
|
|
|
path += "/";
|
|
|
|
}
|
|
|
|
path += path2;
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2009-09-08 17:30:59 -04:00
|
|
|
#if 0 // NOT ENABLED YET!
|
2009-09-08 16:18:43 -04:00
|
|
|
/************************* WIDE STRING ***************************/
|
|
|
|
/************************* WIDE STRING ***************************/
|
|
|
|
/************************* WIDE STRING ***************************/
|
|
|
|
|
|
|
|
std::wstring RsDirUtil::getWideTopDir(std::wstring dir)
|
|
|
|
{
|
|
|
|
std::wstring top;
|
|
|
|
|
|
|
|
/* find the subdir: [/][dir1.../]<top>[/]
|
|
|
|
*/
|
|
|
|
int i,j;
|
|
|
|
int len = dir.length();
|
|
|
|
for(j = len - 1; (j > 0) && (dir[j] == '/'); j--);
|
|
|
|
for(i = j; (i > 0) && (dir[i] != '/'); i--);
|
|
|
|
|
|
|
|
if (dir[i] == '/')
|
|
|
|
i++;
|
|
|
|
|
|
|
|
for(; i <= j; i++)
|
|
|
|
{
|
|
|
|
top += dir[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return top;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring RsDirUtil::removeWideTopDir(std::wstring dir)
|
|
|
|
{
|
|
|
|
std::wstring rest;
|
|
|
|
|
|
|
|
/* remove the subdir: [/][dir1.../]<top>[/]
|
|
|
|
*/
|
|
|
|
int i,j;
|
|
|
|
int len = dir.length();
|
|
|
|
for(j = len - 1; (j > 0) && (dir[j] == '/'); j--);
|
|
|
|
for(i = j; (i >= 0) && (dir[i] != '/'); i--);
|
|
|
|
|
|
|
|
/* remove any more slashes */
|
|
|
|
for(; (i >= 0) && (dir[i] == '/'); i--);
|
|
|
|
|
|
|
|
for(j = 0; j <= i; j++)
|
|
|
|
{
|
|
|
|
rest += dir[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
return rest;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring RsDirUtil::getWideRootDir(std::wstring dir)
|
|
|
|
{
|
|
|
|
std::wstring root;
|
|
|
|
|
|
|
|
/* find the subdir: [/]root[/...]
|
|
|
|
*/
|
|
|
|
int i,j;
|
|
|
|
int len = dir.length();
|
|
|
|
for(i = 0; (i < len) && (dir[i] == '/'); i++);
|
|
|
|
for(j = i; (j < len) && (dir[j] != '/'); j++);
|
|
|
|
if (i == j)
|
|
|
|
return root; /* empty */
|
|
|
|
for(; i < j; i++)
|
|
|
|
{
|
|
|
|
root += dir[i];
|
|
|
|
}
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring RsDirUtil::removeWideRootDir(std::wstring path)
|
|
|
|
{
|
|
|
|
unsigned int i, j;
|
|
|
|
unsigned int len = path.length();
|
|
|
|
std::wstring output;
|
|
|
|
|
|
|
|
/* chew leading '/'s */
|
|
|
|
for(i = 0; (i < len) && (path[i] == '/'); i++);
|
|
|
|
if (i == len)
|
|
|
|
return output; /* empty string */
|
|
|
|
|
|
|
|
for(j = i; (j < len) && (path[j] != '/'); j++); /* run to next '/' */
|
|
|
|
for(; (j < len) && (path[j] == '/'); j++); /* chew leading '/'s */
|
|
|
|
|
|
|
|
for(; j < len; j++)
|
|
|
|
{
|
|
|
|
output += path[j];
|
|
|
|
}
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring RsDirUtil::removeWideRootDirs(std::wstring path, std::wstring root)
|
|
|
|
{
|
|
|
|
/* too tired */
|
|
|
|
std::wstring notroot;
|
|
|
|
|
|
|
|
unsigned int i = 0, j = 0;
|
|
|
|
|
|
|
|
/* catch empty data */
|
|
|
|
if ((root.length() < 1) || (path.length() < 1))
|
|
|
|
return notroot;
|
|
|
|
|
|
|
|
if ((path[0] == '/') && (root[0] != '/'))
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(; (i < path.length()) && (j < root.length()) && (path[i] == root[j]); i++, j++);
|
|
|
|
|
|
|
|
/* should have consumed root. */
|
|
|
|
if (j == root.length())
|
|
|
|
{
|
|
|
|
//std::cerr << "matched root!" << std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//std::cerr << "failed i: " << i << ", j: " << j << std::endl;
|
|
|
|
//std::cerr << "root: " << root << " path: " << path << std::endl;
|
|
|
|
return notroot;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (path[i] == '/')
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(; i < path.length(); i++)
|
|
|
|
{
|
|
|
|
notroot += path[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
//std::cerr << "Found NotRoot: " << notroot << std::endl;
|
|
|
|
|
|
|
|
return notroot;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int RsDirUtil::breakupWideDirList(std::wstring path,
|
|
|
|
std::list<std::wstring> &subdirs)
|
|
|
|
{
|
|
|
|
int start = 0;
|
|
|
|
unsigned int i;
|
|
|
|
for(i = 0; i < path.length(); i++)
|
|
|
|
{
|
|
|
|
if (path[i] == '/')
|
|
|
|
{
|
|
|
|
if (i - start > 0)
|
|
|
|
{
|
|
|
|
subdirs.push_back(path.substr(start, i-start));
|
|
|
|
}
|
|
|
|
start = i+1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// get the final one.
|
|
|
|
if (i - start > 0)
|
|
|
|
{
|
|
|
|
subdirs.push_back(path.substr(start, i-start));
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool RsDirUtil::checkWideDirectory(std::wstring dir)
|
|
|
|
{
|
|
|
|
struct stat buf;
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::string d(dir.begin(), dir.end());
|
|
|
|
int val = stat(d.c_str(), &buf);
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
if (val == -1)
|
|
|
|
{
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "RsDirUtil::checkDirectory() ";
|
|
|
|
std::cerr << d << " doesn't exist" << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (!S_ISDIR(buf.st_mode))
|
|
|
|
{
|
|
|
|
// Some other type - error.
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "RsDirUtil::checkDirectory() ";
|
|
|
|
std::cerr << d << " is not Directory" << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool RsDirUtil::checkWideCreateDirectory(std::wstring dir)
|
|
|
|
{
|
|
|
|
struct stat buf;
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::string d(dir.begin(), dir.end());
|
|
|
|
int val = stat(d.c_str(), &buf);
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
if (val == -1)
|
|
|
|
{
|
|
|
|
// directory don't exist. create.
|
|
|
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
|
|
#ifndef WINDOWS_SYS // UNIX
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
if (-1 == mkdir(d.c_str(), 0777))
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
#else // WIN
|
|
|
|
if (-1 == mkdir(d.c_str()))
|
|
|
|
#endif
|
|
|
|
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
|
|
|
|
|
|
{
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "check_create_directory() Fatal Error --";
|
|
|
|
std::cerr <<std::endl<< "\tcannot create:" <<d<<std::endl;
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "check_create_directory()";
|
|
|
|
std::cerr <<std::endl<< "\tcreated:" <<d<<std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else if (!S_ISDIR(buf.st_mode))
|
|
|
|
{
|
|
|
|
// Some other type - error.
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr<<"check_create_directory() Fatal Error --";
|
|
|
|
std::cerr<<std::endl<<"\t"<<d<<" is nor Directory"<<std::endl;
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#ifdef RSDIR_DEBUG
|
|
|
|
std::cerr << "check_create_directory()";
|
|
|
|
std::cerr <<std::endl<< "\tDir Exists:" <<d<<std::endl;
|
|
|
|
#endif
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
|
|
|
bool RsDirUtil::cleanupWideDirectory(std::wstring cleandir, std::list<std::wstring> keepFiles)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* check for the dir existance */
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::string cd(cleandir.begin(), cleandir.end());
|
|
|
|
DIR *dir = opendir(cd.c_str());
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::list<std::wstring>::const_iterator it;
|
|
|
|
|
|
|
|
if (!dir)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct dirent *dent;
|
|
|
|
struct stat buf;
|
|
|
|
|
|
|
|
while(NULL != (dent = readdir(dir)))
|
|
|
|
{
|
|
|
|
/* check entry type */
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::string fname(dent -> d_name);
|
|
|
|
std::wstring wfname(fname.begin(), fname.end());
|
|
|
|
std::string fullname = cd + "/" + fname;
|
|
|
|
|
|
|
|
if (-1 != stat(fullname.c_str(), &buf))
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
{
|
|
|
|
/* only worry about files */
|
|
|
|
if (S_ISREG(buf.st_mode))
|
|
|
|
{
|
|
|
|
/* check if we should keep it */
|
|
|
|
if (keepFiles.end() == (it = std::find(keepFiles.begin(), keepFiles.end(), wfname)))
|
|
|
|
{
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
/* can remove */
|
|
|
|
remove(fullname.c_str());
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* close directory */
|
|
|
|
closedir(dir);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* slightly nicer helper function */
|
|
|
|
bool RsDirUtil::hashWideFile(std::wstring filepath,
|
|
|
|
std::wstring &name, std::string &hash, uint64_t &size)
|
|
|
|
{
|
|
|
|
if (getWideFileHash(filepath, hash, size))
|
|
|
|
{
|
|
|
|
/* extract file name */
|
|
|
|
name = RsDirUtil::getWideTopDir(filepath);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include <openssl/sha.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
|
|
/* Function to hash, and get details of a file */
|
|
|
|
bool RsDirUtil::getWideFileHash(std::wstring filepath,
|
|
|
|
std::string &hash, uint64_t &size)
|
|
|
|
{
|
|
|
|
FILE *fd;
|
|
|
|
int len;
|
|
|
|
SHA_CTX *sha_ctx = new SHA_CTX;
|
|
|
|
unsigned char sha_buf[SHA_DIGEST_LENGTH];
|
|
|
|
unsigned char gblBuf[512];
|
|
|
|
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::string fp(filepath.begin(), filepath.end());
|
|
|
|
|
2011-02-24 17:44:41 -05:00
|
|
|
if (NULL == (fd = fopen64(fp.c_str(), "rb")))
|
2009-09-08 16:18:43 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
|
|
|
|
/* determine size */
|
2011-02-24 17:19:04 -05:00
|
|
|
fseeko64(fd, 0, SEEK_END);
|
|
|
|
size = ftello64(fd);
|
|
|
|
fseeko64(fd, 0, SEEK_SET);
|
2009-09-08 16:18:43 -04:00
|
|
|
|
|
|
|
SHA1_Init(sha_ctx);
|
|
|
|
while((len = fread(gblBuf,1, 512, fd)) > 0)
|
|
|
|
{
|
|
|
|
SHA1_Update(sha_ctx, gblBuf, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* reading failed for some reason */
|
|
|
|
if (ferror(fd))
|
|
|
|
{
|
|
|
|
delete sha_ctx;
|
|
|
|
fclose(fd);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
SHA1_Final(&sha_buf[0], sha_ctx);
|
|
|
|
|
|
|
|
std::ostringstream tmpout;
|
|
|
|
for(int i = 0; i < SHA_DIGEST_LENGTH; i++)
|
|
|
|
{
|
|
|
|
tmpout << std::setw(2) << std::setfill('0') << std::hex << (unsigned int) (sha_buf[i]);
|
|
|
|
}
|
|
|
|
hash = tmpout.str();
|
|
|
|
|
|
|
|
delete sha_ctx;
|
|
|
|
fclose(fd);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsDirUtil::renameWideFile(const std::wstring& from, const std::wstring& to)
|
|
|
|
{
|
|
|
|
int loops = 0;
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(MINGW) || defined(__CYGWIN__)
|
|
|
|
#ifdef WIN_CROSS_UBUNTU
|
|
|
|
std::wstring f,t ;
|
|
|
|
for(int i=0;i<from.size();++i) f.push_back(from[i]) ;
|
|
|
|
for(int i=0;i<to.size();++i) t.push_back(to[i]) ;
|
|
|
|
#else
|
|
|
|
std::wstring f(from),t(to) ;
|
|
|
|
#endif
|
|
|
|
while (!MoveFileEx(f.c_str(), t.c_str(), MOVEFILE_REPLACE_EXISTING))
|
|
|
|
#else
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
std::string f(from.begin(), from.end());
|
|
|
|
std::string t(to.begin(), to.end());
|
|
|
|
while (rename(f.c_str(), t.c_str()) < 0)
|
|
|
|
/***** XXX TO MAKE WIDE SYSTEM CALL ******************************************************/
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
#ifdef WIN32
|
|
|
|
if (GetLastError() != ERROR_ACCESS_DENIED)
|
|
|
|
#else
|
|
|
|
if (errno != EACCES)
|
|
|
|
#endif
|
|
|
|
/* set errno? */
|
|
|
|
return false ;
|
|
|
|
#ifdef WIN32
|
|
|
|
Sleep(100000); /* us */
|
|
|
|
#else
|
|
|
|
usleep(100000); /* us */
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (loops >= 30)
|
|
|
|
return false ;
|
|
|
|
|
|
|
|
loops++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
|
2009-03-29 09:58:28 -04:00
|
|
|
|
2009-09-08 17:30:59 -04:00
|
|
|
#endif // WIDE STUFF NOT ENABLED YET!
|