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