141166Sbostic /*-
2*60740Sbostic * Copyright (c) 1990, 1993
3*60740Sbostic * The Regents of the University of California. All rights reserved.
441166Sbostic *
541166Sbostic * This code is derived from software contributed to Berkeley by
641166Sbostic * Ed James.
741166Sbostic *
841166Sbostic * %sccs.include.redist.c%
941166Sbostic */
1041166Sbostic
1132473Sbostic /*
1232473Sbostic * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
1332473Sbostic *
1432473Sbostic * Copy permission is hereby granted provided that this notice is
1532473Sbostic * retained on all partial or complete copies.
1632473Sbostic *
1732473Sbostic * For more info on this and all of my stuff, mail edjames@berkeley.edu.
1832473Sbostic */
1932473Sbostic
2032473Sbostic #ifndef lint
21*60740Sbostic static char sccsid[] = "@(#)log.c 8.1 (Berkeley) 05/31/93";
2232473Sbostic #endif not lint
2332473Sbostic
2432473Sbostic #include "include.h"
2541165Sbostic #include "pathnames.h"
2632473Sbostic
compar(a,b)2732473Sbostic compar(a, b)
2832473Sbostic SCORE *a, *b;
2932473Sbostic {
3032473Sbostic if (b->planes == a->planes)
3132473Sbostic return (b->time - a->time);
3232473Sbostic else
3332473Sbostic return (b->planes - a->planes);
3432473Sbostic }
3532473Sbostic
3632473Sbostic #define SECAMIN 60
3732473Sbostic #define MINAHOUR 60
3832473Sbostic #define HOURADAY 24
3932473Sbostic #define SECAHOUR (SECAMIN * MINAHOUR)
4032473Sbostic #define SECADAY (SECAHOUR * HOURADAY)
4132473Sbostic #define DAY(t) ((t) / SECADAY)
4232473Sbostic #define HOUR(t) (((t) % SECADAY) / SECAHOUR)
4332473Sbostic #define MIN(t) (((t) % SECAHOUR) / SECAMIN)
4432473Sbostic #define SEC(t) ((t) % SECAMIN)
4532473Sbostic
4632473Sbostic char *
timestr(t)4732473Sbostic timestr(t)
4832473Sbostic {
4932473Sbostic static char s[80];
5032473Sbostic
5132473Sbostic if (DAY(t) > 0)
5232474Sbostic (void)sprintf(s, "%dd+%02dhrs", DAY(t), HOUR(t));
5332473Sbostic else if (HOUR(t) > 0)
5432474Sbostic (void)sprintf(s, "%d:%02d:%02d", HOUR(t), MIN(t), SEC(t));
5532473Sbostic else if (MIN(t) > 0)
5632474Sbostic (void)sprintf(s, "%d:%02d", MIN(t), SEC(t));
5732473Sbostic else if (SEC(t) > 0)
5832474Sbostic (void)sprintf(s, ":%02d", SEC(t));
5932473Sbostic else
6032473Sbostic *s = '\0';
6132473Sbostic
6232473Sbostic return (s);
6332473Sbostic }
6432473Sbostic
log_score(list_em)6532473Sbostic log_score(list_em)
6632473Sbostic {
6732473Sbostic register int i, fd, num_scores = 0, good, changed = 0, found = 0;
6832473Sbostic struct passwd *pw;
6932473Sbostic FILE *fp;
7041165Sbostic char *cp, *index(), *rindex();
7132473Sbostic SCORE score[100], thisscore;
7232473Sbostic #ifdef SYSV
7332473Sbostic struct utsname name;
7432473Sbostic #endif
7532473Sbostic
7632473Sbostic umask(0);
7741165Sbostic fd = open(_PATH_SCORE, O_CREAT|O_RDWR, 0644);
7832473Sbostic if (fd < 0) {
7941165Sbostic perror(_PATH_SCORE);
8032473Sbostic return (-1);
8132473Sbostic }
8232473Sbostic /*
8332473Sbostic * This is done to take advantage of stdio, while still
8432473Sbostic * allowing a O_CREAT during the open(2) of the log file.
8532473Sbostic */
8632473Sbostic fp = fdopen(fd, "r+");
8732473Sbostic if (fp == NULL) {
8841165Sbostic perror(_PATH_SCORE);
8932473Sbostic return (-1);
9032473Sbostic }
9132473Sbostic #ifdef BSD
9232473Sbostic if (flock(fileno(fp), LOCK_EX) < 0)
9332473Sbostic #endif
9432473Sbostic #ifdef SYSV
9532473Sbostic while (lockf(fileno(fp), F_LOCK, 1) < 0)
9632473Sbostic #endif
9732473Sbostic {
9832473Sbostic perror("flock");
9932473Sbostic return (-1);
10032473Sbostic }
10132473Sbostic for (;;) {
10232473Sbostic good = fscanf(fp, "%s %s %s %d %d %d",
10332473Sbostic score[num_scores].name,
10432473Sbostic score[num_scores].host,
10532473Sbostic score[num_scores].game,
10632473Sbostic &score[num_scores].planes,
10732473Sbostic &score[num_scores].time,
10832473Sbostic &score[num_scores].real_time);
10932473Sbostic if (good != 6 || ++num_scores >= NUM_SCORES)
11032473Sbostic break;
11132473Sbostic }
11232473Sbostic if (!test_mode && !list_em) {
11332473Sbostic if ((pw = (struct passwd *) getpwuid(getuid())) == NULL) {
11432473Sbostic fprintf(stderr,
11532473Sbostic "getpwuid failed for uid %d. Who are you?\n",
11632473Sbostic getuid());
11732473Sbostic return (-1);
11832473Sbostic }
11932473Sbostic strcpy(thisscore.name, pw->pw_name);
12032473Sbostic #ifdef BSD
12132473Sbostic if (gethostname(thisscore.host, sizeof (thisscore.host)) < 0) {
12232473Sbostic perror("gethostname");
12332473Sbostic return (-1);
12432473Sbostic }
12532473Sbostic #endif
12632473Sbostic #ifdef SYSV
12732473Sbostic uname(&name);
12832473Sbostic strcpy(thisscore.host, name.sysname);
12932473Sbostic #endif
13032473Sbostic
13132473Sbostic cp = rindex(file, '/');
13232473Sbostic if (cp == NULL) {
13332473Sbostic fprintf(stderr, "log: where's the '/' in %s?\n", file);
13432473Sbostic return (-1);
13532473Sbostic }
13632473Sbostic cp++;
13732473Sbostic strcpy(thisscore.game, cp);
13832473Sbostic
13945433Sbostic thisscore.time = clck;
14032473Sbostic thisscore.planes = safe_planes;
14132473Sbostic thisscore.real_time = time(0) - start_time;
14232473Sbostic
14332473Sbostic for (i = 0; i < num_scores; i++) {
14432473Sbostic if (strcmp(thisscore.name, score[i].name) == 0 &&
14532473Sbostic strcmp(thisscore.host, score[i].host) == 0 &&
14632473Sbostic strcmp(thisscore.game, score[i].game) == 0) {
14732473Sbostic if (thisscore.time > score[i].time) {
14832473Sbostic score[i].time = thisscore.time;
14932473Sbostic score[i].planes = thisscore.planes;
15033050Sbostic score[i].real_time =
15133050Sbostic thisscore.real_time;
15232473Sbostic changed++;
15332473Sbostic }
15432473Sbostic found++;
15532473Sbostic break;
15632473Sbostic }
15732473Sbostic }
15832473Sbostic if (!found) {
15932473Sbostic for (i = 0; i < num_scores; i++) {
16032473Sbostic if (thisscore.time > score[i].time) {
16132473Sbostic if (num_scores < NUM_SCORES)
16232473Sbostic num_scores++;
16332473Sbostic bcopy(&score[i],
16432473Sbostic &score[num_scores - 1],
16532473Sbostic sizeof (score[i]));
16632473Sbostic bcopy(&thisscore, &score[i],
16732473Sbostic sizeof (score[i]));
16832473Sbostic changed++;
16932473Sbostic break;
17032473Sbostic }
17132473Sbostic }
17232473Sbostic }
17332473Sbostic if (!found && !changed && num_scores < NUM_SCORES) {
17432473Sbostic bcopy(&thisscore, &score[num_scores],
17532473Sbostic sizeof (score[num_scores]));
17632473Sbostic num_scores++;
17732473Sbostic changed++;
17832473Sbostic }
17932473Sbostic
18032473Sbostic if (changed) {
18132473Sbostic if (found)
18232473Sbostic puts("You beat your previous score!");
18332473Sbostic else
18432473Sbostic puts("You made the top players list!");
18532473Sbostic qsort(score, num_scores, sizeof (*score), compar);
18632473Sbostic rewind(fp);
18732473Sbostic for (i = 0; i < num_scores; i++)
18832473Sbostic fprintf(fp, "%s %s %s %d %d %d\n",
18932473Sbostic score[i].name, score[i].host,
19032473Sbostic score[i].game, score[i].planes,
19132473Sbostic score[i].time, score[i].real_time);
19232473Sbostic } else {
19332473Sbostic if (found)
19432473Sbostic puts("You didn't beat your previous score.");
19532473Sbostic else
19632473Sbostic puts("You didn't make the top players list.");
19732473Sbostic }
19832473Sbostic putchar('\n');
19932473Sbostic }
20032473Sbostic #ifdef BSD
20132473Sbostic flock(fileno(fp), LOCK_UN);
20232473Sbostic #endif
20332473Sbostic #ifdef SYSV
20432473Sbostic /* lock will evaporate upon close */
20532473Sbostic #endif
20632473Sbostic fclose(fp);
20732473Sbostic printf("%2s: %-8s %-8s %-18s %4s %9s %4s\n", "#", "name", "host",
20832473Sbostic "game", "time", "real time", "planes safe");
20932473Sbostic puts("-------------------------------------------------------------------------------");
21032473Sbostic for (i = 0; i < num_scores; i++) {
21132473Sbostic cp = index(score[i].host, '.');
21232473Sbostic if (cp != NULL)
21332473Sbostic *cp = '\0';
21432473Sbostic printf("%2d: %-8s %-8s %-18s %4d %9s %4d\n", i + 1,
21532473Sbostic score[i].name, score[i].host, score[i].game,
21632473Sbostic score[i].time, timestr(score[i].real_time),
21732473Sbostic score[i].planes);
21832473Sbostic }
21932473Sbostic putchar('\n');
22032473Sbostic return (0);
22132473Sbostic }
222