1 /*- 2 * Copyright (c) 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Ed James. 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 /* 38 * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. 39 * 40 * Copy permission is hereby granted provided that this notice is 41 * retained on all partial or complete copies. 42 * 43 * For more info on this and all of my stuff, mail edjames@berkeley.edu. 44 */ 45 46 #ifndef lint 47 static char sccsid[] = "@(#)log.c 5.7 (Berkeley) 10/30/90"; 48 #endif not lint 49 50 #include "include.h" 51 #include "pathnames.h" 52 53 compar(a, b) 54 SCORE *a, *b; 55 { 56 if (b->planes == a->planes) 57 return (b->time - a->time); 58 else 59 return (b->planes - a->planes); 60 } 61 62 #define SECAMIN 60 63 #define MINAHOUR 60 64 #define HOURADAY 24 65 #define SECAHOUR (SECAMIN * MINAHOUR) 66 #define SECADAY (SECAHOUR * HOURADAY) 67 #define DAY(t) ((t) / SECADAY) 68 #define HOUR(t) (((t) % SECADAY) / SECAHOUR) 69 #define MIN(t) (((t) % SECAHOUR) / SECAMIN) 70 #define SEC(t) ((t) % SECAMIN) 71 72 char * 73 timestr(t) 74 { 75 static char s[80]; 76 77 if (DAY(t) > 0) 78 (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t)); 79 else if (HOUR(t) > 0) 80 (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t)); 81 else if (MIN(t) > 0) 82 (void)sprintf(s, "%d:%02d", MIN(t), SEC(t)); 83 else if (SEC(t) > 0) 84 (void)sprintf(s, ":%02d", SEC(t)); 85 else 86 *s = '\0'; 87 88 return (s); 89 } 90 91 log_score(list_em) 92 { 93 register int i, fd, num_scores = 0, good, changed = 0, found = 0; 94 struct passwd *pw; 95 FILE *fp; 96 char *cp, *index(), *rindex(); 97 SCORE score[100], thisscore; 98 #ifdef SYSV 99 struct utsname name; 100 #endif 101 102 umask(0); 103 fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644); 104 if (fd < 0) { 105 perror(_PATH_SCORE); 106 return (-1); 107 } 108 /* 109 * This is done to take advantage of stdio, while still 110 * allowing a O_CREAT during the open(2) of the log file. 111 */ 112 fp = fdopen(fd, "r+"); 113 if (fp == NULL) { 114 perror(_PATH_SCORE); 115 return (-1); 116 } 117 #ifdef BSD 118 if (flock(fileno(fp), LOCK_EX) < 0) 119 #endif 120 #ifdef SYSV 121 while (lockf(fileno(fp), F_LOCK, 1) < 0) 122 #endif 123 { 124 perror("flock"); 125 return (-1); 126 } 127 for (;;) { 128 good = fscanf(fp, "%s %s %s %d %d %d", 129 score[num_scores].name, 130 score[num_scores].host, 131 score[num_scores].game, 132 &score[num_scores].planes, 133 &score[num_scores].time, 134 &score[num_scores].real_time); 135 if (good != 6 || ++num_scores >= NUM_SCORES) 136 break; 137 } 138 if (!test_mode && !list_em) { 139 if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) { 140 fprintf(stderr, 141 "getpwuid failed for uid %d. Who are you?\n", 142 getuid()); 143 return (-1); 144 } 145 strcpy(thisscore.name, pw->pw_name); 146 #ifdef BSD 147 if (gethostname(thisscore.host, sizeof (thisscore.host)) < 0) { 148 perror("gethostname"); 149 return (-1); 150 } 151 #endif 152 #ifdef SYSV 153 uname(&name); 154 strcpy(thisscore.host, name.sysname); 155 #endif 156 157 cp = rindex(file, '/'); 158 if (cp == NULL) { 159 fprintf(stderr, "log: where's the '/' in %s?\n", file); 160 return (-1); 161 } 162 cp++; 163 strcpy(thisscore.game, cp); 164 165 thisscore.time = clck; 166 thisscore.planes = safe_planes; 167 thisscore.real_time = time(0) - start_time; 168 169 for (i = 0; i < num_scores; i++) { 170 if (strcmp(thisscore.name, score[i].name) == 0 && 171 strcmp(thisscore.host, score[i].host) == 0 && 172 strcmp(thisscore.game, score[i].game) == 0) { 173 if (thisscore.time > score[i].time) { 174 score[i].time = thisscore.time; 175 score[i].planes = thisscore.planes; 176 score[i].real_time = 177 thisscore.real_time; 178 changed++; 179 } 180 found++; 181 break; 182 } 183 } 184 if (!found) { 185 for (i = 0; i < num_scores; i++) { 186 if (thisscore.time > score[i].time) { 187 if (num_scores < NUM_SCORES) 188 num_scores++; 189 bcopy(&score[i], 190 &score[num_scores - 1], 191 sizeof (score[i])); 192 bcopy(&thisscore, &score[i], 193 sizeof (score[i])); 194 changed++; 195 break; 196 } 197 } 198 } 199 if (!found && !changed && num_scores < NUM_SCORES) { 200 bcopy(&thisscore, &score[num_scores], 201 sizeof (score[num_scores])); 202 num_scores++; 203 changed++; 204 } 205 206 if (changed) { 207 if (found) 208 puts("You beat your previous score!"); 209 else 210 puts("You made the top players list!"); 211 qsort(score, num_scores, sizeof (*score), compar); 212 rewind(fp); 213 for (i = 0; i < num_scores; i++) 214 fprintf(fp, "%s %s %s %d %d %d\n", 215 score[i].name, score[i].host, 216 score[i].game, score[i].planes, 217 score[i].time, score[i].real_time); 218 } else { 219 if (found) 220 puts("You didn't beat your previous score."); 221 else 222 puts("You didn't make the top players list."); 223 } 224 putchar('\n'); 225 } 226 #ifdef BSD 227 flock(fileno(fp), LOCK_UN); 228 #endif 229 #ifdef SYSV 230 /* lock will evaporate upon close */ 231 #endif 232 fclose(fp); 233 printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", "host", 234 "game", "time", "real time", "planes safe"); 235 puts("-------------------------------------------------------------------------------"); 236 for (i = 0; i < num_scores; i++) { 237 cp = index(score[i].host, '.'); 238 if (cp != NULL) 239 *cp = '\0'; 240 printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1, 241 score[i].name, score[i].host, score[i].game, 242 score[i].time, timestr(score[i].real_time), 243 score[i].planes); 244 } 245 putchar('\n'); 246 return (0); 247 } 248