<net/dlt.h>: Sync with libpcap 1.9.1
[dragonfly.git] / games / hunt / huntd / terminal.c
1 /*-
2  * Copyright (c) 1983-2003, Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the University of California, San Francisco nor
15  *    the names of its contributors may be used to endorse or promote
16  *    products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $OpenBSD: terminal.c,v 1.10 2008/06/20 13:08:44 ragge Exp $
32  * $NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $
33  */
34
35 #include <stdarg.h>
36 #include <syslog.h>
37 #include <err.h>
38 #include <string.h>
39
40 #include "hunt.h"
41 #include "server.h"
42 #include "conf.h"
43
44 #define TERM_WIDTH      80      /* Assume terminals are 80-char wide */
45
46 /*
47  * cgoto:
48  *      Move the cursor to the given position on the given player's
49  *      terminal.
50  */
51 void
52 cgoto(PLAYER *pp, int y, int x)
53 {
54
55         if (pp == ALL_PLAYERS) {
56                 for (pp = Player; pp < End_player; pp++)
57                         cgoto(pp, y, x);
58                 for (pp = Monitor; pp < End_monitor; pp++)
59                         cgoto(pp, y, x);
60                 return;
61         }
62
63         if (x == pp->p_curx && y == pp->p_cury)
64                 return;
65
66         sendcom(pp, MOVE, y, x);
67         pp->p_cury = y;
68         pp->p_curx = x;
69 }
70
71 /*
72  * outch:
73  *      Put out a single character.
74  */
75 void
76 outch(PLAYER *pp, char ch)
77 {
78
79         if (pp == ALL_PLAYERS) {
80                 for (pp = Player; pp < End_player; pp++)
81                         outch(pp, ch);
82                 for (pp = Monitor; pp < End_monitor; pp++)
83                         outch(pp, ch);
84                 return;
85         }
86
87         if (++pp->p_curx >= TERM_WIDTH) {
88                 pp->p_curx = 0;
89                 pp->p_cury++;
90         }
91         putc(ch, pp->p_output);
92 }
93
94 /*
95  * outstr:
96  *      Put out a string of the given length.
97  */
98 void
99 outstr(PLAYER *pp, const char *str, int len)
100 {
101         if (pp == ALL_PLAYERS) {
102                 for (pp = Player; pp < End_player; pp++)
103                         outstr(pp, str, len);
104                 for (pp = Monitor; pp < End_monitor; pp++)
105                         outstr(pp, str, len);
106                 return;
107         }
108
109         pp->p_curx += len;
110         pp->p_cury += (pp->p_curx / TERM_WIDTH);
111         pp->p_curx %= TERM_WIDTH;
112         while (len--)
113                 putc(*str++, pp->p_output);
114 }
115
116 /*
117  * outat:
118  *      draw a string at a location on the client.
119  *      Cursor doesn't move if the location is invalid
120  */
121 void
122 outyx(PLAYER *pp, int y, int x, const char *fmt, ...)
123 {
124         va_list ap;
125         char buf[BUFSIZ];
126         int len;
127
128         va_start(ap, fmt);
129         len = vsnprintf(buf, sizeof(buf), fmt, ap);
130         va_end(ap);
131         if (len == -1)
132                 len = 0;
133         if (len >= (int)sizeof(buf))
134                 len = sizeof(buf) - 1;
135         if (y >= 0 && x >= 0)
136                 cgoto(pp, y, x);
137         if (len > 0)
138                 outstr(pp, buf, len);
139 }
140
141 /*
142  * clrscr:
143  *      Clear the screen, and reset the current position on the screen.
144  */
145 void
146 clrscr(PLAYER *pp)
147 {
148
149         if (pp == ALL_PLAYERS) {
150                 for (pp = Player; pp < End_player; pp++)
151                         clrscr(pp);
152                 for (pp = Monitor; pp < End_monitor; pp++)
153                         clrscr(pp);
154                 return;
155         }
156
157         sendcom(pp, CLEAR);
158         pp->p_cury = 0;
159         pp->p_curx = 0;
160 }
161
162 /*
163  * ce:
164  *      Clear to the end of the line
165  */
166 void
167 ce(PLAYER *pp)
168 {
169         sendcom(pp, CLRTOEOL);
170 }
171
172 /*
173  * sendcom:
174  *      Send a command to the given user
175  */
176 void
177 sendcom(PLAYER *pp, int command, ...)
178 {
179         va_list ap;
180         char    buf[3];
181         int     len = 0;
182
183         va_start(ap, command);
184         buf[len++] = command;
185         switch (command & 0377) {
186         case MOVE:
187                 buf[len++] = va_arg(ap, int);
188                 buf[len++] = va_arg(ap, int);
189                 break;
190         case ADDCH:
191         case READY:
192         case ENDWIN:
193                 buf[len++] = va_arg(ap, int);
194                 break;
195         }
196         va_end(ap);
197
198         if (pp == ALL_PLAYERS) {
199                 for (pp = Player; pp < End_player; pp++)
200                         fwrite(buf, sizeof buf[0], len, pp->p_output);
201                 for (pp = Monitor; pp < End_monitor; pp++)
202                         fwrite(buf, sizeof buf[0], len, pp->p_output);
203                 return;
204         } else
205                 fwrite(buf, sizeof buf[0], len, pp->p_output);
206 }
207
208 /*
209  * sync:
210  *      Flush the output buffer to the player
211  */
212 void
213 flush(PLAYER *pp)
214 {
215         if (pp == ALL_PLAYERS) {
216                 for (pp = Player; pp < End_player; pp++)
217                         fflush(pp->p_output);
218                 for (pp = Monitor; pp < End_monitor; pp++)
219                         fflush(pp->p_output);
220         } else
221                 fflush(pp->p_output);
222 }
223
224 void
225 logx(int prio, const char *fmt, ...)
226 {
227         va_list ap;
228
229         va_start(ap, fmt);
230         if (conf_syslog)
231                 vsyslog(prio, fmt, ap);
232         else if (conf_logerr)
233         /* if (prio < LOG_NOTICE) */
234                 vwarnx(fmt, ap);
235         va_end(ap);
236 }
237
238 void
239 logit(int prio, const char *fmt, ...)
240 {
241         va_list ap;
242         char fmtm[1024];
243
244         va_start(ap, fmt);
245         if (conf_syslog) {
246                 strlcpy(fmtm, fmt, sizeof fmtm);
247                 strlcat(fmtm, ": %m", sizeof fmtm);
248                 vsyslog(prio, fmtm, ap);
249         } else if (conf_logerr)
250         /* if (prio < LOG_NOTICE) */
251                 vwarn(fmt, ap);
252         va_end(ap);
253 }