1 /*
2  *	xtrojka (c) 1994,1995,1996 Maarten Los
3  *
4  *	#include "COPYRIGHT"
5  *
6  *	created:	26.xi.1995
7  *	modified:
8  *
9  *	This module does atomic score handling
10  */
11 
12 
13 #include "debug.h"
14 #include "tr_core.h"
15 
16 #include "_strdefs.h"
17 
18 #include <errno.h>
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include <sys/time.h>
22 #include <sys/uio.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <pwd.h>
26 #include <time.h>
27 #include "xtrojka.h"
28 #include "scores.h"
29 #include "slist.h"
30 #include "sh_slist.h"
31 
32 
33 SCORES scores[NUMSCORES];
34 SCORES old_scores[NUMSCORES];
35 SCORES cur;
36 
37 
38 extern flag is_wizard;
39 extern time_t last_time;
40 
41 
42 int position;
43 
44 
init_scores(void)45 void init_scores(void)
46 {
47 	DEBUG("scores.c", "init_scores")
48 
49 	read_scores();
50 }
51 
52 
do_hiscores(void)53 void do_hiscores(void)
54 {
55 	char hostname[20];
56 
57 	DEBUG("scores.c", "do_hiscores")
58 
59 	position = NUMSCORES+1;
60 
61 	copy_oldscores();
62 	read_scores();
63 
64 	/* see if there is a highscore */
65 	if(is_hiscore()) {
66 
67 		shift_scores();
68 
69 		gethostname(hostname,20);
70 
71 		scores[position].score = tv_score;
72 		scores[position].date = time(0);
73 		scores[position].speed = tv_speed;
74 		scores[position].user = getuid();
75 		scores[position].wizard = is_wizard;
76 		strcpy(scores[position].host, hostname);
77 		memcpy((char*)&cur, (char*)&scores[position], sizeof(cur));
78 
79 		write_scores();
80 		utime(SCOREFILE, NULL);
81 		sleep(1);
82 		last_time = 0;
83 		file_changed(SCOREFILE);
84 
85 	} else {
86 		memset((char*)&cur, 0, sizeof(cur));
87 	}
88 	compare_scores();
89 
90 	draw_slist(kFORCED);
91 }
92 
93 
is_hiscore(void)94 flag is_hiscore(void)
95 {
96 	int i;
97 
98 	DEBUG("scores.c", "is_hiscore")
99 
100 	for(i = 0; i < NUMSCORES; i++)
101 		if(tv_score > scores[i].score) {
102 			position = i;
103 			return 1;
104 		}
105 	return 0;
106 }
107 
108 
shift_scores(void)109 void shift_scores(void)
110 {
111 	int i;
112 
113 	DEBUG("scores.c", "shift_scores")
114 
115 	for(i = NUMSCORES-1; i > position; i--)
116 		scores[i] = scores[i-1];
117 }
118 
119 
read_scores(void)120 void read_scores(void)
121 {
122 	int i;
123 	int fd;
124 
125 	DEBUG("scores.c", "read_scores")
126 
127 	/* clear scores */
128 	for(i = 0; i < NUMSCORES; i++) {
129 		scores[i].score = NO_SCORE;
130 	}
131 
132 	if((fd = open(SCOREFILE, O_RDONLY)) < 0) {
133 		create_scorefile();
134 		write_scores();
135 	} else
136 	if(read(fd, scores, sizeof(scores)) < 0)
137 		fprintf(stderr,"%s\n", STR_R_SCORES);
138 
139 	if(fd >= 0)
140 		close(fd);
141 }
142 
143 
144 
write_scores(void)145 void write_scores(void)
146 {
147 	int fd;
148 
149 	DEBUG("scores.c", "write_scores")
150 
151 	DEBUG("scores.c", "write_scores A")
152 	if((fd = open(SCOREFILE, O_WRONLY)) < 0)  {
153 		fprintf(stderr,"%s (%s)\n", STR_O_SCORES, SCOREFILE);
154 	}
155 
156 #ifdef LOCKING
157 	DEBUG("scores.c", "write_scores")
158 	if(lockf(fd, F_LOCK, sizeof(scores)) < 0)
159 		fprintf(stderr,"%s (%d)\n", STR_L_SCORES, errno);
160 #endif
161 	DEBUG("scores.c", "write_scores B")
162 	if(write(fd, scores, sizeof(scores)) < 0)
163 		fprintf(stderr,"%s (%s)\n", STR_W_SCORES, SCOREFILE);
164 
165 	if(fd >= 0)
166 		close(fd);
167 }
168 
169 
create_scorefile(void)170 void create_scorefile(void)
171 {
172 	int fd;
173 	int oldumask = umask(0);
174 
175 	DEBUG("scores.c", "create_scorefile")
176 
177 	if((fd = creat(SCOREFILE, 0666)) < 0)
178 		fprintf(stderr,"%s (%s)\n", STR_C_SCORES,
179 			SCOREFILE);
180 
181 	umask(oldumask);
182 
183 	if(fd >= 0)
184 		close(fd);
185 }
186 
187 
show_scores_offline(void)188 void show_scores_offline(void)
189 {
190 	int i;
191 	char date_st[30];
192 	char user_st[30];
193 	char string[100];
194 	struct passwd *pw;
195 
196 	DEBUG("scores.c", "show_scores_offline")
197 
198 	for(i = 0;  i < NUMSCORES; i++) {
199 		if(scores[i].score == 0)
200 			break;
201 		strcpy(date_st, ctime(&(scores[i].date)));
202 		date_st[strlen(date_st)-1] = '\0';
203 		pw = getpwuid(scores[i].user);
204 		if(pw)
205 			strcpy(user_st, pw->pw_name);
206 		else
207 			sprintf(user_st,"(uid=%d)",scores[i].user);
208 
209 		compose_score_string(string,i,scores[i],user_st, date_st);
210 		fprintf(stderr,"%s\n", string);
211 	}
212 
213 	putchar('\n');
214 }
215 
216 
217