2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
14 #include <afs/param.h>
18 #include "TaAfsAdmSvrClientInternal.h"
21 #include <afs/afs_AdminErrors.h>
26 * DEFINITIONS ________________________________________________________________
30 #define cmsecLOCAL_BIND_TIMEOUT (15L * 1000L) // wait up to 15 seconds to bind
31 #define cmsecLOCAL_BIND_SLEEP (1L * 1000L) // sleep for a second between
35 * PROTOTYPES _________________________________________________________________
39 BOOL ValidateBinding (RPC_NS_HANDLE hBind, UINT_PTR *pidClient, ULONG *pStatus);
43 * ROUTINES ___________________________________________________________________
47 BOOL ADMINAPI BindToAdminServer (LPCTSTR pszAddress, BOOL fWait, UINT_PTR *pidClient, ULONG *pStatus)
49 RPC_STATUS status = 0;
51 unsigned char *pszPROTOCOL = (unsigned char *)"ncacn_ip_tcp";
52 unsigned char *pszENTRYNAME = (unsigned char *)AFSADMSVR_ENTRYNAME_DEFAULT;
53 unsigned char szEndpoint[ 32 ];
54 wsprintf ((LPTSTR)szEndpoint, "%lu", AFSADMSVR_ENDPOINT_DEFAULT);
56 for (DWORD dwTickStart = GetTickCount(); ; )
59 // First we'll enumerate the name services around here to see if
60 // an admin server is already running.
63 if ((status = RpcNsBindingImportBegin (RPC_C_NS_SYNTAX_DEFAULT, pszENTRYNAME, ITaAfsAdminSvr_v1_0_c_ifspec, NULL, &hEnum)) == 0)
65 RPC_BINDING_HANDLE hBind;
66 status = RpcNsBindingImportNext (hEnum, &hBind);
67 RpcNsBindingImportDone (&hEnum);
70 RpcBindingFree (&hBind);
71 else if (ValidateBinding (hBind, pidClient, (ULONG*)&status))
73 else if (status != RPC_S_CALL_FAILED_DNE) // server rejected us!
77 // Failing that, we'll try to bind to the well-known endpoint that the
78 // admin server may have had to use. (if RpcNsBindingExport failed.)
80 unsigned char *pszStringBinding = NULL;
81 if ((status = RpcStringBindingCompose (NULL, pszPROTOCOL, (unsigned char *)pszAddress, szEndpoint, NULL, &pszStringBinding)) == 0)
83 RPC_BINDING_HANDLE hBind;
84 status = RpcBindingFromStringBinding (pszStringBinding, &hBind);
85 RpcStringFree (&pszStringBinding);
88 RpcBindingFree (&hBind);
89 else if (ValidateBinding (hBind, pidClient, (ULONG*)&status))
91 else if (status != RPC_S_CALL_FAILED_DNE) // server rejected us!
95 // If we can't wait any longer, fail. Otherwise, sleep for a little bit
98 if ((!fWait) || (GetTickCount() - dwTickStart > cmsecLOCAL_BIND_TIMEOUT))
101 Sleep (cmsecLOCAL_BIND_SLEEP);
105 *pStatus = (LONG)status;
110 BOOL ADMINAPI UnbindFromAdminServer (UINT_PTR idClient, ULONG *pStatus)
118 AfsAdmSvr_Disconnect (idClient, &status);
124 if ((status = RpcBindingFree (&hBindTaAfsAdminSvr)) != 0)
128 *pStatus = (LONG)status;
133 BOOL ADMINAPI ForkNewAdminServer (ULONG *pStatus)
135 // Before we can fork a new process, we have to find the program to run.
137 TCHAR szFile[ MAX_PATH ];
138 GetModuleFileName (GetModuleHandle(NULL), szFile, MAX_PATH);
141 if ((pch = (LPTSTR)lstrrchr (szFile, TEXT('\\'))) != NULL)
142 *(1+pch) = TEXT('\0');
143 lstrcat (szFile, AFSADMSVR_PROGRAM);
145 if (GetFileAttributes (szFile) == (DWORD)0xFFFFFFFF)
147 lstrcpy (szFile, AFSADMSVR_PROGRAM); // hope it's on the path
150 // Try to launch the program. Error codes are returns <= 32.
151 // Remember to add the "Timed" keyword, so it will shut itself down
152 // if it's idle too long, and the "Manual" keyword so it won't automatically
153 // start opening a cell and looking around.
155 wsprintf (&szFile[ lstrlen(szFile) ], TEXT(" %s %s"), AFSADMSVR_KEYWORD_TIMED, AFSADMSVR_KEYWORD_MANUAL);
158 if ((hInst = WinExec (szFile, SW_HIDE)) <= 32)
161 *pStatus = (DWORD)hInst;
169 BOOL ValidateBinding (RPC_NS_HANDLE hBind, UINT_PTR *pidClient, ULONG *pStatus)
171 RPC_NS_HANDLE hBindOld = hBindTaAfsAdminSvr;
173 ULONG status = RPC_S_CALL_FAILED_DNE;
175 hBindTaAfsAdminSvr = hBind;
180 gethostname (szMyName, cchSTRING);
182 rc = AfsAdmSvr_Connect (szMyName, pidClient, &status);
187 status = RPC_S_CALL_FAILED_DNE;
192 hBindTaAfsAdminSvr = hBindOld;
199 LPCTSTR ADMINAPI ResolveAddress (LPCTSTR pszAddress)
201 if (!pszAddress || !*pszAddress)
204 // The caller may have specified an IP address or a server name.
205 // If the former, we're done; if the latter, we'll have to look up
206 // the server's IP address.
208 if ((*pszAddress >= TEXT('0')) && (*pszAddress <= TEXT('9')))
212 if ((pEntry = gethostbyname (pszAddress)) == NULL)
213 return pszAddress; // we'll try it by name, but it probly won't work.
216 static TCHAR szResolved[ 1024 ];
217 lstrcpy (szResolved, inet_ntoa (*(struct in_addr *)pEntry->h_addr));
220 return pszAddress; // we'll try it by name, but it probly won't work.