pmdb.c revision cf2f63c2
15c10afb9Smrg
25c10afb9Smrg/*
35c10afb9SmrgCopyright 1996, 1998  The Open Group
45c10afb9Smrg
55c10afb9SmrgPermission to use, copy, modify, distribute, and sell this software and its
65c10afb9Smrgdocumentation for any purpose is hereby granted without fee, provided that
75c10afb9Smrgthe above copyright notice appear in all copies and that both that
85c10afb9Smrgcopyright notice and this permission notice appear in supporting
95c10afb9Smrgdocumentation.
105c10afb9Smrg
115c10afb9SmrgThe above copyright notice and this permission notice shall be included
125c10afb9Smrgin all copies or substantial portions of the Software.
135c10afb9Smrg
145c10afb9SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
155c10afb9SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
165c10afb9SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
175c10afb9SmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
185c10afb9SmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
195c10afb9SmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
205c10afb9SmrgOTHER DEALINGS IN THE SOFTWARE.
215c10afb9Smrg
225c10afb9SmrgExcept as contained in this notice, the name of The Open Group shall
235c10afb9Smrgnot be used in advertising or otherwise to promote the sale, use or
245c10afb9Smrgother dealings in this Software without prior written authorization
255c10afb9Smrgfrom The Open Group.
265c10afb9Smrg*/
275c10afb9Smrg
285c10afb9Smrg#include "pmint.h"
295c10afb9Smrg#include "pmdb.h"
305c10afb9Smrg#include "config.h"
315c10afb9Smrg#include <assert.h>
325c10afb9Smrg#include <stdio.h>
335c10afb9Smrg#include <stdlib.h>
345c10afb9Smrg#include <signal.h>
355c10afb9Smrg
36cf2f63c2Smrgtypedef void (*Signal_Handler)(int);
375c10afb9Smrg
385c10afb9Smrgstatic proxy_service *proxyServiceList = NULL;
395c10afb9Smrg
405c10afb9Smrgstatic Signal_Handler
415c10afb9SmrgSignal (int sig, Signal_Handler handler)
425c10afb9Smrg{
435c10afb9Smrg#ifndef X_NOT_POSIX
445c10afb9Smrg    struct sigaction sigact, osigact;
455c10afb9Smrg    sigact.sa_handler = handler;
465c10afb9Smrg    sigemptyset(&sigact.sa_mask);
475c10afb9Smrg    sigact.sa_flags = 0;
485c10afb9Smrg    sigaction(sig, &sigact, &osigact);
495c10afb9Smrg    return osigact.sa_handler;
505c10afb9Smrg#else
515c10afb9Smrg    return signal(sig, handler);
525c10afb9Smrg#endif
535c10afb9Smrg}
545c10afb9Smrg
555c10afb9Smrgproxy_service *
565c10afb9SmrgFindProxyService (
575c10afb9Smrg    char *serviceName,
585c10afb9Smrg    Bool createIf)
595c10afb9Smrg
605c10afb9Smrg{
615c10afb9Smrg    proxy_service *service = proxyServiceList;
625c10afb9Smrg    int nameLen = strlen (serviceName);
635c10afb9Smrg
645c10afb9Smrg    while (service)
655c10afb9Smrg    {
665c10afb9Smrg	if (strcmp (service->serviceName, serviceName) == 0)
675c10afb9Smrg	    return service;
685c10afb9Smrg	else if (ncasecmp (service->serviceName, serviceName, nameLen) == 0)
695c10afb9Smrg	    return service;
705c10afb9Smrg	else
715c10afb9Smrg	    service = service->next;
725c10afb9Smrg    }
735c10afb9Smrg
745c10afb9Smrg    if (createIf) {
75cf2f63c2Smrg	service = malloc (sizeof (proxy_service));
765c10afb9Smrg	if (!service)
775c10afb9Smrg	    return NULL;
785c10afb9Smrg
79cf2f63c2Smrg	service->serviceName = strdup (serviceName);
805c10afb9Smrg	if (!service->serviceName)
815c10afb9Smrg	{
825c10afb9Smrg	    free (service);
835c10afb9Smrg	    return NULL;
845c10afb9Smrg	}
855c10afb9Smrg
865c10afb9Smrg	service->proxyCount = 0;
875c10afb9Smrg	service->proxyList = NULL;
885c10afb9Smrg
895c10afb9Smrg	if (proxyServiceList == NULL)
905c10afb9Smrg	{
915c10afb9Smrg	    proxyServiceList = service;
925c10afb9Smrg	    service->next = NULL;
935c10afb9Smrg	}
945c10afb9Smrg	else
955c10afb9Smrg	{
965c10afb9Smrg	    service->next = proxyServiceList;
975c10afb9Smrg	    proxyServiceList = service;
985c10afb9Smrg	}
995c10afb9Smrg    }
1005c10afb9Smrg
1015c10afb9Smrg    return service;
1025c10afb9Smrg
1035c10afb9Smrg}
1045c10afb9Smrg
1055c10afb9Smrg
1065c10afb9Smrgrunning_proxy *
1075c10afb9SmrgStartNewProxy (
1085c10afb9Smrg    char *serviceName,
1095c10afb9Smrg    char *startCommand)
1105c10afb9Smrg
1115c10afb9Smrg{
1125c10afb9Smrg    proxy_service *service = FindProxyService (serviceName, True);
1135c10afb9Smrg    running_proxy *proxy;
1145c10afb9Smrg
1155c10afb9Smrg    if (!service)
1165c10afb9Smrg	return NULL;
1175c10afb9Smrg
118cf2f63c2Smrg    proxy = malloc (sizeof (running_proxy));
1195c10afb9Smrg    if (!proxy)
1205c10afb9Smrg	return NULL;
1215c10afb9Smrg
1225c10afb9Smrg    proxy->active = 0;
1235c10afb9Smrg    proxy->pmConn = NULL;
1245c10afb9Smrg    proxy->requests = NULL;
1255c10afb9Smrg    proxy->servers = NULL;
1265c10afb9Smrg    proxy->refused_service = False;
1275c10afb9Smrg
1285c10afb9Smrg    if (service->proxyList == NULL)
1295c10afb9Smrg    {
1305c10afb9Smrg	service->proxyList = proxy;
1315c10afb9Smrg	proxy->next = NULL;
1325c10afb9Smrg    }
1335c10afb9Smrg    else
1345c10afb9Smrg    {
1355c10afb9Smrg	proxy->next = service->proxyList;
1365c10afb9Smrg	service->proxyList = proxy;
1375c10afb9Smrg    }
1385c10afb9Smrg
1395c10afb9Smrg    if (system (startCommand) == -1)
1405c10afb9Smrg    {
1415c10afb9Smrg	printf ("unable to start managed proxy: %s\n", startCommand);
1425c10afb9Smrg	service->proxyList = proxy->next;
1435c10afb9Smrg	free (proxy);
1445c10afb9Smrg	return NULL;
1455c10afb9Smrg    }
1465c10afb9Smrg
1475c10afb9Smrg    if (verbose) {
1485c10afb9Smrg	printf ("started managed proxy: %s\n", startCommand);
1495c10afb9Smrg	printf ("waiting for StartProxy message\n");
1505c10afb9Smrg    }
1515c10afb9Smrg
1525c10afb9Smrg    service->proxyCount++;
1535c10afb9Smrg
1545c10afb9Smrg    return proxy;
1555c10afb9Smrg}
1565c10afb9Smrg
1575c10afb9Smrg/*
1585c10afb9Smrg * ConnectToProxy( pmOpcode, serviceName, proxyAddress )
1595c10afb9Smrg *
1605c10afb9Smrg * Connects to an unmanaged proxy to forward the GetProxyAddr request
1615c10afb9Smrg * to it to handle.
1625c10afb9Smrg *
1635c10afb9Smrg * Ideally this would be non-blocking but there is no non-blocking
1645c10afb9Smrg * variant of IceOpenConnection/IceProtocolSetup.  So we sit here a while.
1655c10afb9Smrg */
1665c10afb9Smrgrunning_proxy *
1675c10afb9SmrgConnectToProxy (
1685c10afb9Smrg    int pmOpcode,
1695c10afb9Smrg    char *serviceName,
1705c10afb9Smrg    char *proxyAddress)
1715c10afb9Smrg
1725c10afb9Smrg{
1735c10afb9Smrg    proxy_service *service = FindProxyService (serviceName, True);
1745c10afb9Smrg    running_proxy *proxy;
1755c10afb9Smrg    IceConn proxy_iceConn;
1765c10afb9Smrg    PMconn *pmConn;
1775c10afb9Smrg
1785c10afb9Smrg    if (!service)
1795c10afb9Smrg	return NULL;
1805c10afb9Smrg
1815c10afb9Smrg    {
1825c10afb9Smrg	int majorVersion, minorVersion;
1835c10afb9Smrg	char *vendor, *release;
1845c10afb9Smrg	char errorString[256];
1855c10afb9Smrg
1865c10afb9Smrg	/*
1875c10afb9Smrg	 * IceOpenConnection will do more than one write to the proxy.
1885c10afb9Smrg	 * If the proxy closes the connection before the second write,
1895c10afb9Smrg	 * the second write may generate a SIGPIPE (empirically this
1905c10afb9Smrg	 * happens on at least AIX).  So, temporarily ignore this signal.
1915c10afb9Smrg	 */
1925c10afb9Smrg
1935c10afb9Smrg	Signal (SIGPIPE, SIG_IGN);
1945c10afb9Smrg
1955c10afb9Smrg	proxy_iceConn = IceOpenConnection( proxyAddress, NULL,
1965c10afb9Smrg					   False, pmOpcode,
1975c10afb9Smrg					   sizeof(errorString), errorString);
1985c10afb9Smrg
1995c10afb9Smrg	Signal (SIGPIPE, SIG_DFL);
2005c10afb9Smrg
2015c10afb9Smrg	if (! proxy_iceConn) {
2025c10afb9Smrg	    printf("unable to open connection to unmanaged proxy \"%s\" at %s\n",
2035c10afb9Smrg		   serviceName, proxyAddress);
2045c10afb9Smrg	    return NULL;
2055c10afb9Smrg	}
2065c10afb9Smrg
2075c10afb9Smrg        /*
2085c10afb9Smrg	 * Mark this fd to be closed upon exec
2095c10afb9Smrg	 */
2105c10afb9Smrg        SetCloseOnExec (IceConnectionNumber (proxy_iceConn));
2115c10afb9Smrg
2125c10afb9Smrg	/* See PMprotocolSetupProc */
213cf2f63c2Smrg	pmConn = malloc (sizeof (PMconn));
2145c10afb9Smrg
2155c10afb9Smrg	if (pmConn == NULL) {
2165c10afb9Smrg	    IceCloseConnection (proxy_iceConn);
2175c10afb9Smrg	    return NULL;
2185c10afb9Smrg	}
2195c10afb9Smrg
2205c10afb9Smrg	if (IceProtocolSetup (proxy_iceConn, pmOpcode,
2215c10afb9Smrg			      (IcePointer)pmConn, /* client_data */
2225c10afb9Smrg			      False, /* must_authenticate */
2235c10afb9Smrg			      &majorVersion, &minorVersion,
2245c10afb9Smrg			      &vendor, &release,
2255c10afb9Smrg			      sizeof(errorString), errorString)
2265c10afb9Smrg	        != IceProtocolSetupSuccess) {
2275c10afb9Smrg	    IceCloseConnection (proxy_iceConn);
2285c10afb9Smrg	    free (pmConn);
2295c10afb9Smrg	    printf ("Could not initialize proxy management protocol with\n  unmanaged proxy \"%s\" at address %s:\n  %s\n",
2305c10afb9Smrg		    serviceName, proxyAddress, errorString);
2315c10afb9Smrg	    return NULL;
2325c10afb9Smrg	}
2335c10afb9Smrg
2345c10afb9Smrg	pmConn->iceConn = proxy_iceConn;
2355c10afb9Smrg	pmConn->pmOpcode = pmOpcode;
2365c10afb9Smrg	pmConn->proto_major_version = majorVersion;
2375c10afb9Smrg	pmConn->proto_minor_version = minorVersion;
2385c10afb9Smrg	pmConn->vendor = vendor;
2395c10afb9Smrg	pmConn->release = release;
2405c10afb9Smrg    }
2415c10afb9Smrg
242cf2f63c2Smrg    proxy = malloc (sizeof (running_proxy));
2435c10afb9Smrg    if (!proxy) {
2445c10afb9Smrg	IceCloseConnection (proxy_iceConn);
2455c10afb9Smrg	free (pmConn);
2465c10afb9Smrg	return NULL;
2475c10afb9Smrg    }
2485c10afb9Smrg
2495c10afb9Smrg    proxy->active = 1;
2505c10afb9Smrg    proxy->pmConn = pmConn;
2515c10afb9Smrg    proxy->requests = NULL;
2525c10afb9Smrg    proxy->servers = NULL;
2535c10afb9Smrg    proxy->refused_service = False;
2545c10afb9Smrg
2555c10afb9Smrg    if (service->proxyList == NULL)
2565c10afb9Smrg    {
2575c10afb9Smrg	service->proxyList = proxy;
2585c10afb9Smrg	proxy->next = NULL;
2595c10afb9Smrg    }
2605c10afb9Smrg    else
2615c10afb9Smrg    {
2625c10afb9Smrg	proxy->next = service->proxyList;
2635c10afb9Smrg	service->proxyList = proxy;
2645c10afb9Smrg    }
2655c10afb9Smrg
2665c10afb9Smrg    if (verbose)
2675c10afb9Smrg	printf ("connected to unmanaged proxy: %s at %s\n",
2685c10afb9Smrg		serviceName, proxyAddress);
2695c10afb9Smrg
2705c10afb9Smrg    service->proxyCount++;
2715c10afb9Smrg
2725c10afb9Smrg    return proxy;
2735c10afb9Smrg}
2745c10afb9Smrg
2755c10afb9Smrg
2765c10afb9SmrgStatus
2775c10afb9SmrgActivateProxyService (
2785c10afb9Smrg    char *serviceName,
2795c10afb9Smrg    PMconn *pmConn)
2805c10afb9Smrg
2815c10afb9Smrg{
2825c10afb9Smrg    proxy_service *service = FindProxyService (serviceName, False);
2835c10afb9Smrg    running_proxy *proxy;
2845c10afb9Smrg
2855c10afb9Smrg    if (!service)
2865c10afb9Smrg	return 0;
2875c10afb9Smrg
2885c10afb9Smrg    proxy = service->proxyList;
2895c10afb9Smrg
2905c10afb9Smrg    while (proxy)
2915c10afb9Smrg    {
2925c10afb9Smrg	if (!proxy->active)
2935c10afb9Smrg	{
2945c10afb9Smrg	    proxy->active = 1;
2955c10afb9Smrg	    proxy->pmConn = pmConn;
2965c10afb9Smrg	    return 1;
2975c10afb9Smrg	}
2985c10afb9Smrg	else
2995c10afb9Smrg	    proxy = proxy->next;
3005c10afb9Smrg    }
3015c10afb9Smrg
3025c10afb9Smrg    return 0;
3035c10afb9Smrg}
3045c10afb9Smrg
3055c10afb9Smrg
3065c10afb9Smrgvoid
3075c10afb9SmrgProxyGone (
3085c10afb9Smrg    IceConn proxyIceConn,
3095c10afb9Smrg    Bool *activeReqs)
3105c10afb9Smrg
3115c10afb9Smrg{
3125c10afb9Smrg    proxy_service *service = proxyServiceList;
3135c10afb9Smrg
3145c10afb9Smrg    while (service)
3155c10afb9Smrg    {
3165c10afb9Smrg	running_proxy *proxy = service->proxyList;
3175c10afb9Smrg	running_proxy *prevProxy = NULL;
3185c10afb9Smrg
3195c10afb9Smrg	while (proxy)
3205c10afb9Smrg	{
3215c10afb9Smrg	    if (proxy->pmConn && (proxy->pmConn->iceConn == proxyIceConn))
3225c10afb9Smrg	    {
3235c10afb9Smrg		server_list *server;
3245c10afb9Smrg		request_list *req;
3255c10afb9Smrg
3265c10afb9Smrg		if (verbose)
3275c10afb9Smrg		    printf ("Proxy disconnected on fd %d",
3285c10afb9Smrg			    IceConnectionNumber(proxyIceConn));
3295c10afb9Smrg
3305c10afb9Smrg		server = proxy->servers;
3315c10afb9Smrg		if (verbose && server)
3325c10afb9Smrg		    fputs (" for server", stdout);
3335c10afb9Smrg
3345c10afb9Smrg		while (server)
3355c10afb9Smrg		{
3365c10afb9Smrg		    server_list *next_server = server->next;
3375c10afb9Smrg		    if (verbose) {
3385c10afb9Smrg			fputc (' ', stdout);
3395c10afb9Smrg			fputs (server->serverAddress, stdout);
3405c10afb9Smrg		    }
3415c10afb9Smrg		    free (server->serverAddress);
3425c10afb9Smrg		    free (server);
3435c10afb9Smrg		    server = next_server;
3445c10afb9Smrg		}
3455c10afb9Smrg
3465c10afb9Smrg		if (verbose)
3475c10afb9Smrg		    fputc ('\n', stdout);
3485c10afb9Smrg
3495c10afb9Smrg		if (prevProxy == NULL)
3505c10afb9Smrg		    service->proxyList = proxy->next;
3515c10afb9Smrg		else
3525c10afb9Smrg		    prevProxy->next = proxy->next;
3535c10afb9Smrg
3545c10afb9Smrg		service->proxyCount--;
3555c10afb9Smrg
3565c10afb9Smrg		*activeReqs = proxy->requests != NULL;
3575c10afb9Smrg		req = proxy->requests;
3585c10afb9Smrg		while (req)
3595c10afb9Smrg		{
3605c10afb9Smrg		    request_list *nextreq = req->next;
3615c10afb9Smrg
3625c10afb9Smrg		    if (req->requestor) {
3635c10afb9Smrg			assert (req->requestor->iceConn != NULL);
3645c10afb9Smrg			if (verbose)
3655c10afb9Smrg			    printf ("Reprocessing request from fd %d for service %s at %s\n",
3665c10afb9Smrg				    IceConnectionNumber (req->requestor->iceConn),
3675c10afb9Smrg				    req->serviceName, req->serverAddress);
3685c10afb9Smrg
3695c10afb9Smrg			ForwardRequest( req->requestor,
3705c10afb9Smrg					req->serviceName, req->serverAddress,
3715c10afb9Smrg					req->hostAddress, req->startOptions,
3725c10afb9Smrg					req->authLen, req->authName,
3735c10afb9Smrg					req->authData);
3745c10afb9Smrg		    }
375cf2f63c2Smrg		    free (req->serviceName);
376cf2f63c2Smrg		    free (req->serverAddress);
377cf2f63c2Smrg		    free (req->hostAddress);
378cf2f63c2Smrg		    free (req->startOptions);
379cf2f63c2Smrg		    free (req->listData);	/* proxyList */
380cf2f63c2Smrg		    free (req->authName);
381cf2f63c2Smrg		    free (req->authData);
3825c10afb9Smrg		    free (req);
3835c10afb9Smrg		    req = nextreq;
3845c10afb9Smrg		}
3855c10afb9Smrg
3865c10afb9Smrg		free (proxy);
3875c10afb9Smrg		return;
3885c10afb9Smrg	    }
3895c10afb9Smrg	    else if (proxy->requests) {
3905c10afb9Smrg		/*
3915c10afb9Smrg		 * If it wasn't a proxy that disconnected, so it might
3925c10afb9Smrg		 * have been a requestor.  Search through all the requests
3935c10afb9Smrg		 * while we're here and look for a match.  If found, delete
3945c10afb9Smrg		 * the request.
3955c10afb9Smrg		 */
3965c10afb9Smrg		request_list **prev_reqP = &proxy->requests;
3975c10afb9Smrg		request_list *req = proxy->requests;
3985c10afb9Smrg		while (req) {
3995c10afb9Smrg		    if (req->requestor->iceConn == proxyIceConn) {
4005c10afb9Smrg			if (verbose) {
4015c10afb9Smrg			    printf ("Requestor disconnected on fd %d while awaiting reply\n  for service %s (%s)",
4025c10afb9Smrg				    IceConnectionNumber(proxyIceConn),
4035c10afb9Smrg				    req->serviceName, req->serverAddress);
4045c10afb9Smrg			    if (proxy->pmConn && proxy->pmConn->iceConn) {
4055c10afb9Smrg				printf (" from proxy on fd %d\n",
4065c10afb9Smrg					IceConnectionNumber(proxy->pmConn->iceConn));
4075c10afb9Smrg			    }
4085c10afb9Smrg			    else
4095c10afb9Smrg				fputc ('\n', stdout);
4105c10afb9Smrg			}
4115c10afb9Smrg
4125c10afb9Smrg			*prev_reqP = req->next;
4135c10afb9Smrg
414cf2f63c2Smrg			free (req->serviceName);
415cf2f63c2Smrg			free (req->serverAddress);
416cf2f63c2Smrg			free (req->hostAddress);
417cf2f63c2Smrg			free (req->startOptions);
418cf2f63c2Smrg			free (req->listData);	/* proxyList */
419cf2f63c2Smrg			free (req->authName);
420cf2f63c2Smrg			free (req->authData);
4215c10afb9Smrg			free (req);
4225c10afb9Smrg
4235c10afb9Smrg			/* return; */ /* should but only one req, but... */
4245c10afb9Smrg		    }
4255c10afb9Smrg		    else
4265c10afb9Smrg			prev_reqP = &req->next;
4275c10afb9Smrg
4285c10afb9Smrg		    req = *prev_reqP;
4295c10afb9Smrg		}
4305c10afb9Smrg	    }
4315c10afb9Smrg
4325c10afb9Smrg	    prevProxy = proxy;
4335c10afb9Smrg	    proxy = proxy->next;
4345c10afb9Smrg	}
4355c10afb9Smrg
4365c10afb9Smrg	service = service->next;
4375c10afb9Smrg    }
4385c10afb9Smrg}
4395c10afb9Smrg
4405c10afb9Smrg
4415c10afb9Smrg/*
4425c10afb9Smrg * GetRuningProxyList returns a list of current proxies for a given
4435c10afb9Smrg * service.  The list is ordered, with proxies serving an address that
4445c10afb9Smrg * matches the argument appearing first on the list and all others
4455c10afb9Smrg * appearing at the end.  If a proxy ever refused a request for additional
4465c10afb9Smrg * service then it is excluded from the list if it doesn't match the
4475c10afb9Smrg * server address.
4485c10afb9Smrg */
4495c10afb9Smrgrunning_proxy_list *
4505c10afb9SmrgGetRunningProxyList (
4515c10afb9Smrg    char *serviceName, char *serverAddress)
4525c10afb9Smrg
4535c10afb9Smrg{
4545c10afb9Smrg    proxy_service *service = FindProxyService (serviceName, False);
4555c10afb9Smrg    running_proxy **proxyList, *proxy;
4565c10afb9Smrg    running_proxy_list *runList;
4575c10afb9Smrg    int headIndex, tailIndex;
4585c10afb9Smrg
4595c10afb9Smrg    if (!service || !service->proxyCount)
4605c10afb9Smrg	return NULL;
4615c10afb9Smrg
462cf2f63c2Smrg    runList = malloc (sizeof (running_proxy_list) +
4635c10afb9Smrg	service->proxyCount * sizeof (running_proxy *));
4645c10afb9Smrg
4655c10afb9Smrg    if (!runList)
4665c10afb9Smrg	return NULL;
4675c10afb9Smrg
4685c10afb9Smrg    runList->count = 0;
4695c10afb9Smrg    runList->current = 0;
4705c10afb9Smrg    runList->list = proxyList = (running_proxy **) (runList + 1);
4715c10afb9Smrg
4725c10afb9Smrg    proxy = service->proxyList;
4735c10afb9Smrg    headIndex = 0;
4745c10afb9Smrg    tailIndex = service->proxyCount - 1;
4755c10afb9Smrg
4765c10afb9Smrg    while (proxy)
4775c10afb9Smrg    {
4785c10afb9Smrg	server_list *server = proxy->servers;
4795c10afb9Smrg	int match = 0;
4805c10afb9Smrg
4815c10afb9Smrg	while (server)
4825c10afb9Smrg	{
4835c10afb9Smrg	    if (strcmp (server->serverAddress, serverAddress) == 0)
4845c10afb9Smrg	    {
4855c10afb9Smrg		match = 1;
4865c10afb9Smrg		break;
4875c10afb9Smrg	    }
4885c10afb9Smrg
4895c10afb9Smrg	    server = server->next;
4905c10afb9Smrg	}
4915c10afb9Smrg
4925c10afb9Smrg	if (match) {
4935c10afb9Smrg	    proxyList[headIndex++] = proxy;
4945c10afb9Smrg	    runList->count++;
4955c10afb9Smrg	}
4965c10afb9Smrg	else if (! proxy->refused_service) {
4975c10afb9Smrg	    proxyList[tailIndex--] = proxy;
4985c10afb9Smrg	    runList->count++;
4995c10afb9Smrg	}
5005c10afb9Smrg
5015c10afb9Smrg	proxy = proxy->next;
5025c10afb9Smrg    }
5035c10afb9Smrg
5045c10afb9Smrg    if (!runList->count) {
5055c10afb9Smrg	free ((char*)runList);
5065c10afb9Smrg	return NULL;
5075c10afb9Smrg    }
5085c10afb9Smrg
5095c10afb9Smrg    /* if we didn't fill the list due to skipping proxies that had previously
5105c10afb9Smrg     * refused to service a new address, then remove the gaps in the list
5115c10afb9Smrg     * between the matched and unmatched server names
5125c10afb9Smrg     */
5135c10afb9Smrg    if (runList->count < service->proxyCount) {
5145c10afb9Smrg	while (tailIndex < service->proxyCount - 1)
5155c10afb9Smrg	    proxyList[headIndex++] = proxyList[++tailIndex];
5165c10afb9Smrg    }
5175c10afb9Smrg
5185c10afb9Smrg    return runList;
5195c10afb9Smrg}
5205c10afb9Smrg
5215c10afb9Smrg
5225c10afb9Smrgvoid
5235c10afb9SmrgFreeProxyList (running_proxy_list *list)
5245c10afb9Smrg
5255c10afb9Smrg{
5265c10afb9Smrg    free (list);
5275c10afb9Smrg}
5285c10afb9Smrg
5295c10afb9Smrg
5305c10afb9SmrgStatus
5315c10afb9SmrgPushRequestorQueue (
5325c10afb9Smrg    running_proxy *proxy,
5335c10afb9Smrg    PMconn *requestor,
5345c10afb9Smrg    running_proxy_list *runList,
5355c10afb9Smrg    char *serviceName,
5365c10afb9Smrg    char *serverAddress,
5375c10afb9Smrg    char *hostAddress,
5385c10afb9Smrg    char *startOptions,
5395c10afb9Smrg    int authLen,
5405c10afb9Smrg    char *authName,
5415c10afb9Smrg    char *authData)
5425c10afb9Smrg
5435c10afb9Smrg{
544cf2f63c2Smrg    request_list *newreq = malloc (sizeof (request_list));
5455c10afb9Smrg
5465c10afb9Smrg    if (!newreq)
5475c10afb9Smrg	return 0;
5485c10afb9Smrg
549cf2f63c2Smrg    newreq->serviceName = strdup (serviceName);
550cf2f63c2Smrg    newreq->serverAddress = strdup (serverAddress);
551cf2f63c2Smrg    newreq->hostAddress = strdup (hostAddress);
552cf2f63c2Smrg    newreq->startOptions = strdup (startOptions);
5535c10afb9Smrg    if (authLen > 0)
5545c10afb9Smrg    {
555cf2f63c2Smrg	newreq->authName = strdup (authName);
556cf2f63c2Smrg	newreq->authData = malloc (authLen);
5575c10afb9Smrg    }
558cf2f63c2Smrg    else
559cf2f63c2Smrg	newreq->authName = newreq->authData = NULL;
5605c10afb9Smrg
5615c10afb9Smrg    if (!newreq->serviceName ||
5625c10afb9Smrg	!newreq->serverAddress ||
5635c10afb9Smrg	!newreq->hostAddress ||
5645c10afb9Smrg	!newreq->startOptions ||
5655c10afb9Smrg	(authLen > 0 && (!newreq->authName || !newreq->authData)))
5665c10afb9Smrg    {
567cf2f63c2Smrg	free (newreq->serviceName);
568cf2f63c2Smrg	free (newreq->serverAddress);
569cf2f63c2Smrg	free (newreq->hostAddress);
570cf2f63c2Smrg	free (newreq->startOptions);
571cf2f63c2Smrg	free (newreq->authName);
572cf2f63c2Smrg	free (newreq->authData);
5735c10afb9Smrg	free (newreq);
5745c10afb9Smrg	return 0;
5755c10afb9Smrg    }
5765c10afb9Smrg
5775c10afb9Smrg    if (authLen > 0)
5785c10afb9Smrg    {
5795c10afb9Smrg	memcpy (newreq->authData, authData, authLen);
5805c10afb9Smrg    }
5815c10afb9Smrg
5825c10afb9Smrg    newreq->requestor = requestor;
5835c10afb9Smrg    newreq->listData = (char *) runList;
5845c10afb9Smrg    newreq->authLen = authLen;
5855c10afb9Smrg    newreq->next = NULL;
5865c10afb9Smrg
5875c10afb9Smrg    if (proxy->requests == NULL)
5885c10afb9Smrg	proxy->requests = newreq;
5895c10afb9Smrg    else
5905c10afb9Smrg    {
5915c10afb9Smrg	request_list *p = proxy->requests;
5925c10afb9Smrg
5935c10afb9Smrg	while (p->next)
5945c10afb9Smrg	    p = p->next;
5955c10afb9Smrg
5965c10afb9Smrg	p->next = newreq;
5975c10afb9Smrg    }
5985c10afb9Smrg
5995c10afb9Smrg    return 1;
6005c10afb9Smrg}
6015c10afb9Smrg
6025c10afb9Smrg
6035c10afb9SmrgStatus
6045c10afb9SmrgPeekRequestorQueue (
6055c10afb9Smrg    PMconn *pmConn,
6065c10afb9Smrg    PMconn **requestor,
6075c10afb9Smrg    running_proxy_list **runList,
6085c10afb9Smrg    char **serviceName,
6095c10afb9Smrg    char **serverAddress,
6105c10afb9Smrg    char **hostAddress,
6115c10afb9Smrg    char **startOptions,
6125c10afb9Smrg    int *authLen,
6135c10afb9Smrg    char **authName,
6145c10afb9Smrg    char **authData)
6155c10afb9Smrg{
6165c10afb9Smrg    running_proxy *proxy = ProxyForPMconn (pmConn);
6175c10afb9Smrg
6185c10afb9Smrg    if (proxy && proxy->requests) {
6195c10afb9Smrg	if (requestor)
6205c10afb9Smrg	    *requestor = proxy->requests->requestor;
6215c10afb9Smrg	if (runList)
6225c10afb9Smrg	    *runList = (running_proxy_list *)
6235c10afb9Smrg		proxy->requests->listData;
6245c10afb9Smrg	if (serviceName)
6255c10afb9Smrg	    *serviceName = proxy->requests->serviceName;
6265c10afb9Smrg	if (serverAddress)
6275c10afb9Smrg	    *serverAddress = proxy->requests->serverAddress;
6285c10afb9Smrg	if (hostAddress)
6295c10afb9Smrg	    *hostAddress = proxy->requests->hostAddress;
6305c10afb9Smrg	if (startOptions)
6315c10afb9Smrg	    *startOptions = proxy->requests->startOptions;
6325c10afb9Smrg	if (authLen)
6335c10afb9Smrg	    *authLen = proxy->requests->authLen;
6345c10afb9Smrg	if (authName)
6355c10afb9Smrg	    *authName = proxy->requests->authName;
6365c10afb9Smrg	if (authData)
6375c10afb9Smrg	    *authData = proxy->requests->authData;
6385c10afb9Smrg
6395c10afb9Smrg	return 1;
6405c10afb9Smrg    }
6415c10afb9Smrg    else
6425c10afb9Smrg	return 0;
6435c10afb9Smrg}
6445c10afb9Smrg
6455c10afb9Smrg
6465c10afb9Smrgrunning_proxy *
6475c10afb9SmrgProxyForPMconn (
6485c10afb9Smrg    PMconn *pmConn)
6495c10afb9Smrg{
6505c10afb9Smrg    proxy_service *service = proxyServiceList;
6515c10afb9Smrg
6525c10afb9Smrg    while (service)
6535c10afb9Smrg    {
6545c10afb9Smrg	running_proxy *proxy = service->proxyList;
6555c10afb9Smrg
6565c10afb9Smrg	while (proxy)
6575c10afb9Smrg	{
6585c10afb9Smrg	    if (proxy->pmConn == pmConn)
6595c10afb9Smrg		return proxy;
6605c10afb9Smrg	    else
6615c10afb9Smrg		proxy = proxy->next;
6625c10afb9Smrg	}
6635c10afb9Smrg
6645c10afb9Smrg	service = service->next;
6655c10afb9Smrg    }
6665c10afb9Smrg
6675c10afb9Smrg    return NULL;
6685c10afb9Smrg}
6695c10afb9Smrg
6705c10afb9Smrg
6715c10afb9SmrgPMconn*
6725c10afb9SmrgPopRequestorQueue (
6735c10afb9Smrg    PMconn *pmConn,
6745c10afb9Smrg    Bool addServer,		/* record this server address */
6755c10afb9Smrg    Bool freeProxyList)
6765c10afb9Smrg{
6775c10afb9Smrg    running_proxy *proxy = ProxyForPMconn (pmConn);
6785c10afb9Smrg
6795c10afb9Smrg    if (proxy) {
6805c10afb9Smrg	PMconn *requestor;
6815c10afb9Smrg	server_list *server;
6825c10afb9Smrg	request_list *nextreq;
6835c10afb9Smrg	Bool newServer = False;
6845c10afb9Smrg
6855c10afb9Smrg	if (addServer) {
6865c10afb9Smrg	    newServer = True;
6875c10afb9Smrg	    server = proxy->servers;
6885c10afb9Smrg
6895c10afb9Smrg	    while (server)
6905c10afb9Smrg	    {
6915c10afb9Smrg		if (strcmp (server->serverAddress,
6925c10afb9Smrg		    proxy->requests->serverAddress) == 0)
6935c10afb9Smrg		{
6945c10afb9Smrg		    newServer = False;
6955c10afb9Smrg		    break;
6965c10afb9Smrg		}
6975c10afb9Smrg
6985c10afb9Smrg		server = server->next;
6995c10afb9Smrg	    }
7005c10afb9Smrg
7015c10afb9Smrg	    if (newServer)
7025c10afb9Smrg	    {
703cf2f63c2Smrg		server = malloc (sizeof (server_list));
7045c10afb9Smrg		server->serverAddress = proxy->requests->serverAddress;
7055c10afb9Smrg		server->next = proxy->servers;
7065c10afb9Smrg		proxy->servers = server;
7075c10afb9Smrg	    }
7085c10afb9Smrg	}
7095c10afb9Smrg
7105c10afb9Smrg	if (!newServer)
7115c10afb9Smrg	    free (proxy->requests->serverAddress);
7125c10afb9Smrg
713cf2f63c2Smrg	free (proxy->requests->serviceName);
714cf2f63c2Smrg	free (proxy->requests->hostAddress);
715cf2f63c2Smrg	free (proxy->requests->startOptions);
716cf2f63c2Smrg	free (proxy->requests->listData);	/* proxyList */
717cf2f63c2Smrg	free (proxy->requests->authName);
718cf2f63c2Smrg	free (proxy->requests->authData);
7195c10afb9Smrg
7205c10afb9Smrg	requestor = proxy->requests->requestor;
7215c10afb9Smrg
7225c10afb9Smrg	nextreq = proxy->requests->next;
7235c10afb9Smrg	free (proxy->requests);
7245c10afb9Smrg	proxy->requests = nextreq;
7255c10afb9Smrg
7265c10afb9Smrg	return requestor;
7275c10afb9Smrg    }
7285c10afb9Smrg
7295c10afb9Smrg    return NULL;
7305c10afb9Smrg}
731