📄 util.c
字号:
/* 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 + -