-
Notifications
You must be signed in to change notification settings - Fork 0
/
scorefile.c
178 lines (146 loc) · 4.77 KB
/
scorefile.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
* scorefile.c: Rog-O-Matic XIV (CMU) Tue Mar 19 21:46:11 1985 - mlm
* Copyright (C) 1985 by A. Appel, G. Jacobson, L. Hamey, and M. Mauldin
*
* This file contains the functions which update the rogomatic scorefile,
* which lives in <RGMDIR>/rgmscore<versionstr>. LOCKFILE is used to
* prevent simultaneous accesses to the file. rgmdelta<versionstr>
* contains new scores, and whenever the score file is printed the delta
* file is sorted and merged into the rgmscore file.
*/
# include <stdio.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <stdlib.h>
# include "types.h"
# include "globals.h"
# include "install.h"
# define LINESIZE 2048
# define SCORE(s,p) (atoi (s+p))
static char lokfil[100];
/*
* add_score: Write a new score line out to the correct rogomatic score
* file by creating a temporary copy and inserting the new line in the
* proper place. Be tense about preventing simultaneous access to the
* score file and catching interrupts and things.
*/
add_score (new_line, vers, ntrm)
char *new_line, *vers;
int ntrm;
{
int wantscore = 1;
char ch;
char newfil[100];
FILE *newlog;
sprintf (lokfil, "%s %s", LOCKFILE, vers);
sprintf (newfil, "%s/rgmdelta%s", RGMDIR, vers);
/* Defer interrupts while mucking with the score file */
critical ();
/*
* Lock the score file. If lock_file fails, asks the user whether he
* wishes to wait. If so, then try lock_file five times and then ask
* again.
*/
while (lock_file (lokfil, MAXLOCK) == 0)
if (--wantscore < 1 && !ntrm)
{ printf ("The score file is busy, do you wish to wait? [y/n] ");
while ((ch = getchar ()) != 'y' && ch != 'n');
if (ch == 'y')
wantscore = 5;
else
{ uncritical (); return; }
}
/* Now create a temporary to copy into */
if ((newlog = wopen (newfil, "a")) == NULL)
{ printf ("\nUnable to write %s\n", newfil); }
else
{ fprintf (newlog, "%s\n", new_line);
fclose (newlog);
}
/* Write the score to the end of the delta file */
/* Now close the file, relinquish control of scorefile, and exit */
unlock_file (lokfil);
uncritical ();
}
/*
* dumpscore: Print out the scoreboard.
*/
dumpscore (vers)
char *vers;
{
char ch, scrfil[100], delfil[100], newfil[100], allfil[100], cmd[256];
FILE *scoref, *deltaf;
int oldmask, intrupscore ();
sprintf (lokfil, "%s %s", LOCKFILE, vers);
sprintf (scrfil, "%s/rgmscore%s", RGMDIR, vers);
sprintf (delfil, "%s/rgmdelta%s", RGMDIR, vers);
sprintf (newfil, "%s/NewScore%s", RGMDIR, vers);
sprintf (allfil, "%s/AllScore%s", RGMDIR, vers);
/* On interrupts we must relinquish control of the score file */
int_exit (intrupscore);
if (lock_file (lokfil, MAXLOCK) == 0)
{ printf ("Score file busy.\n");
exit (1);
}
deltaf = fopen (delfil, "r");
scoref = fopen (scrfil, "r");
/* If there are new scores, sort and merge them into the score file */
if (deltaf != NULL)
{ fclose (deltaf);
/* Defer interrupts while mucking with the score file */
critical ();
/* Make certain any new files are world writeable */
oldmask = umask (0);
/* If we have an old file and a delta file, merge them */
if (scoref != NULL)
{ fclose (scoref);
sprintf (cmd, "sort +4nr -o %s %s; sort -m +4nr -o %s %s %s",
newfil, delfil, allfil, newfil, scrfil);
system (cmd);
if (filelength (allfil) != filelength (delfil) + filelength (scrfil))
{ fprintf (stderr, "Error, new file is wrong length!\n");
unlink (newfil); unlink (allfil);
unlock_file (lokfil);
exit (1);
}
else
{ /* New file is okay, unlink old files and pointer swap score file */
unlink (delfil); unlink (newfil);
unlink (scrfil); link (allfil, scrfil); unlink (allfil);
}
scoref = fopen (scrfil, "r");
}
else
/* Only have delta file, sort into scorefile and unlink delta */
{ sprintf (cmd, "sort +4nr -o %s %s", scrfil, delfil);
system (cmd);
unlink (delfil);
scoref = fopen (scrfil, "r");
}
/* Restore umask */
umask (oldmask);
/* Restore interrupt status after score file stable */
uncritical ();
}
/* Now any new scores have been put into scrfil, read it */
if (scoref == NULL)
{ printf ("Can't find %s\nBest score was %d.\n", scrfil, BEST);
unlock_file (lokfil);
exit (1);
}
printf ("Rog-O-Matic Scores against version %s:\n\n", vers);
printf ("%s%s", "Date User Gold Killed by",
" Lvl Hp Str Ac Exp\n\n");
while ((int) (ch = fgetc (scoref)) != EOF)
putchar (ch);
fclose (scoref);
unlock_file (lokfil);
exit (0);
}
/*
* intrupscore: We have an interrupt, clean up and unlock the score file.
*/
intrupscore ()
{ unlock_file (lokfil);
exit (1);
}