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