xref: /csrg-svn/games/atc/log.c (revision 60740)
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