1*ac1fa6a8Skrw /* $OpenBSD: terminal.c,v 1.14 2017/01/21 08:22:57 krw Exp $ */
23faf6791Sd /* $NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $ */
33faf6791Sd /*
4598075eaSpjanzen * Copyright (c) 1983-2003, Regents of the University of California.
5598075eaSpjanzen * All rights reserved.
6598075eaSpjanzen *
7598075eaSpjanzen * Redistribution and use in source and binary forms, with or without
8598075eaSpjanzen * modification, are permitted provided that the following conditions are
9598075eaSpjanzen * met:
10598075eaSpjanzen *
11598075eaSpjanzen * + Redistributions of source code must retain the above copyright
12598075eaSpjanzen * notice, this list of conditions and the following disclaimer.
13598075eaSpjanzen * + Redistributions in binary form must reproduce the above copyright
14598075eaSpjanzen * notice, this list of conditions and the following disclaimer in the
15598075eaSpjanzen * documentation and/or other materials provided with the distribution.
16598075eaSpjanzen * + Neither the name of the University of California, San Francisco nor
17598075eaSpjanzen * the names of its contributors may be used to endorse or promote
18598075eaSpjanzen * products derived from this software without specific prior written
19598075eaSpjanzen * permission.
20598075eaSpjanzen *
21598075eaSpjanzen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22598075eaSpjanzen * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23598075eaSpjanzen * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24598075eaSpjanzen * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25598075eaSpjanzen * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26598075eaSpjanzen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27598075eaSpjanzen * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28598075eaSpjanzen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29598075eaSpjanzen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30598075eaSpjanzen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31598075eaSpjanzen * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
323faf6791Sd */
333faf6791Sd
34e29f8a1bSguenther #include <sys/select.h>
359ef48543Smestre #include <err.h>
363faf6791Sd #include <stdarg.h>
37c6d62522Sd #include <syslog.h>
38c6d62522Sd #include <string.h>
39c6d62522Sd
409ef48543Smestre #include "conf.h"
413faf6791Sd #include "hunt.h"
42fab1dce0Sd #include "server.h"
43fab1dce0Sd
443faf6791Sd #define TERM_WIDTH 80 /* Assume terminals are 80-char wide */
453faf6791Sd
463faf6791Sd /*
473faf6791Sd * cgoto:
483faf6791Sd * Move the cursor to the given position on the given player's
493faf6791Sd * terminal.
503faf6791Sd */
513faf6791Sd void
cgoto(PLAYER * pp,int y,int x)520f16a76cSmestre cgoto(PLAYER *pp, int y, int x)
533faf6791Sd {
54fab1dce0Sd
55fab1dce0Sd if (pp == ALL_PLAYERS) {
56fab1dce0Sd for (pp = Player; pp < End_player; pp++)
57fab1dce0Sd cgoto(pp, y, x);
58fab1dce0Sd for (pp = Monitor; pp < End_monitor; pp++)
59fab1dce0Sd cgoto(pp, y, x);
60fab1dce0Sd return;
61fab1dce0Sd }
62fab1dce0Sd
633faf6791Sd if (x == pp->p_curx && y == pp->p_cury)
643faf6791Sd return;
65fab1dce0Sd
663faf6791Sd sendcom(pp, MOVE, y, x);
673faf6791Sd pp->p_cury = y;
683faf6791Sd pp->p_curx = x;
693faf6791Sd }
703faf6791Sd
713faf6791Sd /*
723faf6791Sd * outch:
733faf6791Sd * Put out a single character.
743faf6791Sd */
753faf6791Sd void
outch(PLAYER * pp,char ch)760f16a76cSmestre outch(PLAYER *pp, char ch)
773faf6791Sd {
78fab1dce0Sd
79fab1dce0Sd if (pp == ALL_PLAYERS) {
80fab1dce0Sd for (pp = Player; pp < End_player; pp++)
81fab1dce0Sd outch(pp, ch);
82fab1dce0Sd for (pp = Monitor; pp < End_monitor; pp++)
83fab1dce0Sd outch(pp, ch);
84fab1dce0Sd return;
85fab1dce0Sd }
86fab1dce0Sd
873faf6791Sd if (++pp->p_curx >= TERM_WIDTH) {
883faf6791Sd pp->p_curx = 0;
893faf6791Sd pp->p_cury++;
903faf6791Sd }
913faf6791Sd (void) putc(ch, pp->p_output);
923faf6791Sd }
933faf6791Sd
943faf6791Sd /*
953faf6791Sd * outstr:
963faf6791Sd * Put out a string of the given length.
973faf6791Sd */
983faf6791Sd void
outstr(PLAYER * pp,char * str,int len)990f16a76cSmestre outstr(PLAYER *pp, char *str, int len)
1003faf6791Sd {
101fab1dce0Sd if (pp == ALL_PLAYERS) {
102fab1dce0Sd for (pp = Player; pp < End_player; pp++)
103fab1dce0Sd outstr(pp, str, len);
104fab1dce0Sd for (pp = Monitor; pp < End_monitor; pp++)
105fab1dce0Sd outstr(pp, str, len);
106fab1dce0Sd return;
107fab1dce0Sd }
108fab1dce0Sd
1093faf6791Sd pp->p_curx += len;
1103faf6791Sd pp->p_cury += (pp->p_curx / TERM_WIDTH);
1113faf6791Sd pp->p_curx %= TERM_WIDTH;
1123faf6791Sd while (len--)
1133faf6791Sd (void) putc(*str++, pp->p_output);
1143faf6791Sd }
1153faf6791Sd
1163faf6791Sd /*
117fab1dce0Sd * outat:
118fab1dce0Sd * draw a string at a location on the client.
119fab1dce0Sd * Cursor doesn't move if the location is invalid
120fab1dce0Sd */
121fab1dce0Sd void
outyx(PLAYER * pp,int y,int x,const char * fmt,...)122f1db87adSragge outyx(PLAYER *pp, int y, int x, const char *fmt, ...)
123fab1dce0Sd {
124fab1dce0Sd va_list ap;
125fab1dce0Sd char buf[BUFSIZ];
126fab1dce0Sd int len;
127fab1dce0Sd
128fab1dce0Sd va_start(ap, fmt);
129331130adSpjanzen len = vsnprintf(buf, sizeof(buf), fmt, ap);
130331130adSpjanzen va_end(ap);
1317d13dc82Sderaadt if (len == -1)
1327d13dc82Sderaadt len = 0;
133331130adSpjanzen if (len >= (int)sizeof(buf))
134331130adSpjanzen len = sizeof(buf) - 1;
135fab1dce0Sd if (y >= 0 && x >= 0)
136fab1dce0Sd cgoto(pp, y, x);
137331130adSpjanzen if (len > 0)
138fab1dce0Sd outstr(pp, buf, len);
139fab1dce0Sd }
140fab1dce0Sd
141fab1dce0Sd /*
1423faf6791Sd * clrscr:
1433faf6791Sd * Clear the screen, and reset the current position on the screen.
1443faf6791Sd */
1453faf6791Sd void
clrscr(PLAYER * pp)1460f16a76cSmestre clrscr(PLAYER *pp)
1473faf6791Sd {
148fab1dce0Sd
149fab1dce0Sd if (pp == ALL_PLAYERS) {
150fab1dce0Sd for (pp = Player; pp < End_player; pp++)
151fab1dce0Sd clrscr(pp);
152fab1dce0Sd for (pp = Monitor; pp < End_monitor; pp++)
153fab1dce0Sd clrscr(pp);
154fab1dce0Sd return;
155fab1dce0Sd }
156fab1dce0Sd
1573faf6791Sd sendcom(pp, CLEAR);
1583faf6791Sd pp->p_cury = 0;
1593faf6791Sd pp->p_curx = 0;
1603faf6791Sd }
1613faf6791Sd
1623faf6791Sd /*
1633faf6791Sd * ce:
1643faf6791Sd * Clear to the end of the line
1653faf6791Sd */
1663faf6791Sd void
ce(PLAYER * pp)1670f16a76cSmestre ce(PLAYER *pp)
1683faf6791Sd {
1693faf6791Sd sendcom(pp, CLRTOEOL);
1703faf6791Sd }
1713faf6791Sd
1723faf6791Sd /*
1733faf6791Sd * sendcom:
1743faf6791Sd * Send a command to the given user
1753faf6791Sd */
1763faf6791Sd void
sendcom(PLAYER * pp,int command,...)177f1db87adSragge sendcom(PLAYER *pp, int command, ...)
1783faf6791Sd {
1793faf6791Sd va_list ap;
180fab1dce0Sd char buf[3];
181fab1dce0Sd int len = 0;
182fab1dce0Sd
1833faf6791Sd va_start(ap, command);
184fab1dce0Sd buf[len++] = command;
1853faf6791Sd switch (command & 0377) {
1863faf6791Sd case MOVE:
187fab1dce0Sd buf[len++] = va_arg(ap, int);
188fab1dce0Sd buf[len++] = va_arg(ap, int);
1893faf6791Sd break;
1903faf6791Sd case ADDCH:
1913faf6791Sd case READY:
192fab1dce0Sd case ENDWIN:
193fab1dce0Sd buf[len++] = va_arg(ap, int);
1943faf6791Sd break;
1953faf6791Sd }
196fab1dce0Sd va_end(ap);
1973faf6791Sd
198fab1dce0Sd if (pp == ALL_PLAYERS) {
199fab1dce0Sd for (pp = Player; pp < End_player; pp++)
200fab1dce0Sd fwrite(buf, sizeof buf[0], len, pp->p_output);
201fab1dce0Sd for (pp = Monitor; pp < End_monitor; pp++)
202fab1dce0Sd fwrite(buf, sizeof buf[0], len, pp->p_output);
203fab1dce0Sd return;
204fab1dce0Sd } else
205fab1dce0Sd fwrite(buf, sizeof buf[0], len, pp->p_output);
2063faf6791Sd }
207fab1dce0Sd
208fab1dce0Sd /*
209fab1dce0Sd * sync:
210fab1dce0Sd * Flush the output buffer to the player
211fab1dce0Sd */
212fab1dce0Sd void
flush(PLAYER * pp)2130f16a76cSmestre flush(PLAYER *pp)
214fab1dce0Sd {
215fab1dce0Sd if (pp == ALL_PLAYERS) {
216fab1dce0Sd for (pp = Player; pp < End_player; pp++)
217fab1dce0Sd fflush(pp->p_output);
218fab1dce0Sd for (pp = Monitor; pp < End_monitor; pp++)
219fab1dce0Sd fflush(pp->p_output);
220fab1dce0Sd } else
221fab1dce0Sd fflush(pp->p_output);
222fab1dce0Sd }
223fab1dce0Sd
224c6d62522Sd void
logx(int prio,const char * fmt,...)225f1db87adSragge logx(int prio, const char *fmt, ...)
226c6d62522Sd {
227c6d62522Sd va_list ap;
228c6d62522Sd
229c6d62522Sd va_start(ap, fmt);
230c6d62522Sd if (conf_syslog)
231c6d62522Sd vsyslog(prio, fmt, ap);
232c6d62522Sd else if (conf_logerr)
233c6d62522Sd /* if (prio < LOG_NOTICE) */
234c6d62522Sd vwarnx(fmt, ap);
235172f3a86Sespie va_end(ap);
236c6d62522Sd }
237c6d62522Sd
238c6d62522Sd void
logit(int prio,const char * fmt,...)239f1db87adSragge logit(int prio, const char *fmt, ...)
240c6d62522Sd {
241c6d62522Sd va_list ap;
242c6d62522Sd char fmtm[1024];
243c6d62522Sd
244c6d62522Sd va_start(ap, fmt);
245c6d62522Sd if (conf_syslog) {
246c6d62522Sd strlcpy(fmtm, fmt, sizeof fmtm);
247c6d62522Sd strlcat(fmtm, ": %m", sizeof fmtm);
248c6d62522Sd vsyslog(prio, fmtm, ap);
249c6d62522Sd } else if (conf_logerr)
250c6d62522Sd /* if (prio < LOG_NOTICE) */
251c6d62522Sd vwarn(fmt, ap);
252172f3a86Sespie va_end(ap);
253c6d62522Sd }
254