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