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
11 #include <afs/param.h>
15 #include "TaAfsAdmSvrClientInternal.h"
18 #include <afs/afs_AdminErrors.h>
23 * DEFINITIONS ________________________________________________________________
27 #define cmsecLOCAL_BIND_TIMEOUT (15L * 1000L) // wait up to 15 seconds to bind
28 #define cmsecLOCAL_BIND_SLEEP (1L * 1000L) // sleep for a second between
32 * PROTOTYPES _________________________________________________________________
36 BOOL ValidateBinding (RPC_NS_HANDLE hBind, UINT_PTR *pidClient, ULONG *pStatus);
40 * ROUTINES ___________________________________________________________________
44 BOOL ADMINAPI BindToAdminServer (LPCTSTR pszAddress, BOOL fWait, UINT_PTR *pidClient, ULONG *pStatus)
46 RPC_STATUS status = 0;
48 unsigned char *pszPROTOCOL = (unsigned char *)"ncacn_ip_tcp";
49 unsigned char *pszENTRYNAME = (unsigned char *)AFSADMSVR_ENTRYNAME_DEFAULT;
50 unsigned char szEndpoint[ 32 ];
51 wsprintf ((LPTSTR)szEndpoint, "%lu", AFSADMSVR_ENDPOINT_DEFAULT);
53 for (DWORD dwTickStart = GetTickCount(); ; )
55 // First we'll enumerate the name services around here to see if
56 // an admin server is already running.
59 if ((status = RpcNsBindingImportBegin (RPC_C_NS_SYNTAX_DEFAULT, pszENTRYNAME, ITaAfsAdminSvr_v1_0_c_ifspec, NULL, &hEnum)) == 0)
61 RPC_BINDING_HANDLE hBind;
62 status = RpcNsBindingImportNext (hEnum, &hBind);
63 RpcNsBindingImportDone (&hEnum);
66 RpcBindingFree (&hBind);
67 else if (ValidateBinding (hBind, pidClient, (ULONG*)&status))
69 else if (status != RPC_S_CALL_FAILED_DNE) // server rejected us!
73 // Failing that, we'll try to bind to the well-known endpoint that the
74 // admin server may have had to use. (if RpcNsBindingExport failed.)
76 unsigned char *pszStringBinding = NULL;
77 if ((status = RpcStringBindingCompose (NULL, pszPROTOCOL, (unsigned char *)pszAddress, szEndpoint, NULL, &pszStringBinding)) == 0)
79 RPC_BINDING_HANDLE hBind;
80 status = RpcBindingFromStringBinding (pszStringBinding, &hBind);
81 RpcStringFree (&pszStringBinding);
84 RpcBindingFree (&hBind);
85 else if (ValidateBinding (hBind, pidClient, (ULONG*)&status))
87 else if (status != RPC_S_CALL_FAILED_DNE) // server rejected us!
91 // If we can't wait any longer, fail. Otherwise, sleep for a little bit
94 if ((!fWait) || (GetTickCount() - dwTickStart > cmsecLOCAL_BIND_TIMEOUT))
97 Sleep (cmsecLOCAL_BIND_SLEEP);
101 *pStatus = (LONG)status;
106 BOOL ADMINAPI UnbindFromAdminServer (UINT_PTR idClient, ULONG *pStatus)
114 AfsAdmSvr_Disconnect (idClient, &status);
120 if ((status = RpcBindingFree (&hBindTaAfsAdminSvr)) != 0)
124 *pStatus = (LONG)status;
129 BOOL ADMINAPI ForkNewAdminServer (ULONG *pStatus)
131 // Before we can fork a new process, we have to find the program to run.
133 TCHAR szFile[ MAX_PATH ];
134 GetModuleFileName (GetModuleHandle(NULL), szFile, MAX_PATH);
137 if ((pch = (LPTSTR)lstrrchr (szFile, TEXT('\\'))) != NULL)
138 *(1+pch) = TEXT('\0');
139 lstrcat (szFile, AFSADMSVR_PROGRAM);
141 if (GetFileAttributes (szFile) == (DWORD)0xFFFFFFFF)
143 lstrcpy (szFile, AFSADMSVR_PROGRAM); // hope it's on the path
146 // Try to launch the program. Error codes are returns <= 32.
147 // Remember to add the "Timed" keyword, so it will shut itself down
148 // if it's idle too long, and the "Manual" keyword so it won't automatically
149 // start opening a cell and looking around.
151 wsprintf (&szFile[ lstrlen(szFile) ], TEXT(" %s %s"), AFSADMSVR_KEYWORD_TIMED, AFSADMSVR_KEYWORD_MANUAL);
154 if ((hInst = WinExec (szFile, SW_HIDE)) <= 32)
157 *pStatus = (DWORD)hInst;
165 BOOL ValidateBinding (RPC_NS_HANDLE hBind, UINT_PTR *pidClient, ULONG *pStatus)
167 RPC_NS_HANDLE hBindOld = hBindTaAfsAdminSvr;
169 ULONG status = RPC_S_CALL_FAILED_DNE;
171 hBindTaAfsAdminSvr = hBind;
176 gethostname (szMyName, cchSTRING);
178 rc = AfsAdmSvr_Connect (szMyName, pidClient, &status);
183 status = RPC_S_CALL_FAILED_DNE;
188 hBindTaAfsAdminSvr = hBindOld;
195 LPCTSTR ADMINAPI ResolveAddress (LPCTSTR pszAddress)
197 if (!pszAddress || !*pszAddress)
200 // The caller may have specified an IP address or a server name.
201 // If the former, we're done; if the latter, we'll have to look up
202 // the server's IP address.
204 if ((*pszAddress >= TEXT('0')) && (*pszAddress <= TEXT('9')))
208 if ((pEntry = gethostbyname (pszAddress)) == NULL)
209 return pszAddress; // we'll try it by name, but it probly won't work.
212 static TCHAR szResolved[ 1024 ];
213 lstrcpy (szResolved, inet_ntoa (*(struct in_addr *)pEntry->h_addr));
216 return pszAddress; // we'll try it by name, but it probly won't work.