--- 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];