diff src/shmem.c @ 6:8c6d5731234d

First entry of Paradise Server 2.9 patch 10 Beta
author darius
date Sat, 06 Dec 1997 04:37:04 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/shmem.c	Sat Dec 06 04:37:04 1997 +0000
@@ -0,0 +1,286 @@
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, or any derivative works thereof, for any NON-COMMERCIAL
+purpose and without fee is hereby granted, provided that this copyright
+notice appear in all copies.  No representations are made about the
+suitability of this software for any purpose.  This software is provided
+"as is" without express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+--------------------------------------------------------------------------*/
+
+#include "config.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <errno.h>
+#include <signal.h>
+
+#include "shmem.h"
+#include "path.h"
+#include "data.h"
+
+/*---------------------------SHARED MEMORY STRUCTURE----------------------*/
+
+#include "shmemP.h"
+
+/*-------------------------------------------------------------------------*/
+
+struct player *players;
+struct torp *torps;
+struct missile *missiles;
+struct thingy *thingies;
+struct plasmatorp *plasmatorps;
+struct status *status;
+struct status2 *status2;
+struct planet *planets;
+struct t_unit *terrain_grid;
+struct phaser *phasers;
+int *stars;
+struct mctl *mctl;
+struct message *messages;
+struct team *teams;
+
+struct ship *shipvals;
+struct configuration *configvals;
+int *shipsallowed;		/* points inside configvals */
+int *weaponsallowed;		/* ditto */
+int *sun_effect;
+int *ast_effect;
+int *neb_effect;
+int *wh_effect;
+int *num_nebula;
+int *nebula_density;
+int *nebula_subclouds;
+int *num_asteroid;
+float *asteroid_thickness;
+int *asteroid_density;
+int *asteroid_radius;
+float *asteroid_thick_variance;
+int *asteroid_dens_variance;
+int *asteroid_rad_variance;
+int *improved_tracking;
+int *tstart;
+int *newgalaxy;
+int *nontteamlock;
+char *cluephrase_storage;
+
+static int PKEY = 128;
+
+/*------------------------------STARTDAEMON---------------------------------*/
+/*
+ * This function starts the daemon.  It get the path to where the daemon
+ * resides, then tries to start it up.
+ */
+
+
+#ifndef SYSV			/* HP/UX hates this */
+extern int fprintf();
+#endif
+extern pid_t fork();
+extern int execl();
+extern void perror();
+extern int shmget();
+#ifndef IRIX
+extern int shmctl();
+#endif
+extern unsigned int sleep();
+extern uid_t geteuid();
+
+void
+startdaemon(leagueflag, restart)
+  int leagueflag, restart;
+{
+  int i;			/* temp var */
+  char *hell;			/* to hold path to daemon */
+
+  if (restart)
+  {
+    fprintf(stderr, "RE-");
+    kill(status->nukegame, SIGKILL);	/* daemon is killed without giving it
+					 * a chance to blast the shmem */
+    sleep(2);
+  }
+  fprintf(stderr, "Starting daemon...\n");	/* record that deaemon is */
+  i = fork();			/* starting */
+  if (i == 0)
+  {				/* if successful */
+    char *nargv[10];
+    int argc = 0;
+    hell = build_path(DAEMON);
+    nargv[argc++] = "daemon";
+    if (leagueflag)
+      nargv[argc++] = "-l";
+    if (restart)
+      nargv[argc++] = "-a";
+    nargv[argc] = 0;
+    execv(hell, nargv);
+
+    perror(hell);		/* did it work */
+    fprintf(stderr, "Couldn't start daemon!!!\n");
+    _exit(1);			/* let's get out of here */
+  }
+}
+
+
+
+static int shmid = -1;		/* ID number of shared mem */
+
+
+/*--------------------------------OPENMEM----------------------------------*/
+/*
+ * if code is 0, openmem will exit(1) upon finding the memory gone. if code
+ * is 1, openmem will fork a netrek daemon and retry. if code is 2, openmem
+ * will blast any already existing shared memory.
+ */
+
+void
+openmem(code, leagueflag)
+  int code;
+  int leagueflag;		/* only used if code==1 */
+{
+  extern int errno;		/* to get error number */
+  key_t shmemKey = PKEY;	/* shared memory's key */
+  struct memory *sharedMemory;	/* to point to shared memory */
+  char *k;
+
+  k = getenv("TREKSHMKEY");	/* grab shared mem id environment variable */
+  if (k)
+  {				/* if it's set... */
+    int i;
+    if (sscanf(k, "%d", &i) > 0 && i > 0)	/* ...grab its value... */
+      shmemKey = i;		/* ...and use it */
+  }
+
+  errno = 0;			/* clear error number */
+  shmid = shmget(shmemKey, 0, 0);	/* get id of shared mem */
+  if (code == 2)
+  {
+    if (shmid >= 0)
+    {
+      /* If we're in daemon mode and we opened the memory */
+      /* "There can be only one". */
+      fprintf(stderr, "Killing existing segment\n");
+      shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
+      /* create a new one */
+    }
+    shmid = shmget(shmemKey, sizeof(struct memory), IPC_CREAT | 0666);
+  }
+  if (shmid < 0)
+  {				/* if shared mem does not exist */
+    switch (code)
+    {
+     case 0:
+      if (errno != ENOENT)
+      {				/* catastrophic, sell all your stock */
+	perror("shmget");	/* and leave the country type of */
+	exit(1);		/* error--suicide */
+      }
+      fprintf(stderr, "Daemon not running (err:%d)\n", errno);
+      exit(1);
+     case 1:
+      if (errno != ENOENT)
+      {				/* catastrophic, sell all your stock */
+	perror("shmget");	/* and leave the country type of */
+	exit(1);		/* error--suicide */
+      }
+      startdaemon(leagueflag, 0);	/* try to start the daemon */
+      sleep(2);			/* wait for a sec for deamon to start */
+      shmid = shmget(shmemKey, 0, 0);	/* try again to get shared mem */
+      if (shmid < 0)
+      {				/* failure again then get out of here */
+	fprintf(stderr, "Daemon not running (err:%d)\n", errno);
+	exit(1);
+      }
+      break;
+     case 2:
+      perror("daemon: can't open shared memory");
+      exit(1);
+    }
+  }
+  if (code == 2)
+  {
+    struct shmid_ds smbuf;
+
+    shmctl(shmid, IPC_STAT, &smbuf);	/* Hose Ed's robots */
+    smbuf.shm_perm.uid = geteuid();
+    smbuf.shm_perm.mode = 0666;
+    shmctl(shmid, IPC_SET, &smbuf);
+  }
+  sharedMemory = (struct memory *) shmat(shmid, (char *) 0, 0);
+  if (sharedMemory == (struct memory *) - 1)
+  {
+    perror("shared memory");
+    exit(1);
+  }
+  if (code == 2)
+  {
+    /* set the magic number */
+    sharedMemory->shmem_size = sizeof(struct memory);
+  }
+  else
+  {
+    if (sharedMemory->shmem_size != sizeof(struct memory))
+    {
+      fprintf(stderr, "shared memory segment magic number mismatch!\
+ (%d != %ld)\n  aborting to prevent corruption of game data\n",
+	      sharedMemory->shmem_size, (long) sizeof(struct memory));
+      exit(1);
+    }
+  }
+  players = sharedMemory->players;	/* set pointer to fields */
+  torps = sharedMemory->torps;	/* in shared memory structure */
+  missiles = sharedMemory->missiles;	/* for easy access */
+  thingies = sharedMemory->thingies;
+  plasmatorps = sharedMemory->plasmatorps;
+  status = &sharedMemory->status;
+  status2 = &sharedMemory->status2;
+  planets = sharedMemory->planets;
+  terrain_grid = sharedMemory->terrain_grid;
+  phasers = sharedMemory->phasers;
+  stars = sharedMemory->stars;
+  mctl = &sharedMemory->mctl;
+  messages = sharedMemory->messages;
+  teams = sharedMemory->teams;
+  shipvals = sharedMemory->shipvals;
+  configvals = &sharedMemory->configvals;
+  galaxyValid = &sharedMemory->galaxyValid;
+  /* configvals->gwidth = 200000; *//* pick up from galaxy generator later */
+  /* configvals->numplanets = 60; *//* this too */
+
+  shipsallowed = configvals->shipsallowed;
+  weaponsallowed = configvals->weaponsallowed;
+  sun_effect = configvals->sun_effect;
+  ast_effect = configvals->ast_effect;
+  neb_effect = configvals->neb_effect;
+  wh_effect = configvals->wh_effect;
+  num_nebula = &(configvals->num_nebula);
+  nebula_density = &(configvals->nebula_density);
+  nebula_subclouds = &(configvals->nebula_subclouds);
+  num_asteroid = &(configvals->num_asteroid);
+  asteroid_thickness = &(configvals->asteroid_thickness);
+  asteroid_density = &(configvals->asteroid_density);
+  asteroid_radius = &(configvals->asteroid_radius);
+  asteroid_thick_variance = &(configvals->asteroid_thick_variance);
+  asteroid_dens_variance = &(configvals->asteroid_dens_variance);
+  asteroid_rad_variance = &(configvals->asteroid_rad_variance);
+  improved_tracking = configvals->improved_tracking;
+
+  cluephrase_storage = sharedMemory->cluephrase_storage;
+
+  stars[1] = -1;
+}
+
+void
+blast_shmem()
+{
+  shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0);
+}