Blame


1 11a5e2cf 2024-01-16 benni /* $NetBSD: tetris.c,v 1.34 2023/07/01 10:51:35 nia Exp $ */
2 11a5e2cf 2024-01-16 benni
3 11a5e2cf 2024-01-16 benni /*-
4 11a5e2cf 2024-01-16 benni * Copyright (c) 1992, 1993
5 11a5e2cf 2024-01-16 benni * The Regents of the University of California. All rights reserved.
6 11a5e2cf 2024-01-16 benni *
7 11a5e2cf 2024-01-16 benni * This code is derived from software contributed to Berkeley by
8 11a5e2cf 2024-01-16 benni * Chris Torek and Darren F. Provine.
9 11a5e2cf 2024-01-16 benni *
10 11a5e2cf 2024-01-16 benni * Redistribution and use in source and binary forms, with or without
11 11a5e2cf 2024-01-16 benni * modification, are permitted provided that the following conditions
12 11a5e2cf 2024-01-16 benni * are met:
13 11a5e2cf 2024-01-16 benni * 1. Redistributions of source code must retain the above copyright
14 11a5e2cf 2024-01-16 benni * notice, this list of conditions and the following disclaimer.
15 11a5e2cf 2024-01-16 benni * 2. Redistributions in binary form must reproduce the above copyright
16 11a5e2cf 2024-01-16 benni * notice, this list of conditions and the following disclaimer in the
17 11a5e2cf 2024-01-16 benni * documentation and/or other materials provided with the distribution.
18 11a5e2cf 2024-01-16 benni * 3. Neither the name of the University nor the names of its contributors
19 11a5e2cf 2024-01-16 benni * may be used to endorse or promote products derived from this software
20 11a5e2cf 2024-01-16 benni * without specific prior written permission.
21 11a5e2cf 2024-01-16 benni *
22 11a5e2cf 2024-01-16 benni * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 11a5e2cf 2024-01-16 benni * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 11a5e2cf 2024-01-16 benni * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 11a5e2cf 2024-01-16 benni * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 11a5e2cf 2024-01-16 benni * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 11a5e2cf 2024-01-16 benni * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 11a5e2cf 2024-01-16 benni * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 11a5e2cf 2024-01-16 benni * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 11a5e2cf 2024-01-16 benni * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 11a5e2cf 2024-01-16 benni * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 11a5e2cf 2024-01-16 benni * SUCH DAMAGE.
33 11a5e2cf 2024-01-16 benni *
34 11a5e2cf 2024-01-16 benni * @(#)tetris.c 8.1 (Berkeley) 5/31/93
35 11a5e2cf 2024-01-16 benni */
36 11a5e2cf 2024-01-16 benni
37 11a5e2cf 2024-01-16 benni #include <sys/cdefs.h>
38 60af9557 2024-01-16 benni #if !defined(lint) && !defined(__OpenBSD__)
39 11a5e2cf 2024-01-16 benni __COPYRIGHT("@(#) Copyright (c) 1992, 1993\
40 11a5e2cf 2024-01-16 benni The Regents of the University of California. All rights reserved.");
41 11a5e2cf 2024-01-16 benni #endif /* not lint */
42 11a5e2cf 2024-01-16 benni
43 11a5e2cf 2024-01-16 benni /*
44 11a5e2cf 2024-01-16 benni * Tetris (or however it is spelled).
45 11a5e2cf 2024-01-16 benni */
46 11a5e2cf 2024-01-16 benni
47 11a5e2cf 2024-01-16 benni #include <sys/time.h>
48 11a5e2cf 2024-01-16 benni
49 11a5e2cf 2024-01-16 benni #include <err.h>
50 11a5e2cf 2024-01-16 benni #include <fcntl.h>
51 11a5e2cf 2024-01-16 benni #include <signal.h>
52 11a5e2cf 2024-01-16 benni #include <stdio.h>
53 11a5e2cf 2024-01-16 benni #include <stdlib.h>
54 11a5e2cf 2024-01-16 benni #include <string.h>
55 11a5e2cf 2024-01-16 benni #include <unistd.h>
56 11a5e2cf 2024-01-16 benni
57 11a5e2cf 2024-01-16 benni #include "input.h"
58 11a5e2cf 2024-01-16 benni #include "scores.h"
59 11a5e2cf 2024-01-16 benni #include "screen.h"
60 11a5e2cf 2024-01-16 benni #include "tetris.h"
61 11a5e2cf 2024-01-16 benni
62 11a5e2cf 2024-01-16 benni cell board[B_SIZE]; /* 1 => occupied, 0 => empty */
63 11a5e2cf 2024-01-16 benni
64 11a5e2cf 2024-01-16 benni int Rows, Cols; /* current screen size */
65 11a5e2cf 2024-01-16 benni int Offset; /* used to center board & shapes */
66 11a5e2cf 2024-01-16 benni
67 11a5e2cf 2024-01-16 benni static const struct shape *curshape;
68 11a5e2cf 2024-01-16 benni const struct shape *nextshape;
69 11a5e2cf 2024-01-16 benni
70 11a5e2cf 2024-01-16 benni long fallrate; /* less than 1 million; smaller => faster */
71 11a5e2cf 2024-01-16 benni
72 11a5e2cf 2024-01-16 benni int score; /* the obvious thing */
73 11a5e2cf 2024-01-16 benni gid_t gid, egid;
74 11a5e2cf 2024-01-16 benni
75 11a5e2cf 2024-01-16 benni char key_msg[100];
76 11a5e2cf 2024-01-16 benni int showpreview;
77 11a5e2cf 2024-01-16 benni int nocolor;
78 2e032d40 2024-03-01 benni int dofaster;
79 11a5e2cf 2024-01-16 benni
80 11a5e2cf 2024-01-16 benni static void elide(void);
81 11a5e2cf 2024-01-16 benni static void setup_board(void);
82 11a5e2cf 2024-01-16 benni static void onintr(int) __dead;
83 11a5e2cf 2024-01-16 benni static void usage(void) __dead;
84 11a5e2cf 2024-01-16 benni
85 11a5e2cf 2024-01-16 benni /*
86 11a5e2cf 2024-01-16 benni * Set up the initial board. The bottom display row is completely set,
87 11a5e2cf 2024-01-16 benni * along with another (hidden) row underneath that. Also, the left and
88 11a5e2cf 2024-01-16 benni * right edges are set.
89 11a5e2cf 2024-01-16 benni */
90 11a5e2cf 2024-01-16 benni static void
91 11a5e2cf 2024-01-16 benni setup_board(void)
92 11a5e2cf 2024-01-16 benni {
93 11a5e2cf 2024-01-16 benni int i;
94 11a5e2cf 2024-01-16 benni cell *p;
95 11a5e2cf 2024-01-16 benni
96 11a5e2cf 2024-01-16 benni p = board;
97 11a5e2cf 2024-01-16 benni for (i = B_SIZE; i; i--)
98 11a5e2cf 2024-01-16 benni *p++ = (i <= (2 * B_COLS) || (i % B_COLS) < 2) ? 7 : 0;
99 11a5e2cf 2024-01-16 benni }
100 11a5e2cf 2024-01-16 benni
101 11a5e2cf 2024-01-16 benni /*
102 11a5e2cf 2024-01-16 benni * Elide any full active rows.
103 11a5e2cf 2024-01-16 benni */
104 11a5e2cf 2024-01-16 benni static void
105 11a5e2cf 2024-01-16 benni elide(void)
106 11a5e2cf 2024-01-16 benni {
107 11a5e2cf 2024-01-16 benni int i, j, base;
108 11a5e2cf 2024-01-16 benni cell *p;
109 11a5e2cf 2024-01-16 benni
110 11a5e2cf 2024-01-16 benni for (i = A_FIRST; i < A_LAST; i++) {
111 11a5e2cf 2024-01-16 benni base = i * B_COLS + 1;
112 11a5e2cf 2024-01-16 benni p = &board[base];
113 11a5e2cf 2024-01-16 benni for (j = B_COLS - 2; *p++ != 0;) {
114 11a5e2cf 2024-01-16 benni if (--j <= 0) {
115 11a5e2cf 2024-01-16 benni /* this row is to be elided */
116 11a5e2cf 2024-01-16 benni memset(&board[base], 0, B_COLS - 2);
117 11a5e2cf 2024-01-16 benni scr_update();
118 11a5e2cf 2024-01-16 benni tsleep();
119 11a5e2cf 2024-01-16 benni while (--base != 0)
120 11a5e2cf 2024-01-16 benni board[base + B_COLS] = board[base];
121 11a5e2cf 2024-01-16 benni /* don't forget to clear 0th row */
122 11a5e2cf 2024-01-16 benni memset(&board[1], 0, B_COLS - 2);
123 11a5e2cf 2024-01-16 benni scr_update();
124 11a5e2cf 2024-01-16 benni tsleep();
125 11a5e2cf 2024-01-16 benni break;
126 11a5e2cf 2024-01-16 benni }
127 11a5e2cf 2024-01-16 benni }
128 11a5e2cf 2024-01-16 benni }
129 11a5e2cf 2024-01-16 benni }
130 11a5e2cf 2024-01-16 benni
131 11a5e2cf 2024-01-16 benni int
132 11a5e2cf 2024-01-16 benni main(int argc, char *argv[])
133 11a5e2cf 2024-01-16 benni {
134 11a5e2cf 2024-01-16 benni int pos, c;
135 11a5e2cf 2024-01-16 benni const char *keys;
136 11a5e2cf 2024-01-16 benni int level = 2;
137 11a5e2cf 2024-01-16 benni #define NUMKEYS 7
138 11a5e2cf 2024-01-16 benni char key_write[NUMKEYS][10];
139 11a5e2cf 2024-01-16 benni char *nocolor_env;
140 11a5e2cf 2024-01-16 benni int ch, i, j;
141 11a5e2cf 2024-01-16 benni int fd;
142 11a5e2cf 2024-01-16 benni
143 11a5e2cf 2024-01-16 benni gid = getgid();
144 11a5e2cf 2024-01-16 benni egid = getegid();
145 11a5e2cf 2024-01-16 benni setegid(gid);
146 11a5e2cf 2024-01-16 benni
147 11a5e2cf 2024-01-16 benni fd = open("/dev/null", O_RDONLY);
148 11a5e2cf 2024-01-16 benni if (fd < 3)
149 11a5e2cf 2024-01-16 benni exit(1);
150 11a5e2cf 2024-01-16 benni close(fd);
151 11a5e2cf 2024-01-16 benni
152 11a5e2cf 2024-01-16 benni keys = "jkl pqn";
153 11a5e2cf 2024-01-16 benni
154 2e032d40 2024-03-01 benni while ((ch = getopt(argc, argv, "bfk:l:ps")) != -1)
155 11a5e2cf 2024-01-16 benni switch(ch) {
156 11a5e2cf 2024-01-16 benni case 'b':
157 11a5e2cf 2024-01-16 benni nocolor = 1;
158 11a5e2cf 2024-01-16 benni break;
159 2e032d40 2024-03-01 benni case 'f':
160 2e032d40 2024-03-01 benni dofaster = 1;
161 2e032d40 2024-03-01 benni break;
162 11a5e2cf 2024-01-16 benni case 'k':
163 11a5e2cf 2024-01-16 benni if (strlen(keys = optarg) != NUMKEYS)
164 11a5e2cf 2024-01-16 benni usage();
165 11a5e2cf 2024-01-16 benni break;
166 11a5e2cf 2024-01-16 benni case 'l':
167 11a5e2cf 2024-01-16 benni level = atoi(optarg);
168 11a5e2cf 2024-01-16 benni if (level < MINLEVEL || level > MAXLEVEL) {
169 11a5e2cf 2024-01-16 benni errx(1, "level must be from %d to %d",
170 11a5e2cf 2024-01-16 benni MINLEVEL, MAXLEVEL);
171 11a5e2cf 2024-01-16 benni }
172 11a5e2cf 2024-01-16 benni break;
173 11a5e2cf 2024-01-16 benni case 'p':
174 11a5e2cf 2024-01-16 benni showpreview = 1;
175 11a5e2cf 2024-01-16 benni break;
176 11a5e2cf 2024-01-16 benni case 's':
177 11a5e2cf 2024-01-16 benni showscores(0);
178 11a5e2cf 2024-01-16 benni exit(0);
179 11a5e2cf 2024-01-16 benni case '?':
180 11a5e2cf 2024-01-16 benni default:
181 11a5e2cf 2024-01-16 benni usage();
182 11a5e2cf 2024-01-16 benni }
183 11a5e2cf 2024-01-16 benni
184 11a5e2cf 2024-01-16 benni argc -= optind;
185 11a5e2cf 2024-01-16 benni argv += optind;
186 11a5e2cf 2024-01-16 benni
187 11a5e2cf 2024-01-16 benni if (argc)
188 11a5e2cf 2024-01-16 benni usage();
189 11a5e2cf 2024-01-16 benni
190 11a5e2cf 2024-01-16 benni nocolor_env = getenv("NO_COLOR");
191 11a5e2cf 2024-01-16 benni
192 11a5e2cf 2024-01-16 benni if (nocolor_env != NULL && nocolor_env[0] != '\0')
193 11a5e2cf 2024-01-16 benni nocolor = 1;
194 11a5e2cf 2024-01-16 benni
195 11a5e2cf 2024-01-16 benni fallrate = 1000000 / level;
196 11a5e2cf 2024-01-16 benni
197 11a5e2cf 2024-01-16 benni for (i = 0; i <= (NUMKEYS-1); i++) {
198 11a5e2cf 2024-01-16 benni for (j = i+1; j <= (NUMKEYS-1); j++) {
199 11a5e2cf 2024-01-16 benni if (keys[i] == keys[j]) {
200 11a5e2cf 2024-01-16 benni errx(1, "duplicate command keys specified.");
201 11a5e2cf 2024-01-16 benni }
202 11a5e2cf 2024-01-16 benni }
203 11a5e2cf 2024-01-16 benni if (keys[i] == ' ')
204 11a5e2cf 2024-01-16 benni strcpy(key_write[i], "<space>");
205 11a5e2cf 2024-01-16 benni else {
206 11a5e2cf 2024-01-16 benni key_write[i][0] = keys[i];
207 11a5e2cf 2024-01-16 benni key_write[i][1] = '\0';
208 11a5e2cf 2024-01-16 benni }
209 11a5e2cf 2024-01-16 benni }
210 11a5e2cf 2024-01-16 benni
211 11a5e2cf 2024-01-16 benni snprintf(key_msg, sizeof(key_msg),
212 11a5e2cf 2024-01-16 benni "%s - left %s - rotate %s - right %s - drop %s - pause %s - quit %s - down",
213 11a5e2cf 2024-01-16 benni key_write[0], key_write[1], key_write[2], key_write[3],
214 11a5e2cf 2024-01-16 benni key_write[4], key_write[5], key_write[6]);
215 11a5e2cf 2024-01-16 benni
216 11a5e2cf 2024-01-16 benni (void)signal(SIGINT, onintr);
217 11a5e2cf 2024-01-16 benni scr_init();
218 11a5e2cf 2024-01-16 benni setup_board();
219 11a5e2cf 2024-01-16 benni
220 11a5e2cf 2024-01-16 benni scr_set();
221 11a5e2cf 2024-01-16 benni
222 11a5e2cf 2024-01-16 benni pos = A_FIRST*B_COLS + (B_COLS/2)-1;
223 11a5e2cf 2024-01-16 benni nextshape = randshape();
224 11a5e2cf 2024-01-16 benni curshape = randshape();
225 11a5e2cf 2024-01-16 benni
226 11a5e2cf 2024-01-16 benni scr_msg(key_msg, 1);
227 11a5e2cf 2024-01-16 benni
228 11a5e2cf 2024-01-16 benni for (;;) {
229 11a5e2cf 2024-01-16 benni place(curshape, pos, 1);
230 11a5e2cf 2024-01-16 benni scr_update();
231 11a5e2cf 2024-01-16 benni place(curshape, pos, 0);
232 11a5e2cf 2024-01-16 benni c = tgetchar();
233 11a5e2cf 2024-01-16 benni if (c < 0) {
234 11a5e2cf 2024-01-16 benni /*
235 11a5e2cf 2024-01-16 benni * Timeout. Move down if possible.
236 11a5e2cf 2024-01-16 benni */
237 11a5e2cf 2024-01-16 benni if (fits_in(curshape, pos + B_COLS)) {
238 11a5e2cf 2024-01-16 benni pos += B_COLS;
239 11a5e2cf 2024-01-16 benni continue;
240 11a5e2cf 2024-01-16 benni }
241 11a5e2cf 2024-01-16 benni
242 11a5e2cf 2024-01-16 benni /*
243 11a5e2cf 2024-01-16 benni * Put up the current shape `permanently',
244 11a5e2cf 2024-01-16 benni * bump score, and elide any full rows.
245 11a5e2cf 2024-01-16 benni */
246 11a5e2cf 2024-01-16 benni place(curshape, pos, 1);
247 11a5e2cf 2024-01-16 benni score++;
248 11a5e2cf 2024-01-16 benni elide();
249 11a5e2cf 2024-01-16 benni
250 11a5e2cf 2024-01-16 benni /*
251 11a5e2cf 2024-01-16 benni * Choose a new shape. If it does not fit,
252 11a5e2cf 2024-01-16 benni * the game is over.
253 11a5e2cf 2024-01-16 benni */
254 11a5e2cf 2024-01-16 benni curshape = nextshape;
255 11a5e2cf 2024-01-16 benni nextshape = randshape();
256 11a5e2cf 2024-01-16 benni pos = A_FIRST*B_COLS + (B_COLS/2)-1;
257 11a5e2cf 2024-01-16 benni if (!fits_in(curshape, pos))
258 11a5e2cf 2024-01-16 benni break;
259 11a5e2cf 2024-01-16 benni continue;
260 11a5e2cf 2024-01-16 benni }
261 11a5e2cf 2024-01-16 benni
262 11a5e2cf 2024-01-16 benni /*
263 11a5e2cf 2024-01-16 benni * Handle command keys.
264 11a5e2cf 2024-01-16 benni */
265 11a5e2cf 2024-01-16 benni if (c == keys[5]) {
266 11a5e2cf 2024-01-16 benni /* quit */
267 11a5e2cf 2024-01-16 benni break;
268 11a5e2cf 2024-01-16 benni }
269 11a5e2cf 2024-01-16 benni if (c == keys[4]) {
270 11a5e2cf 2024-01-16 benni static char msg[] =
271 11a5e2cf 2024-01-16 benni "paused - press RETURN to continue";
272 11a5e2cf 2024-01-16 benni
273 11a5e2cf 2024-01-16 benni place(curshape, pos, 1);
274 11a5e2cf 2024-01-16 benni do {
275 11a5e2cf 2024-01-16 benni scr_update();
276 11a5e2cf 2024-01-16 benni scr_msg(key_msg, 0);
277 11a5e2cf 2024-01-16 benni scr_msg(msg, 1);
278 11a5e2cf 2024-01-16 benni (void) fflush(stdout);
279 11a5e2cf 2024-01-16 benni } while (rwait(NULL) == -1);
280 11a5e2cf 2024-01-16 benni scr_msg(msg, 0);
281 11a5e2cf 2024-01-16 benni scr_msg(key_msg, 1);
282 11a5e2cf 2024-01-16 benni place(curshape, pos, 0);
283 11a5e2cf 2024-01-16 benni continue;
284 11a5e2cf 2024-01-16 benni }
285 11a5e2cf 2024-01-16 benni if (c == keys[0]) {
286 11a5e2cf 2024-01-16 benni /* move left */
287 11a5e2cf 2024-01-16 benni if (fits_in(curshape, pos - 1))
288 11a5e2cf 2024-01-16 benni pos--;
289 11a5e2cf 2024-01-16 benni continue;
290 11a5e2cf 2024-01-16 benni }
291 11a5e2cf 2024-01-16 benni if (c == keys[1]) {
292 11a5e2cf 2024-01-16 benni /* turn */
293 11a5e2cf 2024-01-16 benni const struct shape *new = &shapes[curshape->rot];
294 11a5e2cf 2024-01-16 benni
295 11a5e2cf 2024-01-16 benni if (fits_in(new, pos))
296 11a5e2cf 2024-01-16 benni curshape = new;
297 11a5e2cf 2024-01-16 benni continue;
298 11a5e2cf 2024-01-16 benni }
299 11a5e2cf 2024-01-16 benni if (c == keys[2]) {
300 11a5e2cf 2024-01-16 benni /* move right */
301 11a5e2cf 2024-01-16 benni if (fits_in(curshape, pos + 1))
302 11a5e2cf 2024-01-16 benni pos++;
303 11a5e2cf 2024-01-16 benni continue;
304 11a5e2cf 2024-01-16 benni }
305 11a5e2cf 2024-01-16 benni if (c == keys[3]) {
306 11a5e2cf 2024-01-16 benni /* move to bottom */
307 11a5e2cf 2024-01-16 benni while (fits_in(curshape, pos + B_COLS)) {
308 11a5e2cf 2024-01-16 benni pos += B_COLS;
309 11a5e2cf 2024-01-16 benni score++;
310 11a5e2cf 2024-01-16 benni }
311 11a5e2cf 2024-01-16 benni continue;
312 11a5e2cf 2024-01-16 benni }
313 11a5e2cf 2024-01-16 benni if (c == keys[6]) {
314 11a5e2cf 2024-01-16 benni /* move down */
315 11a5e2cf 2024-01-16 benni if (fits_in(curshape, pos + B_COLS)) {
316 11a5e2cf 2024-01-16 benni pos += B_COLS;
317 11a5e2cf 2024-01-16 benni score++;
318 11a5e2cf 2024-01-16 benni }
319 11a5e2cf 2024-01-16 benni continue;
320 11a5e2cf 2024-01-16 benni }
321 11a5e2cf 2024-01-16 benni if (c == '\f') {
322 11a5e2cf 2024-01-16 benni scr_clear();
323 11a5e2cf 2024-01-16 benni scr_msg(key_msg, 1);
324 11a5e2cf 2024-01-16 benni }
325 11a5e2cf 2024-01-16 benni }
326 11a5e2cf 2024-01-16 benni
327 11a5e2cf 2024-01-16 benni scr_clear();
328 11a5e2cf 2024-01-16 benni scr_end();
329 11a5e2cf 2024-01-16 benni
330 11a5e2cf 2024-01-16 benni (void)printf("Your score: %d point%s x level %d = %d\n",
331 11a5e2cf 2024-01-16 benni score, score == 1 ? "" : "s", level, score * level);
332 11a5e2cf 2024-01-16 benni savescore(level);
333 11a5e2cf 2024-01-16 benni
334 11a5e2cf 2024-01-16 benni printf("\nHit RETURN to see high scores, ^C to skip.\n");
335 11a5e2cf 2024-01-16 benni
336 11a5e2cf 2024-01-16 benni while ((i = getchar()) != '\n')
337 11a5e2cf 2024-01-16 benni if (i == EOF)
338 11a5e2cf 2024-01-16 benni break;
339 11a5e2cf 2024-01-16 benni
340 11a5e2cf 2024-01-16 benni showscores(level);
341 11a5e2cf 2024-01-16 benni
342 11a5e2cf 2024-01-16 benni exit(0);
343 11a5e2cf 2024-01-16 benni }
344 11a5e2cf 2024-01-16 benni
345 11a5e2cf 2024-01-16 benni static void
346 11a5e2cf 2024-01-16 benni onintr(int signo __unused)
347 11a5e2cf 2024-01-16 benni {
348 11a5e2cf 2024-01-16 benni scr_clear();
349 11a5e2cf 2024-01-16 benni scr_end();
350 11a5e2cf 2024-01-16 benni exit(0);
351 11a5e2cf 2024-01-16 benni }
352 11a5e2cf 2024-01-16 benni
353 11a5e2cf 2024-01-16 benni static void
354 11a5e2cf 2024-01-16 benni usage(void)
355 11a5e2cf 2024-01-16 benni {
356 11a5e2cf 2024-01-16 benni (void)fprintf(stderr, "usage: %s [-bps] [-k keys] [-l level]\n",
357 11a5e2cf 2024-01-16 benni getprogname());
358 11a5e2cf 2024-01-16 benni exit(1);
359 11a5e2cf 2024-01-16 benni }