8a4927482a37c034f918a312e660985dcc96c2c7
[openafs.git] / src / WINNT / client_config / tab_hosts.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 #include <afs/cm_config.h>
17 }
18
19 #include "afs_config.h"
20 #include "tab_hosts.h"
21
22
23 /*
24  * PROTOTYPES _________________________________________________________________
25  *
26  */
27
28 void HostsTab_OnInitDialog (HWND hDlg);
29 BOOL HostsTab_OnApply (HWND hDlg);
30 void HostsTab_OnSelect (HWND hDlg);
31 void HostsTab_OnAdd (HWND hDlg);
32 void HostsTab_OnEdit (HWND hDlg);
33 void HostsTab_OnRemove (HWND hDlg);
34
35 void HostsTab_FillList (HWND hDlg);
36
37 BOOL CALLBACK CellEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
38 void CellEdit_OnInitDialog (HWND hDlg);
39 void CellEdit_OnDestroy (HWND hDlg);
40 void CellEdit_OnApply (HWND hDlg);
41 void CellEdit_OnSelect (HWND hDlg);
42 void CellEdit_OnAdd (HWND hDlg);
43 void CellEdit_OnEdit (HWND hDlg);
44 void CellEdit_OnRemove (HWND hDlg);
45 void CellEdit_Enable (HWND hDlg);
46 void CellEdit_AddServerEntry (HWND hDlg, PCELLDBLINE pLine, int iOrder);
47 int CALLBACK CellEdit_SortFunction (HWND hList, HLISTITEM hItem1, LPARAM lpItem1, HLISTITEM hItem2, LPARAM lpItem2);
48
49 BOOL CALLBACK ServerEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp);
50 void ServerEdit_OnInitDialog (HWND hDlg);
51 BOOL ServerEdit_OnOK (HWND hDlg);
52
53 BOOL TextToAddr (SOCKADDR_IN *pAddr, LPTSTR pszServer);
54
55
56 /*
57  * ROUTINES ___________________________________________________________________
58  *
59  */
60
61 BOOL CALLBACK HostsTab_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
62 {
63    switch (msg)
64       {
65       case WM_INITDIALOG:
66          if (g.fIsCCenter)
67             Main_OnInitDialog (GetParent(hDlg));
68          HostsTab_OnInitDialog (hDlg);
69          break;
70
71       case WM_COMMAND:
72          switch (LOWORD(wp))
73             {
74             case IDAPPLY:
75                if (!HostsTab_OnApply (hDlg))
76                   SetWindowLongPtr (hDlg, DWLP_MSGRESULT, TRUE);
77                break;
78
79             case IDC_ADD:
80                HostsTab_OnAdd (hDlg);
81                break;
82
83             case IDC_EDIT:
84                HostsTab_OnEdit (hDlg);
85                break;
86
87             case IDC_REMOVE:
88                HostsTab_OnRemove (hDlg);
89                break;
90
91             case IDHELP:
92                HostsTab_DlgProc (hDlg, WM_HELP, 0, 0);
93                break;
94             }
95          break;
96
97       case WM_HELP:
98          if (g.fIsCCenter)
99             WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_GENERAL_CCENTER);
100          else
101             WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_CELLS);
102          break;
103
104       case WM_NOTIFY:
105          switch (((LPNMHDR)lp)->code)
106             {
107             case FLN_ITEMSELECT:
108                HostsTab_OnSelect (hDlg);
109                break;
110
111             case FLN_LDBLCLICK:
112                if (IsWindowEnabled (GetDlgItem (hDlg, IDC_EDIT)))
113                   HostsTab_OnEdit (hDlg);
114                break;
115             }
116          break;
117       }
118
119    return FALSE;
120 }
121
122
123 void HostsTab_OnInitDialog (HWND hDlg)
124 {
125    if (!g.Configuration.CellServDB.pFirst)
126       {
127       CSDB_ReadFile (&g.Configuration.CellServDB, NULL);
128
129       // Fill in our list with cell names.
130       //
131       HostsTab_FillList (hDlg);
132       HostsTab_OnSelect (hDlg);
133
134       // If this is the Control Center applet, shove the default cell
135       // name onto the tab too.
136       //
137       if (g.fIsCCenter)
138          {
139          Config_GetCellName (g.Configuration.szCell);
140          SetDlgItemText (hDlg, IDC_CELL, g.Configuration.szCell);
141          }
142       }
143 }
144
145
146 BOOL HostsTab_CommitChanges (BOOL fForce)
147 {
148    HWND hDlg;
149    if ((hDlg = PropSheet_FindTabWindow (g.psh, (DLGPROC)HostsTab_DlgProc)) == NULL)
150       return TRUE;
151    if (fForce)
152       SetWindowLongPtr (hDlg, DWLP_MSGRESULT, FALSE); // Make sure we try to apply
153    if (HostsTab_OnApply (hDlg))
154       return TRUE;
155    SetWindowLongPtr (hDlg, DWLP_MSGRESULT, TRUE);
156    return FALSE;
157 }
158
159
160 BOOL HostsTab_OnApply (HWND hDlg)
161 {
162    // Don't try to do anything if we've already failed the apply
163    if (GetWindowLongPtr (hDlg, DWLP_MSGRESULT))
164       return FALSE;
165
166    if (!CSDB_WriteFile (&g.Configuration.CellServDB))
167       return FALSE;
168
169    // If this is the Control Center applet, we'll have to validate
170    // the cell name too.
171    //
172    if (g.fIsCCenter)
173       {
174       TCHAR szNoCell[ cchRESOURCE ];
175       GetString (szNoCell, IDS_CELL_UNKNOWN);
176
177       TCHAR szCell[ cchRESOURCE ];
178       GetDlgItemText (hDlg, IDC_CELL, szCell, cchRESOURCE);
179
180       if ((!szCell[0]) || (!lstrcmpi (szNoCell, szCell)))
181          {
182          Message (MB_ICONASTERISK | MB_OK, GetErrorTitle(), IDS_NOCELL_DESC_CC);
183          return FALSE;
184          }
185
186       if (!CSDB_FindCell (&g.Configuration.CellServDB, szCell))
187          {
188 #ifdef AFS_AFSDB_ENV
189              int ttl;
190              char cellname[128], i;
191
192              /* we pray for all ascii cellnames */
193              for ( i=0 ; szCell[i] && i < (sizeof(cellname)-1) ; i++ )
194                  cellname[i] = szCell[i];
195              cellname[i] = '\0';
196
197              if (cm_SearchCellByDNS(cellname, NULL, &ttl, NULL, NULL))
198 #endif
199              {
200                  Message (MB_ICONASTERISK | MB_OK, GetErrorTitle(), IDS_BADCELL_DESC_CC);
201                  return FALSE;
202              }
203          }
204
205       if (!Config_SetCellName (szCell))
206          return FALSE;
207       lstrcpy (g.Configuration.szCell, szCell);
208       }
209
210    return TRUE;
211 }
212
213
214 void HostsTab_OnSelect (HWND hDlg)
215 {
216    HWND hList = GetDlgItem (hDlg, IDC_LIST);
217    HLISTITEM hItem = FastList_FindFirstSelected (hList);
218    HLISTITEM hNext = FastList_FindNextSelected (hList, hItem);
219
220    EnableWindow (GetDlgItem (hDlg, IDC_EDIT), !!hItem && !hNext);
221    EnableWindow (GetDlgItem (hDlg, IDC_REMOVE), !!hItem);
222 }
223
224
225 void HostsTab_OnAdd (HWND hDlg)
226 {
227    TCHAR szTitle[ cchRESOURCE ];
228    GetString (szTitle, IDS_CELLADD_TITLE);
229
230    LPPROPSHEET psh = PropSheet_Create (szTitle, FALSE, GetParent(hDlg), 0);
231    psh->sh.dwFlags |= PSH_NOAPPLYNOW;  // Remove the Apply button
232    psh->sh.dwFlags |= PSH_HASHELP;     // Add a Help button instead
233    PropSheet_AddTab (psh, szTitle, IDD_CELL_EDIT, (DLGPROC)CellEdit_DlgProc, 0, TRUE);
234    PropSheet_ShowModal (psh);
235
236    HostsTab_FillList (hDlg);
237    HostsTab_OnSelect (hDlg);
238 }
239
240
241 void HostsTab_OnEdit (HWND hDlg)
242 {
243    HWND hList = GetDlgItem (hDlg, IDC_LIST);
244    HLISTITEM hItem = FastList_FindFirstSelected (hList);
245    if (hItem)
246       {
247       PCELLDBLINE pLine = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
248       CELLDBLINEINFO Info;
249       CSDB_CrackLine (&Info, pLine->szLine);
250
251       LPTSTR pszTitle = FormatString (IDS_CELLEDIT_TITLE, TEXT("%s"), ((Info.szComment[0]) ? Info.szComment : Info.szCell));
252
253       LPPROPSHEET psh = PropSheet_Create (pszTitle, FALSE, GetParent(hDlg), (LPARAM)pLine);
254       psh->sh.dwFlags |= PSH_NOAPPLYNOW;  // Remove the Apply button
255       psh->sh.dwFlags |= PSH_HASHELP;     // Add a Help button instead
256       PropSheet_AddTab (psh, ((Info.szComment[0]) ? Info.szComment : Info.szCell), IDD_CELL_EDIT, (DLGPROC)CellEdit_DlgProc, (LPARAM)pLine, TRUE);
257       PropSheet_ShowModal (psh);
258
259       FreeString (pszTitle);
260       }
261
262    HostsTab_FillList (hDlg);
263    HostsTab_OnSelect (hDlg);
264 }
265
266
267 void HostsTab_OnRemove (HWND hDlg)
268 {
269    HWND hList = GetDlgItem (hDlg, IDC_LIST);
270    HLISTITEM hItem = FastList_FindFirstSelected (hList);
271    HLISTITEM hNext = FastList_FindNextSelected (hList, hItem);
272
273    if (!hItem)
274       {
275       return;
276       }
277    else if (hNext)
278       {
279       if (Message (MB_ICONEXCLAMATION | MB_OKCANCEL, GetCautionTitle(), IDS_HOSTREM_MANY) != IDOK)
280          return;
281       }
282    else // (!hNext)
283       {
284       PCELLDBLINE pLine = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
285       CELLDBLINEINFO Info;
286       CSDB_CrackLine (&Info, pLine->szLine);
287
288       if (Message (MB_ICONEXCLAMATION | MB_OKCANCEL, GetCautionTitle(), IDS_HOSTREM_ONE, TEXT("%s"), Info.szCell) != IDOK)
289          return;
290       }
291
292    for ( ; hItem; hItem = FastList_FindNextSelected (hList, hItem))
293       {
294       PCELLDBLINE pLine = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
295       CSDB_RemoveCell (&g.Configuration.CellServDB, pLine);
296       }
297
298    HostsTab_FillList (hDlg);
299    HostsTab_OnSelect (hDlg);
300 }
301
302
303 void HostsTab_FillList (HWND hDlg)
304 {
305    HWND hList = GetDlgItem (hDlg, IDC_LIST);
306    FastList_Begin (hList);
307    FastList_RemoveAll (hList);
308
309    for (PCELLDBLINE pLine = g.Configuration.CellServDB.pFirst; pLine; pLine = pLine->pNext)
310       {
311       CELLDBLINEINFO Info;
312       if (!CSDB_CrackLine (&Info, pLine->szLine))
313          continue;
314       if (!Info.szCell[0])
315          continue;
316
317       TCHAR szText[ MAX_PATH ];
318       lstrcpy (szText, Info.szCell);
319
320 #if 0 // Add this if you like a more verbose Cell Hosts tab
321       if (Info.szComment)
322          wsprintf (&szText[ lstrlen(szText) ], TEXT(" (%s)"), Info.szComment);
323 #endif
324
325       FASTLISTADDITEM ai;
326       memset (&ai, 0x00, sizeof(ai));
327       ai.iFirstImage = IMAGE_NOIMAGE;
328       ai.iSecondImage = IMAGE_NOIMAGE;
329       ai.pszText = szText;
330       ai.lParam = (LPARAM)pLine;
331       FastList_AddItem (hList, &ai);
332       }
333
334    FastList_End (hList);
335 }
336
337
338 BOOL CALLBACK CellEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
339 {
340    switch (msg)
341       {
342       case WM_INITDIALOG:
343          CellEdit_OnInitDialog (hDlg);
344          break;
345
346       case WM_DESTROY:
347          CellEdit_OnDestroy (hDlg);
348          break;
349
350       case WM_COMMAND:
351          switch (LOWORD(wp))
352             {
353             case IDAPPLY:
354                CellEdit_OnApply (hDlg);
355                break;
356
357             case IDC_CELL:
358                CellEdit_Enable (hDlg);
359                break;
360
361             case IDC_COMMENT:
362                CellEdit_Enable (hDlg);
363                break;
364
365             case IDC_ADD:
366                CellEdit_OnAdd (hDlg);
367                CellEdit_Enable (hDlg);
368                break;
369
370             case IDC_EDIT:
371                CellEdit_OnEdit (hDlg);
372                CellEdit_Enable (hDlg);
373                break;
374
375             case IDC_REMOVE:
376                CellEdit_OnRemove (hDlg);
377                CellEdit_Enable (hDlg);
378                break;
379
380             case IDHELP:
381                CellEdit_DlgProc (hDlg, WM_HELP, 0, 0);
382                break;
383             }
384          break;
385
386       case WM_HELP:
387          if (PropSheet_FindTabParam (hDlg))
388             WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_CELLPROP_EDIT);
389          else
390             WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_CELLPROP_ADD);
391          break;
392
393       case WM_NOTIFY:
394          switch (((LPNMHDR)lp)->code)
395             {
396             case FLN_ITEMSELECT:
397                CellEdit_OnSelect (hDlg);
398                break;
399
400             case FLN_LDBLCLICK:
401                if (IsWindowEnabled (GetDlgItem (hDlg, IDC_EDIT)))
402                   CellEdit_OnEdit (hDlg);
403                CellEdit_Enable (hDlg);
404                break;
405             }
406          break;
407       }
408
409    return FALSE;
410 }
411
412
413 void CellEdit_OnInitDialog (HWND hDlg)
414 {
415    PCELLDBLINE pLine = (PCELLDBLINE)PropSheet_FindTabParam (hDlg);
416    if (pLine)
417       {
418       CELLDBLINEINFO Info;
419       CSDB_CrackLine (&Info, pLine->szLine);
420       SetDlgItemText (hDlg, IDC_CELL, Info.szCell);
421       SetDlgItemText (hDlg, IDC_COMMENT, Info.szComment);
422
423       int iOrder = 0;
424       for (pLine = pLine->pNext; pLine; pLine = pLine->pNext)
425          {
426          CELLDBLINEINFO Info;
427          if (!CSDB_CrackLine (&Info, pLine->szLine))
428             break;
429          if (Info.szCell[0])
430             break;
431
432          CellEdit_AddServerEntry (hDlg, pLine, iOrder++);
433          }
434       }
435
436    // Prepare the columns on the server list
437    //
438    HWND hList = GetDlgItem (hDlg, IDC_LIST);
439
440    FASTLISTCOLUMN Column;
441    Column.dwFlags = FLCF_JUSTIFY_LEFT;
442    Column.cxWidth = 200;
443    GetString (Column.szText, IDS_SVRCOL_COMMENT);
444    FastList_SetColumn (hList, 0, &Column);
445
446    Column.dwFlags = FLCF_JUSTIFY_LEFT;
447    Column.cxWidth = 100;
448    GetString (Column.szText, IDS_SVRCOL_SERVER);
449    FastList_SetColumn (hList, 1, &Column);
450
451    FastList_SetSortFunction (hList, CellEdit_SortFunction);
452
453    // Remove the Context Help [?] thing from the title bar
454    //
455    DWORD dwStyle = GetWindowLong (GetParent (hDlg), GWL_STYLE);
456    dwStyle &= ~DS_CONTEXTHELP;
457    SetWindowLong (GetParent (hDlg), GWL_STYLE, dwStyle);
458
459    dwStyle = GetWindowLong (GetParent (hDlg), GWL_EXSTYLE);
460    dwStyle &= ~WS_EX_CONTEXTHELP;
461    SetWindowLong (GetParent (hDlg), GWL_EXSTYLE, dwStyle);
462
463    // A little cleanup and we're done!
464    //
465    CellEdit_Enable (hDlg);
466    CellEdit_OnSelect (hDlg);
467 }
468
469
470 void CellEdit_OnDestroy (HWND hDlg)
471 {
472    HWND hList = GetDlgItem (hDlg, IDC_LIST);
473    for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
474       {
475       PCELLDBLINE pInfo = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
476       Delete (pInfo);
477       }
478 }
479
480
481 void CellEdit_OnApply (HWND hDlg)
482 {
483    TCHAR szCell[ cchCELLDBLINE ];
484    GetDlgItemText (hDlg, IDC_CELL, szCell, cchCELLDBLINE);
485
486    TCHAR szComment[ cchCELLDBLINE ];
487    GetDlgItemText (hDlg, IDC_COMMENT, szComment, cchCELLDBLINE);
488
489    TCHAR szLinkedCell[ cchCELLDBLINE ] = TEXT("");
490
491    // Find out if there's already an entry in CellServDB for this cell
492    //
493    PCELLDBLINE pCellLine;
494    if ((pCellLine = CSDB_FindCell (&g.Configuration.CellServDB, szCell)) != NULL)
495       {
496       CELLDBLINEINFO Info;
497       if (CSDB_CrackLine (&Info, pCellLine->szLine))
498          lstrcpy (szLinkedCell, Info.szLinkedCell);
499       }
500
501    // Replace our cell's entry in CellServDB, or add one if necessary.
502    //
503    if ((pCellLine = CSDB_AddCell (&g.Configuration.CellServDB, szCell, szLinkedCell, szComment)) != NULL)
504       {
505       // Remove the old servers from this cell
506       //
507       CSDB_RemoveCellServers (&g.Configuration.CellServDB, pCellLine);
508
509       // Add the servers from our list to the CellServDB
510       //
511       PCELLDBLINE pAppendTo = pCellLine;
512
513       HWND hList = GetDlgItem (hDlg, IDC_LIST);
514       for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
515          {
516          PCELLDBLINE pFromList = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
517
518          pAppendTo = CSDB_AddLine (&g.Configuration.CellServDB, pAppendTo, pFromList->szLine);
519          }
520       }
521 }
522
523
524 void CellEdit_OnSelect (HWND hDlg)
525 {
526    HWND hList = GetDlgItem (hDlg, IDC_LIST);
527    HLISTITEM hItem = FastList_FindFirstSelected (hList);
528    HLISTITEM hNext = FastList_FindNextSelected (hList, hItem);
529
530    EnableWindow (GetDlgItem (hDlg, IDC_EDIT), !!hItem && !hNext);
531    EnableWindow (GetDlgItem (hDlg, IDC_REMOVE), !!hItem);
532 }
533
534
535 void CellEdit_OnAdd (HWND hDlg)
536 {
537    CELLDBLINE Line;
538    memset (&Line, 0x00, sizeof(CELLDBLINE));
539
540    int iOrder = 0;
541
542    HWND hList = GetDlgItem (hDlg, IDC_LIST);
543    for (HLISTITEM hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
544       {
545       PCELLDBLINE pInfo = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
546       iOrder = max (iOrder, 1+ (int)(pInfo->pNext));
547       }
548
549    if (ModalDialogParam (IDD_SERVER_EDIT, hDlg, (DLGPROC)ServerEdit_DlgProc, (LPARAM)&Line) == IDOK)
550       {
551       CellEdit_AddServerEntry (hDlg, &Line, iOrder);
552       }
553 }
554
555
556 void CellEdit_OnEdit (HWND hDlg)
557 {
558    HWND hList = GetDlgItem (hDlg, IDC_LIST);
559    HLISTITEM hItem = FastList_FindFirstSelected (hList);
560    PCELLDBLINE pInfo = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
561
562    CELLDBLINE Line;
563    memcpy (&Line, pInfo, sizeof(CELLDBLINE));
564
565    if (ModalDialogParam (IDD_SERVER_EDIT, hDlg, (DLGPROC)ServerEdit_DlgProc, (LPARAM)&Line) == IDOK)
566       {
567       CELLDBLINEINFO Info;
568       CSDB_CrackLine (&Info, Line.szLine);
569
570       TCHAR szServer[ cchRESOURCE ];
571       lstrcpy (szServer, inet_ntoa (*(struct in_addr *)&Info.ipServer));
572
573       FastList_SetItemText (hList, hItem, 0, Info.szComment);
574       FastList_SetItemText (hList, hItem, 1, szServer);
575
576       lstrcpy (pInfo->szLine, Line.szLine);
577       }
578 }
579
580
581 void CellEdit_OnRemove (HWND hDlg)
582 {
583    HWND hList = GetDlgItem (hDlg, IDC_LIST);
584    FastList_Begin (hList);
585
586    HLISTITEM hItem;
587    while ((hItem = FastList_FindFirstSelected (hList)) != NULL)
588       {
589       PCELLDBLINE pInfo = (PCELLDBLINE)FastList_GetItemParam (hList, hItem);
590       Delete (pInfo);
591       FastList_RemoveItem (hList, hItem);
592       }
593
594    FastList_End (hList);
595 }
596
597
598 void CellEdit_Enable (HWND hDlg)
599 {
600    BOOL fEnable = TRUE;
601
602    TCHAR szText[ cchRESOURCE ];
603    GetDlgItemText (hDlg, IDC_CELL, szText, cchRESOURCE);
604    if (!szText[0])
605       fEnable = FALSE;
606
607    if (!FastList_FindFirst (GetDlgItem (hDlg, IDC_LIST)))
608       fEnable = FALSE;
609
610    EnableWindow (GetDlgItem (GetParent (hDlg), IDOK), fEnable);
611 }
612
613
614 void CellEdit_AddServerEntry (HWND hDlg, PCELLDBLINE pLine, int iOrder)
615 {
616    HWND hList = GetDlgItem (hDlg, IDC_LIST);
617
618    PCELLDBLINE pCopy = New (CELLDBLINE);
619    memcpy (pCopy, pLine, sizeof(CELLDBLINE));
620    pCopy->pPrev = NULL;
621    pCopy->pNext = (PCELLDBLINE)iOrder;
622
623    CELLDBLINEINFO Info;
624    CSDB_CrackLine (&Info, pCopy->szLine);
625
626    TCHAR szServer[ cchRESOURCE ];
627    lstrcpy (szServer, inet_ntoa (*(struct in_addr *)&Info.ipServer));
628
629    FASTLISTADDITEM ai;
630    memset (&ai, 0x00, sizeof(ai));
631    ai.iFirstImage = IMAGE_NOIMAGE;
632    ai.iSecondImage = IMAGE_NOIMAGE;
633    ai.pszText = Info.szComment;
634    ai.lParam = (LPARAM)pCopy;
635    HLISTITEM hItem = FastList_AddItem (hList, &ai);
636
637    FastList_SetItemText (hList, hItem, 1, szServer);
638 }
639
640
641 int CALLBACK CellEdit_SortFunction (HWND hList, HLISTITEM hItem1, LPARAM lpItem1, HLISTITEM hItem2, LPARAM lpItem2)
642 {
643    if (!hItem1 || !hItem2)
644       return 0;
645
646    PCELLDBLINE pLine1 = (PCELLDBLINE)lpItem1;
647    PCELLDBLINE pLine2 = (PCELLDBLINE)lpItem2;
648
649    int iOrder1 = (int)(pLine1->pNext);
650    int iOrder2 = (int)(pLine2->pNext);
651    return iOrder1 - iOrder2;
652 }
653
654
655 BOOL CALLBACK ServerEdit_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
656 {
657    switch (msg)
658       {
659       case WM_INITDIALOG:
660          SetWindowLongPtr (hDlg, DWLP_USER, lp);
661          ServerEdit_OnInitDialog (hDlg);
662          break;
663
664       case WM_COMMAND:
665          switch (LOWORD(wp))
666             {
667             case IDOK:
668                if (ServerEdit_OnOK (hDlg))
669                   EndDialog (hDlg, IDOK);
670                break;
671
672             case IDCANCEL:
673                EndDialog (hDlg, IDCANCEL);
674                break;
675
676             case IDHELP:
677                ServerEdit_DlgProc (hDlg, WM_HELP, 0, 0);
678                break;
679
680             case IDC_ADDR_SPECIFIC:
681             case IDC_ADDR_LOOKUP:
682                EnableWindow (GetDlgItem (hDlg, IDC_SERVER), IsDlgButtonChecked (hDlg, IDC_ADDR_SPECIFIC));
683                break;
684             }
685          break;
686
687       case WM_HELP:
688          PCELLDBLINE pLine;
689          pLine = (PCELLDBLINE)GetWindowLongPtr (hDlg, DWLP_USER);
690
691          CELLDBLINEINFO Info;
692          if (!CSDB_CrackLine (&Info, pLine->szLine))
693             WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_CELLPROP_SERVER_ADD);
694          else
695             WinHelp (hDlg, g.szHelpFile, HELP_CONTEXT, IDH_AFSCONFIG_CELLPROP_SERVER_EDIT);
696          break;
697       }
698
699    return FALSE;
700 }
701
702
703 void ServerEdit_OnInitDialog (HWND hDlg)
704 {
705     PCELLDBLINE pLine = (PCELLDBLINE)GetWindowLongPtr (hDlg, DWLP_USER);
706
707    TCHAR szTitle[ cchRESOURCE ];
708    CELLDBLINEINFO Info;
709    if (!CSDB_CrackLine (&Info, pLine->szLine))
710       GetString (szTitle, IDS_ADDSERVER_TITLE);
711    else
712       GetString (szTitle, IDS_EDITSERVER_TITLE);
713    SetWindowText (hDlg, szTitle);
714
715    SOCKADDR_IN Addr;
716    memset (&Addr, 0x00, sizeof(SOCKADDR_IN));
717    Addr.sin_family = AF_INET;
718    Addr.sin_addr.s_addr = Info.ipServer;
719    SA_SetAddr (GetDlgItem (hDlg, IDC_SERVER), &Addr);
720
721    CheckDlgButton (hDlg, IDC_ADDR_SPECIFIC, !!Info.ipServer);
722    CheckDlgButton (hDlg, IDC_ADDR_LOOKUP, !Info.ipServer);
723    EnableWindow (GetDlgItem (hDlg, IDC_SERVER), IsDlgButtonChecked (hDlg, IDC_ADDR_SPECIFIC));
724
725    SetDlgItemText (hDlg, IDC_COMMENT, Info.szComment);
726 }
727
728
729 BOOL ServerEdit_OnOK (HWND hDlg)
730 {
731    PCELLDBLINE pLine = (PCELLDBLINE)GetWindowLongPtr (hDlg, DWLP_USER);
732
733    TCHAR szComment[ cchCELLDBLINE ];
734    GetDlgItemText (hDlg, IDC_COMMENT, szComment, cchCELLDBLINE);
735
736    SOCKADDR_IN Addr;
737    if (IsDlgButtonChecked (hDlg, IDC_ADDR_SPECIFIC))
738       {
739       SA_GetAddr (GetDlgItem (hDlg, IDC_SERVER), &Addr);
740       lstrcpy (szComment, inet_ntoa (*(struct in_addr *)&Addr.sin_addr.s_addr));
741       }
742    if (!TextToAddr (&Addr, szComment))
743       {
744       Message (MB_ICONHAND, GetErrorTitle(), IDS_BADLOOKUP_DESC, TEXT("%s"), szComment);
745       return FALSE;
746       }
747
748    TCHAR szServer[ cchCELLDBLINE ];
749    lstrcpy (szServer, inet_ntoa (*(struct in_addr *)&Addr.sin_addr.s_addr));
750
751    CSDB_FormatLine (pLine->szLine, szServer, NULL, szComment, FALSE);
752    return TRUE;
753 }
754
755
756 BOOL TextToAddr (SOCKADDR_IN *pAddr, LPTSTR pszServer)
757 {
758    if (!pszServer || !*pszServer)
759       return FALSE;
760
761    try {
762       memset (pAddr, 0x00, sizeof(SOCKADDR_IN));
763       pAddr->sin_family = AF_INET;
764
765       if ((*pszServer >= TEXT('0')) && (*pszServer <= TEXT('9')))
766          {
767          if ((pAddr->sin_addr.s_addr = inet_addr (pszServer)) == 0)
768             return FALSE;
769
770          HOSTENT *pEntry;
771          if ((pEntry = gethostbyaddr ((char*)&pAddr->sin_addr.s_addr, sizeof(int), AF_INET)) == NULL)
772             return FALSE;
773
774          if (pEntry->h_name[0])
775             lstrcpy (pszServer, pEntry->h_name);  // return the server's fqdn
776          }
777       else // Need to lookup the server by its name
778          {
779          HOSTENT *pEntry;
780          if ((pEntry = gethostbyname (pszServer)) == NULL)
781             return FALSE;
782
783          memcpy (&pAddr->sin_addr, (struct in_addr *)pEntry->h_addr, sizeof(struct in_addr));
784          if (!pAddr->sin_addr.s_addr)
785             return FALSE;
786
787          if (pEntry->h_name[0])
788             lstrcpy (pszServer, pEntry->h_name);  // return the server's fqdn
789          }
790
791       return TRUE;
792       }
793    catch(...)
794       {
795       return FALSE;
796       }
797 }
798