Mercurial > ~darius > hgwebdir.cgi > paradise_server
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); +}