rogue

Ken Arnold's Rogue
git clone https://git.woozle.org/neale/rogue.git

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}