/*
 * gchecker.c - Order verification for Galaxy v3.1
 * Copyright (C) 1993 by Robert Stone
 * Major portions of this code are Copyright (C) 1992 by Russel Wallace
 * 
 * Requires gcc C compiler.
 *
 * Typo corrected by Robert Novak (rnovak@nyx.cs.du.edu) ('RECIEVED')
 */

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<math.h>
#include	<fcntl.h>
#include	<dirent.h>
#include	<ctype.h>
#include	<assert.h>

#define MAX_PATH	1024
#define	NAMESIZE	21
#define	MAXPOP		1000.0
#define	POPPERCOL	8
#define	POPINC		.08
#define	INDPERSHIP	10
#define	INDPERCAP	5
#define	BATTLEMAGIC	3.107232506
#define	DRIVEMAGIC	20.0
#define	FIELDSPACE	2
#define	COLUMNSPACE	4
#define	PRINTWIDTH	80
#define	ADDRSIZE	61
#define	ORDERGAP	3
#define	MAPWIDTH	PRINTWIDTH
#define	MAPHEIGHT	40

#define	addlist2(l,p)	(*l = p, l = &p->next)
#define	identify(a,b)	nametop(a,b)

enum {
   PR_CAP,
   PR_MAT,
   PR_SHIP,
   PR_DRIVE,
   PR_WEAPONS,
   PR_SHIELDS,
   PR_CARGO,
};

enum {
   CG_CAP,
   CG_MAT,
   CG_COL,
   CG_EMPTY,
   MAXCARGO
};

typedef struct list {
   struct list    *next;
}               list;

typedef struct strlist {
   struct strlist *next;
   char           *s[1];
}               strlist;

struct player;
typedef struct player player;

typedef struct fleetname
{
        struct fleetname *next;
        char name[NAMESIZE];
        float fleetspeed;
} fleetname;

typedef struct shiptype {
   struct shiptype *next;
   char            name[NAMESIZE];
   double          drive;
   int             attacks;
   double          weapons;
   double          shields;
   double          cargo;
   int             flag;
}               shiptype;

typedef struct planet {
   struct planet  *next;
   char            name[NAMESIZE];
   player         *owner;
   double          x, y;
   double          size;
   double          resources;
   double          pop;
   double          ind;
   int             producing;
   shiptype       *producingshiptype;
   double          cap;
   double          mat;
   double          col;
   double          inprogress;
   double          spent;
   struct planet  *routes[MAXCARGO];
}               planet;

typedef struct Aplanet {
   struct Aplanet *next;
   planet         *p;
   char            ownername[NAMESIZE];
   char            producingshiptypename[NAMESIZE];
   char            routenames[MAXCARGO][NAMESIZE];
}               Aplanet;

typedef struct group {
   struct group   *next;
   shiptype       *type;
   double          drive;
   double          weapons;
   double          shields;
   double          cargo;
   int             loadtype;
   double          load;
   planet         *from;
   planet         *where;
   double          dist;
   int             ships;
   int             left;
   fleetname      *thefleet;
   struct group   *alias;
}               group;

typedef struct alliance {
   struct alliance *next;
   player         *who;
}               alliance;

typedef struct Aalliance {
   struct Aalliance *next;
   alliance       *a;
   char            whoname[NAMESIZE];
}               Aalliance;

typedef struct participant {
   struct participant *next;
   player         *who;
   group          *groups;
}               participant;

typedef struct battle {
   struct battle  *next;
   planet         *where;
   participant    *participants;
}               battle;

typedef struct bombing {
   struct bombing *next;
   char            name[NAMESIZE];
   player         *owner;
   double          pop;
   double          ind;
   int             producing;
   shiptype       *producingshiptype;
   double          cap;
   double          mat;
   double          col;
   player         *who;
   alliance       *viewers;
}               bombing;

struct player {
   player         *next;
   char            name[NAMESIZE];
   char            addr[ADDRSIZE];
   char	           pswd[NAMESIZE];
   double          drive;
   double          weapons;
   double          shields;
   double          cargo;
   shiptype       *shiptypes;
   fleetname      *fleetnames;
   alliance       *allies;
   group          *groups;
   double          mx, my, msize;
   int             underscores;
   int             twocol;
   int             namecase;
   int             lastorders;
   int             fleettables;
   int             autounload;
   int             prodtable;
   int             sortgroups;
   strlist        *orders;
   strlist        *messages;
   strlist        *mistakes;
};

struct dirent  *dp;
DIR            *dfd;
player         *players;
planet         *planets;
battle         *battles;
bombing        *bombings;
strlist        *messages;
double          galaxysize;
int             turn;
unsigned long   randno;
char            map[MAPWIDTH][MAPHEIGHT];
char            buf[256];
char            gamename[256];
FILE           *f = 0;
double          x1, x2, tmpy1, y2;
int             underscores;
int             twocol;
int             reportfileno;
int		nerrors = 0;

char           *productname[] =
{
   "CAP",
   "MAT",
   0,
   "Drive",
   "Weapons",
   "Shields",
   "Cargo",
};


void print_er_banner(char *name);
void print_er_footer(void);

int 
memicmp(char c1[256], char c2[256], int val)
{
   int             char1, char2, i;
   for (i = 0; i < val; i++) {
      char1 = tolower(c1[i]);
      char2 = tolower(c2[i]);
      if (char1 != char2)
	 return 1;
   }
   return 0;
}

int 
strcmpl(char c1[100], char c2[100])
{
   int             char1, char2, i;
   for (i = 0; i < 100; i++) {
      char1 = tolower(c1[i]);
      char2 = tolower(c2[i]);
      if (char1 != char2)
	 return 1;
      if ((char1 == '\0') || (char2 == '\0')) {
	 return 0;
      }
   }
}

char           *
findnext()
{
   if ((dp = readdir(dfd)) == NULL)
      return NULL;
   if (strcmp(dp->d_name, ".") == 0)
      if ((dp = readdir(dfd)) == NULL)
	 return NULL;
   if (strcmp(dp->d_name, "..") == 0)
      if ((dp = readdir(dfd)) == NULL)
	 return NULL;
   return dp->d_name;
}

char           *
findfirst(char *dir)
{
   closedir(dfd);
   if ((dfd = opendir(dir)) == NULL)
      return NULL;
   return findnext();
}

void           *
numtop(void *base, char *s)
{
   list           *p;
   int             i, n;

   i = 0;
   n = atoi(s);
   for (p = base; p; p = p->next) {
      i++;
      if (i == n)
	 return p;
   }
   return 0;
}

void 
removelist(void *_base, void *_p)
{
   list          **base;
   list           *p;
   list           *q;

   base = _base;
   p = _p;
   if (*base == p)
      *base = p->next;
   else {
      for (q = *base; q->next != p; q = q->next)
	 assert(q);
      q->next = p->next;
   }
   free(p);
}

_atoi(char *s)
{
   if (!isdigit(s[0]))
      return 0;
   return atoi(s);
}

rand(void)
{
   randno = randno * 1103515245 + 12345;
   return (randno / 0x10000) & 0x7fff;
}

FILE           *
Fopen(char *filename, char *mode)
{
   FILE           *f;

   f = fopen(filename, mode);
   if (f == 0) {
      printf("Can't open file %s in mode %s\n", filename, mode);
      exit(1);
   }
   return f;
}

void           *
alloc(int n)
{
   void           *p;

   p = malloc(n);
   if (p == 0) {
      printf("Out of memory\n");
      exit(1);
   }
   return p;
}

char           *
strdup(const char *s)
{
   return strcpy(alloc(strlen(s) + 1), s);
}

void 
addlist(void *_base, void *_p)
{
   list          **base;
   list           *p, *q;

   base = _base;
   p = _p;
   p->next = 0;
   if (*base) {
      for (q = *base; q->next; q = q->next);
      q->next = p;
   } else
      *base = p;
}

void 
freelist(void *base)
{
   list           *p, *p2;

   p = base;
   while (p) {
      p2 = p->next;
      free(p);
      p = p2;
   }
}

void 
freestrlist(strlist * s)
{
   strlist        *s2;

   while (s) {
      s2 = s->next;
      free(s->s[0]);
      free(s);
      s = s2;
   }
}

void           *
nametop(void *head, char *s)
{
   list           *p;

   if (!s[0])
      return 0;
   for (p = head; p; p = p->next)
      if (!strcmpl((char *) (p + 1), s))
	 return p;
   return 0;
}

void 
getbuf(void)
{
   int             i;
   char            c;

   i = 0;
   for (;;) {
      c = fgetc(f);
      if (c == (char)EOF) {
	 buf[0] = (char)EOF;
	 return;
      }
      if (c == '\n') {
	 buf[i] = 0;
	 return;
      }
      if (i == sizeof buf - 1) {
	 buf[i] = 0;
	 while (c != (char)EOF && c != '\n')
	    c = fgetc(f);
	 if (c == (char)EOF)
	    buf[0] = (char)EOF;
	 return;
      }
      buf[i++] = c;
   }
}

double 
frand(double x)
{
   return fmod((rand() % 100) * .01 + rand() % 10000, x);
}

double 
frand2(void)
{
   return (rand() % 20000 - 10000) * .0001;
}

double 
weaponmass(shiptype * t)
{
   return (t->attacks ? t->weapons : 0) +
   ((t->attacks > 1) ? ((t->attacks - 1) * 0.5 * t->weapons) : 0);
}

double 
typemass(shiptype * t)
{
   return t->drive +
   weaponmass(t) +
   t->shields +
   t->cargo;
}

double 
shipmass(group * g)
{
   double          l;

   l = g->load;
   if (g->cargo)
      l /= g->cargo;
   return typemass(g->type) + l;
}

double 
dist(planet * p1, planet * p2)
{
   double          dx, dy;

   dx = p1->x - p2->x;
   dy = p1->y - p2->y;
   return sqrt(dx * dx + dy * dy);
}

void 
send(group * g, planet * p)
{
   g->from = g->where;
   g->where = p;
   g->dist = dist(p, g->from);
}

void 
setproduction(planet * p, int t)
{
   p->inprogress = 0;
   p->producing = t;
   p->producingshiptype = 0;
}

char            outbuf[256];
int             outi;

void 
ftrunc3(void)
{
   int             i;

   i = strlen(buf);
   while (i && buf[i - 1] == '0')
      buf[--i] = 0;
   if (i && buf[i - 1] == '.')
      buf[i - 1] = 0;
}

char           *
getstr(char *s)
{
   static char    *s1;
   static char     buf[256];
   int             i;

   if (s)
      s1 = s;
   while (isspace(*s1))
      s1++;
   i = 0;
   if (*s1 == '"') {
      s1++;
      while (*s1 && *s1 != '"') {
	 buf[i] = *s1;
	 if (*s1 == '_' || *s1 == ',')
	    buf[i] = ' ';
	 i++;
	 s1++;
      }
      s1++;
   } else if (*s1 != ';')
      while (*s1 && !isspace(*s1)) {
	 buf[i] = *s1;
	 if (*s1 == '_' || *s1 == ',')
	    buf[i] = ' ';
	 i++;
	 s1++;
      }
   while (i && isspace(buf[i - 1]))
      i--;
   buf[i] = 0;
   i = 0;
   while (isspace(buf[i]))
      i++;
   return buf + i;
}

int             indent;
int             comma;

void 
docomma(void)
{
   if (comma)
      fputc(',', f);
   comma = 1;
}

void 
wi(int n)
{
   docomma();
   if (n)
      fprintf(f, "%d", n);
}

void 
wf(double n)
{
   docomma();
   sprintf(buf, "%lf", n);
   ftrunc3();
   if (strcmp(buf, "0"))
      fprintf(f, buf);
}

void 
ws(char *s)
{
   int             i;

   docomma();
   for (i = 0; s[i]; i++)
      if (s[i] == ' ')
	 s[i] = '_';
   fprintf(f, "%s", s);
}

void 
nl(void)
{
   int             i;

   fputc('\n', f);
   for (i = 0; i != indent; i++)
      fputc(' ', f);
   comma = 0;
}

void 
cb(void)
{
   indent--;
   nl();
   ws("@");
}


void 
nstrcpy(char *to, char *from, int n)
{
   n--;
   do
      if ((*to++ = *from++) == 0)
	 return;
   while (--n);
   *to = 0;
}


int             lastc;

rc(void)
{
   lastc = fgetc(f);
   assert(lastc != (char)EOF);
   return lastc;
}

void 
rs(char *s)
{
   if (lastc == ',') {
      rc();
      if (isspace(lastc)) {
	 *s = 0;
	 return;
      }
   }
   while (isspace(lastc))
      rc();
   while (!isspace(lastc) && lastc != ',') {
      if (lastc == '_')
	 lastc = ' ';
      *s++ = lastc;
      rc();
   }
   *s = 0;
}

ri(void)
{
   rs(buf);
   return atoi(buf);
}

double 
rf(void)
{
   rs(buf);
   return atof(buf);
}

strlist        *
makestrlist(char *ns)
{
   strlist        *s;

   s = alloc(sizeof(strlist));
   s->s[0] = strdup(ns);
   return s;
}

void 
rtext(strlist ** sp)
{
   int             i;
   strlist        *s;

   while (lastc != '\n')
      rc();
   for (;;) {
      getbuf();
      for (i = 0; isspace(buf[i]); i++);
      if (buf[i] == '@')
	 break;
      s = makestrlist(buf);
      addlist2(sp, s);
   }
   *sp = 0;
}

int
loadgame(char *name)
{
   char           *F;
   int             maxno, i;
   planet         *p, **pp;
   player         *P, **Pp;
   alliance       *a, **ap;
   group          *g, **gp;
   shiptype       *t, **tp;
   fleetname      *fl,**fp;
   battle         *b, **bp;
   bombing        *B, **Bp;
   participant    *r, **rp;
   Aplanet        *Ap, *Aplanets, **App;
   Aalliance      *Aa, *Aalliances, **Aap;

   sprintf(buf, "data/%s", name);
   F = findfirst(buf);
   if (!F) {
      fprintf(stderr,"No turn files for game %s\n", name);
      exit(1); /* 1 = no turn files */
   }
   maxno = 0;
   do {
      i = atoi(F);
      if (i > maxno)
	 maxno = i;
      F = findnext();
   }
   while (F);

   sprintf(buf, "data/%s/%d", name, maxno);
   f = Fopen(buf, "r");
   fprintf(stderr,"Loading game %s turn %d...\n", name, maxno);
   lastc = ' ';

   turn = ri();
   if (turn != maxno)
      fprintf(stderr,"Warning, file %d is actually for turn %d\n", maxno, turn);
   galaxysize = rf();

   rtext(&messages);

   pp = &planets;
   App = &Aplanets;
   Aplanets = 0;
   for (;;) {
      rs(buf);
      if (buf[0] == '@')
	 break;
      p = alloc(sizeof(planet));
      Ap = alloc(sizeof(Aplanet));
      Ap->p = p;
      strcpy(p->name, buf);
      rs(Ap->ownername);
      p->x = rf();
      p->y = rf();
      p->size = rf();
      p->resources = rf();
      p->pop = rf();
      p->ind = rf();
      p->producing = ri();
      rs(Ap->producingshiptypename);
      p->cap = rf();
      p->mat = rf();
      p->col = rf();
      p->inprogress = rf();
      p->spent = 0;
      for (i = 0; i != MAXCARGO; i++)
	 rs(Ap->routenames[i]);
      addlist2(pp, p);
      addlist2(App, Ap);
   }
   *pp = 0;
   *App = 0;

   Pp = &players;
   Aap = &Aalliances;
   Aalliances = 0;
   for (;;) {
      rs(buf);
      if (buf[0] == '@')
	 break;
      P = alloc(sizeof(player));
      strcpy(P->name, buf);
      rs(P->addr);
      rs(P->pswd);
      P->drive = rf();
      P->weapons = rf();
      P->shields = rf();
      P->cargo = rf();
      P->mx = rf();
      P->my = rf();
      P->msize = rf();
      P->prodtable = ri();
      P->autounload = ri();
      P->fleettables = ri();
      P->sortgroups = ri();
      P->underscores = ri();
      P->twocol = ri();
      P->namecase = ri();
      P->lastorders = ri();
      P->orders = 0;

      tp = &P->shiptypes;
      for (;;) {
	 rs(buf);
	 if (buf[0] == '@')
	    break;
	 t = alloc(sizeof(shiptype));
	 strcpy(t->name, buf);
	 t->drive = rf();
	 t->attacks = ri();
	 t->weapons = rf();
	 t->shields = rf();
	 t->cargo = rf();
	 addlist2(tp, t);
      }
      *tp = 0;

      fp = &P->fleetnames;
      for (;;) {
         rs (buf);
         if (buf[0] == '@')
            break;
         fl = alloc (sizeof (fleetname));
         strcpy (fl->name, buf);
         fl->fleetspeed = 1000.0;
         addlist2 (fp, fl);
      }
      *fp = 0;

      ap = &P->allies;
      for (;;) {
	 rs(buf);
	 if (buf[0] == '@')
	    break;
	 a = alloc(sizeof(alliance));
	 Aa = alloc(sizeof(Aalliance));
	 Aa->a = a;
	 strcpy(Aa->whoname, buf);
	 addlist2(ap, a);
	 addlist2(Aap, Aa);
      }
      *ap = 0;

      gp = &P->groups;
      for (;;) {
	 rs(buf);
	 if (buf[0] == '@')
	    break;
	 g = alloc(sizeof(group));
	 g->type = nametop(P->shiptypes, buf);
	 assert(g->type);
	 g->drive = rf();
	 g->weapons = rf();
	 g->shields = rf();
	 g->cargo = rf();
	 g->loadtype = ri();
	 g->load = rf();
	 rs(buf);
	 g->from = nametop(planets, buf);
	 assert(g->from);
	 rs(buf);
	 g->where = nametop(planets, buf);
	 assert(g->where);
	 g->dist = rf();
	 g->ships = ri();

         rs(buf);
         if (buf[0]) {
            fl = identify (P->fleetnames, buf);
            g->thefleet = fl;
         }
         else
            g->thefleet = 0;

	 addlist2(gp, g);
      }
      *gp = 0;

      rtext(&P->messages);

      rtext(&P->mistakes);

      addlist2(Pp, P);
   }
   *Pp = 0;
   *Aap = 0;

   bp = &battles;
   for (;;) {
      rs(buf);
      if (buf[0] == '@')
	 break;
      b = alloc(sizeof(battle));
      b->where = nametop(planets, buf);
      assert(b->where);

      rp = &b->participants;
      for (;;) {
	 rs(buf);
	 if (buf[0] == '@')
	    break;
	 r = alloc(sizeof(participant));
	 r->who = nametop(players, buf);
	 assert(r->who);

	 gp = &r->groups;
	 for (;;) {
	    rs(buf);
	    if (buf[0] == '@')
	       break;
	    g = alloc(sizeof(group));
	    g->type = nametop(r->who->shiptypes, buf);
	    assert(g->type);
	    g->drive = rf();
	    g->weapons = rf();
	    g->shields = rf();
	    g->cargo = rf();
	    g->loadtype = ri();
	    g->load = rf();
	    g->ships = ri();
	    g->left = ri();
	    addlist2(gp, g);
	 }
	 *gp = 0;

	 addlist2(rp, r);
      }
      *rp = 0;

      addlist2(bp, b);
   }
   *bp = 0;

   Bp = &bombings;
   for (;;) {
      rs(buf);
      if (buf[0] == '@')
	 break;
      B = alloc(sizeof(bombing));
      B->who = nametop(players, buf);
      assert(B->who);
      rs(B->name);
      rs(buf);
      B->owner = nametop(players, buf);
      assert(B->owner);
      B->pop = rf();
      B->ind = rf();
      B->producing = ri();
      rs(buf);
      B->producingshiptype = nametop(B->owner->shiptypes, buf);
      B->cap = rf();
      B->mat = rf();
      B->col = rf();

      ap = &B->viewers;
      for (;;) {
	 rs(buf);
	 if (buf[0] == '@')
	    break;
	 a = alloc(sizeof(alliance));
	 a->who = nametop(players, buf);
	 assert(a->who);
	 addlist2(ap, a);
      }
      *ap = 0;

      addlist2(Bp, B);
   }
   *Bp = 0;

   fclose(f);

   for (Ap = Aplanets; Ap; Ap = Ap->next) {
      p = Ap->p;
      p->owner = nametop(players, Ap->ownername);
      p->producingshiptype = 0;
      if (p->owner)
	 p->producingshiptype = nametop(p->owner->shiptypes, Ap->producingshiptypename);
      assert(p->producing != PR_SHIP || p->producingshiptype);
      for (i = 0; i != MAXCARGO; i++)
	 p->routes[i] = nametop(planets, Ap->routenames[i]);
   }
   freelist(Aplanets);

   for (Aa = Aalliances; Aa; Aa = Aa->next) {
      Aa->a->who = nametop(players, Aa->whoname);
      assert(Aa->a->who);
   }
   freelist(Aalliances);

   return 0;
}


void 
convertcap(planet * p)
{
   double          indinc;

   indinc = p->pop - p->ind;
   if (indinc > p->cap)
      indinc = p->cap;
   p->cap -= indinc;
   p->ind += indinc;
}

void 
unloadcap(planet * p, double x)
{
   p->cap += x;
   convertcap(p);
}

void 
unloadcol(planet * p, double x, player * P)
{
   double          y;

   x *= POPPERCOL;
   y = p->size - p->pop;
   if (y > x)
      y = x;
   p->pop += y;
   x -= y;
   p->col += x / POPPERCOL;
   if (!p->owner)
      p->owner = P;
   convertcap(p);
}

void 
unloadgroup(group * g, player * P)
{
   double          x;
   planet         *p;

   x = g->load * g->ships;
   p = g->where;
   switch (g->loadtype) {
   case CG_CAP:
      unloadcap(p, x);
      break;
   case CG_MAT:
      p->mat += x;
      break;
   case CG_COL:
      unloadcol(p, x, P);
      break;
   }
   g->load = 0;
   g->loadtype = CG_EMPTY;
}


double 
calcdefense(group * target)
{
   return target->type->shields * target->shields * BATTLEMAGIC /
   pow(shipmass(target), .333333333333333);
}

cankill(group * attack, group * target)
{
   double          defense, ratio;

   if (!attack->type->attacks)
      return 0;
   defense = calcdefense(target);
   if (!defense)
      return 1;
   ratio = attack->weapons * attack->type->weapons / defense;
   return ratio > .251;
}

kill(group * attack, group * target)
{
   double          defense, ratio;

   if (!attack->type->attacks)
      return 0;
   defense = calcdefense(target);
   if (!defense)
      return 1;
   ratio = attack->weapons * attack->type->weapons / defense;
   return ratio > pow(4.0, frand2());
}

double
cargospace(group * g)
{
   double          size;

   size = g->type->cargo;
   return g->cargo * size * (1 + size / 10);
}


double 
ftrunc2(double x)
{
   char            buf[32];

   sprintf(buf, "%0.2lf", x);
   return atof(buf);
}

void 
cktech(group * g)
{
   shiptype       *t;

   t = g->type;
   g->drive = ftrunc2(g->drive);
   g->weapons = ftrunc2(g->weapons);
   g->shields = ftrunc2(g->shields);
   g->cargo = ftrunc2(g->cargo);
   if (!t->drive)
      g->drive = 0;
   if (!t->attacks)
      g->weapons = 0;
   if (!t->shields)
      g->shields = 0;
   if (!t->cargo)
      g->cargo = 0;
}


void 
mistake(char *comment)
{
	++nerrors;
	printf("*** Problem Sir! (%s.)\n",comment);
}

void 
ckcase(char *s)
{
   int             i;

   i = 0;
   while (s[i]) {
      s[i] = toupper(s[i]);
      do {
	 i++;
	 if (!s[i])
	    return;
      }
      while (!isspace(s[i]));
      do
	 i++;
      while (isspace(s[i]));
   }
}

nametocargotype(char *s)
{
   int             i;
   static char    *cargonames[] =
   {
      "cap",
      "mat",
      "col",
      "emp",
   };
   for (i = 0; i != MAXCARGO; i++)
      if (!strcmpl(cargonames[i], s))
	 return i;
   return -1;
}

group          *
findgroup(player * P, char *s)
{
   group          *g;

   if (!strcmpl(s, "max")) {
      if (!P->groups)
	 return 0;
      for (g = P->groups; g->next; g = g->next);
      return g;
   }
   return numtop(P->groups, s);
}

void 
processturns(char *ordersfilename)
{
   int             i, j, k;
   double          x, y, z;
   char           *ns;
   char		  tns[128];
   strlist        *s;
   strlist       **sp;
   player         *P, *P2, *P3;
   group          *g, *g2;
   planet         *p, *p2;
   shiptype       *t;
   fleetname	  *fl;
   fleetname	  *fl2;
   double          dist;
   double          dist2;
   battle         *b;
   participant    *r;
   alliance       *a, *plist;
   char           *F;
   int		   naming_flag = 0;


/*   nextgame();  */

      if(ordersfilename != NULL)  {
	 if(!(f = Fopen(ordersfilename, "r"))) {
	    fprintf(stderr,"No orders file could be found.\n");
	    abort();
	 }
         fprintf(stderr,"Reading orders from file '%s'...\n",
		 ordersfilename);
      } else {
	 f = stdin;
	 fprintf(stderr,"Reading stdin for orders...\n");
      }

      for (;;) {
	 getbuf();
	 if (buf[0] == (char)EOF) {
	    fclose(f);


	    turn++;

	    /* Do all orders except renaming */

	    for (P = players; P; P = P->next) {
	       for (s = P->orders; s; s = s->next) {


		  switch (tolower(getstr(s->s[0])[0])) {

/* message command */

		  case '@':
		  printf("%s\n",s->s[0]); 
		     printf("[message removed]\n");
		     ns = getstr(0);
		     if (ns[0]) {
			plist = 0;
			do {
			   P2 = identify(players, ns);
			   if (P2) {
			      a = alloc(sizeof(alliance));
			      a->who = P2;
			      addlist(&plist, a);
			   } else
			      mistake("Player not recognized");
			   ns = getstr(0);
			}
			while (ns[0]);
			for (a = plist; a; a = a->next)
			   addlist(&a->who->messages, makestrlist(""));

			while (s->next) {
			   s = s->next;
			   if (getstr(s->s[0])[0] == '@') {
			      printf("@\n");
			      break;
			   }
			   for (a = plist; a; a = a->next)
			      addlist(&a->who->messages, makestrlist(s->s[0]));
			   s->s[0][0] = 0;
			}
			freelist(plist);
		     } else {
			addlist(&messages, makestrlist(""));
		
			while (s->next) {
			   s = s->next;
			   if (getstr(s->s[0])[0] == '@') {
			      printf("@\n");
			      break;
			   }
			   addlist(&messages, makestrlist(s->s[0]));
			   s->s[0][0] = 0;
			}
		     }
		     break;

/* a_command */

		  case 'a':
		  printf("%s\n",s->s[0]); 
		     P2 = identify(players, getstr(0));
		     if (!P2) {
			mistake("Player not recognized");
			break;
		     }
		     for (a = P->allies; a; a = a->next)
			if (a->who == P2)
			   break;
		     if (!a && P2 != P) {
			a = alloc(sizeof(alliance));
			a->who = P2;
			addlist(&P->allies, a);
		     }
		     break;

/* b_command */
		  case 'b':
		  printf("%s\n",s->s[0]); 

                     g = findgroup(P, getstr(0));
                     if (!g) {
                        mistake("Group not recognized");
                        break;
                     }
                     ns = getstr(0);
                     if (!memicmp(ns, "fleet", 5)) {
			if (g->dist) {
			    mistake(P, *s, "Fleet is in hyperspace");
			    break;
			}
                        g->thefleet = 0;
                        break;
                     }
                     i = atoi(ns);
                     if (i >= g->ships) {
                        mistake("Not enough ships in group");
                        break;
                     }
                     g2 = alloc(sizeof(group));
                     *g2 = *g;
                     g2->ships = i;
                     g->ships -= i;
                     g->thefleet = 0;
                     addlist(&P->groups, g2);
		     break;
/* d_command */
		  case 'd':
		  printf("%s\n",s->s[0]); 
                     ns = getstr(0);
                     if (!ns[0]) {
                        mistake("No ship type name given");
                        break;
                     }
                  
                     if (identify (P->fleetnames, ns)) {
                        mistake ("Name already in use for fleet");
                        break;
                     }

/* Occasionally someone designs a ship called "Cargo" or something, then
   doesn't understand why the planet didn't produce the ship when they
   do "P planet Cargo" :)  This will fix this problem.  - RJS */

/* need to change that '7' down there with something that will change
   with the array.  Yea, I know.  I'm being anal.  But when it comes
   back to haunt us...    -RJS */

                     for(i=0; i < 7;i++) {
                        if(productname[i] && !strcmpl(productname[i],ns)) {
 	                   mistake("Ship name can not be the same as a product name");
	                   break;
                        }
                     }
                  
                     if (nametop(P->shiptypes, ns)) {
                        mistake("Ship type name already in use");
                        break;
                     }
                  
                     if (!memicmp(ns, "fleet", 5)) {
                        ns = getstr(0);
                        if (!ns[0]) {
	                   mistake ("No fleet name given");
	                   break;
                        }
                        if (identify (P->fleetnames, ns)) {
	                   mistake ("Fleet name already in use");
	                   break;
                        }
                        if (identify (P->shiptypes, ns)) {
	                   mistake ("Name already in use for ship type");
	                   break;
                        }
                        fl = alloc (sizeof (fleetname));
                        nstrcpy (fl->name, ns, NAMESIZE);
                        fl->fleetspeed = 1000.0;
                        addlist (&P->fleetnames, fl);
                        if (P->namecase)
	                   ckcase (fl->name);
                        break;
                     }
                  
                     t = alloc(sizeof(shiptype));
                     nstrcpy(t->name, ns, NAMESIZE);
                     t->drive = atof(getstr(0));
                     if (t->drive < 1)
                        t->drive = 0;
                     t->attacks = atoi(getstr(0));
                     t->weapons = atof(getstr(0));
                     if (t->weapons < 1)
                        t->attacks = 0;
                     if (!t->attacks)
                        t->weapons = 0;
                     t->shields = atof(getstr(0));
                     if (t->shields < 1)
                        t->shields = 0;
                     t->cargo = atof(getstr(0));
                     if (t->cargo < 1)
                        t->cargo = 0;
                     if (!t->drive && !t->attacks && !t->shields && !t->cargo) {
                        mistake("At least one component must be non-zero");
                        free(t);
                        break;
                     }
                     addlist(&P->shiptypes, t);
                     if (P->namecase)
                        ckcase(t->name);
		     break;

/* e_command */
		  case 'e':
		  printf("%s\n",s->s[0]); 
                     ns = getstr (0);
                     t = nametop (P->shiptypes, ns);
                     fl = identify(P->fleetnames, ns);
                     if (!t && !fl) {
                        mistake("Ship or fleet type not recognized");
                        break;
                     }
                  
                     if (fl) {
                        for (g=P->groups; g; g=g->next) {
	                   if ((g->thefleet == fl)&&(g->dist)) {
                               mistake("Fleet is in hyperspace"); 
                               break;
			   } 
			}
                        for (g=P->groups; g; g=g->next)
	                   if (g->thefleet == fl)
	                      g->thefleet = 0;
                        removelist (&P->fleetnames, fl);
                        break;
                     }
                  
                     for (g = P->groups; g; g = g->next)
                        if (g->type == t) {
	                   mistake("Some of these ships still exist");
	                   break;
                        }
                     if (g)
                        break;
                     for (p = planets; p; p = p->next)
                        if (p->producingshiptype == t) {
	                   mistake("Some of these ships are still being produced");
	                   break;
                        }
                     if (p)
                        break;
                     removelist(&P->shiptypes, t);
		     break;


/* f_command */
		  case 'f':
		  printf("%s\n",s->s[0]); 
		     P2 = identify(players, getstr(0));
		     if (!P2) {
			mistake("Player not recognized");
			break;
		     }
		     if (P2->addr[0])
			printf("The address of %s is %s\n", 
			   P2->name, P2->addr);
		     else
			printf("There is currently no address for %s.\n",
			   P2->name);
		     break;

/* i_command */
		  case 'i':
		  printf("%s\n",s->s[0]); 
                     ns = getstr(0);
                     g = findgroup(P, ns);
                     fl = identify (P->fleetnames, ns);
                     if (!g && !fl) {
                        mistake("Group or fleet not recognized");
                        break;
                     }
                     if (fl) {
                        p = identify (planets, getstr(0));
                        if (!p) {
	                   mistake ("Planet not recognized");
	                   break;
                        }
                        for (g=P->groups; g; g=g->next) {
                           if ((g->thefleet == fl)&&(g->dist)) {
	                      mistake ("Fleet is in hyperspace");
	                      break;
                           }
                           if ((g->thefleet == fl)&&(!g->type->drive)) {
	                      mistake ("Fleet cannot move");
	                      break;
                           }
                        }
                        for (g=P->groups; g; g=g->next) {
	                   if (g->thefleet == fl) {
	                      g->from = p;
	                      g->dist = -1;
                           }
                        }
                        break;
                     }
                     if (g->type->drive == 0) {
                        mistake("Ships in this group can't move");
                        break;
                     }
                     if (g->dist) {
                        mistake("Group is in hyperspace");
                        break;
                     }
                     p = identify(planets, getstr(0));
                     if (!p) {
                        mistake("Planet not recognized");
                        break;
                     }
                     i = g->ships;
                     if ((j = atoi(getstr(0))) != 0) {
                        i = j;
                        if (i > g->ships) {
	                   mistake("Not enough ships, all available used");
	                   i = g->ships;
                        }
                        if (i != g->ships) {
	                   g2 = alloc(sizeof(group));
	                   *g2 = *g;
	                   addlist(&P->groups, g2);
	                   g->ships -= i;
	                   g2->ships = i;
	                   g = g2;
                        }
                     }
                     g->from = p;
                     g->dist = -1;
                     g->thefleet = 0;
                     break;
                
/* j_command */
		  case 'j':
		  printf("%s\n",s->s[0]); 
                     ns = getstr(0);
                     g = findgroup (P,ns);
                     fl = identify (P->fleetnames, ns);
                     if (!g && !fl) {
                        mistake ("Group or fleet not recognized");
                        break;
                     }
                     if (fl) {
                        fl2 = identify (P->fleetnames, getstr(0));
                        for (g=P->groups; g; g=g->next) {
	                   if (g->thefleet == fl) {
	                      p = g->where;
	                      dist = g->dist;
	                   }
	                   if (g->thefleet == fl2) {
	                      p2 = g->where;
	                      dist2 = g->dist;
	                   }
                        }
                        if (dist) {
	                   mistake ("First fleet is in hyperspace");
	                   break;
                        }
                        if (dist2) {
	                   mistake ("Second fleet is in hyperspace");
	                   break;
                        }
                        if (p != p2) {
	                   mistake ("Fleets are not at the same planet");
	                   break;
                        }
                        for (g=P->groups; g; g=g->next)
                           if (g->thefleet == fl)
                              g->thefleet = fl2;
                        break;
                     }
                     if (g->dist) {
                        mistake ("Group is in hyperspace");
                        break;
                     }
                     fl = identify (P->fleetnames,getstr (0)); 
                     if (!fl) {
                        mistake ("Fleet type not recognized"); 
                        break;
                     }
                     if ((j = atoi (getstr (0))) != 0) {
                        i = j;
                        if (i > g->ships) {
                           mistake ("Not enough ships, all available used");
                           i = g->ships;
                        }
                        if (i != g->ships) {
	                   g2 = alloc(sizeof(group));
                           *g2 = *g;
                           addlist (&P->groups, g2);
                           g->ships -= i;
                           g2->ships = i;
                           g = g2;
                        }
                     }
                     for (g2=P->groups; g2; g2=g2->next) {
                        if ((g2->thefleet == fl)&&(g2->dist)) {
	                   mistake ("Fleet is in hyperspace");
	                   break;
                        }
                        if ((g2->thefleet == fl)&&(!g2->dist)&& (g2->where != g->where)) {
                           mistake ("Group is at the wrong planet");
                           break;
                        }
                     }
                     g->thefleet = fl;
		     break;
/* l_command */
		  case 'l':
		  printf("%s\n",s->s[0]); 
		     g = findgroup(P, getstr(0));
		     if (!g) {
			mistake("Group not recognized");
			break;
		     }
		     if (g->type->cargo == 0) {
			mistake("Group cannot carry cargo");
			break;
		     }
		     if (g->dist) {
			mistake("Group is in hyperspace");
			break;
		     }
		     x = cargospace(g);
		     if (x <= g->load) {
			mistake("Group is fully loaded");
			break;
		     }
		     p = g->where;
		     if (p->owner != P) {
			mistake("Group is not at one of your planets");
			break;
		     }
		     k = nametocargotype(getstr(0));
		     if (k < 0 || k > 2) {
			mistake("Cargo type not recognized");
			break;
		     }
		     if (g->load && g->loadtype != k) {
			mistake( 
			   "Group is already carrying a different load");
			break;
		     }
		     i = g->ships;
		     if ((j = _atoi(getstr(0))) != 0) {
			i = j;
			if (i > g->ships) {
			   mistake( 
			      "Not enough ships, all available used");
			   i = g->ships;
			}
/*
			if (i != g->ships) {
			   g2 = alloc(sizeof(group));
			   *g2 = *g;
			   addlist(&P->groups, g2);
			   g->ships -= i;
			   g2->ships = i;
			   g = g2;
			}
*/
		     }
		     x = (x - g->load) * g->ships;
		     switch (k) {
		     case CG_CAP:
			y = p->cap;
			if (!y) {
			   mistake("No capital available");
			   break;
			}
			if (y > x)
			   y = x;
			g->load += y / g->ships;
			p->cap -= y;
			break;
		     case CG_MAT:
			y = p->mat;
			if (!y) {
			   mistake("No materials available");
			   break;
			}
			if (y > x)
			   y = x;
			g->load += y / g->ships;
			p->mat -= y;
			break;
		     case CG_COL:
			y = p->col;
			if (!y) {
			   mistake("No colonists available");
			   break;
			}
			if (y > x)
			   y = x;
			g->load += y / g->ships;
			p->col -= y;
			break;
		     }
		     g->loadtype = k;
		     break;

/* m_command */
		  case 'm':
		  printf("%s\n",s->s[0]); 
		     x = atof(getstr(0));
		     y = atof(getstr(0));
		     z = atof(getstr(0));
		     if (z < 1) {
			mistake("Size must be at least 1");
			break;
		     }
		     P->mx = x;
		     P->my = y;
		     P->msize = z;
		     break;

/* o_command */
		  case 'o':
		  printf("%s\n",s->s[0]); 
		     ns = getstr(0);
		     i = 1;
		     if (!strcmpl(ns, "no")) {
			i = 0;
			ns = getstr(0);
		     }
		     if (!strcmpl(ns, "prodtable")) {
			P->prodtable = i;
			break;
		     }
		     if (!strcmpl(ns, "autounload")) {
			P->autounload = i;
			break;
		     }
		     if (!strcmpl(ns, "sortgroups")) {
			P->sortgroups = i;
			break;
		     }
		     if (!strcmpl(ns, "fleettables")) {
			P->fleettables = i;
			break;
		     }
		     if (!strcmpl(ns, "underscores")) {
			P->underscores = i;
			break;
		     }
		     if (!strcmpl(ns, "twocol")) {
			P->twocol = i;
			break;
		     }
		     if (!strcmpl(ns, "namecase")) {
			P->namecase = i;
			break;
		     }
		     mistake("Option not recognized");
		     break;

/* p_command */
		  case 'p':
		  printf("%s\n",s->s[0]); 
		     p = identify(planets, getstr(0));
		     if (!p) {
			mistake("Planet not recognized");
			break;
		     }
		     if (p->owner != P) {
			mistake("Planet not owned by you");
			break;
		     }
		     ns = getstr(0);
		     if (!strcmpl(ns, "cap")) {
			setproduction(p, PR_CAP);
			break;
		     }
		     if (!strcmpl(ns, "mat")) {
			setproduction(p, PR_MAT);
			break;
		     }
		     if (!strcmpl(ns, "drive")) {
			setproduction(p, PR_DRIVE);
			break;
		     }
		     if (!strcmpl(ns, "weapons")) {
			setproduction(p, PR_WEAPONS);
			break;
		     }
		     if (!strcmpl(ns, "shields")) {
			setproduction(p, PR_SHIELDS);
			break;
		     }
		     if (!strcmpl(ns, "cargo")) {
			setproduction(p, PR_CARGO);
			break;
		     }
		     t = identify(P->shiptypes, ns);
		     if (!t) {
			mistake("Production type not recognized");
			break;
		     }
		     if (p->producing != PR_SHIP || p->producingshiptype != t) {
			setproduction(p, PR_SHIP);
			p->producingshiptype = t;
		     }
		     break;

/* q_command */
		  case 'q':
		  printf("%s\n",s->s[0]); 
		     if (identify(players, getstr(0)) != P) {
			mistake("Player identification not given");
			break;
		     }
		     P->addr[0] = 0;
		     printf("%s is quitting the game\n", P->name);
		     break;

/* r_command */
		  case 'r':
		  printf("%s\n",s->s[0]); 
		     p = identify(planets, getstr(0));
		     if (!p) {
			mistake("Source planet not recognized");
			break;
		     }
		     if (p->owner != P) {
			mistake("Planet not owned by you");
			break;
		     }
		     i = nametocargotype(getstr(0));
		     if (i < 0) {
			mistake("Cargo type not recognized");
			break;
		     }
		     p2 = 0;
		     ns = getstr(0);
		     if (ns[0]) {
			p2 = identify(planets, ns);
			if (!p2) {
			   mistake("Destination planet not recognized");
			   break;
			}
		     }
		     p->routes[i] = p2;
		     break;

/* s_command */
		  case 's':
		  printf("%s\n",s->s[0]); 
                     ns = getstr(0);
                     g = findgroup(P, ns);
                     fl = identify (P->fleetnames, ns);
                     if (!g && !fl) {
                        mistake("Group or fleet not recognized");
                        break;
                     }
                     if (fl) {
                        p = identify (planets, getstr(0));
                        if (!p) {
	                   mistake ("Planet not recognized");
	                   break;
                        }
                        for (g=P->groups; g; g=g->next) {
	                   if ((g->thefleet == fl)&&(g->dist)) {
	                      mistake ("Fleet is in hyperspace");
	                      break;
                           }
	                   if ((g->thefleet == fl)&&(!g->type->drive)) {
	                      mistake ("Fleet cannot move");
	                      break;
                           }
                        }
                        for (g=P->groups; g; g=g->next)
	                   if (g->thefleet == fl)
	                      send (g, p);
                        break;
                     }
                     if (g->type->drive == 0) {
                        mistake("Ships in this group can't move");
                        break;
                     }
                     if (g->dist) {
                        mistake("Group is in hyperspace");
                        break;
                     }
                     p = identify(planets, getstr(0));
                     if (!p) {
                        mistake("Planet not recognized");
                        break;
                     }
                     i = g->ships;
                     if ((j = atoi(getstr(0))) != 0) {
                        i = j;
                        if (i > g->ships) {
	                   mistake("Not enough ships, all available used");
	                   i = g->ships;
                        }
                        if (i != g->ships) {
	                   g2 = alloc(sizeof(group));
	                   *g2 = *g;
	                   addlist(&P->groups, g2);
	                   g->ships -= i;
	                   g2->ships = i;
	                   g = g2;
                        }
                     }
                     g->thefleet = 0;
                     send(g, p);
		     break;

/* u_command */
		  case 'u':
		  printf("%s\n",s->s[0]); 
		     g = findgroup(P, getstr(0));
		     if (!g) {
			mistake("Group not recognized");
			break;
		     }
		     if (g->loadtype == CG_EMPTY) {
			mistake("No cargo on board");
			break;
		     }
		     if (g->dist) {
			mistake("Group is in hyperspace");
			break;
		     }
		     if (g->loadtype == CG_COL && g->where->owner &&
			 g->where->owner != P) {
			mistake( 
			   "Can't unload colonists onto an alien planet");
			break;
		     }
		     i = g->ships;
		     if ((j = _atoi(getstr(0))) != 0) {
			i = j;
			if (i > g->ships) {
			   mistake( 
			      "Not enough ships, all available used");
			   i = g->ships;
			}
			if (i != g->ships) {
			   g2 = alloc(sizeof(group));
			   *g2 = *g;
			   addlist(&P->groups, g2);
			   g->ships -= i;
			   g2->ships = i;
			   g = g2;
			}
		     }
		     unloadgroup(g, P);
		     break;

/* w_command */
		  case 'w':
		  printf("%s\n",s->s[0]); 
		     P2 = identify(players, getstr(0));
		     if (!P2) {
			mistake("Player not recognized");
			break;
		     }
		     for (a = P->allies; a; a = a->next)
			if (a->who == P2) {
			   removelist(&P->allies, a);
			   break;
			}
		     break;
		  case 'x':
		  printf("%s\n",s->s[0]); 
		     g = findgroup(P, getstr(0));
		     if (!g) {
			mistake("Group not recognized");
			break;
		     }
		     if (g->dist) {
			mistake("Group is in hyperspace");
			break;
		     }
		     if (g->loadtype == CG_COL && g->where->owner &&
			 g->where->owner != P) {
			mistake( 
				"Can't unload colonists onto an alien planet");
			break;
		     }
		     i = g->ships;
		     if ((j = _atoi(getstr(0))) != 0) {
			i = j;
			if (i > g->ships) {
			   mistake( 
			      "Not enough ships, all available used");
			   i = g->ships;
			}
			if (i != g->ships) {
			   g2 = alloc(sizeof(group));
			   *g2 = *g;
			   addlist(&P->groups, g2);
			   g->ships -= i;
			   g2->ships = i;
			   g = g2;
			}
		     }
		     unloadgroup(g, P);
		     g->where->mat += shipmass(g) * g->ships;
		     g->ships = 0;
		     break;

/* y_command */
		  case 'y':
		  printf("%s\n",s->s[0]); 
		      ns = getstr (0);
		      nstrcpy (P->pswd, ns, NAMESIZE);
		      break;
/* z_command */
		  case 'z':
		  printf("%s\n",s->s[0]); 
		     ns = getstr(0);
		     if (!ns[0]) {
			mistake("No new address given");
			break;
		     }
		     nstrcpy(P->addr, ns, ADDRSIZE);
		     break;
		  case 'c': case 'g': case 'n': case 't':
		     naming_flag++;
		     break;
		  }
		  }
	    }

	    /* Do renaming and upgrade orders: cgnt */
	    if(naming_flag) printf("\n\nAnd, Your honor, here are your"
		   " naming and recomissioning proclamations:\n\n");

	    for (P = players; P; P = P->next) {
	       for (s = P->orders; s; s = s->next) {

		  switch (tolower(getstr(s->s[0])[0])) {

/* c_command */
		  case 'c':
		  printf("%s\n",s->s[0]); 
		     ns = getstr(0);
		     i = strlen(ns);
		     while (i && !isalnum(ns[i - 1]))
			i--;
		     ns[i] = 0;
		     if (!ns[0]) {
			mistake("No new race name given");
			break;
		     }
		     if (nametop(players, ns)) {
			mistake("Race name already in use");
			break;
		     }
		     nstrcpy(P->name, ns, NAMESIZE);
		     if (P->namecase)
			ckcase(P->name);
		     break;

/* g_command */
		  case 'g':
		  printf("%s\n",s->s[0]); 
		     g = findgroup(P, getstr(0));
		     if (!g) {
			mistake("Group not recognized");
			break;
		     }
		     if (g->dist) {
			mistake("Group is in hyperspace");
			break;
		     }
		     p = g->where;
		     t = g->type;
		     x = INDPERSHIP * ((1 - g->drive / P->drive) * t->drive +
			     (1 - g->weapons / P->weapons) * weaponmass(t) +
				(1 - g->shields / P->shields) * t->shields +
				       (1 - g->cargo / P->cargo) * t->cargo);
		     y = p->ind * .75 + p->pop * .25 - p->spent;
		     ns = getstr(0);
		     if (ns[0]) {
			i = _atoi(ns);
			if (i == 0)
			   i = g->ships;
			if (i > g->ships) {
			   mistake( 
				"Not enough ships, all available used");
			   i = g->ships;
			}
			if (i != g->ships) {
			   g2 = alloc(sizeof(group));
			   *g2 = *g;
			   addlist(&P->groups, g2);
			   g->ships -= i;
			   g2->ships = i;
			   g = g2;
			}
			z = y / i;
			if (z >= x)
			   memcpy(&g->drive, &P->drive, 4 * sizeof(double));
			else {
			   z /= x;
			   x *= z;
			   g->drive = g->drive + (P->drive - g->drive) * z;
			   g->weapons = g->weapons + 
			      (P->weapons - g->weapons) * z;
			   g->shields = g->shields + 
			      (P->shields - g->shields) * z;
			   g->cargo = g->cargo + (P->cargo - g->cargo) * z;
			}
			cktech(g);
		     } else {
			i = g->ships;
			if (x * i > y) {
			   i = y / x;
			   g2 = alloc(sizeof(group));
			   *g2 = *g;
			   addlist(&P->groups, g2);
			   g->ships -= i;
			   g2->ships = i;
			   g = g2;
			}
			memcpy(&g->drive, &P->drive, 4 * sizeof(double));
			cktech(g);
		     }
		     p->spent += x * i;
		     break;

/* n_command */
		  case 'n':
		  printf("%s\n",s->s[0]); 
		     p = identify(planets, getstr(0));
		     if (!p) {
			mistake("Planet not recognized");
			break;
		     }
		     if (p->owner != P) {
			mistake("Planet not owned by you");
			break;
		     }
		     ns = getstr(0);
		     if (!ns[0]) {
			mistake("New planet name not provided");
			break;
		     }
		     if (nametop(planets, ns)) {
			mistake("Name already in use");
			break;
		     }
		     nstrcpy(p->name, ns, NAMESIZE);
		     if (P->namecase)
			ckcase(p->name);
		     break;

/* t_command */
		  case 't':
		  printf("%s\n",s->s[0]); 
                     ns = getstr (0);
                     t = identify(P->shiptypes, ns);
                     fl = identify(P->fleetnames, ns);
                     if (!t && !fl) {
                        mistake("Ship or fleet type not recognized");
                        break;
                     }
                     ns = getstr(0);
                     if (!ns[0]) {
                        mistake("New name not provided");
                        break;
                     }
                     if (identify(P->fleetnames, ns)) {
                        mistake("Name already in use for fleet type");
                        break;
                     }
                     if (nametop(P->shiptypes, ns)) {
                        mistake("Name already in use for ship type");
                        break;
                     }
                     if (fl) {
                        nstrcpy (fl->name, ns, NAMESIZE);
                        if (P->namecase)
	                   ckcase (fl->name);
                     }
                     else {
                        nstrcpy(t->name, ns, NAMESIZE);
                        if (P->namecase)
                           ckcase(t->name);
                     }
		     break;
		  }
               }
	    }


	    break;
	 }
	 if (!memicmp(buf, "#galaxy", 7)) {

      NEXTPLAYER:

	    getstr(buf);
	    strcpy(gamename,getstr(0));
	    strcpy(tns,getstr(0)); 

	    loadgame(gamename);	       /* try to load the game */

	       P = identify(players, tns);

	       if (P) {
		  f = fopen(ordersfilename,"r");
		  while(memicmp(buf, "#galaxy", 7)) getbuf();

		  ns = getstr(0);
		  if ((!strcmpl(P->pswd, ns))||(!(P->pswd[0]))) {
		     fprintf(stderr,"Reading orders for %s...\n", P->name);
		     print_er_banner(P->name);
		     P->lastorders = turn + 1;
		     if (P->orders) {
		        freestrlist(P->orders);
		        P->orders = 0;
		     }
		     sp = &P->orders;
		     for (;;) {
		        getbuf();
   
		       /* if (!memicmp(buf, "#galaxy", 7)) {
			   *sp = 0;
			   goto NEXTPLAYER;
		        } */ 
   
		        if(!memicmp(buf, "#end",4)) {
			   *sp=0;
			   break;
		        } else if(buf[0] == (char)EOF) {
		           printf("You didn't end your orders with the #end"
			          " on the last line!\nShame on you!\n");
			   exit(3); /* 3 = no #end statement */
		           break;
		        } 
	   	
		        s = makestrlist(buf);
		        addlist2(sp, s);
		     }
		  } else {
		     fprintf(stderr, "Incorrect password for '%s'\n", tns);
		     exit(4); /* 4 = Incorrect password */
		     }
	       } else {
		  fprintf(stderr,"Unrecognized player '%s'\n", tns);
		  exit(2);  /* 2 = Unrecognized player */
		  }
	    
	 }
   }
}

void
print_er_banner(char *name)
{
   printf(
"\n\
---------------------------------------------------------------------------\n\
Galaxy %s Turn %d ORDERS RECEIVED Report for %s\n\
---------------------------------------------------------------------------\n\
\n\
The following is a communication directly to the headquarters of the\n\
Great and Powerful %s from Galaxy Headquarters....\n\
\n\
Use this information at your own risk.... no guarantees, no apologies.\n\
\n\
Your excellency!  We have received your orders.  They have been transcribed\n\
> below with comments where appropriate:\n\n\n", gamename, turn + 1, name, name);
}

void print_er_footer(void)
{
   printf("----- end of order transcript -----\n\n\
If your orders are not listed above, you may have made a mistake\n\
in your racename, gamename, or somewhere else. Successfully processed\n\
orders are usually listed in full above these lines.\n\n");

   switch(nerrors) {
      case 0:
         printf(
"\nThank you sir!  All your orders were valid.  May your rule have no end!\n\
\n");
         break;
      case 1:
         printf("\nSir, there is a problem with one of your orders.\n");
         break;
      case 2: case 3: case 4:
         printf(
"\nUh, Sir...  there are a few problems with some of the orders that we\n\
received from you.  Please retransmit in order to verify.\n");
	 break;
      case 5: case 6: case 7: case 8: case 9:
         printf(
"Ah... um..... *cough*  *clear-throat*  Um, I'm not sure how to tell you\n\
this, uh sir, but there seem to be a large number of...  um... problems?\n\
with your orders....\n");
 	 break;
      default:
	 printf(
"Aaaaahhhh.... um....  uh....  Sir, uh, your Majesty, ehhh, it would seem\n\
as if, uh, there could be some, ah...  major complications perhaps?  with\n\
the orders that we received.  Um.... if you could just resend them, we\n\
would be quite grateful!\n");
	 break;
   }

   printf(
"\n\n\
---------------------------------------------------------------------------\n\
TRANSMISSION TERMINATED...\n\
---------------------------------------------------------------------------\n");

}

int
main(int argc, char *argv[])
{

   dfd = opendir(".");
   srand();
   randno = (unsigned long) rand();
   fprintf(stderr,"Galaxy v3.40  Order Checker by Robert Stone\n\
Copyright 1991-1992 by Russell Wallace and Robert Stone\n\
Revised for Galaxy v3.40 by Kevin Pankhurst\n\
Minor mods by Robert Novak for his games\n");
   if(argc > 1) {
	processturns(argv[1]);
   } else {
   processturns(NULL);
   }
   print_er_footer();
   return 0;
}

/*
 * exit codes:
 * 1 = no such game
 * 2 = no such player
 * 3 = no end statement
 * 4 = password incorrect
 *
 */
