This repository has been archived by the owner on Jan 18, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlscore.c
124 lines (113 loc) · 2.72 KB
/
lscore.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "ladder.h"
#include <unistd.h>
#include <pwd.h>
#define MAXSCORE 5
#define XMASK 12345
static char sf[] = SCOREFILE;
static char lf[] = SCOREFILE ".LCK";
typedef struct
{
int score, level;
uid_t uid; /* to avoid user names */
int xor;
} SCORE;
SCORE scores[MAXSCORE + 1];
static void lock_score(void)
{
int i;
FILE *lfp;
for( i = 3; i; i-- )
if( lfp = fopen(lf,"r") )
{
fclose(lfp);
sleep(2);
}
else
break;
if( !i || !(lfp = fopen(lf,"w")) )
{
perror(lf);
exit(EXIT_FAILURE);
}
fclose(lfp);
}
/* Read the score file. Note, that if it can be read, it is sorted. If it
* can't be read, is malformed or if it's too short, the scores themselves
* become 0. Any possible error doesn't matter at all.
*/
static void read_scores(void)
{
FILE *sfp;
SCORE *scp;
lock_score();
memset(scores,0,sizeof(scores));
if( sfp = fopen(sf,"r") )
{
for( scp = scores; scp < &scores[MAXSCORE]; scp++ )
if( fscanf(sfp,"%d%d%d%d",
&scp->score,&scp->level,&scp->uid,&scp->xor) != 4
|| scp->score ^ scp->level ^ scp->uid ^ scp->xor ^ XMASK )
{
scp->score = 0;
break;
}
fclose(sfp);
}
remove(lf);
}
static void percolate(void)
{
SCORE *scp;
for( scp = &scores[MAXSCORE]; scp > scores; scp-- )
if( scp[0].score > scp[-1].score ||
scp[0].score == scp[-1].score &&
scp[0].level >= scp[-1].level )
{
SCORE tmp = scp[0];
scp[0] = scp[-1];
scp[-1] = tmp;
}
}
void upd_score()
{
FILE *sfp;
SCORE *scp;
read_scores();
lock_score();
if( !(sfp = fopen(sf,"w")) )
{
perror(sf);
mexit1();
}
scores[MAXSCORE].score = score;
scores[MAXSCORE].level = level;
scores[MAXSCORE].xor = XMASK ^ score ^ level ^
(scores[MAXSCORE].uid = getuid());
percolate();
for( scp = scores; scp < &scores[MAXSCORE]; scp++ )
fprintf(sfp,"%d %d %d %d\n",
scp->score,scp->level,scp->uid,scp->xor);
fclose(sfp);
remove(lf);
}
void prt_score(int r, int c)
{
int i;
struct passwd *pw;
read_scores();
mvaddstr(r,c,"High Scores");
for( i = 0; i < MAXSCORE; i++ )
{
mvprintw(r + i + 2,c,"%d) ",i + 1);
if( scores[i].score )
{
printw("%5d00 %2d ",scores[i].score,scores[i].level + 1);
if( pw = getpwuid(scores[i].uid) )
addstr(pw->pw_name);
else
printw("UID %d",scores[i].uid);
}
else
clrtoeol();
}
}