value = (time.tv_sec << 32) + time.tv_nsec;
sequence.appendBits64(int64_t(value));
#elif defined __WIN32__
-#error "missing impl"
+//#error "missing impl"
+ assert(false);
#endif
}
/**
break;
}
#elif defined __WIN32__
-#error "missing impl"
+//#error "missing impl"
+ assert(false);
#endif
}
m_logger(logger),
m_maxThreads(maxThreads),
m_maxKillTimeSec(3),
- m_mutexThreads(LC_MUTEX_THREADS) {
+ m_mutexThreads(LC_MUTEX_THREADS),
+ m_shouldStop(false){
m_threads = new ReThread*[maxThreads];
memset(m_threads, 0, maxThreads * sizeof *m_threads);
}
typedef u_int64_t uint64_t;
typedef u_int8_t uint8_t;
typedef __off_t ReFileSize_t;
-enum ReOSType {
- OS_UNDEF,
- OS_LINUX = 'l',
- OS_WIN32 = 'w'
-};
typedef struct timespec ReFileTime_t;
# define _strdup strdup
# define _unlink unlink
# define OS_SEPARATOR "\\"
typedef _int64 int64_t;
typedef unsigned long long uint64_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef unsigned long uint32_t;
typedef long int int32_t;
inline int getLastOSError() {
return GetLastError();
}
+inline void bzero(void* ptr, size_t size){
+ memset(ptr, 0, size);
+}
#endif
+enum ReOSType {
+ OS_UNDEF,
+ OS_LINUX = 'l',
+ OS_WIN32 = 'w'
+};
typedef int ReErrNo_t;
/**
packString255(buffer, m_string255);
packString64k(buffer, m_string64k);
packString4t(buffer, m_string4t);
+ return buffer;
}
const char* toString(ReByteBuffer& buffer) {
buffer.setLength(0).append("id: ").appendInt(m_serialId);
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = timeout % 1000 * 1000;
select(maxfd + 1, &rdset, NULL, NULL, &timeval);
- doRead = FD_ISSET(m_socket, &rdset);
+ doRead = FD_ISSET(m_socket, &rdset) != 0;
}
buffer->ensureSize(8096 + 1);
size_t size = buffer->capacity();
m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK,
LC_UDPCONNECTION_CLOSE_1, i18n("Connection has been closed: $1:$2"))
.arg(address()).arg(m_port).end();
- if (::close(m_socket) != 0)
+#if defined __linux__
+ int rc = ::close(m_socket);
+#elif defined __WIN32__
+ int rc = closesocket(m_socket);
+#endif
+ if (rc != 0)
m_logger->sayF(LOG_ERROR | GRAN_USER | CAT_NETWORK,
LC_UDPCONNECTION_CLOSE_2, i18n("socket close failed: $1")).arg(
strerror(errno)).end();
const char* s_syncExamples[] = {
"dirtool sync --basename-pattern=;*.txt;*.doc e:\\data\\ d:\\backup\\data2",
"dirtool sync --type=r --max-size=1G usr etc /media/backup",
+ "dirtool sync --delete=7d /home/ /backup",
NULL };
const char* s_tcpUsage[] = {
/**
* Checks whether the given value is a time expression.
*
- * Possible: <date> <date_time> <n><unit>
- * Units: m(inutes) h(our) d(ays)
+ * Possible: <n>[<unit>]
+ * Units: b(ytes) k(ilobytes [1000]) K(ilobytes [1024])
+ * m(egabytes [1000**2]) M(egabytes [1024**2])
+ * g(igabytes [1000**3]) G(igabytes [1024**3])
*
* @param value value to check
* @return the value (multiplied with the unit factor)
m_output = stdout;
}
}
+ m_programArgs.getString("verbose", buffer);
+ unsigned int nValue = 0;
+ int length;
+ if (buffer.length() == 0)
+ m_verboseLevel = V_NORMAL;
+ else if ( (length = ReStringUtils::lengthOfUnsigned(buffer.str(),
+ buffer.length(), &nValue)) == 0 || length != buffer.length())
+ help("not a verbose level (0..5): ", buffer.str());
+ else
+ m_verboseLevel = VerboseLevel(min(V_DEBUG, nValue));
}
/**
m_traverser(NULL, this, logger),
m_filter(),
m_start(time(NULL)),
+ //m_statInfo(),
m_logger(logger) {
#pragma warning( pop )
}
"add", false);
m_programArgs.addBool("dry",
i18n("does nothing, but says what should be done"), 'Y', "dry", false);
+ m_programArgs.addString("delete",
+ i18n(
+ "delete the files/folders of the target directory not existing in the source directory.\n"
+ "If a time expression is given only files will be deleted if they are older than this.\n"
+ "a time expression is a date, a time, a date/time or a relative time.\n"
+ "relative times are a number and a unit.\n"
+ "units: m(inutes) h(hours), d(days). Default: m(inutes)\n"
+ "examples: -D7d --delete=30d -D24h -D2009.3.2/12:00 -D1999.01.01"),
+ 'E', "delete", false, NULL);
m_programArgs.addInt("timediff",
i18n("filetime difference is considered to be equal\n"
"if the difference is less than this value (in seconds)"), 'I',
bool dry = m_programArgs.getBool("dry");
bool ignoreDate = m_programArgs.getBool("ignoredate");
bool mustExist = m_programArgs.getBool("mustexist");
+ if (m_programArgs.getString("delete", buffer)[0] != '\0')
+ checkDate(buffer.str());
+
setFilterFromProgramArgs(filter);
int64_t sumSizes = 0;
int files = 0;
int diff = int(
m_statInfo.st_mtime
- entry->filetimeToTime(entry->modified()));
- if (!ignoreDate && diff <= maxFileTimeDiff) {
+ if (!ignoreDate && (diff <= maxFileTimeDiff || diff == 3600)) {
if (m_verboseLevel >= V_CHATTER)
fprintf(m_output, "=ignored: %s same time\n",
targetRelativePath);
#elif defined __WIN32__
int ix = name.length() - 1;
if (ix >= 0 && name.str()[ix] != OS_SEPARATOR_CHAR)
- ix = -1;
+ ix = -1;
else
- name.setLength(ix);
+ name.setLength(ix);
bool rc = stat(name.str(), &m_statInfo) == 0;
if (ix >= 0)
- name.appendChar(OS_SEPARATOR_CHAR);
+ name.appendChar(OS_SEPARATOR_CHAR);
return rc;
#endif
}
int64_t m_start;
struct stat m_statInfo;
ReLogger* m_logger;
-
};
class ReDirBatch: public ReTool {
--- /dev/null
+/*\r
+ * ReFileUtils.cpp\r
+ * \r
+ * License: Public Domain\r
+ * You can use and modify this file without any restriction.\r
+ * Do what you want.\r
+ * No warranties and disclaimer of any damages.\r
+ * You also can use this license: http://www.wtfpl.net\r
+ * The latest sources: https://github.com/republib\r
+ */\r
+#include "base/rebase.hpp"\r
+#include "os/reos.hpp"\r
+\r
+/**\r
+ * Returns the name of a subdirectory in the temporary directory.\r
+ *\r
+ * If the directory does not exist it will be created.\r
+ *\r
+ * @param node the name of the subdirectory\r
+ * @return the full name of the subdirectory\r
+ */\r
+ReByteBuffer ReFileUtils::tempDir(const char* node){\r
+ ReByteBuffer rc;\r
+ if (getenv("TMP") != NULL) {\r
+ rc = getenv("TMP");\r
+ } else if (getenv("TEMP")) {\r
+ rc = getenv("TEMP");\r
+ } else {\r
+#if defined __linux__\r
+ rc = "/tmp/";\r
+#elif defined __WIN32__\r
+ rc = "c:\\temp";\r
+#endif\r
+ }\r
+ if (node != NULL){\r
+ rc.ensureLastChar(OS_SEPARATOR_CHAR);\r
+ rc.append(node);\r
+ _mkdir(rc.str(), ALLPERMS);\r
+ }\r
+ return rc;\r
+}\r
+/**\r
+ * Returns the name of a file in a subdirectory in the temporary directory.\r
+ *\r
+ * If the directory does not exist it will be created.\r
+ *\r
+ * @param node the name of the subdirectory\r
+ * @param node the name of the subdirectory\r
+ * @param the full name of the subdirectory\r
+ */\r
+ReByteBuffer ReFileUtils::tempFile(const char* node, const char* subdir){\r
+ ReByteBuffer rc = tempDir(subdir);\r
+ rc.ensureLastChar(OS_SEPARATOR_CHAR);\r
+ rc.append(node);\r
+ return rc;\r
+}\r
--- /dev/null
+/*\r
+ * ReFileUtils.hpp\r
+ * \r
+ * License: Public Domain\r
+ * You can use and modify this file without any restriction.\r
+ * Do what you want.\r
+ * No warranties and disclaimer of any damages.\r
+ * You also can use this license: http://www.wtfpl.net\r
+ * The latest sources: https://github.com/republib\r
+ */\r
+#if ! defined REFILE_UTILS_HPP\r
+#define REFILE_UTILS_HPP\r
+\r
+class ReFileUtils {\r
+public:\r
+ static ReByteBuffer tempDir(const char* node);\r
+ static ReByteBuffer tempFile(const char* node, const char* subdir);\r
+};\r
+#endif
\ No newline at end of file
* @param sequence IN/OUT: the place for the byte sequence
*/
ReByteBuffer& ReRemoteDir::serialize(ReByteBuffer& sequence) {
+ return sequence;
}
/**
ReNetCommandHandler::ProcessingState ReRemoteDirService::handleNetCommand(
ReByteBuffer& command, ReByteBuffer& data, ReTCPConnection* connection) {
-
+ return ReNetCommandHandler::PS_UNDEF;
}
date.QuadPart -= adjust.QuadPart;
// converts back from 100-nanoseconds to seconds
time_t rc = (time_t) (date.QuadPart / 10000000);
+#if defined __WIN32__
+ static int s_diffTime = 0x7fffffff;
+ if (s_diffTime == 0x7fffffff){
+ s_diffTime = 0;
+ ReByteBuffer tempFile = ReFileUtils::tempFile("$$redir$$.tmp", NULL);
+ const char* filename = tempFile.str();
+ FILE* fp = fopen(filename, "w");
+ if (fp != NULL){
+ struct stat info;
+ int rcStat = stat(filename, &info);
+ fclose(fp);
+ if (rcStat == 0) {
+ WIN32_FIND_DATAA data;
+ HANDLE handle = FindFirstFile(filename, &data);
+ if (handle != INVALID_HANDLE_VALUE){
+ time_t other = filetimeToTime(&data.ftLastWriteTime);
+ s_diffTime = info.st_mtime - other;
+ FindClose(handle);
+ }
+ }
+ }
+ }
+ rc += s_diffTime;
+#endif
return rc;
#endif
}
sequence.appendBits64(int64_t(value));
value = (m_minAge.tv_sec << 32) + m_minAge.tv_nsec;
#elif defined __WIN32__
-#error "missing impl"
+// #error "missing impl"
+ assert(false);
#endif
sequence.appendBits64(int64_t(value));
packBool(sequence, m_allDirectories);
+ return sequence;
}
/**
&& time1.dwLowDateTime > time2.dwLowDateTime);
#endif
}
+#include "os/ReFileUtils.hpp"
#include "os/ReTraverser.hpp"
#include "os/ReDirTools.hpp"
#include "net/renet.hpp"