Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

253 lines
5.9 KiB

/*
Enhanced NCSA Mosaic from Spyglass
"Guitar"
Copyright 1994 Spyglass, Inc.
All Rights Reserved
Author(s):
Jim Seidman [email protected]
*/
#include "all.h"
PRIVATE char *hostname = "localhost"; /* The name of this host */
#define HOST_CACHE_SIZE 10
/* Cache for keeping track of the last few hosts */
static struct {
char hostname[128 + 1];
struct MultiAddress address;
time_t lastused;
} cache[HOST_CACHE_SIZE];
static BOOL bNetCacheInit = FALSE;
/* Report Internet Error
** ---------------------
*/
PUBLIC int HTInetStatus(char *where)
{
#ifdef WIN32
strerror(errno);
XX_DMsg(DBG_LOAD, ("errno = %d (WinSock: %d) after call to %s failed.\n%s\n", errno, WS_WSAGETLASTERROR(), where, strerror(errno)));
#endif
return -errno;
}
PUBLIC const char *HTHostName(void)
{
return hostname;
}
#define STATE_PARSE_DIDLOOKUP (STATE_OTHER)
int Net_MultiParse_Async(struct Mwin *tw, int nState, void **ppInfo)
{
struct Params_MultiParseInet *pParams;
int n;
struct MultiAddress *pAddress;
char buf[1024];
char *port;
struct Params_MultiGetHostByName *pghbn;
unsigned long addr;
pParams = *ppInfo;
switch (nState)
{
case STATE_INIT:
pParams->request = HTRequest_validate(pParams->request);
if (!pParams->str || !pParams->str[0])
{
*pParams->pStatus = -1;
return STATE_DONE;
}
strncpy(pParams->host, pParams->str, sizeof(pParams->host)); /* Take a copy we can mutilate */
/* Parse port number if present */
if ((port = strchr(pParams->host, ':')))
{
*port++ = 0; /* Chop off port */
if (port[0] >= '0' && port[0] <= '9')
{
*pParams->pPort = (unsigned short) WS_HTONS((unsigned short) strtol(port, (char **) 0, 10));
}
}
addr = WS_INET_ADDR(pParams->host);
if (addr != 0xffffffff)
{
/* Numeric node address: */
pParams->pAddress->aAddrs[0] = addr;
pParams->pAddress->nCount = 1;
pParams->pAddress->nLastUsed = 0;
*pParams->pStatus = 0;
return STATE_DONE;
}
else
{
pAddress = NULL;
#ifdef FEATURE_NO_DNS_CACHE
if (gPrefs.bUseDNSCache)
{
#endif
/* Alphanumeric node name: */
if (!bNetCacheInit)
{
memset(cache, 0, sizeof(cache));
bNetCacheInit = TRUE;
}
else
{
/* See if this host is present in the cache */
for (n = 0; n < HOST_CACHE_SIZE; n++)
{
if (!GTR_strcmpi(cache[n].hostname, pParams->host))
{
pAddress = &cache[n].address;
cache[n].lastused = time(NULL);
break;
}
}
}
if (pAddress)
{
memcpy(pParams->pAddress, &cache[n].address, sizeof(struct MultiAddress));
*pParams->pStatus = 0;
return STATE_DONE;
}
#ifdef FEATURE_NO_DNS_CACHE
}
#endif
/* If we got here, we actually have to go out on the network
to retrieve the address */
pghbn = GTR_MALLOC(sizeof(*pghbn));
GTR_formatmsg(RES_STRING_FINDADDR,buf,sizeof(buf),pParams->host);
WAIT_Push(tw, waitSameInteract, buf);
WAIT_SetStatusBarIcon( tw, SBI_FindingIcon );
pghbn->szHost = pParams->host;
pghbn->pDest = pParams->pAddress;
pghbn->pStatus = pParams->pStatus;
Async_DoCall(Net_MultiGetHostByName_Async, pghbn);
return STATE_PARSE_DIDLOOKUP;
}
case STATE_PARSE_DIDLOOKUP:
WAIT_Pop(tw);
if (*pParams->pStatus < 0)
{
/* The lookup failed */
ERR_InternalReportError(tw, errHostNotFound, pParams->host, NULL, pParams->request,NULL,NULL);
return STATE_DONE;
}
else if (*pParams->pStatus == HT_REDIRECTION_DCACHE_TIMEOUT)
{
PSTR psz;
/* Don't put up an error if request is in dcache */
if (!(psz = PszGetDCachePath(pParams->request->destination->szActualURL, NULL, NULL)))
{
/* request not in cache, error out */
*pParams->pStatus = -1;
ERR_InternalReportError(tw, errHostNotFound, pParams->host, NULL, pParams->request,NULL,NULL);
}
else
GTR_FREE(psz);
return STATE_DONE;
}
else
{
int oldest;
time_t date;
#ifdef FEATURE_NO_DNS_CACHE
if (gPrefs.bUseDNSCache)
{
#endif
/* Store it in the cache for later */
date = cache[0].lastused;
oldest = 0;
for (n = 1; n < HOST_CACHE_SIZE; n++)
{
if (cache[n].lastused < date)
{
date = cache[n].lastused;
oldest = n;
}
}
memcpy(&cache[oldest].address, pParams->pAddress, sizeof(struct MultiAddress));
strcpy(cache[oldest].hostname, pParams->host);
cache[oldest].lastused = time(NULL);
#ifdef FEATURE_NO_DNS_CACHE
}
#endif
return STATE_DONE;
}
case STATE_ABORT:
pParams->request = HTRequest_validate(pParams->request);
if (tw) WAIT_Pop(tw);
*pParams->pStatus = -1;
return STATE_DONE;
}
XX_Assert((0), ("Function called with illegal state: %d", nState));
return STATE_DONE;
}
void Net_UpdateCache(struct MultiAddress *pAddress)
{
int n;
unsigned long sample;
#ifdef FEATURE_NO_DNS_CACHE
if (gPrefs.bUseDNSCache)
{
#endif
XX_Assert((bNetCacheInit), ("Address cache not initialized!"));
/* To find this entry in the cache we just take a sample from
the address and search for that. We can't assume that the
values will be in the same order as they are in the cache,
since this item may have fallen out of the cache and then
back in. */
sample = pAddress->aAddrs[0];
for (n = 0; n < HOST_CACHE_SIZE; n++)
{
if (Net_CompareAddresses(sample, &cache[n].address))
{
/* We need to copy over the whole thing instead of just
copying nLastUsed since the items might be in a
different order */
memcpy(&cache[n].address, pAddress, sizeof(*pAddress));
cache[n].lastused = time(NULL);
break;
}
}
#ifdef FEATURE_NO_DNS_CACHE
}
#endif
}
BOOL Net_CompareAddresses(unsigned long single, struct MultiAddress *pMulti)
{
int n;
BOOL bResult;
bResult = FALSE;
for (n = 0; n < pMulti->nCount; n++)
{
if (pMulti->aAddrs[n] == single)
{
bResult = TRUE;
break;
}
}
return bResult;
}