Windows: AFSTearDownExtents may experience active extents
[openafs.git] / src / WINNT / afssvrmgr / svr_address.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
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  */
9
10 #include <winsock2.h>
11 #include <ws2tcpip.h>
12
13 extern "C" {
14 #include <afs/param.h>
15 #include <afs/stds.h>
16 }
17
18 #include "svrmgr.h"
19 #include "svr_address.h"
20 #include <stdlib.h>
21
22 /*
23  * PROTOTYPES _________________________________________________________________
24  *
25  */
26
27 void ChangeAddr_OnInitDialog (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp);
28 void ChangeAddr_Enable (HWND hDlg, BOOL fEnable);
29 void ChangeAddr_OnSelect (HWND hDlg);
30 void ChangeAddr_OnEndTask_Init (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp, LPTASKPACKET ptp);
31 void ChangeAddr_OnRemove (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp);
32 void ChangeAddr_OnChange (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp);
33
34 BOOL CALLBACK NewAddr_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
35 void NewAddr_OnInitDialog (HWND hDlg, LPSOCKADDR_IN pAddr);
36 void NewAddr_OnOK (HWND hDlg, LPSOCKADDR_IN pAddr);
37
38
39 /*
40  * SERVER ADDRESSES ___________________________________________________________
41  *
42  */
43
44 void Server_FillAddrList (HWND hDlg, LPSERVERSTATUS lpss, BOOL fCanAddUnspecified)
45 {
46    HWND hList = GetDlgItem (hDlg, IDC_SVR_ADDRESSES);
47
48    LB_StartChange (hList, TRUE);
49
50    if (!lpss || !lpss->nAddresses)
51       {
52       if (fCanAddUnspecified)
53          (void)LB_AddItem (hList, IDS_SVR_NO_ADDR, (LPARAM)-1);
54       }
55    else for (size_t iAddr = 0; iAddr < lpss->nAddresses; ++iAddr)
56       {
57       int AddrInt;
58       AfsClass_AddressToInt (&AddrInt, &lpss->aAddresses[ iAddr ]);
59       if (AddrInt == 0)
60          continue;
61
62       LPTSTR pszAddress = FormatString (TEXT("%1"), TEXT("%a"), &lpss->aAddresses[ iAddr ]);
63       (void)LB_AddItem (hList, pszAddress, (LPARAM)iAddr);
64       FreeString (pszAddress);
65       }
66
67    LB_EndChange (hList, 0);
68 }
69
70
71 void Server_ParseAddress (LPSOCKADDR_IN pAddr, LPTSTR pszText)
72 {
73    int addrNetwork = inet_addr (pszText);
74
75    memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
76    pAddr->sin_family = AF_INET;
77    pAddr->sin_addr.s_addr = addrNetwork;
78 }
79
80
81 BOOL Server_Ping (LPSOCKADDR_IN pAddr, LPCTSTR pszServerName)
82 {
83    BOOL rc = FALSE;
84
85    try {
86       struct hostent *phe;
87       if ((phe = gethostbyname (pszServerName)) == NULL)
88          memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
89       else
90          {
91          memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
92          pAddr->sin_family = 2;
93          pAddr->sin_port = 0;
94          pAddr->sin_addr.s_addr = *(ULONG *)phe->h_addr;
95          rc = TRUE;
96          }
97       }
98    catch (...)
99       {
100       memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
101       }
102
103    return rc;
104 }
105
106
107 BOOL CALLBACK ChangeAddr_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
108 {
109    if (AfsAppLib_HandleHelp (IDD_SVR_ADDRESS, hDlg, msg, wp, lp))
110       return TRUE;
111
112    if (msg == WM_INITDIALOG)
113       SetWindowLongPtr (hDlg, DWLP_USER, lp);
114
115    LPSVR_CHANGEADDR_PARAMS lpp;
116    if ((lpp = (LPSVR_CHANGEADDR_PARAMS)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
117       {
118       switch (msg)
119          {
120          case WM_INITDIALOG:
121             ChangeAddr_OnInitDialog (hDlg, lpp);
122             StartTask (taskSVR_PROP_INIT, hDlg, lpp->lpiServer);
123             break;
124
125          case WM_ENDTASK:
126             LPTASKPACKET ptp;
127             if ((ptp = (LPTASKPACKET)lp) != NULL)
128                {
129                if (ptp->idTask == taskSVR_PROP_INIT)
130                   ChangeAddr_OnEndTask_Init (hDlg, lpp, ptp);
131                FreeTaskPacket (ptp);
132                }
133             break;
134
135          case WM_COMMAND:
136             switch (LOWORD(wp))
137                {
138                case IDC_SVR_ADDRESSES:
139                   if (HIWORD(wp) == LBN_SELCHANGE)
140                      ChangeAddr_OnSelect (hDlg);
141                   break;
142
143                case IDC_ADDR_CHANGE:
144                   ChangeAddr_OnChange (hDlg, lpp);
145                   break;
146
147                case IDC_ADDR_REMOVE:
148                   ChangeAddr_OnRemove (hDlg, lpp);
149                   break;
150
151                case IDOK:
152                   EndDialog (hDlg, IDOK);
153                   break;
154
155                case IDCANCEL:
156                   EndDialog (hDlg, IDCANCEL);
157                   break;
158                }
159             break;
160          }
161       }
162
163    return FALSE;
164 }
165
166
167 void ChangeAddr_OnInitDialog (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp)
168 {
169    TCHAR szName[ cchNAME ];
170    lpp->lpiServer->GetServerName (szName);
171
172    TCHAR szText[ cchRESOURCE ];
173    GetDlgItemText (hDlg, IDC_TITLE, szText, cchRESOURCE);
174
175    LPTSTR pszTitle = FormatString (szText, TEXT("%s"), szName);
176    SetDlgItemText (hDlg, IDC_TITLE, pszTitle);
177    FreeString (pszTitle);
178
179    HWND hList = GetDlgItem (hDlg, IDC_SVR_ADDRESSES);
180    LB_StartChange (hList, TRUE);
181    LB_AddItem (hList, IDS_QUERYING, 0);
182    LB_EndChange (hList, 0);
183
184    ChangeAddr_Enable (hDlg, FALSE);
185 }
186
187
188 void ChangeAddr_Enable (HWND hDlg, BOOL fEnable)
189 {
190    EnableWindow (GetDlgItem (hDlg, IDC_SVR_ADDRESSES), fEnable);
191    EnableWindow (GetDlgItem (hDlg, IDC_ADDR_CHANGE), fEnable);
192    EnableWindow (GetDlgItem (hDlg, IDC_ADDR_REMOVE), fEnable);
193
194    if (fEnable)
195       ChangeAddr_OnSelect (hDlg);
196 }
197
198
199 void ChangeAddr_OnSelect (HWND hDlg)
200 {
201    HWND hList = GetDlgItem (hDlg, IDC_SVR_ADDRESSES);
202    BOOL fSelected = (LB_GetSelected (hList) != -1) ? TRUE : FALSE;
203
204    EnableWindow (GetDlgItem (hDlg, IDC_ADDR_CHANGE), fSelected);
205    EnableWindow (GetDlgItem (hDlg, IDC_ADDR_REMOVE), fSelected);
206 }
207
208
209 void ChangeAddr_OnEndTask_Init (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp, LPTASKPACKET ptp)
210 {
211    if (!ptp->rc)
212       {
213       TCHAR szName[ cchNAME ];
214       lpp->lpiServer->GetServerName (szName);
215       ErrorDialog (ptp->status, IDS_ERROR_REFRESH_SERVER_STATUS, TEXT("%s"), szName);
216       }
217    else
218       {
219       memcpy (&lpp->ssOld, &TASKDATA(ptp)->ss, sizeof(SERVERSTATUS));
220       memcpy (&lpp->ssNew, &TASKDATA(ptp)->ss, sizeof(SERVERSTATUS));
221       ChangeAddr_Enable (hDlg, TRUE);
222       }
223
224    Server_FillAddrList (hDlg, &lpp->ssNew, FALSE);
225 }
226
227
228 void ChangeAddr_OnRemove (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp)
229 {
230    HWND hList = GetDlgItem (hDlg, IDC_SVR_ADDRESSES);
231
232    int iSel;
233    if ((iSel = LB_GetSelected (hList)) != -1)
234       {
235       TCHAR szItem[ cchRESOURCE ] = TEXT("");
236       SendMessage (hList, LB_GETTEXT, iSel, (LPARAM)szItem);
237
238       SOCKADDR_IN AddrSel;
239       Server_ParseAddress (&AddrSel, szItem);
240
241       int AddrSelInt;
242       AfsClass_AddressToInt (&AddrSelInt, &AddrSel);
243
244       if (AddrSelInt != 0)
245          {
246          for (size_t iAddr = 0; iAddr < lpp->ssOld.nAddresses; ++iAddr)
247             {
248             int OldAddrInt;
249             AfsClass_AddressToInt (&OldAddrInt, &lpp->ssOld.aAddresses[iAddr]);
250
251             int NewAddrInt;
252             AfsClass_AddressToInt (&NewAddrInt, &lpp->ssNew.aAddresses[iAddr]);
253
254             if ((OldAddrInt == AddrSelInt) || (NewAddrInt == AddrSelInt))
255                {
256                AfsClass_IntToAddress (&lpp->ssNew.aAddresses[iAddr], 0);
257                }
258             }
259          }
260
261       Server_FillAddrList (hDlg, &lpp->ssNew, FALSE);
262       ChangeAddr_OnSelect (hDlg);
263       }
264 }
265
266
267 void ChangeAddr_OnChange (HWND hDlg, LPSVR_CHANGEADDR_PARAMS lpp)
268 {
269    HWND hList = GetDlgItem (hDlg, IDC_SVR_ADDRESSES);
270
271    int iSel;
272    if ((iSel = LB_GetSelected (hList)) != -1)
273       {
274       TCHAR szItem[ cchRESOURCE ] = TEXT("");
275       SendMessage (hList, LB_GETTEXT, iSel, (LPARAM)szItem);
276
277       SOCKADDR_IN AddrSel;
278       Server_ParseAddress (&AddrSel, szItem);
279
280       int AddrSelInt;
281       AfsClass_AddressToInt (&AddrSelInt, &AddrSel);
282
283       if (AddrSelInt != 0)
284          {
285          SOCKADDR_IN AddrNew = AddrSel;
286          if (ModalDialogParam (IDD_SVR_NEWADDR, hDlg, (DLGPROC)NewAddr_DlgProc, (LPARAM)&AddrNew) != IDOK)
287             return;
288
289          int AddrNewInt;
290          AfsClass_AddressToInt (&AddrNewInt, &AddrNew);
291          if (AddrNewInt && (AddrNewInt != AddrSelInt))
292             {
293
294             // First see if the new IP address is already in the server's
295             // list of IP addresses--if so, just delete the old address.
296             //
297             size_t iAddr;
298             for (iAddr = 0; iAddr < lpp->ssOld.nAddresses; ++iAddr)
299                {
300                int OldAddrInt;
301                AfsClass_AddressToInt (&OldAddrInt, &lpp->ssOld.aAddresses[iAddr]);
302
303                int NewAddrInt;
304                AfsClass_AddressToInt (&NewAddrInt, &lpp->ssNew.aAddresses[iAddr]);
305
306                if ((OldAddrInt == AddrNewInt) || (NewAddrInt == AddrNewInt))
307                   {
308                   AddrNewInt = 0;
309                   break;
310                   }
311                }
312
313             // Now update the SERVERSTATUS structure.
314             //
315             for (iAddr = 0; iAddr < lpp->ssOld.nAddresses; ++iAddr)
316                {
317                int OldAddrInt;
318                AfsClass_AddressToInt (&OldAddrInt, &lpp->ssOld.aAddresses[iAddr]);
319
320                int NewAddrInt;
321                AfsClass_AddressToInt (&NewAddrInt, &lpp->ssNew.aAddresses[iAddr]);
322
323                if ((OldAddrInt == AddrSelInt) || (NewAddrInt == AddrSelInt))
324                   {
325                   AfsClass_IntToAddress (&lpp->ssNew.aAddresses[iAddr], AddrNewInt);
326                   break;
327                   }
328                }
329             }
330          }
331
332       Server_FillAddrList (hDlg, &lpp->ssNew, FALSE);
333       ChangeAddr_OnSelect (hDlg);
334       }
335 }
336
337
338 BOOL CALLBACK NewAddr_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
339 {
340    if (AfsAppLib_HandleHelp (IDD_SVR_NEWADDR, hDlg, msg, wp, lp))
341       return TRUE;
342
343    if (msg == WM_INITDIALOG)
344       SetWindowLongPtr (hDlg, DWLP_USER, lp);
345
346    LPSOCKADDR_IN pAddr;
347    if ((pAddr = (LPSOCKADDR_IN)GetWindowLongPtr (hDlg, DWLP_USER)) != NULL)
348       {
349       switch (msg)
350          {
351          case WM_INITDIALOG:
352             NewAddr_OnInitDialog (hDlg, pAddr);
353             break;
354
355          case WM_COMMAND:
356             switch (LOWORD(wp))
357                {
358                case IDOK:
359                   NewAddr_OnOK (hDlg, pAddr);
360                   EndDialog (hDlg, IDOK);
361                   break;
362
363                case IDCANCEL:
364                   EndDialog (hDlg, IDCANCEL);
365                   break;
366                }
367             break;
368          }
369       }
370
371    return FALSE;
372 }
373
374
375 void NewAddr_OnInitDialog (HWND hDlg, LPSOCKADDR_IN pAddr)
376 {
377    TCHAR szText[ cchRESOURCE ];
378    GetDlgItemText (hDlg, IDC_TITLE, szText, cchRESOURCE);
379
380    LPTSTR pszTitle = FormatString (szText, TEXT("%a"), pAddr);
381    SetDlgItemText (hDlg, IDC_TITLE, pszTitle);
382    FreeString (pszTitle);
383
384    SA_SetAddr (GetDlgItem (hDlg, IDC_ADDRESS), pAddr);
385 }
386
387
388 void NewAddr_OnOK (HWND hDlg, LPSOCKADDR_IN pAddr)
389 {
390    SA_GetAddr (GetDlgItem (hDlg, IDC_ADDRESS), pAddr);
391 }
392