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.