+/* $NetBSD: arithmetic.c,v 1.16 2001/02/05 00:20:58 christos Exp $ */
+
/*
- * Copyright (c) 1989 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Eamonn McManus of Trinity College Dublin.
* SUCH DAMAGE.
*/
+#include <sys/cdefs.h>
#ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
- All rights reserved.\n";
+__COPYRIGHT("@(#) Copyright (c) 1989, 1993\n\
+ The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#ifndef lint
-/*static char sccsid[] = "from: @(#)arithmetic.c 5.5 (Berkeley) 2/27/91";*/
-static char rcsid[] = "$Id: arithmetic.c,v 1.3 1993/08/01 18:57:22 mycroft Exp $";
+#if 0
+static char sccsid[] = "@(#)arithmetic.c 8.1 (Berkeley) 5/31/93";
+#else
+__RCSID("$NetBSD: arithmetic.c,v 1.16 2001/02/05 00:20:58 christos Exp $");
+#endif
#endif /* not lint */
/*
*/
#include <sys/types.h>
-#include <sys/signal.h>
+#include <err.h>
#include <ctype.h>
+#include <signal.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
+
+int getrandom __P((int, int, int));
+void intr __P((int)) __attribute__((__noreturn__));
+int main __P((int, char *[]));
+int opnum __P((int));
+void penalise __P((int, int, int));
+int problem __P((void));
+void showstats __P((void));
+void usage __P((void)) __attribute__((__noreturn__));
-char keylist[] = "+-x/";
-char defaultkeys[] = "+-";
-char *keys = defaultkeys;
+const char keylist[] = "+-x/";
+const char defaultkeys[] = "+-";
+const char *keys = defaultkeys;
int nkeys = sizeof(defaultkeys) - 1;
int rangemax = 10;
int nright, nwrong;
time_t qtime;
#define NQUESTS 20
+extern char *__progname; /* from crt0.o */
+
/*
* Select keys from +-x/ to be asked addition, subtraction, multiplication,
* and division problems. More than one key may be given. The default is
* bound is 10. After every NQUESTS questions, statistics on the performance
* so far are printed.
*/
-void
+int
main(argc, argv)
int argc;
char **argv;
{
- extern char *optarg;
- extern int optind;
int ch, cnt;
- void intr();
- while ((ch = getopt(argc, argv, "r:o:")) != EOF)
+ /* Revoke setgid privileges */
+ setgid(getgid());
+
+ while ((ch = getopt(argc, argv, "r:o:")) != -1)
switch(ch) {
case 'o': {
- register char *p;
+ const char *p;
for (p = keys = optarg; *p; ++p)
- if (!index(keylist, *p)) {
- (void)fprintf(stderr,
- "arithmetic: unknown key.\n");
- exit(1);
- }
+ if (!strchr(keylist, *p))
+ errx(1, "arithmetic: unknown key.");
nkeys = p - optarg;
break;
}
case 'r':
- if ((rangemax = atoi(optarg)) <= 0) {
- (void)fprintf(stderr,
- "arithmetic: invalid range.\n");
- exit(1);
- }
+ if ((rangemax = atoi(optarg)) <= 0)
+ errx(1, "arithmetic: invalid range.");
break;
case '?':
default:
/* Handle interrupt character. Print score and exit. */
void
-intr()
+intr(dummy)
+ int dummy __attribute__((__unused__));
{
showstats();
exit(0);
}
/* Print score. Original `arithmetic' had a delay after printing it. */
+void
showstats()
{
if (nright + nwrong > 0) {
* answer causes the numbers in the problem to be penalised, so that they are
* more likely to appear in subsequent problems.
*/
+int
problem()
{
- register char *p;
+ char *p;
time_t start, finish;
int left, op, right, result;
char line[80];
+ right = left = result = 0;
op = keys[random() % nkeys];
if (op != '/')
right = getrandom(rangemax + 1, op, 1);
* operand number `operand' (0 or 1). If we run out of memory, we just
* forget about the penalty (how likely is this, anyway?).
*/
+void
penalise(value, op, operand)
int value, op, operand;
{
struct penalty *p;
- char *malloc();
op = opnum(op);
if ((p = (struct penalty *)malloc((u_int)sizeof(*p))) == NULL)
* as a value, or represents a position in the penalty list. If the latter,
* we find the corresponding value and return that, decreasing its penalty.
*/
+int
getrandom(maxval, op, operand)
int maxval, op, operand;
{
int value;
- register struct penalty **pp, *p;
+ struct penalty **pp, *p;
op = opnum(op);
value = random() % (maxval + penalty[op][operand]);
* correspond to the actual sum of penalties in the list. Provide an
* obscure message.
*/
- (void)fprintf(stderr, "arithmetic: bug: inconsistent penalties\n");
- exit(1);
+ errx(1, "arithmetic: bug: inconsistent penalties.");
/* NOTREACHED */
}
/* Return an index for the character op, which is one of [+-x/]. */
+int
opnum(op)
int op;
{
char *p;
- if (op == 0 || (p = index(keylist, op)) == NULL) {
- (void)fprintf(stderr,
- "arithmetic: bug: op %c not in keylist %s\n", op, keylist);
- exit(1);
- }
+ if (op == 0 || (p = strchr(keylist, op)) == NULL)
+ errx(1, "arithmetic: bug: op %c not in keylist %s",
+ op, keylist);
return(p - keylist);
}
/* Print usage message and quit. */
+void
usage()
{
- (void)fprintf(stderr, "usage: arithmetic [-o +-x/] [-r range]\n");
+ (void)fprintf(stderr, "Usage: %s [-o +-x/] [-r range]\n",
+ __progname);
exit(1);
}