source: main/tags/2.40/gsdl/src/w32server/fnord.cpp@ 21085

Last change on this file since 21085 was 4642, checked in by sjboddie, 21 years ago

Added command line arguments to server.exe so the GLI can tell it to use
an alternative config file.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 34.8 KB
Line 
1/**********************************************************************
2 *
3 * fnord.cpp
4 * Copyright (C) 1996
5 *
6 * A component of the fnord webserver written by [email protected].
7 *
8 * Altered for use with the Greenstone digital library software by the
9 * New Zealand Digital Library Project at the University of Waikato,
10 * New Zealand.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *********************************************************************/
27
28#include "text_t.h"
29#include <windows.h>
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33#include <memory.h>
34#pragma hdrstop
35#include "netio.h"
36#include "settings.h"
37#include "httpsrv.h"
38#include "resource.h"
39#include "locate.h"
40#include "cgiwrapper.h"
41#include "startbrowser.h"
42#include "d_winsock.h"
43
44#define MAINWINDOWWIDTH 400
45#define MAINWINDOWHEIGHT 200
46
47#define WASTEHEIGHT 44 // Error in ht due to caption and menu bar
48#define WASTEWIDTH 6
49#define SPACERWIDTH 5
50
51// size and position of the collection title
52#define COLTITLEWIDTH 351
53#define COLTITLEHEIGHT 35
54#define COLTITLEX ((MAINWINDOWWIDTH-COLTITLEWIDTH)/2)
55#define COLTITLEY 10
56
57// size and position of the version string
58#define VERSIONWIDTH MAINWINDOWWIDTH
59#define VERSIONHEIGHT 20
60#define VERSIONX 0
61#define VERSIONY (COLTITLEY+COLTITLEHEIGHT)
62
63// size and position of the Greenstone digital library logo
64#define LOGOWIDTH 135
65#define LOGOHEIGHT 55
66#define LOGOX (MAINWINDOWWIDTH-(LOGOWIDTH+SPACERWIDTH))
67#define LOGOY (MAINWINDOWHEIGHT-(LOGOHEIGHT+SPACERWIDTH))
68
69// size and position of the enter button
70#define ENTERBUTTONWIDTH 160
71#define ENTERBUTTONHEIGHT 30
72#define ENTERBUTTONX SPACERWIDTH
73#define ENTERBUTTONY ((MAINWINDOWHEIGHT-(LOGOHEIGHT+SPACERWIDTH))-(ENTERBUTTONHEIGHT+SPACERWIDTH))
74
75// size and position of the enter string
76#define ENTERSTRINGX (ENTERBUTTONX+ENTERBUTTONWIDTH+SPACERWIDTH)
77#define ENTERSTRINGY ENTERBUTTONY
78#define ENTERSTRINGWIDTH (MAINWINDOWWIDTH-(ENTERBUTTONWIDTH+SPACERWIDTH+SPACERWIDTH+SPACERWIDTH))
79#define ENTERSTRINGHEIGHT ENTERBUTTONHEIGHT
80
81// size and position of the info string
82#define INFOWIDTH MAINWINDOWWIDTH
83#define INFOHEIGHT (MAINWINDOWHEIGHT-INFOY)
84#define INFOX 0
85#define INFOY ENTERBUTTONY
86
87// size and position of restricted buttons
88#define ALTERNATIVEBUTTONWIDTH 160
89#define ALTERNATIVEBUTTONHEIGHT 30
90#define ALTERNATIVEBUTTONX SPACERWIDTH
91#define ALTERNATIVEBUTTONY LOGOY
92
93#define INFOBUTTONWIDTH 30
94
95// size and position of restart button
96#define RESTARTBUTTONWIDTH 160
97#define RESTARTBUTTONHEIGHT 30
98#define RESTARTBUTTONX 50
99#define RESTARTBUTTONY (MAINWINDOWHEIGHT-RESTARTBUTTONHEIGHT-15)
100
101const char versionstring[] = "version " GSDL_VERSION;
102
103const char strnothing[] = "";
104const char strinit[] = "Initialising...";
105const char strsb[] = "Starting browser...";
106const char strrestartlib[] = "Press the 'Restart Library' button to start a browser\n"
107"and enter library";
108const char strenterlib[] = "Press this button to begin using\n"
109"the library";
110const char *enterstring = NULL; // points to the current enter string
111const char *infostring = NULL; // points to the current info string
112
113
114// globals to do with networking and browsers
115int have_networking = 0;
116int netscapeneeded = 0;
117char startbrowserdir[1024] = ""; // HARD LIMIT!!!!!
118
119
120// stats to do with the last time the enter library button was pressed
121// these stats are needed to make suggestions about the proxy
122int enterlib_libaccessnum = -1; // -1 = NA
123DWORD enterlib_time = 0;
124
125
126enum { undefined_window, console_window, plain_window }
127window_state;
128
129HDC coltitledc = NULL;
130HBITMAP defcoltitlebitmap = NULL, coltitlebitmap=NULL;
131
132HDC logodc=NULL;
133HBITMAP deflogobitmap=NULL, logobitmap=NULL;
134
135HWND GoButton = NULL;
136HWND Enter = NULL;
137HWND EnterRestricted = NULL;
138HWND InfoRestricted = NULL;
139int init_type = 0;
140int init_done = 0;
141
142void finish_up() {
143 // remember the current preferences
144 write_settings("");
145
146 // Shutdown the HTTP server
147 EndHTTPServer();
148
149 // Shutdown the main server modules
150 CleanUpNetIO();
151 // RemoveFnordFromTray();
152
153 // Unload the wsock32 dll
154 d_UnloadWinsock();
155
156 // Clean up graphics stuff from window
157
158 if (defcoltitlebitmap != NULL)
159 SelectObject (coltitledc, defcoltitlebitmap);
160 if (coltitlebitmap != NULL)
161 DeleteObject (coltitlebitmap);
162 if (coltitledc != NULL)
163 DeleteDC (coltitledc);
164
165 if (deflogobitmap != NULL)
166 SelectObject (logodc, deflogobitmap);
167 if (logobitmap != NULL)
168 DeleteObject (logobitmap);
169 if (logodc != NULL)
170 DeleteDC (logodc);
171
172 // Shutdown the main window
173 PostQuitMessage(0);
174}
175
176
177int overlap(int left, int top, int right, int bottom,
178 RECT &r2)
179{
180 if (left <= r2.right && r2.left <= right &&
181 top <= r2.bottom && r2.top <= bottom)
182 return 1;
183 else
184 return 0;
185}
186
187
188void paint_window (HDC pdc, RECT &updateRect) {
189 // make sure the various DCs are set up
190 if (coltitledc == NULL) {
191 coltitledc = CreateCompatibleDC(pdc);
192 defcoltitlebitmap = (HBITMAP)SelectObject (coltitledc, coltitlebitmap);
193 }
194
195 if (logodc == NULL) {
196 logodc = CreateCompatibleDC(pdc);
197 deflogobitmap = (HBITMAP)SelectObject (logodc, logobitmap);
198 }
199
200 // remove any remaining sign of initial buttons
201 if (init_done && (overlap (ENTERBUTTONX, ENTERBUTTONY, ENTERBUTTONX+ENTERBUTTONWIDTH,
202 ALTERNATIVEBUTTONY+ALTERNATIVEBUTTONHEIGHT, updateRect))) {
203 RECT initRect;
204 initRect.left = ENTERBUTTONX;
205 initRect.top = ENTERBUTTONY;
206 initRect.right = ENTERBUTTONX+ENTERBUTTONWIDTH;
207 initRect.bottom = ALTERNATIVEBUTTONY+ALTERNATIVEBUTTONHEIGHT;
208 FillRect(pdc, &initRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
209 }
210
211 // update the collection title if needed
212 if (overlap(COLTITLEX, COLTITLEY,
213 COLTITLEX+COLTITLEWIDTH, COLTITLEY+COLTITLEHEIGHT,
214 updateRect)) {
215 BitBlt (pdc, COLTITLEX, COLTITLEY,
216 COLTITLEX+COLTITLEWIDTH, COLTITLEY+COLTITLEHEIGHT,
217 coltitledc, 0, 0, SRCCOPY);
218 }
219
220 // update the version string if needed
221 if (overlap (VERSIONX, VERSIONY,
222 VERSIONX+VERSIONWIDTH, VERSIONY+VERSIONHEIGHT,
223 updateRect)) {
224 RECT versionRect;
225 versionRect.left = VERSIONX;
226 versionRect.top = VERSIONY;
227 versionRect.right = VERSIONX+VERSIONWIDTH;
228 versionRect.bottom = VERSIONY+VERSIONHEIGHT;
229 DrawText(pdc, versionstring, -1, &versionRect, DT_CENTER);
230 }
231
232 // decide what we want to draw
233 if (init_done && gsdl_show_console) {
234 // we want to draw a "console" window
235 if (window_state != console_window ||
236 overlap (text_rect.left, text_rect.top,
237 text_rect.right, text_rect.bottom,
238 updateRect)) {
239 refresh_console (pdc);
240 }
241
242 window_state = console_window;
243
244 } else {
245 // we want to draw a "plain" window
246
247 // update the enter string if needed
248 if (overlap (ENTERSTRINGX, ENTERSTRINGY, ENTERSTRINGX+ENTERSTRINGWIDTH,
249 ENTERSTRINGY+ENTERSTRINGHEIGHT, updateRect)) {
250
251 RECT enterstringRect;
252 enterstringRect.left = ENTERSTRINGX;
253 enterstringRect.top = ENTERSTRINGY;
254 enterstringRect.right = ENTERSTRINGX+ENTERSTRINGWIDTH;
255 enterstringRect.bottom = ENTERSTRINGY+ENTERSTRINGHEIGHT;
256 FillRect(pdc, &enterstringRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
257
258 if ((enterstring != NULL) && (strlen(enterstring) > 0)) {
259
260 int cury = ENTERSTRINGY;
261 int startline = 0, here = 0;
262 while (enterstring[here] != '\0') {
263 if (enterstring[here] < ' ') {
264 if (here - startline > 0) {
265 // output the text
266 TextOut (pdc, ENTERSTRINGX, cury,
267 &enterstring[startline], here-startline);
268 cury += line_spacing;
269 }
270 startline = here+1;
271 }
272 here++;
273 }
274 // output any remaining text
275 if (here - startline > 0) {
276 TextOut (pdc, ENTERSTRINGX, cury, &enterstring[startline], here-startline);
277 }
278 }
279 }
280
281 window_state = plain_window;
282 }
283
284 // update the info string if needed
285 if (init_done && !gsdl_show_console &&
286 ((infostring != NULL) && overlap (INFOX, INFOY,
287 INFOX+INFOWIDTH, INFOY+INFOHEIGHT,
288 updateRect))) {
289 RECT infoRect;
290 infoRect.left = INFOX;
291 infoRect.top = INFOY;
292 infoRect.right = INFOX+INFOWIDTH;
293 infoRect.bottom = INFOY+INFOHEIGHT;
294 FillRect(pdc, &infoRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
295 DrawText(pdc, infostring, -1, &infoRect, DT_CENTER);
296 }
297
298 // update the logo (always)
299 BitBlt (pdc, LOGOX, LOGOY, LOGOX+LOGOWIDTH, LOGOY+LOGOHEIGHT,
300 logodc, 0, 0, SRCCOPY);
301}
302
303
304void handle_painting (HWND Window) {
305 HDC pdc; PAINTSTRUCT ps;
306 pdc = BeginPaint(Window, &ps);
307
308 paint_window (pdc, ps.rcPaint);
309
310 EndPaint(Window, &ps);
311}
312
313
314// returns 1 on success, 0 otherwise
315int enter_library (HWND Window) {
316 int res;
317
318 // get the url and attempt to start a browser
319 char *localname = GetLocalName(NULL);
320 if (have_networking) {
321 text_t url = "http://" + text_t(localname);
322
323 gsdl_url = url;
324 write_settings(gsdl_url);
325
326 if (gsdl_port_num != 80)
327 url += ":" + text_t(gsdl_port_num);
328
329 url += gsdl_enterlib;
330
331 // add a unique ending so it will always result in a request
332 text_t::const_iterator it =
333 findchar (gsdl_enterlib.begin(), gsdl_enterlib.end(), '?');
334 if (it == gsdl_enterlib.end()) url.push_back ('?');
335 else url.push_back ('&');
336 int tcount = GetTickCount();
337 url += "uq=" + text_t(tcount);
338
339 // remember the library access number for later proxy checking
340 enterlib_libaccessnum = libaccessnum;
341
342 if (gsdl_start_browser) {
343
344 // do a quick check to make sure we're using netscape when
345 // we should be (it might have been just installed)
346 if (netscapeneeded) gsdl_check_browser_settings (netscapeneeded);
347
348 char *cstr_url = url.getcstr();
349 if (strlen (startbrowserdir) <= 0) {
350 res = startbrowser (cstr_url, gsdl_browser_exe, NULL);
351
352 } else res = startbrowser (cstr_url, gsdl_browser_exe, startbrowserdir);
353
354 delete cstr_url;
355
356 } else {
357 return 1;
358 }
359 }
360
361 if (res == SB_NOERROR) {
362 // success !!
363
364 // remember the time the browser was started for later proxy checking
365 if (have_networking) enterlib_time = GetTickCount();
366
367 return 1;
368 }
369
370 // no browser was started
371 enterlib_libaccessnum = -1;
372
373 if ((res == SB_FAIL_BADFORMAT) || (res == SB_FAIL_NOTFOUND)) {
374 if (!netscapeneeded) { // any browser
375 MessageBox(Window,
376 "Failed to start your chosen browser. It seems that your\n"
377 "chosen browser has been removed or corrupted.\n"
378 "Please check your browser choice by going to the\n"
379 "'Settings...' item under the 'File' menu.",
380 "Greenstone Digital Library Software", MB_OK);
381 } else { // netscape used
382 MessageBox(Window,
383 "Failed to start Netscape. It seems that Netscape has\n"
384 "been removed or corrupted. You need Netscape\n"
385 "installed to use the Greenstone Digital Library\n"
386 "software on non-networked machines.",
387 "Greenstone Digital Library Software", MB_OK);
388 }
389
390 } else {
391 MessageBox(Window,
392 "Failed to start your browser. This may have been\n"
393 "because there was not enough memory available. Shut\n"
394 "down all other applications you have running, and\n"
395 "try again.",
396 "Greenstone Digital Library Software", MB_OK);
397 }
398
399 return 0; // failed
400}
401
402
403void install_netscape (HWND Window) {
404 char installpath[256];
405
406 // try to find the browser directory
407 char *gsdlhome = gsdl_gsdlhome.getcstr();
408 strcpy (installpath, gsdlhome); // use gsdlhome to find the CD-ROM drive...
409 delete gsdlhome;
410
411 // remove any slashes from the pathname
412 int len = strlen (installpath);
413 while ((len > 0) && ((installpath[len-1] == '\\') || (installpath[len-1] == '/'))) {
414 len--;
415 }
416 // remove '\gsdl'
417 len = len - 5;
418 installpath[len] = '\0';
419
420 strcat (installpath, "\\netscape\\");
421
422 // check this directory
423 if (!cstrcheckdir(installpath)) {
424 return;
425 }
426
427 // get the operating system information
428 OSVERSIONINFO osver;
429 memset(&osver, 0, sizeof(OSVERSIONINFO));
430 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
431 GetVersionEx(&osver);
432
433 // get the install program for this operating system
434 if (osver.dwPlatformId == VER_PLATFORM_WIN32s) {
435 strcat (installpath, "n16e405.exe");
436 } else {
437 strcat (installpath, "n32e405.exe");
438 }
439
440 // run the install program
441 int res = WinExec (installpath, SW_SHOW);
442 if (res == 0) {
443 // out of resources or memory
444 MessageBox (Window,
445 "Did not have enough resources or memory to run the\n"
446 "install program. Try shutting down all other programs\n"
447 "and trying again.",
448 "Greenstone Digital Library Software",
449 MB_OK|MB_APPLMODAL);
450
451 } else if (res == ERROR_BAD_FORMAT) {
452 // executable image is corrupt -- ????
453 MessageBox (Window,
454 "The install program seems to be corrupt.",
455 "Greenstone Digital Library Software",
456 MB_OK|MB_APPLMODAL);
457
458 } else if ((res == ERROR_FILE_NOT_FOUND) || (res == ERROR_PATH_NOT_FOUND)) {
459 // couldn't find the executable -- ????
460 MessageBox (Window,
461 "Could not find the install program. Try installing\n"
462 "Netscape from the Greenstone Digital Library\n"
463 "software's install program.",
464 "Greenstone Digital Library Software",
465 MB_OK|MB_APPLMODAL);
466 }
467}
468
469void open_help () {
470 char topdir[256], cmd[256];
471
472 // try to find the browser directory
473 char *gsdlhome = gsdl_gsdlhome.getcstr();
474 strcpy (topdir, gsdlhome); // use gsdlhome to find the CD-ROM drive...
475 delete gsdlhome;
476 strcpy (cmd, "notepad ");
477
478 // remove any slashes from the pathname
479 int len = strlen (topdir);
480 while ((len > 0) && ((topdir[len-1] == '\\') || (topdir[len-1] == '/'))) {
481 len--;
482 }
483 // remove the '\gsdl'
484 len = len - 5;
485 topdir[len] = '\0';
486
487 strcat (topdir, "\\README.txt");
488 strcat (cmd, topdir);
489
490 WinExec (cmd, SW_SHOW);
491}
492
493
494long __stdcall WndProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) {
495 switch(Message) {
496 // Constant Messages
497 case WM_CREATE:
498 break;
499
500 case WM_COMMAND:
501 if ((GoButton != NULL) && ((HWND)LParam == GoButton)) {
502 // attempt to start a browser
503 gsdl_start_browser = 1;
504 if (enter_library (Window) && !gsdl_show_console)
505 ShowWindow(Window,SW_MINIMIZE);
506
507 } else if ((Enter != NULL) && ((HWND)LParam == Enter)) {
508 init_done = 1;
509 init_type = 1;
510
511 } else if ((EnterRestricted != NULL) && ((HWND)LParam == EnterRestricted)) {
512 init_done = 1;
513 init_type = 0;
514
515 } else if ((InfoRestricted != NULL) && ((HWND)LParam == InfoRestricted)) {
516 MessageBox (NULL, "The Greenstone system automatically determines whether your computer has\n"
517 "network software installed or is connected to a network. It operates correctly\n"
518 "under any of these conditions.\n\n"
519 "The restricted version is intended for use when the standard one\n\n"
520 " (a) causes an unwanted telephone dialup operation;\n"
521 " (b) fails to run because network software is installed, but installed\n"
522 " incorrectly.\n\n"
523 "The restricted version only works with Netscape (not Internet Explorer).\n\n"
524 "Unless these problems arise, you should always use the standard version\n"
525 "(press the 'Enter Library' button).\n",
526 "Greenstone Digital Library Software",
527 MB_OK | MB_ICONINFORMATION | MB_APPLMODAL);
528
529 } else {
530 switch (LOWORD(WParam)) {
531 case ID_PROJECT_SETTINGS:
532 Settings_Dialog(Window, netscapeneeded);
533 break;
534 case ID_INSTALL_NETSCAPE:
535 install_netscape(Window);
536 break;
537 case IDHELP:
538 open_help();
539 break;
540 case ID_PROJECT_EXIT:
541 finish_up();
542 break;
543 default:
544 break;
545 }
546 }
547 break;
548
549 case WM_PAINT:
550 handle_painting(Window);
551 break;
552
553 case HTTP_SERVER_MSG:
554 ProcessHTTPServerMsg(WParam, LParam);
555 break;
556
557 case WM_DESTROY:
558 finish_up();
559 break;
560
561 default:
562 //Unhandled Messages end up here (DefWindowProc)
563 return DefWindowProc(Window, Message, WParam, LParam);
564 }
565
566 return(0);
567}
568
569// returns 0 if successful,
570// otherwise a WSA error number
571int tryinitnetwork (HANDLE Instance, HWND MsgWindow, char *path) {
572 // try to load winsock
573 int err = d_LoadWinsock (path);
574
575 if (err == D_NOERROR) {
576 // next, try to init netio
577 err = InitNetIO();
578
579 if (err == 0) {
580 // next, try to start the http server
581 err = StartHTTPServer(MsgWindow);
582
583 if (err == 0) {
584 // finally, get the host name (no error value
585 // is returned from this function)
586 GetLocalName((HINSTANCE)Instance);
587
588 } else {
589 // couldn't start the http server,
590 // deinit netio and unload winsock
591 CleanUpNetIO();
592 d_UnloadWinsock();
593 }
594
595 } else {
596 // couldn't init netio, unload winsock
597 d_UnloadWinsock();
598 }
599
600 } else {
601 // couldn't load winsock
602 err = WSASYSNOTREADY;
603 }
604
605 return err;
606}
607
608
609// inits all the network functionality
610// returns 0 if an unrecoverable error occurred,
611// and 1 if everything successfully initialised.
612int initnetwork (HANDLE Instance, HWND MsgWindow) {
613 OSVERSIONINFO osver;
614
615 // get the operating system information
616 memset(&osver, 0, sizeof(OSVERSIONINFO));
617 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
618 GetVersionEx(&osver);
619
620 // first try to initialise the network with system installed
621 // networking software
622 startbrowserdir[0] = '\0';
623 netscapeneeded = 0;
624 int err = 1;
625 if (init_type == 1) err = tryinitnetwork (Instance, MsgWindow, NULL);
626
627 // if an error occurred, try again with billsock
628 if (err != 0) {
629 // get the path of billsock (current directory + ("net16" | "net32"))
630 char winsockpath[1024]; // HARD LIMIT!!!!
631
632 find_location();
633 char *data_location_c = data_location.getcstr();
634 strcpy (winsockpath, data_location_c);
635 delete data_location_c;
636
637 // remove all the slashes at the end of billpath
638 int len = strlen (winsockpath);
639 while ((len > 0) && ((winsockpath[len-1] == '\\') || (winsockpath[len-1] == '/'))) {
640 len--;
641 }
642 winsockpath[len] = '\0';
643
644 if (osver.dwPlatformId == VER_PLATFORM_WIN32s)
645 strcat (winsockpath, "\\net16\\");
646 else {
647 strcat (winsockpath, "\\net32\\");
648 strcpy (startbrowserdir, winsockpath);
649 }
650
651 // try again
652 err = tryinitnetwork (Instance, MsgWindow, winsockpath);
653
654 if (err == 0) {
655 // we will need to use netscape on 95/98/NT machines
656 if (osver.dwPlatformId != VER_PLATFORM_WIN32s) {
657 netscapeneeded = 1;
658 // make sure the browser state is in step with the network condition
659 gsdl_check_browser_settings (netscapeneeded);
660 }
661
662 // check to see if a browser is running
663 if (browserrunning(gsdl_browser_exe) == NO_ERROR) {
664 MessageBox (NULL,
665 "The Greenstone Digital Library software has detected a\n"
666 "running browser. To let our networking software\n"
667 "correctly initialize, please shut down your browser\n"
668 "and restart the Greenstone Digital Library software.",
669 "Greenstone Digital Library Software", MB_OK|MB_APPLMODAL);
670 PostMessage(MsgWindow,WM_CLOSE,0,0);
671 finish_up(); // will unload winsock
672 exit(0); // nothing more to do
673 }
674 }
675 }
676
677 // if an error occurred display a nice error message
678 if (err != 0) {
679
680 // WSASYSNOTREADY Couldn't load winsock
681 // WSAVERNOTSUPPORTED The version of Windows Sockets support requested
682 // is not provided by this particular Windows Sockets implementation.
683 // WSAEINVAL The Windows Sockets version specified by the application
684 // is not supported by this DLL.
685 // WSAEPROTONOSUPPORT The specified protocol is not supported.
686 // WSAEPROTOTYPE The specified protocol is the wrong type for this socket.
687 // WSAESOCKTNOSUPPORT The specified socket type is not supported in
688 // this address family.
689 // WSANOTINITIALISED A successful WSAStartup must occur before
690 // using this function.
691 // WSAENETDOWN The Windows Sockets implementation
692 // has detected that the network subsystem has failed.
693 // WSAEADDRINUSE The specified address
694 // is already in use. (See the SO_REUSEADDR socket option under setsockopt.)
695 // WSAEFAULT The namelen argument is too small (less
696 // than the size of a struct sockaddr).
697 // WSAEINPROGRESS A blocking Windows Sockets call is in progress.
698 // WSAEAFNOSUPPORT The specified address family is not supported
699 // by this protocol.
700 // WSAENOBUFS Not enough buffers available, too many connections.
701 // WSAENOTSOCK The descriptor is not a socket.
702 // WSAEISCONN The socket is already connected.
703 // WSAEMFILE No more file descriptors are available.
704 // WSAEOPNOTSUPP The referenced socket is not of a type that
705 // supports the listen operation.
706
707 // get a text version of the error number
708 char errstr[256];
709
710 switch (err) {
711 case WSASYSNOTREADY: strcpy(errstr, "WSASYSNOTREADY");
712 break;
713 case WSAVERNOTSUPPORTED: strcpy (errstr, "WSAVERNOTSUPPORTED");
714 break;
715 case WSAEINVAL: strcpy (errstr, "WSAEINVAL");
716 break;
717 case WSAEPROTONOSUPPORT: strcpy (errstr, "WSAEPROTONOSUPPORT");
718 break;
719 case WSAEPROTOTYPE: strcpy (errstr, "WSAEPROTOTYPE");
720 break;
721 case WSAESOCKTNOSUPPORT: strcpy (errstr, "WSAESOCKTNOSUPPORT");
722 break;
723 case WSANOTINITIALISED: strcpy (errstr, "WSANOTINITIALISED");
724 break;
725 case WSAEFAULT: strcpy (errstr, "WSAEFAULT");
726 break;
727 case WSAEAFNOSUPPORT: strcpy (errstr, "WSAEAFNOSUPPORT");
728 break;
729 case WSAENOTSOCK: strcpy (errstr, "WSAENOTSOCK");
730 break;
731 case WSAEISCONN: strcpy (errstr, "WSAEISCONN");
732 break;
733 case WSAEOPNOTSUPP: strcpy (errstr, "WSAEOPNOTSUPP");
734 break;
735 case WSAENETDOWN: strcpy (errstr, "WSAENETDOWN");
736 break;
737 case WSAEADDRINUSE: strcpy (errstr, "WSAEADDRINUSE");
738 break;
739 case WSAEINPROGRESS: strcpy (errstr, "WSAEINPROGRESS");
740 break;
741 case WSAENOBUFS: strcpy (errstr, "WSAENOBUFS");
742 break;
743 case WSAEMFILE: strcpy (errstr, "WSAEMFILE");
744 break;
745 default: sprintf (errstr, "WSA ERROR: %i", err);
746 break;
747 }
748
749 // create a nice error message
750 char message[2048];
751
752 switch (err) {
753 case WSAEADDRINUSE:
754 // couldn't bind socket
755 sprintf (message, "Could not find a free socket.", errstr);
756 break;
757
758 default:
759 // cannot init winsock
760 sprintf (message, "Could not initialize the network\n"
761 " (Reason: %s).", errstr);
762 break;
763 }
764
765 strcat (message, "\n\n"
766 "Please submit a bug report using the support.htm file\n"
767 "on the CD-ROM.");
768
769 MessageBox (NULL, message, "Greenstone Digital Library Software", MB_OK);
770 }
771
772 return (err == 0);
773}
774
775
776void log_computer_info () {
777 char tmpstr[1024];
778
779 // get various information about this computer
780 if (gsdl_keep_log || gsdl_show_console) {
781 // get operating system information
782 OSVERSIONINFO osver;
783 osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
784
785 if (GetVersionEx(&osver)) {
786 if (osver.dwPlatformId == VER_PLATFORM_WIN32s) {
787 log_message ("Platform: win32s\n");
788 } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
789 log_message ("Platform: windows 95\n");
790 } else if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
791 log_message ("Platform: windows NT\n");
792 }
793
794 sprintf (tmpstr, "MajorVersion: %i\n", (int)osver.dwMajorVersion);
795 log_message(tmpstr);
796 sprintf (tmpstr, "MinorVersion: %i\n", (int)osver.dwMinorVersion);
797 log_message(tmpstr);
798 sprintf (tmpstr, "BuildNumber: %i\n", (int)osver.dwBuildNumber);
799 log_message(tmpstr);
800 sprintf (tmpstr, "CSDVersion: %s\n\n", osver.szCSDVersion);
801 log_message(tmpstr);
802 }
803
804 // get memory information
805 MEMORYSTATUS memstatus;
806 memstatus.dwLength = sizeof(MEMORYSTATUS);
807 GlobalMemoryStatus(&memstatus);
808
809 sprintf (tmpstr, "TotalPhys: %i Meg\n", (int)(memstatus.dwTotalPhys/1024/1024));
810 log_message (tmpstr);
811 sprintf (tmpstr, "AvailPhys: %i Meg\n", (int)(memstatus.dwAvailPhys/1024/1024));
812 log_message (tmpstr);
813 sprintf (tmpstr, "TotalPageFile: %i Meg\n", (int)(memstatus.dwTotalPageFile/1024/1024));
814 log_message (tmpstr);
815 sprintf (tmpstr, "AvailPageFile: %i Meg\n", (int)(memstatus.dwAvailPageFile/1024/1024));
816 log_message (tmpstr);
817 sprintf (tmpstr, "TotalVirtual: %i Meg\n", (int)(memstatus.dwTotalVirtual/1024/1024));
818 log_message (tmpstr);
819 sprintf (tmpstr, "AvailVirtual: %i Meg\n\n", (int)(memstatus.dwAvailVirtual/1024/1024));
820 log_message (tmpstr);
821
822 // log the version number
823 log_message("GSDL version: " GSDL_VERSION "\n");
824 }
825
826}
827
828// possible command line options are
829// --location=directory (the path to GSDLHOME which defaults to the
830// directory where server.exe lives)
831// --config=file (the path to the configuration file to use which defaults
832// to GSDLHOME\gsdlsite.cfg)
833static void parse_args(const text_t cmdline, text_t &location, text_t &config_file) {
834
835 location.clear();
836 config_file.clear();
837
838 if (cmdline.size() < 3) return;
839
840 text_t name, val;
841 bool foundname = false;
842 text_t::const_iterator here = cmdline.begin();
843 text_t::const_iterator end = cmdline.end();
844 while (here != end) {
845 if (*here == '-' && ((here+1) != end) && (*(here+1) == '-')) {
846 here++;
847 if (name == "location") {
848 location = val;
849 } else if (name == "config") {
850 config_file = val;
851 }
852 foundname = false;
853 name.clear();
854 val.clear();
855 } else if (*here == '=') {
856 foundname = true;
857 } else {
858 if (foundname) {
859 val.push_back(*here);
860 } else {
861 name.push_back(*here);
862 }
863 }
864 here++;
865 }
866 if (name == "location") {
867 location = val;
868 } else if (name == "config") {
869 config_file = val;
870 }
871}
872
873
874int __stdcall WinMain(HINSTANCE Instance, HINSTANCE /*PrevInstance*/, LPSTR CmdLineStr, int /*CmdShow*/) {
875 HWND MainWindow; MSG Message; WNDCLASS MainClass;
876
877 // parse arguments
878 text_t location, config_file;
879 parse_args(CmdLineStr, location, config_file);
880 gsdl_conffile = config_file;
881
882 //Create a window class
883 MainClass.style = CS_HREDRAW | CS_VREDRAW;
884 MainClass.lpfnWndProc = WndProc;
885 MainClass.cbClsExtra = 0;
886 MainClass.cbWndExtra = 0;
887 MainClass.hInstance = Instance;
888 MainClass.hIcon = LoadIcon(Instance, MAKEINTRESOURCE(TRAY_ICON));
889 MainClass.hCursor = LoadCursor(NULL, IDC_ARROW);
890 MainClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
891 MainClass.lpszMenuName = MAKEINTRESOURCE(Main_Menu);
892 MainClass.lpszClassName = "Greenstone Digital Library Software";
893 if (!RegisterClass(&MainClass))
894 return 0;
895
896
897 // Load various bitmaps
898 coltitlebitmap = LoadBitmap (Instance, MAKEINTRESOURCE(GSDL_COL_TITLE));
899 logobitmap= LoadBitmap (Instance, MAKEINTRESOURCE(GSDL_LOGO));
900
901 // Create the main window
902 MainWindow = CreateWindow("Greenstone Digital Library Software",
903 "Greenstone Digital Library Software",
904 WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
905 WS_MINIMIZEBOX,
906 CW_USEDEFAULT, CW_USEDEFAULT,
907 MAINWINDOWWIDTH + WASTEWIDTH,
908 MAINWINDOWHEIGHT + WASTEHEIGHT,
909 NULL, NULL, Instance, NULL);
910
911 text_rect.left = 0;
912 text_rect.top = VERSIONY+VERSIONHEIGHT + 5;
913 text_rect.right = MAINWINDOWWIDTH;
914 text_rect.bottom = LOGOY-SPACERWIDTH;
915
916 window_state = undefined_window;
917
918 ShowWindow(MainWindow, SW_SHOW);
919 set_location(location);
920
921 // get ready to draw the main window
922 RECT windowRect;
923 GetClientRect (MainWindow, &windowRect);
924 HDC pdc = GetDC (MainWindow);
925
926 // retrieve and save the text metrics
927 TEXTMETRIC tm;
928 GetTextMetrics(pdc, &tm);
929 line_spacing = tm.tmHeight + tm.tmExternalLeading;
930 GSDL_Window = MainWindow;
931
932 // init various modules
933 read_settings (0); // don't know if netscape is needed at this point
934
935 if (!gsdl_auto_enter) {
936
937 // add the select version checkbox
938 Enter = CreateWindow("BUTTON", // predefined class
939 "Enter Library", // button text
940 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_DEFPUSHBUTTON, // styles
941 ENTERBUTTONX, // starting x position
942 ENTERBUTTONY, // starting y position
943 ENTERBUTTONWIDTH, // button width
944 ENTERBUTTONHEIGHT, // button height
945 MainWindow, // parent window
946 NULL, // No menu
947 Instance,
948 NULL); // pointer not needed
949
950 EnterRestricted = CreateWindow("Button", // predefined class
951 "Restricted Version", // button text
952 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_PUSHBUTTON, // styles
953 ALTERNATIVEBUTTONX, // starting x position
954 ALTERNATIVEBUTTONY, // starting y position
955 ALTERNATIVEBUTTONWIDTH-(INFOBUTTONWIDTH+SPACERWIDTH), // button width
956 ALTERNATIVEBUTTONHEIGHT, // button height
957 MainWindow, // parent window
958 (HMENU)NULL, // No menu
959 Instance,
960 NULL); // pointer not needed
961
962 InfoRestricted = CreateWindow("Button", // predefined class
963 NULL,
964 WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_BITMAP, // styles
965 ALTERNATIVEBUTTONWIDTH-INFOBUTTONWIDTH+SPACERWIDTH, // starting x position
966 ALTERNATIVEBUTTONY, // starting y position
967 INFOBUTTONWIDTH, // button width
968 ALTERNATIVEBUTTONHEIGHT, // button height
969 MainWindow, // parent window
970 (HMENU)NULL, // No menu
971 Instance,
972 NULL); // pointer not needed
973
974 HANDLE i_icon = LoadImage (Instance, MAKEINTRESOURCE(GSDL_ICBMP), IMAGE_BITMAP,
975 INFOBUTTONWIDTH-4, ALTERNATIVEBUTTONHEIGHT-4, LR_DEFAULTCOLOR);
976 SendMessage (InfoRestricted, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)i_icon);
977
978 SetFocus (Enter);
979
980 enterstring = strenterlib;
981 paint_window (pdc, windowRect);
982
983 // message loop for init buttons
984 while (!init_done) {
985 if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
986 if (Message.message == WM_QUIT) return Message.wParam;
987 if (!IsDialogMessage (MainWindow, &Message)) {
988 TranslateMessage(&Message); /* translate keyboard messages */
989 DispatchMessage(&Message); /* return control to Windows NT */
990 }
991 } else {
992 Sleep (1);
993 }
994 }
995
996 // don't want these buttons anymore
997 DestroyWindow (Enter);
998 DestroyWindow (EnterRestricted);
999 DestroyWindow (InfoRestricted);
1000
1001 enterstring = strnothing;
1002 paint_window (pdc, windowRect);
1003
1004 } else {
1005 // auto enter is enabled - start up standard version
1006 init_type = 1;
1007 init_done = 1;
1008 }
1009
1010 // draw the main window containing an init message
1011 infostring = strinit;
1012 paint_window (pdc, windowRect);
1013 DWORD lastcheck = GetTickCount();
1014
1015 have_networking = initnetwork (Instance, MainWindow);
1016 if (!have_networking) {
1017 MessageBox(NULL,
1018 "Failed to initialize networking.",
1019 "Greenstone Digital Library Software",MB_OK|MB_SYSTEMMODAL);
1020 exit (0);
1021 }
1022
1023 if (!gsdl_init()) // quit if can't initialise the library correctly
1024 exit (0);
1025 initstartbrowser();
1026 log_computer_info ();
1027
1028 // show the initialising message for at least 1 second
1029 while (DiffTickCounts (lastcheck, GetTickCount()) < 1000) {
1030 Sleep (1);
1031 }
1032
1033 // attempt to start a browser
1034 if (gsdl_show_console || !gsdl_start_browser) infostring = strnothing;
1035 else infostring = strsb;
1036 paint_window (pdc, windowRect);
1037 lastcheck = GetTickCount();
1038 if (enter_library (MainWindow) && !gsdl_show_console) {
1039 // stay maximised for at least 1 second
1040 while (DiffTickCounts (lastcheck, GetTickCount()) < 1000) Sleep (1);
1041 ShowWindow(MainWindow,SW_MINIMIZE);
1042 }
1043
1044 // add the "restart library" button
1045 GoButton = CreateWindow("BUTTON", // predefined class
1046 "Restart Library", // button text
1047 WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, // styles
1048 RESTARTBUTTONX, // starting x position
1049 RESTARTBUTTONY, // starting y position
1050 RESTARTBUTTONWIDTH, // button width
1051 RESTARTBUTTONHEIGHT, // button height
1052 MainWindow, // parent window
1053 NULL, // No menu
1054 Instance,
1055 NULL); // pointer not needed
1056
1057 infostring = strrestartlib;
1058 paint_window (pdc, windowRect);
1059
1060 // release the DC used to display the init messages
1061 ReleaseDC (MainWindow, pdc);
1062
1063 //Message loop
1064 lastcheck = GetTickCount();
1065 int seenbrowser = 0; // if we see a browser then it disappears
1066 // we will ask if they want to close the
1067 // the library down
1068 char last_gsdl_browser_exe[MAX_FILENAME_SIZE]; // need to notice when the
1069 // browser setting changes
1070 strcpy (last_gsdl_browser_exe, gsdl_browser_exe);
1071
1072 for (;;) {
1073 if (PeekMessage(&Message, NULL, 0, 0, PM_REMOVE)) {
1074 if (Message.message == WM_QUIT) break;
1075 if (!IsDialogMessage (MainWindow, &Message)) {
1076 TranslateMessage(&Message); /* translate keyboard messages */
1077 DispatchMessage(&Message); /* return control to Windows NT */
1078 }
1079
1080 } else {
1081 if (DiffTickCounts (lastcheck, GetTickCount()) > 500) {
1082 // make sure the browser hasn't changed
1083 if (strcmp (last_gsdl_browser_exe, gsdl_browser_exe) != 0) {
1084 seenbrowser = 0;
1085 strcpy (last_gsdl_browser_exe, gsdl_browser_exe);
1086 }
1087
1088 // do check
1089 lastcheck = GetTickCount();
1090 if (gsdl_start_browser && browserrunning(gsdl_browser_exe) == NO_ERROR) {
1091 // we were able to connect to a browser
1092 seenbrowser = 1;
1093
1094 // see if the enter library button has been pressed
1095 // with nothing happening for 20 seconds
1096 if ((enterlib_libaccessnum >= 0) &&
1097 (enterlib_libaccessnum == libaccessnum) &&
1098 (DiffTickCounts (enterlib_time, GetTickCount()) > 20000)) {
1099 // something could be wrong!! (most likely cause is a proxy)
1100 MessageBox(NULL,
1101 "Your browser does not seem to be responding to the 'Enter Library'\n"
1102 "request. Try turning off all proxy servers in your browser settings.\n"
1103 "If you are using Internet Explorer make sure BOTH dialup settings\n"
1104 "AND LAN settings have their proxy servers disabled.",
1105 "Greenstone Digital Library Software",MB_OK|MB_SYSTEMMODAL);
1106 enterlib_libaccessnum = -1;
1107 }
1108
1109
1110 } else {
1111 // no browser was found
1112
1113 if (seenbrowser) {
1114 // we have seen a browser in the past
1115 if (MessageBox(NULL,
1116 "The Greenstone Digital Library software has noticed that you\n"
1117 "shut down your browser. Would you also like to shut down the\n"
1118 "Greenstone Digital Library software?",
1119 "Greenstone Digital Library Software",MB_YESNO|MB_SYSTEMMODAL) == IDYES)
1120 PostMessage(MainWindow,WM_CLOSE,0,0);
1121 }
1122 seenbrowser = 0;
1123 }
1124 }
1125
1126 Sleep (1); // millisecond
1127 }
1128 }
1129
1130 return Message.wParam;
1131}
Note: See TracBrowser for help on using the repository browser.