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 } 254