source: gsdl/trunk/runtime-src/src/w32server/fnord.cpp@ 18841

Last change on this file since 18841 was 18841, checked in by ak19, 15 years ago

Reverting previous erroneous commit

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