--- xonix-1.4.orig/x11.c	Thu Sep 14 11:55:55 1995
+++ xonix-1.4/x11.c	Wed Jan 19 17:19:34 2000
@@ -879,7 +879,7 @@
 {
   const struct score_rec *ra = (struct score_rec *)a;
   const struct score_rec *rb = (struct score_rec *)b;
-  return ra->score - rb->score;
+  return rb->score - ra->score; /* reversed DMR */
 }
 
 #endif /* __unix */
@@ -896,8 +896,9 @@
   FILE *high;
   struct passwd *pw;
   char *fullname = 0, *cp;
-  struct score_rec score_rec[MAXSCORES];
-  int i, numentries = 0;
+  struct score_rec score_rec[MAXSCORES+1]; /* DMR: deliberately
+                                              contains a spare slot */
+  int i, numentries = 0, hserror = 0;
   char tempname[sizeof(PATH_TEMPSCORE) + 15];
   char hugestring[MAXSCORES * 100];
   
@@ -905,6 +906,11 @@
   Arg wargs[2];
   Cardinal x, y;
 
+  /*
+   *  Modified DMR: blank score_rec before continuing
+   */
+  memset (score_rec, 0, (MAXSCORES+1) * sizeof (struct score_rec));
+
   if((pw = getpwuid(getuid())) == 0) {
     fprintf(stderr, "xonix: Who are you?\n");
     endpwent();
@@ -948,41 +954,86 @@
     numentries = i;
     fclose(high);
   }
-  if(numentries)
+  if(numentries > 1)
     qsort(score_rec, numentries, sizeof(struct score_rec), compare);
 
-  /* make sure the new list will be world-readable */
-  (void)umask(umask(0) & ~0644);
-  sprintf(tempname, "%s.%d", PATH_TEMPSCORE, (int)getpid());
-  if((high = fopen(tempname, "w")) == NULL) {
-    fprintf(stderr, "xonix: cannot rewrite high score file\n");
+  /*
+   *  Modified DMR -- don't open the new high score table if we don't
+   *  need to
+   */
+  if(numentries >= MAXSCORES && gHighScore < score_rec[MAXSCORES-1].score) {
+    /* sorry, not among top ten */
     free(fullname);
     gameover_pending = 0;
     return;
   }
   
-  if(numentries >= MAXSCORES && gHighScore < score_rec[0].score) {
-    /* sorry, not among top ten */
-    fclose(high);
-    (void)unlink(tempname);
+  /* make sure the new list will be world-readable */
+  (void)umask(umask(0) & ~0644);
+  sprintf(tempname, "%s.%d", PATH_TEMPSCORE, (int)getpid());
+  if((high = fopen(tempname, "w")) == NULL) {
+    fprintf(stderr, "xonix: cannot rewrite high score file\n");
     free(fullname);
     gameover_pending = 0;
     return;
   }
-  
-  for(i = 0; i < numentries; i++) {
-    /* look where to put entry */
-    if(score_rec[i].score > gHighScore) break;
-  }
+
+  /*
+   *  Modified DMR: put the new entry at the end of the table and
+   *  re-sort.
+   */
+  score_rec[numentries].score = gHighScore;
+  score_rec[numentries].level = gLevel;
+  strncpy (score_rec[numentries].login, pw->pw_name, 10);
+  strncpy (score_rec[numentries].full, fullname, 64);
+  score_rec[numentries].tstamp = time(NULL);
+  free(fullname);
+
+  if(numentries > 0)
+    qsort(score_rec, numentries+1, sizeof(struct score_rec), compare);
+
+  if(numentries < MAXSCORES)
+    numentries++;
+
+  /*
+   *  Commented DMR: Write at most the first ten entries to disc.
+   *  There will be eleven entries if we've added to a score table
+   *  which used to have ten.  However, the eleventh is the one which
+   *  is supposed to be discarded so everything's safe.
+   */
+  for(i = 0; i < numentries; i++)
+    if (fprintf(high, "%u\t%u\t%s\t%s\t%ld\n",
+		score_rec[i].score, score_rec[i].level,
+		score_rec[i].login, score_rec[i].full,
+		score_rec[i].tstamp)
+	== EOF) {
+      fprintf (stderr, "xonix: error writing to new highscore file\n");
+      hserror = 1;
+      break;
+    }
+  fclose(high);
+
+  if (!hserror)
+    if(rename(tempname, PATH_HIGHSCORE)) {
+      fprintf(stderr, "xonix: cannot install new highscore file\n");
+      hserror = 1;
+    }
 
 #ifdef SEND_MAIL
-  if(numentries > 0 && gHighScore > score_rec[numentries - 1].score &&
-     strcmp(pw->pw_name, score_rec[numentries - 1].login) != 0) {
+  /*
+   *  Modified DMR: only mail out if we successfully updated the score
+   *  file.  The new score is the highest if it is strictly greater
+   *  than the second-highest score, which we know is stored at
+   *  score_rec[1]
+   */
+  if(!hserror && numentries > 1 &&
+     gHighScore > score_rec[1].score &&
+     strcmp(pw->pw_name, score_rec[1].login) != 0) {
     /* we have got a new champion, warn the old one (:-) */
     FILE *mail;
     char cmd[200];
     char tbuf[20];
-    struct score_rec *sp = &score_rec[numentries - 1];
+    struct score_rec *sp = &score_rec[1];
     struct tm *tm;
 
     strncpy(cmd, PATH_RMAIL, 200);
@@ -997,9 +1048,10 @@
       fprintf(mail,
 	      "To: %s (%s)\n"
 	      "Subject: Lost xonix championship\n\n"
+              "[This message was generated by the xonix game]\n\n"
 	      "Your previously held first rank in the local xonix score\n"
 	      "table (%u points, level %u, dated %s) has been\n"
-	      "vanished today by me with %u points.\n\n"
+	      "vanquished today by me with %u points.\n\n"
 	      "\t\tpitying you\t%s (%s)\n",
 	      sp->login, sp->full,
 	      sp->score, sp->level, tbuf,
@@ -1012,44 +1064,11 @@
 
 #endif /* SEND_MAIL */
 
-  if(numentries >= MAXSCORES) {
-    i--;
-    if(i > 0)
-      /* we must shift something */
-      memmove(&score_rec[0], &score_rec[1],
-	      i * sizeof(struct score_rec));
-  } else {
-    if(numentries > i)
-      /* we must shift something */
-      memmove(&score_rec[i + 1], &score_rec[i],
-	      (numentries - i) * sizeof(struct score_rec));
-    numentries++;
-  }
-  
-  score_rec[i].score = gHighScore;
-  score_rec[i].level = gLevel;
-  
-  memset(score_rec[i].login, 0, 11);
-  strncpy(score_rec[i].login, pw->pw_name, 10);
-  memset(score_rec[i].full, 0, 65);
-  strncpy(score_rec[i].full, fullname, 64);
-  score_rec[i].tstamp = time(NULL);
-  free(fullname);
-
-  for(i = 0; i < numentries; i++)
-    (void)fprintf(high, "%u\t%u\t%s\t%s\t%ld\n",
-		  score_rec[i].score, score_rec[i].level,
-		  score_rec[i].login, score_rec[i].full,
-		  score_rec[i].tstamp);
-  fclose(high);
-  
-  if(rename(tempname, PATH_HIGHSCORE))
-    fprintf(stderr, "xonix: cannot install new highscore file\n");
 
   /* create hugestring for highscore label */
   hugestring[0] = 0;
   for(i = 0; i < numentries; i++) {
-    struct score_rec *sp = &score_rec[numentries - i - 1];
+    struct score_rec *sp = &score_rec[i];
     struct tm *tm;
     char tbuf[20];
     char line[100];

