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