~ubuntu-branches/ubuntu/vivid/imaze/vivid

« back to all changes in this revision

Viewing changes to source/server.c

  • Committer: Bazaar Package Importer
  • Author(s): Hans Freitag
  • Date: 2002-11-28 13:24:12 UTC
  • Revision ID: james.westby@ubuntu.com-20021128132412-lw82xl9oq1j36g8b
Tags: upstream-1.4
ImportĀ upstreamĀ versionĀ 1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** - - -  iMaze  - - -
 
3
**
 
4
** Copyright (c) 1993-2001 by Hans-Ulrich Kiel & Joerg Czeranski
 
5
** All rights reserved.
 
6
**
 
7
** Redistribution and use in source and binary forms, with or without
 
8
** modification, are permitted provided that the following conditions are
 
9
** met:
 
10
**
 
11
** 1. Redistributions of source code must retain the above copyright
 
12
**    notice, this list of conditions and the following disclaimer.
 
13
** 2. Redistributions in binary form must reproduce the above copyright
 
14
**    notice, this list of conditions and the following disclaimer in the
 
15
**    documentation and/or other materials provided with the distribution.
 
16
** 3. The name of the authors may not be used to endorse or promote
 
17
**    products derived from this software without specific prior written
 
18
**    permission.
 
19
** 4. The name ``iMaze'' may not be used for products derived from this
 
20
**    software unless a prefix or a suffix is added to the name.
 
21
**
 
22
** THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
 
23
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
24
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
25
** DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
 
26
** INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
27
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
28
** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
29
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
30
** STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 
31
** IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
32
** POSSIBILITY OF SUCH DAMAGE.
 
33
**
 
34
**
 
35
** Datei: server.c
 
36
**
 
37
** Kommentar:
 
38
**  Das Hauptprogramm des Servers
 
39
**  inklusive des Startens der anderen Prozesse
 
40
*/
 
41
 
 
42
 
 
43
#include <stdio.h>
 
44
#include <stdlib.h>
 
45
#include <string.h>
 
46
#include <signal.h>
 
47
 
 
48
#include "argv.h"
 
49
#include "global.h"
 
50
#include "fehler.h"
 
51
#include "speicher.h"
 
52
#include "system.h"
 
53
#include "labyrinth.h"
 
54
#include "server_netz.h"
 
55
#include "server.h"
 
56
#include "init_spieler.h"
 
57
 
 
58
static char sccsid[] = "@(#)server.c    3.19 12/04/01";
 
59
 
 
60
 
 
61
static int zeittakt_parsen(char *str);
 
62
 
 
63
 
 
64
static char *labfile_name = NULL;
 
65
 
 
66
struct arg_option argv_opts[] =
 
67
{
 
68
        { Arg_Include, NULL, net_opts },
 
69
        { Arg_Include, NULL, feature_opts },
 
70
        { Arg_Callback, "c", (void *)zeittakt_parsen,
 
71
                "set cycle time (15-150 ms, default 60)", "time" },
 
72
        { Arg_End, NULL, &labfile_name, NULL, "lab-file" }
 
73
};
 
74
 
 
75
 
 
76
/* Identifikationstext, mit dem jede Labyrinthdatei beginnt: */
 
77
static char MAGIC[] = "iMazeLab1\n";
 
78
 
 
79
u_int feldlaenge, feldbreite; /* Feldgroesse */
 
80
block **spielfeld;            /* Daten des Spielfeldes */
 
81
 
 
82
static void *session_deskriptor; /* Deskriptor zur Kommunikation mit der
 
83
                                    einzigen Session, die gestartet wird */
 
84
static char *session_status; /* Infostring ueber die einzige Session */
 
85
 
 
86
static int zeittakt = 60; /* in Millisekunden */
 
87
 
 
88
 
 
89
/*
 
90
** zeittakt_parsen
 
91
**
 
92
** Seiteneffekte:
 
93
**  setzt zeittakt
 
94
*/
 
95
static int zeittakt_parsen(char *str)
 
96
{
 
97
        long takt;
 
98
        char *end;
 
99
 
 
100
        takt = strtol(str, &end, 10);
 
101
        if (*end != 0 || takt < 15 || takt > 150)
 
102
                return 1; /* parse/value error */
 
103
 
 
104
        zeittakt = takt;
 
105
        return 0; /* ok */
 
106
}
 
107
 
 
108
 
 
109
/*
 
110
** ende_handler
 
111
**  wird aufgerufen, wenn der Server vom User beendet wird;
 
112
**  schickt dem Session-Prozess die Nachricht; der Server-Prozess wird
 
113
**  erst beendet, wenn der Session-Prozess geantwortet hat
 
114
**
 
115
** Parameter:
 
116
**  signum: Dummy-Parameter
 
117
*/
 
118
static void ende_handler(int signum)
 
119
{
 
120
        char daten; /* Puffer fuer die Nachricht */
 
121
 
 
122
        /* Nachricht NT_SPIEL_BEENDEN an Session-Prozess senden */
 
123
        daten = NT_SPIEL_BEENDEN;
 
124
        nachricht_senden(session_deskriptor, NULL, sizeof daten, &daten);
 
125
}
 
126
 
 
127
 
 
128
static void spieler_an_session(void *verbindung, char *progname, char *spruch,
 
129
        int kamera)
 
130
{
 
131
        char *daten; /* Puffer zum Uebertragen des Spruchs
 
132
                        an den Sessions-Prozess */
 
133
        int progname_laenge, spruch_laenge, daten_laenge;
 
134
 
 
135
        if (progname == NULL || progname[0] == 0)
 
136
                progname_laenge = 0;
 
137
        else
 
138
                progname_laenge = strlen(progname) + 1; /* Null mitkopieren */
 
139
 
 
140
        /* Laenge begrenzen */
 
141
        if (progname_laenge > 255)
 
142
                progname_laenge = 255;
 
143
 
 
144
        /* Kameras habens keinen Spruch, da sie nicht toeten koennen */
 
145
        if (spruch == NULL || spruch[0] == 0 || kamera)
 
146
                spruch_laenge = 0;
 
147
        else
 
148
                spruch_laenge = strlen(spruch) + 1; /* Null mitkopieren */
 
149
 
 
150
        /* Speicher fuer den Typ, die Laenge des Programmnamen, den Namen
 
151
           selbst und den Spruch belegen */
 
152
        daten_laenge = 2 + progname_laenge + spruch_laenge;
 
153
        speicher_belegen((void **)&daten, daten_laenge);
 
154
 
 
155
        /* die Nachricht beginnt mit dem Typ und der Laenge des Namen */
 
156
        daten[0] = kamera ? NT_NEUE_KAMERA : NT_NEUER_SPIELER;
 
157
        daten[1] = progname_laenge;
 
158
 
 
159
        /* dann der Programmname */
 
160
        if (progname_laenge)
 
161
                memcpy(daten + 2, progname, progname_laenge);
 
162
 
 
163
        /* und zuletzt der Spruch */
 
164
        if (spruch_laenge)
 
165
                memcpy(daten + 2 + progname_laenge, spruch, spruch_laenge);
 
166
 
 
167
        /* dem Session-Prozess den Verbindungsdeskriptor per Nachricht
 
168
           uebergeben */
 
169
        nachricht_senden(session_deskriptor, verbindung, daten_laenge, daten);
 
170
 
 
171
        /* allen Speicher wieder freigeben */
 
172
        speicher_freigeben((void **)&daten);
 
173
        if (progname != NULL)
 
174
                speicher_freigeben((void **)&progname);
 
175
        if (spruch != NULL)
 
176
                speicher_freigeben((void **)&spruch);
 
177
 
 
178
        /* der Verbindungsdeskriptor wird vom Server nicht mehr
 
179
           benoetigt, aufraeumen; einen evtl. gestarteten
 
180
           Initialisierungsprozess implizit beenden */
 
181
        verbindung_freigeben(verbindung);
 
182
}
 
183
 
 
184
 
 
185
/*
 
186
** server
 
187
**  loest die Initialisierung von neuen Clients aus und kommuniziert
 
188
**  mit dem Session-Prozess
 
189
**
 
190
** Seiteneffekte:
 
191
**  diese Prozedur ist eine Endlosschleife und wird nur durch Fehler
 
192
**  oder Signale per exit verlassen
 
193
*/
 
194
static void server(void)
 
195
{
 
196
        /* Status initialisieren */
 
197
        speicher_belegen((void **)&session_status, 1);
 
198
        session_status[0] = 0;
 
199
 
 
200
        /* Endlosschleife, s.o. */
 
201
        for (;;)
 
202
        {
 
203
                /* auf Nachrichten von den anderen Prozessen und neue
 
204
                   Verbindungen von Clients warten */
 
205
                if (nachricht_oder_verbindung_erwarten(1,
 
206
                        &session_deskriptor) == NULL)
 
207
                /* eine Verbindung steht evtl. bereit */
 
208
                {
 
209
                        void *verbindung; /* Deskriptor fuer die Verbindung zum
 
210
                                             neuen Client */
 
211
                        char *progname;   /* Name des Client-Programms */
 
212
                        char *spruch;     /* Spruch des neuen Spielers */
 
213
                        int kamera;       /* Spieler will nur zusehen */
 
214
                        init_e init_result;
 
215
 
 
216
                        /* versuchen, die Verbindung entgegenzunehmen */
 
217
                        if ((verbindung = verbindung_annehmen()) == NULL)
 
218
                                /* keine Verbindung bekommen oder ein
 
219
                                   Initialisierungsprozess wurde abgespalten, um die
 
220
                                   Verbindung anzunehmen */
 
221
                                continue;
 
222
 
 
223
                        /* die Verbindung wurde angenommen; evtl. ist dies ein
 
224
                           abgespaltener Initialisierungsprozess */
 
225
 
 
226
                        /* dem Client die Initialisierungsdaten senden
 
227
                           und die Verbindung vom Prolog auf das Spiel schalten */
 
228
                        init_result = init_spieler(verbindung, feldbreite,
 
229
                                feldlaenge, spielfeld, session_status,
 
230
                                &progname, &spruch, &kamera);
 
231
                        if (init_result != Init_Success ||
 
232
                                verbindung_auf_spiel(session_deskriptor,
 
233
                                        verbindung))
 
234
                        {
 
235
                                /* Speicher fuer Programmname und Spruch
 
236
                                   bei Fehler wieder freigeben */
 
237
                                if (progname != NULL)
 
238
                                        speicher_freigeben((void **)&progname);
 
239
 
 
240
                                if (spruch != NULL)
 
241
                                        speicher_freigeben((void **)&spruch);
 
242
 
 
243
                                /* bei einem Fehler die Verbindung abbrechen und weiter
 
244
                                   warten; einen evtl. gestarteten Initialisierungsprozess
 
245
                                   implizit beenden */
 
246
                                verbindung_abbrechen(verbindung, init_result !=
 
247
                                        Init_Aborted_By_Client /* fehler? */);
 
248
                                continue;
 
249
                        }
 
250
 
 
251
                        /* Spieler an Session uebergeben; einen evtl.
 
252
                           gestarteten Initialisierungsprozess implizit
 
253
                           beenden */
 
254
                        spieler_an_session(verbindung, progname,
 
255
                                spruch, kamera);
 
256
                }
 
257
                else
 
258
                /* eine Nachricht von einer Session liegt evtl. an */
 
259
                {
 
260
                        void *daten;      /* Datenteil der Nachricht */
 
261
                        int laenge;       /* Laenge des Datenteils */
 
262
                        void *verbindung; /* Verbindungsdeskriptor, auf den die
 
263
                                             Nachricht sich bezieht */
 
264
                        char typ;         /* Typ der Nachricht; siehe server.h */
 
265
 
 
266
                        /* Nachricht (Typ und Deskriptor) entgegennehmen */
 
267
                        if (nachricht_empfangen(session_deskriptor, &verbindung,
 
268
                                &laenge, &daten))
 
269
                                /* keine Nachricht bekommen; weiter warten */
 
270
                                continue;
 
271
 
 
272
                        /* Session-Status erneuern? */
 
273
                        if (laenge > 0 && ((char *)daten)[0] == NT_STATUS)
 
274
                        {
 
275
                                speicher_freigeben((void **)&session_status);
 
276
 
 
277
                                /* Typ entfernen, Null anhaengen */
 
278
                                if (laenge > 1)
 
279
                                        memmove(daten, (char *)daten + 1,
 
280
                                                laenge - 1);
 
281
 
 
282
                                ((char *)daten)[laenge - 1] = 0;
 
283
 
 
284
                                /* und abspeichern */
 
285
                                session_status = daten;
 
286
                                continue;
 
287
                        }
 
288
 
 
289
                        /* Datenteil besteht nicht genau aus dem Typ? */
 
290
                        if (laenge != 1)
 
291
                        {
 
292
                                /* dann Speicher wieder freigeben */
 
293
                                if (laenge)
 
294
                                        speicher_freigeben(&daten);
 
295
 
 
296
                                /* und Nachricht ignorieren */
 
297
                                continue;
 
298
                        }
 
299
 
 
300
                        typ = *(char *)daten; /* Typ der Nachricht */
 
301
 
 
302
                        /* Speicher wieder freigeben */
 
303
                        speicher_freigeben(&daten);
 
304
 
 
305
                        /* wenn der Session-Prozess sich beendet hat, den
 
306
                           Server-Prozess auch beenden */
 
307
                        if (typ == NT_SPIEL_ENDE)
 
308
                                exit(0);
 
309
 
 
310
                        /* alle weiteren Nachrichten ignorieren und einen
 
311
                           evtl. mitgesandten Deskriptor wieder freigeben */
 
312
                        if (verbindung != NULL)
 
313
                                verbindung_freigeben(verbindung);
 
314
                }
 
315
        }
 
316
}
 
317
 
 
318
 
 
319
/*
 
320
** aussenwand_korrigieren
 
321
**  korrigiert eine Aussenwand des Spielfeldes, falls diese unsichtbar,
 
322
**  begehbar oder nicht schusssicher ist
 
323
**
 
324
** Parameter:
 
325
**  wand: Zeiger auf eine Wand im Spielfeld
 
326
**
 
327
** Rueckgabewert:
 
328
**  0, falls nichts veraendert wurde, 1 sonst
 
329
**
 
330
** Seiteneffekte:
 
331
**  *wand wird noetigenfalls korrigiert
 
332
*/
 
333
static int aussenwand_korrigieren(struct wand *wand)
 
334
{
 
335
        int veraendert; /* Flag, ob etwas veraendert wurde */
 
336
 
 
337
        veraendert = 0;
 
338
 
 
339
        /* die Wand muss schusssicher sein */
 
340
        if (!wand->schusssicher)
 
341
                wand->schusssicher = 1,
 
342
                veraendert = 1;
 
343
 
 
344
        /* die Wand muss unbegehbar sein */
 
345
        if (!wand->unbegehbar)
 
346
                wand->unbegehbar = 1,
 
347
                veraendert = 1;
 
348
 
 
349
        /* die Wand muss die Farbe einer Wand haben */
 
350
        if (wand->farbe < 1 || wand->farbe > 7)
 
351
                wand->farbe = 1,
 
352
                veraendert = 1;
 
353
 
 
354
        /* zurueckmelden, ob etwas veraendert wurde */
 
355
        return veraendert;
 
356
}
 
357
 
 
358
 
 
359
/*
 
360
** ladelab
 
361
**  laedt das Labyrinth aus einer Datei
 
362
**
 
363
** Parameter:
 
364
**  dateiname: der Dateiname
 
365
**
 
366
** Seiteneffekte:
 
367
**  spielfeld, feldbreite und feldlaenge werden initialisiert
 
368
*/
 
369
static void ladelab(char *dateiname)
 
370
{
 
371
        FILE *datei;                  /* Deskriptor fuer die Labyrinthdatei */
 
372
        char magic[sizeof MAGIC - 1]; /* Identifikationstext in der Datei */
 
373
        u_char daten[4];              /* Puffer zum Lesen aus der Datei */
 
374
        int x, y, i;                  /* Indizes fuer das Spielfeld */
 
375
        int warnung;                  /* Labyrinth enthaelt
 
376
                                         unzulaessige Daten */
 
377
 
 
378
        /* falls der Dateiname "-" ist, von stdin lesen, sonst Datei oeffnen */
 
379
        if (strcmp(dateiname, "-"))
 
380
        {
 
381
                /* Datei zum Lesen oeffnen */
 
382
                datei = fopen(dateiname, "rb");
 
383
 
 
384
                /* bei Fehler, diesen anzeigen und Programm abbrechen */
 
385
                if (datei == NULL)
 
386
                {
 
387
                        static char *meldung[] = { "iMaze - Initialization Error", "",
 
388
                                "Can't read labyrinth file", NULL, NULL };
 
389
 
 
390
                lese_fehler:
 
391
                        /* Fehlermeldung zusammenstellen und ausgeben */
 
392
                        meldung[3] = dateiname;
 
393
                        uebler_fehler(meldung, NULL);
 
394
                }
 
395
        }
 
396
        else
 
397
                /* stdin benutzen */
 
398
                datei = stdin;
 
399
 
 
400
        /* Identifikationstext aus der Datei lesen */
 
401
        if (fread(magic, 1, sizeof magic, datei) != sizeof magic)
 
402
                /* bei Fehler "Initialization Error" anzeigen */
 
403
                goto lese_fehler;
 
404
 
 
405
        /* Falls der Identifikationstext nicht der erwartete ist,
 
406
           Fehler anzeigen und Programm abbrechen */
 
407
        if (memcmp(MAGIC, magic, sizeof magic))
 
408
        {
 
409
                static char *meldung[] = { "iMaze - Initialization Error", "",
 
410
                        "Invalid labyrinth file format", NULL, NULL };
 
411
 
 
412
        format_fehler:
 
413
                /* Fehlermeldung zusammenstellen und ausgeben */
 
414
                meldung[3] = dateiname;
 
415
                uebler_fehler(meldung, NULL);
 
416
        }
 
417
 
 
418
        /* Feldgroesse aus der Datei lesen */
 
419
        if (fread(daten, 1, 2, datei) != 2)
 
420
                /* bei Fehler "Initialization Error" anzeigen */
 
421
                goto lese_fehler;
 
422
        feldbreite = daten[0];
 
423
        feldlaenge = daten[1];
 
424
 
 
425
        /* Feldgroesse ueberpruefen */
 
426
        if (feldbreite < 1 || feldbreite > MAXFELDBREITE ||
 
427
                feldlaenge < 1 || feldlaenge > MAXFELDBREITE)
 
428
                /* bei ungueltier Groesse "Initialization Error" anzeigen */
 
429
                goto format_fehler;
 
430
 
 
431
        /* Speicher fuer das Spielfeld belegen */
 
432
        speicher_belegen((void **)&spielfeld, feldbreite * sizeof(block *));
 
433
 
 
434
        for (x = 0; x < feldbreite; x++)
 
435
                speicher_belegen((void **)&spielfeld[x],
 
436
                        feldlaenge * sizeof(block));
 
437
 
 
438
        /* bei unzulaessigem Spielfeldinhalt Warnung ausgeben,
 
439
           aber weitermachen */
 
440
        warnung = 0;
 
441
 
 
442
        /* Spielfeld einlesen */
 
443
        for (y = 0; y < feldlaenge; y++)
 
444
                for (x = 0; x < feldbreite; x++)
 
445
                {
 
446
                        /* einen Block (4 Waende) aus der Datei lesen */
 
447
                        if (fread(daten, 1, 4, datei) != 4)
 
448
                                /* bei Fehler "Initialization Error" anzeigen */
 
449
                                goto lese_fehler;
 
450
 
 
451
                        /* alle 4 Waende in Spielfeld kopieren */
 
452
                        for (i = 0; i < 4; i++)
 
453
                        {
 
454
                                struct wand *wand; /* Zeiger in das Spielfeld */
 
455
 
 
456
                                wand = &spielfeld[x][y][i];
 
457
 
 
458
                                /* Farbe und Flags "schusssicher" und "unbegehbar" aus der
 
459
                                   Datei uebernehmen */
 
460
                                wand->farbe = daten[i] & 15;
 
461
                                wand->schusssicher = daten[i] >> 6 & 1;
 
462
                                wand->unbegehbar = daten[i] >> 7 & 1;
 
463
 
 
464
                                /* Daten unzulaessig? */
 
465
                                warnung |=
 
466
                                        wand->unbegehbar && wand->farbe >= 8 ||
 
467
                                        !wand->unbegehbar && wand->farbe >= 1 &&
 
468
                                        wand->farbe <= 7 ||
 
469
                                        wand->schusssicher ^ (wand->farbe != 0) ||
 
470
                                        (daten[i] >> 4 & 3) != 0;
 
471
                        }
 
472
                }
 
473
 
 
474
        /* falls am Rand keine Waende sind, korrigieren */
 
475
        for (x = 0; x < feldbreite; x++)
 
476
        {
 
477
                warnung |= aussenwand_korrigieren(&spielfeld[x][0][NORD]);
 
478
                warnung |= aussenwand_korrigieren(&spielfeld[x][feldlaenge - 1][SUED]);
 
479
        }
 
480
        for (y = 0; y < feldlaenge; y++)
 
481
        {
 
482
                warnung |= aussenwand_korrigieren(&spielfeld[0][y][WEST]);
 
483
                warnung |= aussenwand_korrigieren(&spielfeld[feldbreite - 1][y][OST]);
 
484
        }
 
485
 
 
486
        /* Datei schliessen, wenn es nicht stdin war */
 
487
        if (datei != stdin)
 
488
                fclose(datei);
 
489
 
 
490
        /* evtl. Warnung ausgeben */
 
491
        if (warnung)
 
492
        {
 
493
                fprintf(stderr, "imazesrv: Invalid labyrinth\n");
 
494
                fprintf(stderr, "imazesrv: %s\n", dateiname);
 
495
                fprintf(stderr, "imazesrv:\n");
 
496
                fprintf(stderr, "imazesrv: Who cares?\n");
 
497
        }
 
498
}
 
499
 
 
500
 
 
501
/* bis hier lokaler Teil                       */
 
502
/***********************************************/
 
503
/* ab hier globaler Teil                       */
 
504
 
 
505
 
 
506
/*
 
507
** uebler_fehler
 
508
**  zeigt eine Fehlermeldung an und beendet das Programm
 
509
**
 
510
** Parameter:
 
511
**  meldung: Feld von Strings, die die Zeilen des auszugebenden Textes
 
512
**           beinhalten
 
513
**  knopf: Text der auf einem Bestaetigungs-Knopf stehen sollte;
 
514
**         wird ignoriert
 
515
**
 
516
** Seiteneffekte:
 
517
**  Ende des Programms
 
518
*/
 
519
void uebler_fehler(char **meldung, char *knopf)
 
520
{
 
521
        int i; /* Zaehlvariable fuer Ausgeben der Meldung */
 
522
 
 
523
        /* Ausgabe der Meldung auf standard-error */
 
524
        for (i = 0; meldung[i] != NULL; i++)
 
525
                fprintf(stderr, "imazesrv: %s\n", meldung[i]);
 
526
 
 
527
        /* Programm abbrechen */
 
528
        exit(1);
 
529
}
 
530
 
 
531
 
 
532
/*
 
533
** main
 
534
**  die Hauptroutine, der Server und eine Session werden gestartet
 
535
**
 
536
** Parameter:
 
537
**  argc: Anzahl der Argumente inklusive Programmname
 
538
**  argv: Argumentliste
 
539
*/
 
540
int main(int argc, char **argv)
 
541
{
 
542
        /* diese Signale immer ignorieren */
 
543
        signal(SIGHUP, SIG_IGN);
 
544
        signal(SIGALRM, SIG_IGN);
 
545
        signal(SIGPIPE, SIG_IGN);
 
546
 
 
547
        /* fuer diese Signale gibt es fuer einen Prozess einen Handler,
 
548
           erstmal ignorieren */
 
549
        signal(SIGINT, SIG_IGN);
 
550
        signal(SIGTERM, SIG_IGN);
 
551
 
 
552
        process_args(&argc, argv);
 
553
 
 
554
        /* Labyrinth laden */
 
555
        ladelab(labfile_name);
 
556
 
 
557
        /* Netzwerkroutinen initialisieren */
 
558
        netzwerk_init();
 
559
 
 
560
        /* eine Session starten */
 
561
        if ((session_deskriptor = session_starten()) != NULL)
 
562
        {
 
563
                /* dies ist der Server-Prozess */
 
564
 
 
565
                /* fuer diese Signale einen Handler installieren, der ein
 
566
                   sauberes Programmende erlaubt */
 
567
                handle_signal(SIGINT, ende_handler);
 
568
                handle_signal(SIGTERM, ende_handler);
 
569
 
 
570
                server();
 
571
        }
 
572
        else
 
573
                /* dies ist der Session-Prozess */
 
574
                session(zeittakt);
 
575
 
 
576
        return 0;
 
577
}