Merge branch 'vendor/OPENSSL'
[dragonfly.git] / games / hack / hack.rumors.c
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.rumors.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.rumors.c,v 1.3 1999/11/16 02:57:10 billf Exp $ */
4 /* $DragonFly: src/games/hack/hack.rumors.c,v 1.3 2006/08/21 19:45:32 pavalos Exp $ */
5
6 #include "hack.h"                       /* for RUMORFILE and BSD (index) */
7 #define CHARSZ  8                       /* number of bits in a char */
8 int n_rumors = 0;
9 int n_used_rumors = -1;
10 char *usedbits;
11
12 static void init_rumors(FILE *);
13 static bool skipline(FILE *);
14 static void outline(FILE *);
15 static bool used(int);
16
17 static void
18 init_rumors(FILE *rumf)
19 {
20         int i;
21
22         n_used_rumors = 0;
23         while (skipline(rumf))
24                 n_rumors++;
25         rewind(rumf);
26         i = n_rumors / CHARSZ;
27         usedbits = alloc((unsigned)(i + 1));
28         for (; i >= 0; i--)
29                 usedbits[i] = 0;
30 }
31
32 static bool
33 skipline(FILE *rumf)
34 {
35         char line[COLNO];
36
37         for (;;) {
38                 if (!fgets(line, sizeof(line), rumf))
39                         return (0);
40                 if (strchr(line, '\n'))
41                         return (1);
42         }
43 }
44
45 static void
46 outline(FILE *rumf)
47 {
48         char line[COLNO];
49         char *ep;
50
51         if (!fgets(line, sizeof(line), rumf))
52                 return;
53         if ((ep = strchr(line, '\n')) != 0)
54                 *ep = 0;
55         pline("This cookie has a scrap of paper inside! It reads: ");
56         pline(line);
57 }
58
59 void
60 outrumor(void)
61 {
62         int rn, i;
63         FILE *rumf;
64
65         if (n_rumors <= n_used_rumors ||
66             (rumf = fopen(RUMORFILE, "r")) == NULL)
67                 return;
68         if (n_used_rumors < 0)
69                 init_rumors(rumf);
70         if (!n_rumors)
71                 goto none;
72         rn = rn2(n_rumors - n_used_rumors);
73         i = 0;
74         while (rn || used(i)) {
75                 skipline(rumf);
76                 if (!used(i))
77                         rn--;
78                 i++;
79         }
80         usedbits[i / CHARSZ] |= (1 << (i % CHARSZ));
81         n_used_rumors++;
82         outline(rumf);
83 none:
84         fclose(rumf);
85 }
86
87 static bool
88 used(int i)
89 {
90         return (usedbits[i / CHARSZ] & (1 << (i % CHARSZ)));
91 }