3
|
1 /* $Id: main.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
|
|
2
|
|
3 /*
|
|
4 * main.c
|
|
5 */
|
|
6 #include "copyright.h"
|
|
7
|
|
8 #include <stdio.h>
|
|
9 #include <string.h>
|
|
10 #include <sys/types.h>
|
|
11 #include <signal.h>
|
|
12 #include <setjmp.h>
|
|
13 #include <pwd.h>
|
|
14 #ifdef hpux
|
|
15 #include <time.h>
|
|
16 #else
|
|
17 #include <sys/time.h>
|
|
18 #include <sys/wait.h>
|
|
19 #endif /* hpux */
|
|
20 #include "Wlib.h"
|
|
21 #include "defs.h"
|
|
22 #include "struct.h"
|
|
23 #include "data.h"
|
|
24 #include "packets.h"
|
|
25 #include "proto.h"
|
|
26 #include "gameconf.h"
|
|
27 #ifdef SOUND
|
|
28 #include "Slib.h"
|
|
29 #endif
|
|
30 #include "sound.h"
|
|
31
|
|
32 jmp_buf env;
|
|
33
|
|
34 #ifdef AMIGA
|
|
35 /* needed for metafork... implemented by running a whole new copy
|
|
36 don't honestly know why I bothered ;-) */
|
|
37 char **command_line;
|
|
38 int global_argc;
|
|
39 #endif
|
|
40
|
|
41 #ifdef GATEWAY
|
|
42 #define DEFAULT_GATEWAY "atlgw" /* for Quar */
|
|
43
|
|
44 static char *get_gw P((void));
|
|
45 static unsigned long mkaddr P((char *m));
|
|
46 static void getUdpPort P((void));
|
|
47 #endif
|
|
48
|
|
49 extern int UdpLocalPort;
|
|
50 /* Prototypes */
|
|
51 static void printUsage P((char *prog));
|
|
52 static void show_credits ();
|
|
53
|
|
54 int
|
|
55 main(argc, argv)
|
|
56 int argc;
|
|
57 char **argv;
|
|
58 {
|
|
59 int intrupt();
|
|
60 int team, s_type;
|
|
61 char *dpyname = NULL;
|
|
62 int usage = 0;
|
|
63 int err = 0;
|
|
64 char *name, *ptr, *cp;
|
|
65 #if !defined(NeXT) && !defined(RS6K) && !defined(SVR4)
|
|
66 char *rindex();
|
|
67 #endif
|
|
68 struct passwd *pwent;
|
|
69 int passive = 0;
|
|
70 #ifdef METASERVER
|
|
71 int usemeta = 0;
|
|
72 #endif /* METASERVER */
|
|
73 /* char *defaultsFile=NULL;*/
|
|
74
|
|
75 pseudo[0] = defpasswd[0] = '\0';
|
|
76
|
|
77 #ifdef AMIGA
|
|
78 command_line = argv;
|
|
79 global_argc=argc;
|
|
80 #endif
|
|
81
|
|
82 name = *argv++;
|
|
83 argc--;
|
|
84 if ((ptr = rindex(name, '/')) != NULL)
|
|
85 name = ptr + 1;
|
|
86 #ifdef GATEWAY
|
|
87 netaddr = -1; /* special NULL address */
|
|
88 serverName = get_gw(); /* default machine is gw */
|
|
89 #endif
|
|
90 while (*argv) {
|
|
91 if (**argv != '-') {
|
|
92 serverName = *argv; /* don't abort argument processing */
|
|
93 argv++;
|
|
94 argc--;
|
|
95 } else {
|
|
96 ++*argv;
|
|
97
|
|
98 argc--;
|
|
99 ptr = *argv++;
|
|
100 while (*ptr) {
|
|
101 switch (*ptr) {
|
|
102 case 'C': /* character name */
|
|
103 (void) strncpy(pseudo, *argv, sizeof(pseudo));
|
|
104 argv++;
|
|
105 argc--;
|
|
106 break;
|
|
107
|
|
108 case 'c': /* Credits */
|
|
109 show_credits();
|
|
110 exit (0);
|
|
111 break;
|
|
112
|
|
113 case 'P': /* authorization password */
|
|
114 (void) strncpy(defpasswd, *argv, sizeof(defpasswd));
|
|
115 {
|
|
116 int i;
|
|
117 for (i = 0; (*argv)[i]; i++)
|
|
118 (*argv)[i] = 0;
|
|
119 }
|
|
120 argv++;
|
|
121 argc--;
|
|
122 break;
|
|
123
|
|
124 case 'u':
|
|
125 usage++;
|
|
126 break;
|
|
127 case 's':
|
|
128 if (*argv) {
|
|
129 xtrekPort = atoi(*argv);
|
|
130 passive = 1;
|
|
131 argv++;
|
|
132 argc--;
|
|
133 }
|
|
134 break;
|
|
135 case 'p':
|
|
136 if (*argv) {
|
|
137 xtrekPort = atoi(*argv);
|
|
138 argv++;
|
|
139 argc--;
|
|
140 }
|
|
141 break;
|
|
142 case 'd':
|
|
143 dpyname = *argv;
|
|
144 argc--;
|
|
145 argv++;
|
|
146 break;
|
|
147 #ifdef METASERVER
|
|
148 case 'm':
|
|
149 usemeta = 1;
|
|
150 break;
|
|
151 #endif /* METASERVER */
|
|
152 case 'h':
|
|
153 serverName = *argv;
|
|
154 if (!serverName)
|
|
155 err++;
|
|
156 #ifdef GATEWAY
|
|
157 gw_mach = *argv;
|
|
158 #endif
|
|
159 argc--;
|
|
160 argv++;
|
|
161 break;
|
|
162 #ifdef GATEWAY
|
|
163 case 'H':
|
|
164 netaddr = mkaddr(*argv);
|
|
165 argc--;
|
|
166 argv++;
|
|
167 break;
|
|
168 #endif
|
|
169
|
|
170 case 't':
|
|
171 title = *argv;
|
|
172 argc--;
|
|
173 argv++;
|
|
174 break;
|
|
175 case 'r':
|
|
176 defaultsFile = *argv;
|
|
177 argv++;
|
|
178 argc--;
|
|
179 break;
|
|
180 #ifdef AUTHORIZE
|
|
181 case 'o':
|
|
182 RSA_Client = -1;
|
|
183 break;
|
|
184 case 'R':
|
|
185 RSA_Client = -2;
|
|
186 break;
|
|
187 #else
|
|
188 case 'o':
|
|
189 case 'R':
|
|
190 printf("This client does not have binary authorization.\n");
|
|
191 break;
|
|
192 #endif
|
|
193 case 'e':
|
|
194 #ifdef AUTHORIZE
|
|
195 checkExpire(1);
|
|
196 #else
|
|
197 printf("This client does not RSA verify and will not expire.\n");
|
|
198 #endif
|
|
199 exit(0);
|
|
200 break;
|
|
201 case 'f': /* list ftp sites */
|
|
202 fprintf(stderr, "\n\
|
|
203 The newest version of the Paradise client can be found at:\n\
|
|
204 ftp.pnetrek.org in /pub/paradise/bin/\n\
|
|
205 or ftp.cs.umn.edu in /users/glamm/paradise/bin/\n\
|
|
206 \n\
|
|
207 Quick ftp instructions:\n\
|
|
208 This assumes you are bob@school.edu and are using a Sun workstation\n\
|
|
209 ('sparc' architecture). Modify with your mailing address and architecture.\n\
|
|
210 Type:\n\
|
|
211 ftp ftp.cs.umn.edu\n\
|
|
212 (at name prompt) anonymous\n\
|
|
213 (at password prompt) bob@school.edu\n\
|
|
214 (at ftp> prompt) cd users/glamm/paradise/bin\n\
|
|
215 (at ftp> prompt) binary\n\
|
|
216 (at ftp> prompt) dir\n\
|
|
217 (lots of files printed - pick out the latest release for your architecture.\n\
|
|
218 all the client binaries begin with 'netrek'.)\n\
|
|
219 (at ftp> prompt) get netrek.Sparc-SunOS-static\n\
|
|
220 (note: static and dynamic are functionally the same.\n\
|
|
221 (at ftp> prompt) bye\n\
|
|
222 \n\
|
|
223 That's it!\n");
|
|
224 exit(0);
|
|
225 case 'G':
|
|
226 if (*argv) {
|
|
227 ghoststart++;
|
|
228 ghost_pno = atoi(*argv);
|
|
229 printf("Emergency restart being attempted...\n");
|
|
230 argv++;
|
|
231 argc--;
|
|
232 }
|
|
233 break;
|
|
234 case '2': /* force paradise */
|
|
235 paradise = 1;
|
|
236 break;
|
|
237 #ifdef RECORDER
|
|
238 case 'F': /* File playback */
|
|
239 if (*argv) {
|
|
240 playFile = strdup(*argv);
|
|
241 playback = 1;
|
|
242 argv++;
|
|
243 argc--;
|
|
244 }
|
|
245 break;
|
|
246 #endif
|
|
247 case 'U':
|
|
248 if(*argv == NULL || (UdpLocalPort = atoi(*argv)) <= 0) {
|
|
249 fprintf(stderr, "Error: -U requires a port number\n");
|
|
250 usage++;
|
|
251 break;
|
|
252 }
|
|
253 argc--;
|
|
254 argv++;
|
|
255 break;
|
|
256 default:
|
|
257 fprintf(stderr, "%s: unknown option '%c'\n", name, *ptr);
|
|
258 err++;
|
|
259 break;
|
|
260 }
|
|
261 ptr++;
|
|
262 }
|
|
263 }
|
|
264 }
|
|
265 #ifdef GATEWAY
|
|
266 if (netaddr == -1) {
|
|
267 fprintf(stderr,
|
|
268 "netrek: no remote address set (-H). Restricted server will not work.\n");
|
|
269 }
|
|
270 #endif
|
|
271
|
|
272
|
|
273
|
|
274 inittrigtables();
|
|
275
|
|
276 initStars(); /* moved from redraw.c at KAO\'s suggestion */
|
|
277
|
|
278 if (usage || err) {
|
|
279 printUsage(name);
|
|
280 #ifdef AUTHORIZE
|
|
281 checkExpire(1);
|
|
282 #endif
|
|
283 exit(0);
|
|
284 /* exit(err); Exits from checkExpire */
|
|
285 }
|
|
286 defaultsFile = initDefaults(defaultsFile);
|
|
287
|
|
288 #ifdef AUTHORIZE
|
|
289 if (RSA_Client != -1)
|
|
290 checkExpire(0);
|
|
291 #endif
|
|
292
|
|
293 /* compatability */
|
|
294 if (argc > 0)
|
|
295 serverName = argv[0];
|
|
296
|
|
297 srandom(getpid() + time((long *) 0));
|
|
298
|
|
299 #ifdef RECORDER
|
|
300 if(playback || booleanDefault("playback",0)) {
|
|
301 defNickName = "playback";
|
|
302 usemeta=0;
|
|
303 serverName = "playback";
|
|
304 } else
|
|
305 #endif
|
|
306 {
|
|
307 if (serverName) {
|
|
308 char temp[80], *s;
|
|
309 sprintf(temp, "server.%s", serverName);
|
|
310 if ((s = getdefault(temp))) {
|
|
311 s=strdup(s);
|
|
312 printf("Using nickname \"%s\" for server %s\n", serverName, s);
|
|
313 defNickName = serverName;
|
|
314 serverName = s;
|
|
315 defFlavor = getdefault("flavor");
|
|
316 if(defFlavor)
|
|
317 defFlavor=strdup(defFlavor);
|
|
318 }
|
|
319 }
|
|
320 if (!serverName) {
|
|
321 if(serverName = getdefault("server"))
|
|
322 serverName = strdup(serverName);
|
|
323 }
|
|
324 if (!serverName && !passive) {
|
|
325 serverName = DEFAULT_SERVER;
|
|
326 #ifdef METASERVER
|
|
327 usemeta = 1; /* no server specified, show the menu */
|
|
328 #endif
|
|
329 }
|
|
330 if (passive)
|
|
331 serverName = "passive"; /* newwin gets a wrong title otherwise */
|
|
332
|
|
333 if (xtrekPort < 0)
|
|
334 xtrekPort = intDefault("port", -1);
|
|
335 if (xtrekPort < 0)
|
|
336 xtrekPort = DEFAULT_PORT;
|
|
337 #if 0
|
|
338 #ifdef AUTHORIZE
|
|
339 if (RSA_Client >= 0)
|
|
340 RSA_Client = booleanDefault("useRSA", RSA_Client);
|
|
341 else
|
|
342 RSA_Client = (RSA_Client == -2);
|
|
343 #endif
|
|
344 #endif /* 0 */
|
|
345
|
|
346 } /* playback */
|
|
347 build_default_configuration();
|
|
348
|
|
349 #ifdef METASERVER
|
|
350 metaserverAddress = stringDefault("metaserver",
|
|
351 "metaserver.ecst.csuchico.edu");
|
|
352 if (usemeta)
|
|
353 parsemeta();
|
|
354 #endif /* METASERVER */
|
|
355
|
|
356 W_Initialize(dpyname);
|
|
357 #ifdef SOUND
|
|
358 S_Initialize();
|
|
359 #endif
|
|
360
|
|
361
|
|
362 #ifdef METASERVER
|
|
363 metaFork = booleanDefault("metaFork", metaFork);
|
|
364 /* do the metawindow thang */
|
|
365 if (usemeta) {
|
|
366 metawindow();
|
|
367 metainput();
|
|
368 if (metaFork)
|
|
369 W_Initialize(dpyname);
|
|
370 newwin(dpyname, name);
|
|
371 } else
|
|
372 #endif /* METASERVER */
|
|
373
|
|
374 /* this creates the necessary x windows for the game */
|
|
375 newwin(dpyname, name);
|
|
376
|
|
377 #ifdef TIMELORD
|
|
378 start_timelord();
|
|
379 #endif
|
|
380
|
|
381 /* open memory...? */
|
|
382 openmem();
|
|
383 #ifdef RECORDER
|
|
384 if (!startPlayback())
|
|
385 #endif
|
|
386 {
|
|
387 if (!passive) {
|
|
388 callServer(xtrekPort, serverName);
|
|
389 } else {
|
|
390 connectToServer(xtrekPort);
|
|
391 }
|
|
392 }
|
|
393 #ifdef FEATURE
|
|
394 sendFeature("FEATURE_PACKETS", 'S', 1, 0, 0);
|
|
395 #endif
|
|
396
|
|
397 timeStart = time(NULL);
|
|
398 findslot();
|
|
399
|
|
400 /* sets all the settings from defaults file (.xtrekrc probably) */
|
|
401 resetDefaults();
|
|
402
|
|
403 #ifdef UNIX_SOUND
|
|
404 init_sound();
|
|
405 play_sound(SND_PARADISE);
|
|
406 #endif
|
|
407
|
|
408 mapAll();
|
|
409 /* signal(SIGINT, SIG_IGN);*/
|
|
410 signal(SIGCHLD, (void (*) ()) reaper);
|
|
411
|
|
412 /* Get login name */
|
|
413 if ((pwent = getpwuid(getuid())) != NULL)
|
|
414 (void) strncpy(login, pwent->pw_name, sizeof(login));
|
|
415 else
|
|
416 (void) strncpy(login, "Bozo", sizeof(login));
|
|
417 login[sizeof(login) - 1] = '\0';
|
|
418
|
|
419 if (pseudo[0] == '\0') {
|
|
420 if ((cp = getdefault("name")) != 0)
|
|
421 (void) strncpy(pseudo, cp, sizeof(pseudo));
|
|
422 else
|
|
423 (void) strncpy(pseudo, login, sizeof(pseudo));
|
|
424 }
|
|
425 pseudo[sizeof(pseudo) - 1] = '\0';
|
|
426
|
|
427 if (defpasswd[0] == '\0') {
|
|
428 char buf[100], buf2[100]; /* added password by character name -JR */
|
|
429 sprintf(buf,"password.%s",pseudo);
|
|
430 if (serverName) /* password by server name -TH */
|
|
431 sprintf(buf2, "password.%s", serverName);
|
|
432 if((cp = getdefault(buf)) || (cp = getdefault(buf2)) ||
|
|
433 (cp = getdefault("password")))
|
|
434 (void) strncpy(defpasswd, cp, sizeof(defpasswd));
|
|
435 }
|
|
436 defpasswd[sizeof(defpasswd) - 1] = '\0';
|
|
437
|
|
438 /*
|
|
439 sendLoginReq("Gray Lensman", "hh", "sfd", 0); loginAccept = -1; while
|
|
440 (loginAccept == -1) { socketPause(1,0); readFromServer(); }
|
|
441 */
|
|
442 getname(pseudo, defpasswd);
|
|
443 loggedIn = 1;
|
|
444 #ifdef TIMER
|
|
445 timeBank[T_SERVER] = timeStart;
|
|
446 timeBank[T_DAY] = 0;
|
|
447 #endif /* TIMER */
|
|
448
|
|
449
|
|
450 #ifdef AUTOKEY
|
|
451 /* autokey.c */
|
|
452 autoKeyDefaults();
|
|
453 #endif /* AUTOKEY */
|
|
454
|
|
455 /*
|
|
456 Set p_hostile to hostile, so if keeppeace is on, the guy starts off
|
|
457 hating everyone (like a good fighter should)
|
|
458 */
|
|
459 me->p_hostile = (1 << number_of_teams) - 1;
|
|
460
|
|
461 redrawTstats();
|
|
462
|
|
463 me->p_planets = 0;
|
|
464 me->p_genoplanets = 0;
|
|
465 me->p_armsbomb = 0;
|
|
466 me->p_genoarmsbomb = 0;
|
|
467 /* Set up a reasonable default */
|
|
468 me->p_whydead = KQUIT;
|
|
469 me->p_teami = -1;
|
|
470 s_type = defaultShip(CRUISER); /* from rlb7h 11/15/91 TC */
|
|
471
|
|
472 if (booleanDefault("netStats", 1))
|
|
473 startPing(); /* tell the server that we support pings */
|
|
474
|
|
475 #ifdef AUTOKEY
|
|
476 if (autoKey) {
|
|
477 /* XX: changes entire state of display */
|
|
478 W_AutoRepeatOff();
|
|
479 }
|
|
480 #endif
|
|
481 /*
|
|
482 hack to make galaxy class ships work. This could be more elegant, but
|
|
483 the configuration code would have to be modified quite a bit, since
|
|
484 the client doesn't know if it's on a paradise server until after it
|
|
485 connects, and it needs the configuration info before it connects.
|
|
486 */
|
|
487 init_galaxy_class();
|
|
488
|
|
489 initkeymap(-1); /* needs to have ship types initialized -JR */
|
|
490
|
|
491 setjmp(env); /* Reentry point of game */
|
|
492
|
|
493 if (ghoststart) {
|
|
494 int i;
|
|
495
|
|
496 ghoststart = 0;
|
|
497
|
|
498 for (i = -1; i < 5; i++)
|
|
499 if (teaminfo[i].letter == me->p_mapchars[0])
|
|
500 break;
|
|
501
|
|
502 me->p_teami = i;
|
|
503
|
|
504 if (me->p_damage > me->p_ship->s_maxdamage) {
|
|
505 me->p_status = POUTFIT;
|
|
506 } else
|
|
507 me->p_status = PALIVE;
|
|
508 } else
|
|
509 me->p_status = POUTFIT;
|
|
510
|
|
511 while (1) {
|
|
512 switch (me->p_status) {
|
|
513 case POUTFIT:
|
|
514 case PTQUEUE:
|
|
515 /* give the player the motd and find out which team he wants */
|
|
516 #if 1
|
|
517 new_entrywindow(&team, &s_type);
|
|
518 #else
|
|
519 entrywindow(&team, &s_type);
|
|
520 #endif
|
|
521 allowPlayerlist = 1;
|
|
522 if (W_IsMapped(playerw))
|
|
523 playerlist();
|
|
524
|
|
525 #ifdef RECORDER
|
|
526 if (!playback)
|
|
527 #endif
|
|
528 if (team == -1) {
|
|
529 W_DestroyWindow(w);
|
|
530 #ifdef AUTOKEY
|
|
531 if (autoKey)
|
|
532 W_AutoRepeatOn();
|
|
533 #endif
|
|
534 sendByeReq();
|
|
535 sleep(1);
|
|
536 printf("OK, bye!\n");
|
|
537 EXIT(0);
|
|
538 }
|
|
539 sendVersion();
|
|
540 myship = getship(myship->s_type);
|
|
541
|
|
542 currentship = myship->s_type;
|
|
543
|
|
544 /*
|
|
545 sendOptionsPacket(); /* this would totally blast any flags you
|
|
546 had on the server
|
|
547 */
|
|
548
|
|
549 redrawall = 1;
|
|
550 enter();
|
|
551 calibrate_stats();
|
|
552 W_ClearWindow(w);
|
|
553 /*
|
|
554 for (i = 0; i < NSIG; i++) { signal(i, SIG_IGN); }
|
|
555 */
|
|
556
|
|
557 me->p_status = PALIVE; /* Put player in game */
|
|
558
|
|
559 #ifdef UNIX_SOUND
|
|
560 kill_sound ();
|
|
561 #endif
|
|
562
|
|
563 #ifdef HOCKEY
|
|
564 hockeyInit();
|
|
565 #endif /*HOCKEY*/
|
|
566
|
|
567 #ifdef TIMER
|
|
568 timeBank[T_SHIP] = time(NULL);
|
|
569 #endif /* TIMER */
|
|
570
|
|
571 if (showStats) /* Default showstats are on. */
|
|
572 W_MapWindow(statwin);
|
|
573
|
|
574 #ifdef GATEWAY
|
|
575 /* pick a nice set of UDP ports */
|
|
576 getUdpPort();
|
|
577 #endif
|
|
578
|
|
579 #if ATM
|
|
580 if (tryUdp && commMode != COMM_UDP) {
|
|
581 sendUdpReq(COMM_UDP);
|
|
582 }
|
|
583 #endif /* ATM */
|
|
584 #ifdef SHORT_PACKETS
|
|
585 if (tryShort) {
|
|
586 sendShortReq(SPK_VON);
|
|
587 tryShort = 0; /* only try it once */
|
|
588 }
|
|
589 #endif /* SHORT_PACKETS */
|
|
590 /* Send request for a full update */
|
|
591 if (askforUpdate) {
|
|
592 if(recv_short)
|
|
593 sendShortReq(SPK_SALL);
|
|
594 else
|
|
595 sendUdpReq(COMM_UPDATE);
|
|
596 }
|
|
597 sendUpdatePacket(1000000 / updateSpeed);
|
|
598
|
|
599 W_Deiconify(baseWin);
|
|
600
|
|
601 break;
|
|
602 case PALIVE:
|
|
603 case PEXPLODE:
|
|
604 case PDEAD:
|
|
605 case POBSERVE:
|
|
606
|
|
607 #ifdef TIMELORD
|
|
608 /* reading the MOTD doesn't count against your playing time */
|
|
609 update_timelord_notcount();
|
|
610 #endif
|
|
611
|
|
612 /* Get input until the player quits or dies */
|
|
613 input();
|
|
614 W_ClearWindow(mapw);
|
|
615 #ifdef TIMELORD
|
|
616 /* get any fractional minutes we missed */
|
|
617 update_timelord(1);
|
|
618 #endif
|
|
619 break;
|
|
620 default:
|
|
621 printf("client has p_status=%d. how strange\n", me->p_status);
|
|
622 me->p_status = POUTFIT;
|
|
623 }
|
|
624 }
|
|
625
|
|
626 /* NOTREACHED */
|
|
627 }
|
|
628
|
|
629 static void
|
|
630 printUsage(prog)
|
|
631 char *prog;
|
|
632 {
|
|
633 fprintf(stderr, "Usage:\n %s [ options ] [ ntserv-host ]\n\
|
|
634 Where options are\n\
|
|
635 [-h] host server host name\n\
|
|
636 [-p] port server port number\n\
|
|
637 [-r] xtrekrc defaults file to replace ~/.xtrekrc\n\
|
|
638 [-t] title window manager title\n\
|
|
639 [-d] display set Xwindows display\n\
|
|
640 [-C] name netrek pseudonym\n\
|
|
641 [-P] passwd passwd to use to attempt autologin\n\
|
|
642 [-R] use RSA authorization (default)\n\
|
|
643 [-o] use old (non-RSA) authorization\n\
|
|
644 [-s] port wait for connection from ntserv on a port (debugging)\n\
|
|
645 %s\
|
|
646 %s\
|
|
647 [-U] port specify base local UDP port number to use\n\
|
|
648 [-e] check the expire time on the client\n\
|
|
649 [-f] how to get the newest client\n\
|
|
650 [-u] print usage\n\
|
|
651 [-c] Paradise credits\n\
|
|
652 For emergency restart:\n\
|
|
653 [-2] force paradise - use if you were on a paradise server\n\
|
|
654 [-G] playernum specify player number to use\n\
|
|
655 [-s] port specify socket number to use\n\
|
|
656 Paradise Client %s\n\
|
|
657 For more information on how to play Paradise, use Netscape or Internet\n\
|
|
658 Explorer and connect to:\n\
|
|
659 http://www.pnetrek.org/ OR\n\
|
|
660 http://www.cs.umn.edu/users/glamm/paradise/\n\n", prog,
|
|
661 #ifdef METASERVER
|
|
662 " [-m] check metaserver for active servers\n",
|
|
663 #else
|
|
664 "",
|
|
665 #endif /* METASERVER */
|
|
666 #ifdef RECORDER
|
|
667 " [-F] file Replay from file instead of connecting\n",
|
|
668 #else
|
|
669 "",
|
|
670 #endif
|
|
671 CLIENTVERS);
|
|
672 }
|
|
673
|
|
674 void
|
|
675 reaper()
|
|
676 {
|
|
677 #if defined(hpux) || defined(SVR4) || defined(AMIGA)
|
|
678 wait((int *) 0);
|
|
679 #else
|
|
680 /* well, hell, just use NULL, it works for everything else anyway */
|
|
681 /* while (wait3((union wait *) 0, WNOHANG, NULL) > 0);*/
|
|
682 while(wait3(NULL, WNOHANG, NULL) > 0);
|
|
683 #endif /* hpux */
|
|
684 }
|
|
685
|
|
686 #ifdef GATEWAY
|
|
687 static struct udpmap_t {
|
|
688 int uid;
|
|
689 int serv_port;
|
|
690 int port;
|
|
691 int local_port;
|
|
692 } udpmap[] = {
|
|
693 /* 5000, 5001, 5000 *//* generic */
|
|
694 {
|
|
695 1290, 5010, 5011, 5010
|
|
696 }, /* fadden */
|
|
697 {
|
|
698 757, 5020, 5021, 5020
|
|
699 }, /* user2 */
|
|
700 };
|
|
701 #define MAPSIZE (sizeof(udpmap) / sizeof(struct udpmap_t))
|
|
702
|
|
703 static void
|
|
704 getUdpPort()
|
|
705 {
|
|
706 int i;
|
|
707 uid_t uid;
|
|
708 char *gw_m, *gw_p, *gw_lp, *gw_sp, *err, *getenv();
|
|
709
|
|
710 /* should always be set prior, but in case not .. */
|
|
711 if (!gw_mach) {
|
|
712 gw_m = getenv("GW_MACH");
|
|
713 if (gw_m)
|
|
714 gw_mach = gw_m;
|
|
715 else
|
|
716 gw_mach = DEFAULT_GATEWAY;
|
|
717 }
|
|
718 uid = getuid();
|
|
719
|
|
720 for (i = 0; i < MAPSIZE; i++) {
|
|
721 if (uid == udpmap[i].uid) {
|
|
722 gw_serv_port = udpmap[i].serv_port;
|
|
723 gw_port = udpmap[i].port;
|
|
724 gw_local_port = udpmap[i].local_port;
|
|
725 return;
|
|
726 }
|
|
727 }
|
|
728
|
|
729 gw_p = getenv("GW_PORT");
|
|
730 gw_sp = getenv("GW_SPORT");
|
|
731 gw_lp = getenv("GW_LPORT");
|
|
732
|
|
733 if (gw_p) {
|
|
734 gw_port = strtol(gw_p, &err, 10);
|
|
735 if (err == gw_p) {
|
|
736 fprintf(stderr, "netrek: malformed integer for GW_PORT: %s\n",
|
|
737 gw_p);
|
|
738 /* let something else complain about port 0 */
|
|
739 }
|
|
740 } else
|
|
741 gw_port = 5001;
|
|
742 if (gw_sp) {
|
|
743 gw_serv_port = strtol(gw_sp, &err, 10);
|
|
744 if (err == gw_sp) {
|
|
745 fprintf(stderr, "netrek: malformed integer for GW_SPORT: %s\n",
|
|
746 gw_sp);
|
|
747 /* let something else complain about port 0 */
|
|
748 }
|
|
749 } else
|
|
750 gw_serv_port = 5000;
|
|
751
|
|
752 if (gw_lp) {
|
|
753 gw_local_port = strtol(gw_lp, &err, 10);
|
|
754 if (err == gw_lp) {
|
|
755 fprintf(stderr, "netrek: malformed integer for GW_LPORT: %s\n",
|
|
756 gw_lp);
|
|
757 /* let something else complain about port 0 */
|
|
758 }
|
|
759 } else
|
|
760 gw_local_port = 5000;
|
|
761
|
|
762 /*
|
|
763 printf("gw_mach: \'%s\'\n", gw_mach); printf("gw_local_port: %d\n",
|
|
764 gw_local_port); printf("gw_serv_port: %d\n", gw_serv_port);
|
|
765 printf("gw_port: %d\n", gw_port);
|
|
766 */
|
|
767 }
|
|
768
|
|
769 #include <sys/socket.h>
|
|
770 #include <netinet/in.h>
|
|
771 #include <netdb.h>
|
|
772
|
|
773 /*
|
|
774 * In the event of problems assiocated with the above include files the
|
|
775 * following routine can be alternately used to convert a string
|
|
776 * ("xxx.xxx.xxx.xxx") to an internet address number.
|
|
777 *
|
|
778 * (author: Andy McFadden)
|
|
779 */
|
|
780
|
|
781 #ifdef notneeded
|
|
782 unsigned long
|
|
783 dotAddrToNetAddr(str)
|
|
784 char *str;
|
|
785 {
|
|
786 char *t;
|
|
787 unsigned long answer = 0;
|
|
788 t = str;
|
|
789 for (i = 0; i < 4; i++) {
|
|
790 answer = (answer << 8) | atoi(t);
|
|
791 while (*t && *t != '.')
|
|
792 t++;
|
|
793 if (*t)
|
|
794 t++;
|
|
795 }
|
|
796 return answer;
|
|
797 }
|
|
798 #endif
|
|
799
|
|
800 /*
|
|
801 * More network "correct" routine
|
|
802 */
|
|
803
|
|
804 static unsigned long
|
|
805 mkaddr(m)
|
|
806 char *m;
|
|
807 {
|
|
808 struct in_addr ad;
|
|
809 struct hostent *hp;
|
|
810
|
|
811 hp = gethostbyname(m);
|
|
812 if (!hp) {
|
|
813 ad.s_addr = inet_addr(m);
|
|
814 if (ad.s_addr == -1) {
|
|
815 fprintf(stderr, "netrek: unknown host \'%s\'\n", m);
|
|
816 exit(1);
|
|
817 }
|
|
818 } else
|
|
819 bcopy(hp->h_addr, (char *) &ad, hp->h_length);
|
|
820
|
|
821 return ad.s_addr;
|
|
822 }
|
|
823
|
|
824 static char *
|
|
825 get_gw()
|
|
826 {
|
|
827 char *gw_m;
|
|
828
|
|
829 gw_m = getenv("GW_MACH");
|
|
830 if (gw_m)
|
|
831 gw_mach = gw_m;
|
|
832 else
|
|
833 gw_mach = DEFAULT_GATEWAY;
|
|
834
|
|
835 return gw_mach;
|
|
836 }
|
|
837
|
|
838 #endif
|
|
839
|
|
840 void
|
|
841 show_credits()
|
|
842 {
|
|
843 printf ("Paradise Netrek\n\
|
|
844 \n\
|
|
845 Copyright (c) 1986 Chris Guthrie\n\
|
|
846 Copyright (c) 1989 Kevin P. Smith\n\
|
|
847 Copyright (c) 1993 Larry Denys, Kurt Olsen, Brandon Gillespie, and\n\
|
|
848 Robert Forsman\n\
|
|
849 Copyright (c) Eric Mehlaff, Sujal Patel, Robert Glamm, \n\
|
|
850 Lars Bernhardsson, Kurt Siegl, Nick Trown\n\
|
|
851 \n\
|
|
852 Paradise Developers\n\
|
|
853 Larry Deny Robert Forsman\n\
|
|
854 Brandon Gillespie Kurt Olsen\n\
|
|
855 \n\
|
|
856 Paradise Contributors (In alphabetical order):\n\
|
|
857 Terence Chang Mike McGrath\n\
|
|
858 Bill Dyess Matthew Mead\n\
|
|
859 Jerry Frain Gary Parnes\n\
|
|
860 Robert Glamm Sujal Patel\n\
|
|
861 T. Hadley Joe Rumsey\n\
|
|
862 Heath A. Kehoe Rado Smiljanic\n\
|
|
863 Andy McFadden Joe Young\n\
|
|
864 ");
|
|
865 }
|