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