Commit | Line | Data |
---|---|---|
e04f5cf8 KB |
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 | ||
58d1eeab KB |
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 | |
55900916 | 21 | static char sccsid[] = "@(#)log.c 5.7 (Berkeley) %G%"; |
58d1eeab KB |
22 | #endif not lint |
23 | ||
24 | #include "include.h" | |
3e3e3488 | 25 | #include "pathnames.h" |
58d1eeab KB |
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) | |
44de9b23 | 52 | (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t)); |
58d1eeab | 53 | else if (HOUR(t) > 0) |
44de9b23 | 54 | (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t)); |
58d1eeab | 55 | else if (MIN(t) > 0) |
44de9b23 | 56 | (void)sprintf(s, "%d:%02d", MIN(t), SEC(t)); |
58d1eeab | 57 | else if (SEC(t) > 0) |
44de9b23 | 58 | (void)sprintf(s, ":%02d", SEC(t)); |
58d1eeab KB |
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; | |
3e3e3488 | 70 | char *cp, *index(), *rindex(); |
58d1eeab KB |
71 | SCORE score[100], thisscore; |
72 | #ifdef SYSV | |
73 | struct utsname name; | |
74 | #endif | |
75 | ||
58d1eeab | 76 | umask(0); |
3e3e3488 | 77 | fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644); |
58d1eeab | 78 | if (fd < 0) { |
3e3e3488 | 79 | perror(_PATH_SCORE); |
58d1eeab KB |
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) { | |
3e3e3488 | 88 | perror(_PATH_SCORE); |
58d1eeab KB |
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 | ||
55900916 | 139 | thisscore.time = clck; |
58d1eeab KB |
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; | |
04492df2 KB |
150 | score[i].real_time = |
151 | thisscore.real_time; | |
58d1eeab KB |
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 | } |