int minLength, const char* separator, char padding){
if (length == (size_t) -1)
length = strlen(data);
- if (length < abs(minLength)){
+ if ((int) length < abs(minLength)){
ensureSize(m_length + abs(minLength));
if (minLength < 0)
appendChar(padding, - minLength - length);
append(data, length);
if (minLength > 0)
appendChar(padding, minLength - length);
- } else if (length > maxLength){
+ } else if ((int) length > maxLength){
ensureSize(m_length + maxLength);
int sepLength = separator == NULL ? 0 : strlen(separator);
int lengthPart1 = (maxLength - sepLength + 1) / 2;
CAT_PROG = 0x00080000,
CAT_RESOURCE = 0x00100000,
CAT_TEST = 0x00200000,
+ CAT_SECURITY = 0x00400000,
CAT_ALL = 0xfffff000,
};
va_end(args);
return log(isError, buffer);
}
-
-#if defined RE_TESTUNIT
-#endif /*RE_TESTUNIT*/
LC_DIRTOOLS = 50100,
LC_SEQARRAY = 50200,
LC_HASHLIST = 50300,
+ LC_TRAVERSER = 50400,
};
enum RELOC_UDPCONNECTION {
LC_UDPCONNECTION_CONSTRUCT = 50101,
\r
class TestReDirTools : public ReTestUnit {\r
public:\r
- TestReDirTools() : ReTestUnit("ReDirTools", __FILE__){\r
+ TestReDirTools() : ReTestUnit("ReDirTools", __FILE__),\r
+ // m_base\r
+ // m_buffer\r
+ m_testAll(true),\r
+ m_logger(ReLogger::globalLogger())\r
+ {\r
m_base = testDir();\r
ReDirectory::deleteTree(m_base.str());\r
m_base.append("dirtool");\r
ReByteBuffer m_base;\r
ReByteBuffer m_buffer;\r
bool m_testAll;\r
+ ReLogger* m_logger;\r
private:\r
const char* makeDir(const char* relPath){\r
m_buffer = m_base;\r
}\r
void run(){\r
initTree();\r
- testList2();\r
testToolSync();\r
+ testList2();\r
if (m_testAll){\r
testToolStatistic();\r
testBasic();\r
}\r
// F:\temp\retestunit\dirtool\r
void testList2(){\r
- const char* argv[] = { "dt", "list", m_base.str(), NULL };\r
+ const char* argv[] = { "dt", "list", "-r", m_base.str(), NULL };\r
ReDirTools tools;\r
- tools.main(3, (char**) argv);\r
+ tools.main(4, (char**) argv);\r
}\r
void testList(){\r
const char* argv[] = { "list", m_base.str(), NULL };\r
- ReDirList().run(2, argv);\r
+ ReDirList(m_logger).run(2, argv);\r
}\r
int secOfFileTime(ReFileTime_t data){\r
#if defined __linux__\r
checkF(hash.get("cache.txt", buffer));\r
}\r
void testDirStatistic(){\r
- ReDirStatistic stat;\r
+ ReDirStatistic stat(m_logger);\r
const ReStringList& list = stat.calculate(m_base.str(), 1);\r
ReByteBuffer buffer;\r
ReByteBuffer expected;\r
class TestReTraverser : public ReTestUnit {
public:
- TestReTraverser() : ReTestUnit("ReTraverser", __FILE__){
+ TestReTraverser() : ReTestUnit("ReTraverser", __FILE__),
+ m_base(),
+ m_buffer(),
+ m_logger(ReLogger::globalLogger())
+ {
m_base = testDir();
m_base.append("traverser");
_mkdir(m_base.str(), ALLPERMS);
private:
ReByteBuffer m_base;
ReByteBuffer m_buffer;
+ ReLogger* m_logger;
private:
const char* makeDir(const char* relPath){
m_buffer = m_base;
}
void testList(){
const char* argv[] = { "list", m_base.str(), NULL };
- ReDirList().run(2, argv);
+ ReDirList(m_logger).run(2, argv);
}
void testCopyFile(){
#if defined __linux__
void testAll(){
try
{
- testBase();
- //testOs();
+ testOs();
if (s_testAll){
testBase();
testString();
\r
#include "base/rebase.hpp"\r
#include "os/reos.hpp"\r
+#include "math/remath.hpp"\r
\r
enum LOCATION_DIRTOOL {\r
LC_COPY_FILE_1 = LC_DIRTOOLS + 1, // 50101\r
LC_SET_PROPERTIES_3, // 50111\r
LC_TOUCH_1, // 50112\r
};\r
-const char* ReDirTools::m_version = "2015.02.04";\r
+const char* ReDirTools::m_version = "2015.02.25";\r
+ReLogger* ReDirTools::m_logger = NULL;\r
\r
static const char* s_helpSummary[] = {\r
"dirtool or dt <command> <opts>",\r
"batch produce output to handle the found files with a script",\r
"help shows info about the arguments/options",\r
"list shows the meta data of the selected files",\r
+ "md5 shows the MD5 checksum of the selected files",\r
"statistic shows statistics about a direcctory tree",\r
"synchronize copies only modified or new files from",\r
" from a source directory tre to a target",\r
NULL\r
};\r
\r
+const char* s_md5Usage[] = {\r
+ "<command>: m(d5) [<opts>] <dir_or_file1> [<dir_or_file2> ...]",\r
+ " shows the MD5 check sum of the given files",\r
+ NULL\r
+};\r
+const char* s_md5Examples[] = {\r
+ "dirtool md5 --buffer-size=512 e:\\data",\r
+ "dirtool m --type=f --size=10M -p;*.iso /home/iso /down/debian.iso",\r
+ NULL\r
+};\r
+\r
static const char* s_statisticUsage[] = {\r
"<command>: st(atistic) [<opts>] <path1> [<path2> ...] [<depth>]",\r
" shows a statistic about a directory tree",\r
* @param addCurrentDirIfNoArguments\r
* <code>true</code>: if no arguments are given the current\r
* directory will be added as argument\r
+ * @param logger logger for error messages\r
*/\r
ReTool::ReTool(const char* usage[], const char* example[],\r
int minArguments, int reservedFirst, int reservedLast,\r
- bool addCurrentDirIfNoArguments) :\r
+ bool addCurrentDirIfNoArguments, ReLogger* logger) :\r
ReDirOptions(usage, example),\r
ReDirTreeStatistic(),\r
m_minArguments(minArguments),\r
m_reservedFirst(reservedFirst),\r
m_reservedLast(reservedLast),\r
m_addCurrentDirIfNoArguments(addCurrentDirIfNoArguments),\r
- m_traverser(NULL, this),\r
+ m_traverser(NULL, this, logger),\r
m_filter(),\r
m_start(time(NULL)),\r
- m_logger(ReLogger::globalLogger())\r
+ m_logger(logger)\r
{\r
}\r
\r
name.append(ext);\r
setFilterFromProgramArgs(m_filter);\r
m_traverser.setPropertiesFromFilter(&m_filter);\r
- ReDirStatus_t entry;\r
+ ReDirStatus_t entry(m_logger);\r
entry.m_path = protocol;\r
if (entry.findFirst()){\r
do {\r
\r
/**\r
* Constructor.\r
+ *\r
+ * @param logger logger for error handling\r
+ * @param deltaList increment if list must be increased\r
+ * @param deltaBuffer increment if content buffer must be increased\r
*/\r
-ReDirStatistic::ReDirStatistic(int deltaList, int deltaBuffer) :\r
- ReTool(s_statisticUsage, s_statisticExamples, 2, 0, 1, false),\r
+ReDirStatistic::ReDirStatistic(ReLogger* logger, int deltaList, int deltaBuffer) :\r
+ ReTool(s_statisticUsage, s_statisticExamples, 2, 0, 1, false, logger),\r
m_list(deltaList, deltaBuffer)\r
{\r
// standard short options: D d O o P p T t v y Z z\r
}\r
/**\r
* Constructor.\r
+ *\r
+ * @param logger logger for error handling\r
*/\r
-ReDirBatch::ReDirBatch() :\r
- ReTool(s_batchUsage, s_batchExamples, 0, 0, 0, true),\r
+ReDirBatch::ReDirBatch(ReLogger* logger) :\r
+ ReTool(s_batchUsage, s_batchExamples, 0, 0, 0, true, logger),\r
m_arguments(),\r
m_script(),\r
m_isExe(false)\r
\r
/**\r
* Constructor.\r
+ *\r
+ * @param logger logger for error handling\r
*/\r
-ReDirList::ReDirList() :\r
- ReTool(s_listUsage, s_listExamples, 0, 0, 0, true),\r
+ReDirList::ReDirList(ReLogger* logger) :\r
+ ReTool(s_listUsage, s_listExamples, 0, 0, 0, true, logger),\r
+ m_widthOwner(13),\r
m_shortFormat(false),\r
- m_hideRights(false),\r
+ m_withRights(false),\r
m_numerical(false)\r
{\r
// standard short options: D d O o P p T t v y Z z\r
m_programArgs.addBool("short", i18n("output is only path and basename"),\r
'1', "--short", false);\r
- m_programArgs.addBool("rights", i18n("do not show the permission/right info"),\r
- 'h', "--hide-rights", false);\r
+ m_programArgs.addBool("rights", i18n("show the permission/right info"),\r
+ 'r', "--rights", false);\r
m_programArgs.addBool("numerical", i18n("the permission/right info is shown as numbers"),\r
'n', "--numerical", false);\r
+ m_programArgs.addInt("owner", i18n("space reserved for owner/group"), \r
+ 'w', "--width-owner", 13);\r
addStandardFilterOptions();\r
}\r
\r
*/\r
void ReDirList::doIt(){\r
m_shortFormat = m_programArgs.getBool("short");\r
- m_hideRights = m_programArgs.getBool("rights");\r
+ m_withRights = m_programArgs.getBool("rights");\r
m_numerical = m_programArgs.getBool("numerical");\r
+ m_widthOwner = m_programArgs.getInt("owner");\r
processFileArguments();\r
printSummary();\r
}\r
if (m_shortFormat)\r
fprintf(m_output, "%s%s\n", entry->m_path.str(), entry->node());\r
else {\r
- if (! m_hideRights)\r
- entry->rightsAsString(bufferRights, m_numerical);\r
+ if (m_withRights)\r
+ entry->rightsAsString(bufferRights, m_numerical, m_widthOwner);\r
fprintf(m_output, "%c%s %12.6f %s %s%s\n",\r
entry->typeAsChar(),\r
bufferRights.str(),\r
}\r
}\r
\r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param logger logger for error handling\r
+ */\r
+ReDirMD5::ReDirMD5(ReLogger* logger) :\r
+ ReTool(s_md5Usage, s_md5Examples, 0, 0, 0, true, logger),\r
+ m_buffer()\r
+{\r
+ // standard short options: D d O o P p T t v y Z z\r
+ m_programArgs.addInt("buffersize", i18n("buffer size for file reading (in KiByte)"), \r
+ 'b', "--buffer-size", 4*1024);\r
+ addStandardFilterOptions();\r
+}\r
+\r
+/**\r
+ * Lists the metadata of the specified files.\r
+ */\r
+void ReDirMD5::doIt(){\r
+ int size = m_programArgs.getInt("buffersize") * 1024;\r
+ m_buffer.setLength(size);\r
+ processFileArguments();\r
+ printSummary();\r
+}\r
+\r
+/**\r
+ * Processes one directory.\r
+ *\r
+ * @param entry the properties of the directory to process\r
+ */\r
+void ReDirMD5::processDir(ReDirStatus_t* entry){\r
+}\r
+/**\r
+ * Processes one file.\r
+ *\r
+ * @param entry the properties of the file to process\r
+ */\r
+void ReDirMD5::processFile(ReDirStatus_t* entry){\r
+ const char* name = entry->fullName();\r
+ FILE* fp = fopen(name, "rb");\r
+ if (fp != NULL) {\r
+ ReMD5 digest;\r
+ size_t readBytes;\r
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(m_buffer.buffer());\r
+ size_t blockSize = m_buffer.length();\r
+\r
+ while( (readBytes = fread(buffer, 1, blockSize, fp)) > 0){\r
+ digest.update(buffer, readBytes);\r
+ }\r
+ fclose(fp);\r
+ fprintf(m_output, "%s %s\n", digest.hexDigest().str(), name);\r
+ }\r
+}\r
+\r
\r
/**\r
* Calculates the statistic of a directory tree.\r
}\r
/**\r
* Constructor.\r
+ *\r
+ * @param logger logger for error handling\r
*/\r
-ReDirTouch::ReDirTouch() :\r
- ReTool(s_touchUsage, s_touchExamples, 1, 0, 0, false),\r
+ReDirTouch::ReDirTouch(ReLogger* logger) :\r
+ ReTool(s_touchUsage, s_touchExamples, 1, 0, 0, false, logger),\r
m_buffer()\r
//m_modified()\r
//m_accessed()\r
}\r
/**\r
* Constructor.\r
+ *\r
+ * @param logger logger for error handling\r
*/\r
-ReDirSync::ReDirSync() :\r
- ReTool(s_syncUsage, s_syncExamples, 2, 0, 1, false),\r
+ReDirSync::ReDirSync(ReLogger* logger) :\r
+ ReTool(s_syncUsage, s_syncExamples, 2, 0, 1, false, logger),\r
m_buffer()\r
{\r
// standard short options: D d O o P p T t v y Z z\r
argv++;\r
const char* arg0 = argv[0];\r
if (isArg("batch", arg0)){\r
- ReDirBatch batch;\r
+ ReDirBatch batch(m_logger);\r
batch.help(NULL);\r
} else if (isArg("list", arg0)){\r
- ReDirList list;\r
+ ReDirList list(m_logger);\r
list.help(NULL);\r
} else if (isArg("help", arg0))\r
printField(s_helpSummary);\r
else if (isArg("statistic", arg0)){\r
- ReDirStatistic stat;\r
+ ReDirStatistic stat(m_logger);\r
stat.help(NULL);\r
} else if (isArg("test", arg0)){\r
void testAll();\r
}\r
argc--;\r
argv++;\r
+ m_logger = ReLogger::globalLogger();\r
const char* arg0 = argv[0];\r
if (isArg("batch", arg0))\r
- ReDirBatch().run(argc, argv);\r
- else if (isArg("list", arg0))\r
- ReDirList().run(argc, argv);\r
+ ReDirBatch(m_logger).run(argc, argv);\r
else if (isArg("help", arg0))\r
tools.help(argc, argv);\r
+ else if (isArg("list", arg0))\r
+ ReDirList(m_logger).run(argc, argv);\r
+ else if (isArg("md5", arg0))\r
+ ReDirMD5(m_logger).run(argc, argv);\r
else if (isArg("statistic", arg0))\r
- ReDirStatistic().run(argc, argv);\r
+ ReDirStatistic(m_logger).run(argc, argv);\r
else if (isArg("synchronize", arg0))\r
- ReDirSync().run(argc, argv);\r
+ ReDirSync(m_logger).run(argc, argv);\r
else if (isArg("touch", arg0))\r
- ReDirTouch().run(argc, argv);\r
+ ReDirTouch(m_logger).run(argc, argv);\r
else if (isArg("test", arg0)){\r
void testAll();\r
testAll();\r
public:
ReTool(const char* usage[], const char* example[],
int minArguments, int reservedFirst, int reservedLast,
- bool addCurrentDirIfNoArguments);
+ bool addCurrentDirIfNoArguments, ReLogger* logger);
virtual ~ReTool();
public:
virtual bool trace(const char* currentFile);
name.setLength(ix);
bool rc = stat(name.str(), &m_statInfo) == 0;
if (ix >= 0)
- name.append(OS_SEPARATOR_CHAR);
+ name.appendChar(OS_SEPARATOR_CHAR);
return rc;
#endif
}
class ReDirBatch : public ReTool {
public:
- ReDirBatch();
+ ReDirBatch(ReLogger* logger);
protected:
virtual void doIt();
virtual void processDir(ReDirStatus_t* entry);
*/
class ReDirList : public ReTool {
public:
- ReDirList();
+ ReDirList(ReLogger* logger);
protected:
virtual void doIt();
virtual void processDir(ReDirStatus_t* entry);
virtual void processFile(ReDirStatus_t* entry);
protected:
+ int m_widthOwner;
bool m_shortFormat;
- bool m_hideRights;
+ bool m_withRights;
bool m_numerical;
+
+};
+
+/**
+ * List file attributes of files.
+ */
+class ReDirMD5 : public ReTool {
+public:
+ ReDirMD5(ReLogger* logger);
+protected:
+ virtual void doIt();
+ virtual void processDir(ReDirStatus_t* entry);
+ virtual void processFile(ReDirStatus_t* entry);
+protected:
+ ReByteBuffer m_buffer;
};
/**
*/
class ReDirSync : public ReTool {
public:
- ReDirSync();
+ ReDirSync(ReLogger* logger);
protected:
virtual void doIt();
void copyFile(ReDirStatus_t* entry, const char* target);
*/
class ReDirStatistic : public ReTool {
public:
- ReDirStatistic(int deltaList = 512, int deltaBuffer = 0x10000);
+ ReDirStatistic(ReLogger* logger, int deltaList = 512, int deltaBuffer = 0x10000);
~ReDirStatistic();
public:
const ReStringList& calculate(const char* base, int depth,
*/
class ReDirTouch : public ReTool {
public:
- ReDirTouch();
+ ReDirTouch(ReLogger* logger);
protected:
virtual void doIt();
virtual void processDir(ReDirStatus_t* entry);
class ReDirTools {
+
public:
virtual void usage(const char* msg, const char* msg2 = NULL);
void help(int argc, const char* argv[]);
void usage(ReTool& tool);
public:
static const char* m_version;
+ static ReLogger* m_logger;
};
#endif /* OS_DIRTOOLS_HPP_ */
#include "aclapi.h"\r
#pragma comment(lib, "advapi32.lib")\r
#endif\r
+\r
+enum RELOC_TRAVERSER {
+ LC_RIGHTS_AS_STRING_1 = LC_TRAVERSER + 1, // 50301
+ LC_RIGHTS_AS_STRING_2, // 50302
+ LC_RIGHTS_AS_STRING_3, // 50303
+ LC_GET_PRIVILEGE_1, // 50304
+ LC_GET_PRIVILEGE_2, // 50305
+ LC_GET_PRIVILEGE_3, // 50306
+ LC_GET_FILE_OWNER_1, // 50307
+ LC_GET_FILE_OWNER_2, // 50308
+};
+\r
/**\r
* Constructor.\r
*/\r
-ReDirStatus_t::ReDirStatus_t() :\r
+ReDirStatus_t::ReDirStatus_t(ReLogger* logger) :\r
m_path(),\r
m_fullName(),\r
m_passNo(0),\r
+ m_logger(logger),\r
#ifdef __linux__\r
m_handle(NULL),\r
m_data(NULL)\r
//m_status;\r
#elif defined WIN32\r
- m_handle(INVALID_HANDLE_VALUE)\r
+ m_handle(INVALID_HANDLE_VALUE),\r
//m_data;\r
+ m_getPrivilege(true)\r
#endif\r
{\r
#ifdef __linux__\r
return m_fullName.str();\r
}\r
\r
+#if defined __WIN32__\r
+/** Gets the name of the file owner.\r
+*\r
+* @param handle file handle (see <code>CreateFile()</code>)\r
+* @param name OUT: the owner: [domain\\]name\r
+* @return <code>true</code>: success\r
+*/\r
+bool ReDirStatus_t::getFileOwner(HANDLE handle, const char* file,\r
+ ReByteBuffer& name, ReLogger* logger){\r
+ bool rc = false;\r
+ PSID pSidOwner = NULL;\r
+ PSECURITY_DESCRIPTOR pSD = NULL;\r
+ if (GetSecurityInfo(handle, SE_FILE_OBJECT,\r
+ OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD) != ERROR_SUCCESS) {\r
+ if (logger != NULL)\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_FILE_OWNER_1,\r
+ "GetSecurityInfo($1): $2").arg(file).arg((int) GetLastError()).end();\r
+ } else {\r
+ char accountName[128];\r
+ char domainName[128];\r
+ DWORD dwAcctName = sizeof accountName;\r
+ DWORD dwDomainName = sizeof domainName;\r
+ SID_NAME_USE eUse = SidTypeUnknown;\r
+ if (! LookupAccountSid(NULL, pSidOwner, accountName, &dwAcctName, domainName, \r
+ &dwDomainName, &eUse)){\r
+ if (logger != NULL)\r
+ logger->sayF(LOG_ERROR | CAT_SECURITY, LC_GET_FILE_OWNER_2,\r
+ "LookupAccountSid(): $1").arg((int) GetLastError()).end();\r
+ } else {\r
+ if (dwDomainName > 0)\r
+ name.append(domainName).appendChar('\\');\r
+ name.append(accountName);\r
+ rc = true;\r
+ }\r
+ }\r
+ return rc;\r
+}\r
+#endif /* __WIN32__ */\r
+\r
+#if defined __WIN32__\r
+/** Tries to get a privilege.\r
+*\r
+* @param privilege the name of the privilege, e.g. "SeBackup"\r
+* @param logger logger for error logging\r
+*/\r
+bool ReDirStatus_t::getPrivilege(const char* privilege, ReLogger* logger){
+ bool rc = false;
+ LUID luidPrivilege;\r
+ HANDLE hAccessToken;\r
+ if (! OpenProcessToken (GetCurrentProcess(), \r
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hAccessToken)){\r
+ if (logger != NULL)\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_1,\r
+ "OpenProcessToken(): $1").arg((int) GetLastError()).end();\r
+ } else if (! LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &luidPrivilege)) {\r
+ if (logger != NULL)\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_2,\r
+ "LookupPrivilegeValue(): $1").arg((int) GetLastError()).end(); \r
+ } else {\r
+ TOKEN_PRIVILEGES tpPrivileges;\r
+ tpPrivileges.PrivilegeCount = 1;\r
+ tpPrivileges.Privileges[0].Luid = luidPrivilege;\r
+ tpPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
+ if (AdjustTokenPrivileges (hAccessToken, FALSE, &tpPrivileges, \r
+ 0, NULL, NULL) == 0)\r
+ rc = true;\r
+ else {\r
+ int error = GetLastError();\r
+ if (error != 1300 && logger != NULL)\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_GET_PRIVILEGE_3,\r
+ "AdjustTokenPrivileges(): $1").arg((int) GetLastError()).end();\r
+ }\r
+ }\r
+ return rc;\r
+}
+#endif /* __WIN32__ */\r
+\r
/**\r
* Tests whether the instance is a directory.\r
*\r
/**\r
* Returns the file rights as a string.\r
*\r
- * @param buffer OUT: the file rights\r
- * @return <code>buffer.str()</code> (for chaining)\r
+ * @param buffer OUT: the file rights\r
+ * @param numerical <code>true</code>: the owner/group should be numerical (UID/GID)\r
+ * @param ownerWidth the width for group/owner\r
+ * @return <code>buffer.str()</code> (for chaining)\r
*/\r
-const char* ReDirStatus_t::rightsAsString(ReByteBuffer& buffer, bool numerical) {\r
+const char* ReDirStatus_t::rightsAsString(ReByteBuffer& buffer, bool numerical, \r
+ int ownerWidth) {\r
buffer.setLength(0);\r
#if defined __linux__\r
if (numerical){\r
}\r
#elif defined __WIN32__\r
const char* name = fullName();\r
- DWORD access = isDirectory() ? 0 : GENERIC_READ;\r
- DWORD shareFlag = isDirectory() ? 0 : FILE_SHARE_READ;\r
- DWORD flag = isDirectory() ? FILE_FLAG_BACKUP_SEMANTICS : FILE_ATTRIBUTE_NORMAL;\r
- HANDLE handle;\r
+ HANDLE handle = INVALID_HANDLE_VALUE;\r
if (! isDirectory()){\r
- handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ,\r
- NULL, OPEN_EXISTING, flag, NULL);\r
- } else {\r
- LUID luidPrivilege;\r
- DWORD dwErrorCode;\r
- HANDLE hAccessToken;\r
- if (! OpenProcessToken (GetCurrentProcess(), \r
- TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hAccessToken)){\r
- printf("OpenProcessToken(): %d\n", GetLastError());\r
+ if ( (handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,\r
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
+ m_logger->sayF(LOG_ERROR | CAT_FILE, LC_RIGHTS_AS_STRING_1,\r
+ "CreateFile($1): $2").arg(name).arg((int) GetLastError()).end();\r
+ } else if (m_getPrivilege){\r
+ // we try only one time:\r
+ m_getPrivilege = false;\r
+ if (getPrivilege(SE_BACKUP_NAME, m_logger)){\r
+ if ( (handle = CreateFile(name, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, \r
+ NULL)) != INVALID_HANDLE_VALUE)\r
+ m_logger->sayF(LOG_ERROR | CAT_FILE, LC_RIGHTS_AS_STRING_2,\r
+ "CreateFile($1): $2").arg(name).arg((int) GetLastError()).end();\r
}\r
\r
- if (! LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &luidPrivilege)) {\r
- printf("LookupPrivilegeValue(): %d\n", GetLastError());\r
- } else {\r
- TOKEN_PRIVILEGES tpPrivileges;\r
- tpPrivileges.PrivilegeCount = 1;\r
- tpPrivileges.Privileges[0].Luid = luidPrivilege;\r
- tpPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
- if (AdjustTokenPrivileges (hAccessToken, FALSE, &tpPrivileges, \r
- 0, NULL, NULL) != 0){\r
- printf("AdjustTokenPrivileges(): %d\n", GetLastError());\r
- }\r
- }\r
- handle = CreateFile(name, 0, 0, NULL, OPEN_EXISTING, flag, NULL);\r
- }\r
- if (handle == INVALID_HANDLE_VALUE){\r
- int error = GetLastError();\r
- printf("CreateFile(%s): %d\n", name, error);\r
- } else {\r
- PSID pSidOwner = NULL;\r
- PSECURITY_DESCRIPTOR pSD = NULL;\r
- DWORD dwRtnCode = GetSecurityInfo(handle, SE_FILE_OBJECT,\r
- OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD);\r
- if (dwRtnCode != ERROR_SUCCESS) {\r
- int error = GetLastError();\r
- printf("GetSecurityInfo(%s): %d\n", name, error);\r
- } else {\r
- if (numerical){\r
- buffer.appendInt((int) pSidOwner, " %08x");\r
- } else {\r
- char accountName[128];\r
- char domainName[128];\r
- DWORD dwAcctName = sizeof accountName;\r
- DWORD dwDomainName = sizeof domainName;\r
- SID_NAME_USE eUse = SidTypeUnknown;\r
- BOOL bRtnBool = LookupAccountSid(NULL, // local computer\r
- pSidOwner, accountName, &dwAcctName, domainName,\r
- &dwDomainName, &eUse);\r
- if (! bRtnBool){\r
- int error = GetLastError();\r
- printf("LookupAccountSid(%s): %d\n", name, error);\r
- } else {\r
- if (domainName[0] != '\0')\r
- buffer.append(domainName, -1).appendChar('/');\r
- }\r
- buffer.append(accountName, -1);\r
- }\r
- }\r
}\r
+ ReByteBuffer owner;\r
+ if (handle != INVALID_HANDLE_VALUE)\r
+ getFileOwner(handle, name, owner, m_logger);\r
+ CloseHandle(handle);\r
+ buffer.appendFix(owner.str(), owner.length(), ownerWidth, ownerWidth);\r
#endif\r
return buffer.str();\r
}\r
*\r
* @param base the base directory. The traversal starts at this point\r
*/\r
-ReTraverser::ReTraverser(const char* base, ReTraceUnit* tracer) :\r
+ReTraverser::ReTraverser(const char* base, ReTraceUnit* tracer, ReLogger* logger) :\r
ReDirTreeStatistic(),\r
m_minLevel(0),\r
m_maxLevel(512),\r
// m_dirs\r
m_passNoForDirSearch(2),\r
m_dirPatterns(NULL),\r
- m_tracer(tracer)\r
+ m_tracer(tracer),\r
+ m_logger(logger)\r
{\r
memset(m_dirs, 0, sizeof m_dirs);\r
- m_dirs[0] = new ReDirStatus_t();\r
+ m_dirs[0] = new ReDirStatus_t(m_logger);\r
// remove a preceeding "./". This simplifies the pattern expressions:\r
if (m_base.startsWith(ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())){\r
m_base.remove(0, 2);\r
destroy();\r
m_base.setLength(0).append(base);\r
memset(m_dirs, 0, sizeof m_dirs);\r
- m_dirs[0] = new ReDirStatus_t();\r
+ m_dirs[0] = new ReDirStatus_t(m_logger);\r
// remove a preceeding "./". This simplifies the pattern expressions:\r
if (m_base.startsWith(ReByteBuffer(".").appendChar(OS_SEPARATOR_CHAR).str())){\r
m_base.remove(0, 2);\r
if (level >= 0)\r
m_level = level;\r
if (m_dirs[m_level] == NULL)\r
- m_dirs[m_level] = new ReDirStatus_t();\r
+ m_dirs[m_level] = new ReDirStatus_t(m_logger);\r
ReDirStatus_t* current = m_dirs[m_level];\r
current->m_passNo = 1;\r
if (level >= 0){\r
};
public:
- ReDirStatus_t();
+ ReDirStatus_t(ReLogger* logger);
public:
const ReFileTime_t* accessed();
ReFileSize_t fileSize();
bool isRegular();
const ReFileTime_t* modified();
const char* node() const;
- const char* rightsAsString(ReByteBuffer& buffer, bool numerical);
+ const char* rightsAsString(ReByteBuffer& buffer, bool numerical, int ownerWidth);
Type_t type();
char typeAsChar();
public:
+ static const char* filetimeToString(const ReFileTime_t* time, ReByteBuffer& buffer);
static time_t filetimeToTime(const ReFileTime_t* time);
+#if defined __WIN32__
+ static bool getFileOwner(HANDLE handle, const char* file, ReByteBuffer& name,
+ ReLogger* logger = NULL);
+ static bool getPrivilege(const char* privilege, ReLogger* logger);
+#endif
static void timeToFiletime(time_t time, ReFileTime_t& filetime);
- static const char* filetimeToString(const ReFileTime_t* time, ReByteBuffer& buffer);
public:
ReByteBuffer m_path;
ReByteBuffer m_fullName;
int m_passNo;
+ ReLogger* m_logger;
#ifdef __linux__
DIR* m_handle;
struct dirent* m_data;
#elif defined WIN32
HANDLE m_handle;
WIN32_FIND_DATAA m_data;
+ bool m_getPrivilege;
#endif
};
class ReDirEntryFilter_t{
#define MAX_ENTRY_STACK_DEPTH 256
class ReTraverser : public ReDirTreeStatistic {
public:
- ReTraverser(const char* base, ReTraceUnit* tracer = NULL);
+ ReTraverser(const char* base, ReTraceUnit* tracer = NULL, ReLogger* logger = NULL);
virtual ~ReTraverser();
public:
void changeBase(const char* base);
RePatternList* m_dirPatterns;
ReDirTreeStatistic m_statistic;
ReTraceUnit* m_tracer;
+ ReLogger* m_logger;
};
#endif /* OS_RETRAVERSER_HPP_ */