Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afsadmsvr / TaAfsAdmSvrClientBind.cpp
blob5589f32b0db50e64e1a646e579ea56700777ea71
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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
8 */
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
18 #include "TaAfsAdmSvrClientInternal.h"
20 extern "C" {
21 #include <afs/afs_AdminErrors.h>
22 } // extern "C"
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(); ; )
58 #ifdef notdef
59 // First we'll enumerate the name services around here to see if
60 // an admin server is already running.
62 RPC_NS_HANDLE hEnum;
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);
69 if (status)
70 RpcBindingFree (&hBind);
71 else if (ValidateBinding (hBind, pidClient, (ULONG*)&status))
72 return TRUE;
73 else if (status != RPC_S_CALL_FAILED_DNE) // server rejected us!
74 break;
76 #endif
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);
87 if (status)
88 RpcBindingFree (&hBind);
89 else if (ValidateBinding (hBind, pidClient, (ULONG*)&status))
90 return TRUE;
91 else if (status != RPC_S_CALL_FAILED_DNE) // server rejected us!
92 break;
95 // If we can't wait any longer, fail. Otherwise, sleep for a little bit
96 // and try again.
98 if ((!fWait) || (GetTickCount() - dwTickStart > cmsecLOCAL_BIND_TIMEOUT))
99 break;
101 Sleep (cmsecLOCAL_BIND_SLEEP);
104 if (pStatus)
105 *pStatus = (LONG)status;
106 return FALSE;
110 BOOL ADMINAPI UnbindFromAdminServer (UINT_PTR idClient, ULONG *pStatus)
112 BOOL rc = TRUE;
113 ULONG status = 0;
115 RpcTryExcept
117 ULONG status;
118 AfsAdmSvr_Disconnect (idClient, &status);
120 RpcExcept(1)
122 RpcEndExcept
124 if ((status = RpcBindingFree (&hBindTaAfsAdminSvr)) != 0)
125 rc = FALSE;
127 if (!rc && pStatus)
128 *pStatus = (LONG)status;
129 return rc;
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);
140 LPTSTR pch;
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);
157 UINT hInst;
158 if ((hInst = WinExec (szFile, SW_HIDE)) <= 32)
160 if (pStatus)
161 *pStatus = (DWORD)hInst;
162 return FALSE;
165 return TRUE;
169 BOOL ValidateBinding (RPC_NS_HANDLE hBind, UINT_PTR *pidClient, ULONG *pStatus)
171 RPC_NS_HANDLE hBindOld = hBindTaAfsAdminSvr;
172 BOOL rc = FALSE;
173 ULONG status = RPC_S_CALL_FAILED_DNE;
175 hBindTaAfsAdminSvr = hBind;
177 RpcTryExcept
179 STRING szMyName;
180 gethostname (szMyName, cchSTRING);
182 rc = AfsAdmSvr_Connect (szMyName, pidClient, &status);
184 RpcExcept(1)
186 rc = FALSE;
187 status = RPC_S_CALL_FAILED_DNE;
189 RpcEndExcept
191 if (!rc)
192 hBindTaAfsAdminSvr = hBindOld;
193 if (!rc && pStatus)
194 *pStatus = status;
195 return rc;
199 LPCTSTR ADMINAPI ResolveAddress (LPCTSTR pszAddress)
201 if (!pszAddress || !*pszAddress)
202 return NULL;
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')))
209 return pszAddress;
211 HOSTENT *pEntry;
212 if ((pEntry = gethostbyname (pszAddress)) == NULL)
213 return pszAddress; // we'll try it by name, but it probly won't work.
215 try {
216 static TCHAR szResolved[ 1024 ];
217 lstrcpy (szResolved, inet_ntoa (*(struct in_addr *)pEntry->h_addr));
218 return szResolved;
219 } catch (...) {
220 return pszAddress; // we'll try it by name, but it probly won't work.