score.c revision 1.4
1/* $OpenBSD: score.c,v 1.4 1998/07/09 04:34:25 pjanzen Exp $ */ 2/* $NetBSD: score.c,v 1.3 1995/04/22 10:09:12 cgd Exp $ */ 3 4/* 5 * Copyright (c) 1980, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38#if 0 39static char sccsid[] = "@(#)score.c 8.1 (Berkeley) 5/31/93"; 40#else 41static char rcsid[] = "$OpenBSD: score.c,v 1.4 1998/07/09 04:34:25 pjanzen Exp $"; 42#endif 43#endif /* not lint */ 44 45#include "robots.h" 46#include "pathnames.h" 47 48char *Scorefile = _PATH_SCORE; 49 50#ifndef MAX_PER_UID 51#define MAX_PER_UID 5 52#endif 53 54int Max_per_uid = MAX_PER_UID; 55 56static SCORE Top[MAXSCORES]; 57 58/* 59 * score: 60 * Post the player's score, if reasonable, and then print out the 61 * top list. 62 */ 63void 64score(score_wfd) 65 int score_wfd; 66{ 67 register int inf = score_wfd; 68 register SCORE *scp; 69 uid_t uid; 70 register bool done_show = FALSE; 71 static int numscores, max_uid; 72 73 Newscore = FALSE; 74 75 if (read(inf, &max_uid, sizeof max_uid) == sizeof max_uid) 76 read(inf, Top, sizeof Top); 77 else { 78 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 79 scp->s_score = -1; 80 max_uid = Max_per_uid; 81 } 82 83 uid = getuid(); 84 if (Top[MAXSCORES-1].s_score <= Score) { 85 numscores = 0; 86 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 87 if (scp->s_score < 0 || 88 (scp->s_uid == uid && ++numscores == max_uid)) { 89 if (scp->s_score > Score) 90 break; 91 scp->s_score = Score; 92 scp->s_uid = uid; 93 set_name(scp); 94 Newscore = TRUE; 95 break; 96 } 97 if (scp == &Top[MAXSCORES]) { 98 Top[MAXSCORES-1].s_score = Score; 99 Top[MAXSCORES-1].s_uid = uid; 100 set_name(&Top[MAXSCORES-1]); 101 Newscore = TRUE; 102 } 103 if (Newscore) 104 qsort(Top, MAXSCORES, sizeof Top[0], cmp_sc); 105 } 106 107 if (!Newscore) { 108 Full_clear = FALSE; 109 fsync(inf); 110 lseek(inf, 0, SEEK_SET); 111 return; 112 } 113 else 114 Full_clear = TRUE; 115 116 for (scp = Top; scp < &Top[MAXSCORES]; scp++) { 117 if (scp->s_score < 0) 118 break; 119 move((scp - Top) + 1, 15); 120 if (!done_show && scp->s_uid == uid && scp->s_score == Score) 121 standout(); 122 printw(" %d\t%d\t%-*s ", (scp - Top) + 1, scp->s_score, 123 (int)(sizeof scp->s_name), scp->s_name); 124 if (!done_show && scp->s_uid == uid && scp->s_score == Score) { 125 standend(); 126 done_show = TRUE; 127 } 128 } 129 Num_scores = scp - Top; 130 refresh(); 131 132 if (Newscore) { 133 lseek(inf, 0L, SEEK_SET); 134 write(inf, &max_uid, sizeof max_uid); 135 write(inf, Top, sizeof Top); 136 } 137 fsync(inf); 138 lseek(inf, 0, SEEK_SET); 139} 140 141void 142set_name(scp) 143 SCORE *scp; 144{ 145 PASSWD *pp; 146 147 if ((pp = getpwuid(scp->s_uid)) == NULL) 148 pp->pw_name = "???"; 149 strncpy(scp->s_name, pp->pw_name, MAXNAME); 150} 151 152/* 153 * cmp_sc: 154 * Compare two scores. 155 */ 156int 157cmp_sc(s1, s2) 158 const void *s1, *s2; 159{ 160 return ((SCORE *)s2)->s_score - ((SCORE *)s1)->s_score; 161} 162 163/* 164 * show_score: 165 * Show the score list for the '-s' option. 166 */ 167void 168show_score() 169{ 170 register SCORE *scp; 171 register int inf; 172 static int max_score; 173 174 if ((inf = open(Scorefile, O_RDONLY)) < 0) { 175 perror(Scorefile); 176 return; 177 } 178 179 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 180 scp->s_score = -1; 181 182 read(inf, &max_score, sizeof max_score); 183 read(inf, Top, sizeof Top); 184 close(inf); 185 inf = 1; 186 for (scp = Top; scp < &Top[MAXSCORES]; scp++) 187 if (scp->s_score >= 0) 188 printf("%d\t%d\t%.*s\n", inf++, scp->s_score, 189 (int)(sizeof scp->s_name), scp->s_name); 190} 191