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

📄 util.c

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

#include "syshdrs.h"
#include "shell.h"
#include "trace.h"
#include "util.h"

uid_t gUid;
char gUser[32];
char gHome[256];
char gShell[256];
char gOurDirectoryPath[260];
char gOurInstallationPath[260];
#ifdef ncftp
static int gResolveSig;
#endif

#if defined(WIN32) || defined(_WINDOWS)
#elif defined(HAVE_SIGSETJMP)
sigjmp_buf gGetHostByNameJmp;
#else	/* HAVE_SIGSETJMP */
jmp_buf gGetHostByNameJmp;
#endif	/* HAVE_SIGSETJMP */

#ifndef HAVE_MEMMOVE
void *memmove(void *dst0, void *src0, size_t length);
#endif

static const unsigned char B64EncodeTable[64] =
{
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
	'w', 'x', 'y', 'z', '0', '1', '2', '3',
	'4', '5', '6', '7', '8', '9', '+', '/'
};

static const unsigned char B64DecodeTable[256] =
{
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 000-007 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 010-017 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 020-027 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 030-037 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 040-047 */
	'\177', '\177', '\177', '\76', '\177', '\177', '\177', '\77',	/* 050-057 */
	'\64', '\65', '\66', '\67', '\70', '\71', '\72', '\73',		/* 060-067 */
	'\74', '\75', '\177', '\177', '\177', '\100', '\177', '\177',	/* 070-077 */
	'\177', '\0', '\1', '\2', '\3', '\4', '\5', '\6',	/* 100-107 */
	'\7', '\10', '\11', '\12', '\13', '\14', '\15', '\16',	/* 110-117 */
	'\17', '\20', '\21', '\22', '\23', '\24', '\25', '\26',		/* 120-127 */
	'\27', '\30', '\31', '\177', '\177', '\177', '\177', '\177',	/* 130-137 */
	'\177', '\32', '\33', '\34', '\35', '\36', '\37', '\40',	/* 140-147 */
	'\41', '\42', '\43', '\44', '\45', '\46', '\47', '\50',		/* 150-157 */
	'\51', '\52', '\53', '\54', '\55', '\56', '\57', '\60',		/* 160-167 */
	'\61', '\62', '\63', '\177', '\177', '\177', '\177', '\177',	/* 170-177 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 200-207 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 210-217 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 220-227 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 230-237 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 240-247 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 250-257 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 260-267 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 270-277 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 300-307 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 310-317 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 320-327 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 330-337 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 340-347 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 350-357 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 360-367 */
	'\177', '\177', '\177', '\177', '\177', '\177', '\177', '\177',		/* 370-377 */
};

void
ToBase64(void *dst0, const void *src0, size_t n, int terminate)
{
	unsigned char *dst;
	const unsigned char *src, *srclim;
	unsigned int c0, c1, c2;
	unsigned int ch;

	src = src0;
	srclim = src + n;
	dst = dst0;

	while (src < srclim) {
		c0 = *src++;
		if (src < srclim) {
			c1 = *src++;
		} else {
			c1 = 0;
		}
		if (src < srclim) {
			c2 = *src++;
		} else {
			c2 = 0;
		}

		ch = c0 >> 2;
		dst[0] = B64EncodeTable[ch & 077];

		ch = ((c0 << 4) & 060) | ((c1 >> 4) & 017);
		dst[1] = B64EncodeTable[ch & 077];

		ch = ((c1 << 2) & 074) | ((c2 >> 6) & 03);
		dst[2] = B64EncodeTable[ch & 077];

		ch = (c2 & 077);
		dst[3] = B64EncodeTable[ch & 077];

		dst += 4;
	}
	if (terminate != 0)
		*dst = '\0';
}						       /* ToBase64 */



void
FromBase64(void *dst0, const void *src0, size_t n, int terminate)
{
	unsigned char *dst;
	const unsigned char *src, *srclim;
	unsigned int c0, c1, c2, c3;
	unsigned int ch;

	src = src0;
	srclim = src + n;
	dst = dst0;

	while (src < srclim) {
		c0 = *src++;
		if (src < srclim) {
			c1 = *src++;
		} else {
			c1 = 0;
		}
		if (src < srclim) {
			c2 = *src++;
		} else {
			c2 = 0;
		}
		if (src < srclim) {
			c3 = *src++;
		} else {
			c3 = 0;
		}

		ch = (((unsigned int) B64DecodeTable[c0]) << 2) | (((unsigned int) B64DecodeTable[c1]) >> 4);
		dst[0] = (unsigned char) ch;

		ch = (((unsigned int) B64DecodeTable[c1]) << 4) | (((unsigned int) B64DecodeTable[c2]) >> 2);
		dst[1] = (unsigned char) ch;

		ch = (((unsigned int) B64DecodeTable[c2]) << 6) | (((unsigned int) B64DecodeTable[c3]));
		dst[2] = (unsigned char) ch;

		dst += 3;
	}
	if (terminate != 0)
		*dst = '\0';
}						       /* FromBase64 */

/* This should only be called if the program wouldn't function
 * usefully without the memory requested.
 */
void
OutOfMemory(void)
{
	(void) fprintf(stderr, "Out of memory!\n");
	exit(1);
}	/* OutOfMemory */



void
MyInetAddr(char *dst, size_t siz, char **src, int i)
{
	struct in_addr *ia;
#ifndef HAVE_INET_NTOP
	char *cp;
#endif

	(void) Strncpy(dst, "???", siz);
	if (src != (char **) 0) {
		ia = (struct in_addr *) src[i];
#ifdef HAVE_INET_NTOP	/* Mostly to workaround bug in IRIX 6.5's inet_ntoa */
		(void) inet_ntop(AF_INET, ia, dst, siz - 1);
#else
		cp = inet_ntoa(*ia);
		if ((cp != (char *) 0) && (cp != (char *) -1) && (cp[0] != '\0'))
			(void) Strncpy(dst, cp, siz);
#endif
	}
}	/* MyInetAddr */




/* On entry, you should have 'host' be set to a symbolic name (like
 * cse.unl.edu), or set to a numeric address (like 129.93.3.1).
 * If the function fails, it will return NULL, but if the host was
 * a numeric style address, you'll have the ip_address to fall back on.
 */

struct hostent *
GetHostEntry(const char *host, struct in_addr *ip_address)
{
	struct in_addr ip;
	struct hostent *hp;

	/* See if the host was given in the dotted IP format, like "36.44.0.2."
	 * If it was, inet_addr will convert that to a 32-bit binary value;
	 * it not, inet_addr will return (-1L).
	 */
	ip.s_addr = inet_addr(host);
	if (ip.s_addr != INADDR_NONE) {
		hp = gethostbyaddr((char *) &ip, (int) sizeof(ip), AF_INET);
	} else {
		/* No IP address, so it must be a hostname, like ftp.wustl.edu. */
		hp = gethostbyname(host);
		if (hp != NULL)
			ip = * (struct in_addr *) hp->h_addr_list;
	}
	if (ip_address != NULL)
		*ip_address = ip;
	return (hp);
}	/* GetHostEntry */



/* This simplifies a pathname, by converting it to the
 * equivalent of "cd $dir ; dir=`pwd`".  In other words,
 * if $PWD==/usr/spool/uucp, and you had a path like
 * "$PWD/../tmp////./../xx/", it would be converted to
 * "/usr/spool/xx".
 */
void
CompressPath(char *const dst, const char *const src, const size_t dsize)
{
	int c;
	const char *s;
	char *d, *lim;
	char *a, *b;

	if (src[0] == '\0') {
		*dst = '\0';
		return;
	}

	s = src;
	d = dst;
	lim = d + dsize - 1;	/* leave room for nul byte. */
	for (;;) {
		c = *s;
		if (c == '.') {
			if (((s == src) || (s[-1] == '/')) && ((s[1] == '/') || (s[1] == '\0'))) {
				/* Don't copy "./" */
				if (s[1] == '/')
					++s;
				++s;
			} else if (d < lim) {
				*d++ = *s++;
			} else {
				++s;
			}
		} else if (c == '/') {
			/* Don't copy multiple slashes. */
			if (d < lim)
				*d++ = *s++;
			else
				++s;
			for (;;) {
				c = *s;
				if (c == '/') {
					/* Don't copy multiple slashes. */
					++s;
				} else if (c == '.') {
					c = s[1];
					if (c == '/') {
						/* Skip "./" */
						s += 2;
					} else if (c == '\0') {
						/* Skip "./" */
						s += 1;
					} else {
						break;
					}
				} else {
					break;
				}
			}
		} else if (c == '\0') {
			/* Remove trailing slash. */
			if ((d[-1] == '/') && (d > (dst + 1)))
				d[-1] = '\0';
			*d = '\0';
			break;
		} else if (d < lim) {
			*d++ = *s++;
		} else {
			++s;
		}
	}
	a = dst;

	/* fprintf(stderr, "<%s>\n", dst); */
	/* Go through and remove .. in the path when we know what the
	 * parent directory is.  After we get done with this, the only
	 * .. nodes in the path will be at the front.
	 */
	while (*a != '\0') {
		b = a;
		for (;;) {
			/* Get the next node in the path. */
			if (*a == '\0')
				return;
			if (*a == '/') {
				++a;
				break;
			}
			++a;
		}
		if ((b[0] == '.') && (b[1] == '.')) {
			if (b[2] == '/') {
				/* We don't know what the parent of this
				 * node would be.
				 */
				continue;
			}
		}
		if ((a[0] == '.') && (a[1] == '.')) {
			if (a[2] == '/') {
				/* Remove the .. node and the one before it. */
				if ((b == dst) && (*dst == '/'))
					(void) memmove(b + 1, a + 3, strlen(a + 3) + 1);
				else
					(void) memmove(b, a + 3, strlen(a + 3) + 1);
				a = dst;	/* Start over. */
			} else if (a[2] == '\0') {
				/* Remove a trailing .. like:  /aaa/bbb/.. */
				if ((b <= dst + 1) && (*dst == '/'))
					dst[1] = '\0';
				else
					b[-1] = '\0';
				a = dst;	/* Start over. */
			} else {
				/* continue processing this node.
				 * It is probably some bogus path,
				 * like ".../", "..foo/", etc.
				 */
			}
		}
	}
}	/* CompressPath */



void
PathCat(char *const dst, const size_t dsize, const char *const cwd, const char *const src)
{
	char *cp;
	char tmp[512];

	if (src[0] == '/') {
		CompressPath(dst, src, dsize);
		return;
	}
	cp = Strnpcpy(tmp, (char *) cwd, sizeof(tmp) - 1);
	*cp++ = '/';
	*cp = '\0';
	(void) Strnpcat(cp, (char *) src, sizeof(tmp) - (cp - tmp));
	CompressPath(dst, tmp, dsize);
}	/* PathCat */



char *
FileToURL(char *url, size_t urlsize, const char *const fn, const char *const rcwd, const char *const startdir, const char *const user, const char *const pass, const char *const hname, const unsigned int port)
{
	size_t ulen, dsize;
	char *dst, pbuf[32];
	int isUser;

	/* //<user>:<password>@<host>:<port>/<url-path> */
	/* Note that if an absolute path is given,
	 * you need to escape the first entry, i.e. /pub -> %2Fpub
	 */
	(void) Strncpy(url, "ftp://", urlsize);
	isUser = 0;
	if ((user != NULL) && (user[0] != '\0') && (strcmp(user, "anonymous") != 0) && (strcmp(user, "ftp") != 0)) {
		isUser = 1;
		(void) Strncat(url, user, urlsize);
		if ((pass != NULL) && (pass[0] != '\0')) {
			(void) Strncat(url, ":", urlsize);
			(void) Strncat(url, "PASSWORD", urlsize);
		}
		(void) Strncat(url, "@", urlsize);
	}
	(void) Strncat(url, hname, urlsize);
	if ((port != 21) && (port != 0)) {
		(void) sprintf(pbuf, ":%u", (unsigned int) port);
		(void) Strncat(url, pbuf, urlsize);
	}

	ulen = strlen(url);
	dst = url + ulen;
	dsize = urlsize - ulen;
	PathCat(dst, dsize, rcwd, fn);
	if ((startdir != NULL) && (startdir[0] != '\0') && (startdir[1] /* i.e. not "/" */ != '\0')) {
		if (strncmp(dst, startdir, strlen(startdir)) == 0) {
			/* Form relative URL. */
			memmove(dst, dst + strlen(startdir), strlen(dst) - strlen(startdir) + 1);
		} else if (isUser != 0) {
			/* Absolute URL, but different from start dir.
			 * Make sure to use %2f as first slash so that
			 * the translation uses "/pub" instead of "pub"
			 * since the / characters are just delimiters.
			 */
			dst[dsize - 1] = '\0';
			dst[dsize - 2] = '\0';
			dst[dsize - 3] = '\0';
			dst[dsize - 4] = '\0';
			memmove(dst + 4, dst + 1, strlen(dst + 1));
			dst[0] = '/';
			dst[1] = '%';
			dst[2] = '2';
			dst[3] = 'F';
		}
	}

	return (url);
}	/* FileToURL */




/* This will abbreviate a string so that it fits into max characters.
 * It will use ellipses as appropriate.  Make sure the string has
 * at least max + 1 characters allocated for it.
 */
void
AbbrevStr(char *dst, const char *src, size_t max, int mode)
{
	int len;

	len = (int) strlen(src);
	if (len > (int) max) {
		if (mode == 0) {
			/* ...Put ellipses at left */
			(void) strcpy(dst, "...");
			(void) Strncat(dst, (char *) src + len - (int) max + 3, max + 1);
		} else {
			/* Put ellipses at right... */
			(void) Strncpy(dst, (char *) src, max + 1);
			(void) strcpy(dst + max - 3, "...");
		}
	} else {
		(void) Strncpy(dst, (char *) src, max + 1);
	}
}	/* AbbrevStr */




char *
Path(char *const dst, const size_t siz, const char *const parent, const char *const fname)
{
	(void) Strncpy(dst, parent, siz);
	(void) Strncat(dst, LOCAL_PATH_DELIM_STR, siz);
	return (Strncat(dst, fname, siz));
}	/* Path */




char *
OurDirectoryPath(char *const dst, const size_t siz, const char *const fname)
{
	return (Path(dst, siz, gOurDirectoryPath, fname));
}	/* OurDirectoryPath */



char *
OurInstallationPath(char *const dst, const size_t siz, const char *const fname)
{
	return (Path(dst, siz, gOurInstallationPath, fname));
}	/* OurInstallationPath */




/* Create, if necessary, a directory in the user's home directory to
 * put our incredibly important stuff in.
 */
void
InitOurDirectory(void)
{
#if defined(WIN32) || defined(_WINDOWS)
	DWORD dwType, dwSize;
	HKEY hkey;
	char *cp;
	int rc;

	ZeroMemory(gOurDirectoryPath, (DWORD) sizeof(gOurDirectoryPath));
	ZeroMemory(gOurInstallationPath, (DWORD) sizeof(gOurInstallationPath));

	if (RegOpenKeyEx(
		HKEY_LOCAL_MACHINE,
		"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\ncftp.exe",
		(DWORD) 0,
		KEY_QUERY_VALUE,
		&hkey) == ERROR_SUCCESS)
	{
		dwSize = (DWORD) (sizeof(gOurInstallationPath) - 1);
		dwType = 0;
		if (RegQueryValueEx(
			hkey,
			NULL,
			(DWORD *) 0,
			&dwType,
			(LPBYTE) gOurInstallationPath,
			&dwSize) == ERROR_SUCCESS)
		{
			// This gave us the path to ncftp.exe;
			// But we use a subdirectory in that directory.
			//
			cp = StrRFindLocalPathDelim(gOurInstallationPath);
			if (cp == NULL)
				ZeroMemory(gOurInstallationPath, (DWORD) sizeof(gOurInstallationPath));
			else
				ZeroMemory(cp, (DWORD) (cp - gOurInstallationPath));
		}
		RegCloseKey(hkey);
	}

	if (gOurInstallationPath[0] == '\0') {
		if (GetModuleFileName(NULL, gOurInstallationPath, (DWORD) sizeof(gOurInstallationPath) - 1) <= 0) {
			ZeroMemory(gOurInstallationPath, (DWORD) sizeof(gOurInstallationPath));
		} else {
			// This gave us the path to the current .exe;
			// But we use a subdirectory in that directory.
			//
			cp = StrRFindLocalPathDelim(gOurInstallationPath);
			if (cp == NULL)
				ZeroMemory(gOurInstallationPath, (DWORD) sizeof(gOurInstallationPath));
			else
				ZeroMemory(cp, (DWORD) (cp - gOurInstallationPath));
		}
	}

	if (gOurInstallationPath[0] != '\0') {
		if ((cp = getenv("NCFTPDIR")) != NULL) {
			if (*cp == '"')
				cp++;
			(void) STRNCPY(gOurDirectoryPath, cp);
			cp = strrchr(gOurDirectoryPath, '"');
			if ((cp != NULL) && (cp[1] == '\0'))
				*cp = '\0';
		} else if ((cp = getenv("HOME")) != NULL) {
			if (*cp == '"')

⌨️ 快捷键说明

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