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