File: | src/games/hunt/huntd/answer.c |
Warning: | line 172, column 2 Value stored to 'cp1' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: answer.c,v 1.22 2017/01/21 08:22:57 krw Exp $ */ |
2 | /* $NetBSD: answer.c,v 1.3 1997/10/10 16:32:50 lukem Exp $ */ |
3 | /* |
4 | * Copyright (c) 1983-2003, Regents of the University of California. |
5 | * All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions are |
9 | * met: |
10 | * |
11 | * + Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. |
13 | * + Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. |
16 | * + Neither the name of the University of California, San Francisco nor |
17 | * the names of its contributors may be used to endorse or promote |
18 | * products derived from this software without specific prior written |
19 | * permission. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
22 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
23 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ |
33 | |
34 | #include <sys/select.h> |
35 | |
36 | #include <arpa/inet.h> |
37 | #include <netinet/in.h> |
38 | |
39 | #include <ctype.h> |
40 | #include <fcntl.h> |
41 | #include <stdlib.h> |
42 | #include <string.h> |
43 | #include <syslog.h> |
44 | #include <unistd.h> |
45 | |
46 | #include "conf.h" |
47 | #include "hunt.h" |
48 | #include "server.h" |
49 | |
50 | /* Exported symbols for hosts_access(): */ |
51 | int allow_severity = LOG_INFO6; |
52 | int deny_severity = LOG_WARNING4; |
53 | |
54 | |
55 | /* List of spawning connections: */ |
56 | struct spawn *Spawn = NULL((void *)0); |
57 | |
58 | static void stplayer(PLAYER *, int); |
59 | static void stmonitor(PLAYER *); |
60 | static IDENT * get_ident(struct sockaddr *, int, u_long, char *, char); |
61 | |
62 | void |
63 | answer_first(void) |
64 | { |
65 | struct sockaddr sockstruct; |
66 | int newsock; |
67 | socklen_t socklen; |
68 | struct spawn *sp; |
69 | |
70 | /* |
71 | * Answer the call to hunt, turning off blocking I/O, so a slow |
72 | * or dead terminal won't stop the game. All subsequent reads |
73 | * check how many bytes they read. |
74 | */ |
75 | socklen = sizeof sockstruct; |
76 | newsock = accept4(Socket, (struct sockaddr *) &sockstruct, &socklen, |
77 | SOCK_NONBLOCK0x4000); |
78 | if (newsock < 0) { |
79 | logit(LOG_ERR3, "accept"); |
80 | return; |
81 | } |
82 | |
83 | /* Remember this spawning connection: */ |
84 | sp = calloc(1, sizeof *sp); |
85 | if (sp == NULL((void *)0)) { |
86 | logit(LOG_ERR3, "calloc"); |
87 | close(newsock); |
88 | return; |
89 | } |
90 | |
91 | /* Keep the calling machine's source addr for ident purposes: */ |
92 | memcpy(&sp->source, &sockstruct, sizeof sp->source); |
93 | sp->sourcelen = socklen; |
94 | |
95 | /* Warn if we lose connection info: */ |
96 | if (socklen > sizeof Spawn->source) |
97 | logx(LOG_WARNING4, |
98 | "struct sockaddr is not big enough! (%d > %zu)", |
99 | socklen, sizeof Spawn->source); |
100 | |
101 | /* Start listening to the spawning connection */ |
102 | sp->fd = newsock; |
103 | FD_SET(sp->fd, &Fds_mask)__fd_set((sp->fd), (&Fds_mask)); |
104 | if (sp->fd >= Num_fds) |
105 | Num_fds = sp->fd + 1; |
106 | |
107 | sp->reading_msg = 0; |
108 | sp->inlen = 0; |
109 | |
110 | /* Add to the spawning list */ |
111 | if ((sp->next = Spawn) != NULL((void *)0)) |
112 | Spawn->prevnext = &sp->next; |
113 | sp->prevnext = &Spawn; |
114 | Spawn = sp; |
115 | } |
116 | |
117 | int |
118 | answer_next(struct spawn *sp) |
119 | { |
120 | PLAYER *pp; |
121 | char *cp1, *cp2; |
122 | u_int32_t version; |
123 | FILE *conn; |
124 | int len; |
125 | char teamstr[] = "[x]"; |
126 | |
127 | if (sp->reading_msg) { |
128 | /* Receive a message from a player */ |
129 | len = read(sp->fd, sp->msg + sp->msglen, |
130 | sizeof sp->msg - sp->msglen); |
131 | if (len < 0) |
132 | goto error; |
133 | sp->msglen += len; |
134 | if (len && sp->msglen < sizeof sp->msg) |
135 | return FALSE0; |
136 | |
137 | teamstr[1] = sp->team; |
138 | outyx(ALL_PLAYERS((PLAYER *)1), HEIGHT23, 0, "%s%s: %.*s", |
139 | sp->name, |
140 | sp->team == ' ' ? "": teamstr, |
141 | sp->msglen, |
142 | sp->msg); |
143 | ce(ALL_PLAYERS((PLAYER *)1)); |
144 | sendcom(ALL_PLAYERS((PLAYER *)1), REFRESH('r' | 0200)); |
145 | sendcom(ALL_PLAYERS((PLAYER *)1), READY('g' | 0200), 0); |
146 | flush(ALL_PLAYERS((PLAYER *)1)); |
147 | goto close_it; |
148 | } |
149 | |
150 | /* Fill the buffer */ |
151 | len = read(sp->fd, sp->inbuf + sp->inlen, |
152 | sizeof sp->inbuf - sp->inlen); |
153 | if (len <= 0) |
154 | goto error; |
155 | sp->inlen += len; |
156 | if (sp->inlen < sizeof sp->inbuf) |
157 | return FALSE0; |
158 | |
159 | /* Extract values from the buffer */ |
160 | cp1 = sp->inbuf; |
161 | memcpy(&sp->uid, cp1, sizeof (u_int32_t)); |
162 | cp1+= sizeof(u_int32_t); |
163 | memcpy(sp->name, cp1, NAMELEN20); |
164 | cp1+= NAMELEN20; |
165 | memcpy(&sp->team, cp1, sizeof (u_int8_t)); |
166 | cp1+= sizeof(u_int8_t); |
167 | memcpy(&sp->enter_status, cp1, sizeof (u_int32_t)); |
168 | cp1+= sizeof(u_int32_t); |
169 | memcpy(sp->ttyname, cp1, NAMELEN20); |
170 | cp1+= NAMELEN20; |
171 | memcpy(&sp->mode, cp1, sizeof (u_int32_t)); |
172 | cp1+= sizeof(u_int32_t); |
Value stored to 'cp1' is never read | |
173 | |
174 | /* Convert data from network byte order: */ |
175 | sp->uid = ntohl(sp->uid)(__uint32_t)(__builtin_constant_p(sp->uid) ? (__uint32_t)( ((__uint32_t)(sp->uid) & 0xff) << 24 | ((__uint32_t )(sp->uid) & 0xff00) << 8 | ((__uint32_t)(sp-> uid) & 0xff0000) >> 8 | ((__uint32_t)(sp->uid) & 0xff000000) >> 24) : __swap32md(sp->uid)); |
176 | sp->enter_status = ntohl(sp->enter_status)(__uint32_t)(__builtin_constant_p(sp->enter_status) ? (__uint32_t )(((__uint32_t)(sp->enter_status) & 0xff) << 24 | ((__uint32_t)(sp->enter_status) & 0xff00) << 8 | ((__uint32_t)(sp->enter_status) & 0xff0000) >> 8 | ((__uint32_t)(sp->enter_status) & 0xff000000) >> 24) : __swap32md(sp->enter_status)); |
177 | sp->mode = ntohl(sp->mode)(__uint32_t)(__builtin_constant_p(sp->mode) ? (__uint32_t) (((__uint32_t)(sp->mode) & 0xff) << 24 | ((__uint32_t )(sp->mode) & 0xff00) << 8 | ((__uint32_t)(sp-> mode) & 0xff0000) >> 8 | ((__uint32_t)(sp->mode) & 0xff000000) >> 24) : __swap32md(sp->mode)); |
178 | |
179 | /* |
180 | * Make sure the name contains only printable characters |
181 | * since we use control characters for cursor control |
182 | * between driver and player processes |
183 | */ |
184 | sp->name[NAMELEN20] = '\0'; |
185 | for (cp1 = cp2 = sp->name; *cp1 != '\0'; cp1++) |
186 | if (isprint((unsigned char)*cp1) || *cp1 == ' ') |
187 | *cp2++ = *cp1; |
188 | *cp2 = '\0'; |
189 | |
190 | /* Make sure team name is valid */ |
191 | if (sp->team < '1' || sp->team > '9') |
192 | sp->team = ' '; |
193 | |
194 | /* Tell the other end this server's hunt driver version: */ |
195 | version = htonl((u_int32_t) HUNT_VERSION)(__uint32_t)(__builtin_constant_p((u_int32_t) (-1)) ? (__uint32_t )(((__uint32_t)((u_int32_t) (-1)) & 0xff) << 24 | ( (__uint32_t)((u_int32_t) (-1)) & 0xff00) << 8 | ((__uint32_t )((u_int32_t) (-1)) & 0xff0000) >> 8 | ((__uint32_t )((u_int32_t) (-1)) & 0xff000000) >> 24) : __swap32md ((u_int32_t) (-1))); |
196 | (void) write(sp->fd, &version, sizeof version); |
197 | |
198 | if (sp->mode == C_MESSAGE2) { |
199 | /* The clients only wants to send a message: */ |
200 | sp->msglen = 0; |
201 | sp->reading_msg = 1; |
202 | return FALSE0; |
203 | } |
204 | |
205 | /* Use a stdio file descriptor from now on: */ |
206 | conn = fdopen(sp->fd, "w"); |
207 | |
208 | /* The player is a monitor: */ |
209 | if (sp->mode == C_MONITOR1) { |
210 | if (conf_monitor && End_monitor < &Monitor[MAXMON2]) { |
211 | pp = End_monitor++; |
212 | if (sp->team == ' ') |
213 | sp->team = '*'; |
214 | } else { |
215 | /* Too many monitors */ |
216 | fprintf(conn, "Too many monitors\n"); |
217 | fflush(conn); |
218 | logx(LOG_NOTICE5, "too many monitors"); |
219 | goto close_it; |
220 | } |
221 | |
222 | /* The player is a normal hunter: */ |
223 | } else { |
224 | if (End_player < &Player[MAXPL14]) |
225 | pp = End_player++; |
226 | else { |
227 | fprintf(conn, "Too many players\n"); |
228 | fflush(conn); |
229 | /* Too many players */ |
230 | logx(LOG_NOTICE5, "too many players"); |
231 | goto close_it; |
232 | } |
233 | } |
234 | |
235 | /* Find the player's running scorecard */ |
236 | pp->p_ident = get_ident(&sp->source, sp->sourcelen, sp->uid, |
237 | sp->name, sp->team); |
238 | pp->p_output = conn; |
239 | pp->p_death[0] = '\0'; |
240 | pp->p_fd = sp->fd; |
241 | |
242 | /* No idea where the player starts: */ |
243 | pp->p_y = 0; |
244 | pp->p_x = 0; |
245 | |
246 | /* Mode-specific initialisation: */ |
247 | if (sp->mode == C_MONITOR1) |
248 | stmonitor(pp); |
249 | else |
250 | stplayer(pp, sp->enter_status); |
251 | |
252 | /* And, they're off! Caller should remove and free sp. */ |
253 | return TRUE1; |
254 | |
255 | error: |
256 | if (len < 0) |
257 | logit(LOG_WARNING4, "read"); |
258 | else |
259 | logx(LOG_WARNING4, "lost connection to new client"); |
260 | |
261 | close_it: |
262 | /* Destroy the spawn */ |
263 | *sp->prevnext = sp->next; |
264 | if (sp->next) sp->next->prevnext = sp->prevnext; |
265 | FD_CLR(sp->fd, &Fds_mask)__fd_clr((sp->fd), (&Fds_mask)); |
266 | close(sp->fd); |
267 | free(sp); |
268 | return FALSE0; |
269 | } |
270 | |
271 | /* Start a monitor: */ |
272 | static void |
273 | stmonitor(PLAYER *pp) |
274 | { |
275 | |
276 | /* Monitors get to see the entire maze: */ |
277 | memcpy(pp->p_maze, Maze, sizeof pp->p_maze); |
278 | drawmaze(pp); |
279 | |
280 | /* Put the monitor's name near the bottom right on all screens: */ |
281 | outyx(ALL_PLAYERS((PLAYER *)1), |
282 | STAT_MON_ROW(5 + 14 + 1) + 1 + (pp - Monitor), STAT_NAME_COL61, |
283 | "%5.5s%c%-10.10s %c", " ", |
284 | stat_char(pp)(((pp)->p_flying < 0) ? (((pp)->p_cloak < 0) ? (( (pp)->p_scan < 0) ? ' ' : '*') : '+') : '&'), pp->p_ident->i_name, pp->p_ident->i_team); |
285 | |
286 | /* Ready the monitor: */ |
287 | sendcom(pp, REFRESH('r' | 0200)); |
288 | sendcom(pp, READY('g' | 0200), 0); |
289 | flush(pp); |
290 | } |
291 | |
292 | /* Start a player: */ |
293 | static void |
294 | stplayer(PLAYER *newpp, int enter_status) |
295 | { |
296 | int x, y; |
297 | PLAYER *pp; |
298 | int len; |
299 | |
300 | Nplayer++; |
301 | |
302 | for (y = 0; y < UBOUND1; y++) |
303 | for (x = 0; x < WIDTH51; x++) |
304 | newpp->p_maze[y][x] = Maze[y][x]; |
305 | for ( ; y < DBOUND(23 - 1); y++) { |
306 | for (x = 0; x < LBOUND1; x++) |
307 | newpp->p_maze[y][x] = Maze[y][x]; |
308 | for ( ; x < RBOUND(51 - 1); x++) |
309 | newpp->p_maze[y][x] = SPACE' '; |
310 | for ( ; x < WIDTH51; x++) |
311 | newpp->p_maze[y][x] = Maze[y][x]; |
312 | } |
313 | for ( ; y < HEIGHT23; y++) |
314 | for (x = 0; x < WIDTH51; x++) |
315 | newpp->p_maze[y][x] = Maze[y][x]; |
316 | |
317 | /* Drop the new player somewhere in the maze: */ |
318 | do { |
319 | x = rand_num(WIDTH51 - 1) + 1; |
320 | y = rand_num(HEIGHT23 - 1) + 1; |
321 | } while (Maze[y][x] != SPACE' '); |
322 | newpp->p_over = SPACE' '; |
323 | newpp->p_x = x; |
324 | newpp->p_y = y; |
325 | newpp->p_undershot = FALSE0; |
326 | |
327 | /* Send them flying if needed */ |
328 | if (enter_status == Q_FLY2 && conf_fly) { |
329 | newpp->p_flying = rand_num(conf_flytime); |
330 | newpp->p_flyx = 2 * rand_num(conf_flystep + 1) - conf_flystep; |
331 | newpp->p_flyy = 2 * rand_num(conf_flystep + 1) - conf_flystep; |
332 | newpp->p_face = FLYER'&'; |
333 | } else { |
334 | newpp->p_flying = -1; |
335 | newpp->p_face = rand_dir(); |
336 | } |
337 | |
338 | /* Initialize the new player's attributes: */ |
339 | newpp->p_damage = 0; |
340 | newpp->p_damcap = conf_maxdam; |
341 | newpp->p_nchar = 0; |
342 | newpp->p_ncount = 0; |
343 | newpp->p_nexec = 0; |
344 | newpp->p_ammo = conf_ishots; |
345 | newpp->p_nboots = 0; |
346 | |
347 | /* Decide on what cloak/scan status to enter with */ |
348 | if (enter_status == Q_SCAN3 && conf_scan) { |
349 | newpp->p_scan = conf_scanlen * Nplayer; |
350 | newpp->p_cloak = 0; |
351 | } else if (conf_cloak) { |
352 | newpp->p_scan = 0; |
353 | newpp->p_cloak = conf_cloaklen; |
354 | } else { |
355 | newpp->p_scan = 0; |
356 | newpp->p_cloak = 0; |
357 | } |
358 | newpp->p_ncshot = 0; |
359 | |
360 | /* |
361 | * For each new player, place a large mine and |
362 | * a small mine somewhere in the maze: |
363 | */ |
364 | do { |
365 | x = rand_num(WIDTH51 - 1) + 1; |
366 | y = rand_num(HEIGHT23 - 1) + 1; |
367 | } while (Maze[y][x] != SPACE' '); |
368 | Maze[y][x] = GMINE'g'; |
369 | for (pp = Monitor; pp < End_monitor; pp++) |
370 | check(pp, y, x); |
371 | |
372 | do { |
373 | x = rand_num(WIDTH51 - 1) + 1; |
374 | y = rand_num(HEIGHT23 - 1) + 1; |
375 | } while (Maze[y][x] != SPACE' '); |
376 | Maze[y][x] = MINE';'; |
377 | for (pp = Monitor; pp < End_monitor; pp++) |
378 | check(pp, y, x); |
379 | |
380 | /* Create a score line for the new player: */ |
381 | (void) snprintf(Buf, sizeof Buf, "%5.2f%c%-10.10s %c", |
382 | newpp->p_ident->i_score, stat_char(newpp)(((newpp)->p_flying < 0) ? (((newpp)->p_cloak < 0 ) ? (((newpp)->p_scan < 0) ? ' ' : '*') : '+') : '&' ), |
383 | newpp->p_ident->i_name, newpp->p_ident->i_team); |
384 | len = strlen(Buf); |
385 | y = STAT_PLAY_ROW5 + 1 + (newpp - Player); |
386 | for (pp = Player; pp < End_player; pp++) { |
387 | if (pp != newpp) { |
388 | /* Give everyone a few more shots: */ |
389 | pp->p_ammo += conf_nshots; |
390 | newpp->p_ammo += conf_nshots; |
391 | outyx(pp, y, STAT_NAME_COL61, Buf, len); |
392 | ammo_update(pp); |
393 | } |
394 | } |
395 | for (pp = Monitor; pp < End_monitor; pp++) |
396 | outyx(pp, y, STAT_NAME_COL61, Buf, len); |
397 | |
398 | /* Show the new player what they can see and where they are: */ |
399 | drawmaze(newpp); |
400 | drawplayer(newpp, TRUE1); |
401 | look(newpp); |
402 | |
403 | /* Make sure that the position they enter in will be erased: */ |
404 | if (enter_status == Q_FLY2 && conf_fly) |
405 | showexpl(newpp->p_y, newpp->p_x, FLYER'&'); |
406 | |
407 | /* Ready the new player: */ |
408 | sendcom(newpp, REFRESH('r' | 0200)); |
409 | sendcom(newpp, READY('g' | 0200), 0); |
410 | flush(newpp); |
411 | } |
412 | |
413 | /* |
414 | * rand_dir: |
415 | * Return a random direction |
416 | */ |
417 | int |
418 | rand_dir(void) |
419 | { |
420 | switch (rand_num(4)) { |
421 | case 0: |
422 | return LEFTS'{'; |
423 | case 1: |
424 | return RIGHT'}'; |
425 | case 2: |
426 | return BELOW'!'; |
427 | case 3: |
428 | return ABOVE'i'; |
429 | } |
430 | return(-1); |
431 | } |
432 | |
433 | /* |
434 | * get_ident: |
435 | * Get the score structure of a player |
436 | */ |
437 | static IDENT * |
438 | get_ident(struct sockaddr *sa, int salen, u_long uid, char *name, char team) |
439 | { |
440 | IDENT *ip; |
441 | static IDENT punt; |
442 | u_int32_t machine; |
443 | |
444 | if (sa->sa_family == AF_INET2) |
445 | machine = ntohl((u_long)((struct sockaddr_in *)sa)->sin_addr.s_addr)(__uint32_t)(__builtin_constant_p((u_long)((struct sockaddr_in *)sa)->sin_addr.s_addr) ? (__uint32_t)(((__uint32_t)((u_long )((struct sockaddr_in *)sa)->sin_addr.s_addr) & 0xff) << 24 | ((__uint32_t)((u_long)((struct sockaddr_in *)sa)->sin_addr .s_addr) & 0xff00) << 8 | ((__uint32_t)((u_long)((struct sockaddr_in *)sa)->sin_addr.s_addr) & 0xff0000) >> 8 | ((__uint32_t)((u_long)((struct sockaddr_in *)sa)->sin_addr .s_addr) & 0xff000000) >> 24) : __swap32md((u_long) ((struct sockaddr_in *)sa)->sin_addr.s_addr)); |
446 | else |
447 | machine = 0; |
448 | |
449 | for (ip = Scores; ip != NULL((void *)0); ip = ip->i_next) |
450 | if (ip->i_machine == machine |
451 | && ip->i_uid == uid |
452 | /* && ip->i_team == team */ |
453 | && strncmp(ip->i_name, name, NAMELEN20) == 0) |
454 | break; |
455 | |
456 | if (ip != NULL((void *)0)) { |
457 | if (ip->i_team != team) { |
458 | logx(LOG_INFO6, "player %s %s team %c", |
459 | name, |
460 | team == ' ' ? "left" : ip->i_team == ' ' ? |
461 | "joined" : "changed to", |
462 | team == ' ' ? ip->i_team : team); |
463 | ip->i_team = team; |
464 | } |
465 | if (ip->i_entries < conf_scoredecay) |
466 | ip->i_entries++; |
467 | else |
468 | ip->i_kills = (ip->i_kills * (conf_scoredecay - 1)) |
469 | / conf_scoredecay; |
470 | ip->i_score = ip->i_kills / (double) ip->i_entries; |
471 | } |
472 | else { |
473 | /* Alloc new entry -- it is released in clear_scores() */ |
474 | ip = malloc(sizeof (IDENT)); |
475 | if (ip == NULL((void *)0)) { |
476 | logit(LOG_ERR3, "malloc"); |
477 | /* Fourth down, time to punt */ |
478 | ip = &punt; |
479 | } |
480 | ip->i_machine = machine; |
481 | ip->i_team = team; |
482 | ip->i_uid = uid; |
483 | strlcpy(ip->i_name, name, sizeof ip->i_name); |
484 | ip->i_kills = 0; |
485 | ip->i_entries = 1; |
486 | ip->i_score = 0; |
487 | ip->i_absorbed = 0; |
488 | ip->i_faced = 0; |
489 | ip->i_shot = 0; |
490 | ip->i_robbed = 0; |
491 | ip->i_slime = 0; |
492 | ip->i_missed = 0; |
493 | ip->i_ducked = 0; |
494 | ip->i_gkills = ip->i_bkills = ip->i_deaths = 0; |
495 | ip->i_stillb = ip->i_saved = 0; |
496 | ip->i_next = Scores; |
497 | Scores = ip; |
498 | |
499 | logx(LOG_INFO6, "new player: %s%s%c%s", |
500 | name, |
501 | team == ' ' ? "" : " (team ", |
502 | team, |
503 | team == ' ' ? "" : ")"); |
504 | } |
505 | |
506 | return ip; |
507 | } |
508 | |
509 | void |
510 | answer_info(FILE *fp) |
511 | { |
512 | struct spawn *sp; |
513 | char buf[128]; |
514 | const char *bf; |
515 | struct sockaddr_in *sa; |
516 | |
517 | if (Spawn == NULL((void *)0)) |
518 | return; |
519 | fprintf(fp, "\nSpawning connections:\n"); |
520 | for (sp = Spawn; sp; sp = sp->next) { |
521 | sa = (struct sockaddr_in *)&sp->source; |
522 | bf = inet_ntop(AF_INET2, &sa->sin_addr, buf, sizeof buf); |
523 | if (!bf) { |
524 | logit(LOG_WARNING4, "inet_ntop"); |
525 | bf = "?"; |
526 | } |
527 | fprintf(fp, "fd %d: state %d, from %s:%d\n", |
528 | sp->fd, sp->inlen + (sp->reading_msg ? sp->msglen : 0), |
529 | bf, sa->sin_port); |
530 | } |
531 | } |