📄 ccache_hash.c
字号:
static char rcsid[] = "ccache_hash.c,v 1.14 1995/11/29 00:48:30 duane Exp";/********************************************************************************** FILE** hash.c**** DESCRIPTION** This file contains the socket control algorithms and structures.** It manages the hash table and expirations of sockets.**** FUNCTIONS** SockInit()** free_url()** Compare_URL()** StripFileName()** SearchList()** GetConnection()** DisconnectOne()** TouchDate()** SockRetrieve()** SockGetData()** ExpireSocket()** ShutDownCache()** DestroyDataReturn()** DumpHash()**** David Merkel & Mark Peterson, University of Colorado - Boulder, July 1994 * * ---------------------------------------------------------------------- * Copyright (c) 1994, 1995. All rights reserved. * * The Harvest software was developed by the Internet Research Task * Force Research Group on Resource Discovery (IRTF-RD): * * Mic Bowman of Transarc Corporation. * Peter Danzig of the University of Southern California. * Darren R. Hardy of the University of Colorado at Boulder. * Udi Manber of the University of Arizona. * Michael F. Schwartz of the University of Colorado at Boulder. * Duane Wessels of the University of Colorado at Boulder. * * This copyright notice applies to software in the Harvest * ``src/'' directory only. Users should consult the individual * copyright notices in the ``components/'' subdirectories for * copyright information about other software bundled with the * Harvest source code distribution. * * TERMS OF USE * * The Harvest software may be used and re-distributed without * charge, provided that the software origin and research team are * cited in any use of the system. Most commonly this is * accomplished by including a link to the Harvest Home Page * (http://harvest.cs.colorado.edu/) from the query page of any * Broker you deploy, as well as in the query result pages. These * links are generated automatically by the standard Broker * software distribution. * * The Harvest software is provided ``as is'', without express or * implied warranty, and with no support nor obligation to assist * in its use, correction, modification or enhancement. We assume * no liability with respect to the infringement of copyrights, * trade secrets, or any patents, and are not responsible for * consequential damages. Proper use of the Harvest software is * entirely the responsibility of the user. * * DERIVATIVE WORKS * * Users may make derivative works from the Harvest software, subject * to the following constraints: * * - You must include the above copyright notice and these * accompanying paragraphs in all forms of derivative works, * and any documentation and other materials related to such * distribution and use acknowledge that the software was * developed at the above institutions. * * - You must notify IRTF-RD regarding your distribution of * the derivative work. * * - You must clearly notify users that your are distributing * a modified version and not the original Harvest software. * * - Any derivative product is also subject to these copyright * and use restrictions. * * Note that the Harvest software is NOT in the public domain. We * retain copyright, as specified above. * * HISTORY OF FREE SOFTWARE STATUS * * Originally we required sites to license the software in cases * where they were going to build commercial products/services * around Harvest. In June 1995 we changed this policy. We now * allow people to use the core Harvest software (the code found in * the Harvest ``src/'' directory) for free. We made this change * in the interest of encouraging the widest possible deployment of * the technology. The Harvest software is really a reference * implementation of a set of protocols and formats, some of which * we intend to standardize. We encourage commercial * re-implementations of code complying to this set of standards. * ******************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <netdb.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "ccache.h"#include "time_it.h"#include "util.h"/* Allow differnet passwords on the same socket */#define ALLOW_DIFFERENT_PASSWORDS/* Hash function is last 8 bits of the IP number of the destination host. */#define GetHKey(theIP) ((int) ((theIP) & 0xff))/* Flag to prevent non-initialized hash from being used. */static Boolean initialized = FALSE;/* The hash table. */static SockCntlRec *SockHash[HASH_SLOTS];/* The expiration queue. */static SockCntlRec *TimeOutListNew = NULL;static SockCntlRec *TimeOutListOld = NULL;/* Current number of connections being maintained. */static int currConnections = 0;/* Default values. */static int maxConnections = 10;static long timeOut = 300;/* Called on timer expiration. */int ExpireSocket(int whichTimer);/* Called on SIGUSR1 to dump the hash table to stdout. */static void DumpHash();/****************************************************************************** function: void SockInit()**** parameters: InitConfigRec sets the initialization parameters to the** library package. If NULL, we use the defaults.**** postcondistions: The structures are initialized and ready to accept** connections.**** other: This function should only be called once, and must be called before** any other related function call.*****************************************************************************/void SockInit(InitConfigRec * initParam){ if (initialized) /* If we've already initialed, don't do it again. */ return; initialized = TRUE; /* Set initialization to TRUE */ signal(SIGUSR1, DumpHash); /* On this interrupt the Hash table */ /* spills its guts. */ /* Initialize the Hash Table to NULL's */ memset((char *) SockHash, '\0', (sizeof(SockCntlRec *) * HASH_SLOTS)); /* Initialize the timer package. */ InitTimer(); /* If no initailization was given use default values. */ if (!initParam) return; /* Set the maximum number of connections to maintain. */ if (initParam->maxConnections > MIN_CONNECTIONS) maxConnections = initParam->maxConnections; /* Set the timeOut for inactive connections. */ if (initParam->timeOut > MIN_TIMEOUT) timeOut = initParam->timeOut;}/***************************************************************************** function: free_url()**** parameters: An allocated URL structure.**** postconditions: The URL is deallocated.****************************************************************************/static void free_url(URL * toFree){ if (toFree->url) xfree(toFree->url); if (toFree->pathname) xfree(toFree->pathname); if (toFree->host) xfree(toFree->host); if (toFree->user) xfree(toFree->user); if (toFree->password) xfree(toFree->password); if (toFree->raw_pathname) xfree(toFree->raw_pathname); xfree((char *) toFree); toFree = NULL;}/*************************************************************************** function: CompareURL()**** parameters: Two preallocated URL structures.**** postconditions: Returns TRUE if these to connections have the same** hostname and port number.*************************************************************************/static int CompareURL(URL * ua, URL * ub){#ifdef DEBUG printf("inside of CompareURL\n"); printf("ub->host: %s\n", ub->host); printf("ua->host: %s\n", ua->host);#endif if (strcmp(ua->host, ub->host) != 0) return FALSE; if (ua->port != ub->port) return FALSE; return TRUE;}/******************************************************************************** function name: StripFileName()**** preconditions: Buffer must be an empty pre-allocated string.** Path must contain a unix pathname.**** postconditions: The last unit of the pathname is placed into the buffer.********************************************************************************/static void StripFileName(buffer, path) char *buffer; char *path;{ int i; for (i = strlen(path); i >= 0; i--) { if (path[i] == '/') break; } strcpy(buffer, &path[i + 1]);}/************************************************************************ function: SearchList()**** parameters: An allocated SockCntlRec and a URL. The SockCntrlRec *** should point to the beginning of the hash to search.**** postconditions: A socket with a matching URL is returned if an** INACTIVE one is available.**********************************************************************/static SockCntlRec *SearchList(SockCntlRec * theRec, URL * theURL){ SockCntlRec *tmpPtr; char errorReply[SERV_REPLY_LENGTH]; URL *newURL; int errNum; /* Make sure we've initizlized and the URL is valid */ if (!initialized || theURL == NULL) return (NULL); newURL = dup_url(theURL); tmpPtr = theRec; /* Go until we've checked all in the list. */ while (tmpPtr != NULL) { /* See if this one is inactive and matches our URL. */ if ((tmpPtr->sockStateStor == INACTIVE) && (CompareURL(tmpPtr->socketInfo, theURL))) { /* If the user or password is different relogin in. */ if ((strcmp(tmpPtr->socketInfo->user, theURL->user) != 0)#ifndef ALLOW_DIFFERENT_PASSWORDS || (strcmp(tmpPtr->socketInfo->password, theURL->password) != 0)#endif ) { free_url(tmpPtr->socketInfo); tmpPtr->socketInfo = newURL; if ((errNum = Login(tmpPtr->socketInfo->user, tmpPtr->socketInfo->password, tmpPtr->theSocket, FALSE, errorReply)) < 0) { CancelTimer(tmpPtr->timerid); ExpireSocket(tmpPtr->timerid); DoError(errNum, errorReply); return (NULL); } return (tmpPtr); } free_url(tmpPtr->socketInfo); tmpPtr->socketInfo = newURL; return (tmpPtr); } /* Look at the next one. */ tmpPtr = tmpPtr->hashNext; } return (NULL);}/****************************************************************************** function: GetConnection()**** parameters: An allocated URL and the IP number of the host to connect** to.**** postconditions: The socket is returned to the structure.****************************************************************************/static SockCntlRec *GetConnection(URL * theURL, long theIPnum){ SockCntlRec *locSockRec; int errNum; char errorReply[SERV_REPLY_LENGTH]; char errorIgnore[SERV_REPLY_LENGTH]; locSockRec = (SockCntlRec *) malloc(sizeof(SockCntlRec)); if (!locSockRec) { DoError(MEMORY_ERROR, NULL); return NULL; } /* Configure a new socket. */ locSockRec->socketInfo = theURL; locSockRec->theHostIP = theIPnum; locSockRec->timerid = SetTimer(timeOut, ExpireSocket); locSockRec->incomDataBuf = NULL; locSockRec->incomDataFile = NULL; locSockRec->incomDataSize = 0; locSockRec->listPrev = NULL; locSockRec->listNext = NULL; locSockRec->hashPrev = NULL; locSockRec->hashNext = NULL; locSockRec->theSocket = FTPInit(theIPnum, theURL->port, errorReply); if (locSockRec->theSocket < 0) { DoError(locSockRec->theSocket, errorReply); free_url(theURL); theURL = NULL; free((char *) locSockRec); return NULL; } /* Try to Login, if not successful, close the connection. */ if ((errNum = Login(theURL->user, theURL->password, locSockRec->theSocket, TRUE, errorReply)) < 0) { CancelTimer(locSockRec->timerid); Disconnect(locSockRec->theSocket, errorIgnore); free_url(locSockRec->socketInfo); theURL = NULL; free((char *) locSockRec); locSockRec = NULL; if (errNum != SERV_REPLY_ERROR) DoError(errNum, NULL); else DoError(errNum, errorReply); } return (locSockRec);}/*********************************************************************** function: DisconnectOne()**** parameters: None**** postconditions: Attempts to disconnect the oldest inactive connection.*********************************************************************/Boolean DisconnectOne(){ SockCntlRec *locSockRec;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -