Neale Pickett
·
2011-10-13
netwait.c
1/*
2 * score editor
3 *
4 * @(#)netwait.c 4.6 (Berkeley) 02/05/99
5 */
6
7# include <stdio.h>
8# include <pwd.h>
9# include <signal.h>
10# include <ctype.h>
11# include <unctrl.h>
12
13# define TRUE 1
14# define FALSE 0
15# define bool char
16# define RN (((Seed = Seed*11109+13849) >> 16) & 0xffff)
17
18# define MAXSTR 80
19
20# include "netwait.h"
21
22SCORE Top_ten[10];
23
24char frob,
25 Buf[BUFSIZ],
26 *Reason[] = {
27 "killed",
28 "quit",
29 "A total winner",
30 "killed with Amulet",
31 };
32
33int Seed,
34 Inf;
35
36struct passwd *getpwnam();
37
38int
39main(ac, av)
40int ac;
41char **av;
42{
43 char *scorefile;
44 FILE *outf;
45
46 if (ac == 1)
47 scorefile = SCOREFILE;
48 else
49 scorefile = av[1];
50 Seed = getpid();
51
52 if ((Inf = open(scorefile, 2)) < 0) {
53 perror(scorefile);
54 exit(1);
55 }
56 frob = 0;
57 s_encread((char *) Top_ten, sizeof Top_ten, Inf);
58
59 while (do_comm())
60 continue;
61
62 exit(0);
63}
64
65/*
66 * do_comm:
67 * Get and execute a command
68 */
69bool
70do_comm(void)
71{
72 char *sp;
73 SCORE *scp;
74 struct passwd *pp;
75 static FILE *outf = NULL;
76 static bool written = TRUE;
77
78 printf("\nCommand: ");
79 while (isspace(Buf[0] = getchar()) || Buf[0] == '\n')
80 continue;
81 fgets(&Buf[1], BUFSIZ, stdin);
82 Buf[strlen(Buf) - 1] = '\0';
83 switch (Buf[0]) {
84 case 'w':
85 if (strncmp(Buf, "write", strlen(Buf)))
86 goto def;
87 lseek(Inf, 0L, 0);
88 if (outf == NULL && (outf = fdopen(Inf, "w")) == NULL) {
89 perror("fdopen");
90 exit(1);
91 }
92 fseek(outf, 0L, 0);
93 if (s_lock_sc())
94 {
95 int (*fp)();
96
97 fp = signal(SIGINT, SIG_IGN);
98 frob = 0;
99 s_encwrite((char *) Top_ten, sizeof Top_ten, outf);
100 s_unlock_sc();
101 signal(SIGINT, fp);
102 written = TRUE;
103 }
104 break;
105
106 case 'a':
107 if (strncmp(Buf, "add", strlen(Buf)))
108 goto def;
109 add_score();
110 written = FALSE;
111 break;
112
113 case 'd':
114 if (strncmp(Buf, "delete", strlen(Buf)))
115 goto def;
116 del_score();
117 written = FALSE;
118 break;
119
120 case 'p':
121 if (strncmp(Buf, "print", strlen(Buf)))
122 goto def;
123 printf("\nTop Ten Rogueists:\nRank\tScore\tName\n");
124 for (scp = Top_ten; scp < &Top_ten[10]; scp++)
125 if (!pr_score(scp, TRUE))
126 break;
127 break;
128
129 case 'q':
130 if (strncmp(Buf, "quit", strlen(Buf)))
131 goto def;
132 if (!written) {
133 printf("No write\n");
134 written = TRUE;
135 }
136 else
137 return FALSE;
138 break;
139
140 default:
141def:
142 printf("Unkown command: \"%s\"\n", Buf);
143 }
144 return TRUE;
145}
146
147/*
148 * add_score:
149 * Add a score to the score file
150 */
151void
152add_score(void)
153{
154 SCORE *scp;
155 struct passwd *pp;
156 int i;
157 static SCORE new;
158
159 printf("Name: ");
160 fgets(new.sc_name, MAXSTR, stdin);
161 new.sc_name[strlen(new.sc_name) - 1] = '\0';
162 do {
163 printf("Reason: ");
164 if ((new.sc_flags = getchar()) < '0' || new.sc_flags > '2') {
165 for (i = 0; i < 3; i++)
166 printf("%d: %s\n", i, Reason[i]);
167 ungetc(new.sc_flags, stdin);
168 }
169 while (getchar() != '\n')
170 continue;
171 } while (new.sc_flags < '0' || new.sc_flags > '2');
172 new.sc_flags -= '0';
173 do {
174 printf("User: ");
175 fgets(Buf, BUFSIZ, stdin);
176 Buf[strlen(Buf) - 1] = '\0';
177 if ((pp = getpwnam(Buf)) == NULL)
178 printf("who (%s)?\n", Buf);
179 } while (pp == NULL);
180 new.sc_uid = pp->pw_uid;
181 do {
182 printf("Monster: ");
183 if (!isalpha(new.sc_monster = getchar())) {
184 printf("type A-Za-z [%s]\n", unctrl(new.sc_monster));
185 ungetc(new.sc_monster, stdin);
186 }
187 while (getchar() != '\n')
188 continue;
189 } while (!isalpha(new.sc_monster));
190 printf("Score: ");
191 scanf("%d", &new.sc_score);
192 printf("Level: ");
193 scanf("%d", &new.sc_level);
194 while (getchar() != '\n')
195 continue;
196 pr_score(&new, FALSE);
197 printf("Really add it? ");
198 if (getchar() != 'y')
199 return;
200 while (getchar() != '\n')
201 continue;
202 insert_score(&new);
203}
204
205/*
206 * pr_score:
207 * Print out a score entry. Return FALSE if last entry.
208 */
209void
210pr_score(SCORE *scp, bool num)
211{
212 struct passwd *pp;
213
214 if (scp->sc_score) {
215 if (num)
216 printf("%d", scp - Top_ten + 1);
217 printf("\t%d\t%s: %s on level %d", scp->sc_score, scp->sc_name,
218 Reason[scp->sc_flags], scp->sc_level);
219 if (scp->sc_flags == 0)
220 printf(" by %s", s_killname((char) scp->sc_monster, TRUE));
221 if ((pp = getpwuid(scp->sc_uid)) == NULL)
222 printf(" (%d)", scp->sc_uid);
223 else
224 printf(" (%s)", pp->pw_name);
225 putchar('\n');
226 }
227 return scp->sc_score;
228}
229
230/*
231 * insert_score:
232 * Insert a score into the top ten list
233 */
234void
235insert_score(SCORE *new)
236{
237 SCORE *scp, *sc2;
238 int flags, uid, amount;
239
240 flags = new->sc_flags;
241 uid = new->sc_uid;
242 amount = new->sc_score;
243
244 for (scp = Top_ten; scp < &Top_ten[10]; scp++)
245 if (amount > scp->sc_score)
246 break;
247 else if (flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
248 scp = &Top_ten[10];
249 if (scp < &Top_ten[10]) {
250 if (flags != 2)
251 for (sc2 = scp; sc2 < &Top_ten[10]; sc2++) {
252 if (sc2->sc_uid == uid && sc2->sc_flags != 2)
253 break;
254 }
255 else
256 sc2 = &Top_ten[9];
257 while (sc2 > scp) {
258 *sc2 = sc2[-1];
259 sc2--;
260 }
261 *scp = *new;
262 sc2 = scp;
263 }
264}
265
266/*
267 * del_score:
268 * Delete a score from the score list.
269 */
270void
271del_score(void)
272{
273 SCORE *scp;
274 int i;
275 int num;
276
277 for (;;) {
278 printf("Which score? ");
279 fgets(Buf, BUFSIZ, stdin);
280 if (Buf[0] == '\n')
281 return;
282 sscanf(Buf, "%d", &num);
283 if (num < 1 || num > 10)
284 printf("range is 1-10\n");
285 else
286 break;
287 }
288 num--;
289 for (scp = &Top_ten[num]; scp < &Top_ten[9]; scp++)
290 *scp = scp[1];
291 Top_ten[9].sc_score = 0;
292 for (i = 0; i < MAXSTR; i++)
293 Top_ten[9].sc_name[i] = RN;
294 Top_ten[9].sc_flags = RN;
295 Top_ten[9].sc_level = RN;
296 Top_ten[9].sc_monster = RN;
297 Top_ten[9].sc_uid = RN;
298}