📄 util.c
字号:
cp++;
(void) STRNCPY(gOurDirectoryPath, cp);
cp = strrchr(gOurDirectoryPath, '"');
if ((cp != NULL) && (cp[1] == '\0'))
*cp = '\0';
} else {
STRNCPY(gOurDirectoryPath, gOurInstallationPath);
if (gUser[0] == '\0') {
STRNCAT(gOurDirectoryPath, "\\Users\\default");
} else {
STRNCAT(gOurDirectoryPath, "\\Users\\");
STRNCAT(gOurDirectoryPath, gUser);
}
}
rc = MkDirs(gOurDirectoryPath, 00755);
}
#else
struct stat st;
char *cp;
#ifdef BINDIR
(void) STRNCPY(gOurInstallationPath, BINDIR);
#else
memset(gOurInstallationPath, 0, sizeof(gOurInstallationPath));
#endif
cp = getenv("NCFTPDIR");
if (cp != NULL) {
(void) STRNCPY(gOurDirectoryPath, cp);
} else if (STREQ(gHome, "/")) {
/* Don't create it if you're root and your home directory
* is the root directory.
*
* If you are root and you want to store your ncftp
* config files, move your home directory somewhere else,
* such as /root or /home/root.
*/
gOurDirectoryPath[0] = '\0';
return;
} else {
(void) Path(gOurDirectoryPath,
sizeof(gOurDirectoryPath),
gHome,
kOurDirectoryName
);
}
if (stat(gOurDirectoryPath, &st) < 0) {
if (mkdir(gOurDirectoryPath, 00755) < 0) {
gOurDirectoryPath[0] = '\0';
}
}
#endif
} /* InitOurDirectory */
void
InitUserInfo(void)
{
#if defined(WIN32) || defined(_WINDOWS)
DWORD nSize;
char *cp;
memset(gUser, 0, sizeof(gUser));
nSize = sizeof(gUser) - 1;
if (! GetUserName(gUser, &nSize))
STRNCPY(gUser, "default");
memset(gHome, 0, sizeof(gHome));
(void) GetTempPath((DWORD) sizeof(gHome) - 1, gHome);
cp = strrchr(gHome, '\\');
if ((cp != NULL) && (cp[1] == '\0'))
*cp = '\0';
memset(gShell, 0, sizeof(gShell));
#else
struct passwd *pwptr;
char *envp;
gUid = geteuid();
pwptr = getpwuid(gUid);
if (pwptr == NULL) {
envp = getenv("LOGNAME");
if (envp == NULL) {
(void) fprintf(stderr, "Who are you?\n");
(void) fprintf(stderr, "You have a user id number of %d, but no username associated with it.\n", (int) gUid);
(void) STRNCPY(gUser, "unknown");
} else {
(void) STRNCPY(gUser, envp);
}
envp = getenv("HOME");
if (envp == NULL)
(void) STRNCPY(gHome, "/");
else
(void) STRNCPY(gHome, envp);
envp = getenv("SHELL");
if (envp == NULL)
(void) STRNCPY(gShell, "/bin/sh");
else
(void) STRNCPY(gShell, envp);
} else {
/* Copy home directory. */
(void) STRNCPY(gHome, pwptr->pw_dir);
/* Copy user name. */
(void) STRNCPY(gUser, pwptr->pw_name);
/* Copy shell. */
(void) STRNCPY(gShell, pwptr->pw_shell);
}
#endif
InitOurDirectory();
} /* InitUserInfo */
int
MayUseFirewall(const char *const hn, int firewallType, const char *const firewallExceptionList)
{
#ifdef HAVE_STRSTR
char buf[256];
char *tok;
char *parse;
#endif /* HAVE_STRSTR */
if (firewallType == kFirewallNotInUse)
return (0);
if (firewallExceptionList[0] == '\0') {
if (strchr(hn, '.') == NULL) {
/* Unqualified host name,
* assume it is in local domain.
*/
return (0);
} else {
return (1);
}
}
if (strchr(hn, '.') == NULL) {
/* Unqualified host name,
* assume it is in local domain.
*
* If "localdomain" is in the exception list,
* do not use the firewall for this host.
*/
(void) STRNCPY(buf, firewallExceptionList);
for (parse = buf; (tok = strtok(parse, ", \n\t\r")) != NULL; parse = NULL) {
if (strcmp(tok, "localdomain") == 0)
return (0);
}
/* fall through */
}
#ifdef HAVE_STRSTR
(void) STRNCPY(buf, firewallExceptionList);
for (parse = buf; (tok = strtok(parse, ", \n\t\r")) != NULL; parse = NULL) {
/* See if host or domain was from exclusion list
* matches the host to open.
*/
if (strstr(hn, tok) != NULL)
return (0);
}
#endif /* HAVE_STRSTR */
return (1);
} /* MayUseFirewall */
int
StrToBool(const char *const s)
{
int c;
int result;
c = *s;
if (isupper(c))
c = tolower(c);
result = 0;
switch (c) {
case 'f': /* false */
/*FALLTHROUGH*/
case 'n': /* no */
break;
case 'o': /* test for "off" and "on" */
c = (int) s[1];
if (isupper(c))
c = tolower(c);
if (c == 'f')
break;
/*FALLTHROUGH*/
case 't': /* true */
/*FALLTHROUGH*/
case 'y': /* yes */
result = 1;
break;
default: /* 1, 0, -1, other number? */
if (atoi(s) != 0)
result = 1;
}
return result;
} /* StrToBool */
void
AbsoluteToRelative(char *const dst, const size_t dsize, const char *const dir, const char *const root, const size_t rootlen)
{
*dst = '\0';
if (strcmp(dir, root) != 0) {
if (strcmp(root, "/") == 0) {
(void) Strncpy(dst, dir + 1, dsize);
} else if ((strncmp(root, dir, rootlen) == 0) && (dir[rootlen] == '/')) {
(void) Strncpy(dst, dir + rootlen + 1, dsize);
} else {
/* Still absolute. */
(void) Strncpy(dst, dir, dsize);
}
}
} /* AbsoluteToRelative */
#if defined(WIN32) || defined(_WINDOWS)
#else
/* Some commands may want to jump back to the start too. */
static void
CancelGetHostByName(int sigNum)
{
#ifdef ncftp
gResolveSig = sigNum;
#endif
#ifdef HAVE_SIGSETJMP
siglongjmp(gGetHostByNameJmp, (sigNum != 0) ? 1 : 0);
#else /* HAVE_SIGSETJMP */
longjmp(gGetHostByNameJmp, (sigNum != 0) ? 1 : 0);
#endif /* HAVE_SIGSETJMP */
} /* CancelGetHostByName */
#endif
int
GetHostByName(char *const volatile dst, size_t dsize, const char *const hn, int t)
{
#if defined(WIN32) || defined(_WINDOWS)
struct hostent *hp;
struct in_addr ina;
if (inet_addr(hn) != (unsigned long) 0xFFFFFFFF) {
/* Address is an IP address string, which is what we want. */
(void) Strncpy(dst, hn, dsize);
return (0);
}
hp = gethostbyname(hn);
if (hp != NULL) {
(void) memcpy(&ina.s_addr, hp->h_addr_list[0], (size_t) hp->h_length);
(void) Strncpy(dst, inet_ntoa(ina), dsize);
return (0);
}
#else
int sj;
vsigproc_t osigpipe, osigint, osigalrm;
struct hostent *hp;
#ifndef HAVE_INET_NTOP
struct in_addr ina;
#endif
#ifdef HAVE_INET_ATON
if (inet_aton(hn, &ina) != 0) {
/* Address is an IP address string, which is what we want. */
(void) Strncpy(dst, hn, dsize);
return (0);
}
#else
if (inet_addr(hn) != (unsigned long) 0xFFFFFFFF) {
/* Address is an IP address string, which is what we want. */
(void) Strncpy(dst, hn, dsize);
return (0);
}
#endif
#ifdef HAVE_SIGSETJMP
osigpipe = osigint = osigalrm = (sigproc_t) 0;
sj = sigsetjmp(gGetHostByNameJmp, 1);
#else /* HAVE_SIGSETJMP */
osigpipe = osigint = osigalrm = (sigproc_t) 0;
sj = setjmp(gGetHostByNameJmp);
#endif /* HAVE_SIGSETJMP */
if (sj != 0) {
/* Caught a signal. */
(void) alarm(0);
(void) NcSignal(SIGPIPE, osigpipe);
(void) NcSignal(SIGINT, osigint);
(void) NcSignal(SIGALRM, osigalrm);
#ifdef ncftp
Trace(0, "Canceled GetHostByName because of signal %d.\n", gResolveSig);
#endif
} else {
osigpipe = NcSignal(SIGPIPE, CancelGetHostByName);
osigint = NcSignal(SIGINT, CancelGetHostByName);
osigalrm = NcSignal(SIGALRM, CancelGetHostByName);
if (t > 0)
(void) alarm((unsigned int) t);
hp = gethostbyname(hn);
if (t > 0)
(void) alarm(0);
(void) NcSignal(SIGPIPE, osigpipe);
(void) NcSignal(SIGINT, osigint);
(void) NcSignal(SIGALRM, osigalrm);
if (hp != NULL) {
#ifdef HAVE_INET_NTOP /* Mostly to workaround bug in IRIX 6.5's inet_ntoa */
(void) memset(dst, 0, dsize);
(void) inet_ntop(AF_INET, hp->h_addr_list[0], dst, dsize - 1);
#else
(void) memcpy(&ina.s_addr, hp->h_addr_list[0], (size_t) hp->h_length);
(void) Strncpy(dst, inet_ntoa(ina), dsize);
#endif
return (0);
}
}
#endif /* !Windows */
*dst = '\0';
return (-1);
} /* GetHostByName */
/* Converts a date string, like "19930602204445" into to a time_t. */
time_t UnDate(char *dstr)
{
#ifndef HAVE_MKTIME
return ((time_t) -1);
#else
struct tm ut, *t;
time_t now;
time_t result = (time_t) -1;
(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;
result = mktime(&ut);
}
return result;
#endif /* HAVE_MKTIME */
} /* UnDate */
#ifndef HAVE_MEMMOVE
/* This code is derived from software contributed to Berkeley by
* Chris Torek.
*/
/*
* sizeof(word) MUST BE A POWER OF TWO
* SO THAT wmask BELOW IS ALL ONES
*/
typedef int word; /* "word" used for optimal copy speed */
#define wsize sizeof(word)
#define wmask (wsize - 1)
/*
* Copy a block of memory, handling overlap.
* This is the routine that actually implements
* (the portable versions of) bcopy, memcpy, and memmove.
*/
void *
memmove(void *dst0, void *src0, size_t length)
{
register char *dst = (char *) dst0;
register const char *src = (char *) src0;
register size_t t;
if (length == 0 || dst == src) /* nothing to do */
return dst;
/*
* Macros: loop-t-times; and loop-t-times, t>0
*/
#define TLOOP(s) if (t) TLOOP1(s)
#define TLOOP1(s) do { s; } while (--t)
if ((unsigned long)dst < (unsigned long)src) {
/*
* Copy forward.
*/
t = (int)src; /* only need low bits */
if ((t | (int)dst) & wmask) {
/*
* Try to align operands. This cannot be done
* unless the low bits match.
*/
if ((t ^ (int)dst) & wmask || length < wsize)
t = length;
else
t = wsize - (t & wmask);
length -= t;
TLOOP1(*dst++ = *src++);
}
/*
* Copy whole words, then mop up any trailing bytes.
*/
t = length / wsize;
TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
t = length & wmask;
TLOOP(*dst++ = *src++);
} else {
/*
* Copy backwards. Otherwise essentially the same.
* Alignment works as before, except that it takes
* (t&wmask) bytes to align, not wsize-(t&wmask).
*/
src += length;
dst += length;
t = (int)src;
if ((t | (int)dst) & wmask) {
if ((t ^ (int)dst) & wmask || length <= wsize)
t = length;
else
t &= wmask;
length -= t;
TLOOP1(*--dst = *--src);
}
t = length / wsize;
TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
t = length & wmask;
TLOOP(*--dst = *--src);
}
return(dst0);
} /* MemMove */
#endif /* ! HAVE_MEMMOVE */
#if defined(HAVE_STRCOLL) && !defined(HAVE_STRNCOLL)
int
strncoll(const char *a, const char *b, size_t n)
{
int rc;
if (n < 511) {
char sa[512], sb[512];
memset(sa, 0, sizeof(sa));
memset(sb, 0, sizeof(sb));
(void) strncpy(sa, a, n);
(void) strncpy(sb, b, n);
rc = (strcoll(sa, sb));
return (rc);
} else {
char *ma, *mb;
n += 5; /* enough for a 32-bit zero char. */
ma = (char *) malloc(n);
if (ma == NULL)
return (0); /* panic */
mb = (char *) malloc(n);
if (mb == NULL) {
free(ma);
return (0); /* panic */
}
(void) strncpy(ma, a, n);
(void) strncpy(mb, b, n);
rc = (strcoll(ma, mb));
free(ma);
free(mb);
return (rc);
}
} /* strncoll */
#endif
int
DecodeDirectoryURL(
const FTPCIPtr cip, /* area pointed to may be modified */
char *url, /* always modified */
LineListPtr cdlist, /* always modified */
char *fn, /* always modified */
size_t fnsize
)
{
int rc;
char urlstr2[256];
char *cp;
/* Add a trailing slash, if needed, i.e., convert
* "ftp://ftp.gnu.org/pub/gnu" to
* "ftp://ftp.gnu.org/pub/gnu/"
*
* We also generalize and assume that if the user specified
* something with a .extension that the user was intending
* to specify a file instead of a directory.
*/
cp = strrchr(url, '/');
if ((cp != NULL) && (cp[1] != '\0') && (strchr(cp, '.') == NULL)) {
(void) STRNCPY(urlstr2, url);
(void) STRNCAT(urlstr2, "/");
url = urlstr2;
}
rc = FTPDecodeURL(cip, url, cdlist, fn, fnsize, NULL, NULL);
return (rc);
} /* DecodeDirectoryURL */
#if defined(WIN32) || defined(_WINDOWS)
void SysPerror(const char *const errMsg)
{
char reason[128];
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reason,
(DWORD) sizeof(reason),
NULL
);
if (reason[strlen(reason) - 1] = '\n')
reason[strlen(reason) - 1] = '\0';
(void) fprintf(stderr, "%s: %s\n", errMsg, reason);
} /* SysPerror */
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -