123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- #include <kopano/platform.h>
- #include <cerrno>
- #include <cstdlib>
- #include <fcntl.h>
- #include <mapidefs.h>
- #include <mapicode.h>
- #include <climits>
- #include <pthread.h>
- #include <unistd.h>
- #include <sys/stat.h>
- #include <sys/time.h>
- #include <kopano/ECLogger.h>
- #include "TmpPath.h"
- namespace KC {
- HRESULT UnixTimeToFileTime(time_t t, FILETIME *ft)
- {
- __int64 l;
- l = (__int64)t * 10000000 + NANOSECS_BETWEEN_EPOCHS;
- ft->dwLowDateTime = (unsigned int)l;
- ft->dwHighDateTime = (unsigned int)(l >> 32);
- return hrSuccess;
- }
- HRESULT FileTimeToUnixTime(const FILETIME &ft, time_t *t)
- {
- __int64 l;
- l = ((__int64)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
- l -= NANOSECS_BETWEEN_EPOCHS;
- l /= 10000000;
-
- if(sizeof(time_t) < 8) {
-
- if(l < (__int64)INT_MIN) {
- l = INT_MIN;
- }
- if(l > (__int64)INT_MAX) {
- l = INT_MAX;
- }
- }
- *t = (time_t)l;
- return hrSuccess;
- }
- void UnixTimeToFileTime(time_t t, int *hi, unsigned int *lo)
- {
- __int64 ll;
- ll = (__int64)t * 10000000 + NANOSECS_BETWEEN_EPOCHS;
- *lo = (unsigned int)ll;
- *hi = (unsigned int)(ll >> 32);
- }
- time_t FileTimeToUnixTime(unsigned int hi, unsigned int lo)
- {
- time_t t = 0;
- FILETIME ft;
- ft.dwHighDateTime = hi;
- ft.dwLowDateTime = lo;
-
- if(FileTimeToUnixTime(ft, &t) != hrSuccess)
- return 0;
-
- return t;
- }
- static const LONGLONG UnitsPerMinute = 600000000;
- static const LONGLONG UnitsPerHalfMinute = 300000000;
- void RTimeToFileTime(LONG rtime, FILETIME *pft)
- {
-
- ULONGLONG q = rtime;
- q *= UnitsPerMinute;
- pft->dwLowDateTime = q & 0xFFFFFFFF;
- pft->dwHighDateTime = q >> 32;
- }
-
- void FileTimeToRTime(const FILETIME *pft, LONG *prtime)
- {
-
-
- ULONGLONG q = pft->dwHighDateTime;
- q <<= 32;
- q |= pft->dwLowDateTime;
- q += UnitsPerHalfMinute;
- q /= UnitsPerMinute;
- *prtime = q & 0x7FFFFFFF;
- }
- HRESULT RTimeToUnixTime(LONG rtime, time_t *unixtime)
- {
- FILETIME ft;
- if (unixtime == NULL)
- return MAPI_E_INVALID_PARAMETER;
- RTimeToFileTime(rtime, &ft);
- FileTimeToUnixTime(ft, unixtime);
- return hrSuccess;
- }
- HRESULT UnixTimeToRTime(time_t unixtime, LONG *rtime)
- {
- FILETIME ft;
- if (rtime == NULL)
- return MAPI_E_INVALID_PARAMETER;
- UnixTimeToFileTime(unixtime, &ft);
- FileTimeToRTime(&ft, rtime);
- return hrSuccess;
- }
-
- bool operator ==(const FILETIME &a, const FILETIME &b)
- {
- return a.dwLowDateTime == b.dwLowDateTime && a.dwHighDateTime == b.dwHighDateTime;
- }
- bool operator >(const FILETIME &a, const FILETIME &b)
- {
- return ((a.dwHighDateTime > b.dwHighDateTime) ||
- ((a.dwHighDateTime == b.dwHighDateTime) &&
- (a.dwLowDateTime > b.dwLowDateTime)));
- }
- bool operator >=(const FILETIME &a, const FILETIME &b)
- {
- return a > b || a == b;
- }
- bool operator <(const FILETIME &a, const FILETIME &b)
- {
- return ((a.dwHighDateTime < b.dwHighDateTime) ||
- ((a.dwHighDateTime == b.dwHighDateTime) &&
- (a.dwLowDateTime < b.dwLowDateTime)));
- }
- bool operator <=(const FILETIME &a, const FILETIME &b)
- {
- return a < b || a == b;
- }
- time_t operator -(const FILETIME &a, const FILETIME &b)
- {
- time_t aa, bb;
- FileTimeToUnixTime(a, &aa);
- FileTimeToUnixTime(b, &bb);
- return aa - bb;
- }
- #ifndef HAVE_TIMEGM
- time_t timegm(struct tm *t) {
- time_t convert;
- char *tz = NULL;
- char *s_tz = NULL;
- tz = getenv("TZ");
- if(tz)
- s_tz = strdup(tz);
-
-
- setenv("TZ", "UTC0", 1);
- tzset();
- convert = mktime(t);
- if (s_tz) {
- setenv("TZ", s_tz, 1);
- tzset();
- } else {
- unsetenv("TZ");
- tzset();
- }
- free(s_tz);
- return convert;
- }
- #endif
- struct tm* gmtime_safe(const time_t* timer, struct tm *result)
- {
- struct tm *tmp = NULL;
- tmp = gmtime_r(timer, result);
- if(tmp == NULL)
- memset(result, 0, sizeof(struct tm));
- return tmp;
- }
- double timespec2dbl(const struct timespec &t)
- {
- return (double)t.tv_sec + t.tv_nsec/1000000000.0;
- }
- struct timespec GetDeadline(unsigned int ulTimeoutMs)
- {
- struct timespec deadline;
- struct timeval now;
- gettimeofday(&now, NULL);
- now.tv_sec += ulTimeoutMs / 1000;
- now.tv_usec += 1000 * (ulTimeoutMs % 1000);
- if (now.tv_usec >= 1000000) {
- ++now.tv_sec;
- now.tv_usec -= 1000000;
- }
- deadline.tv_sec = now.tv_sec;
- deadline.tv_nsec = now.tv_usec * 1000;
- return deadline;
- }
- int CreatePath(const char *createpath)
- {
- struct stat s;
- char *path = strdup(createpath);
-
- size_t len = strlen(path);
- while (len > 0 && (path[len-1] == '/' || path[len-1] == '\\'))
- path[--len] = 0;
- if (stat(path, &s) == 0) {
- free(path);
- if (s.st_mode & S_IFDIR)
- return 0;
- return -1;
- }
-
-
- char *trail = strrchr(path, '/') > strrchr(path, '\\') ?
- strrchr(path, '/') : strrchr(path, '\\');
- if (trail == NULL) {
-
-
- free(path);
- return -1;
- }
- *trail = '\0';
- if (CreatePath(path) != 0) {
- free(path);
- return -1;
- }
-
- int ret = mkdir(createpath, 0700);
- free(path);
- return ret;
- }
- double GetTimeOfDay()
- {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return (double)tv.tv_sec + ((double)tv.tv_usec / 1000000);
- }
- void set_thread_name(pthread_t tid, const std::string & name)
- {
- #ifdef HAVE_PTHREAD_SETNAME_NP_2
- if (name.size() > 15)
- pthread_setname_np(tid, name.substr(0, 15).c_str());
- else
- pthread_setname_np(tid, name.c_str());
- #endif
- }
- ssize_t read_retry(int fd, void *data, size_t len)
- {
- auto buf = static_cast<char *>(data);
- size_t tread = 0;
- while (len > 0) {
- ssize_t ret = read(fd, buf, len);
- if (ret < 0 && (errno == EINTR || errno == EAGAIN))
- continue;
- if (ret < 0)
- return ret;
- if (ret == 0)
- break;
- len -= ret;
- buf += ret;
- tread += ret;
- }
- return tread;
- }
- ssize_t write_retry(int fd, const void *data, size_t len)
- {
- auto buf = static_cast<const char *>(data);
- size_t twrote = 0;
- while (len > 0) {
- ssize_t ret = write(fd, buf, len);
- if (ret < 0 && (errno == EINTR || errno == EAGAIN))
- continue;
- if (ret < 0)
- return ret;
- if (ret == 0)
- break;
- len -= ret;
- buf += ret;
- twrote += ret;
- }
- return twrote;
- }
- bool force_buffers_to_disk(const int fd)
- {
- return fsync(fd) != -1;
- }
- void my_readahead(const int fd)
- {
- #ifdef LINUX
- struct stat st;
- if (fstat(fd, &st) == 0)
- (void)readahead(fd, 0, st.st_size);
- #endif
- }
- void give_filesize_hint(const int fd, const off_t len)
- {
- #ifdef LINUX
-
-
-
-
- posix_fallocate(fd, 0, len);
- #endif
- }
- }
|