121473Smckusick /* 221473Smckusick * Copyright (c) 1980 Regents of the University of California. 3*33690Sbostic * All rights reserved. 4*33690Sbostic * 5*33690Sbostic * Redistribution and use in source and binary forms are permitted 6*33690Sbostic * provided that this notice is preserved and that due credit is given 7*33690Sbostic * to the University of California at Berkeley. The name of the University 8*33690Sbostic * may not be used to endorse or promote products derived from this 9*33690Sbostic * software without specific prior written permission. This software 10*33690Sbostic * is provided ``as is'' without express or implied warranty. 1121473Smckusick */ 1221473Smckusick 1321473Smckusick #ifndef lint 14*33690Sbostic static char sccsid[] = "@(#)score.c 5.2 (Berkeley) 03/09/88"; 15*33690Sbostic #endif /* not lint */ 1621473Smckusick 1721473Smckusick # include "robots.h" 1821473Smckusick # include <pwd.h> 1921473Smckusick 2021473Smckusick typedef struct { 2121473Smckusick int s_uid; 2221473Smckusick int s_score; 2321473Smckusick char s_name[MAXNAME]; 2421473Smckusick } SCORE; 2521473Smckusick 2621473Smckusick typedef struct passwd PASSWD; 2721473Smckusick 2821473Smckusick char *Scorefile = SCOREFILE; 2921473Smckusick 3021473Smckusick int Max_per_uid = MAX_PER_UID; 3121473Smckusick 3221473Smckusick static SCORE Top[MAXSCORES]; 3321473Smckusick 3421473Smckusick /* 3521473Smckusick * score: 3621473Smckusick * Post the player's score, if reasonable, and then print out the 3721473Smckusick * top list. 3821473Smckusick */ 3921473Smckusick score() 4021473Smckusick { 4121473Smckusick register int inf; 4221473Smckusick register SCORE *scp; 4321473Smckusick register int uid; 4421473Smckusick register bool done_show = FALSE; 4521473Smckusick static int numscores, max_uid; 4621473Smckusick 4721473Smckusick Newscore = FALSE; 4821473Smckusick if ((inf = open(Scorefile, 2)) < 0) { 4921473Smckusick perror(Scorefile); 5021473Smckusick return; 5121473Smckusick } 5221473Smckusick 5321473Smckusick if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid) 5421473Smckusick read(inf, Top, sizeof Top); 5521473Smckusick else { 5621473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++) 5721473Smckusick scp->s_score = -1; 5821473Smckusick max_uid = Max_per_uid; 5921473Smckusick } 6021473Smckusick 6121473Smckusick uid = getuid(); 6221473Smckusick if (Top[MAXSCORES-1].s_score <= Score) { 6321473Smckusick numscores = 0; 6421473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++) 6521473Smckusick if (scp->s_score < 0 || 6621473Smckusick (scp->s_uid == uid && ++numscores == max_uid)) { 6721473Smckusick if (scp->s_score > Score) 6821473Smckusick break; 6921473Smckusick scp->s_score = Score; 7021473Smckusick scp->s_uid = uid; 7121473Smckusick set_name(scp); 7221473Smckusick Newscore = TRUE; 7321473Smckusick break; 7421473Smckusick } 7521473Smckusick if (scp == &Top[MAXSCORES]) { 7621473Smckusick Top[MAXSCORES-1].s_score = Score; 7721473Smckusick Top[MAXSCORES-1].s_uid = uid; 7821473Smckusick set_name(&Top[MAXSCORES-1]); 7921473Smckusick Newscore = TRUE; 8021473Smckusick } 8121473Smckusick if (Newscore) 8221473Smckusick qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc); 8321473Smckusick } 8421473Smckusick 8521473Smckusick if (!Newscore) { 8621473Smckusick Full_clear = FALSE; 8721473Smckusick close(inf); 8821473Smckusick return; 8921473Smckusick } 9021473Smckusick else 9121473Smckusick Full_clear = TRUE; 9221473Smckusick 9321473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++) { 9421473Smckusick if (scp->s_score < 0) 9521473Smckusick break; 9621473Smckusick move((scp - Top) + 1, 15); 9721473Smckusick if (!done_show && scp->s_uid == uid && scp->s_score == Score) 9821473Smckusick standout(); 9921473Smckusick printw(" %d\t%d\t%-8.8s ", (scp - Top) + 1, scp->s_score, scp->s_name); 10021473Smckusick if (!done_show && scp->s_uid == uid && scp->s_score == Score) { 10121473Smckusick standend(); 10221473Smckusick done_show = TRUE; 10321473Smckusick } 10421473Smckusick } 10521473Smckusick Num_scores = scp - Top; 10621473Smckusick refresh(); 10721473Smckusick 10821473Smckusick if (Newscore) { 10921473Smckusick lseek(inf, 0L, 0); 11021473Smckusick write(inf, &max_uid, sizeof max_uid); 11121473Smckusick write(inf, Top, sizeof Top); 11221473Smckusick } 11321473Smckusick close(inf); 11421473Smckusick } 11521473Smckusick 11621473Smckusick set_name(scp) 11721473Smckusick register SCORE *scp; 11821473Smckusick { 11921473Smckusick register PASSWD *pp; 12021473Smckusick 12121473Smckusick if ((pp = getpwuid(scp->s_uid)) == NULL) 12221473Smckusick pp->pw_name = "???"; 12321473Smckusick strncpy(scp->s_name, pp->pw_name, MAXNAME); 12421473Smckusick } 12521473Smckusick 12621473Smckusick /* 12721473Smckusick * cmp_sc: 12821473Smckusick * Compare two scores. 12921473Smckusick */ 13021473Smckusick cmp_sc(s1, s2) 13121473Smckusick register SCORE *s1, *s2; 13221473Smckusick { 13321473Smckusick return s2->s_score - s1->s_score; 13421473Smckusick } 13521473Smckusick 13621473Smckusick /* 13721473Smckusick * show_score: 13821473Smckusick * Show the score list for the '-s' option. 13921473Smckusick */ 14021473Smckusick show_score() 14121473Smckusick { 14221473Smckusick register SCORE *scp; 14321473Smckusick register int inf; 14421473Smckusick static int max_score; 14521473Smckusick 14621473Smckusick if ((inf = open(Scorefile, 0)) < 0) { 14721473Smckusick perror(Scorefile); 14821473Smckusick return; 14921473Smckusick } 15021473Smckusick 15121473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++) 15221473Smckusick scp->s_score = -1; 15321473Smckusick 15421473Smckusick read(inf, &max_score, sizeof max_score); 15521473Smckusick read(inf, Top, sizeof Top); 15621473Smckusick close(inf); 15721473Smckusick inf = 1; 15821473Smckusick for (scp = Top; scp < &Top[MAXSCORES]; scp++) 15921473Smckusick if (scp->s_score >= 0) 16021473Smckusick printf("%d\t%d\t%.*s\n", inf++, scp->s_score, sizeof scp->s_name, scp->s_name); 16121473Smckusick } 162