121473Smckusick /*
2*60840Sbostic * Copyright (c) 1980, 1993
3*60840Sbostic * The Regents of the University of California. All rights reserved.
433690Sbostic *
542591Sbostic * %sccs.include.redist.c%
621473Smckusick */
721473Smckusick
821473Smckusick #ifndef lint
9*60840Sbostic static char sccsid[] = "@(#)score.c 8.1 (Berkeley) 05/31/93";
1033690Sbostic #endif /* not lint */
1121473Smckusick
1221473Smckusick # include "robots.h"
1337017Sbostic # include <sys/types.h>
1421473Smckusick # include <pwd.h>
1541323Sbostic # include "pathnames.h"
1621473Smckusick
1721473Smckusick typedef struct {
1821473Smckusick int s_uid;
1921473Smckusick int s_score;
2021473Smckusick char s_name[MAXNAME];
2121473Smckusick } SCORE;
2221473Smckusick
2321473Smckusick typedef struct passwd PASSWD;
2421473Smckusick
2541323Sbostic char *Scorefile = _PATH_SCORE;
2621473Smckusick
2721473Smckusick int Max_per_uid = MAX_PER_UID;
2821473Smckusick
2921473Smckusick static SCORE Top[MAXSCORES];
3021473Smckusick
3121473Smckusick /*
3221473Smckusick * score:
3321473Smckusick * Post the player's score, if reasonable, and then print out the
3421473Smckusick * top list.
3521473Smckusick */
score()3621473Smckusick score()
3721473Smckusick {
3821473Smckusick register int inf;
3921473Smckusick register SCORE *scp;
4021473Smckusick register int uid;
4121473Smckusick register bool done_show = FALSE;
4221473Smckusick static int numscores, max_uid;
4321473Smckusick
4421473Smckusick Newscore = FALSE;
4521473Smckusick if ((inf = open(Scorefile, 2)) < 0) {
4621473Smckusick perror(Scorefile);
4721473Smckusick return;
4821473Smckusick }
4921473Smckusick
5021473Smckusick if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid)
5121473Smckusick read(inf, Top, sizeof Top);
5221473Smckusick else {
5321473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++)
5421473Smckusick scp->s_score = -1;
5521473Smckusick max_uid = Max_per_uid;
5621473Smckusick }
5721473Smckusick
5821473Smckusick uid = getuid();
5921473Smckusick if (Top[MAXSCORES-1].s_score <= Score) {
6021473Smckusick numscores = 0;
6121473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++)
6221473Smckusick if (scp->s_score < 0 ||
6321473Smckusick (scp->s_uid == uid && ++numscores == max_uid)) {
6421473Smckusick if (scp->s_score > Score)
6521473Smckusick break;
6621473Smckusick scp->s_score = Score;
6721473Smckusick scp->s_uid = uid;
6821473Smckusick set_name(scp);
6921473Smckusick Newscore = TRUE;
7021473Smckusick break;
7121473Smckusick }
7221473Smckusick if (scp == &Top[MAXSCORES]) {
7321473Smckusick Top[MAXSCORES-1].s_score = Score;
7421473Smckusick Top[MAXSCORES-1].s_uid = uid;
7521473Smckusick set_name(&Top[MAXSCORES-1]);
7621473Smckusick Newscore = TRUE;
7721473Smckusick }
7821473Smckusick if (Newscore)
7921473Smckusick qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc);
8021473Smckusick }
8121473Smckusick
8221473Smckusick if (!Newscore) {
8321473Smckusick Full_clear = FALSE;
8421473Smckusick close(inf);
8521473Smckusick return;
8621473Smckusick }
8721473Smckusick else
8821473Smckusick Full_clear = TRUE;
8921473Smckusick
9021473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++) {
9121473Smckusick if (scp->s_score < 0)
9221473Smckusick break;
9321473Smckusick move((scp - Top) + 1, 15);
9421473Smckusick if (!done_show && scp->s_uid == uid && scp->s_score == Score)
9521473Smckusick standout();
9621473Smckusick printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name);
9721473Smckusick if (!done_show && scp->s_uid == uid && scp->s_score == Score) {
9821473Smckusick standend();
9921473Smckusick done_show = TRUE;
10021473Smckusick }
10121473Smckusick }
10221473Smckusick Num_scores = scp - Top;
10321473Smckusick refresh();
10421473Smckusick
10521473Smckusick if (Newscore) {
10621473Smckusick lseek(inf, 0L, 0);
10721473Smckusick write(inf, &max_uid, sizeof max_uid);
10821473Smckusick write(inf, Top, sizeof Top);
10921473Smckusick }
11021473Smckusick close(inf);
11121473Smckusick }
11221473Smckusick
set_name(scp)11321473Smckusick set_name(scp)
11421473Smckusick register SCORE *scp;
11521473Smckusick {
11621473Smckusick register PASSWD *pp;
11721473Smckusick
11821473Smckusick if ((pp = getpwuid(scp->s_uid)) == NULL)
11921473Smckusick pp->pw_name = "???";
12021473Smckusick strncpy(scp->s_name, pp->pw_name, MAXNAME);
12121473Smckusick }
12221473Smckusick
12321473Smckusick /*
12421473Smckusick * cmp_sc:
12521473Smckusick * Compare two scores.
12621473Smckusick */
cmp_sc(s1,s2)12721473Smckusick cmp_sc(s1, s2)
12821473Smckusick register SCORE *s1, *s2;
12921473Smckusick {
13021473Smckusick return s2->s_score - s1->s_score;
13121473Smckusick }
13221473Smckusick
13321473Smckusick /*
13421473Smckusick * show_score:
13521473Smckusick * Show the score list for the '-s' option.
13621473Smckusick */
show_score()13721473Smckusick show_score()
13821473Smckusick {
13921473Smckusick register SCORE *scp;
14021473Smckusick register int inf;
14121473Smckusick static int max_score;
14221473Smckusick
14321473Smckusick if ((inf = open(Scorefile, 0)) < 0) {
14421473Smckusick perror(Scorefile);
14521473Smckusick return;
14621473Smckusick }
14721473Smckusick
14821473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++)
14921473Smckusick scp->s_score = -1;
15021473Smckusick
15121473Smckusick read(inf, &max_score, sizeof max_score);
15221473Smckusick read(inf, Top, sizeof Top);
15321473Smckusick close(inf);
15421473Smckusick inf = 1;
15521473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++)
15621473Smckusick if (scp->s_score >= 0)
15721473Smckusick printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name);
15821473Smckusick }
159