/* u_misc.c
*
* Copyright (c) 1996-2005 Mike Gleason, NcFTP Software.
* All rights reserved.
*
*/
#include "syshdrs.h"
#ifdef PRAGMA_HDRSTOP
# pragma hdrstop
#endif
static int wsaInit = 0;
#if defined(WIN32) || defined(_WINDOWS)
WSADATA wsaData;
#endif
void
InitWinsock(void)
{
#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
# ifdef _CONSOLE
fprintf(stderr, "could not initialize winsock\n");
# endif
exit(1);
}
#endif
wsaInit++;
} /* InitWinsock */
void
DisposeWinsock(void)
{
#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
if (wsaInit > 0) { WSACleanup(); wsaInit--; }
#else
wsaInit--;
#endif
} /* DisposeWinsock */
#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
int gettimeofday(struct timeval *const tp, void *junk)
{
SYSTEMTIME systemTime;
GetSystemTime(&systemTime);
/* Create an arbitrary second counter;
* Note that this particular one creates
* a problem at the end of the month.
*/
tp->tv_sec =
systemTime.wSecond +
systemTime.wMinute * 60 +
systemTime.wHour * 3600 +
systemTime.wDay * 86400;
tp->tv_usec = systemTime.wMilliseconds * 1000;
return 0;
} /* gettimeofday */
void WinSleep(unsigned int seconds)
{
DWORD now, deadline;
DWORD milliseconds = seconds * 1000;
if (milliseconds > 0) {
now = GetTickCount();
deadline = now + milliseconds;
if (now < deadline) {
/* Typical case */
do {
milliseconds = deadline - now;
Sleep(milliseconds);
now = GetTickCount();
} while (now < deadline);
} else {
/* Overflow case */
deadline = now - 1;
milliseconds -= (0xFFFFFFFF - now);
do {
Sleep(0xFFFFFFFF - now);
now = GetTickCount();
} while (now > deadline);
/* Counter has now wrapped around */
deadline = now + milliseconds;
do {
milliseconds = deadline - now;
Sleep(milliseconds);
now = GetTickCount();
} while (now < deadline);
}
}
} /* WinSleep */
#endif
#if defined(WIN32) || defined(_WINDOWS) || defined(__CYGWIN__)
char *
StrFindLocalPathDelim(const char *src) /* TODO: optimize */
{
const char *first;
int c;
first = NULL;
for (;;) {
c = *src++;
if (c == '\0')
break;
if (IsLocalPathDelim(c)) {
first = src - 1;
break;
}
}
return ((char *) first);
} /* StrFindLocalPathDelim */
char *
StrRFindLocalPathDelim(const char *src) /* TODO: optimize */
{
const char *last;
int c;
last = NULL;
for (;;) {
c = *src++;
if (c == '\0')
break;
if (IsLocalPathDelim(c))
last = src - 1;
}
return ((char *) last);
} /* StrRFindLocalPathDelim */
void
StrRemoveTrailingLocalPathDelim(char *dst)
{
char *cp;
cp = StrRFindLocalPathDelim(dst);
if ((cp == NULL) || (cp[1] != '\0'))
return;
/* Note: Do not destroy a path of "/" */
while ((cp > dst) && (IsLocalPathDelim(*cp)))
*cp-- = '\0';
} /* StrRemoveTrailingLocalPathDelim */
void
TVFSPathToLocalPath(char *dst)
{
int c;
/* Note: Technically we don't need to do this,
* since Win32 accepts a / as equivalent to a \
* in a pathname.
*/
if (dst != NULL) {
for (;;) {
c = *dst++;
if (c == '\0')
break;
if (c == '/')
dst[-1] = LOCAL_PATH_DELIM;
}
}
} /* TVFSPathToLocalPath */
void
LocalPathToTVFSPath(char *dst)
{
int c;
if (dst != NULL) {
for (;;) {
c = *dst++;
if (c == '\0')
break;
if (c == LOCAL_PATH_DELIM)
dst[-1] = '/';
}
}
} /* LocalPathToTVFSPath */
#endif
#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
int
WinFStat64(const int h0, struct WinStat64 *const stp)
{
HANDLE h;
__int64 fSize;
DWORD fSize1, fSize2;
struct _stat st32;
DWORD winErr;
h = (HANDLE) _get_osfhandle(h0);
if (h == INVALID_HANDLE_VALUE)
return (-1);
memset(stp, 0, sizeof(struct WinStat64));
if (_fstat(h0, &st32) < 0)
return (-1);
stp->st_atime = st32.st_atime;
stp->st_ctime = st32.st_ctime;
stp->st_dev = st32.st_dev;
stp->st_gid = st32.st_gid;
stp->st_ino = st32.st_ino;
stp->st_mode = st32.st_mode;
stp->st_mtime = st32.st_mtime;
stp->st_nlink = st32.st_nlink;
stp->st_rdev = st32.st_rdev;
stp->st_uid = st32.st_uid;
if (S_ISREG(stp->st_mode)) {
fSize = (_int64)0;
fSize1 = GetFileSize(h, &fSize2);
if ((fSize1 == 0xFFFFFFFF) && ((winErr = GetLastError()) != NO_ERROR))
goto return_err;
fSize = ((__int64) fSize2 << 32) | (__int64) fSize1;
stp->st_size = fSize;
}
return (0);
return_err:
stp->st_size = (__int32) st32.st_size;
if ((winErr = GetLastError()) == ERROR_SHARING_VIOLATION) {
errno = EBUSY;
} else if ((winErr == ERROR_PATH_NOT_FOUND) || (winErr == ERROR_FILE_NOT_FOUND)) {
errno = ENOENT;
} else if (winErr == ERROR_INVALID_PARAMETER) {
errno = EINVAL;
} else {
errno = 100000 + winErr;
}
return (-1);
} /* WinFStat64 */
int
WinStat64(const char *const path, struct WinStat64 *const stp)
{
HANDLE h;
__int64 fSize;
DWORD fSize1, fSize2;
struct _stat st32;
DWORD winErr;
memset(stp, 0, sizeof(struct WinStat64));
if (_stat(path, &st32) < 0)
return (-1);
stp->st_atime = st32.st_atime;
stp->st_ctime = st32.st_ctime;
stp->st_dev = st32.st_dev;
stp->st_gid = st32.st_gid;
stp->st_ino = st32.st_ino;
stp->st_mode = st32.st_mode;
stp->st_mtime = st32.st_mtime;
stp->st_nlink = st32.st_nlink;
stp->st_rdev = st32.st_rdev;
stp->st_uid = st32.st_uid;
if (S_ISREG(stp->st_mode)) {
h = CreateFile(path,
0, /* Not GENERIC_READ; use 0 for "query attributes only" mode */
0,
NULL,
OPEN_EXISTING, /* fails if it doesn't exist */
0,
NULL
);
if (h == INVALID_HANDLE_VALUE)
goto return_err;
fSize = (_int64)0;
fSize1 = GetFileSize(h, &fSize2);
if ((fSize1 == 0xFFFFFFFF) && ((winErr = GetLastError()) != NO_ERROR))
goto return_err;
fSize = ((__int64) fSize2 << 32) | (__int64) fSize1;
stp->st_size = fSize;
CloseHandle(h);
}
return (0);
return_err:
stp->st_size = (__int32) st32.st_size;
if ((winErr = GetLastError()) == ERROR_SHARING_VIOLATION) {
errno = EBUSY;
} else if ((winErr == ERROR_PATH_NOT_FOUND) || (winErr == ERROR_FILE_NOT_FOUND)) {
errno = ENOENT;
} else if (winErr == ERROR_INVALID_PARAMETER) {
errno = EINVAL;
} else {
errno = 100000 + winErr;
}
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
return (-1);
} /* WinStat64 */
#endif
syntax highlighted by Code2HTML, v. 0.9.1