⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* util.c
 *
 * Copyright (c) 1996-2001 Mike Gleason, NCEMRSoft.
 * All rights reserved.
 *
 */

#include "syshdrs.h"

#if defined(WIN32) || defined(_WINDOWS)
#include <conio.h>
extern void GetSpecialDir(char *dst, size_t size, int whichDir);
#endif


static void *
Realloc(void *ptr, size_t siz)
{
	if (ptr == NULL)
		return (void *) malloc(siz);
	return ((void *) realloc(ptr, siz));
}	/* Realloc */


/* Use getcwd/getwd to get the full path of the current local
 * working directory.
 */
char *
FTPGetLocalCWD(char *buf, size_t size)
{
#ifdef HAVE_GETCWD
	static char *cwdBuf = NULL;
	static size_t cwdBufSize = 0;

	if (cwdBufSize == 0) {
		cwdBufSize = (size_t) 128;
		cwdBuf = (char *) malloc(cwdBufSize);
	}

	for (errno = 0; ; ) {
		if (cwdBuf == NULL) {
			return NULL;
		}

		if (getcwd(cwdBuf, cwdBufSize) != NULL)
			break;
		if (errno != ERANGE) {
			(void) Strncpy(buf, ".", size);
			return NULL;
		}
		cwdBufSize *= 2;
		cwdBuf = (char *) Realloc(cwdBuf, cwdBufSize);
	}

	return (Strncpy(buf, cwdBuf, size));
#else
#ifdef HAVE_GETWD
	static char *cwdBuf = NULL;
	char *dp;

	/* Due to the way getwd is usually implemented, it's
	 * important to have a buffer large enough to hold the
	 * whole thing.  getwd usually starts at the end of the
	 * buffer, and works backwards, returning you a pointer
	 * to the beginning of it when it finishes.
	 */
	if (size < MAXPATHLEN) {
		/* Buffer not big enough, so use a temporary one,
		 * and then copy the first 'size' bytes of the
		 * temporary buffer to your 'buf.'
		 */
		if (cwdBuf == NULL) {
			cwdBuf = (char *) malloc((size_t) MAXPATHLEN);
			if (cwdBuf == NULL) {
				return NULL;
			}
		}
		dp = cwdBuf;
	} else {
		/* Buffer is big enough already. */
		dp = buf;
	}
	*dp = '\0';
	if (getwd(dp) == NULL) {
		/* getwd() should write the reason why in the buffer then,
		 * according to the man pages.
		 */
		(void) Strncpy(buf, ".", size);
		return (NULL);
	}
	return (Strncpy(buf, dp, size));

#elif defined(WIN32) || defined(_WINDOWS)
	if (GetCurrentDirectory((DWORD) size - 1, buf) < 1)
		return NULL;
	buf[size - 1] = '\0';
	return buf;
#else
	/* Not a solution, but does anybody not have either of
	 * getcwd or getwd?
	 */
	--Error--;
#endif
#endif
}   /* GetCWD */



/* Read a line, and axe the end-of-line. */
char *
FGets(char *str, size_t size, FILE *fp)
{
	char *cp, *nlptr;

	cp = fgets(str, ((int) size) - 1, fp);
	if (cp != NULL) {
		cp[((int) size) - 1] = '\0';	/* ensure terminator */
		nlptr = cp + strlen(cp) - 1;
		if (*nlptr == '\n')
			*nlptr = '\0';
	} else {
		memset(str, 0, size);
	}
	return cp;
}	/* FGets */




#if defined(WIN32) || defined(_WINDOWS)

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 */

#endif




#if defined(WIN32) || defined(_WINDOWS)
#else
/* This looks up the user's password entry, trying to look by the username.
 * We have a couple of extra hacks in place to increase the probability
 * that we can get the username.
 */
struct passwd *
GetPwByName(void)
{
	char *cp;
	struct passwd *pw;

	cp = getlogin();
	if (cp == NULL) {
		cp = (char *) getenv("LOGNAME");
		if (cp == NULL)
			cp = (char *) getenv("USER");
	}
	pw = NULL;
	if (cp != NULL)
		pw = getpwnam(cp);
	return (pw);
}	/* GetPwByName */
#endif



char *
GetPass(const char *const prompt)
{
#ifdef HAVE_GETPASS
	return getpass(prompt);
#elif defined(_CONSOLE) && (defined(WIN32) || defined(_WINDOWS))
	static char pwbuf[128];
	char *dst, *dlim;
	int c;

	(void) memset(pwbuf, 0, sizeof(pwbuf));
	if (! _isatty(_fileno(stdout)))
		return (pwbuf);
	(void) fputs(prompt, stdout);
	(void) fflush(stdout);

	for (dst = pwbuf, dlim = dst + sizeof(pwbuf) - 1;;) {
		c = _getch();
		if ((c == 0) || (c == 0xe0)) {
			/* The key is a function or arrow key; read and discard. */
			(void) _getch();
		}
		if ((c == '\r') || (c == '\n'))
			break;
		if (dst < dlim)
			*dst++ = c;
	}
	*dst = '\0';

	(void) fflush(stdout);
	(void) fflush(stdin);
	return (pwbuf);
#else
	static char pwbuf[128];

	(void) memset(pwbuf, 0, sizeof(pwbuf));
#if defined(WIN32) || defined(_WINDOWS)
	if (! _isatty(_fileno(stdout)))
#else
	if (! isatty(1))
#endif
		return (pwbuf);
	(void) fputs(prompt, stdout);
	(void) fflush(stdout);
	(void) FGets(pwbuf, sizeof(pwbuf), stdin);
	(void) fflush(stdout);
	(void) fflush(stdin);
	return (pwbuf);
#endif
}	/* GetPass */




void
GetHomeDir(char *dst, size_t size)
{
#if defined(WIN32) || defined(_WINDOWS)
	const char *homedrive, *homepath;

	homedrive = getenv("HOMEDRIVE");
	homepath = getenv("HOMEPATH");
	if ((homedrive != NULL) && (homepath != NULL)) {
		(void) Strncpy(dst, homedrive, size);
		(void) Strncat(dst, homepath, size);
		return;
	}

//	GetSpecialDir(dst, size, CSIDL_PERSONAL	/* "My Documents" */);
//	if (dst[0] != '\0')
//		return;
//
//	dst[0] = '\0';
//	if (GetWindowsDirectory(dst, size - 1) < 1)
//		(void) Strncpy(dst, ".", size);
//	else if (dst[1] == ':') {
//		dst[2] = '\\';
//		dst[3] = '\0';
//	}
#else
	const char *cp;
	struct passwd *pw;

	pw = NULL;
#if defined(USE_GETPWUID)
	/* Try to use getpwuid(), but if we have to, fall back to getpwnam(). */
	if ((pw = getpwuid(getuid())) == NULL)
		pw = GetPwByName();	/* Oh well, try getpwnam() then. */
#else
	/* Try to use getpwnam(), but if we have to, fall back to getpwuid(). */
	if ((pw = GetPwByName()) == NULL)
		pw = getpwuid(getuid());	/* Try getpwnam() then. */
#endif
	if (pw != NULL)
		cp = pw->pw_dir;
	else if ((cp = (const char *) getenv("LOGNAME")) == NULL)
			cp = ".";
	(void) Strncpy(dst, cp, size);
#endif
}	/* GetHomeDir */




void
GetUsrName(char *dst, size_t size)
{
#if defined(WIN32) || defined(_WINDOWS)
	DWORD size1;

	size1 = size - 1;
	if (! GetUserName(dst, &size1))
		(void) strncpy(dst, "unknown", size);
	dst[size - 1] = '\0';
#else
	const char *cp;
	struct passwd *pw;

	pw = NULL;
#ifdef USE_GETPWUID
	/* Try to use getpwuid(), but if we have to, fall back to getpwnam(). */
	if ((pw = getpwuid(getuid())) == NULL)
		pw = GetPwByName();	/* Oh well, try getpwnam() then. */
#else
	/* Try to use getpwnam(), but if we have to, fall back to getpwuid(). */
	if ((pw = GetPwByName()) == NULL)
		pw = getpwuid(getuid());	/* Try getpwnam() then. */
#endif
	if (pw != NULL)
		cp = pw->pw_name;
	else if ((cp = (const char *) getenv("LOGNAME")) == NULL)
			cp = "UNKNOWN";
	(void) Strncpy(dst, cp, size);
#endif
}	/* GetUserName */





/* Closes the file supplied, if it isn't a std stream. */
void
CloseFile(FILE **f)
{
	if (*f != NULL) {
		if ((*f != stdout) && (*f != stdin) && (*f != stderr))
			(void) fclose(*f);
		*f = NULL;
	}
}	/* CloseFile */



/*VARARGS*/
void
PrintF(const FTPCIPtr cip, const char *const fmt, ...)
{
	va_list ap;
	char buf[256];

	va_start(ap, fmt);
	if (cip->debugLog != NULL) {
		(void) vfprintf(cip->debugLog, fmt, ap);
		(void) fflush(cip->debugLog);
	}
	if (cip->debugLogProc != NULL) {
#ifdef HAVE_VSNPRINTF
		(void) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
		buf[sizeof(buf) - 1] = '\0';
#else
		(void) vsprintf(buf, fmt, ap);
#endif
		(*cip->debugLogProc)(cip, buf);
	}
	va_end(ap);
}	/* PrintF */





/*VARARGS*/
void
Error(const FTPCIPtr cip, const int pError, const char *const fmt, ...)
{
	va_list ap;
	int errnum;
	size_t len;
	char buf[256];
	int endsinperiod;
	int endsinnewline;
#ifndef HAVE_STRERROR
	char errnostr[16];
#endif

	errnum = errno;
	va_start(ap, fmt);
#ifdef HAVE_VSNPRINTF
	vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
	buf[sizeof(buf) - 1] = '\0';
#else
	(void) vsprintf(buf, fmt, ap);
#endif
	va_end(ap);

	if (pError != 0) {
		len = strlen(buf);
		endsinperiod = 0;
		endsinnewline = 0;
		if (len > 2) {
			if (buf[len - 1] == '\n') {
				endsinnewline = 1;
				buf[len - 1] = '\0';
				if (buf[len - 2] == '.') {
					endsinperiod = 1;
					buf[len - 2] = '\0';
				}
			} else if (buf[len - 1] == '.') {
				endsinperiod = 1;
				buf[len - 1] = '\0';
			}
		}
#ifdef HAVE_STRERROR
		(void) STRNCAT(buf, ": ");
		(void) STRNCAT(buf, strerror(errnum));
#else
#	ifdef HAVE_SNPRINTF
		sprintf(errnostr, sizeof(errnostr) - 1, " (errno = %d)", errnum);
		errnostr[sizeof(errnostr) - 1] = '\0';
#	else
		sprintf(errnostr, " (errno = %d)", errnum);
#	endif
		STRNCAT(buf, errnostr);
#endif
		if (endsinperiod != 0)
			(void) STRNCAT(buf, ".");
		if (endsinnewline != 0)
			(void) STRNCAT(buf, "\n");
	}

	if (cip->errLog != NULL) {
		(void) fprintf(cip->errLog, "%s", buf);
		(void) fflush(cip->errLog);
	}
	if ((cip->debugLog != NULL) && (cip->debugLog != cip->errLog)) {
		if ((cip->errLog != stderr) || (cip->debugLog != stdout)) {
			(void) fprintf(cip->debugLog, "%s", buf);
			(void) fflush(cip->debugLog);
		}
	}
	if (cip->errLogProc != NULL) {
		(*cip->errLogProc)(cip, buf);
	}
	if ((cip->debugLogProc != NULL) && (cip->debugLogProc != cip->errLogProc)) {
		(*cip->debugLogProc)(cip, buf);
	}
}	/* Error */




/* Cheezy, but somewhat portable way to get GMT offset. */
#ifdef HAVE_MKTIME
static
time_t GetUTCOffset(int mon, int mday)
{
	struct tm local_tm, utc_tm, *utc_tmptr;
	time_t local_t, utc_t, utcOffset;

	ZERO(local_tm);
	ZERO(utc_tm);
	utcOffset = 0;

	local_tm.tm_year = 94;	/* Doesn't really matter. */
	local_tm.tm_mon = mon;
	local_tm.tm_mday = mday;
	local_tm.tm_hour = 12;
	local_tm.tm_isdst = -1;
	local_t = mktime(&local_tm);

	if (local_t != (time_t) -1) {
		utc_tmptr = gmtime(&local_t);
		utc_tm.tm_year = utc_tmptr->tm_year;
		utc_tm.tm_mon = utc_tmptr->tm_mon;
		utc_tm.tm_mday = utc_tmptr->tm_mday;
		utc_tm.tm_hour = utc_tmptr->tm_hour;
		utc_tm.tm_isdst = -1;
		utc_t = mktime(&utc_tm);

		if (utc_t != (time_t) -1)
			utcOffset = (local_t - utc_t);
	}
	return (utcOffset);
}	/* GetUTCOffset */
#endif	/* HAVE_MKTIME */



/* Converts a MDTM date, like "19930602204445"
 * format to a time_t.
 */
time_t UnMDTMDate(char *dstr)
{
#ifndef HAVE_MKTIME
	return (kModTimeUnknown);
#else
	struct tm ut, *t;
	time_t mt, now;
	time_t result = kModTimeUnknown;

	if (strncmp(dstr, "19100", 5) == 0) {
		/* Server Y2K bug! */
		return (result);
	}

	(void) time(&now);
	t = localtime(&now);

	/* Copy the whole structure of the 'tm' pointed to by t, so it will
	 * also set all fields we don't specify explicitly to be the same as
	 * they were in t.  That way we copy non-standard fields such as
	 * tm_gmtoff, if it exists or not.
	 */
	ut = *t;

	/* The time we get back from the server is (should be) in UTC. */
	if (sscanf(dstr, "%04d%02d%02d%02d%02d%02d",
		&ut.tm_year,
		&ut.tm_mon,
		&ut.tm_mday,
		&ut.tm_hour,
		&ut.tm_min,
		&ut.tm_sec) == 6)
	{
		--ut.tm_mon;
		ut.tm_year -= 1900;
		mt = mktime(&ut);
		if (mt != (time_t) -1) {
			mt += GetUTCOffset(ut.tm_mon, ut.tm_mday);
			result = (time_t) mt;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -