source: trunk/gsdl/src/w32server/fnord.cpp@ 2286

Last change on this file since 2286 was 2286, checked in by sjboddie, 23 years ago

Had a bit of a tidy up in the fnord webserver code. The main change of note
was the removal of our reliance on the MAX_URL_SIZE constant. URLs and post
data of any length should now work.

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