1 /************************************************************************
2  *   IRC - Internet Relay Chat, win32/gui.c
3  *   Copyright (C) 2000-2004 David Flynn (DrBin) & Dominick Meglio (codemastr)
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 1, or (at your option)
8  *   any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #define WIN32_VERSION BASE_VERSION PATCH1 PATCH2 PATCH3 PATCH4 PATCH5
21 #include "sys.h"
22 #include "resource.h"
23 #include "version.h"
24 #include "setup.h"
25 #include <windows.h>
26 #include <windowsx.h>
27 #include <commctrl.h>
28 #include "struct.h"
29 #include "common.h"
30 #include "numeric.h"
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <sys/types.h>
34 #include <io.h>
35 #include <direct.h>
36 #include <errno.h>
37 #include "h.h"
38 #include <richedit.h>
39 #include <commdlg.h>
40 #include "win32.h"
41 
ShowDialog(HWND * handle,HINSTANCE inst,char * template,HWND parent,DLGPROC proc)42 __inline void ShowDialog(HWND *handle, HINSTANCE inst, char *template, HWND parent,
43 			 DLGPROC proc)
44 {
45 	if (!IsWindow(*handle))
46 	{
47 		*handle = CreateDialog(inst, template, parent, (DLGPROC)proc);
48 		ShowWindow(*handle, SW_SHOW);
49 	}
50 	else
51 		SetForegroundWindow(*handle);
52 }
53 
54 /* Comments:
55  *
56  * DrBin did a great job with the original GUI, but he has been gone a long time.
57  * In his absense, it was decided it would be best to continue windows development.
58  * The new code is based on his so it will be pretty much similar in features, my
59  * main goal is to make it more stable. A lot of what I know about GUI coding
60  * I learned from DrBin so thanks to him for teaching me :) -- codemastr
61  */
62 
63 LRESULT CALLBACK MainDLG(HWND, UINT, WPARAM, LPARAM);
64 LRESULT CALLBACK LicenseDLG(HWND, UINT, WPARAM, LPARAM);
65 LRESULT CALLBACK InfoDLG(HWND, UINT, WPARAM, LPARAM);
66 LRESULT CALLBACK CreditsDLG(HWND, UINT, WPARAM, LPARAM);
67 LRESULT CALLBACK DalDLG(HWND, UINT, WPARAM, LPARAM);
68 LRESULT CALLBACK HelpDLG(HWND, UINT, WPARAM, LPARAM);
69 LRESULT CALLBACK StatusDLG(HWND, UINT, WPARAM, LPARAM);
70 LRESULT CALLBACK ConfigErrorDLG(HWND, UINT, WPARAM, LPARAM);
71 LRESULT CALLBACK FromVarDLG(HWND, UINT, WPARAM, LPARAM, unsigned char *, unsigned char **);
72 LRESULT CALLBACK FromFileReadDLG(HWND, UINT, WPARAM, LPARAM);
73 LRESULT CALLBACK FromFileDLG(HWND, UINT, WPARAM, LPARAM);
74 
75 extern  void      SocketLoop(void *dummy);
76 HINSTANCE hInst;
77 NOTIFYICONDATA SysTray;
78 void CleanUp(void);
79 HTREEITEM AddItemToTree(HWND, LPSTR, int, short);
80 void win_map(aClient *, HWND, short);
81 extern Link *Servers;
82 extern ircstats IRCstats;
83 unsigned char *errors = NULL;
84 extern VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
85 extern BOOL IsService;
CleanUp(void)86 void CleanUp(void)
87 {
88 	Shell_NotifyIcon(NIM_DELETE ,&SysTray);
89 }
CleanUpSegv(int sig)90 void CleanUpSegv(int sig)
91 {
92 	Shell_NotifyIcon(NIM_DELETE ,&SysTray);
93 }
94 HWND hStatusWnd;
95 HWND hwIRCDWnd=NULL;
96 HWND hwTreeView;
97 HWND hWndMod;
98 HANDLE hMainThread = 0;
99 UINT WM_TASKBARCREATED, WM_FINDMSGSTRING;
100 FARPROC lpfnOldWndProc;
101 HMENU hContext;
102 OSVERSIONINFO VerInfo;
103 char OSName[OSVER_SIZE];
104 #ifdef USE_LIBCURL
105 extern char *find_loaded_remote_include(char *url);
106 #endif
107 
TaskBarCreated()108 void TaskBarCreated()
109 {
110 	HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0);
111 	SysTray.cbSize = sizeof(NOTIFYICONDATA);
112 	SysTray.hIcon = hIcon;
113 	SysTray.hWnd = hwIRCDWnd;
114 	SysTray.uCallbackMessage = WM_USER;
115 	SysTray.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
116 	SysTray.uID = 0;
117 	strcpy(SysTray.szTip, WIN32_VERSION);
118 	Shell_NotifyIcon(NIM_ADD ,&SysTray);
119 }
120 
LinkSubClassFunc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)121 LRESULT LinkSubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
122 {
123 	static HCURSOR hCursor;
124 	if (!hCursor)
125 		hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
126 	if (Message == WM_MOUSEMOVE || Message == WM_LBUTTONDOWN)
127 		SetCursor(hCursor);
128 
129 	return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
130 }
131 
132 
133 
RESubClassFunc(HWND hWnd,UINT Message,WPARAM wParam,LPARAM lParam)134 LRESULT RESubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
135 {
136 	POINT p;
137 	RECT r;
138 	DWORD start, end;
139 	unsigned char string[500];
140 
141 	if (Message == WM_GETDLGCODE)
142 	   return DLGC_WANTALLKEYS;
143 
144 
145 	if (Message == WM_CONTEXTMENU)
146 	{
147 		p.x = GET_X_LPARAM(lParam);
148 		p.y = GET_Y_LPARAM(lParam);
149 		if (GET_X_LPARAM(lParam) == -1 && GET_Y_LPARAM(lParam) == -1)
150 		{
151 			GetClientRect(hWnd, &r);
152 			p.x = (int)((r.left + r.right)/2);
153 			p.y = (int)((r.top + r.bottom)/2);
154 			ClientToScreen(hWnd,&p);
155 		}
156 		if (!SendMessage(hWnd, EM_CANUNDO, 0, 0))
157 			EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_GRAYED);
158 		else
159 			EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_ENABLED);
160 		if (!SendMessage(hWnd, EM_CANPASTE, 0, 0))
161 			EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_GRAYED);
162 		else
163 			EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_ENABLED);
164 		if (GetWindowLong(hWnd, GWL_STYLE) & ES_READONLY)
165 		{
166 			EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_GRAYED);
167 			EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_GRAYED);
168 		}
169 		else
170 		{
171 			EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_ENABLED);
172 			EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_ENABLED);
173 		}
174 		SendMessage(hWnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
175 		if (start == end)
176 			EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_GRAYED);
177 		else
178 			EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_ENABLED);
179 		TrackPopupMenu(hContext,TPM_LEFTALIGN|TPM_RIGHTBUTTON,p.x,p.y,0,GetParent(hWnd),NULL);
180 		return 0;
181 	}
182 
183 	return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
184 }
185 
CloseUnreal(HWND hWnd)186 int CloseUnreal(HWND hWnd)
187 {
188 	if (MessageBox(hWnd, "Close UnrealIRCd?", "Are you sure?", MB_YESNO|MB_ICONQUESTION)
189 	    == IDNO)
190 		 return 0;
191 	else
192 	{
193 		 DestroyWindow(hWnd);
194 		 exit(0);
195 	}
196 }
197 
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)198 int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
199 {
200 	MSG msg;
201 	unsigned char *s;
202 	HWND hWnd;
203 	WSADATA WSAData;
204 	HICON hIcon;
205 	SERVICE_TABLE_ENTRY DispatchTable[] =
206 	{
207 		{ "UnrealIRCd", ServiceMain },
208 		{ 0, 0 }
209 	};
210 	DWORD need;
211 
212 	VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
213 	GetVersionEx(&VerInfo);
214 	GetOSName(OSName);
215 	if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
216 	{
217 		SC_HANDLE hService, hSCManager = OpenSCManager(NULL, NULL, GENERIC_EXECUTE);
218 		if ((hService = OpenService(hSCManager, "UnrealIRCd", GENERIC_EXECUTE)))
219 		{
220 			int save_err = 0;
221 			StartServiceCtrlDispatcher(DispatchTable);
222 			if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
223 			{
224 				SERVICE_STATUS status;
225 				/* Restart handling, it's ugly but it's as
226 				 * pretty as it is gonna get :)
227 				 */
228 				if (__argc == 2 && !strcmp(__argv[1], "restartsvc"))
229 				{
230 					QueryServiceStatus(hService, &status);
231 					if (status.dwCurrentState != SERVICE_STOPPED)
232 					{
233 						ControlService(hService,
234 							SERVICE_CONTROL_STOP, &status);
235 						while (status.dwCurrentState == SERVICE_STOP_PENDING)
236 						{
237 							QueryServiceStatus(hService, &status);
238 							if (status.dwCurrentState != SERVICE_STOPPED)
239 								Sleep(1000);
240 						}
241 					}
242 				}
243 				if (!StartService(hService, 0, NULL))
244 					save_err = GetLastError();
245 			}
246 
247 			CloseServiceHandle(hService);
248 			CloseServiceHandle(hSCManager);
249 			if (save_err != ERROR_SERVICE_DISABLED)
250 				exit(0);
251 		} else {
252 			CloseServiceHandle(hSCManager);
253 		}
254 	}
255 	InitCommonControls();
256 	WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
257 	WM_FINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
258 	atexit(CleanUp);
259 	if(!LoadLibrary("riched20.dll"))
260 		LoadLibrary("riched32.dll");
261 	InitDebug();
262 
263 	if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
264     	{
265 		MessageBox(NULL, "Unable to initialize WinSock", "UnrealIRCD Initalization Error", MB_OK);
266 		return FALSE;
267 	}
268 	hInst = hInstance;
269 
270 	hWnd = CreateDialog(hInstance, "WIRCD", 0, (DLGPROC)MainDLG);
271 	hwIRCDWnd = hWnd;
272 
273 	TaskBarCreated();
274 
275 	if (InitwIRCD(__argc, __argv) != 1)
276 	{
277 		MessageBox(NULL, "UnrealIRCd has failed to initialize in InitwIRCD()", "UnrealIRCD Initalization Error" ,MB_OK);
278 		return FALSE;
279 	}
280 	ShowWindow(hWnd, SW_SHOW);
281 	hMainThread = (HANDLE)_beginthread(SocketLoop, 0, NULL);
282 	if (TStime() > 1459461600)
283 	{
284 		MessageBox(NULL, "UnrealIRCd 3.2.x is no longer supported after December 31, 2016. "
285 		                 "You should upgrade to UnrealIRCd 4. "
286 		                 "See https://www.unrealircd.org/docs/UnrealIRCd_3.2.x_deprecated",
287 		                 "UnrealIRCd 3.2.x is deprecated", 		                 MB_OK);
288 	}
289 	while (GetMessage(&msg, NULL, 0, 0))
290 	{
291 		if (!IsWindow(hStatusWnd) || !IsDialogMessage(hStatusWnd, &msg))
292 		{
293 			TranslateMessage(&msg);
294 			DispatchMessage(&msg);
295 		}
296 	}
297 	return FALSE;
298 
299 }
300 
MainDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)301 LRESULT CALLBACK MainDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
302 {
303 	static HCURSOR hCursor;
304 	static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
305 
306 	unsigned char *argv[3];
307 	aClient *paClient;
308 	unsigned char *msg;
309 	POINT p;
310 
311 	if (message == WM_TASKBARCREATED)
312 	{
313 		TaskBarCreated();
314 		return TRUE;
315 	}
316 
317 	switch (message)
318 	{
319 		case WM_INITDIALOG:
320 		{
321 			ShowWindow(hDlg, SW_HIDE);
322 			hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
323 			hContext = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_CONTEXT)),0);
324 			/* Rehash popup menu */
325 			hRehash = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_REHASH)),0);
326 			/* About popup menu */
327 			hAbout = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_ABOUT)),0);
328 			/* Systray popup menu set the items to point to the other menus*/
329 			hTray = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_SYSTRAY)),0);
330 			ModifyMenu(hTray, IDM_REHASH, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hRehash, "&Rehash");
331 			ModifyMenu(hTray, IDM_ABOUT, MF_BYCOMMAND|MF_POPUP|MF_STRING, (UINT)hAbout, "&About");
332 
333 			SetWindowText(hDlg, WIN32_VERSION);
334 			SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_SMALL,
335 				(LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0));
336 			SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_BIG,
337 				(LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,32, 32, 0));
338 			return TRUE;
339 		}
340 		case WM_SIZE:
341 		{
342 			if (wParam & SIZE_MINIMIZED)
343 				ShowWindow(hDlg,SW_HIDE);
344 			return 0;
345 		}
346 		case WM_CLOSE:
347 			return CloseUnreal(hDlg);
348 		case WM_USER:
349 		{
350 			switch(LOWORD(lParam))
351 			{
352 				case WM_LBUTTONDBLCLK:
353 					ShowWindow(hDlg, SW_SHOW);
354 					ShowWindow(hDlg,SW_RESTORE);
355 					SetForegroundWindow(hDlg);
356 				case WM_RBUTTONDOWN:
357 					SetForegroundWindow(hDlg);
358 					break;
359 				case WM_RBUTTONUP:
360 				{
361 					unsigned long i = 60000;
362 					MENUITEMINFO mii;
363 					GetCursorPos(&p);
364 					DestroyMenu(hConfig);
365 					hConfig = CreatePopupMenu();
366 					DestroyMenu(hLogs);
367 					hLogs = CreatePopupMenu();
368 					AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
369 					if (conf_log)
370 					{
371 						ConfigItem_log *logs;
372 						AppendMenu(hConfig, MF_POPUP|MF_STRING, (UINT)hLogs, "Logs");
373 						for (logs = conf_log; logs; logs = (ConfigItem_log *)logs->next)
374 						{
375 							AppendMenu(hLogs, MF_STRING, i++, logs->file);
376 						}
377 					}
378 					AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
379 					if (conf_include)
380 					{
381 						ConfigItem_include *inc;
382 						for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next)
383 						{
384 							if (inc->flag.type & INCLUDE_NOTLOADED)
385 								continue;
386 #ifdef USE_LIBCURL
387 							if (inc->flag.type & INCLUDE_REMOTE)
388 								AppendMenu(hConfig, MF_STRING, i++, inc->url);
389 							else
390 #endif
391 							AppendMenu(hConfig, MF_STRING, i++, inc->file);
392 						}
393 						AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
394 					}
395 					AppendMenu(hConfig, MF_STRING, IDM_MOTD, conf_files->motd_file);
396 					AppendMenu(hConfig, MF_STRING, IDM_SMOTD, conf_files->smotd_file);
397 					AppendMenu(hConfig, MF_STRING, IDM_OPERMOTD, conf_files->opermotd_file);
398 					AppendMenu(hConfig, MF_STRING, IDM_BOTMOTD, conf_files->botmotd_file);
399 					AppendMenu(hConfig, MF_STRING, IDM_RULES, conf_files->rules_file);
400 
401 					if (conf_tld)
402 					{
403 						ConfigItem_tld *tlds;
404 						AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
405 						for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *)tlds->next)
406 						{
407 							if (!tlds->flag.motdptr)
408 								AppendMenu(hConfig, MF_STRING, i++, tlds->motd_file);
409 							if (!tlds->flag.rulesptr)
410 								AppendMenu(hConfig, MF_STRING, i++, tlds->rules_file);
411 							if (tlds->smotd_file)
412 								AppendMenu(hConfig, MF_STRING, i++, tlds->smotd_file);
413 						}
414 					}
415 					AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
416 					AppendMenu(hConfig, MF_STRING, IDM_NEW, "New File");
417 					mii.cbSize = sizeof(MENUITEMINFO);
418 					mii.fMask = MIIM_SUBMENU;
419 					mii.hSubMenu = hConfig;
420 					SetMenuItemInfo(hTray, IDM_CONFIG, MF_BYCOMMAND, &mii);
421 					TrackPopupMenu(hTray, TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
422 					/* Kludge for a win bug */
423 					SendMessage(hDlg, WM_NULL, 0, 0);
424 					break;
425 				}
426 			}
427 			return 0;
428 		}
429 		case WM_DESTROY:
430 			return 0;
431 		case WM_MOUSEMOVE:
432 		{
433 			POINT p;
434 			p.x = LOWORD(lParam);
435 			p.y = HIWORD(lParam);
436 			if ((p.x >= 24) && (p.x <= 78) && (p.y >= 178) && (p.y <= 190))
437 				SetCursor(hCursor);
438 			else if ((p.x >= 85) && (p.x <= 132) && (p.y >= 178) && (p.y <= 190))
439 				SetCursor(hCursor);
440 			else if ((p.x >= 140) && (p.x <= 186) && (p.y >= 178) && (p.y <= 190))
441 				SetCursor(hCursor);
442 			else if ((p.x >= 194) && (p.x <= 237) && (p.y >= 178) && (p.y <= 190))
443 				SetCursor(hCursor);
444 			else if ((p.x >= 245) && (p.x <= 311) && (p.y >= 178) && (p.y <= 190))
445 				SetCursor(hCursor);
446 			return 0;
447 		}
448 		case WM_LBUTTONDOWN:
449 		{
450 			POINT p;
451 	         	p.x = LOWORD(lParam);
452 		     	p.y = HIWORD(lParam);
453 			if ((p.x >= 24) && (p.x <= 78) && (p.y >= 178) && (p.y <= 190))
454              		{
455 				ClientToScreen(hDlg,&p);
456 				TrackPopupMenu(hRehash,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
457 				return 0;
458 			}
459 			else if ((p.x >= 85) && (p.x <= 132) && (p.y >= 178) && (p.y <= 190))
460 			{
461 				ShowDialog(&hStatusWnd, hInst, "Status", hDlg, StatusDLG);
462 				return 0;
463 			}
464 			else if ((p.x >= 140) && (p.x <= 186) && (p.y >= 178) && (p.y <= 190))
465 			{
466 				unsigned long i = 60000;
467 				ClientToScreen(hDlg,&p);
468 				DestroyMenu(hConfig);
469 				hConfig = CreatePopupMenu();
470 				DestroyMenu(hLogs);
471 				hLogs = CreatePopupMenu();
472 
473 				AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
474 				if (conf_log)
475 				{
476 					ConfigItem_log *logs;
477 					AppendMenu(hConfig, MF_POPUP|MF_STRING, (UINT)hLogs, "Logs");
478 					for (logs = conf_log; logs; logs = (ConfigItem_log *)logs->next)
479 					{
480 						AppendMenu(hLogs, MF_STRING, i++, logs->file);
481 					}
482 				}
483 				AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
484 
485 				if (conf_include)
486 				{
487 					ConfigItem_include *inc;
488 					for (inc = conf_include; inc; inc = (ConfigItem_include *)inc->next)
489 					{
490 #ifdef USE_LIBCURL
491 						if (inc->flag.type & INCLUDE_REMOTE)
492 							AppendMenu(hConfig, MF_STRING, i++, inc->url);
493 						else
494 #endif
495 						AppendMenu(hConfig, MF_STRING, i++, inc->file);
496 					}
497 					AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
498 				}
499 
500 				AppendMenu(hConfig, MF_STRING, IDM_MOTD, conf_files->motd_file);
501 				AppendMenu(hConfig, MF_STRING, IDM_SMOTD, conf_files->smotd_file);
502 				AppendMenu(hConfig, MF_STRING, IDM_OPERMOTD, conf_files->opermotd_file);
503 				AppendMenu(hConfig, MF_STRING, IDM_BOTMOTD, conf_files->botmotd_file);
504 				AppendMenu(hConfig, MF_STRING, IDM_RULES, conf_files->rules_file);
505 
506 				if (conf_tld)
507 				{
508 					ConfigItem_tld *tlds;
509 					AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
510 					for (tlds = conf_tld; tlds; tlds = (ConfigItem_tld *)tlds->next)
511 					{
512 						if (!tlds->flag.motdptr)
513 							AppendMenu(hConfig, MF_STRING, i++, tlds->motd_file);
514 						if (!tlds->flag.rulesptr)
515 							AppendMenu(hConfig, MF_STRING, i++, tlds->rules_file);
516 						if (tlds->smotd_file)
517 							AppendMenu(hConfig, MF_STRING, i++, tlds->smotd_file);
518 					}
519 				}
520 				AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
521 				AppendMenu(hConfig, MF_STRING, IDM_NEW, "New File");
522 				TrackPopupMenu(hConfig,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
523 
524 				return 0;
525 			}
526 			else if ((p.x >= 194) && (p.x <= 237) && (p.y >= 178) && (p.y <= 190))
527 			{
528 				ClientToScreen(hDlg,&p);
529 				TrackPopupMenu(hAbout,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
530 				return 0;
531 			}
532 			else if ((p.x >= 245) && (p.x <= 311) && (p.y >= 178) && (p.y <= 190))
533 				return CloseUnreal(hDlg);
534 		}
535 		case WM_COMMAND:
536 		{
537 			if (LOWORD(wParam) >= 60000 && HIWORD(wParam) == 0 && !lParam)
538 			{
539 				unsigned char path[MAX_PATH];
540 				if (GetMenuString(hLogs, LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND))
541 					DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)path);
542 
543 				else
544 				{
545 					GetMenuString(hConfig,LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND);
546 #ifdef USE_LIBCURL
547 					if (url_is_valid(path))
548 					{
549 						char *file = find_loaded_remote_include(path);
550 						DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)file);
551 					}
552 					else
553 #endif
554 						DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)path);
555 				}
556 				return FALSE;
557 			}
558 
559 			switch(LOWORD(wParam))
560 			{
561 				case IDM_STATUS:
562 					ShowDialog(&hStatusWnd, hInst, "Status", hDlg,StatusDLG);
563 					break;
564 				case IDM_SHUTDOWN:
565 					return CloseUnreal(hDlg);
566 				case IDM_RHALL:
567 					MessageBox(NULL, "Rehashing all files", "Rehashing", MB_OK);
568 					sendto_realops("Rehashing all files via the console");
569 					rehash(&me,&me,0);
570 					reread_motdsandrules();
571 					break;
572 				case IDM_RHCONF:
573 					MessageBox(NULL, "Rehashing the Config file", "Rehashing", MB_OK);
574 					sendto_realops("Rehashing the Config file via the console");
575 					rehash(&me,&me,0);
576 					break;
577 				case IDM_RHMOTD:
578 				{
579 					MessageBox(NULL, "Rehashing all MOTD and Rules files", "Rehashing", MB_OK);
580 					rehash_motdrules();
581 					sendto_realops("Rehashing all MOTD and Rules files via the console");
582 					break;
583 				}
584 				case IDM_RHOMOTD:
585 					MessageBox(NULL, "Rehashing the OperMOTD", "Rehashing", MB_OK);
586 					read_motd(conf_files->opermotd_file, &opermotd);
587 					sendto_realops("Rehashing the OperMOTD via the console");
588 					break;
589 				case IDM_RHBMOTD:
590 					MessageBox(NULL, "Rehashing the BotMOTD", "Rehashing", MB_OK);
591 					read_motd(conf_files->botmotd_file, &botmotd);
592 					sendto_realops("Rehashing the BotMOTD via the console");
593 					break;
594 				case IDM_LICENSE:
595 					DialogBox(hInst, "FromVar", hDlg, (DLGPROC)LicenseDLG);
596 					break;
597 				case IDM_INFO:
598 					DialogBox(hInst, "FromVar", hDlg, (DLGPROC)InfoDLG);
599 					break;
600 				case IDM_CREDITS:
601 					DialogBox(hInst, "FromVar", hDlg, (DLGPROC)CreditsDLG);
602 					break;
603 				case IDM_DAL:
604 					DialogBox(hInst, "FromVar", hDlg, (DLGPROC)DalDLG);
605 					break;
606 				case IDM_HELP:
607 					DialogBox(hInst, "Help", hDlg, (DLGPROC)HelpDLG);
608 					break;
609 				case IDM_CONF:
610 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
611 						(LPARAM)CPATH);
612 					break;
613 				case IDM_MOTD:
614 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
615 						(LPARAM)conf_files->motd_file);
616 					break;
617 				case IDM_SMOTD:
618 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
619 						(LPARAM)conf_files->smotd_file);
620 					break;
621 				case IDM_OPERMOTD:
622 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
623 						(LPARAM)conf_files->opermotd_file);
624 					break;
625 				case IDM_BOTMOTD:
626 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
627 						(LPARAM)conf_files->botmotd_file);
628 					break;
629 				case IDM_RULES:
630 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
631 						(LPARAM)conf_files->rules_file);
632 					break;
633 				case IDM_NEW:
634 					DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)NULL);
635 					break;
636 			}
637 		}
638 	}
639 	return FALSE;
640 }
641 
LicenseDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)642 LRESULT CALLBACK LicenseDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
643 {
644 	return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd License", gnulicense);
645 }
646 
InfoDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)647 LRESULT CALLBACK InfoDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
648 {
649 	return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd Team", unrealinfo);
650 }
651 
CreditsDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)652 LRESULT CALLBACK CreditsDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
653 {
654 	return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd Credits", unrealcredits);
655 }
656 
DalDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)657 LRESULT CALLBACK DalDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
658 {
659 	return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd DALnet Credits", dalinfotext);
660 }
661 
FromVarDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam,unsigned char * title,unsigned char ** s)662 LRESULT CALLBACK FromVarDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam,
663 			    unsigned char *title, unsigned char **s)
664 {
665 	HWND hWnd;
666 	switch (message)
667 	{
668 		case WM_INITDIALOG:
669 		{
670 			unsigned char	String[16384];
671 			int size;
672 			unsigned char *RTFString;
673 			StreamIO *stream = malloc(sizeof(StreamIO));
674 			EDITSTREAM edit;
675 			SetWindowText(hDlg, title);
676 			bzero(String, 16384);
677 			lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_TEXT), GWL_WNDPROC, (DWORD)RESubClassFunc);
678 			while (*s)
679 			{
680 				strcat(String, *s++);
681 				if (*s)
682 					strcat(String, "\r\n");
683 			}
684 			size = CountRTFSize(String)+1;
685 			RTFString = malloc(size);
686 			bzero(RTFString, size);
687 			IRCToRTF(String,RTFString);
688 			RTFBuf = RTFString;
689 			size--;
690 			stream->size = &size;
691 			stream->buffer = &RTFBuf;
692 			edit.dwCookie = (UINT)stream;
693 			edit.pfnCallback = SplitIt;
694 			SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
695 			free(RTFString);
696 			free(stream);
697 			return TRUE;
698 		}
699 
700 		case WM_COMMAND:
701 		{
702 			hWnd = GetDlgItem(hDlg, IDC_TEXT);
703 			if (LOWORD(wParam) == IDOK)
704 				return EndDialog(hDlg, TRUE);
705 			if (LOWORD(wParam) == IDM_COPY)
706 			{
707 				SendMessage(hWnd, WM_COPY, 0, 0);
708 				return 0;
709 			}
710 			if (LOWORD(wParam) == IDM_SELECTALL)
711 			{
712 				SendMessage(hWnd, EM_SETSEL, 0, -1);
713 				return 0;
714 			}
715 			if (LOWORD(wParam) == IDM_PASTE)
716 			{
717 				SendMessage(hWnd, WM_PASTE, 0, 0);
718 				return 0;
719 			}
720 			if (LOWORD(wParam) == IDM_CUT)
721 			{
722 				SendMessage(hWnd, WM_CUT, 0, 0);
723 				return 0;
724 			}
725 			if (LOWORD(wParam) == IDM_UNDO)
726 			{
727 				SendMessage(hWnd, EM_UNDO, 0, 0);
728 				return 0;
729 			}
730 			if (LOWORD(wParam) == IDM_DELETE)
731 			{
732 				SendMessage(hWnd, WM_CLEAR, 0, 0);
733 				return 0;
734 			}
735 			break;
736 		}
737 		case WM_CLOSE:
738 			EndDialog(hDlg, TRUE);
739 			break;
740 		case WM_DESTROY:
741 			break;
742 		}
743 	return (FALSE);
744 }
745 
FromFileReadDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)746 LRESULT CALLBACK FromFileReadDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
747 {
748 	HWND hWnd;
749 	switch (message)
750 	{
751 		case WM_INITDIALOG:
752 		{
753 			int fd,len;
754 			unsigned char *buffer = '\0', *string = '\0';
755 			EDITSTREAM edit;
756 			StreamIO *stream = malloc(sizeof(StreamIO));
757 			unsigned char szText[256];
758 			struct stat sb;
759 			HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
760 			wsprintf(szText, "UnrealIRCd Viewer - %s", (unsigned char *)lParam);
761 			SetWindowText(hDlg, szText);
762 			lpfnOldWndProc = (FARPROC)SetWindowLong(hWnd, GWL_WNDPROC, (DWORD)RESubClassFunc);
763 			if ((fd = open((unsigned char *)lParam, _O_RDONLY|_O_BINARY)) != -1)
764 			{
765 				fstat(fd,&sb);
766 				/* Only allocate the amount we need */
767 				buffer = malloc(sb.st_size+1);
768 				buffer[0] = 0;
769 				len = read(fd, buffer, sb.st_size);
770 				buffer[len] = 0;
771 				len = CountRTFSize(buffer)+1;
772 				string = malloc(len);
773 				bzero(string,len);
774 				IRCToRTF(buffer,string);
775 				RTFBuf = string;
776 				len--;
777 				stream->size = &len;
778 				stream->buffer = &RTFBuf;
779 				edit.dwCookie = (UINT)stream;
780 				edit.pfnCallback = SplitIt;
781 				SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
782 				SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
783 				close(fd);
784 				RTFBuf = NULL;
785 				free(buffer);
786 				free(string);
787 				free(stream);
788 			}
789 			return TRUE;
790 		}
791 		case WM_COMMAND:
792 		{
793 			hWnd = GetDlgItem(hDlg, IDC_TEXT);
794 			if (LOWORD(wParam) == IDOK)
795 				return EndDialog(hDlg, TRUE);
796 			if (LOWORD(wParam) == IDM_COPY)
797 			{
798 				SendMessage(hWnd, WM_COPY, 0, 0);
799 				return 0;
800 			}
801 			if (LOWORD(wParam) == IDM_SELECTALL)
802 			{
803 				SendMessage(hWnd, EM_SETSEL, 0, -1);
804 				return 0;
805 			}
806 			if (LOWORD(wParam) == IDM_PASTE)
807 			{
808 				SendMessage(hWnd, WM_PASTE, 0, 0);
809 				return 0;
810 			}
811 			if (LOWORD(wParam) == IDM_CUT)
812 			{
813 				SendMessage(hWnd, WM_CUT, 0, 0);
814 				return 0;
815 			}
816 			if (LOWORD(wParam) == IDM_UNDO)
817 			{
818 				SendMessage(hWnd, EM_UNDO, 0, 0);
819 				return 0;
820 			}
821 			if (LOWORD(wParam) == IDM_DELETE)
822 			{
823 				SendMessage(hWnd, WM_CLEAR, 0, 0);
824 				return 0;
825 			}
826 			break;
827 		}
828 		case WM_CLOSE:
829 			EndDialog(hDlg, TRUE);
830 			break;
831 		case WM_DESTROY:
832 			break;
833 	}
834 	return FALSE;
835 }
836 
HelpDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)837 LRESULT CALLBACK HelpDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
838 {
839 	static HFONT hFont;
840 	static HCURSOR hCursor;
841 	switch (message)
842 	{
843 		case WM_INITDIALOG:
844 			hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
845 			hFont = CreateFont(8,0,0,0,0,0,1,0,ANSI_CHARSET,0,0,PROOF_QUALITY,0,"MS Sans Serif");
846 			SendMessage(GetDlgItem(hDlg, IDC_EMAIL), WM_SETFONT, (WPARAM)hFont,TRUE);
847 			SendMessage(GetDlgItem(hDlg, IDC_URL), WM_SETFONT, (WPARAM)hFont,TRUE);
848 			lpfnOldWndProc = (FARPROC)SetWindowLong(GetDlgItem(hDlg, IDC_EMAIL), GWL_WNDPROC, (DWORD)LinkSubClassFunc);
849 			SetWindowLong(GetDlgItem(hDlg, IDC_URL), GWL_WNDPROC, (DWORD)LinkSubClassFunc);
850 			return TRUE;
851 
852 		case WM_DRAWITEM:
853 		{
854 			LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
855 			unsigned char text[500];
856 			COLORREF oldtext;
857 			RECT focus;
858 			GetWindowText(lpdis->hwndItem, text, 500);
859 			if (wParam == IDC_URL || IDC_EMAIL)
860 			{
861 				FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_3DFACE));
862 				oldtext = SetTextColor(lpdis->hDC, RGB(0,0,255));
863 				DrawText(lpdis->hDC, text, strlen(text), &lpdis->rcItem, DT_CENTER|DT_VCENTER);
864 				SetTextColor(lpdis->hDC, oldtext);
865 				if (lpdis->itemState & ODS_FOCUS)
866 				{
867 					CopyRect(&focus, &lpdis->rcItem);
868 					focus.left += 2;
869 					focus.right -= 2;
870 					focus.top += 1;
871 					focus.bottom -= 1;
872 					DrawFocusRect(lpdis->hDC, &focus);
873 				}
874 				return TRUE;
875 			}
876 		}
877 		case WM_COMMAND:
878 			if (LOWORD(wParam) == IDOK)
879 				EndDialog(hDlg, TRUE);
880 			if (HIWORD(wParam) == BN_DBLCLK)
881 			{
882 				if (LOWORD(wParam) == IDC_URL)
883 					ShellExecute(NULL, "open", "http://www.unrealircd.com", NULL, NULL,
884 						SW_MAXIMIZE);
885 				else if (LOWORD(wParam) == IDC_EMAIL)
886 					ShellExecute(NULL, "open", "mailto:unreal-users@lists.sourceforge.net", NULL, NULL,
887 						SW_MAXIMIZE);
888 				EndDialog(hDlg, TRUE);
889 				return 0;
890 			}
891 			break;
892 		case WM_CLOSE:
893 			EndDialog(hDlg, TRUE);
894 			break;
895 		case WM_DESTROY:
896 			DeleteObject(hFont);
897 			break;
898 
899 	}
900 	return FALSE;
901 }
902 
903 
904 
905 
906 
907 
908 
909 
StatusDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)910 LRESULT CALLBACK StatusDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
911 {
912 	switch (message)
913 	{
914 		case WM_INITDIALOG:
915 		{
916 			hwTreeView = GetDlgItem(hDlg, IDC_TREE);
917 			win_map(&me, hwTreeView, 0);
918 			SetDlgItemInt(hDlg, IDC_CLIENTS, IRCstats.clients, FALSE);
919 			SetDlgItemInt(hDlg, IDC_SERVERS, IRCstats.servers, FALSE);
920 			SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
921 			SetDlgItemInt(hDlg, IDC_UNKNOWN, IRCstats.unknown, FALSE);
922 			SetDlgItemInt(hDlg, IDC_OPERS, IRCstats.operators, FALSE);
923 			SetDlgItemInt(hDlg, IDC_CHANNELS, IRCstats.channels, FALSE);
924 			if (IRCstats.clients > IRCstats.global_max)
925 				IRCstats.global_max = IRCstats.clients;
926 			if (IRCstats.me_clients > IRCstats.me_max)
927 					IRCstats.me_max = IRCstats.me_clients;
928 			SetDlgItemInt(hDlg, IDC_MAXCLIENTS, IRCstats.global_max, FALSE);
929 			SetDlgItemInt(hDlg, IDC_LCLIENTS, IRCstats.me_clients, FALSE);
930 			SetDlgItemInt(hDlg, IDC_LSERVERS, IRCstats.me_servers, FALSE);
931 			SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, IRCstats.me_max, FALSE);
932 			SetTimer(hDlg, 1, 5000, NULL);
933 			return TRUE;
934 		}
935 		case WM_CLOSE:
936 			DestroyWindow(hDlg);
937 			return TRUE;
938 		case WM_TIMER:
939 			TreeView_DeleteAllItems(hwTreeView);
940 			win_map(&me, hwTreeView, 1);
941 			SetDlgItemInt(hDlg, IDC_CLIENTS, IRCstats.clients, FALSE);
942 			SetDlgItemInt(hDlg, IDC_SERVERS, IRCstats.servers, FALSE);
943 			SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
944 			SetDlgItemInt(hDlg, IDC_INVISO, IRCstats.invisible, FALSE);
945 			SetDlgItemInt(hDlg, IDC_UNKNOWN, IRCstats.unknown, FALSE);
946 			SetDlgItemInt(hDlg, IDC_OPERS, IRCstats.operators, FALSE);
947 			SetDlgItemInt(hDlg, IDC_CHANNELS, IRCstats.channels, FALSE);
948 			if (IRCstats.clients > IRCstats.global_max)
949 				IRCstats.global_max = IRCstats.clients;
950 			if (IRCstats.me_clients > IRCstats.me_max)
951 					IRCstats.me_max = IRCstats.me_clients;
952 			SetDlgItemInt(hDlg, IDC_MAXCLIENTS, IRCstats.global_max, FALSE);
953 			SetDlgItemInt(hDlg, IDC_LCLIENTS, IRCstats.me_clients, FALSE);
954 			SetDlgItemInt(hDlg, IDC_LSERVERS, IRCstats.me_servers, FALSE);
955 			SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, IRCstats.me_max, FALSE);
956 			SetTimer(hDlg, 1, 5000, NULL);
957 			return TRUE;
958 		case WM_COMMAND:
959 			if (LOWORD(wParam) == IDOK)
960 			{
961 				DestroyWindow(hDlg);
962 				return TRUE;
963 			}
964 			break;
965 
966 	}
967 	return FALSE;
968 }
969 
970 /* This was made by DrBin but I cleaned it up a bunch to make it work better */
971 
AddItemToTree(HWND hWnd,LPSTR lpszItem,int nLevel,short remap)972 HTREEITEM AddItemToTree(HWND hWnd, LPSTR lpszItem, int nLevel, short remap)
973 {
974 	TVITEM tvi;
975 	TVINSERTSTRUCT tvins;
976 	static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
977 	static HTREEITEM hPrevLev[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
978 	HTREEITEM hti;
979 
980 	if (remap)
981 	{
982 		hPrev = (HTREEITEM)TVI_FIRST;
983 		memset(hPrevLev, 0, sizeof(HTREEITEM)*10);
984 	}
985 
986 	tvi.mask = TVIF_TEXT|TVIF_PARAM;
987 	tvi.pszText = lpszItem;
988 	tvi.cchTextMax = lstrlen(lpszItem);
989 	tvi.lParam = (LPARAM)nLevel;
990 	tvins.item = tvi;
991 	tvins.hInsertAfter = hPrev;
992 	if (nLevel == 1)
993 		tvins.hParent = TVI_ROOT;
994 	else
995 		tvins.hParent = hPrevLev[nLevel-1];
996 	hPrev = (HTREEITEM)SendMessage(hWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT) &tvins);
997 	hPrevLev[nLevel] = hPrev;
998 	TreeView_EnsureVisible(hWnd,hPrev);
999 	if (nLevel > 1)
1000 	{
1001 	        hti = TreeView_GetParent(hWnd, hPrev);
1002         	tvi.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
1003 	        tvi.hItem = hti;
1004 	        TreeView_SetItem(hWnd, &tvi);
1005 	}
1006 	return hPrev;
1007 }
1008 
1009 /*
1010  * Now used to create list of servers for server list tree view -- David Flynn
1011  * Recoded by codemastr to be faster.
1012  * I removed the Potvin credit because it no longer uses any original code and I don't
1013  * even think Potvin actually made the original code
1014  */
win_map(aClient * server,HWND hwTreeView,short remap)1015 void win_map(aClient *server, HWND hwTreeView, short remap)
1016 {
1017         aClient *acptr;
1018 	Link *lp;
1019 
1020 	AddItemToTree(hwTreeView,server->name,server->hopcount+1, remap);
1021 
1022 	for (lp = Servers; lp; lp = lp->next)
1023         {
1024                 acptr = lp->value.cptr;
1025                 if (acptr->srvptr != server)
1026                         continue;
1027                 win_map(acptr, hwTreeView, 0);
1028         }
1029 }
1030 
1031 /* ugly stuff, but hey it works -- codemastr */
win_log(unsigned char * format,...)1032 void win_log(unsigned char *format, ...)
1033 {
1034         va_list ap;
1035         unsigned char buf[2048];
1036 		unsigned char *buf2;
1037         va_start(ap, format);
1038         ircvsprintf(buf, format, ap);
1039 	if (!IsService)
1040 	{
1041 		strcat(buf, "\r\n");
1042 		if (errors)
1043 		{
1044 			buf2 = MyMalloc(strlen(errors)+strlen(buf)+1);
1045 			sprintf(buf2, "%s%s",errors,buf);
1046 			MyFree(errors);
1047 			errors = NULL;
1048 		}
1049 		else
1050 		{
1051 			buf2 = MyMalloc(strlen(buf)+1);
1052 			sprintf(buf2, "%s",buf);
1053 		}
1054 		errors = buf2;
1055 	}
1056 	else
1057 	{
1058 		FILE *fd = fopen("service.log", "a");
1059 		if (fd)
1060 		{
1061 			fprintf(fd, "%s\n", buf);
1062 			fclose(fd);
1063 		}
1064 #ifdef _DEBUG
1065 		else
1066 		{
1067 		    OutputDebugString(buf);
1068 		}
1069 #endif
1070 	}
1071         va_end(ap);
1072 }
1073 
win_error()1074 void win_error()
1075 {
1076 	if (errors && !IsService)
1077 		DialogBox(hInst, "ConfigError", hwIRCDWnd, (DLGPROC)ConfigErrorDLG);
1078 }
1079 
ConfigErrorDLG(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam)1080 LRESULT CALLBACK ConfigErrorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
1081 {
1082 	switch (message)
1083 	{
1084 		case WM_INITDIALOG:
1085 			MessageBeep(MB_ICONEXCLAMATION);
1086 			SetDlgItemText(hDlg, IDC_CONFIGERROR, errors);
1087 			MyFree(errors);
1088 			errors = NULL;
1089 			return (TRUE);
1090 		case WM_COMMAND:
1091 			if (LOWORD(wParam) == IDOK)
1092 				EndDialog(hDlg, TRUE);
1093 			break;
1094 		case WM_CLOSE:
1095 			EndDialog(hDlg, TRUE);
1096 			break;
1097 		case WM_DESTROY:
1098 			break;
1099 
1100 		}
1101 	return (FALSE);
1102 }
1103