1 /*---------------------------------------------------------------------------
2  * Gamedriver Communications module.
3  *
4  *---------------------------------------------------------------------------
5  * Throughout the module the fact is used that valid socket numbers
6  * are always >= 0. Unused sockets are therefore marked with negative
7  * numbers.
8  *
9  * All information needed for an interactive object are stored in
10  * a 'interactive_t'. This struct is linked to by the shadow sentence
11  * of the interactive object.
12  *
13  * Sending data is performed through the function add_message().
14  * The function collects the data in interactive.message_buf[] until
15  * it is filled (or a special 'flush' message is passed), then the
16  * data is written en-bloc to the network.
17  *
18  * Incoming data is collected in interactive.text[]. interactive.text_end
19  * indexes the first free character in the buffer where new data is to
20  * be appended. The new data is not passed directly to the command parser,
21  * instead it is processed by a dfa implementing the important parts
22  * of the telnet protocol. The dfa analyses the data read, interprets
23  * any telnet commands and stores the remaining 'pure' data starting
24  * from the beginning of .text[].
25  *
26  * Initialized to start working in the state TS_DATA, the dfa does its
27  * thing until it either reaches a line end or the end of the current
28  * data. If it is a line end, it terminates the pure data collected so
29  * far with a '\0', goes into state TS_READY, and lets .tn_end index
30  * the next unprocessed raw data char. If it is the end of the current
31  * data, the dfa stays in whatever state it was and indexes the current end
32  * of the pure data gathered so far with interactive.command_end. Once
33  * a new chunk of data has been read, the dfa simply continues where it
34  * took off.
35  *
36  * There are some variations to this scheme, but you get the idea. It is
37  * possible to do all telnet negotiations on mudlib level, but it must
38  * be either the driver or the mudlib, not both.
39  *
40  * To understand get_message() itself fully, think of it as a coroutine
41  * with its own state. It does not really return to the caller (though
42  * that is how it is implemented), in merely yields control back to
43  * caller in order to process the found command or the pending heartbeat.
44  * TODO: Obvious possibility for implementation multi-threading.
45  *
46  * Timing is implemented this way: The driver usually stays in the input
47  * loop, waiting in 1 second intervals for incoming data. An alarm() is
48  * triggered by backend.c every 2 seconds and sets the flag variable
49  * comm_time_to_call_heart_beat. The loop checks this variable every second
50  * and, if it is set, aborts its input loop and returns to the backend.
51  * To mark the cause of the return, the variable time_to_call_heart_beat is
52  * set before return.
53  *
54  * TODO: The noecho/charmode logic, especially in combination with
55  * TODO:: the telnet machine is frustratingly underdocumented.
56  *
57  * The data that can not written directly to the sockets is put instead into
58  * an intermediate buffer, from which the backend loop will continue writing
59  * when possible. The buffers are stored in a linked list in the interactive_s
60  * structure.
61  *
62  * TODO: Fiona says: The telnet code is frustrating. It would be better if
63  * TODO:: the common handling of e.g. TELNET_NAWS is offered by hooks,
64  * TODO:: as the Anarres version of MudOS does. This would mean a rewrite.
65  *---------------------------------------------------------------------------
66  */
67 
68 #define SAVE_NOECHO       /* TODO: Define to enable safe NOECHO mode */
69 #define SIMULATE_CHARMODE /* TODO: Even linemode clients stay in charmode */
70 
71 #include "driver.h"
72 #include "typedefs.h"
73 
74 #include "my-alloca.h"
75 
76 #include <stdio.h>
77 #include <ctype.h>
78 #include <sys/time.h>
79 #include <stdarg.h>
80 #include <stddef.h>
81 #include <sys/ioctl.h>
82 
83 #define TELOPTS
84 #include "../mudlib/sys/telnet.h"
85 
86 #ifdef HAVE_NETDB_H
87 #    include <netdb.h>
88 #endif
89 
90 #ifdef HAVE_SYS_PARAM_H
91 #    include <sys/param.h>
92 #endif
93 
94 #include <signal.h>
95 
96 #if defined(_AIX)
97 #    include <sys/select.h>
98 #endif
99 
100 #ifdef HAVE_FCNTL
101 #    include <fcntl.h>
102 #endif
103 
104 #ifdef SOCKET_INC
105 #    include SOCKET_INC
106 #endif
107 
108 #include "comm.h"
109 #include "access_check.h"
110 #include "actions.h"
111 #include "array.h"
112 #include "closure.h"
113 #include "ed.h"
114 #include "exec.h"
115 #include "filestat.h"
116 #include "gcollect.h"
117 #include "interpret.h"
118 #include "main.h"
119 #include "mstrings.h"
120 #include "object.h"
121 #include "pkg-mccp.h"
122 #include "pkg-pgsql.h"
123 #ifdef USE_TLS
124 #include "pkg-tls.h"
125 #endif
126 #include "sent.h"
127 #include "simulate.h"
128 #include "stdstrings.h"
129 #include "svalue.h"
130 #include "swap.h"
131 #include "wiz_list.h"
132 #include "xalloc.h"
133 
134 #include "i-eval_cost.h"
135 
136 #include "../mudlib/sys/comm.h"
137 #include "../mudlib/sys/configuration.h"
138 #include "../mudlib/sys/driver_hook.h"
139 #include "../mudlib/sys/input_to.h"
140 
141 /* if driver is compiled for ERQ demon then include the necessary file
142  */
143 #ifdef ERQ_DEMON
144 #    ifdef ERQ_INCLUDE
145 #        include ERQ_INCLUDE
146 #    else
147 #        include "util/erq/erq.h"
148 #    endif
149 #endif
150 
151 /* When no special networking code is needed, define the
152  * socket function to their normal Unix names.
153  */
154 #if !defined (SOCKET_LIB) && !defined(SOCKET_INC)
155 #    define socket_number(s) (s)
156 #    define socket_ioctl  ioctl
157 #    ifndef hpux
158 #        define socket_select select
159 #    else
160 #        define socket_select(n,r,w,x,t) select(n, (int *)r, (int *)w, (int *)x, t)
161          /* Silences the compiler */
162 #    endif
163 #    define socket_read   read
164 #    define socket_write  write
165 #    define socket_close  close
166 #endif /* SOCKET_LIB */
167 
168 #if defined(_AIX)
169 typedef unsigned long length_t;
170 #elif defined(__INTEL_COMPILER) || defined (__GNUC__)
171 typedef socklen_t length_t;
172 #else
173 typedef int length_t;
174 #endif
175 
176 #if defined(CYGWIN)
177 extern int socketpair(int, int, int, int[2]);
178 #endif
179 
180 #ifndef EPROTO
181 #    define EPROTO EINTR
182 #endif
183 #ifndef SIGCLD
184 #    define SIGCLD SIGCHLD
185 #endif
186 
187 #ifndef MAXHOSTNAMELEN
188 #    define MAXHOSTNAMELEN 64
189 #endif
190 
191 #ifndef INET_ADDRSTRLEN
192 #    define INET_ADDRSTRLEN 16
193 #endif
194 
195 /* Amazing how complicated networking can be, hm? */
196 
197 /*-------------------------------------------------------------------------*/
198 /* Types */
199 
200 /* --- struct input_to_s: input_to() datastructure
201  *
202  * input-to structures describe a pending input_to() for a given
203  * interactive object. It is a specialization of input_s,
204  * which therefore must be the first element.
205  */
206 typedef struct input_to_s input_to_t;
207 
208 struct input_to_s {
209     input_t     input;
210     callback_t  fun;        /* The function to call, and its args */
211     p_uint      eval_nr;    /* The thread number where this started. */
212 };
213 
214 /*-------------------------------------------------------------------------*/
215 /* Variables */
216 
217 interactive_t *all_players[MAX_PLAYERS];
218   /* Pointers to the structures of the interactive users.
219    * Unused entries are NULL.
220    * TODO: A list would be nicer
221    */
222 
223 static int max_player = -1;
224   /* Index of the last used entry in all_players[]. */
225 
226 int num_player = 0;
227   /* The current number of active users */
228 
229 char *message_flush = NULL;
230   /* Special flush message for add_message().
231    * It is a variable instead of a define to keep gcc from complaining about
232    * a 'null format string'.
233    */
234 
235 p_int write_buffer_max_size = WRITE_BUFFER_MAX_SIZE;
236   /* Amount of data held pending in the write fifo queue.
237    *   0: No queue.
238    *  -1: Infinite queue.
239    */
240 
241 static char udp_buf[65536];
242   /* Buffer for incoming UDP datagrams in get_message().
243    * If it is too small, the rest of the to be received datagram will be
244    * discarded. As UDP datagrams get be as large as (65536 - UDP-Header -
245    * IP-Header) we will just play safe here.
246    * static (file-scope) buffer, because we don't want to allocate such a
247    * large buffer on the stack or by xalloc (it is used often, we're not
248    * multi-threaded nor is get_message() re-entrant).
249    * Note for IPv6: IPv6 supports so-called jumbograms with payloads up to
250    * 2^32-1 octets in length (rfc2675). Obviously, we don't support that. ;-)
251    */
252 
253 #ifdef COMM_STAT
254 
255 /* The statistics were originally introduced to measure the efficiency
256  * of the message buffering in comparison to the unbuffered sending of
257  * data. Nowadays, it's just interesting to know how much bandwidth you
258  * use.
259  */
260 
261 unsigned long add_message_calls = 0;
262   /* Number of calls to add_message() */
263 
264 unsigned long inet_packets = 0;
265   /* Number packets sent to the users */
266 
267 unsigned long inet_volume = 0;
268   /* Amount of data sent to the users */
269 
270 unsigned long inet_packets_in = 0;
271   /* Number packets received from the users */
272 
273 unsigned long inet_volume_in = 0;
274   /* Amount of data received from the users */
275 
276 #endif
277 
278 /*-------------------------------------------------------------------------*/
279 
280 #ifdef ERQ_DEMON
281 
282 #define MAX_PENDING_ERQ  32  /* Max number of pending requests */
283 
284 #define FLAG_NO_ERQ   -2    /* No ERQ connected */
285 #define FLAG_ERQ_STOP -1    /* Severing connection */
286 
287 static SOCKET_T erq_demon = FLAG_NO_ERQ;
288   /* Socket of the connection to the erq demon. */
289 
290 static SOCKET_T erq_proto_demon = -1;
291   /* Socket to hold the connection to an aspiring new erq demon
292    * while the connection to the current one is being severed.
293    */
294 
295 static char buf_from_erq[ERQ_MAX_REPLY];
296   /* Buffer for the data received from the erq */
297 
298 static char * input_from_erq = &buf_from_erq[0];
299   /* Pointer to the first free byte in buf_from_erq. */
300 
301 static unsigned long erq_pending_len = 0;
302   /* erq_pending_len is used by send_erq(), but needs
303    * to be cleared by stop_erq_demon().
304    */
305 
306 typedef struct erq_callback_s {
307     svalue_t fun;
308     Bool     string_arg;
309 } erq_callback_t;
310 
311 static erq_callback_t pending_erq[MAX_PENDING_ERQ+1];
312   /* ERQ callback handles. The last one is reserved for callback-free
313    * requests.
314    * .fun is the callback closure, .string_arg is TRUE if the closure
315    * takes its data as a string instead of an array as argument.
316    *
317    * The free entries are organised in a singly linked list of
318    * T_INVALID .fun svalues, using the .fun.u.generic to point to the next
319    * free entry.
320    */
321 
322 static erq_callback_t *free_erq;
323   /* The first free entry in the freelist in pending_erq[] */
324 
325 /* The size of the IPTABLE depends on the number of users,
326  * and is at least 200.
327  */
328 #if MAX_PLAYERS > 700
329 #    define IPSIZE MAX_PLAYERS
330 #else
331 #    if MAX_PLAYERS > 100
332 #        define IPSIZE (MAX_PLAYERS*2)
333 #    else
334 #        define IPSIZE 200
335 #    endif
336 #endif
337 
338 static struct ipentry {
339     struct in_addr  addr;  /* The address (only .s_addr is significant) */
340     string_t       *name;  /* tabled string with the hostname for <addr> */
341 } iptable[IPSIZE];
342   /* Cache of known names for given IP addresses.
343    * It is used as a ringbuffer, indexed by ipcur.
344    * TODO: Instead of a simple circular buffer, the lookup should be
345    * TODO:: hashed over the IP address. Worst case would still be O(IPSIZE),
346    * TODO:: but best case would be O(1).
347    * TODO: Allow unlimited numbers of entries, but give them a max lifetime
348    * TODO:: of a day. After that, even existing entries need to be
349    * TODO:: re-resolved. Maybe an additional size limit. (suggested by Coogan)
350    */
351 
352 static int ipcur = 0;
353   /* Index of the next entry to use in the iptable[].
354    */
355 
356 #endif /* ERQ_DEMON */
357 
358 /*-------------------------------------------------------------------------*/
359 
360 /* --- Communication sockets --- */
361 
362 static SOCKET_T sos[MAXNUMPORTS];
363   /* The login sockets.
364    */
365 
366 static SOCKET_T udp_s = -1;
367   /* The UDP socket */
368 
369 /* --- Networking information --- */
370 
371 static char host_name[MAXHOSTNAMELEN+1];
372   /* This computer's hostname, used for query_host_name() efun.
373    */
374 
375 static struct in_addr host_ip_number;
376   /* This computer's numeric IP address only, used for
377    * the query_host_ip_number() efun.
378    */
379 
380 static struct sockaddr_in host_ip_addr_template;
381   /* The template address of this computer. It is copied locally
382    * and augmented with varying port numbers to open the driver's ports.
383    */
384 
385 char * domain_name = NULL;
386   /* This computer's domain name, as needed by lex.c::get_domainname().
387    */
388 
389 static int min_nfds = 0;
390   /* The number of fds used by the driver's sockets (udp, erq, login).
391    * It is the number of the highest fd plus one.
392    */
393 
394 /* --- Telnet handling --- */
395 
396 Bool sending_telnet_command = MY_FALSE;
397   /* Mutex queried in add_message() to hide telnet commands
398    * from snoopers and shadows.
399    */
400 
401 static void (*telopts_do  [NTELOPTS])(int);
402 static void (*telopts_dont[NTELOPTS])(int);
403 static void (*telopts_will[NTELOPTS])(int);
404 static void (*telopts_wont[NTELOPTS])(int);
405 
406   /* Tables with the telnet statemachine handlers.
407    */
408 
409 enum telnet_states {
410   TS_DATA = 0,
411   TS_IAC,
412   TS_WILL,
413   TS_WONT,
414   TS_DO,
415   TS_DONT,
416   TS_SB,
417   TS_SB_IAC,
418   TS_READY,
419   TS_SYNCH,
420   TS_INVALID
421 };
422 
423   /* Telnet states
424    */
425 
TN_START_VALID(int x)426 static inline int TN_START_VALID(int x) {
427   return (x & ~TS_IAC) == TS_SB;
428 }
429 
430 
431 /* --- Misc --- */
432 
433 static volatile Bool urgent_data = MY_FALSE;
434   /* Flag set when a SIGURG/SIGIO announces the arrival of
435    * OOB data.
436    */
437 
438 static volatile mp_int urgent_data_time;
439   /* The backend::current_time when urgent_data was set last.
440    */
441 
442 static interactive_t *first_player_for_flush = NULL;
443   /* First interactive user to flush. Marks the head of the list
444    * formed by interactive.{next,previous}_player_for_flush
445    */
446 
447 
448 /* Bitflags for interactive.do_close
449  *
450  * Putting PROTO_ERQ into do_close looks strange, but actually makes
451  * sense because some of the steps to be taken for both are the
452  * same.
453  */
454 
455 #define FLAG_DO_CLOSE   0x1
456 #define FLAG_PROTO_ERQ  0x2
457 
458 
459 /*-------------------------------------------------------------------------*/
460 
461 /* Outgoing connections in-progress */
462 
463 typedef enum {
464       ocNotUsed    /* Entry not used */
465     , ocUsed       /* Entry holds pending connection */
466     , ocLoggingOn  /* Entry is doing the LPC logon protocol.
467                     * This value should not appear outside of
468                     * check_for_out_connections(), if it does, it
469                     * means that LPC logon threw an error.
470                     */
471 } OutConnStatus;
472 
473 struct OutConn {
474     struct sockaddr_in   target;   /* Address connected to (allocated) */
475     object_t           * curr_obj; /* Associated object */
476     int                  socket;   /* Socket on our side */
477     OutConnStatus        status;   /* Status of this entry */
478 } outconn[MAX_OUTCONN];
479 
480 /*-------------------------------------------------------------------------*/
481 
482 /* Forward declarations */
483 
484 static void mccp_telnet_neg(int);
485 
486 static void free_input_to(input_to_t *);
487 static void free_input_handler(input_t *);
488 static void telnet_neg(interactive_t *);
489 static void send_will(int);
490 static void send_wont(int);
491 static void send_do(int);
492 static void send_dont(int);
493 static void add_flush_entry(interactive_t *ip);
494 static void remove_flush_entry(interactive_t *ip);
495 static void clear_message_buf(interactive_t *ip);
496 static void new_player(object_t *receiver, SOCKET_T new_socket, struct sockaddr_in *addr, size_t len, int login_port);
497 
498 #ifdef ERQ_DEMON
499 
500 static long read_32(char *);
501 static Bool send_erq(int handle, int request, const char *arg, size_t arglen);
502 static void shutdown_erq_demon(void);
503 static void stop_erq_demon(Bool);
504 static string_t * lookup_ip_entry (struct in_addr addr, Bool useErq);
505 static void add_ip_entry(struct in_addr addr, const char *name);
506 #ifdef USE_IPV6
507 static void update_ip_entry(const char *oldname, const char *newname);
508 static int open_ipv6_conn(const char *hostname, const unsigned short int port, struct sockaddr_in *pTarget);
509 #endif
510 
511 #endif /* ERQ_DEMON */
512 
513 static INLINE ssize_t comm_send_buf(char *msg, size_t size, interactive_t *ip);
514 
515 #ifdef USE_IPV6
516 
517 /*-------------------------------------------------------------------------*/
518 
519 /* Not every IPv6 supporting platform has all the defines (like AIX 4.3) */
520 
521 #ifndef IPV6_ADDR_SCOPE_GLOBAL
522 #  define IPV6_ADDR_SCOPE_GLOBAL 0x0e
523 #endif
524 
525 #ifndef s6_addr8
526 #  define s6_addr8  __u6_addr.__u6_addr8
527 #endif
528 
529 #ifndef s6_addr16
530 #  define s6_addr16 __u6_addr.__u6_addr16
531 #endif
532 
533 #ifndef s6_addr32
534 #  define s6_addr32 __u6_addr.__u6_addr32
535 #endif
536 
CREATE_IPV6_MAPPED(struct in_addr * v6,uint32 v4)537 static inline void CREATE_IPV6_MAPPED(struct in_addr *v6, uint32 v4) {
538   v6->s6_addr32[0] = 0;
539   v6->s6_addr32[1] = 0;
540   v6->s6_addr32[2] = 0x0000ffff;
541   v6->s6_addr32[2] = 0xffff0000;
542   v6->s6_addr32[3] = v4;
543 }
544 
545 /* These are the typical IPv6 structures - we use them transparently.
546  *
547  * --- arpa/inet.h ---
548  *
549  * struct in6_addr {
550  *         union {
551  *                 u_int32_t u6_addr32[4];
552  * #ifdef notyet
553  *                 u_int64_t u6_addr64[2];
554  * #endif
555  *                 u_int16_t u6_addr16[8];
556  *                 u_int8_t  u6_addr8[16];
557  *         } u6_addr;
558  * };
559  * #define s6_addr32       u6_addr.u6_addr32
560  * #ifdef notyet
561  * #define s6_addr64       u6_addr.u6_addr64
562  * #endif
563  * #define s6_addr16       u6_addr.u6_addr16
564  * #define s6_addr8        u6_addr.u6_addr8
565  * #define s6_addr         u6_addr.u6_addr8
566  *
567  * --- netinet/in.h ---
568  *
569  * struct sockaddr_in6 {
570  *    u_char                sin6_len;
571  *    u_char                sin6_family;
572  *    u_int16_t        sin6_port;
573  *    u_int32_t        sin6_flowinfo;
574  *    struct                 in6_addr        sin6_addr;
575  * };
576  *
577  */
578 
579 /*-------------------------------------------------------------------------*/
580 static char *
inet6_ntoa(struct in6_addr in)581 inet6_ntoa (struct in6_addr in)
582 
583 /* Convert the ipv6 address <in> into a string and return it.
584  * Note: the string is stored in a local buffer.
585  */
586 
587 {
588     static char str[INET6_ADDRSTRLEN+1];
589 
590     if (NULL == inet_ntop(AF_INET6, &in, str, INET6_ADDRSTRLEN))
591     {
592         perror("inet_ntop");
593     }
594     return str;
595 } /* inet6_ntoa() */
596 
597 /*-------------------------------------------------------------------------*/
598 static struct in6_addr
inet6_addr(const char * to_host)599 inet6_addr (const char *to_host)
600 
601 /* Convert the name <to_host> into a ipv6 address and return it.
602  */
603 
604 {
605     struct in6_addr addr;
606 
607     inet_pton(AF_INET6, to_host, &addr);
608     return addr;
609 } /* inet6_addr() */
610 
611 #endif /* USE_IPV6 */
612 
613 /*-------------------------------------------------------------------------*/
614 static char *
decode_noecho(char noecho)615 decode_noecho (char noecho)
616 
617 /* Decode the <noecho> flag byte into a string.
618  * Result is a pointer to a static buffer.
619  */
620 
621 {
622     static char buf[100];
623     strcpy(buf, "(");
624     if (noecho & NOECHO_REQ) strcat(buf, "NOECHO_REQ, ");
625     if (noecho & CHARMODE_REQ) strcat(buf, "CHARMODE_REQ, ");
626     if (noecho & NOECHO) strcat(buf, "NOECHO, ");
627     if (noecho & CHARMODE) strcat(buf, "CHARMODE, ");
628     if (noecho & NOECHO_ACK) strcat(buf, "NOECHO_ACK, ");
629     if (noecho & CHARMODE_ACK) strcat(buf, "CHARMODE_ACK, ");
630 #ifdef SAVE_NOECHO
631     if (noecho & NOECHO_DELAYED) strcat(buf, "NOECHO_DELAYED, ");
632 #endif
633     if (noecho & NOECHO_STALE) strcat(buf, "NOECHO_STALE, ");
634     if (noecho & IGNORE_BANG) strcat(buf, "IGNORE_BANG");
635     strcat(buf, ")");
636 
637     return buf;
638 } /* decode_noecho() */
639 
640 /*-------------------------------------------------------------------------*/
641 static void
dump_bytes(void * data,size_t length,int indent)642 dump_bytes (void * data, size_t length, int indent)
643 
644 /* Write the datablock starting at <data> of size <length> to stderr.
645  * If it spans more than one line, indent the following lines by <indent>.
646  */
647 
648 {
649     int cur_indent = 0;
650     unsigned char * datap = (unsigned char *)data;
651 
652     while (length > 0)
653     {
654         size_t count;
655 
656         if (cur_indent)
657             fprintf(stderr, "%*.*s", cur_indent, cur_indent, " ");
658         else
659             cur_indent = indent;
660         fprintf(stderr, " %p:", datap);
661 
662         for (count = 0; count < 16 && length > 0; ++count, --length, ++datap)
663         {
664             fprintf(stderr, " %02x", *datap);
665         }
666         putc('\n', stderr);
667     }
668 } /* dump_bytes() */
669 
670 /*-------------------------------------------------------------------------*/
671 static void comm_fatal (interactive_t *ip, char *fmt, ...)
672                           FORMATDEBUG(printf,2,3) ;
673 static void
comm_fatal(interactive_t * ip,char * fmt,...)674 comm_fatal (interactive_t *ip, char *fmt, ...)
675 
676 /* The telnet code ran into a fatal error.
677  * Dump the data from the current interactive structure and disconnect
678  * the user (we have to assume that the interactive structure is
679  * irrecoverably hosed).
680  * TODO: Make similar functions comm_error(), comm_perror() which prefix
681  * TODO:: the error message with the ip %p and obj name.
682  */
683 
684 {
685     va_list va;
686     static Bool in_fatal = MY_FALSE;
687     char * ts;
688     char * msg = "\r\n=== Internal communications error in mud driver.\r\n"
689                    "=== Please log back in and inform the administration.\r\n"
690                    "\r\n";
691 
692     /* Prevent double fatal. */
693     if (in_fatal)
694         fatal("Recursive call to comm_fatal().");
695     in_fatal = MY_TRUE;
696     ts = time_stamp();
697 
698     /* Print the error message */
699 
700     va_start(va, fmt);
701 
702     fflush(stdout);
703     fprintf(stderr, "%s ", ts);
704     vfprintf(stderr, fmt, va);
705     fflush(stderr);
706     if (current_object)
707         fprintf(stderr, "%s Current object was %s\n"
708                       , ts, current_object->name
709                             ? get_txt(current_object->name) : "<null>");
710     debug_message("%s ", ts);
711     vdebug_message(fmt, va);
712     if (current_object)
713         debug_message("%s Current object was %s\n"
714                      , ts, current_object->name
715                            ? get_txt(current_object->name) : "<null>");
716     debug_message("%s Dump of the call chain:\n", ts);
717     (void)dump_trace(MY_TRUE, NULL); fflush(stdout);
718 
719     va_end(va);
720 
721     /* Dump the interactive structure */
722 
723     fprintf(stderr, "--- Dump of current interactive structure (%p..%p) --- \n"
724                   , ip, ip + sizeof(*ip) - 1);
725     fprintf(stderr, "  .socket:            %d\n", ip->socket);
726     fprintf(stderr, "  .ob:                %p", ip->ob);
727       if (ip->ob)  fprintf(stderr, " (%s)", get_txt(ip->ob->name));
728       putc('\n', stderr);
729     fprintf(stderr, "  .input_handler:     %p\n", ip->input_handler);
730     fprintf(stderr, "  .modify_command:    %p", ip->modify_command);
731       if (ip->modify_command)  fprintf(stderr, " (%s)", get_txt(ip->modify_command->name));
732       putc('\n', stderr);
733     fprintf(stderr, "  .prompt:           ");
734       dump_bytes(&(ip->prompt), sizeof(ip->prompt), 21);
735     fprintf(stderr, "  .addr:             ");
736       dump_bytes(&(ip->addr), sizeof(ip->addr), 21);
737     fprintf(stderr, "  .closing:           %02hhx\n", (unsigned char)ip->closing);
738     fprintf(stderr, "  .tn_enabled:        %02hhx\n", (unsigned char)ip->tn_enabled);
739     fprintf(stderr, "  .do_close:          %02hhx", (unsigned char)ip->do_close);
740       if (ip->do_close & (FLAG_DO_CLOSE|FLAG_PROTO_ERQ)) fprintf(stderr, " (");
741       if (ip->do_close & FLAG_DO_CLOSE) fprintf(stderr, "DO_CLOSE");
742       if (ip->do_close & (FLAG_DO_CLOSE|FLAG_PROTO_ERQ)) fprintf(stderr, ", ");
743       if (ip->do_close & FLAG_PROTO_ERQ) fprintf(stderr, "PROTO_ERQ");
744       if (ip->do_close & (FLAG_DO_CLOSE|FLAG_PROTO_ERQ)) fprintf(stderr, ")");
745       putc('\n', stderr);
746     fprintf(stderr, "  .noecho:            %02hhx", (unsigned char)ip->noecho);
747       fprintf(stderr, " %s\n", decode_noecho(ip->noecho));
748     fprintf(stderr, "  .tn_state:          %hhd", ip->tn_state);
749       switch(ip->tn_state) {
750       case TS_DATA:    fprintf(stderr, " (TS_DATA)\n"); break;
751       case TS_IAC:     fprintf(stderr, " (TS_IAC)\n"); break;
752       case TS_WILL:    fprintf(stderr, " (TS_WILL)\n"); break;
753       case TS_WONT:    fprintf(stderr, " (TS_WONT)\n"); break;
754       case TS_DO:      fprintf(stderr, " (TS_DO)\n"); break;
755       case TS_DONT:    fprintf(stderr, " (TS_DONT)\n"); break;
756       case TS_SB:      fprintf(stderr, " (TS_SB)\n"); break;
757       case TS_SB_IAC:  fprintf(stderr, " (TS_SB_IAC)\n"); break;
758       case TS_READY:   fprintf(stderr, " (TS_READY)\n"); break;
759       case TS_SYNCH:   fprintf(stderr, " (TS_SYNCH)\n"); break;
760       case TS_INVALID: fprintf(stderr, " (TS_INVALID)\n"); break;
761       default: putc('\n', stderr);
762       }
763     fprintf(stderr, "  .save_tn_state:     %hhd", ip->save_tn_state);
764       switch(ip->save_tn_state) {
765       case TS_DATA:    fprintf(stderr, " (TS_DATA)\n"); break;
766       case TS_IAC:     fprintf(stderr, " (TS_IAC)\n"); break;
767       case TS_WILL:    fprintf(stderr, " (TS_WILL)\n"); break;
768       case TS_WONT:    fprintf(stderr, " (TS_WONT)\n"); break;
769       case TS_DO:      fprintf(stderr, " (TS_DO)\n"); break;
770       case TS_DONT:    fprintf(stderr, " (TS_DONT)\n"); break;
771       case TS_SB:      fprintf(stderr, " (TS_SB)\n"); break;
772       case TS_SB_IAC:  fprintf(stderr, " (TS_SB_IAC)\n"); break;
773       case TS_READY:   fprintf(stderr, " (TS_READY)\n"); break;
774       case TS_SYNCH:   fprintf(stderr, " (TS_SYNCH)\n"); break;
775       case TS_INVALID: fprintf(stderr, " (TS_INVALID)\n"); break;
776       default: putc('\n', stderr);
777       }
778     fprintf(stderr, "  .supress_go_ahead:  %02hhx\n", (unsigned char)ip->supress_go_ahead);
779     fprintf(stderr, "  .text_end:          %hd (%p)\n", ip->text_end, ip->text+ip->text_end);
780     fprintf(stderr, "  .command_start:     %hd (%p)\n", ip->command_start, ip->text+ip->command_start);
781     fprintf(stderr, "  .command_end:       %hd (%p)\n", ip->command_end, ip->text+ip->command_end);
782     fprintf(stderr, "  .tn_start:          %hd (%p)\n", ip->tn_start, ip->text+ip->tn_start);
783     fprintf(stderr, "  .tn_end:            %hd (%p)\n", ip->tn_end, ip->text+ip->tn_end);
784     fprintf(stderr, "  .chars_ready:       %"PRId32"\n",ip->chars_ready);
785     fprintf(stderr, "  .snoop_on:          %p", ip->snoop_on);
786       if (ip->snoop_on && ip->snoop_on->ob) fprintf(stderr, " (%s)", get_txt(ip->snoop_on->ob->name));
787       putc('\n', stderr);
788     fprintf(stderr, "  .snoop_by:          %p", ip->snoop_by);
789       if (ip->snoop_by) fprintf(stderr, " (%s)", get_txt(ip->snoop_by->name));
790       putc('\n', stderr);
791     fprintf(stderr, "  .last_time:         %"PRIdMPINT"\n", ip->last_time);
792     fprintf(stderr, "  .numCmds:           %ld\n", ip->numCmds);
793     fprintf(stderr, "  .maxNumCmds:        %ld\n", ip->maxNumCmds);
794     fprintf(stderr, "  .trace_level:       %d\n", ip->trace_level);
795     fprintf(stderr, "  .trace_prefix:      %p", ip->trace_prefix);
796       if (ip->trace_prefix) fprintf(stderr, " '%s'", get_txt(ip->trace_prefix));
797       putc('\n', stderr);
798     fprintf(stderr, "  .message_length:    %d (%p)\n", ip->message_length, ip->message_buf+ip->message_length);
799     fprintf(stderr, "  .next_for_flush:    %p", ip->next_player_for_flush);
800       if (ip->next_player_for_flush) fprintf(stderr, " (%s)", get_txt(ip->next_player_for_flush->ob->name));
801       putc('\n', stderr);
802     fprintf(stderr, "  .prev_for_flush:    %p", ip->previous_player_for_flush);
803       if (ip->previous_player_for_flush) fprintf(stderr, " (%s)", get_txt(ip->previous_player_for_flush->ob->name));
804       putc('\n', stderr);
805     fprintf(stderr, "  .access_class:      %ld\n", ip->access_class);
806     fprintf(stderr, "  .charset:          ");
807       dump_bytes(&(ip->charset), sizeof(ip->charset), 21);
808     fprintf(stderr, "  .combine_cset:     ");
809       dump_bytes(&(ip->combine_cset), sizeof(ip->combine_cset), 21);
810     fprintf(stderr, "  .quote_iac:         %02hhx\n", (unsigned char)ip->quote_iac);
811     fprintf(stderr, "  .catch_tell_activ:  %02hhx\n", (unsigned char)ip->catch_tell_activ);
812     fprintf(stderr, "  .gobble_char:       %02hhx\n", (unsigned char)ip->gobble_char);
813     fprintf(stderr, "  .ts_data:           %02hhx\n", (unsigned char)ip->ts_data);
814     fprintf(stderr, "  .text:             ");
815       dump_bytes(&(ip->text), sizeof(ip->text), 21);
816     fprintf(stderr, "  .message_buf:      ");
817       dump_bytes(&(ip->message_buf), sizeof(ip->message_buf), 21);
818     fprintf(stderr, "------\n");
819 
820     /* Disconnect the user */
821     comm_send_buf(msg, strlen(msg), ip);
822     remove_interactive(ip->ob, MY_TRUE);
823 
824     /* Unset mutex */
825     in_fatal = MY_FALSE;
826 } /* comm_fatal() */
827 
828 /*-------------------------------------------------------------------------*/
829 static void
set_socket_nonblocking(SOCKET_T new_socket)830 set_socket_nonblocking (SOCKET_T new_socket)
831 
832 /* Set the <new_socket> into non-blocking mode.
833  * Abort on error.
834  */
835 
836 {
837     int tmp;
838 
839     tmp = 1;
840 
841 # ifdef USE_IOCTL_FIONBIO
842     if (socket_ioctl(new_socket, FIONBIO, &tmp) == -1) {
843         perror("ioctl socket FIONBIO");
844         abort();
845     }
846 # else /* !USE_IOCTL_FIONBIO */
847 # ifdef USE_FCNTL_O_NDELAY
848     if (fcntl(new_socket, F_SETFL, O_NDELAY) == -1) {
849 # else
850     if (fcntl(new_socket, F_SETFL, FNDELAY) == -1) {
851 # endif
852         perror("fcntl socket FNDELAY");
853         abort();
854     }
855 # endif /* !USE_IOCTL_FIONBIO */
856 
857 } /* set_socket_nonblocking() */
858 
859 /*-------------------------------------------------------------------------*/
860 static void
861 set_close_on_exec (SOCKET_T new_socket)
862 
863 /* Set that <new_socket> is closed when the driver performs an exec()
864  * (i.e. when starting the ERQ).
865  * Failure is acceptable as this is just a nicety.
866  */
867 
868 {
869 #ifdef HAVE_FCNTL
870     fcntl(new_socket, F_SETFD, 1L);
871 #endif
872 } /* set_close_on_exec() */
873 
874 /*-------------------------------------------------------------------------*/
875 static void
876 set_socket_own (SOCKET_T new_socket)
877 
878 /* Enable OOB communication on <new_socket>: the driver is set to
879  * receive SIGIO and SIGURG signals, and OOBINLINE is enabled.
880  * Failure is acceptable as both facilities are not available everywhere.
881  */
882 
883 {
884 #if defined(F_SETOWN) && defined(USE_FCNTL_SETOWN)
885     if (0 > fcntl(new_socket, F_SETOWN, getpid()))
886     {
887         perror("fcntl SETOWN");
888     }
889 #endif
890 #if defined(SO_OOBINLINE) && defined(USE_OOBINLINE)
891     {
892         int on = 1;
893         if (0 > setsockopt(new_socket, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof on))
894         {
895             perror("setsockopt SO_OOBINLINE");
896         }
897     }
898 #endif
899     new_socket = 0; /* Prevent 'not used' warning */
900 } /* set_socket_own() */
901 
902 /*-------------------------------------------------------------------------*/
903 void
904 initialize_host_name (const char *hname)
905 
906 /* This function is called at an early stage of the driver startup in order
907  * to initialise the global host_name with a useful value (specifically so
908  * that we can open the debug.log file).
909  * If <hname> is given, the hostname is parsed from the string, otherwise it
910  * is queried from the system.
911  *
912  * The value set in this function will later be overwritten by the
913  * call to initialize_host_ip_number().
914  *
915  * exit() on failure.
916  */
917 
918 {
919     char *domain;
920 
921     /* Get the (possibly qualified) hostname */
922     if (hname != NULL)
923     {
924         if (strlen(hname) > MAXHOSTNAMELEN)
925         {
926             fprintf(stderr, "%s Given hostname '%s' too long.\n"
927                           , time_stamp(), hname);
928             exit(1);
929         }
930         else
931             strcpy(host_name, hname);
932     }
933     else
934     {
935         if (gethostname(host_name, sizeof host_name) == -1) {
936             herror("gethostname");
937             exit(1);
938         }
939     }
940 
941     /* Cut off the domain name part of the hostname, if any.
942      */
943     domain = strchr(host_name, '.');
944     if (domain)
945         *domain = '\0';
946 } /* initialize_host_name() */
947 
948 /*-------------------------------------------------------------------------*/
949 void
950 initialize_host_ip_number (const char *hname, const char * haddr)
951 
952 /* Initialise the globals host_ip_number and host_ip_addr_template.
953  * If <hname> or <haddr> are given, the hostname/hostaddr are parsed
954  * from the strings, otherwise they are queried from the system.
955  *
956  * Open the UDP port if requested so that it can be used in inaugurate_master().
957  * exit() on failure.
958  */
959 
960 {
961     char *domain;
962     length_t tmp;
963 
964     /* Get the (possibly qualified) hostname */
965     if (hname != NULL)
966     {
967         if (strlen(hname) > MAXHOSTNAMELEN)
968         {
969             fprintf(stderr, "%s Given hostname '%s' too long.\n"
970                           , time_stamp(), hname);
971             exit(1);
972         }
973         else
974             strcpy(host_name, hname);
975     }
976     else
977     {
978         if (gethostname(host_name, sizeof host_name) == -1) {
979             herror("gethostname");
980             exit(1);
981         }
982     }
983 
984     /* Get the host address */
985     memset(&host_ip_addr_template, 0, sizeof host_ip_addr_template);
986     if (haddr != NULL)
987     {
988 #ifndef USE_IPV6
989         host_ip_number.s_addr = inet_addr(haddr);
990         host_ip_addr_template.sin_family = AF_INET;
991         host_ip_addr_template.sin_addr = host_ip_number;
992 #else
993         host_ip_number = inet6_addr(haddr);
994         host_ip_addr_template.sin_family = AF_INET6;
995         host_ip_addr_template.sin_addr = host_ip_number;
996 #endif
997 
998         /* Find the domain part of the hostname */
999         domain = strchr(host_name, '.');
1000     }
1001     else
1002     {
1003         struct hostent *hp;
1004 
1005         hp = gethostbyname(host_name);
1006         if (!hp) {
1007             fprintf(stderr, "%s gethostbyname: unknown host '%s'.\n"
1008                           , time_stamp(), host_name);
1009             exit(1);
1010         }
1011         memcpy(&host_ip_addr_template.sin_addr, hp->h_addr, (size_t)hp->h_length);
1012         host_ip_addr_template.sin_family = (unsigned short)hp->h_addrtype;
1013         host_ip_number = host_ip_addr_template.sin_addr;
1014 
1015         /* Now set the template to the proper _ANY value */
1016         memset(&host_ip_addr_template.sin_addr, 0, sizeof(host_ip_addr_template.sin_addr));
1017 #ifndef USE_IPV6
1018         host_ip_addr_template.sin_addr.s_addr = INADDR_ANY;
1019         host_ip_addr_template.sin_family = AF_INET;
1020 #else
1021         host_ip_addr_template.sin_addr = in6addr_any;
1022         host_ip_addr_template.sin_family = AF_INET6;
1023 #endif
1024 
1025         /* Find the domain part of the hostname */
1026         if (hname == NULL)
1027             domain = strchr(hp->h_name, '.');
1028         else
1029             domain = strchr(host_name, '.');
1030     }
1031 
1032 #ifndef USE_IPV6
1033     printf("%s Hostname '%s' address '%s'\n"
1034           , time_stamp(), host_name, inet_ntoa(host_ip_number));
1035     debug_message("%s Hostname '%s' address '%s'\n"
1036                  , time_stamp(), host_name, inet_ntoa(host_ip_number));
1037 #else
1038     printf("%s Hostname '%s' address '%s'\n"
1039           , time_stamp(), host_name, inet6_ntoa(host_ip_number));
1040     debug_message("%s Hostname '%s' address '%s'\n"
1041                  , time_stamp(), host_name, inet6_ntoa(host_ip_number));
1042 #endif
1043 
1044     /* Put the domain name part of the hostname into domain_name, then
1045      * strip it off the host_name[] (as only query_host_name() is going
1046      * to need it).
1047      * Note that domain might not point into host_name[] here, so we
1048      * can't just stomp '\0' in there.
1049      */
1050     if (domain)
1051     {
1052         domain_name = strdup(domain+1);
1053     }
1054     else
1055         domain_name = strdup("unknown");
1056 
1057     domain = strchr(host_name, '.');
1058     if (domain)
1059         *domain = '\0';
1060 
1061     /* Initialize udp at an early stage so that the master object can use
1062      * it in inaugurate_master() , and the port number is known.
1063      */
1064     if (udp_port != -1)
1065     {
1066         struct sockaddr_in host_ip_addr;
1067 
1068         memcpy(&host_ip_addr, &host_ip_addr_template, sizeof(host_ip_addr));
1069 
1070         host_ip_addr.sin_port = htons((u_short)udp_port);
1071         debug_message("%s UDP recv-socket requested for port: %d\n"
1072                      , time_stamp(), udp_port);
1073         udp_s = socket(host_ip_addr.sin_family, SOCK_DGRAM, 0);
1074         if (udp_s == -1)
1075         {
1076             perror("socket(udp_socket)");
1077             exit(1);
1078         }
1079         tmp = 1;
1080         if (setsockopt (udp_s, SOL_SOCKET, SO_REUSEADDR,
1081                         (char *) &tmp, sizeof (tmp)) < 0)
1082         {
1083             perror ("setsockopt(udp_s, SO_REUSEADDR)");
1084             exit(1);
1085         }
1086 
1087         /* Bind the UDP socket to an address.
1088          * First, try the given port number, if that one is in use
1089          * already, let bind() select one. If that one is in use, too,
1090          * close the socket again and pretend that we never had one.
1091          * Other errors abort the driver.
1092          */
1093         for(;;) {
1094             if (-1 == bind(udp_s, (struct sockaddr *)&host_ip_addr
1095                           , sizeof(host_ip_addr)))
1096             {
1097                 if (errno == EADDRINUSE) {
1098                     fprintf(stderr, "%s UDP port %d already bound!\n"
1099                                   , time_stamp(), udp_port);
1100                     debug_message("%s UDP port %d already bound!\n"
1101                                   , time_stamp(), udp_port);
1102                     if (host_ip_addr.sin_port) {
1103                         host_ip_addr.sin_port = 0;
1104                         continue;
1105                     }
1106                     close(udp_s);
1107                     udp_s = -1;
1108                 } else {
1109                     perror("udp-bind");
1110                     exit(1);
1111                 }
1112             }
1113             break;
1114         }
1115     }
1116 
1117     /* If we got the UDP socket, get query it's real address and
1118      * initialise it.
1119      */
1120     if (udp_s >= 0) {
1121         struct sockaddr_in host_ip_addr;
1122 
1123         tmp = sizeof(host_ip_addr);
1124         if (!getsockname(udp_s, (struct sockaddr *)&host_ip_addr, &tmp))
1125         {
1126             int oldport = udp_port;
1127 
1128             udp_port = ntohs(host_ip_addr.sin_port);
1129             if (oldport != udp_port)
1130                 debug_message("%s UDP recv-socket on port: %d\n"
1131                              , time_stamp(), udp_port);
1132         }
1133         set_socket_nonblocking(udp_s);
1134         set_close_on_exec(udp_s);
1135         if (socket_number(udp_s) >= min_nfds)
1136             min_nfds = socket_number(udp_s)+1;
1137     }
1138 
1139 } /* initialize_host_ip_number() */
1140 
1141 
1142 /*-------------------------------------------------------------------------*/
1143 static void
1144 urgent_data_handler (int signo)
1145 
1146 /* Signal handler for SIGURG/SIGIO: set the urgent_data flag and
1147  * note the time.
1148  */
1149 
1150 {
1151     if (d_flag)
1152         write(2, "received urgent data\n", 21);
1153     urgent_data = MY_TRUE;
1154     urgent_data_time = current_time;
1155 }
1156 
1157 /*-------------------------------------------------------------------------*/
1158 void
1159 prepare_ipc(void)
1160 
1161 /* Open all login sockets on driver startup, exit() on a failure.
1162  */
1163 
1164 {
1165     length_t tmp;
1166     int i;
1167     struct sigaction sa; // for installing the signal handlers
1168 
1169 #ifdef ERQ_DEMON
1170     /* Initialize the IP name lookup table */
1171     memset(iptable, 0, sizeof(iptable));
1172 #endif
1173 
1174     for (i = 0; i < MAX_OUTCONN; i++)
1175         outconn[i].status = ocNotUsed;
1176 
1177     /* Initialize the telnet machine unless mudlib_telopts() already
1178      * did that.
1179      */
1180     if (!telopts_do[0])
1181       init_telopts();
1182 
1183     /* Loop over all given port numbers.
1184      * Remember: positive number are actual port numbers to be opened,
1185      * negative numbers are the fd numbers of already existing sockets.
1186      */
1187     for (i = 0; i < numports; i++)
1188     {
1189         struct sockaddr_in host_ip_addr;
1190 
1191         memcpy(&host_ip_addr, &host_ip_addr_template, sizeof(host_ip_addr));
1192 
1193         if (port_numbers[i] > 0)
1194         {
1195             /* Real port number */
1196 
1197             host_ip_addr.sin_port = htons((u_short)port_numbers[i]);
1198             sos[i] = socket(host_ip_addr.sin_family, SOCK_STREAM, 0);
1199             if ((int)sos[i] == -1) {
1200                 perror("socket");
1201                 exit(1);
1202             }
1203             tmp = 1;
1204             if (setsockopt(sos[i], SOL_SOCKET, SO_REUSEADDR
1205                           , (char *) &tmp, sizeof (tmp)) < 0) {
1206                 perror ("setsockopt");
1207                 exit (1);
1208             }
1209             if (bind(sos[i], (struct sockaddr *)&host_ip_addr, sizeof host_ip_addr) == -1) {
1210                 if (errno == EADDRINUSE) {
1211                     fprintf(stderr, "%s Port %d already bound!\n"
1212                                   , time_stamp(), port_numbers[i]);
1213                     debug_message("%s Port %d already bound!\n"
1214                                  , time_stamp(), port_numbers[i]);
1215                     exit(errno);
1216                 } else {
1217                     perror("bind");
1218                     exit(1);
1219                 }
1220             }
1221         }
1222         else {
1223 
1224             /* Existing socket */
1225 
1226             sos[i] = -port_numbers[i];
1227             tmp = sizeof(host_ip_addr);
1228             if (!getsockname(sos[i], (struct sockaddr *)&host_ip_addr, &tmp))
1229                 port_numbers[i] = ntohs(host_ip_addr.sin_port);
1230         }
1231 
1232         /* Initialise the socket */
1233         if (listen(sos[i], 5) == -1) {
1234             perror("listen");
1235             exit(1);
1236         }
1237         set_socket_nonblocking(sos[i]);
1238         set_close_on_exec(sos[i]);
1239 
1240         if (socket_number(sos[i]) >= min_nfds)
1241             min_nfds = socket_number(sos[i])+1;
1242     } /* for(i = 0..numports) */
1243 
1244     // install some signal handlers
1245     sigemptyset(&sa.sa_mask);
1246     sa.sa_flags = SA_RESTART; // restart syscalls after handling a signal
1247 
1248     /* We ignore SIGPIPE and handle the errors on write/send ourself */
1249     sa.sa_handler = SIG_IGN;
1250     if (sigaction(SIGPIPE, &sa, NULL) == -1)
1251         perror("Unable to install signal handler for SIGPIPE");   // uhoh. SIGPIPE terminates...
1252 
1253     sa.sa_handler = urgent_data_handler;
1254     if (sigaction(SIGURG, &sa, NULL) == -1)
1255         perror("Unable to install signal handler for SIGURG");
1256     if (sigaction(SIGIO, &sa, NULL) == -1)
1257         perror("Unable to install signal handler for SIGIO");   // uhoh. SIGIO terminates...
1258 
1259 } /* prepare_ipc() */
1260 
1261 /*-------------------------------------------------------------------------*/
1262 void
1263 ipc_remove (void)
1264 
1265 /* Called when the driver is shutting down, this function closes all
1266  * open sockets.
1267  */
1268 
1269 {
1270     int i;
1271 
1272     printf("%s Shutting down ipc...\n", time_stamp());
1273     for (i = 0; i < numports; i++)
1274         socket_close(sos[i]);
1275 
1276     if (udp_s >= 0)
1277         socket_close(udp_s);
1278 
1279 #ifdef ERQ_DEMON
1280     shutdown_erq_demon();
1281 #endif
1282 
1283 } /* ipc_remove() */
1284 
1285 /*-------------------------------------------------------------------------*/
1286 static INLINE ssize_t
1287 comm_send_buf (char *msg, size_t size, interactive_t *ip)
1288 
1289 /* Low level send routine, just tries to send the data without buffering.
1290    A return value -1 indicates a total failure (i.e. the connection should
1291    be dropped), otherwise the amount of data sent (even if it's 0).
1292 */
1293 {
1294     int     retries;   /* Number of retries left when sending data */
1295     ssize_t n;         /* Bytes that have been sent */
1296 
1297     for (retries = 6;;)
1298     {
1299 #ifdef USE_TLS
1300         if ((n = (ip->tls_status == TLS_INACTIVE ?
1301                   (int)socket_write(ip->socket, msg, size):
1302                   (int)tls_write(ip, msg, size))) != -1)
1303 #else
1304         if ((n = (int)socket_write(ip->socket, msg, size)) != -1)
1305 #endif
1306         {
1307             break;
1308         }
1309 
1310         switch (errno)
1311         {
1312 
1313         case EINTR:
1314             if (--retries)
1315                 continue;
1316             n = 0;
1317             break;
1318 
1319         case EWOULDBLOCK:
1320             n = 0;
1321             break;
1322 
1323         case EMSGSIZE:
1324             fprintf(stderr, "%s comm: write EMSGSIZE.\n", time_stamp());
1325             break;
1326 
1327         case EINVAL:
1328             fprintf(stderr, "%s comm: write EINVAL.\n", time_stamp());
1329             break;
1330 
1331         case ENETUNREACH:
1332             fprintf(stderr, "%s comm: write ENETUNREACH.\n", time_stamp());
1333             break;
1334 
1335         case EHOSTUNREACH:
1336             fprintf(stderr, "%s comm: write EHOSTUNREACH.\n", time_stamp());
1337             break;
1338 
1339         case EPIPE:
1340             fprintf(stderr, "%s comm: write EPIPE detected\n", time_stamp());
1341             break;
1342 
1343         case ECONNRESET:
1344             fprintf(stderr, "%s comm: write ECONNRESET detected\n", time_stamp());
1345             break;
1346 
1347         default:
1348             {
1349                 int e = errno;
1350                 fprintf(stderr, "%s comm: write: unknown errno %d (%s)\n"
1351                                   , time_stamp(), e, strerror(e));
1352             }
1353         }
1354 
1355         if (n == 0) // don't close for EWOULDBLOCK/EINTR
1356             return 0;
1357 
1358         ip->do_close = FLAG_DO_CLOSE;
1359         return -1;
1360 
1361     } /* for (retries) */
1362 
1363 #ifdef COMM_STAT
1364     inet_packets++;
1365     inet_volume += n;
1366 #endif
1367 
1368     return n;
1369 } /* comm_send_buf() */
1370 
1371 /*-------------------------------------------------------------------------*/
1372 Bool
1373 comm_socket_write (char *msg, size_t size, interactive_t *ip, write_buffer_flag_t flags)
1374 
1375 /* Stand in for socket_write(): take the data to be written, compress and
1376  * encrypt them if needed and send them to <ip>. If no data can be send
1377  * right now append them to the buffer. Returns false if no more data
1378  * is accepted at this time (messages are discarded or the connection
1379  * was dropped).
1380  */
1381 
1382 {
1383     struct write_buffer_s *b;
1384     char *buf;
1385     size_t length;
1386 
1387     if (size == 0)
1388         return MY_TRUE;
1389 
1390 #ifdef USE_MCCP
1391     /* We cannot discard already compressed packets,
1392      * because the zlib will generate a checksum
1393      * over all bytes. So we have to check before
1394      * compressing the message whether we can send
1395      * or put them in the write buffer.
1396      *
1397      * To provide a consistent behavior we do this
1398      * also for uncompressed connections.
1399      */
1400 #endif
1401 
1402     if (!(flags & WB_NONDISCARDABLE) && ip->write_first)
1403     {
1404         p_int max_size;
1405 
1406         max_size = ip->write_max_size;
1407         if (max_size == -2)
1408             max_size = write_buffer_max_size;
1409 
1410         if (max_size >= 0 && ip->write_size >= (p_uint) max_size)
1411         {
1412             /* Buffer overflow. */
1413             if (ip->msg_discarded != DM_NONE)
1414                 return MY_FALSE; /* Message will be or was sent. */
1415 
1416             /* Notify the master about it. */
1417             ip->msg_discarded = DM_SEND_INFO;
1418             add_flush_entry(ip);
1419 
1420             return MY_FALSE;
1421         }
1422     }
1423 
1424 #ifdef USE_MCCP
1425     if (ip->out_compress)
1426     {
1427         int status;
1428 
1429         ip->out_compress->next_in = (unsigned char *) msg;
1430         ip->out_compress->avail_in = size;
1431 
1432         ip->out_compress->next_out = ip->out_compress_buf;
1433         ip->out_compress->avail_out = COMPRESS_BUF_SIZE;
1434 
1435         status = deflate(ip->out_compress, Z_SYNC_FLUSH);
1436 
1437         if (status != Z_OK)
1438         {
1439             fprintf(stderr, "%s comm: MCCP compression error: %d\n"
1440                           , time_stamp(), status);
1441             return MY_FALSE;
1442         }
1443 
1444         /* ok.. perhaps i should take care that all data in message_buf
1445          * is compressed, but i guess there is no chance that 1024 byte
1446          * compressed won't fit into the 8192 byte buffer
1447          */
1448 
1449         length = ip->out_compress->next_out - ip->out_compress_buf;
1450         buf = (char *) ip->out_compress_buf;
1451     }
1452     else
1453 #endif /* USE_MCCP */
1454     {
1455         buf = msg;
1456         length = size;
1457     }
1458 
1459     /* now sending the buffer... */
1460     if (ip->write_first == NULL)
1461     {
1462         /* Try writing to the socket first. */
1463         ssize_t n = comm_send_buf(buf, length, ip);
1464 
1465         if (n == -1)
1466             return MY_FALSE;
1467         else if (n == length)
1468         {
1469             /* We're done. */
1470             return MY_TRUE;
1471         }
1472         else if (n > 0)
1473         {
1474             buf += n;
1475             length -= n;
1476         }
1477     }
1478 
1479     /* We have to enqueue the message. */
1480 
1481     b = xalloc(sizeof(struct write_buffer_s) + length - 1);
1482     if (!b)
1483         outofmem(sizeof(struct write_buffer_s) + length - 1, "comm_socket_write()");
1484 
1485     b->length = length;
1486     b->pos = 0;
1487     b->flags = flags;
1488     b->next = NULL;
1489     memcpy(b->buffer, buf, length);
1490 
1491      /* Chain in the new buffer */
1492     if (ip->write_first)
1493         ip->write_last = ip->write_last->next = b;
1494     else
1495         ip->write_last = ip->write_first = b;
1496 
1497     ip->write_size += length;
1498     ip->msg_discarded = DM_NONE;
1499 
1500     return MY_TRUE;
1501 } /* comm_socket_write() */
1502 
1503 /*-------------------------------------------------------------------------*/
1504 static void
1505 comm_write_pending (interactive_t * ip)
1506 
1507 /* Send as much from the write buffer of <ip> as possible.
1508  */
1509 
1510 {
1511     while (ip->write_first != NULL)
1512     {
1513         struct write_buffer_s *buf;
1514         ssize_t n;
1515 
1516         buf = ip->write_first;
1517         n = comm_send_buf(buf->buffer + buf->pos, buf->length - buf->pos, ip);
1518 
1519         if (n == -1)
1520             return;
1521 
1522         buf->pos += n;
1523         if (buf->pos < buf->length)
1524             return;
1525 
1526         ip->write_first = buf->next;
1527         ip->write_size -= buf->length;
1528         xfree(buf);
1529     }
1530 } /* comm_write_pending() */
1531 
1532 /*-------------------------------------------------------------------------*/
1533 static void
1534 add_discarded_message (interactive_t *ip)
1535 
1536 /* Calls the H_MSG_DISCARDED driver hook and adds the
1537  * message to the write buffer of <ip>. <ip> is removed
1538  * from the list of dirty interactives if it's clean afterwards.
1539  */
1540 {
1541     string_t *discarded_msg;
1542 
1543     if (driver_hook[H_MSG_DISCARDED].type == T_CLOSURE)
1544     {
1545         if (driver_hook[H_MSG_DISCARDED].x.closure_type == CLOSURE_LAMBDA)
1546         {
1547             free_object(driver_hook[H_MSG_DISCARDED].u.lambda->ob, "add_discarded_message");
1548             driver_hook[H_MSG_DISCARDED].u.lambda->ob = ref_object(ip->ob, "add_discarded_message");
1549         }
1550 
1551         push_ref_valid_object(inter_sp, ip->ob, "add_discarded_message");
1552 
1553         call_lambda(&driver_hook[H_MSG_DISCARDED], 1);
1554 
1555         if (inter_sp->type == T_STRING)
1556         {
1557             /* The new discarded_msg. Adopt the reference. */
1558             discarded_msg = inter_sp->u.str;
1559 
1560             inter_sp->type = T_INVALID;
1561             inter_sp--;
1562         }
1563         else
1564         {
1565             pop_stack();
1566             discarded_msg = NULL;
1567         }
1568     }
1569     else if (driver_hook[H_MSG_DISCARDED].type == T_STRING)
1570     {
1571         discarded_msg = ref_mstring(driver_hook[H_MSG_DISCARDED].u.str);
1572     }
1573     else
1574     {
1575         discarded_msg = ref_mstring(STR_DISCARDED_MSG);
1576     }
1577 
1578     if (discarded_msg)
1579     {
1580         /* Append it to the write buffer. */
1581         comm_socket_write(get_txt(discarded_msg), mstrsize(discarded_msg)
1582                         , ip, WB_NONDISCARDABLE);
1583         free_mstring(discarded_msg);
1584     }
1585 
1586     ip->msg_discarded = DM_INFO_WAS_SENT;
1587 
1588     if (!ip->message_length)
1589         remove_flush_entry(ip);
1590 }
1591 
1592 /*-------------------------------------------------------------------------*/
1593 void
1594 add_message (const char *fmt, ...)
1595 
1596 /* Send a message to the current command_giver. The message is composed
1597  * from the <fmt> string and the following arguments using the normal
1598  * printf() semantics.
1599  *
1600  * The format string "%s" is special in that it bypasses the normal
1601  * printf() handling and uses the given char* argument directly as data
1602  * source, allowing to send strings of arbitrary length.
1603  * The format string FMT_STRING accepts a string_t argument of arbitrary length.
1604  * The format string FMT_BINARY accepts a char* as text argument, followed
1605  * by a size_t with the string length. The text may contain any character.
1606  *
1607  * All other format strings compose the message to send in a local buffer
1608  * and are therefore subject to a length restriction.
1609  *
1610  * This function also does the telnet, snooping, and shadow handling.
1611  * If an interactive player is shadowed, object.c::shadow_catch_message()
1612  * is called to give the shadows the opportunity to intercept the message.
1613  *
1614  * All messages are accumulated in interactive.message_buf, which is
1615  * flushed when it is full. This flush can be forced by passing the
1616  * special 'string' message_flush (which is actually just a NULL pointer)
1617  * as <fmt> string to this function.
1618  *
1619  * Messages which can't be send (e.g. because the command_giver was
1620  * destructed or disconnected) are printed on stdout, preceeded by ']'.
1621  *
1622  * If an error other than EINTR occured while sending the data to
1623  * the network, the message is discarded and the socket is marked
1624  * for disconnection.
1625  *
1626  * Note that add_message() might be called recursively.
1627  */
1628 
1629 {
1630     char  buff[MAX_TEXT + MAX_TEXT/2];
1631       /* Composition buffer for the final message.
1632        * We hope that it's big enough, but to be sure the code will
1633        * check for buffer overruns.
1634        * Message is composed starting from buff[1] on, buff[0] is
1635        * set to '%' for easier snooper-message generation.
1636        */
1637     int   length;
1638     int   min_length;
1639       /* When accumulating data in ip.message_buf[], this is the
1640        * threshold over which the buffer will be written to the
1641        * socket.
1642        * TODO: Actually, it is used just as a flag for flush/non-flush.
1643        */
1644     string_t *srcstr;
1645       /* If not NULL, this string was passed in to be printed.
1646        * source will point to the first real character of it.
1647        */
1648     int   old_message_length;  /* accumulated message length so far */
1649     char *source;              /* Pointer to the final message to add */
1650     size_t srclen;             /* Length of the message in source/srcstr */
1651     char *end;                 /* One char past the end of .message_buf[] */
1652     char *dest;                /* First free char in .message_buf[] */
1653     va_list va;
1654     interactive_t *ip;       /* The interactive user */
1655     object_t      *snooper;  /* Snooper of <ip> */
1656 
1657     source = NULL;
1658     srcstr = NULL;
1659     srclen = 0;
1660     length = 0;
1661 
1662     va_start(va, fmt);
1663 
1664     /* Test if the command_giver is a real, living, undestructed user,
1665      * and not disconnected, closing or actually a new ERQ demon.
1666      * If the command_giver fails the test, the message is printed
1667      * to stdout and the function returns.
1668      */
1669     if ( command_giver == NULL
1670      || (   command_giver->flags & O_DESTRUCTED
1671          && fmt != message_flush )
1672      || !(O_SET_INTERACTIVE(ip, command_giver))
1673      || (ip->do_close && fmt != message_flush && !sending_telnet_command)
1674        )
1675     {
1676         putchar(']');
1677         if ( fmt == FMT_STRING )
1678         {
1679             /* Make sure to print embedded '\0' characters as well */
1680 
1681             size_t len;
1682 
1683             srcstr = va_arg(va, string_t *);
1684             source = get_txt(srcstr);
1685             srclen = mstrsize(srcstr);
1686 
1687             for ( len = 0; len < srclen; )
1688             {
1689                 if (*source == '\0')
1690                 {
1691                     putc('\0', stdout);
1692                     source++;
1693                     len++;
1694                 }
1695                 else
1696                 {
1697                     size_t slen;
1698 
1699                     fputs(source, stdout);
1700                     slen = strlen(source);
1701                     source += slen;
1702                     len += slen;
1703                 }
1704             }
1705         }
1706         else if ( fmt != message_flush )
1707         {
1708             vprintf(fmt, va);
1709         }
1710         fflush(stdout);
1711         va_end(va);
1712         return;
1713     }
1714 
1715     old_message_length = ip->message_length;
1716 
1717     /* --- Compose the final message --- */
1718 
1719     /* Create the final message and handle snoopers and shadows.
1720      */
1721 
1722     min_length = MAX_SOCKET_PACKET_SIZE-1;
1723       /* Allow some wiggle room for source characters like NL which
1724        * expand into two characters.
1725        */
1726 
1727     if ( fmt == message_flush )
1728     {
1729         /* Just flush, nothing to add */
1730 
1731         min_length = 1;
1732         source = "";
1733         srclen = 0;
1734         srcstr = NULL;
1735     }
1736     else /* add the message */
1737     {
1738 #ifdef COMM_STAT
1739         add_message_calls++;
1740 #endif
1741 
1742         /* Compose the final message in buff[] (while checking for overruns)
1743          * and point source to it.
1744          * Recognize the special formats '%s', FMT_STRING and FMT_BINARY
1745          * to bypass buff[] for messages of arbitrary length and content.
1746          */
1747 
1748         if (fmt == FMT_STRING)
1749         {
1750             srcstr = va_arg(va, string_t *);
1751             va_end(va);
1752 
1753             source = get_txt(srcstr);
1754             srclen = mstrsize(srcstr);
1755         }
1756         else if (fmt == FMT_BINARY)
1757         {
1758             source = va_arg(va, char *);
1759             srclen = va_arg(va, size_t);
1760             va_end(va);
1761             srcstr = NULL;
1762         }
1763         else if (fmt[0] == '%' && fmt[1] == 's' && !fmt[2])
1764         {
1765             source = va_arg(va, char *);
1766             va_end(va);
1767             srclen = strlen(source);
1768             srcstr = NULL;
1769         }
1770         else
1771         {
1772             size_t len;
1773             len = vsnprintf(buff+1, sizeof(buff)-1, fmt,va);
1774             va_end(va);
1775             /* old sprintf() implementations returned -1 if the output was
1776              * truncated. Since size_t is an unsigned type, the check for
1777              * len == -1 is implicitly included by >= sizeof(...)-1, because
1778              * -1 will be wrapped to SIZE_T_MAX which is the maximum sizeof()
1779              * can return and can never be valid as return value here. */
1780             if (len >= sizeof(buff)-1)
1781             {
1782                 char err[] = "\n*** Message truncated ***\n";
1783                 debug_message("%s Message too long (Length: %zu): '%.200s...'\n"
1784                              , time_stamp(), len, buff);
1785                 (void)strcpy(buff+(sizeof(buff)-sizeof(err)), err);
1786             }
1787             source = buff+1;
1788             srclen = strlen(buff+1);
1789             srcstr = NULL;
1790         }
1791 
1792         /* If we're not sending a telnet command with this message,
1793          * pass on the new data to any snooper and/or shadow
1794          */
1795 
1796         if (!sending_telnet_command)
1797         {
1798 
1799             /* If there's a shadow successfully handling the
1800              * message, return.
1801              * This may cause a recursive call to add_message()!.
1802              */
1803 
1804             if (shadow_catch_message(command_giver, source))
1805             {
1806                 return;
1807             }
1808 
1809             /* If there's a snooper, send it the new message prepended
1810              * with a '%'.
1811              * For interactive snoopers this means a recursion with
1812              * the command_giver set to the snooper, for non-interactive
1813              * snoopers it's a simple call to tell_npc(), with an
1814              * adaption of the global trace_level to this users trace
1815              * settings.
1816              */
1817 
1818             if ( NULL != (snooper = ip->snoop_by)
1819              && !(snooper->flags & O_DESTRUCTED))
1820             {
1821                 buff[0] = '%';
1822                 if (O_IS_INTERACTIVE(snooper))
1823                 {
1824                     object_t *save;
1825 
1826                     save = command_giver;
1827                     command_giver = snooper;
1828                     if (source != buff+1)
1829                     {
1830                         if (srcstr != NULL)
1831                         {
1832                             add_message("%s", "%");
1833                             add_message(FMT_STRING, srcstr);
1834                         }
1835                         else if (srclen >= sizeof buff - 1)
1836                         {
1837                             add_message("%s", "%");
1838                             add_message("%s", source);
1839                         }
1840                         else
1841                         {
1842                             strcpy(buff+1, source);
1843                             add_message("%s", buff);
1844                         }
1845                     }
1846                     else
1847                     {
1848                         add_message("%s", buff);
1849                     }
1850                     command_giver = save;
1851                 }
1852                 else
1853                 {
1854                     trace_level |= ip->trace_level;
1855                     if (source != buff+1)
1856                     {
1857                         if (srcstr != NULL)
1858                         {
1859                             tell_npc(snooper, STR_PERCENT);
1860                             tell_npc(snooper, srcstr);
1861                         }
1862                         else if (srclen >= sizeof buff - 1)
1863                         {
1864                             tell_npc(snooper, STR_PERCENT);
1865                             tell_npc_str(snooper, source);
1866                         }
1867                         else
1868                         {
1869                             strcpy(buff+1, source);
1870                             tell_npc_str(snooper, buff);
1871                         }
1872                     } else
1873                     {
1874                         tell_npc_str(snooper, buff);
1875                     }
1876                 }
1877             } /* if (snooper) */
1878         } /* if (!sending_telnet_command */
1879     } /* if (flush or not) */
1880 
1881 #ifdef DEBUG
1882     if (d_flag > 1)
1883         debug_message("%s [%s (%zu)]: %s"
1884                      , time_stamp(), get_txt(command_giver->name)
1885                      , srclen, source);
1886 #endif
1887 
1888     /* --- Send the final message --- */
1889 
1890     /* Append the final message to the .message_buf[], taking
1891      * care of all the necessary charset and telnet translations.
1892      */
1893 
1894     dest = &ip->message_buf[old_message_length];
1895     end  = &ip->message_buf[sizeof ip->message_buf];
1896 
1897     /* If there's any recursive call, let it begin
1898      * at the start.
1899      */
1900     ip->message_length = 0;
1901 
1902     /* This loop advances source until it reaches the end.
1903      * Every character encountered is copied, translated or fed
1904      * into the telnet machine.
1905      */
1906 
1907 #ifdef DEBUG_TELNET
1908 if (sending_telnet_command)
1909 {
1910     char *cp;
1911     long left;
1912     printf("%s TDEBUG: '%s' Sending telnet (%zu bytes): "
1913           , time_stamp(), get_txt(ip->ob->name), strlen(source));
1914     for (cp = source, left = srclen; left > 0; cp++, left--)
1915         printf(" %02x", (unsigned char)*cp);
1916     printf("\n");
1917 }
1918 #endif
1919 
1920     do /* while (srclen != 0) */
1921     {
1922         ptrdiff_t chunk;  /* Current size of data in .message_buf[] */
1923         char   c;         /* Currently processed character */
1924 
1925         while (srclen != 0 && dest != end)
1926         {
1927             c = *source++;
1928             srclen--;
1929 
1930             /* Process the character:
1931              *  - copy it if the corresponding .charset bit is set,
1932              *    or if it's part of a telnet command.
1933              *  - translate a '\n' into '\r\n'
1934              *  - double an IAC if quote_iac is active.
1935              *  - stop this loop if the source is exhausted or
1936              *    if the buffer is full.
1937              */
1938             if (sending_telnet_command)
1939             {
1940                 *dest++ = c;
1941             }
1942             else if (!(ip->charset[(c&0xff)>>3] & 1<<(c&7)))
1943                 NOOP;
1944             else if (c == '\n')
1945             {
1946                 if (dest + 1 == end)
1947                 {
1948                     /* Not enough space in the buffer - revisit this char
1949                      * on the next time around */
1950                     source--;
1951                     srclen++;
1952                     break;
1953                 }
1954 
1955                 /* Insert CR before NL */
1956                 *dest++ = '\r';
1957                 *dest++ = c;
1958             }
1959             else if ( (unsigned char)c == IAC && ip->quote_iac)
1960             {
1961                 if (dest + 1 == end)
1962                 {
1963                     /* Not enough space in the buffer - revisit this char
1964                      * on the next time around */
1965                     source--;
1966                     srclen++;
1967                     break;
1968                 }
1969 
1970                 *dest++ = c;
1971                 *dest++ = c;
1972             }
1973             else
1974             {
1975                 *dest++ = c;
1976             }
1977 
1978             /* Other characters are silently dropped */
1979         } /* while() */
1980 
1981         /* Check how much data there is in .message_buf[].
1982          * If it is enough, send it, else terminate the outer loop
1983          * (because *source must be exhausted for this to happen).
1984          */
1985         chunk = dest - ip->message_buf;
1986         if (chunk < min_length)
1987         {
1988             break;
1989         }
1990 
1991         /* Write .message_buf[] to the network. */
1992 
1993         if (!comm_socket_write(ip->message_buf, (size_t)chunk, ip, 0))
1994         {
1995             if (old_message_length)
1996                 clear_message_buf(ip);
1997             return;
1998         }
1999 
2000         /* Continue with the processing of source */
2001         dest = &ip->message_buf[0];
2002     } while (srclen != 0);
2003 
2004     /* --- Final touches --- */
2005 
2006     ip->message_length = length = dest - ip->message_buf;
2007 
2008     /* Update the list of interactives with pending data */
2009 
2010     if ( length && !old_message_length )
2011     {
2012         /* Buffer became 'dirty': add this interactive to the list.
2013          */
2014         add_flush_entry(ip);
2015     }
2016     if ( !length && old_message_length ) /* buffer has become empty */
2017     {
2018         clear_message_buf(ip);
2019     }
2020 } /* add_message() */
2021 
2022 /*-------------------------------------------------------------------------*/
2023 static INLINE void
2024 reset_input_buffer (interactive_t *ip)
2025 
2026 /* When returning from CHARMODE to LINEMODE, the input buffer variables
2027  * need to be reset. This function takes care of it.
2028  * Note that there might be additional lines pending between .tn_end and
2029  * .text_end.
2030  */
2031 
2032 {
2033     if (ip->command_start)
2034     {
2035         DTN(("reset input buffer: cmd_start %hd, tn_start %hd, tn_end %hd, text_end %hd\n",
2036              ip->command_start, ip->tn_start, ip->tn_end, ip->text_end));
2037         ip->tn_start -= ip->command_start;
2038         ip->tn_end -= ip->command_start;
2039         ip->text_end -= ip->command_start;
2040         if (ip->tn_start < 0)
2041             ip->tn_start = 0;
2042         if (ip->tn_end < 0)
2043             ip->tn_end = 0;
2044         if (ip->text_end <= 0)
2045             ip->text_end = 0;
2046         else
2047         {
2048             move_memory( ip->text, ip->text + ip->command_start
2049                        , ip->text_end
2050                        );
2051         }
2052         if (ip->command_end)
2053             ip->command_end = ip->tn_end;
2054         ip->command_start = 0;
2055     }
2056 } /* reset_input_buffer() */
2057 
2058 /*-------------------------------------------------------------------------*/
2059 static void
2060 add_flush_entry (interactive_t *ip)
2061 
2062 /* Add the given interactive <ip> to the list of 'dirty' interactives.
2063  * The function is safe to call for interactives already in the list.
2064  */
2065 
2066 {
2067     if ( ip->previous_player_for_flush || first_player_for_flush == ip)
2068         return;
2069 
2070     if ( NULL != (ip->next_player_for_flush = first_player_for_flush) )
2071     {
2072         first_player_for_flush->previous_player_for_flush = ip;
2073     }
2074     ip->previous_player_for_flush = NULL;
2075     first_player_for_flush = ip;
2076 } /* add_flush_entry() */
2077 
2078 /*-------------------------------------------------------------------------*/
2079 static void
2080 remove_flush_entry (interactive_t *ip)
2081 
2082 /* Remove the given interactive <ip> from the list of 'dirty' interactives
2083  * and make sure it is really clean. The function is safe to call for
2084  * interactives not in the list.
2085  */
2086 
2087 {
2088     /* To make it safe for calling the function even for interactives
2089      * not in the flush list, we check that <ip> is either in the middle
2090      * or at the end of the flush list (one or both of the .previous
2091      * and .next pointers is !NULL), or if .previous is NULL, that it is
2092      * the first entry in the list.
2093      */
2094 
2095     if ( ip->previous_player_for_flush )
2096     {
2097         ip->previous_player_for_flush->next_player_for_flush
2098           = ip->next_player_for_flush;
2099     }
2100     else if (first_player_for_flush == ip)
2101     {
2102         first_player_for_flush = ip->next_player_for_flush;
2103     }
2104 
2105     if ( ip->next_player_for_flush )
2106     {
2107         ip->next_player_for_flush->previous_player_for_flush
2108           = ip->previous_player_for_flush;
2109     }
2110 
2111     ip->previous_player_for_flush = NULL;
2112     ip->next_player_for_flush = NULL;
2113 } /* remove_flush_entry() */
2114 
2115 /*-------------------------------------------------------------------------*/
2116 void
2117 flush_all_player_mess (void)
2118 
2119 /* Flush all pending data from the interactives. Usually called before
2120  * every input loop, after a user logged in, or after an LPC runtime
2121  * error was processed.
2122  */
2123 
2124 {
2125     interactive_t *ip, *nip;
2126     object_t *save = command_giver;
2127 
2128     for ( ip = first_player_for_flush; ip != NULL; ip = nip)
2129     {
2130         nip = ip->next_player_for_flush;
2131           /* add_message() will clobber (ip)->next_player_for_flush! */
2132         command_giver = ip->ob;
2133         add_message(message_flush);
2134 
2135         if(ip->msg_discarded == DM_SEND_INFO)
2136             add_discarded_message(ip);
2137     }
2138     command_giver = save;
2139 } /* flush_all_player_mess() */
2140 
2141 /*-------------------------------------------------------------------------*/
2142 static void
2143 clear_message_buf (interactive_t *ip)
2144 
2145 /* Clear the buffer of the given interactive <ip> and remove it from
2146  * the list of 'dirty' interactives if there is nothing else to do.
2147  * The function is safe to call for interactives not in the list.
2148  *
2149  * This function is called after an interactive sent all pending data (or
2150  * failing while doing so).
2151  */
2152 
2153 {
2154     ip->message_length = 0;
2155 
2156     if (ip->msg_discarded != DM_SEND_INFO)
2157         remove_flush_entry(ip);
2158 } /* clear_message_buf() */
2159 
2160 /*-------------------------------------------------------------------------*/
2161 Bool
2162 get_message (char *buff)
2163 
2164 /* Get a message from a user, or wait until it is time for the next
2165  * heartbeat/callout. You can tell this apart by the result:
2166  *
2167  *   true: a user message was received and placed into buff; the user
2168  *         object is set as command_giver.
2169  *   false: it is just time to call the heart_beat.
2170  *
2171  * In both cases, time_to_call_heart_beat is set if a heartbeat is due.
2172  *
2173  * Internally, get_message() scans the array of interactive users in
2174  * search for one with a complete message in its incoming buffer. If
2175  * an earlier select() marked the socket for the current user as pending
2176  * with data, this data is read into the buffer before the check for
2177  * a message is performed. get_message() returns for the first user found
2178  * with a complete message. Since get_message() keeps its own
2179  * status of which user was looked at last, the next call to get_message()
2180  * will continue the scan where it left off.
2181  *
2182  * If no user has a complete message, a call to select() waits for more
2183  * incoming data. If this succeeds (and no heartbeat requires an
2184  * immediate return), the cycle begins again. If a heart_beat is due
2185  * even before select() executed, the waiting time for select() is
2186  * set to 0 so that only the status of the sockets is recorded and
2187  * get_message returns (almost) immediately.
2188  *
2189  * Normally, users can give only one command per cycle. The exception
2190  * is when they are editing, then they can give up to ALLOWED_ED_CMDS.
2191  *
2192  * Heartbeats are detected by checking the backend variable comm_time_-
2193  * to_call_heart_beat, which is set by the SIGALRM handler. If it is
2194  * true, get_message() sets the variable time_to_call_heart_beat to
2195  * inform the backend and returns.
2196  *
2197  * If a heart_beat occurs during the reading and returning of player
2198  * commands, the comm_time_c_h_b variable is set, but not evaluated.
2199  * This evaluation happens only when a select() is performed (therefore
2200  * the second variable time_to_c_h_b). This way every user can issure
2201  * at least one command in one backend cycle, even if that takes longer
2202  * than one heart_beat time. This makes it also legal for comm_to_c_h_b
2203  * to be set upon entering get_message().
2204  *
2205  * For short latency, the UDP socket is checked on every call to
2206  * get_message(), even if a previous select() did not mark it as ready
2207  * (this is disabled under BeOS and Windows).
2208  */
2209 
2210 {
2211     /* State information: */
2212     static fd_set readfds, writefds;
2213       /* List of sockets with pending data.
2214        * You can ignore a 'could be used uninitialized' warning.
2215        */
2216     static int NextCmdGiver = -1;
2217       /* Index of current user to check */
2218     static int CmdsGiven = 0;
2219       /* Number of commands the current user gave in this cycle. */
2220 
2221 #   define StartCmdGiver       (max_player)
2222 #   define DecreaseCmdGiver    NextCmdGiver--
2223 
2224     int    i;
2225     interactive_t * ip = NULL;
2226     fd_set exceptfds;
2227 
2228 
2229     /* The endless loop */
2230 
2231     while(MY_TRUE)
2232     {
2233         struct sockaddr_in addr;
2234         length_t length; /* length of <addr> */
2235         struct timeval timeout;
2236 
2237         /* --- select() on the sockets and handle ERQ --- */
2238 
2239         /* This also removes users which connection is marked
2240          * as to be closed.
2241          */
2242 
2243         if (NextCmdGiver < 0)
2244         {
2245             int nfds;     /* number of fds for select() */
2246             int res;      /* result from select() */
2247             int twait;    /* wait time in seconds for select() */
2248             int retries;  /* retries of select() after EINTR */
2249 
2250             flush_all_player_mess();
2251             twait = comm_time_to_call_heart_beat ? 0 : 1;
2252               /* If the heart_beat is due, just check the state
2253                * of the sockets, but don't wait.
2254                */
2255 
2256             /* Set up fd-sets. */
2257 
2258             FD_ZERO(&readfds);
2259             FD_ZERO(&writefds);
2260             for (i = 0; i < numports; i++) {
2261                 FD_SET(sos[i], &readfds);
2262             } /* for */
2263             nfds = min_nfds;
2264             for (i = max_player + 1; --i >= 0;)
2265             {
2266                 ip = all_players[i];
2267                 if (!ip)
2268                     continue;
2269 
2270                 if (ip->do_close)
2271                 {
2272                     ip->do_close &= FLAG_PROTO_ERQ;
2273                     remove_interactive(ip->ob, MY_FALSE);
2274                     continue;
2275                 }
2276 
2277                 if (ip->tn_state == TS_READY)
2278                 {
2279                     /* If telnet is ready for commands, react quickly. */
2280                     twait = 0;
2281                 }
2282                 else
2283                 {
2284                     FD_SET(ip->socket, &readfds);
2285                     if (socket_number(ip->socket) >= nfds)
2286                         nfds = socket_number(ip->socket)+1;
2287                 }
2288 
2289                 if (ip->write_first != NULL)
2290                 {
2291                     /* There is something to write. */
2292                     FD_SET(ip->socket, &writefds);
2293                 }
2294 
2295             } /* for (all players) */
2296 #ifdef ERQ_DEMON
2297             if (erq_demon >= 0)
2298             {
2299                 FD_SET(erq_demon, &readfds);
2300             }
2301 #endif
2302             if (udp_s >= 0)
2303             {
2304                 FD_SET(udp_s, &readfds);
2305             }
2306 
2307 #ifdef USE_PGSQL
2308             pg_setfds(&readfds, &writefds, &nfds);
2309 #endif
2310 
2311             /* select() until time is up or there is data */
2312 
2313             for (retries = 6;;)
2314             {
2315                 check_alarm();
2316                 timeout.tv_sec = twait;
2317                 timeout.tv_usec = 0;
2318                 res = socket_select(nfds, &readfds, &writefds, 0, &timeout);
2319                 if (res == -1)
2320                 {
2321                     if (errno == EINTR)
2322                     {
2323                         /* We got an alarm, probably need heart_beat.
2324                          * But finish the select call since we already have
2325                          * prepared readfds.
2326                          */
2327                         if (comm_time_to_call_heart_beat)
2328                             twait = 0;
2329                         if (--retries >= 0)
2330                             continue;
2331                     }
2332                     else
2333                     {
2334                         perror("select");
2335                     }
2336 
2337                     /* Despite the failure, pretend select() suceeded with
2338                      * zero sockets to read, and process heart_beat / buffered
2339                      * commands.
2340                      */
2341                     FD_ZERO(&readfds);
2342                 }
2343                 break;
2344             } /* for (retries) */
2345 
2346             /* If we got a SIGIO/SIGURG, telnet wants to synch with us.
2347              */
2348             if (urgent_data)
2349             {
2350                 DTN(("telnet wants to sync\n"));
2351                 check_alarm();
2352                 urgent_data = MY_FALSE;
2353                 timeout.tv_sec = 0;
2354                 timeout.tv_usec = 0;
2355                 memset((char *)&exceptfds, 255, (size_t)(nfds + 7) >> 3);
2356                 if (socket_select(nfds, 0, 0, &exceptfds, &timeout) > 0)
2357                 {
2358                     for (i = max_player + 1; --i >= 0;)
2359                     {
2360                         ip = all_players[i];
2361                         if (!ip)
2362                             continue;
2363                         if (FD_ISSET(ip->socket, &exceptfds))
2364                         {
2365                             DTN(("ts_data = TS_SYNCH\n"));
2366                             ip->ts_data = TS_SYNCH;
2367                             switch (ip->tn_state)
2368                             {
2369                               case TS_DATA:
2370                               case TS_READY:
2371                                 ip->tn_state = TS_SYNCH;
2372                                 ip->gobble_char = '\0';
2373                                 DTN(("tn_state = TS_SYNCH\n"));
2374                             }
2375                         }
2376                     } /* for (all players) */
2377                 }
2378                 /* Maybe the data didn't arrive yet, so try again later.
2379                  * But don't waste time doing it for too long.
2380                  */
2381                 else if (current_time - urgent_data_time < 600)
2382                 {
2383                     urgent_data = MY_TRUE;
2384                 }
2385             } /* if (urgent_data) */
2386 
2387 #ifdef USE_PGSQL
2388             pg_process_all();
2389 #endif
2390 
2391             /* Initialise the user scan */
2392             CmdsGiven = 0;
2393             NextCmdGiver = StartCmdGiver;
2394 
2395 #ifdef ERQ_DEMON
2396 
2397             /* --- Handle data from the ERQ ---
2398              * TODO: This should be a function on its own.
2399              * TODO: Define the erq messages as structs.
2400              */
2401             if (erq_demon >= 0 && FD_ISSET(erq_demon, &readfds))
2402             {
2403                 mp_int l;
2404                 mp_int msglen;  /* Length of the current erq message */
2405                 mp_int rest;
2406                 int32  handle;
2407                 char  *rp;      /* Read pointer into buf_from_erq[] */
2408 
2409                 FD_CLR(erq_demon, &readfds);
2410 
2411                 /* Try six times to read data from the ERQ, appending
2412                  * it to what is already in buf_from_erq[].
2413                  */
2414                 retries = 6;
2415                 do {
2416                     l = socket_read(
2417                       erq_demon,
2418                       input_from_erq,
2419                       (size_t)(&buf_from_erq[sizeof buf_from_erq] - input_from_erq)
2420                     );
2421                 } while(l < 0 && errno == EINTR && --retries >= 0);
2422 
2423                 /* If there is no data, stop the erq, else handle it. */
2424 
2425                 if (l <= 0)
2426                 {
2427 #ifdef DEBUG_ERQ
2428                     fprintf(stderr, "%s read %"PRIdMPINT" bytes from erq demon\n"
2429                                   , time_stamp(), l);
2430                     if (l)
2431                         perror("");
2432 #endif /* DEBUG_ERQ */
2433                     stop_erq_demon(MY_TRUE);
2434                 }
2435                 else
2436                 {
2437                     input_from_erq += l;
2438                     l = input_from_erq - &buf_from_erq[0];
2439                     rp = buf_from_erq;
2440 
2441                     /* l is the amount of data left to consider,
2442                      * rp points to the data to be considered next.
2443                      *
2444                      * Loop while there are messages left in the buffer.
2445                      */
2446 
2447                     for (; l >= 8 && l >= (msglen = read_32(rp))
2448                          ; rp += msglen, l -= msglen)
2449                     {
2450                         Bool keep_handle;
2451 
2452                         /* Is the message length valid?
2453                          * TODO: use sizeof(struct) here
2454                          */
2455                         if (msglen < 8) {
2456 #ifdef DEBUG_ERQ
2457                             fprintf( stderr
2458                                    , "%s invalid length of message from"
2459                                      "erq demon: %"PRIdMPINT" bytes\n"
2460                                    , time_stamp(), msglen);
2461 #endif /* DEBUG_ERQ */
2462                             stop_erq_demon(MY_TRUE);
2463                             break;
2464                         }
2465 
2466                         handle = read_32(rp+4); /* get the handle */
2467 
2468                         if (handle == ERQ_HANDLE_KEEP_HANDLE
2469                          && msglen >= 8)
2470                         {
2471                             /* _KEEP_HANDLE wrapper are used when
2472                              * more messages for the (real) handle
2473                              * are to be expected. The real message
2474                              * follows after the _KEEP_HANDLE.
2475                              */
2476                             handle = read_32(rp+8); /* the real handle */
2477                             keep_handle = MY_TRUE;
2478                             msglen -= 4;  /* adjust the message parameters */
2479                             l -= 4;
2480                             rp += 4;
2481                         }
2482                         else if (handle == ERQ_HANDLE_RLOOKUP)
2483                         {
2484                             /* The result of a hostname lookup. */
2485 
2486                             if (msglen < 13 || rp[msglen-1]) {
2487 #ifdef DEBUG
2488                               if (msglen == 12) {
2489                                 if (d_flag > 1)
2490                                   debug_message("%s Host lookup failed\n"
2491                                                , time_stamp());
2492                               } else {
2493                                 debug_message("%s Bogus reverse name lookup.\n"
2494                                              , time_stamp());
2495                               }
2496 #endif
2497                             } else {
2498                                 uint32 naddr;
2499                                 struct in_addr net_addr;
2500 
2501                                 memcpy((char*)&naddr, rp+8, sizeof(naddr));
2502 #ifndef USE_IPV6
2503                                 net_addr.s_addr = naddr;
2504 #else
2505                                 CREATE_IPV6_MAPPED(&net_addr, naddr);
2506 #endif
2507                                 add_ip_entry(net_addr, rp+12);
2508                             }
2509                             continue;
2510                         }
2511 #ifdef USE_IPV6
2512                         else if (handle == ERQ_HANDLE_RLOOKUPV6)
2513                         {
2514                             /* The result of a hostname lookup. */
2515 
2516                             if (msglen < 9 || rp[msglen-1]) {
2517 #ifdef DEBUG
2518                                 debug_message("%s Bogus reverse name lookup.\n"
2519                                              , time_stamp());
2520 #else
2521                                 NOOP;
2522 #endif
2523                             } else {
2524                                 char * space;
2525 
2526                                 space = strchr(rp+8, ' ');
2527 
2528                                 if (space == NULL)
2529                                 {
2530                                     debug_message("%s IP6 Host lookup failed: %s\n"
2531                                                  , time_stamp(), rp+8);
2532                                 }
2533                                 else if (strlen(space+1))
2534                                 {
2535                                     *space = '\0';
2536                                     update_ip_entry(rp+8, space+1);
2537                                 }
2538                             }
2539                             continue;
2540                         }
2541 #endif /* USE_IPV6 */
2542                         else
2543                         {
2544                             /* remove the callback handle after processing
2545                              * the message.
2546                              */
2547                             keep_handle = MY_FALSE;
2548                         }
2549 
2550                         /* We have an ERQ message for a user supplied
2551                          * handle - execute it (after some sanity checks).
2552                          */
2553 
2554                         rest = msglen - 8;
2555                         if ((uint32)handle < MAX_PENDING_ERQ
2556                          && pending_erq[handle].fun.type != T_INVALID
2557                          && (   rest <= (mp_int)max_array_size
2558                              || !max_array_size
2559                              || pending_erq[handle].string_arg
2560                             )
2561                            )
2562                         {
2563                             svalue_t *erqp = &pending_erq[handle].fun;
2564                             object_t *ob;
2565                             wiz_list_t *user;
2566                             int num_arg;
2567 
2568                             command_giver = 0;
2569                             current_interactive = 0;
2570                             ob = !CLOSURE_MALLOCED(erqp->x.closure_type)
2571                                  ? erqp->u.ob
2572                                  : erqp->u.lambda->ob;
2573                             if (pending_erq[handle].string_arg)
2574                             {
2575                                 string_t * str;
2576 
2577                                 str = new_n_mstring(rp + 8, rest);
2578                                 push_string(inter_sp, str);
2579 
2580                                 num_arg = 1;
2581                             }
2582                             else
2583                             {
2584                                 unsigned char *cp;
2585                                 vector_t *v;
2586                                 svalue_t *svp;
2587 
2588                                 current_object = ob;
2589                                 v = allocate_array(rest);
2590                                 current_object = NULL;
2591                                 push_array(inter_sp, v);
2592                                 push_number(inter_sp, rest);
2593                                 cp = (unsigned char *)rp + 8;
2594                                 for (svp = v->item; --rest >=0; svp++)
2595                                 {
2596                                     svp->u.number = *cp++;
2597                                 }
2598 
2599                                 num_arg = 2;
2600                             }
2601 
2602                             user = ob->user;
2603                             if (user->last_call_out != current_time)
2604                             {
2605                                 user->last_call_out = current_time;
2606                                 CLEAR_EVAL_COST;
2607                             } else {
2608                                 assigned_eval_cost = eval_cost = user->call_out_cost;
2609                             }
2610                             RESET_LIMITS;
2611                             secure_callback_lambda(erqp, num_arg);
2612                             user->call_out_cost = eval_cost;
2613                             if (!keep_handle || (ob->flags & O_DESTRUCTED))
2614                             {
2615                                 free_svalue(erqp);
2616                                 erqp->type = T_INVALID;
2617                                 erqp->u.generic = (void *)free_erq;
2618                                 free_erq = &pending_erq[handle];
2619                             }
2620                         } /* if(valid handle) */
2621 
2622                         /* Messages for invalid handles are no error: e.g. the
2623                          * object could have gone away unexpectantly before
2624                          * the erq had time to answer.
2625                          */
2626 
2627                     } /* for (l,rp in buf_from_erq) */
2628 
2629                     /* Delete the processed data from the buffer */
2630                     if (rp != buf_from_erq)
2631                     {
2632                         move_memory(buf_from_erq, rp, (size_t)l);
2633                         input_from_erq = &buf_from_erq[l];
2634                     }
2635                 } /* if (read data from erq) */
2636             } /* if (erq socket ready) */
2637 
2638 #endif /* ERQ_DEMON */
2639 
2640             /* --- Try to get a new player --- */
2641             for (i = 0; i < numports; i++)
2642             {
2643                 if (FD_ISSET(sos[i], &readfds))
2644                 {
2645                     SOCKET_T new_socket;
2646 
2647                     length = sizeof addr;
2648                     new_socket = accept(sos[i], (struct sockaddr *)&addr
2649                                               , &length);
2650                     if ((int)new_socket != -1)
2651                         new_player( NULL, new_socket, &addr, (size_t)length
2652                                   , port_numbers[i]);
2653                     else if ((int)new_socket == -1
2654                       && errno != EWOULDBLOCK && errno != EINTR
2655                       && errno != EAGAIN && errno != EPROTO )
2656                     {
2657                         /* EBADF would be a valid cause for an abort,
2658                          * same goes for ENOTSOCK, EOPNOTSUPP, EFAULT.
2659                          * However, don't abort() because that tends to
2660                          * leave Mud admins baffled (and would opens the
2661                          * door for DoS attacks).
2662                          */
2663                         int errorno = errno;
2664                         fprintf( stderr
2665                                , "%s comm: Can't accept on socket %d "
2666                                  "(port %d): %s\n"
2667                                , time_stamp(), sos[i], port_numbers[i]
2668                                , strerror(errorno)
2669                                );
2670                         debug_message("%s comm: Can't accept on socket %d "
2671                                       "(port %d): %s\n"
2672                                      , time_stamp(), sos[i], port_numbers[i]
2673                                      , strerror(errorno)
2674                                      );
2675                         /* TODO: Was: perror(); abort(); */
2676                     }
2677                 }
2678             } /* for */
2679             /* check for alarm signal (heart beat) */
2680             if (comm_time_to_call_heart_beat)
2681             {
2682                 time_to_call_heart_beat = MY_TRUE;
2683                 return MY_FALSE;
2684             }
2685         } /* if (no NextCmdGiver) */
2686 
2687         /* See if we got any udp messages.
2688          * We don't test readfds so that we can accept udp messages with
2689          * short latency. But for the same reason, it was necessary to
2690          * include the descriptor number in the set to be selected on.
2691          * Note for Cygwin: since making sockets non-blocking
2692          *   is a bit tricky, we check if the socket is actually ready,
2693          *   to prevent freezing.
2694          * TODO: Always use the readfds information.
2695          */
2696 #if !defined(CYGWIN)
2697         if (udp_s >= 0)
2698 #else
2699         if (udp_s >= 0 && FD_ISSET(udp_s, &readfds))
2700 #endif
2701         {
2702             char *ipaddr_str;
2703             int cnt;
2704 
2705             length = sizeof addr;
2706             cnt = recvfrom(udp_s, udp_buf, sizeof(udp_buf)-1, 0
2707                           , (struct sockaddr *)&addr, &length);
2708             if (cnt != -1)
2709             {
2710                 string_t *udp_data;
2711 
2712                 udp_data = new_n_mstring(udp_buf, cnt);
2713                 if (!udp_data)
2714                 {
2715                     debug_message("%s Out of memory (%d bytes) for UDP message.\n"
2716                                  , time_stamp(), cnt);
2717                 }
2718                 else
2719                 {
2720                     command_giver = NULL;
2721                     current_interactive = NULL;
2722                     current_object = NULL;
2723                     trace_level = 0;
2724 #ifndef USE_IPV6
2725                     ipaddr_str = inet_ntoa(addr.sin_addr);
2726 #else
2727                     ipaddr_str = inet6_ntoa(addr.sin_addr);
2728 #endif
2729                     push_c_string(inter_sp, ipaddr_str);
2730                     push_string(inter_sp, udp_data); /* adopts the ref */
2731                     push_number(inter_sp, ntohs(addr.sin_port));
2732                     RESET_LIMITS;
2733                     callback_master(STR_RECEIVE_UDP, 3);
2734                     CLEAR_EVAL_COST;
2735                 }
2736             }
2737         } /* if (upd_s) */
2738 
2739         /* --- The Scan for User Commands --- */
2740 
2741         for (; NextCmdGiver >= 0; DecreaseCmdGiver)
2742         {
2743             object_t *snooper;
2744 
2745             ip = all_players[NextCmdGiver];
2746 
2747             if (ip == 0)
2748                 continue;
2749 
2750 #ifdef USE_TLS
2751             /* Special case for setting up a TLS connection: don't
2752              * attempt IO if the connection is still being set up.
2753              */
2754             if (ip->tls_status == TLS_HANDSHAKING)
2755             {
2756                 tls_continue_handshake(ip);
2757                 continue;
2758             }
2759 #endif
2760 
2761             if (FD_ISSET(ip->socket, &writefds))
2762             {
2763                 comm_write_pending(ip);
2764             }
2765             /* Skip players which have reached the ip->maxNumCmds limit
2766              * for this second. We let the data accumulate on the socket.
2767              */
2768             if (ip->last_time == current_time
2769              && ip->maxNumCmds >= 0
2770              && ip->numCmds >= ip->maxNumCmds)
2771                 continue;
2772 
2773             /* Get the data (if any), at max enough to fill .text[] */
2774 
2775             if (FD_ISSET(ip->socket, &readfds)) {
2776                 int l;
2777 
2778                 l = MAX_TEXT - ip->text_end;
2779 
2780                 /* In CHARMODE with combine-charset, the driver gets
2781                  * confused when receiving MAX_TEXT or more combinable
2782                  * characters.
2783                  * I couldn't quite figure out what and why, but
2784                  * reading less than MAX_TEXT characters works around
2785                  * the issue.
2786                  */
2787 #ifndef SIMULATE_CHARMODE
2788                 if ((ip->noecho & (CHARMODE_REQ|CHARMODE)) == (CHARMODE_REQ|CHARMODE))
2789 #else
2790                 if (ip->noecho & (CHARMODE_REQ|CHARMODE))
2791 #endif
2792                 {
2793                     l -= 2;
2794                 }
2795 
2796                 DTN(("text_end %hd, can read %d chars\n", ip->text_end, l));
2797 
2798 #ifdef USE_TLS
2799                 if (ip->tls_status != TLS_INACTIVE)
2800                     l = tls_read(ip, ip->text + ip->text_end, (size_t)l);
2801                 else
2802 #endif
2803                     l = socket_read(ip->socket, ip->text + ip->text_end, (size_t)l);
2804                 DTN(("# chars read: %d\n", l));
2805                 if (l == -1)
2806                 {
2807                     switch (errno)
2808                     {
2809                         case EAGAIN:
2810                             // There was no data for available for immediate read.
2811                             // This should not happen for plain TCP connections, but
2812                             // may for TLS connections.
2813 #ifdef USE_TLS
2814                             if (ip->tls_status == TLS_INACTIVE)
2815 #endif
2816                                 debug_message("%s Got unexpected EAGAIN upon socket read. Retrying later.\n");
2817                             // Fall-through
2818                         case EINTR:
2819                             // read was interrupted by a signal. Ignore and retry later again.
2820                             continue;
2821                         default:
2822                             // we regard other errors as non-recoverable.
2823                             debug_message("%s Error (%d) upon reading socket %d (ip %p '%s'), closing connection: %s\n"
2824                                           , time_stamp(), errno, ip->socket, ip,
2825                                           (ip->ob ? get_txt(ip->ob->name) : "<no name>"),
2826                                           strerror(errno));
2827                             remove_interactive(ip->ob, MY_FALSE);
2828                             continue;
2829                     }
2830                 }
2831                 if (l == 0) // TODO: is this really such a severe error?
2832                 {
2833                     if (ip->closing)
2834                         comm_fatal(ip, "Tried to read from closing socket.\n");
2835                         /* This will forcefully disconnect the user */
2836                     else
2837                         remove_interactive(ip->ob, MY_FALSE);
2838                     continue;
2839                 }
2840 #ifdef COMM_STAT
2841                 inet_packets_in++;
2842                 inet_volume_in += l;
2843 #endif
2844 
2845                 ip->text_end += l;
2846 
2847                 /* Here would be the place to send data through an
2848                  * outportal instead of returning it.
2849                  */
2850 
2851                 telnet_neg(ip);
2852             } /* if (cmdgiver socket ready) */
2853 
2854             /* if ip->text[0] does not hold a valid character, the outcome
2855              * of the comparison to input_escape does not matter.
2856              */
2857 
2858             /* ----- CHARMODE -----
2859              * command_start is 0 at the beginning. Received chars start at
2860              * text[0].  After the first character is processed, command_start
2861              * will be 1.  Chars are in text[1] then. Only after a
2862              * full_newline is command_start reset to 0. This is important for
2863              * bang-escape, the first char in a 'line' is stored in text[0],
2864              * subsequent chars are in text[1].
2865              *
2866              * chars_ready is the number of chars in the text buffer. If the
2867              * user is slow this will be 1. If the user pastes data it could
2868              * be more.  The chars are processed then one at a time (or if
2869              * combine-charset is used that many until a non-combinable char
2870              * is reached).
2871              *
2872              * The processed char(s) are copied to buff and handled in the
2873              * backend.
2874              *
2875              * If telnet_neg() returned state READY, we want to process the
2876              * string end marker (which represents the \r\n) also and have to
2877              * add 1 to strlen() for the chars_ready.
2878              *
2879              * The remark above 'if (destix > 0 && !buff[destix-1])' is not
2880              * quite true (anymore). Because we process the string terminating
2881              * \0 as a char, we will have a destix > 0 always - even if we got
2882              * a new line.  Mind, that buff[destix-1] is always buff[0] in
2883              * that 'if', because newlines are never combinable and we always
2884              * start with a new buffer for it!
2885              *
2886 #ifndef SIMULATE_CHARMODE
2887              * TODO: I dont think that it is neccesary to disable charmode if
2888              * TODO:: the client refuses to use it. The disadvantage of the
2889              * TODO:: present behaviour is a confused lpc object (which could
2890              * TODO:: not know if it gets linemode-lines). The charmode code
2891              * TODO:: does work with clients in linemode.
2892 #endif
2893              */
2894 
2895 #ifndef SIMULATE_CHARMODE
2896             if ((ip->noecho & (CHARMODE_REQ|CHARMODE)) == (CHARMODE_REQ|CHARMODE))
2897 #else
2898             if (ip->noecho & (CHARMODE_REQ|CHARMODE))
2899 #endif
2900             {
2901                 DTN(("CHARMODE_REQ\n"));
2902                 if (ip->text[0] != input_escape
2903                  || find_no_bang(ip) & IGNORE_BANG )
2904                 {
2905                     /* Unescaped input.
2906                      * Puts the next character(s) (addressed by
2907                      * .command_start) into buff[0] and return the data.
2908                      */
2909 
2910                     int destix;  /* Save index */
2911                     Bool end_of_line = MY_FALSE;
2912 
2913                     DTN(("  Unescaped input\n"));
2914 
2915                     if (ip->tn_state != TS_READY)
2916                     {
2917                         /* .text[] contains an incomplete negotiation.
2918                          * Set .chars_ready the amount of pure data available
2919                          * and temporarily suspend the telnet machine.
2920                          */
2921                         length = (TN_START_VALID(ip->tn_state)
2922                                    ? ip->tn_start
2923                                    : ip->command_end
2924                                  ) - ip->command_start;
2925                         DTN(("    incomplete negotiation: length %ld\n"
2926                            , (long)length));
2927                         if (!length)
2928                             continue;
2929                         if (length < 0)
2930                         {
2931                             comm_fatal(ip, "comm: data length < 0: %ld\n", (long)length);
2932                             continue;
2933                         }
2934                         DTN(("    save machine state %hhd, set to %d (READY)\n"
2935                           , ip->tn_state, TS_READY));
2936                         ip->save_tn_state = ip->tn_state;
2937                         ip->chars_ready = length;
2938                         ip->tn_state = TS_READY;
2939                     }
2940                     else if (!ip->chars_ready)
2941                     {
2942                         /* Empty input: we received an end of line.
2943                          * The telnet machine is already suspended, but
2944                          * we have to set the state for it to return to.
2945                          * At the moment it is TS_INVALID, so the next
2946                          * character received would be thrown away.
2947                          */
2948                         DTN(("    Empty input: save machine state %d (DATA)\n"
2949                           , TS_DATA));
2950                         length = strlen(ip->text + ip->command_start) + 1;
2951                         ip->chars_ready = length;
2952                         ip->save_tn_state = TS_DATA;
2953                         end_of_line = MY_TRUE;
2954                         /* tn_state is TS_READY */
2955                     }
2956 
2957                     /* Copy as many characters from the text[] into
2958                      * the buff[] as possible.
2959                      */
2960                     DTN(("  %"PRId32" chars ready\n", ip->chars_ready));
2961                     if (end_of_line)
2962                     {
2963                         DTN(("    faking NL\n"));
2964                         buff[0] = '\n';
2965                         destix = 1;
2966                     }
2967                     else for (destix = 0; destix < ip->chars_ready; )
2968                     {
2969                         char ch;
2970 
2971                         ch = ip->text[ip->command_start++];
2972                         buff[destix++] = ch;
2973                         if (!(ip->combine_cset[(ch&0xff) / 8] & (1 << (ch % 8)))
2974                          || !ch
2975                            )
2976                         {
2977                             /* This character can't be combined (or it is the
2978                              * end of the line).
2979                              * If it is not the first character encountered,
2980                              * undo the previous store; in either case break
2981                              * the loop.
2982                              */
2983                             if (destix != 1)
2984                             {
2985                                 destix--;
2986                                 ip->command_start--;
2987                             }
2988                             break;
2989                         }
2990                     }
2991 
2992                     /* destix is now the number of characters stored in
2993                      * buff[], and is at least 1.
2994                      */
2995 
2996                     if (!buff[destix-1])
2997                     {
2998                         /* End of line. Reinitialise the telnet machine
2999                          */
3000                         DTN(("    end of line: reinit telnet machine\n"));
3001                         destix--;
3002                         ip->command_start = 0;
3003                         ip->tn_state = TS_DATA;
3004                         telnet_neg(ip);
3005                     }
3006 
3007                     buff[destix] = '\0';
3008 
3009                     if (!end_of_line)
3010                         ip->chars_ready -= destix;
3011                     DTN(("  %"PRId32" chars left ready\n", ip->chars_ready));
3012                     if (!ip->chars_ready)
3013                     {
3014                         /* All the pure data was read, now restore the
3015                          * old telnet machine state.
3016                          * Leave the first char in to make input escape
3017                          * possible
3018                          */
3019                         DTN(("    restore old telnet machine state %hhd\n"
3020                             , ip->save_tn_state));
3021                         ip->tn_state = ip->save_tn_state;
3022                         ip->save_tn_state = TS_INVALID;
3023                         ip->tn_start -= ip->command_start - 1;
3024                         ip->command_end -= ip->command_start - 1;
3025 
3026                         if (ip->command_start && ip->command_end > 0)
3027                         {
3028                             move_memory( ip->text, ip->text+ip->command_start
3029                                        , ip->command_end
3030                                        );
3031                         }
3032 
3033                         ip->command_start = 1;
3034 
3035                         /* When receiving a pure data line in charmode, starting
3036                          * with the second char, these two values may become
3037                          * negative. We have to correct them then to point
3038                          * to ip->command_start.
3039                          */
3040                         DTN(("    tn_start %hd, command_end %hd\n", ip->tn_start, ip->command_end));
3041                         if (ip->tn_start < 1)
3042                             ip->tn_start = 1;
3043                         if (ip->command_end < 1)
3044                             ip->command_end = 1;
3045 
3046                         ip->text_end = ip->tn_end = ip->command_end;
3047                     }
3048 
3049                     command_giver = ip->ob;
3050                     trace_level = ip->trace_level;
3051                     DecreaseCmdGiver;
3052                     CmdsGiven = 0;
3053 
3054                     if (ip->last_time != current_time)
3055                     {
3056                         ip->last_time = current_time;
3057                         ip->numCmds = 0;
3058                     }
3059                     else
3060                         ip->numCmds++;
3061 
3062                     DTN(("--- return with char command %02x '%c' length %d ---\n", buff[0], buff[0], destix));
3063 
3064                     return MY_TRUE;
3065                 }
3066                 else if (ip->tn_state != TS_READY)
3067                 {
3068                     DT(("'%s'   Escaped input\n", get_txt(ip->ob->name)));
3069                     length = (TN_START_VALID(ip->tn_state)
3070                               ? ip->tn_start
3071                               : ip->command_end
3072                              ) - ip->command_start;
3073                     DTN(("  data length %ld\n", (long)length));
3074                     if (length < 0)
3075                     {
3076                         comm_fatal(ip, "comm: data length < 0: %ld\n", (long)length);
3077                         continue;
3078                     }
3079                     if (length > ip->chars_ready)
3080                     {
3081                         comm_socket_write(ip->text + ip->chars_ready
3082                                         , (size_t)(length - ip->chars_ready)
3083                                         , ip, 0);
3084                         ip->chars_ready = length;
3085                     }
3086                 }
3087             } /* if (CHARMODE_REQ) */
3088 
3089             /* The telnet negotiation produces the commands starting at
3090              * the beginning of .text[] and terminated with a '\0'. Whenever
3091              * a command is complete, the tn_state is TS_READY.
3092              */
3093             DTN(("tn complete, telnet machine state: %hhd\n", ip->tn_state));
3094             if (ip->tn_state == TS_READY)
3095             {
3096                 /* We have a command: copy it into buff, handle a
3097                  * possible snooper and return.
3098                  */
3099 
3100                 DTN(("telnet machine ready\n"));
3101                 /* buffer overflows here are impossible even with strcpy(),
3102                  * because buff is allocated in backend() as MAX_TEXT+4 and
3103                  * ip->text is allocated as MAX_TEXT+2. Ok, as long as nobody
3104                  * changes buff in backend() withour changing ip->text ... */
3105                 strcpy(buff, ip->text);
3106                 command_giver = ip->ob;
3107                 trace_level = ip->trace_level;
3108                 ip->chars_ready = 0; /* for escaped charmode */
3109 
3110                 /* Reinitialize the telnet machine, possibly already
3111                  * producing the next command in .text[].
3112                  */
3113                 ip->tn_state = TS_DATA;
3114                 telnet_neg(ip);
3115 
3116                 /* If the user is not in ed, don't let him issue another command
3117                  * before the poll comes again.
3118                  */
3119                 if (ip->input_handler
3120                  && ip->input_handler->type == INPUT_ED
3121                  && CmdsGiven < ALLOWED_ED_CMDS)
3122                 {
3123                     CmdsGiven++;
3124                     FD_CLR(ip->socket, &readfds);
3125                 }
3126                 else
3127                 {
3128                     DecreaseCmdGiver;
3129                     CmdsGiven = 0;
3130                 }
3131 
3132                 /* Manage snooping - should the snooper see type ahead?
3133                  * Well, he doesn't here.
3134                  */
3135                 if (NULL != (snooper = ip->snoop_by)
3136                  && !(snooper->flags & O_DESTRUCTED)
3137                  && !(ip->noecho & NOECHO_REQ)
3138                    )
3139                 {
3140                     if (O_IS_INTERACTIVE(snooper))
3141                     {
3142                         command_giver = snooper;
3143                         add_message("%% %s\n", buff);
3144                     }
3145                     else
3146                     {
3147                         /* buff is limited to MAX_TEXT+4. Additionally,
3148                          * get_message() is usually not called recursively or
3149                          * from a very high stack depth, so alloca() is
3150                          * probably ok. */
3151                         char *snoop_message = alloca(strlen(buff) + 4);
3152                         sprintf(snoop_message, "%% %s\n", buff);
3153                         tell_npc_str(snooper, snoop_message);
3154                     }
3155                     command_giver = ip->ob;
3156                 }
3157 
3158                 if (ip->last_time != current_time)
3159                 {
3160                     ip->last_time = current_time;
3161                     ip->numCmds = 0;
3162                 }
3163                 else
3164                     ip->numCmds++;
3165 
3166 #ifndef SIMULATE_CHARMODE
3167                 if ((ip->noecho & (CHARMODE_REQ|CHARMODE)) == CHARMODE_REQ)
3168                 {
3169                     DTN(("   clear CHARMODE as it was refused anyway\n"));
3170                     ip->noecho &= ~(CHARMODE_REQ|CHARMODE|CHARMODE_ACK);
3171                     reset_input_buffer(ip);
3172                 }
3173 #endif /* SIMULATE_CHARMODE */
3174 
3175                 DTN(("--- return with line command ---\n"));
3176                 DTN(("--- '%s'\n", buff));
3177                 return MY_TRUE;
3178             } /* if (have a command) */
3179 
3180         } /* for (NextCmdGiver) */
3181 
3182         /* If we got here, we couldn't find any commands:
3183          * loop and select (on timeout) again.
3184          */
3185 
3186     } /* while(forever) */
3187 
3188     /* NOTREACHED */
3189 #   undef StartCmdGiver
3190 #   undef DecreaseCmdGiver
3191 
3192 } /* get_message() */
3193 
3194 /*-------------------------------------------------------------------------*/
3195 void
3196 remove_interactive (object_t *ob, Bool force)
3197 
3198 /* Remove the interactive user <ob> immediately.
3199  * If <force> is true, the user is removed under all circumstances and
3200  * without even flushing the outgoing buffer.
3201  * This function should not be called from within a LPC command execution.
3202  */
3203 
3204 {
3205     object_t *save = command_giver;
3206     int i;
3207     interactive_t *interactive;
3208     object_t * curobj_save = current_object;
3209     int save_privilege;
3210 
3211     interactive = O_GET_INTERACTIVE(ob);
3212 
3213     /* Proper call? */
3214     for (i = 0; i < MAX_PLAYERS && all_players[i] != interactive; i++) NOOP;
3215     if (i >= MAX_PLAYERS)
3216     {
3217         fatal("Could not find and remove player %s\n", get_txt(ob->name));
3218         abort();
3219     }
3220     if (interactive->closing && !force)
3221         fatal("Double call to remove_interactive()\n");
3222 
3223     interactive->closing = MY_TRUE;
3224     current_object = ob;
3225 
3226     /* If the object is not destructed, save any ed buffers. */
3227 
3228     if ( !(ob->flags & O_DESTRUCTED) )
3229     {
3230         command_giver = ob;
3231         abort_input_handler(interactive);
3232     }
3233 
3234     save_privilege = malloc_privilege;
3235 
3236     /* If the object is still not destructed, inform the master */
3237 
3238     if ( !(ob->flags & O_DESTRUCTED) )
3239     {
3240         int numRemaining = interactive->text_end - interactive->command_start;
3241 
3242         command_giver = NULL;
3243         current_interactive = NULL;
3244         push_ref_object(inter_sp, ob, "remove_interactive");
3245 
3246         if (numRemaining > 0)
3247         {
3248             string_t * remaining = NULL;
3249             memsafe( remaining = new_n_mstring(interactive->text+interactive->command_start, numRemaining)
3250                    , numRemaining, "buffer for remaining data from socket");
3251             push_string(inter_sp, remaining);
3252         }
3253         else
3254             push_ref_string(inter_sp, STR_EMPTY);
3255 
3256         malloc_privilege = MALLOC_MASTER;
3257         callback_master(STR_DISCONNECT, 2);
3258         /* master might have used exec() */
3259         ob = interactive->ob;
3260     }
3261 
3262     interactive->catch_tell_activ = MY_FALSE;
3263 
3264     /* Untie eventual snooping relations */
3265 
3266     if (interactive->snoop_by)
3267     {
3268         if (O_IS_INTERACTIVE(interactive->snoop_by))
3269         {
3270             O_GET_INTERACTIVE(interactive->snoop_by)->snoop_on = NULL;
3271         }
3272         else
3273         {
3274             free_object(interactive->snoop_by, "remove_interactive");
3275         }
3276         interactive->snoop_by = NULL;
3277     }
3278     if (interactive->snoop_on)
3279     {
3280         interactive->snoop_on->snoop_by = NULL;
3281         interactive->snoop_on = NULL;
3282     }
3283 
3284     command_giver = ob;
3285 
3286 #ifdef ERQ_DEMON
3287     /* If this object is disconnected because it was used to connect
3288      * a new ERQ, put the connection into place and greet the ERQ.
3289      */
3290     if (interactive->do_close & FLAG_PROTO_ERQ
3291      && interactive->socket == erq_proto_demon
3292      && !force)
3293     {
3294         static unsigned char erq_welcome[] = { IAC, TELOPT_BINARY };
3295 
3296         add_message(message_flush);
3297         remove_flush_entry(interactive); /* To be sure */
3298 
3299         erq_demon = interactive->socket;
3300         erq_proto_demon = -1;
3301         socket_write(erq_demon, erq_welcome, sizeof erq_welcome);
3302     }
3303     else
3304 #endif
3305     {
3306         if (!force)
3307         {
3308             /* Say goodbye to the user. */
3309             trace_level |= interactive->trace_level;
3310             add_message(message_flush);
3311         }
3312 
3313         remove_flush_entry(interactive); /* To be sure */
3314 
3315 #ifdef USE_MCCP
3316         if (interactive->out_compress)
3317             end_compress(interactive, MY_TRUE);
3318             /* Always force the compression end as we won't get
3319              * a second chance at it.
3320              */
3321 #endif
3322 
3323         /* If there is anything left, try now. */
3324         comm_write_pending(interactive);
3325 
3326 #ifdef USE_TLS
3327         tls_deinit_connection(interactive);
3328 #endif
3329         shutdown(interactive->socket, 2);
3330         socket_close(interactive->socket);
3331     } /* if (erq or user) */
3332 
3333     release_host_access(interactive->access_class);
3334       /* One user less in this class */
3335 
3336     num_player--;
3337 
3338     /* Release all associated resources */
3339 
3340     while (interactive->input_handler)
3341     {
3342         input_t * ih = interactive->input_handler;
3343 
3344         interactive->input_handler = ih->next;
3345         free_input_handler(ih);
3346     }
3347 
3348     if (interactive->modify_command)
3349     {
3350         free_object(interactive->modify_command, "remove_interactive");
3351     }
3352 
3353 #ifdef USE_MCCP
3354     if (interactive->out_compress_buf)
3355        xfree(interactive->out_compress_buf);
3356     if (interactive->out_compress)
3357        xfree(interactive->out_compress);
3358 #endif
3359     free_svalue(&interactive->prompt);
3360 
3361     if (interactive->trace_prefix)
3362         free_mstring(interactive->trace_prefix);
3363 
3364     while (interactive->write_first)
3365     {
3366         struct write_buffer_s *tmp = interactive->write_first;
3367         interactive->write_first = tmp->next;
3368         xfree(tmp);
3369     }
3370 
3371     /* Unlink the interactive structure from the shadow sentence
3372      * of the object.
3373      */
3374     O_GET_INTERACTIVE(ob) = NULL;
3375     check_shadow_sent(ob);
3376 
3377     xfree(interactive);
3378     if (i < MAX_PLAYERS)
3379         all_players[i] = NULL;
3380     while (max_player && !all_players[max_player])
3381         max_player--;
3382     free_object(ob, "remove_interactive");
3383 
3384     command_giver = check_object(save);
3385     current_object = curobj_save;
3386     malloc_privilege = save_privilege;
3387 } /* remove_interactive() */
3388 
3389 /*-------------------------------------------------------------------------*/
3390 void
3391 refresh_access_data(void (*add_entry)(struct sockaddr_in *, int, long*) )
3392 
3393 /* Called from access_check after the ACCESS_FILE has been (re)read, this
3394  * function has to call the passed callback function add_entry for every
3395  * user currently logged in.
3396  */
3397 
3398 {
3399     interactive_t **user, *this;
3400     int n;
3401 
3402     user = all_players;
3403     for (n = max_player + 2; --n; user++)
3404     {
3405         this = *user;
3406         if (this)
3407         {
3408             struct sockaddr_in addr;
3409             int port;
3410             length_t length;
3411 
3412             length = sizeof(addr);
3413             getsockname(this->socket, (struct sockaddr *)&addr, &length);
3414             port = ntohs(addr.sin_port);
3415             (*add_entry)(&this->addr, port, &this->access_class);
3416         }
3417     }
3418 }
3419 
3420 /*-------------------------------------------------------------------------*/
3421 static INLINE void
3422 set_default_conn_charset (char charset[32])
3423 
3424 /* Set the default connection charset bitmask in <charset>.
3425  */
3426 
3427 {
3428     memset(charset, 255, 32);
3429     charset['\0'/8] &= ~(1 << '\0' % 8);
3430 } /* set_default_conn_charset() */
3431 
3432 /*-------------------------------------------------------------------------*/
3433 static INLINE void
3434 set_default_combine_charset (char charset[32])
3435 
3436 /* Set the default combine charset bitmask in <charset>.
3437  */
3438 
3439 {
3440     memset(charset, 0, 32);
3441     charset['\n'/8] &= ~(1 << '\n' % 8);
3442     charset['\0'/8] &= ~(1 << '\0' % 8);
3443 } /* set_default_combine_charset() */
3444 
3445 /*-------------------------------------------------------------------------*/
3446 static void
3447 new_player ( object_t *ob, SOCKET_T new_socket
3448            , struct sockaddr_in *addr, size_t addrlen
3449            , int login_port
3450            )
3451 
3452 /* Accept (or reject) a new connection on <new_socket> from <addr> (length
3453  * of structure is <addrlen>), accepted on port <login_port>.
3454  *
3455  * Called when get_message() detects a new connection on one of the
3456  * login ports, this function checks if the user may access the mud.
3457  *
3458  * If yes and <ob> is NULL, a new interactive structure is generated and
3459  * bound to the master, then master->connect() is called. This call is
3460  * expected to return an object and the interactive structure is rebound to
3461  * that object.
3462  * If yes and <ob> is an object, a new interactive structure is generated
3463  * and bound to <ob>
3464  *
3465  * Finally, logon() is called in the newly-interactive object.
3466  * Alternatively if no <ob> is given, master->connect() may exec() the
3467  * connection away from the master, in which case no further action will be
3468  * taken after the return from that call.
3469  *
3470  * If the connection can't be accepted for some reason, a failure
3471  * message will be send back to the user and the socket will be
3472  * closed.
3473  */
3474 
3475 {
3476     int   i;             /* Index of free slot in all_players[] */
3477     char *message;       /* Failure message */
3478     svalue_t *ret;       /* LPC call results */
3479     interactive_t *new_interactive;
3480                          /* The new interactive structure */
3481     long class;     /* Access class */
3482 
3483     /* Set some useful socket options */
3484     set_socket_nonblocking(new_socket);
3485     set_close_on_exec(new_socket);
3486     set_socket_own(new_socket);
3487 
3488     /* Check for access restrictions for this connection */
3489     message = allow_host_access(addr, login_port, &class);
3490 
3491     if (access_log != NULL)
3492     {
3493         FILE *log_file = fopen (access_log, "a");
3494 
3495         if (log_file) {
3496             FCOUNT_WRITE(log_file);
3497             fprintf(log_file, "%s %s: %s\n"
3498                    , time_stamp()
3499 #ifndef USE_IPV6
3500                    , inet_ntoa(addr->sin_addr)
3501 #else
3502                    , inet6_ntoa(addr->sin_addr)
3503 #endif
3504                    , message ? "denied" : "granted");
3505             fclose(log_file);
3506         }
3507     }
3508 
3509     if (message)
3510     {
3511         socket_write(new_socket, message, strlen(message));
3512         socket_write(new_socket, "\r\n", 2);
3513         socket_close(new_socket);
3514         return;
3515     }
3516 
3517     if (d_flag)
3518         debug_message("%s New player at socket %d.\n"
3519                      , time_stamp(), new_socket);
3520 
3521     /* Look for an empty slot in all_players[] */
3522     for (i = 0; i < MAX_PLAYERS && all_players[i] != NULL; i++) NOOP;
3523     if (i >= MAX_PLAYERS)
3524     {
3525         /* calling closures here would need special error handling */
3526         if (driver_hook[H_NO_IPC_SLOT].type == T_STRING)
3527         {
3528             string_t *msg;
3529 
3530             msg = driver_hook[H_NO_IPC_SLOT].u.str;
3531             socket_write(new_socket, get_txt(msg), mstrsize(msg));
3532         }
3533         else
3534         {
3535             message = "The mud is full. Come back later.\r\n";
3536             socket_write(new_socket, message, strlen(message));
3537         }
3538         socket_close(new_socket);
3539         debug_message("%s Out of IPC slots for new connection.\n"
3540                      , time_stamp());
3541         return;
3542     }
3543 
3544     /* The master must be loaded and free to accept a login */
3545     assert_master_ob_loaded();
3546     if (O_IS_INTERACTIVE(master_ob))
3547     {
3548         message = "Cannot accept connections. Come back later.\r\n";
3549         socket_write(new_socket, message, strlen(message));
3550         socket_close(new_socket);
3551         debug_message("%s Master still busy with previous new connection.\n"
3552                      , time_stamp());
3553         return;
3554     }
3555 
3556     command_giver = master_ob;
3557     trace_level = 0;
3558     new_interactive = xalloc(sizeof (interactive_t));
3559     if (!new_interactive)
3560     {
3561         message = "Cannot accept connection (out of memory). Come back later.\r\n";
3562         socket_write(new_socket, message, strlen(message));
3563         socket_close(new_socket);
3564         debug_message("%s Out of memory (%zu bytes) for new connection.\n"
3565                      , time_stamp(), sizeof(interactive_t));
3566         return;
3567     }
3568 
3569     if (ob && O_IS_INTERACTIVE(ob))
3570     {
3571         /* The caller provided an object to connect to. But since
3572          * it is already interactive, we have to terminate that
3573          * old connection.
3574          */
3575         remove_interactive(ob, MY_FALSE);
3576     }
3577 
3578     /* Link the interactive to the master */
3579 
3580     assert_shadow_sent(master_ob);
3581     O_GET_INTERACTIVE(master_ob) = new_interactive;
3582     master_ob->flags |= O_ONCE_INTERACTIVE;
3583     new_interactive->ob = ref_object(master_ob, "new_player");
3584     new_interactive->outgoing_conn = (ob != NULL);
3585 
3586     /* Initialize the rest of the interactive structure */
3587 
3588 #ifdef USE_MCCP
3589     new_interactive->compressing = 0;
3590     new_interactive->out_compress = NULL;
3591     new_interactive->out_compress_buf=NULL;
3592 #endif
3593 #ifdef USE_TLS
3594     new_interactive->tls_status = TLS_INACTIVE;
3595     new_interactive->tls_session = NULL;
3596     new_interactive->tls_cb = NULL;
3597 #endif
3598     new_interactive->input_handler = NULL;
3599     put_number(&new_interactive->prompt, 0);
3600     new_interactive->modify_command = NULL;
3601     new_interactive->closing = MY_FALSE;
3602     new_interactive->tn_enabled = MY_TRUE;
3603     new_interactive->do_close = 0;
3604     new_interactive->noecho = 0;
3605     new_interactive->supress_go_ahead = MY_FALSE;
3606     new_interactive->gobble_char = 0;
3607     new_interactive->catch_tell_activ = MY_TRUE;
3608     new_interactive->text_end = 0;
3609     new_interactive->command_start = 0;
3610     new_interactive->command_end = 0;
3611     new_interactive->chars_ready = 0;
3612     new_interactive->save_tn_state = TS_INVALID;
3613     new_interactive->tn_start = 0;
3614     new_interactive->tn_end = 0;
3615     new_interactive->tn_state = TS_DATA;
3616     new_interactive->ts_data = TS_DATA;
3617     new_interactive->snoop_on = NULL;
3618     new_interactive->snoop_by = NULL;
3619     new_interactive->last_time = current_time;
3620     new_interactive->numCmds = 0;
3621     new_interactive->maxNumCmds = -1;
3622     new_interactive->trace_level = 0;
3623     new_interactive->trace_prefix = NULL;
3624     new_interactive->message_length = 0;
3625     new_interactive->quote_iac = MY_TRUE;
3626     set_default_conn_charset(new_interactive->charset);
3627     set_default_combine_charset(new_interactive->combine_cset);
3628     new_interactive->text[0] = '\0';
3629     memcpy(&new_interactive->addr, addr, addrlen);
3630     new_interactive->access_class = class;
3631     new_interactive->socket = new_socket;
3632     new_interactive->next_player_for_flush = NULL;
3633     new_interactive->previous_player_for_flush = NULL;
3634     new_interactive->msg_discarded = DM_NONE;
3635 
3636     new_interactive->write_first = new_interactive->write_last = NULL;
3637     new_interactive->write_size = 0;
3638     new_interactive->write_max_size = -2;
3639 
3640     /* Add the new interactive structure to the list of users */
3641 
3642     all_players[i] = new_interactive;
3643     if (i > max_player)
3644         max_player = i;
3645     num_player++;
3646 
3647     current_interactive = master_ob;
3648 
3649     if (!ob)
3650     {
3651         /* The caller did not provide an object to connect to.
3652          * Call master->connect() and evaluate the result.
3653          */
3654         ret = callback_master(STR_CONNECT, 0);
3655         if (new_interactive != O_GET_INTERACTIVE(master_ob))
3656             return;
3657         if (ret == NULL
3658          || ret->type != T_OBJECT
3659          || (ob = ret->u.ob, O_IS_INTERACTIVE(ob)))
3660         {
3661             remove_interactive(master_ob, MY_FALSE);
3662             return;
3663         }
3664         command_giver = master_ob;
3665         add_message(message_flush);
3666     }
3667 
3668     /* ob is now a non-interactive object, either passed in from the caller
3669      * or returned from connect().
3670      * Relink the interactive from the master to this as the user object.
3671      */
3672 
3673     O_GET_INTERACTIVE(master_ob) = NULL;
3674     master_ob->flags &= ~O_ONCE_INTERACTIVE;
3675     check_shadow_sent(master_ob);
3676     free_object(master_ob, "new_player");
3677 
3678     assert_shadow_sent(ob);
3679     O_GET_INTERACTIVE(ob) = new_interactive;
3680     new_interactive->ob = ref_object(ob, "new_player");
3681     ob->flags |= O_ONCE_INTERACTIVE;
3682 
3683     /* Prepare to call logon() in the new user object.
3684      */
3685     command_giver = ob;
3686     current_interactive = ob;
3687     if (new_interactive->snoop_on)
3688     {
3689         new_interactive->snoop_on->snoop_by = ob;
3690     }
3691 #ifdef ERQ_DEMON
3692     (void) lookup_ip_entry(new_interactive->addr.sin_addr, MY_TRUE);
3693     /* TODO: We could pass the retrieved hostname right to login */
3694 #endif
3695 #ifdef USE_TLS
3696     /* If we're using secure connections and the connect() triggered
3697      * a handshake which is still going on, we call logon() as
3698      * the default TLS callback. This way, logon() is callled only
3699      * if the connection could be established, secure or not.
3700      */
3701     if (new_interactive->tls_status != TLS_HANDSHAKING)
3702     {
3703         /* Connection not secure, or already established: logon. */
3704         logon_object(ob);
3705     }
3706     else if (new_interactive->tls_cb == NULL)
3707     {
3708         callback_t * cb;
3709 
3710         /* Connection in TLS handshake, but not callback: set a callback
3711          * to the logon function.
3712          */
3713         if (find_function(STR_LOGON, current_interactive->prog) < 0)
3714         {
3715             errorf("Could not find %s() on the player %s\n", get_txt(STR_LOGON), get_txt(current_interactive->name));
3716             /* NOTREACHED */
3717         }
3718 
3719         xallocate(cb, sizeof(*cb), "logon tls-callback structure");
3720         setup_function_callback(cb, current_interactive, STR_LOGON, 0, NULL, MY_TRUE);
3721         new_interactive->tls_cb = cb;
3722 
3723     }
3724     /* else: Connection in TLS handshake and callback set by connect(). */
3725 #else
3726     logon_object(ob);
3727 #endif /* USE_TLS */
3728     if (!(ob->flags & O_DESTRUCTED))
3729         print_prompt();
3730     flush_all_player_mess();
3731 } /* new_player() */
3732 
3733 /*-------------------------------------------------------------------------*/
3734 void
3735 set_noecho (interactive_t *ip, char noecho, Bool local_change, Bool external)
3736 
3737 /* Change the input mode <i>->noecho to the given <noecho>, performing all
3738  * necessary telnet negotiations. If the driverhook H_NOECHO is set,
3739  * the hook function is expected to do all the negotiations.
3740  * If <local_change> is TRUE, the driver will not send out any telnet
3741  * commands for CHARMODE/LINEMODE changes.
3742  */
3743 
3744 {
3745     char old, confirm;
3746     object_t *ob;
3747 
3748     if (!ip->tn_enabled)
3749     {
3750         DTN(("set_noecho(%02hhx) old %02hhx: TN disabled\n"
3751             , noecho, ip->noecho));
3752     }
3753 
3754     old = ip->noecho;
3755 
3756     confirm = (char)(
3757       noecho | CHARMODE_REQ_TO_CHARMODE(noecho & (NOECHO_REQ|CHARMODE_REQ)));
3758     DTN(("set_noecho(%02hhx%s) old %02hhx %s\n"
3759        , noecho, local_change ? " local" : "", old, decode_noecho(old)));
3760     DTN(("  -> confirm: %02hhx %s\n"
3761        , confirm, decode_noecho(confirm)));
3762     DTN(("           -> %02hhx %s\n"
3763        , confirm | NOECHO_ACKSHIFT(confirm)
3764        , decode_noecho(confirm | NOECHO_ACKSHIFT(confirm))
3765        ));
3766 
3767     ip->noecho = confirm;
3768 
3769     confirm |= NOECHO_ACKSHIFT(confirm);
3770     if (((confirm ^ old) & (NOECHO_MASK|CHARMODE_MASK)) && ip->tn_enabled )
3771     {
3772         DTN(("set_noecho(): Mode changes\n"));
3773         ob = ip->ob;
3774         if (!(ob->flags & O_DESTRUCTED))
3775         {
3776             if (driver_hook[H_NOECHO].type == T_STRING
3777              || driver_hook[H_NOECHO].type == T_CLOSURE
3778                )
3779             {
3780                 DTN(("set_noecho():   calling H_NOECHO\n"));
3781                 push_number(inter_sp, noecho);
3782                 push_ref_valid_object(inter_sp, ob, "set_no_echo");
3783                 push_number(inter_sp,  local_change ? 1 : 0);
3784                 if (driver_hook[H_NOECHO].type == T_STRING)
3785                     secure_apply_ob(driver_hook[H_NOECHO].u.str, ob, 3, external);
3786                 else
3787                 {
3788                     if (driver_hook[H_NOECHO].x.closure_type == CLOSURE_LAMBDA)
3789                     {
3790                         free_object(driver_hook[H_NOECHO].u.lambda->ob
3791                                    , "set_noecho");
3792                         driver_hook[H_NOECHO].u.lambda->ob
3793                           = ref_object(ob, "set_noecho");
3794                     }
3795                     secure_call_lambda(&driver_hook[H_NOECHO], 3, external);
3796                 }
3797                 if (~confirm & old & CHARMODE_MASK)
3798                 {
3799                     if (ip->save_tn_state != TS_INVALID)
3800                     {
3801                         DT(("'%s' set_noecho():     0 chars ready, "
3802                             "saved state %hhd\n", get_txt(ip->ob->name)
3803                                               , ip->save_tn_state));
3804                         ip->chars_ready = 0;
3805                         ip->tn_state = ip->save_tn_state;
3806                     }
3807                     reset_input_buffer(ip);
3808                 }
3809             }
3810             else
3811             {
3812                 object_t *save;
3813 
3814                 save = command_giver;
3815                 command_giver = ob;
3816 #ifdef SAVE_NOECHO
3817                 ip->noecho &= ~NOECHO_DELAYED;
3818 #endif
3819                 if (~confirm & old & NOECHO)
3820                 {
3821                     DTN(("set_noecho():   WONT TELOPT_ECHO\n"));
3822                     send_wont(TELOPT_ECHO);
3823                 }
3824                 else if (confirm & ~old & NOECHO_MASK)
3825                 {
3826 #ifdef SAVE_NOECHO
3827                     if (confirm & ~old & CHARMODE_MASK)
3828                     {
3829                         ip->noecho |= NOECHO_DELAYED;
3830                         ip->noecho &= ~(NOECHO | NOECHO_REQ);
3831                         DTN(("set_noecho():   delaying WILL TELOPT_ECHO\n"));
3832                     }
3833                     else
3834                     {
3835 #endif
3836                         DTN(("set_noecho():   WILL TELOPT_ECHO\n"));
3837                         send_will(TELOPT_ECHO);
3838 #ifdef SAVE_NOECHO
3839                     }
3840 #endif
3841                 }
3842                 else /* No change in NOECHO mode */ if (confirm & NOECHO)
3843                 {
3844                     /* Since we stay in NOECHO mode, we need the ACK flag set. */
3845                     DTN(("set_noecho():   Staying in NOECHO mode\n"));
3846                     ip->noecho |= NOECHO_ACKSHIFT(NOECHO);
3847                 }
3848 
3849                 if (ip->supress_go_ahead && !(confirm & (NOECHO|CHARMODE)))
3850                 {
3851                     DTN(("set_noecho():   WONT TELOPT_SGA\n"));
3852                     ip->supress_go_ahead = MY_FALSE;
3853                     send_wont(TELOPT_SGA);
3854                 }
3855                 /* Only using SGA for charmode is supported hardcoded.
3856                  * To make more sophisticated negotiations, e.g. using LINEMODE,
3857                  * use the H_NOECHO hook.
3858                  */
3859                 if ((~confirm & old & CHARMODE_MASK)
3860                 ||  ((~confirm & old & NOECHO_STALE) && (old & CHARMODE_MASK))
3861                    )
3862                 {
3863                     if(~confirm & old & CHARMODE_MASK)
3864                     {
3865                         DTN(("set_noecho():   turn off charmode\n"));
3866                         if ((old & CHARMODE) && !local_change)
3867                         {
3868                             DTN(("set_noecho():     DONT TELOPT_SGA\n"));
3869                             send_dont(TELOPT_SGA);
3870                         }
3871                         if (ip->save_tn_state != TS_INVALID)
3872                         {
3873                             DTN(("set_noecho():     0 chars ready, saved state %hhd\n", ip->save_tn_state));
3874                             ip->chars_ready = 0;
3875                             ip->tn_state = ip->save_tn_state;
3876                         }
3877                     }
3878 
3879                     reset_input_buffer(ip);
3880                 }
3881                 else if (confirm & ~old & CHARMODE_MASK)
3882                 {
3883                     DTN(("set_noecho():   turn on charmode\n"));
3884                     if (!local_change)
3885                     {
3886                         DTN(("set_noecho():     DO+WILL TELOPT_SGA\n"));
3887                         send_do(TELOPT_SGA);
3888                         /* some telnet implementations (Windows' telnet is one) mix
3889                          * up DO and WILL SGA, thus we send WILL SGA as well.
3890                          */
3891                         send_will(TELOPT_SGA);
3892                         ip->supress_go_ahead = MY_TRUE;
3893                     }
3894                     else
3895                         /* Since there won't be any telnet negotiation
3896                          * we can assume that CHARMODE is acknowledged.
3897                          */
3898                         ip->noecho |= NOECHO_ACKSHIFT(CHARMODE);
3899 
3900                 }
3901                 else /* No change in CHARMODE mode */ if (confirm & CHARMODE)
3902                 {
3903                     /* Since we stay in CHARMODE mode, we need the ACK flag set. */
3904                     DTN(("set_noecho():   Staying in CHARMODE mode\n"));
3905                     ip->noecho |= NOECHO_ACKSHIFT(CHARMODE);
3906                 }
3907 
3908                 command_giver = save;
3909             }
3910         } /* if (!(ob->flags & O_DESTRUCTED)) */
3911     }
3912     else
3913     {
3914         /* No change in modes.
3915          * However, if we stay in NOECHO/CHARMODE, we need to set
3916          * the ACK flags.
3917          */
3918         if (confirm & CHARMODE)
3919         {
3920             /* Since we stay in CHARMODE mode, we need the ACK flag set. */
3921             DTN(("set_noecho():   Staying in CHARMODE mode\n"));
3922             ip->noecho |= NOECHO_ACKSHIFT(CHARMODE);
3923         }
3924         if (confirm & NOECHO)
3925         {
3926             /* Since we stay in NOECHO mode, we need the ACK flag set. */
3927             DTN(("set_noecho():   Staying in NOECHO mode\n"));
3928             ip->noecho |= NOECHO_ACKSHIFT(NOECHO);
3929         }
3930     }
3931 
3932 } /* set_noecho() */
3933 
3934 /*-------------------------------------------------------------------------*/
3935 int
3936 find_no_bang (interactive_t *ip)
3937 
3938 /* Find the most recent input_to in *<ip> which specified "IGNORE_BANG" and
3939  * return its full "noecho" flags. This may be the ip->noecho itself!
3940  * If there is none, return 0.
3941  */
3942 
3943 {
3944     input_t *ih;
3945 
3946     if (ip->noecho & IGNORE_BANG)
3947         return ip->noecho;
3948 
3949     for (ih = ip->input_handler; ih; ih = ih->next)
3950         if (ih->noecho & IGNORE_BANG)
3951             return ih->noecho;
3952     return 0;
3953 } /* find_no_bang() */
3954 
3955 /*-------------------------------------------------------------------------*/
3956 static Bool
3957 call_input_to (interactive_t *i, char *str, input_to_t *it)
3958 
3959 /* Call the input_to handler <it> for this user <i> and the input <str>.
3960  * Return TRUE if this handler was executed successfully, and FALSE
3961  * if the input was not processed.
3962  *
3963  * This function is only called by call_function_interactive().
3964  */
3965 
3966 {
3967     static input_to_t current_it;
3968       /* Current input_to, static so that longjmp() won't clobber it. */
3969 
3970     struct error_recovery_info error_recovery_info;
3971     object_t   *ob;   /* object holding <function> */
3972 
3973 
3974     /* We got the right input_to_t. Check if it's still valid. */
3975     ob = callback_object(&(it->fun));
3976     if (!ob)
3977     {
3978         /* Sorry, the object has selfdestructed ! */
3979         free_input_to(it);
3980         return MY_FALSE;
3981     }
3982 
3983     if (O_PROG_SWAPPED(ob)
3984      && load_ob_from_swap(ob) < 0)
3985     {
3986         free_input_to(it);
3987         errorf("Out of memory: unswap object '%s'.\n", get_txt(ob->name));
3988         return MY_FALSE;
3989     }
3990 
3991     /* Clear the input_to() reference in case the function called
3992      * sets up a new one.
3993      */
3994     current_it = *it;
3995     xfree(it);
3996     free_svalue(&current_it.input.prompt); /* Don't need this anymore */
3997 
3998     /* Activate the local error recovery context */
3999 
4000     error_recovery_info.rt.last = rt_context;
4001     error_recovery_info.rt.type = ERROR_RECOVERY_BACKEND;
4002     rt_context = (rt_context_t *)&error_recovery_info.rt;
4003 
4004     if (setjmp(error_recovery_info.con.text))
4005     {
4006         /* An error occured: free the remaining data,
4007          * restore the error stack and return
4008          */
4009 
4010         clear_state();
4011         debug_message("%s Error in input_to().\n", time_stamp());
4012         free_callback(&(current_it.fun));
4013         rt_context = error_recovery_info.rt.last;
4014         return MY_TRUE;
4015     }
4016 
4017     /* Call the input_to() function with the newly input string */
4018 
4019     push_c_string(inter_sp, str);
4020     (void)backend_callback(&(current_it.fun), 1);
4021 
4022     rt_context = error_recovery_info.rt.last;
4023 
4024     /* Done */
4025     return MY_TRUE;
4026 }
4027 
4028 /*-------------------------------------------------------------------------*/
4029 Bool
4030 call_function_interactive (interactive_t *i, char *str)
4031 
4032 /* Execute a pending input handler for this user <i> and the input <str>
4033  * Return TRUE if an input_to() or ed() was pending and executed, and FALSE
4034  * if the input was not processed.
4035  *
4036  * This function is called by the backend as part of the input processing.
4037  */
4038 
4039 {
4040     input_t    *ih;
4041     ih = i->input_handler;
4042 
4043     /* _Are_ there an input_to() pending? */
4044     if (!ih)
4045         return MY_FALSE;
4046 
4047     /* Yes, there are. Check if we have to handle input escape. */
4048     if (*str == input_escape && str[1])
4049     {
4050         input_t * prev;
4051 
4052         for (prev = NULL
4053             ; ih && !(ih->noecho & IGNORE_BANG)
4054             ; prev = ih, ih = ih->next)
4055             NOOP;
4056 
4057         if (ih)
4058         {
4059             /* Move this 'IGNORE_BANG' input_to to the top of list
4060              * since it's the one we're going to execute.
4061              */
4062             if (prev)
4063             {
4064                 prev->next = ih->next;
4065                 ih->next = i->input_handler;
4066                 i->input_handler = ih;
4067             }
4068 
4069             if (!(i->noecho & NOECHO) != !(ih->noecho & NOECHO_REQ)) {
4070                 /* !message for ECHO-context  while in NOECHO - simulate the
4071                  * echo by sending the (remaining) raw data we got.
4072                  */
4073                 add_message("%s\n", str + i->chars_ready);
4074                 i->chars_ready = 0;
4075             }
4076 
4077             /* Don't hide the leading input escape */
4078         }
4079         else
4080         {
4081             /* Bang-input but no matching input_to(): return */
4082             return MY_FALSE;
4083         }
4084     }
4085 
4086     switch (ih->type)
4087     {
4088     case INPUT_TO:
4089         {
4090             Bool res;
4091 
4092             i->input_handler = ih->next;
4093 
4094             /* if there is a series of noecho/charmode input, we should only
4095              * negotiate when we know that the state actually should change.
4096              * In other words: should the input_to function request NOECHO
4097              * again, the NOECHO_STALE bit will be cleared and we will not
4098              * turn NOECHO off after the call.
4099              */
4100             if (i->noecho)
4101             {
4102                 i->noecho |= NOECHO_STALE;
4103             }
4104 
4105             res = call_input_to(i, str, (input_to_t*) ih);
4106 
4107             /* If NOECHO is no longer needed, turn it off. */
4108 
4109             if (i->noecho & NOECHO_STALE)
4110             {
4111                 set_noecho(i, i->input_handler ? i->input_handler->noecho : 0
4112                             , i->input_handler ? i->input_handler->local : MY_FALSE
4113                             , MY_TRUE);
4114             }
4115 
4116             return res;
4117         }
4118 
4119     case INPUT_ED:
4120         ed_cmd(str, ih);
4121         return MY_TRUE;
4122     }
4123 
4124     return MY_FALSE;
4125 
4126 } /* call_function_interactive() */
4127 
4128 /*-------------------------------------------------------------------------*/
4129 static Bool
4130 set_call ( object_t *ob, input_to_t *it, char noecho
4131          , Bool local_change, Bool append)
4132 
4133 /* Set a a new input_to <it> with the flags <noecho> (mainly really NOECHO,
4134  * but also IGNORE_BANG or not) to the interactive object <ob>.
4135  * If <local_change> is TRUE, the driver will not send out any telnet
4136  * commands for CHARMODE/LINEMODE changes.
4137  * If <append> is TRUE, the call is appended to the list of existing
4138  * input_to's, if any.
4139  * Return TRUE on success.
4140  *
4141  * Called for efun input_to().
4142  */
4143 
4144 {
4145     interactive_t *ip;
4146 
4147     if (ob == NULL || it == NULL)
4148         return MY_FALSE;
4149     if (!(O_SET_INTERACTIVE(ip, ob))
4150      || ip->closing
4151        )
4152     {
4153         return MY_FALSE;
4154     }
4155 
4156     if (!append && ip->input_handler != NULL)
4157     {
4158         input_t * ih = ip->input_handler;
4159 
4160         while (ih && ih->type != INPUT_TO)
4161             ih = ih->next;
4162 
4163          if (ih && ((input_to_t*)ih)->eval_nr == eval_number)
4164              return MY_FALSE;
4165     }
4166 
4167     it->input.noecho = noecho;
4168     it->input.local = local_change;
4169     it->input.type = INPUT_TO;
4170 
4171     /* Appended input_tos never count. */
4172     it->eval_nr = eval_number - (append ? 1 : 0);
4173 
4174     add_input_handler(ip, &(it->input), append);
4175     return MY_TRUE;
4176 } /* set_call() */
4177 
4178 /*-------------------------------------------------------------------------*/
4179 void
4180 remove_all_players (void)
4181 
4182 /* Destruct all user objects. This is first tried by calling master->remove()
4183  * for every object. If this doesn't destruct the user object,
4184  * destruct() is used.
4185  * The function is called when the game is shut down.
4186  */
4187 
4188 {
4189     int i;
4190 
4191     for (i = 0; i < MAX_PLAYERS; i++) {
4192         if (all_players[i] == 0 || (all_players[i]->ob->flags & O_DESTRUCTED))
4193             continue;
4194         command_giver = all_players[i]->ob;
4195         trace_level |= all_players[i]->trace_level;
4196         RESET_LIMITS;
4197         CLEAR_EVAL_COST;
4198         push_ref_object(inter_sp, all_players[i]->ob, "remove_all_players");
4199         (void)callback_master(STR_REMOVE_PL, 1);
4200         if ( !(all_players[i]->ob->flags & O_DESTRUCTED) ) {
4201             destruct(all_players[i]->ob);
4202         }
4203     }
4204 }
4205 
4206 /*-------------------------------------------------------------------------*/
4207 static void
4208 print_prompt_string (string_t *prompt)
4209 
4210 /* Print the string <prompt> to the current command_giver.
4211  * This function checks if the driver hook H_PRINT_PROMPT is set and in that
4212  * case passes the string through the set function. If it is not set,
4213  * the prompt is printed via add_message().
4214 #ifdef USE_TLS
4215  * The prompt is not printed at all if the interactive is currently
4216  * negotiating the TLS handshake.
4217 #endif
4218  */
4219 
4220 {
4221     svalue_t *hook = &driver_hook[H_PRINT_PROMPT];
4222 
4223 #ifdef USE_TLS
4224     {
4225         interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4226         if (NULL != ip && TLS_HANDSHAKING == ip->tls_status)
4227             return;
4228     }
4229 #endif /* USE_TLS */
4230 
4231     if (hook->type == T_CLOSURE)
4232     {
4233         object_t *ob;
4234 
4235         /* Needed for clean error recovery */
4236 
4237         previous_ob = 0;
4238         current_object = command_giver;
4239 
4240         /* Check if the object the closure is bound to still exists.
4241          * If not, erase the hook, print the prompt using add_message(),
4242          * then throw an error.
4243          */
4244         ob = !CLOSURE_MALLOCED(hook->x.closure_type)
4245              ? hook->u.ob
4246              : hook->u.lambda->ob;
4247 
4248         if (ob->flags & O_DESTRUCTED)
4249         {
4250             free_svalue(hook);
4251             put_number(hook, 0);
4252             current_object = NULL; /* So that catch_tell() can see it */
4253             add_message(FMT_STRING, prompt);
4254             errorf("H_PRINT_PROMPT for %s was a closure bound to a "
4255                    "now-destructed object - hook removed.\n",
4256                    get_txt(command_giver->name));
4257             /* NOTREACHED */
4258         }
4259 
4260         push_ref_string(inter_sp, prompt);
4261         call_lambda(hook, 1);
4262         free_svalue(inter_sp--);
4263     }
4264     else if (hook->type == T_STRING)
4265     {
4266         push_ref_string(inter_sp, prompt);
4267         (void)sapply(hook->u.str, command_giver, 1);
4268     }
4269     else
4270     {
4271         current_object = NULL; /* So that catch_tell() can see it */
4272         add_message(FMT_STRING, prompt);
4273     }
4274 } /* print_prompt_string() */
4275 
4276 /*-------------------------------------------------------------------------*/
4277 void
4278 print_prompt (void)
4279 
4280 /* Print the prompt of the current command_giver, unless disabled
4281  * by input_to. If the prompt is set to a closure, the closure
4282  * is called and expected to return the actual prompt string or
4283  * to print the prompt itself.
4284  */
4285 
4286 {
4287     interactive_t *ip;
4288     svalue_t *prompt = NULL;
4289     object_t * save_current = current_object;
4290     object_t * save_previous = previous_ob;
4291     Bool usingDefaultPrompt = MY_FALSE;
4292 
4293 #ifdef DEBUG
4294     if (command_giver == 0)
4295         fatal("command_giver == 0.\n");
4296 #endif
4297 
4298     if (!(O_SET_INTERACTIVE(ip, command_giver)))
4299         fatal("print_prompt() of non-interactive object\n");
4300 
4301     if (ip->input_handler != NULL)
4302     {
4303         prompt = &ip->input_handler->prompt;
4304     }
4305     else
4306     {
4307         prompt = &ip->prompt;
4308         if (prompt->type != T_CLOSURE && prompt->type != T_STRING)
4309         {
4310             prompt = &driver_hook[H_DEFAULT_PROMPT];
4311             usingDefaultPrompt = MY_TRUE;
4312         }
4313     }
4314 
4315     if (prompt->type == T_CLOSURE)
4316     {
4317         object_t *ob;
4318 
4319         /* Needed for clean error recovery */
4320 
4321         previous_ob = 0;
4322         current_object = command_giver;
4323 
4324         /* Check if the object the closure is bound to still exists.
4325          * If not, restore the prompt to the default (this also works with
4326          * the default prompt driver hook), then throw an error.
4327          */
4328         ob = !CLOSURE_MALLOCED(prompt->x.closure_type)
4329              ? prompt->u.ob
4330              : prompt->u.lambda->ob;
4331 
4332         if (ob && ob->flags & O_DESTRUCTED)
4333         {
4334             free_svalue(prompt);
4335             put_ref_string(prompt, STR_DEFAULT_PROMPT);
4336             print_prompt_string(prompt->u.str);
4337             errorf("Prompt of %s was a closure bound to a now-destructed "
4338                    "object - default prompt restored.\n",
4339                    get_txt(command_giver->name));
4340             /* NOTREACHED */
4341         }
4342 
4343         call_lambda(prompt, 0);
4344         prompt = inter_sp;
4345         if (prompt->type != T_STRING)
4346         {
4347             free_svalue(prompt);
4348         }
4349         else
4350         {
4351             /* beware: print_prompt_string() might cause an error.
4352              * Thus, the LPC stack has to include the prompt to free it then.
4353              */
4354             print_prompt_string(prompt->u.str);
4355             free_svalue(prompt);
4356         }
4357         inter_sp--;
4358     }
4359     else if (prompt->type == T_STRING)
4360     {
4361         print_prompt_string(prompt->u.str);
4362     }
4363     else if (usingDefaultPrompt)
4364     {
4365         /* No prompt nor default prompt given, and it's not an input_to:
4366          * print the usual prompt.
4367          */
4368         print_prompt_string(STR_DEFAULT_PROMPT);
4369     }
4370 
4371     current_object = save_current;
4372     previous_ob = save_previous;
4373 } /* print_prompt() */
4374 
4375 /*-------------------------------------------------------------------------*/
4376 static int
4377 set_snoop (object_t *me, object_t *you)
4378 
4379 /* Set a snoop from <me> on the IO of <you>. If <you> is NULL, an
4380  * existing snoop is terminated. <me> need not to be an interactive
4381  * user.
4382  *
4383  * Return 1 on success, -1 if a snooping loop would be caused, 0 for
4384  * any other failure.
4385  *
4386  * The function calls master->valid_snoop() to test if the snoop
4387  * is allowed.
4388  */
4389 
4390 {
4391     interactive_t *on = NULL; /* interactive struct of <you> */
4392     interactive_t *by = NULL; /* interactive struct of <me> */
4393     interactive_t *tmp;
4394     svalue_t *ret;
4395 
4396     /* Stop if people managed to quit before we got this far */
4397     if (me->flags & O_DESTRUCTED)
4398         return 0;
4399     if (you && (you->flags & O_DESTRUCTED))
4400         return 0;
4401 
4402     /* Check for permissions with valid_snoop in master */
4403     push_ref_object(inter_sp, me, "snoop");
4404     if (you == NULL)
4405         push_number(inter_sp, 0);
4406     else
4407         push_ref_object(inter_sp, you, "snoop");
4408     ret = apply_master(STR_VALID_SNOOP, 2);
4409 
4410     if (!ret || ret->type != T_NUMBER || ret->u.number == 0)
4411         return 0;
4412 
4413     if (me->flags & O_DESTRUCTED)
4414         return 0;
4415 
4416     /* Test is <me> is able to snoop anyway.
4417      * Set <by> to <me>'s interactive struct if yes.
4418      */
4419     if (O_SET_INTERACTIVE(by, me) && by->closing)
4420         return 0;
4421 
4422     if (you)
4423     {
4424         /* Test if <you> can be snooped at all.
4425          * Set <on> to <you>'s interactive struct if yes.
4426          */
4427         if (you->flags & O_DESTRUCTED)
4428             return 0;
4429         if (!(O_SET_INTERACTIVE(on, you)) || on->closing)
4430             return 0;
4431     }
4432     else
4433     {
4434         /* Stop snoop.
4435          * For this, set <on> to the interactive struct of the snoops
4436          * victim. If <by> is NULL, <me> is propably a netdead user
4437          * or a NPC and we have to scan the list of users for the victim.
4438          */
4439 
4440         if (!by)
4441         {
4442             int i;
4443 
4444             for (i = max_player+1;;)
4445             {
4446                 if (--i < 0)
4447                     return 0;
4448                 if (NULL != (on = all_players[i]) && on->snoop_by == me)
4449                     break;
4450             }
4451             if (on->closing)
4452                 return 0;
4453             free_object(me, "set_snoop");
4454         }
4455         else
4456         {
4457             on = by->snoop_on;
4458             if (!on || on->closing)
4459                 return 0;
4460             by->snoop_on = NULL;
4461         }
4462         on->snoop_by = NULL;
4463         return 1;
4464     }
4465 
4466     /* If we come here, a snoop on <you> by <me> is possible.
4467      * Now protect against snooping loops.
4468      */
4469 
4470     for (tmp = on; tmp; tmp = tmp->snoop_on)
4471     {
4472         if (tmp == by)
4473             return -1;
4474     }
4475 
4476     /* Terminate previous snoop, if any */
4477     if (on->snoop_by)
4478     {
4479         interactive_t *ip;
4480 
4481         if (O_SET_INTERACTIVE(ip, on->snoop_by))
4482         {
4483             if (ip->closing)
4484                 return 0;
4485             ip->snoop_on = 0;
4486         }
4487         else
4488         {
4489             free_object(on->snoop_by, "set_snoop");
4490         }
4491         on->snoop_by = NULL;
4492     }
4493 
4494     /* Initialise the new snoop */
4495     if (by)
4496     {
4497         if (by->snoop_on)
4498         {
4499             if (by->snoop_on->closing)
4500                 return 0;
4501             by->snoop_on->snoop_by = 0;
4502             by->snoop_on = 0;
4503         }
4504         by->snoop_on = on;
4505     }
4506     else
4507     {
4508         ref_object(me, "set_snoop");
4509     }
4510 
4511     on->snoop_by = me;
4512     return 1;
4513 } /* set_snoop() */
4514 
4515 /*=========================================================================*/
4516 /*                      Telnet Support
4517  */
4518 
4519 /* Note: when stored in char variables, IAC can be equal to EOF.
4520  * This can cause sprintf(), which is used in add_message(), to abort
4521  * output after EOF. Therefore, don't try to send anything after the IAC
4522  * in the same call to add_message().
4523  */
4524 
4525 /*-------------------------------------------------------------------------*/
4526 static INLINE void
4527 send_telnet_option (char action, char option)
4528 
4529 /* Send IAC <action> <option> */
4530 
4531 {
4532     char msg[3];
4533 
4534     msg[0] = IAC;
4535     msg[1] = action;
4536     msg[2] = option;
4537     SEND_TELNET_COMMAND(
4538       add_message(FMT_BINARY, msg, 3);
4539       add_message(message_flush);
4540     )
4541 } /* send_telnet_option() */
4542 
4543 /*-------------------------------------------------------------------------*/
4544 static void
4545 send_wont (int option)
4546 
4547 /* Send IAC WONT <option> */
4548 
4549 {
4550     DTF(("%s TDEBUG: send IAC WONT %02x\n", time_stamp(), option));
4551     send_telnet_option(WONT, option);
4552 }
4553 
4554 /*-------------------------------------------------------------------------*/
4555 static void
4556 send_dont (int option)
4557 
4558 /* Send IAC DONT <option> */
4559 
4560 {
4561     DTF(("%s TDEBUG: send IAC DONT %02x\n", time_stamp(), option));
4562     send_telnet_option(DONT, option);
4563 }
4564 
4565 /*-------------------------------------------------------------------------*/
4566 static void
4567 send_will (int option)
4568 
4569 /* Send IAC WILL <option> */
4570 
4571 {
4572     DTF(("%s TDEBUG: send IAC WILL %02x\n", time_stamp(), option));
4573     send_telnet_option(WILL, option);
4574 }
4575 
4576 /*-------------------------------------------------------------------------*/
4577 static void
4578 send_do (int option)
4579 
4580 /* Send IAC DO <option> */
4581 
4582 {
4583     DTF(("%s TDEBUG: send IAC DO %02x\n", time_stamp(), option));
4584     send_telnet_option(DO, option);
4585 }
4586 
4587 /*-------------------------------------------------------------------------*/
4588 static void
4589 reply_nil (int option UNUSED)
4590 
4591 /* Dummy function which does nothing. */
4592 
4593 {
4594 #ifdef __MWERKS__
4595 #    pragma unused(option)
4596 #endif
4597 }
4598 
4599 /*-------------------------------------------------------------------------*/
4600 static void
4601 reply_to_do_echo (int option)
4602 
4603 /* Send IAC WONT <option> if we don't want noecho mode.
4604  * If we requested WILL ECHO this is the client's reply. Set NOECHO_ACK. Send
4605  * no reply.  Send WILL ECHO if we want noecho but where told not to echo
4606  * (reactivate noecho mode).
4607  */
4608 
4609 {
4610     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4611 
4612     DTN(("reply to DO ECHO\n"));
4613     if (ip->noecho & NOECHO_MASK) {
4614         if ( !(ip->noecho & NOECHO) ) {
4615             /* We were previously told not to echo */
4616             send_will(option);
4617         }
4618         else DTN(("  we don't need to say WILL\n"));
4619         /* If we already said that we will echo, be quiet */
4620         ip->noecho |= NOECHO_MASK;
4621     } else {
4622         send_wont(option);
4623     }
4624 }
4625 
4626 /*-------------------------------------------------------------------------*/
4627 static void
4628 reply_to_dont_echo (int option)
4629 
4630 /* If we requested WONT ECHO this is the client's reply. Do nothing.
4631  * If client requests us to not echo while we want to, send WONT ECHO and
4632  * delete NOECHO flag. The client may turn the option on again later.
4633  */
4634 
4635 {
4636     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4637 
4638     DTN(("reply to DONT ECHO\n"));
4639     if (ip->noecho & NOECHO_MASK) {
4640         if (!~(ip->noecho | ~NOECHO_MASK)) {
4641             /* We were granted the option before */
4642             send_wont(option);
4643         }
4644         else DTN(("  we don't need to say WONT\n"));
4645         ip->noecho = (char)((ip->noecho & ~NOECHO) | NOECHO_ACK);
4646     }
4647 }
4648 
4649 /*-------------------------------------------------------------------------*/
4650 static void
4651 reply_to_do_sga (int option)
4652 
4653 /* Send IAC WILL <option> if Suppress Go Ahead is not already active and
4654  * mark it as active, send IAC WONT <option> if neither in NOECHO or
4655  * CHARMODE mode.
4656  */
4657 
4658 {
4659     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4660 
4661     DTN(("reply to DO SGA\n"));
4662     if (ip->noecho & (NOECHO_MASK|CHARMODE_MASK)) {
4663         if (!ip->supress_go_ahead) {
4664             ip->supress_go_ahead = MY_TRUE;
4665             send_will(option);
4666         }
4667         else DTN(("  we don't need to say WILL\n"));
4668     } else {
4669         send_wont(option);
4670     }
4671 }
4672 
4673 /*-------------------------------------------------------------------------*/
4674 static void
4675 reply_to_dont_sga (int option)
4676 
4677 /* Send IAC WONT <option> if Suppress Go Ahead is active and mark it as
4678  * inactive.
4679  */
4680 
4681 {
4682     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4683 
4684     DTN(("reply to DONT SGA\n"));
4685     if (ip->supress_go_ahead) {
4686         ip->supress_go_ahead = 0;
4687         send_wont(option);
4688     }
4689 }
4690 
4691 /*-------------------------------------------------------------------------*/
4692 static void
4693 reply_to_will_sga (int option)
4694 
4695 /* Send IAC DO <option> if CHARMODE is requested but not active yet,
4696  * send IAC DONT <option> if CHARMODE is neither requested nor active.
4697  */
4698 
4699 {
4700     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4701 
4702     DTN(("reply to WILL SGA\n"));
4703     if (ip->noecho & CHARMODE_MASK) {
4704         if ( !(ip->noecho & CHARMODE) ) {
4705             send_do(option);
4706         }
4707         else DTN(("  we don't need to say DO\n"));
4708         DTN(("  noecho: %02hhx -> %02hhx\n", ip->noecho, (char)(ip->noecho  | CHARMODE_MASK)));
4709         ip->noecho |= CHARMODE_MASK;
4710     } else {
4711         send_dont(option);
4712     }
4713 #ifdef SAVE_NOECHO
4714     if (ip->noecho & NOECHO_DELAYED)
4715     {
4716         DT(("'%s' set_noecho():   sending delayed WILL TELOPT_ECHO\n",
4717             get_txt(ip->ob->name)));
4718         ip->noecho &= ~NOECHO_DELAYED;
4719         if (!(ip->noecho & NOECHO_MASK))
4720         {
4721             send_will(TELOPT_ECHO);
4722             ip->noecho |= NOECHO_REQ | NOECHO;
4723         }
4724         else DT(("'%s'   we don't need to say WILL\n", get_txt(ip->ob->name)));
4725     }
4726 #endif /* SAVE_NOECHO */
4727 } /* reply_to_will_sga() */
4728 
4729 /*-------------------------------------------------------------------------*/
4730 static void
4731 reply_to_wont_sga (int option)
4732 
4733 /* Send IAC DONT <option> if CHARMODE was granted before.
4734  */
4735 
4736 {
4737     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4738 
4739     DTN(("reply to WONT SGA\n"));
4740     if (ip->noecho & CHARMODE_MASK) {
4741         if (!~(ip->noecho | ~CHARMODE_MASK)) {
4742             /* We were granted the option before */
4743             send_dont(option);
4744         }
4745         else DTN(("  we don't need to say DONT\n"));
4746         DTN(("  noecho: %02hhx -> %02hhx\n", ip->noecho,
4747              (unsigned char)((ip->noecho & ~CHARMODE) | CHARMODE_ACK)));
4748         ip->noecho = (char)((ip->noecho & ~CHARMODE) | CHARMODE_ACK);
4749           /* Don't reset CHARMODE_REQ here: this WONT can be the answer
4750            * to the DO SGA we sent before, and the client can still answer
4751            * with DO SGA to the WILL SGA we sent as well (Windows' telnet
4752            * for example does this).
4753            * Besides, the variables are now set up to treat the input
4754            * in charmode, and changing the flag without the variables
4755            * will do Bad Things(tm).
4756            */
4757     }
4758 } /* reply_to_wont_sga() */
4759 
4760 /*-------------------------------------------------------------------------*/
4761 static void
4762 mccp_telnet_neg (int option)
4763 {
4764     interactive_t *ip = O_GET_INTERACTIVE (command_giver);
4765 
4766      switch (ip->tn_state)
4767      {
4768      case TS_WILL:
4769          DTF(("MCCP NEG (%d) STATE (WILL)\n", option));
4770          break;
4771      case TS_WONT:
4772          DTF(("MCCP NEG (%d) STATE (WONT)\n", option));
4773          break;
4774      case TS_DO:
4775          DTF(("MCCP NEG (%d) STATE (DO)\n", option));
4776 #ifdef USE_MCCP
4777          if (!ip->compressing)
4778              start_compress(ip, option);
4779 #endif
4780          break;
4781      case TS_DONT:
4782          DTF(("MCCP NEG (%d) STATE (DONT)\n", option));
4783 #ifdef USE_MCCP
4784          if (ip->compressing==option)
4785              end_compress(ip, MY_FALSE);
4786 #endif
4787         break;
4788      default:
4789          DTF(("MCCP NEG (%d) STATE (%hhd)\n", option, ip->tn_state));
4790      }
4791 } /* mccp_telnet_neg() */
4792 
4793 /*-------------------------------------------------------------------------*/
4794 static svalue_t *
4795 h_telnet_neg (int n)
4796 
4797 /* Call the H_TELNET_NEG driverhook with <n> arguments on the interpreter
4798  * stack. Return the result from that call, or NULL if the hook isn't
4799  * set. The arguments are removed from the stack in any case.
4800  */
4801 
4802 {
4803     svalue_t *svp;
4804 
4805     RESET_LIMITS;
4806     CLEAR_EVAL_COST;
4807     if (driver_hook[H_TELNET_NEG].type == T_STRING)
4808     {
4809         svp =
4810           secure_callback(driver_hook[H_TELNET_NEG].u.str, command_giver, n);
4811     }
4812     else if (driver_hook[H_TELNET_NEG].type == T_CLOSURE)
4813     {
4814         if (driver_hook[H_TELNET_NEG].x.closure_type == CLOSURE_LAMBDA)
4815         {
4816             free_object(driver_hook[H_TELNET_NEG].u.lambda->ob, "h_telnet_neg");
4817             driver_hook[H_TELNET_NEG].u.lambda->ob = ref_object(command_giver, "h_telnet_neg");
4818         }
4819         svp = secure_callback_lambda(&driver_hook[H_TELNET_NEG], n);
4820     }
4821     else
4822     {
4823         while (--n >= 0)
4824             pop_stack();
4825         svp = NULL;
4826     }
4827     return svp;
4828 }
4829 
4830 /*-------------------------------------------------------------------------*/
4831 static void
4832 reply_h_telnet_neg (int option)
4833 
4834 /* Call the H_TELNET_NEG driver hook with <tn_state> <option> as
4835  * arguments. If the hook is not defined, send WONT <option> if
4836  * the state is TS_DO, or send DONT <option> if the state is TS_WILL.
4837  */
4838 
4839 {
4840     interactive_t *ip = O_GET_INTERACTIVE(command_giver);
4841     int i = 0;
4842 
4843     switch(ip->tn_state) {
4844       case TS_DO:
4845         DTN(("reply to telnet_neg: DO %02x\n", option));
4846         i = DO;
4847         break;
4848       case TS_DONT:
4849         DTN(("reply to telnet_neg: DONT %02x\n", option));
4850         i = DONT;
4851         break;
4852       case TS_WILL:
4853         DTN(("reply to telnet_neg: WILL %02x\n", option));
4854         i = WILL;
4855         break;
4856       case TS_WONT:
4857         DTN(("reply to telnet_neg: WONT %02x\n", option));
4858         i = WONT;
4859         break;
4860       default:
4861         debug_message("%s Invalid tn_state %hhd for interactive '%s'\n"
4862              , time_stamp(), ip->tn_state, get_txt(ip->ob->name));
4863         break;
4864     }
4865     push_number(inter_sp, i);
4866     push_number(inter_sp, option);
4867     if (!h_telnet_neg(2)) {
4868         DTN(("  using default methods\n"));
4869         switch(ip->tn_state) {
4870           case TS_DO:
4871             DTN(("    -> WONT %02x\n", option));
4872             send_wont(option);
4873             break;
4874           case TS_WILL:
4875             DTN(("    -> DONT %02x\n", option));
4876             send_dont(option);
4877             break;
4878         }
4879     }
4880 } /* reply_h_telnet_neg() */
4881 
4882 /*-------------------------------------------------------------------------*/
4883 void
4884 init_telopts (void)
4885 
4886 /* Initialise the telopts_xxx[] tables.
4887  * The default setting is such that requests are ignored or rejected.
4888  */
4889 
4890 {
4891     int i;
4892 
4893     /* Pass all telnet options that we're not
4894      * able to handle to the mudlib.
4895      */
4896     for (i = NTELOPTS; --i >= 0; ) {
4897         telopts_do[i] = reply_h_telnet_neg;
4898         telopts_dont[i] = reply_h_telnet_neg;
4899         telopts_will[i] = reply_h_telnet_neg;
4900         telopts_wont[i] = reply_h_telnet_neg;
4901     }
4902 
4903     telopts_do[TELOPT_ECHO] = reply_to_do_echo;
4904     telopts_dont[TELOPT_ECHO] = reply_to_dont_echo;
4905 
4906     /* Go Ahead does not make any sense when coupling multiple
4907      * interactive users. It is debatable if we are sending
4908      * Go Ahead every time it is appropriate (i.e. , never),
4909      * or we supress it all the time.
4910      * Unfortunately, SGA is also often associated with
4911      * character-at-a-time mode - the RFC even mandates this
4912      * double meaning - which we certainly don't want.
4913      * It might cause problems when we reject Supress Go Ahead
4914      * when some stupid client thinks that the ECHO option need
4915      * be coupled with SGA .
4916      * Thus, reject SGA in general, but not while
4917      * ip->noecho & NOECHO_MASK is true.
4918      */
4919     telopts_do[TELOPT_SGA] = reply_to_do_sga;
4920     telopts_dont[TELOPT_SGA] = reply_to_dont_sga;
4921     telopts_will[TELOPT_SGA] = reply_to_will_sga;
4922     telopts_wont[TELOPT_SGA] = reply_to_wont_sga;
4923 
4924     /* Mud specific protocols */
4925     telopts_do[TELOPT_COMPRESS] = mccp_telnet_neg;
4926     telopts_dont[TELOPT_COMPRESS] = mccp_telnet_neg;
4927     telopts_will[TELOPT_COMPRESS] = mccp_telnet_neg;
4928     telopts_wont[TELOPT_COMPRESS] = mccp_telnet_neg;
4929 
4930     telopts_do[TELOPT_COMPRESS2] = mccp_telnet_neg;
4931     telopts_dont[TELOPT_COMPRESS2] = mccp_telnet_neg;
4932     telopts_will[TELOPT_COMPRESS2] = mccp_telnet_neg;
4933     telopts_wont[TELOPT_COMPRESS2] = mccp_telnet_neg;
4934 } /* init_telopts() */
4935 
4936 /*-------------------------------------------------------------------------*/
4937 void
4938 mudlib_telopts (void)
4939 
4940 /* Set all telopts_xxx[] entries to reply_h_telnet_neg().
4941  * This means that the mudlib does all the telnet negotiation.
4942  * It is called whenever driver hook H_NOECHO is set.
4943  */
4944 
4945 {
4946     int i;
4947 
4948     DT(("All telnet options set to the mudlib.\n"));
4949     for (i = NTELOPTS; --i >= 0; ) {
4950         telopts_do[i] = telopts_dont[i] =
4951           telopts_will[i] = telopts_wont[i] = reply_h_telnet_neg;
4952     }
4953 } /* mudlib_telopts() */
4954 
4955 /*-------------------------------------------------------------------------*/
4956 static INLINE Bool
4957 is_charmode (interactive_t * ip)
4958 
4959 /* Return TRUE if <ip> has charmode enabled, and FALSE if not.
4960  */
4961 
4962 {
4963     return (ip->noecho & CHARMODE_REQ)
4964             && (   ip->text[0] != input_escape
4965                 || find_no_bang(ip) & IGNORE_BANG
4966                )
4967 
4968     ;
4969 } /* is_charmode() */
4970 
4971 /*-------------------------------------------------------------------------*/
4972 static void
4973 telnet_neg (interactive_t *ip)
4974 
4975 /* Process the data read from the socket, performing any telnet negotiations
4976  * necessary, and extract the 'pure' command text. When the function returns,
4977  * all new data in .text[] has been used and .text_end set back as far
4978  * as possible.
4979  *
4980  * The start state for the telnet machine is TS_DATA, and whenever a command
4981  * text has been completed, it assumes the TS_READY state.
4982  *
4983  * The function tn_end and goes on until it reaches text_end or a full newline.
4984  *
4985  * When it returns:
4986  *   tn_end is set to the first unprocessed character.
4987  * When a full newline is found:
4988  *   Processed commands start at command_start and are \0 terminated strings
4989  *    state is set to READY
4990  * else
4991  *   Processed commands start at command_start and end at command_end-1
4992  *   state is set to DATA (or something else if we got a fragmented
4993  *     telnet negotiation).
4994  *
4995  * text_end could move a bit to the start of text if we deleted chars
4996  * from the raw input string (e.g. because it was an IAC).
4997  *
4998  * If gobble_char is set, that char is removed from a fresh text packet.
4999  * Removing of unwanted chars inside of a packet is done at the appropriate
5000  * place (case '\r':). There is no gobbling of <LN><CR> sequences in
5001  * character mode (why not?). Code would have to be added at case '\n':
5002  * to gobble them in-packet.
5003  *
5004  * Example:
5005  * text = "say hello\r\nsay hi\r\n";
5006  *
5007  * Output would be:
5008  * text = "say hello\0\nsay hi\r\n";
5009  *
5010  * command_start = 0
5011  * command_end = 0
5012  * tn_end = 11 (s of 2nd say)
5013  * text_end stays at 19 (first unused char in text)
5014  * state = TS_READY
5015  *
5016  * After a second call of telnet_neg (almost always done by get_message())
5017  * will pre process the second command:
5018  *
5019  * text = "say hi\0lo\0\nsay hi\r\n";
5020  *
5021  * command_start = 0
5022  * command_end = 0
5023  * tn_end = 7
5024  * text_end = 7
5025  * state = READY
5026  */
5027 
5028 {
5029     fd_set exceptfds;
5030     char *from;   /* Next char to process */
5031     char *to;     /* Where to store the extracted command text */
5032     int   state;
5033     int   ch;     /* Current character */
5034     char *first;  /* Begin of the last pure command text */
5035     char *end;    /* End of data in text[] */
5036 
5037     first = ip->text;
5038     from = &first[ip->tn_end];
5039     end = &first[ip->text_end];
5040 
5041     DTN(("telnet_neg: state %hhd\n", ip->tn_state));
5042 
5043     /* Gobble the character *from if gobble_char is set.
5044      * Also test for the end of current buffer content.
5045      *
5046      * If we want to gobble NL, we also gobble NUL
5047      * (used for CR NL and CR NUL digraphs)
5048      */
5049     for (;;)
5050     {
5051         if (from >= end) {
5052 #if 0 /* cannot happen with the current calling pattern */
5053             if (ip->state == TS_READY) return;
5054 #endif
5055             ip->text_end = ip->tn_end = ip->command_end;
5056             return;
5057         }
5058         if (ip->gobble_char) {
5059             DTN(("t_n: gobble char %02hhx (in buf: %02x)\n"
5060                , ip->gobble_char, *from));
5061             if (*from == ip->gobble_char
5062                 || (*from == '\0' && ip->gobble_char == '\n')
5063                )
5064             {
5065                 from++;
5066             }
5067             ip->gobble_char = '\0';
5068             continue;
5069         }
5070         break;
5071     }
5072     to = &first[ip->command_end];
5073 
5074     /* The processing loop */
5075 
5076     do {
5077         ch = (*from++ & 0xff);
5078         DTN(("t_n: processing %02hhx '%c'\n"
5079             , (unsigned char)ch, ch));
5080         switch(ip->tn_state)
5081         {
5082         case TS_READY:
5083             DTN(("t_n: still in TS_READY - return\n"));
5084             /* Previous command hasn't been read yet - don't clobber it! */
5085             return;
5086 
5087         ts_data:
5088             /* Most state functions end with a jump here to check if they
5089              * exhausted their input.
5090              */
5091             if (from >= end)
5092             {
5093                 ip->text_end = ip->tn_end = ip->command_end = (short)(to - first);
5094                  DTN(("t_n: (ts_data) from >= end by %td, text_end := %hd\n (max %d)"
5095                      , (ptrdiff_t)(from-end), ip->text_end, MAX_TEXT));
5096                 *to = '\0';
5097                 if (ip->text_end >= MAX_TEXT)
5098                 {
5099                     /* this looks like a super-long command.
5100                      * Return the text so far as partial command and restart
5101                      * input from the beginning.
5102                      * In charmode, we must not reset command_end, otherwise
5103                      * it might fall under command_start.
5104                      */
5105                     ip->tn_state = TS_READY;
5106                     ip->tn_end = 0;
5107                     ip->text_end = 0;
5108                     if (!(ip->noecho & (CHARMODE_REQ|CHARMODE)))
5109                     {
5110                         ip->command_end = 0;
5111                     }
5112                     return;
5113                 }
5114                 return;
5115             }
5116             ch = (*from++ & 0xff);
5117             DTN(("t_n: (ts_data) processing %02hhx '%c'\n"
5118                 , (unsigned char)ch, ch));
5119             /* FALLTHROUGH */
5120 
5121         case TS_DATA: /* --- Copy/interpret plain data --- */
5122             switch(ch)
5123             {
5124             case IAC:
5125             new_iac:
5126                   if (ip->tn_enabled)
5127                   {
5128                       state = TS_IAC;
5129         change_state:
5130                       DTN(("t_n: new state %d\n", state));
5131                       ip->tn_state = (char)state;
5132                       continue;
5133                   }
5134                   /* FALLTHROUGH if !tn_enabled */
5135 
5136             case '\b':        /* Backspace */
5137             case 0x7f:        /* Delete */
5138                 /* In Linemode, just move to one char back.
5139                  * In Charmode with escaped input, write the data gathered
5140                  * so far and add a rubout sequence ('\b \b').
5141                  * In Charmode with unescaped input, just pass it on to
5142                  * the mudlib.
5143                  *
5144                  * If telnet is disabled, fallthrough to the general
5145                  * data handling.
5146                  */
5147                 if (ip->tn_enabled)
5148                 {
5149                     if ( !(ip->noecho & CHARMODE_REQ) )
5150                     {
5151                         if (to > first)
5152                             to--;
5153                         goto ts_data;
5154                     }
5155 
5156                     if (ip->text[0] == input_escape
5157                      && ! (find_no_bang(ip) & IGNORE_BANG) )
5158                     {
5159                         if (to > &ip->text[ip->chars_ready])
5160                         {
5161                             comm_socket_write(&ip->text[ip->chars_ready]
5162                                             , (size_t)(to - &ip->text[ip->chars_ready])
5163                                             , ip, 0);
5164                             ip->chars_ready = to - ip->text;
5165                         }
5166                         if (to > first)
5167                         {
5168                             comm_socket_write("\b \b", 3, ip, 0);
5169                             to--;
5170                             ip->chars_ready--;
5171                         }
5172                         goto ts_data;
5173                     }
5174                 } /* if (ip->tn_enabled) */
5175                 /* FALLTHROUGH */
5176 
5177             default:
5178                 *to++ = (char)ch;
5179                 /* FALLTHROUGH */
5180 
5181             case '\0':
5182                 /* In Charmode, we should return the \0 (as with CR and LF),
5183                  * but for the caller the \0 has magical properties.
5184                  */
5185                 goto ts_data;
5186 
5187             case '\r':
5188                 /* In Charmode we have to return the \r.
5189                  */
5190                 if (is_charmode(ip))
5191                 {
5192                     *to++ = (char)ch;
5193                     goto ts_data;
5194                 }
5195 
5196                 if (from >= end)
5197                 {
5198                     /* This might be a fragmented CR NL, CR NUL, or
5199                      * a broken client that ends lines with CR only.
5200                      * We proceed as full newline now, but gobble
5201                      * NL or NUL if they are sent afterwards.
5202                      */
5203                     ip->gobble_char = '\n';
5204                 }
5205                 else
5206                 {
5207                     ch = (*from++ & 0xff);
5208                     /* gobble following NL and NUL */
5209                     if (ch && ch != '\n')
5210                         from--;
5211                 }
5212 
5213         full_newline:
5214                 /* Proper line end found: set telnet machine into TS_READY,
5215                  * terminate the command with \0 and return.
5216                  */
5217                 {
5218                     ip->tn_state = TS_READY;
5219                     ip->command_end = 0;
5220                     ip->tn_end = (short)(from - first);
5221 
5222                     /* Even in charmode we append the NUL in case the client
5223                      * refused to use charmode, because then get_message()
5224                      * will treat the data as if in linemode and expect
5225                      * a trailing NUL.
5226                      */
5227                     *to = '\0';
5228                     return;
5229                 }
5230 
5231             case '\n':
5232                 /* In Charmode we have to return the \n.
5233                  */
5234                 if (is_charmode(ip))
5235                 {
5236                     *to++ = (char)ch;
5237                     goto ts_data;
5238                 }
5239 
5240                 ip->gobble_char = '\r';
5241                 goto full_newline;
5242             } /* switch(ch) */
5243 
5244             /* NOTREACHED */
5245 
5246         ts_iac:
5247         case TS_IAC:
5248             DTN(("t_n: state IAC\n"));
5249             /* Begin a telnet negotiation */
5250             switch(ch)
5251             {
5252             case IAC:
5253                 DTN(("t_n: got IAC\n"));
5254                 *to++ = ch;
5255                 ip->tn_state = state = TS_DATA;
5256                 goto ts_data;
5257             case WILL:
5258                 DTN(("t_n: got WILL\n"));
5259                 state = TS_WILL;
5260                 goto change_state;
5261             case WONT:
5262                 DTN(("t_n: got WONT\n"));
5263                 state = TS_WONT;
5264                 goto change_state;
5265             case DO:
5266                 DTN(("t_n: got DO\n"));
5267                 state = TS_DO;
5268                 goto change_state;
5269             case DONT:
5270                 DTN(("t_n: got DONT\n"));
5271                 state = TS_DONT;
5272                 goto change_state;
5273             case SB:
5274                 DTN(("t_n: got SB\n"));
5275                 ip->tn_start = (short)(to - first);
5276                 state = TS_SB;
5277                 goto change_state;
5278             case DM:
5279                 DTN(("t_n: got DM\n"));
5280             data_mark:
5281                 if (ip->ts_data == TS_SYNCH)
5282                 {
5283                     struct timeval timeout;
5284 
5285                     FD_ZERO(&exceptfds);
5286                     FD_SET(ip->socket, &exceptfds);
5287                     timeout.tv_sec = 0;
5288                     timeout.tv_usec = 0;
5289                     if (! socket_select(ip->socket + 1, 0, 0, &exceptfds,
5290                         &timeout))
5291                     {
5292                         if (d_flag)
5293                             debug_message("%s Synch operation finished.\n"
5294                                          , time_stamp());
5295                         ip->ts_data = TS_DATA;
5296                     }
5297                 }
5298                 break;
5299             case NOP:
5300                 DTN(("t_n: got NOP\n")); break;
5301             case GA:
5302                 DTN(("t_n: got GA\n")); break;
5303             default:
5304                 DTN(("t_n: got %02hhx\n", ch)); break;
5305                 break;
5306             } /* switch(ch) */
5307             state = ip->ts_data;
5308             goto change_state;
5309 
5310         case TS_WILL:
5311             command_giver = ip->ob;
5312             if (ch < NTELOPTS) {
5313                 DTN(("t_n: state WILL got %s (%02hhx)\n"
5314                    , telopts[ch], ch));
5315                 if (d_flag)
5316                     debug_message("%s Will %s\n", time_stamp(), telopts[ch]);
5317                 (*telopts_will[ch])(ch);
5318             } else {
5319                 debug_message("%s Unknown telnet option Will %hhd\n"
5320                              , time_stamp(), ch);
5321                 send_dont(ch);
5322             }
5323             state = ip->ts_data;
5324             goto change_state;
5325 
5326         case TS_WONT:
5327             command_giver = ip->ob;
5328             if (ch < NTELOPTS) {
5329                 DTN(("t_n: state WONT got %s (%02hhx)\n"
5330                    , telopts[ch], ch));
5331                 if (d_flag)
5332                     debug_message("%s Wont %s\n", time_stamp(), telopts[ch]);
5333                 (*telopts_wont[ch])(ch);
5334             } else {
5335                 debug_message("%s Unknown telnet option Wont %hhd\n"
5336                              , time_stamp(), ch);
5337             }
5338             state = ip->ts_data;
5339             goto change_state;
5340 
5341         case TS_DO:
5342             command_giver = ip->ob;
5343             if (ch < NTELOPTS) {
5344                 DTN(("t_n: state DO got %s (%02hhx)\n"
5345                    , telopts[ch], ch));
5346                 if (d_flag)
5347                     debug_message("%s Do %s\n", time_stamp(), telopts[ch]);
5348                 (*telopts_do[ch])(ch);
5349             } else {
5350                 debug_message("%s Unknown telnet option Do %hhd\n"
5351                              , time_stamp(), ch);
5352                 send_wont(ch);
5353             }
5354             state = ip->ts_data;
5355             goto change_state;
5356 
5357         case TS_DONT:
5358             command_giver = ip->ob;
5359             if (ch < NTELOPTS) {
5360                 DTN(("t_n: state DONT got %s (%02hhx)\n"
5361                    , telopts[ch], ch));
5362                 if (d_flag)
5363                     debug_message("%s Dont %s\n", time_stamp(), telopts[ch]);
5364                 (*telopts_dont[ch])(ch);
5365             } else {
5366                 debug_message("%s Unknown telnet option Dont %hhd\n"
5367                              , time_stamp(), ch);
5368             }
5369             state = ip->ts_data;
5370             goto change_state;
5371 
5372         case TS_SB:
5373             DTN(("t_n: state TS_SB got %02hhx\n", ch));
5374             if (ch == IAC) {
5375                 state = TS_SB_IAC;
5376                 goto change_state;
5377             }
5378             *to++ = (char)ch;
5379             continue;
5380 
5381         case TS_SB_IAC:
5382           {
5383             mp_int size;
5384             vector_t *v;
5385 
5386             DTN(("t_n: state TS_SB_IAC got %02hhx\n", ch));
5387             if (ch == IAC) {
5388                 DTN(("t_n: that is: state TS_SB_IAC got IAC\n"));
5389                 *to++ = (char)ch;
5390                 state = TS_SB;
5391                 goto change_state;
5392             } else if ((ch == SE || ch == SB)
5393                 && (  (size = (to - first) - ip->tn_start - 1) <= (mp_int)max_array_size
5394                     || !max_array_size)
5395                 && size >= 0
5396                 && (current_object = ip->ob,  v = allocate_array(size)) )
5397             {
5398                 unsigned char *str;
5399                 svalue_t *svp;
5400 
5401                 str = (unsigned char *)&ip->text[ip->tn_start];
5402                 DTN(("t_n: that is: state TS_SB_IAC got useful SE or SB: neg SB %02hhx (%"PRIdMPINT" bytes)\n", *str, size));
5403                 push_number(inter_sp, SB);
5404                 push_number(inter_sp, *str++);
5405                 svp = v->item;
5406                 while (--size >= 0) {
5407                     svp->u.number = *str++;
5408                     svp++;
5409                 }
5410                 push_array(inter_sp, v);
5411                 command_giver = ip->ob;
5412                 h_telnet_neg(3);
5413             }
5414             to = &first[ip->tn_start];
5415             if (ch != SE)
5416                 goto ts_iac;
5417             state = ip->ts_data;
5418             goto change_state;
5419           }
5420 
5421         case TS_SYNCH:
5422             DTN(("t_n: state TS_SYNCH got %02hhx\n", ch));
5423             if (ch == IAC) goto new_iac;
5424             if (ch == DM) goto data_mark;
5425             continue;
5426 
5427         default:
5428             if (d_flag)
5429                 debug_message("%s Bad state: 0x%hhx\n", time_stamp(), ip->tn_state);
5430             state = TS_DATA;
5431             goto change_state;
5432         } /* switch (ip->tn_state) */
5433 
5434     } while(from < end);
5435 
5436     /* We used all the new data in .text[] but found no complete command.
5437      * Reset all pointers necessary to read new data.
5438      */
5439 
5440     ip->text_end = ip->tn_end = ip->command_end = (short)(to - first);
5441     if (ip->text_end == MAX_TEXT)
5442     {
5443         /* telnet negotiation shouldn't have such large data chunks.
5444          * Ignore all data altogether and return to text mode.
5445          */
5446         ip->text_end = ip->tn_end = ip->command_end = 0;
5447         ip->tn_start = ip->command_start = 0;
5448         ip->tn_state = TS_DATA;
5449     }
5450 } /* telnet_neg() */
5451 
5452 /* End of Telnet support */
5453 /*=========================================================================*/
5454 /*                      ERQ Support
5455  */
5456 
5457 #ifdef ERQ_DEMON
5458 /*-------------------------------------------------------------------------*/
5459 void
5460 start_erq_demon (const char *suffix, size_t suffixlen)
5461 
5462 /* Start the ERQ demon from the path 'ERQFILE<suffix>' and setup
5463  * the pending_erq[] array.
5464  */
5465 
5466 {
5467     erq_callback_t *erqp;
5468     char path[MAXPATHLEN+1];
5469     int sockets[2];
5470     int pid, i;
5471     char c;
5472 
5473     /* Create the freelist in pending_erq[] */
5474     pending_erq[0].fun.type = T_INVALID;
5475     pending_erq[0].fun.u.generic = NULL;
5476 
5477     erqp = pending_erq + 1;
5478     while (erqp < &pending_erq[MAX_PENDING_ERQ])
5479     {
5480         erqp->fun.u.generic = (void *)(erqp - 1);
5481         erqp->fun.type = T_INVALID;
5482         erqp++;
5483     }
5484     free_erq = &pending_erq[MAX_PENDING_ERQ-1];
5485 
5486     /* Create the sockets to talk to the ERQ */
5487 /* TODO: Add tests to configure if the system really implements AF_UNIX or socketpair() */
5488     if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0)
5489     {
5490         perror("socketpair");
5491         return;
5492     }
5493 
5494     (void)signal(SIGCLD, SIG_IGN); /* don't create zombie processes */
5495 
5496     printf("%s Attempting to start erq '%s%s'.\n"
5497           , time_stamp(), erq_file, suffix);
5498     debug_message("%s Attempting to start erq '%s%s'.\n"
5499                  , time_stamp(), erq_file, suffix);
5500 
5501     /* Close inherited sockets first. */
5502     for (i = 0; i < numports; i++)
5503         if (port_numbers[i] < 0)
5504             set_close_on_exec(-port_numbers[i]);
5505 
5506     if ((pid = fork()) == 0)
5507     {
5508         /* Child */
5509         dup2(sockets[0], 0);
5510         dup2(sockets[0], 1);
5511         close(sockets[0]);
5512         close(sockets[1]);
5513 
5514         if (strlen(erq_file) + 1 + suffixlen <= sizeof path)
5515         {
5516             sprintf(path, "%s%.*s", erq_file, (int)suffixlen, suffix);
5517             if (erq_args)
5518                 execv((char *)path, erq_args);
5519             else
5520                 execl((char *)path, "erq", "--forked", (char*)0);
5521         }
5522         write(1, "0", 1);  /* indicate failure back to the driver */
5523         _exit(1);
5524     }
5525 
5526     close(sockets[0]);
5527     if (pid == -1) {
5528         close(sockets[1]);
5529         return;
5530     }
5531 
5532     /* Read the first character from the ERQ. If it's '0', the ERQ
5533      * didn't start.
5534      */
5535     read(sockets[1], &c, 1);
5536     if (c == '0') {
5537         close(sockets[1]);
5538 
5539         printf("%s Failed to start erq.\n", time_stamp());
5540         debug_message("%s Failed to start erq.\n", time_stamp());
5541         return;
5542     }
5543 
5544     /* ERQ is up and running */
5545     erq_demon = sockets[1];
5546     set_socket_nonblocking(erq_demon);
5547     if (socket_number(erq_demon) >= min_nfds)
5548         min_nfds = socket_number(erq_demon)+1;
5549 } /* start_erq_demon() */
5550 
5551 /*-------------------------------------------------------------------------*/
5552 static void
5553 shutdown_erq_demon (void)
5554 
5555 /* Close the connection to the ERQ.
5556  * This method is to be used directly only on game shutdown, otherwise
5557  * use stop_erq_demon() instead.
5558  */
5559 
5560 {
5561     if (erq_demon < 0)
5562         return;
5563 
5564     socket_close(erq_demon);
5565     erq_demon = FLAG_NO_ERQ;
5566     erq_pending_len = 0;
5567     input_from_erq = &buf_from_erq[0];
5568 } /* shutdown_erq_demon() */
5569 
5570 /*-------------------------------------------------------------------------*/
5571 static void
5572 stop_erq_demon (Bool notify)
5573 
5574 /* Close the connection to the ERQ and inform all pending requests
5575  * about this. If <notify> is set, the hook H_ERQ_STOP is called.
5576  */
5577 
5578 {
5579     erq_callback_t *erqp;
5580     int i;
5581 
5582     if (erq_demon < 0)
5583         return;
5584 
5585     shutdown_erq_demon();
5586 
5587     /* Inform all pending requests about the loss.
5588      */
5589     erqp = pending_erq;
5590     i = MAX_PENDING_ERQ;
5591     do {
5592         if (erqp->fun.type == T_CLOSURE)
5593         {
5594             *++inter_sp = erqp->fun;
5595             erqp->fun.type = T_INVALID;
5596             erqp->fun.u.generic = (void *)free_erq;
5597             free_erq = erqp;
5598             CLEAR_EVAL_COST;
5599             RESET_LIMITS;
5600             callback_master(STR_STALE_ERQ, 1);
5601         }
5602         erqp++;
5603     } while (--i);
5604 
5605     /* If desired, call H_ERQ_STOP to notify the situation.
5606      */
5607     if (notify)
5608     {
5609         RESET_LIMITS;
5610         CLEAR_EVAL_COST;
5611         if (driver_hook[H_ERQ_STOP].type == T_CLOSURE) {
5612             secure_callback_lambda(&driver_hook[H_ERQ_STOP], 0);
5613         }
5614     }
5615 } /* stop_erq_demon() */
5616 
5617 /*-------------------------------------------------------------------------*/
5618 svalue_t *
5619 f_attach_erq_demon (svalue_t *sp)
5620 
5621 /* EFUN: attach_erq_demon()
5622  *
5623  *   int attach_erq_demon(object ob, int do_close)
5624  *   int attach_erq_demon(string name, int do_close)
5625  *
5626  * In the first form, take away the connection from <ob> and store it as
5627  * _the_ erq connection. <ob> thus becomes a normal non-interactive object.
5628  * In the second form, try to start the ERQ demon from the path
5629  * 'ERQFILE<name>' (ERQFILE defaults to BINDIR/erq). <name> must not
5630  * contain '/..' sequences.
5631  *
5632  * If there is already an ERQ demon connected to the driver, the function
5633  * will fail unless <do_close> is set to 1 or any other odd integer; in
5634  * this case the connection to the old ERQ will be closed first.
5635  *
5636  * Return svalue.number 1 on success, 0 else.
5637  */
5638 
5639 {
5640     object_t *ob;
5641     interactive_t *ip;
5642     string_t *suffix;
5643 
5644     /* Test for the first form: (object ob, int do_close) */
5645     if (sp[-1].type == T_OBJECT)
5646     {
5647         ob = sp[-1].u.ob;
5648         if (!O_SET_INTERACTIVE(ip, ob))
5649         {
5650             errorf("Bad arg 1 to attach_erq_demon(): object is not interactive.\n");
5651             /* NOTREACHED */
5652             return sp;
5653         }
5654 
5655         sp--;
5656         deref_object(ob, "attach_erq_demon");
5657         put_number(sp, 0);
5658         /* we need to read sp[1] below, thus don't overwrite it now. */
5659         if (privilege_violation4(STR_ATTACH_ERQ_DEMON,
5660             ob, 0, sp[1].u.number, sp+1))
5661         {
5662             if (erq_demon != FLAG_NO_ERQ) {
5663                 if (sp[1].u.number & 1) {
5664                     stop_erq_demon(0);
5665                     erq_demon = FLAG_ERQ_STOP;
5666                 } else {
5667                     return sp;
5668                 }
5669             }
5670             erq_proto_demon = ip->socket;
5671             ip->do_close = FLAG_PROTO_ERQ;
5672             sp->u.number = 1;
5673         }
5674         return sp;
5675     }
5676 
5677     /* Otherwise the argument is a string */
5678 
5679     suffix = sp[-1].u.str;
5680     if (mstrstr(suffix, "/.."))
5681     {
5682         errorf("Bad arg 1 to attach_erq_demon(): illegal path.\n");
5683         /* NOTREACHED */
5684         return sp;
5685     }
5686 
5687     {
5688         int n;
5689 
5690         sp--;
5691         n = 0;
5692         if (privilege_violation4(STR_ATTACH_ERQ_DEMON,
5693             0, suffix, sp[1].u.number, sp+1))
5694         {
5695             if (erq_demon != FLAG_NO_ERQ)
5696             {
5697                 if (sp[1].u.number & 1) {
5698                     stop_erq_demon(0);
5699                 } else {
5700                     goto return_result;
5701                 }
5702                 erq_proto_demon = -1;
5703             }
5704             start_erq_demon(get_txt(suffix), mstrsize(suffix));
5705             n = 1;
5706         }
5707 return_result:
5708         free_svalue(sp);
5709         put_number(sp, n);
5710         return sp;
5711     }
5712 
5713     /* NOTREACHED */
5714     return NULL;
5715 } /* f_attach_erq_demon() */
5716 
5717 /*-------------------------------------------------------------------------*/
5718 static Bool
5719 send_erq (int handle, int request, const char *arg, size_t arglen)
5720 
5721 /* Send compose an ERQ message out of <handle>, <request> and <arg>
5722  * and send it to the ERQ. If all the data can't be sent now, the
5723  * next call to send_erq() will send the rest.
5724  *
5725  * Return FALSE if the data couldn't be sent, TRUE on success.
5726  *
5727  * SOCK_SEQPACKET is not portable enough, thus make special provisions
5728  * to deliver messages in an atomic fashion.
5729  */
5730 
5731 {
5732     static char buf[ERQ_MAX_SEND], *pending;
5733     long wrote;
5734 
5735     if (erq_demon < 0)
5736         return MY_FALSE;
5737 
5738     /* Try to send the pending data */
5739     if (erq_pending_len)
5740     {
5741         wrote = socket_write(erq_demon, pending, erq_pending_len);
5742         if (wrote > 0) {
5743             pending += wrote;
5744             erq_pending_len -= wrote;
5745         }
5746         if (erq_pending_len)
5747             return MY_FALSE;
5748     }
5749 
5750     if (arglen + 9 > sizeof buf)
5751         return MY_FALSE;
5752 
5753     /* Create the message and add it to buf[] */
5754     erq_pending_len = arglen + 9;
5755     *(uint32*)buf = htonl(erq_pending_len);
5756     *(uint32*)(buf+4) = htonl(handle);
5757     buf[8] = (char)request;
5758     memcpy(buf + 9, arg, arglen);
5759 
5760     /* Send as much of buf[] as possible */
5761     pending = buf;
5762     wrote = socket_write(erq_demon, buf, erq_pending_len);
5763     if (wrote > 0) {
5764         pending += wrote;
5765         erq_pending_len -= wrote;
5766     }
5767 
5768     return MY_TRUE;
5769 } /* send_erq() */
5770 
5771 /*-------------------------------------------------------------------------*/
5772 svalue_t *
5773 f_send_erq (svalue_t *sp)
5774 
5775 /* EFUN: send_erq()
5776  *
5777  *   int send_erq(int request, string|int* data, closure callback)
5778  *
5779  * Send a request of type <request> and the data <data> to the ERQ>
5780  * If <callback> is set to a closure, it will be called with the
5781  * response from the ERQ.
5782  *
5783  * The function returns svalue.number 1 on success, and 0 on failure.
5784  *
5785  * The function causes a privilege violation "erq".
5786  */
5787 
5788 {
5789     char  *arg;
5790     size_t arglen;
5791     erq_callback_t *new_erq;
5792     int i;
5793     p_int erq_request;
5794 
5795     /* Set arg with the data to send. */
5796 
5797     if (sp[-1].type == T_STRING) {
5798         arg = get_txt(sp[-1].u.str);
5799         arglen = mstrsize(sp[-1].u.str);
5800     }
5801     else /* it's a pointer */
5802     {
5803         vector_t *v;
5804         svalue_t *svp;
5805         char *cp;
5806         p_int j;
5807 
5808         v = sp[-1].u.vec;
5809         arglen = VEC_SIZE(v);
5810         cp = arg = xalloc(arglen);
5811         if (!arg) {
5812             errorf("Out of memory (%zu bytes) in send_erq() for allocating "
5813                    "temporary buffer.\n", arglen);
5814         }
5815         svp = &v->item[0];
5816         for (j = (p_int)arglen; --j >= 0; )
5817             *cp++ = (char)(*svp++).u.number;
5818     }
5819 
5820     erq_request = sp[-2].u.number;
5821 
5822     /* Test if this call is allowed. */
5823 
5824     if (!privilege_violation4(STR_SEND_ERQ, 0, STR_EMPTY
5825                              , erq_request & (~ERQ_CB_STRING)
5826                              , sp))
5827     {
5828         goto failure;
5829     }
5830 
5831     /* Store the callback closure. If none is given, use the
5832      * default callback.
5833      */
5834 
5835     new_erq = NULL;
5836 
5837     if (sp->type == T_NUMBER) { /* it's the number 0 */
5838         new_erq = &pending_erq[MAX_PENDING_ERQ];
5839         new_erq->fun.u.generic = (void *)free_erq;
5840     }
5841     else if (sp->type == T_CLOSURE
5842           && sp->x.closure_type != CLOSURE_UNBOUND_LAMBDA)
5843     {
5844         new_erq = free_erq;
5845     }
5846 
5847     /* Send the request and make up the result. */
5848 
5849     if (new_erq
5850      && 0 != (i = send_erq(new_erq - pending_erq, erq_request & (~ERQ_CB_STRING)
5851                           , arg, arglen))
5852        )
5853     {
5854         free_erq = (erq_callback_t *)new_erq->fun.u.generic;
5855         new_erq->fun = *sp;
5856         new_erq->string_arg = (erq_request & ERQ_CB_STRING) != 0;
5857     }
5858     else
5859     {
5860 failure:
5861         i = 0;
5862         free_svalue(sp);
5863     }
5864     /* cleanup */
5865     if (sp[-1].type != T_STRING) {
5866         /* free arg only if sp-1 is not a string */
5867         xfree(arg);
5868     }
5869     free_svalue(--sp);
5870     (*--sp).u.number = i;
5871 
5872     return sp;
5873 } /* f_send_erq() */
5874 
5875 /*-------------------------------------------------------------------------*/
5876 static long
5877 read_32 (char *str)
5878 
5879 /* Read a 32 bit value from a possibly unaligned network byte order
5880  * representation.
5881  */
5882 
5883 {
5884     unsigned char *p = (unsigned char *)str;
5885 
5886     return (long)p[0]<<24 | (long)p[1]<<16 | (long)p[2]<<8 | p[3];
5887 }
5888 
5889 /*-------------------------------------------------------------------------*/
5890 static void
5891 add_ip_entry (struct in_addr addr, const char *name)
5892 
5893 /* Add a new IP address <addr>/hostname <name> pair to the cache iptable[].
5894  * If the <addr> already exists in the table, replace the old tabled name
5895  * with the new one.
5896  */
5897 
5898 {
5899     int i, ix;
5900     Bool new_entry;
5901 
5902     ix = -1;
5903     new_entry = MY_FALSE;
5904     for (i = 0; i < IPSIZE; i++)
5905     {
5906         if (!memcmp(&(iptable[i].addr.s_addr), &addr.s_addr, sizeof(iptable[i].addr.s_addr)))
5907         {
5908             ix = i;
5909             break;
5910         }
5911     }
5912 
5913     if (ix < 0)
5914     {
5915         ix = ipcur;
5916         new_entry = MY_TRUE;
5917     }
5918 
5919     iptable[ix].addr = addr;
5920     if (iptable[ix].name)
5921         free_mstring(iptable[ix].name);
5922     iptable[ix].name = new_tabled(name);
5923 
5924     if (new_entry)
5925         ipcur = (ipcur+1) % IPSIZE;
5926 } /* add_ip_entry() */
5927 
5928 /*-------------------------------------------------------------------------*/
5929 #ifdef USE_IPV6
5930 
5931 static void
5932 update_ip_entry (const char *oldname, const char *newname)
5933 
5934 /* Change the IP name <oldname> in the iptable[] to <newname>.
5935  * If the <oldname> is not in the table, nothing happens.
5936  */
5937 
5938 {
5939     int i, ix;
5940     Bool new_entry;
5941 
5942     ix = -1;
5943     new_entry = MY_FALSE;
5944     for (i = 0; i < IPSIZE; i++)
5945     {
5946         if (iptable[i].name
5947          && !strncmp(get_txt(iptable[i].name), oldname, mstrsize(iptable[i].name))
5948            )
5949         {
5950             free_mstring(iptable[i].name);
5951             iptable[i].name = new_tabled(newname);
5952         }
5953     }
5954 } /* update_ip_entry() */
5955 
5956 /*-------------------------------------------------------------------------*/
5957 static int
5958 open_ipv6_conn( const char *hostname, const unsigned short int port
5959               , struct sockaddr_in * pTarget)
5960 
5961 /* Create a non-blocking IPv6/IPv4 tcp connnection to the given
5962  * <hostname>:<port>. The <hostname> is first interpreted as IPv6
5963  * address, and if that fails, as IPv4 address.
5964  *
5965  * Result is the socket (with the connnection possibly still in process
5966  * of being opened), or -1 on a failure.
5967  *
5968  * The completed sockaddr_in is passed back in *<pTarget> as well.
5969  *
5970  * WARNING: Not threadsafe!
5971  */
5972 
5973 {
5974     int sock;
5975     int con = 0;
5976     int fd_flags;
5977 
5978     struct hostent *h;
5979     struct protoent *p;
5980     struct sockaddr_in6 addr;
5981 
5982     p = getprotobyname("TCP");
5983     if(!p) return -1;
5984 
5985     sock = socket(AF_INET6, SOCK_STREAM, p->p_proto);
5986     if(sock == -1)
5987     {
5988         perror("socket");
5989         return -1;
5990     }
5991     endprotoent();
5992 
5993     fd_flags = fcntl(sock, F_GETFL, 0);
5994 #if defined(O_NONBLOCK)
5995     fd_flags |= O_NONBLOCK;
5996 #elif defined(O_NDELAY)
5997     fd_flags |= O_NDELAY;
5998 #elif defined(FNDELAY)
5999     fd_flags |= O_FNDELAY;
6000 #endif
6001     if (fcntl(sock, F_SETFL, fd_flags) == -1)
6002     {
6003         perror("setsockopt/fcntl");
6004         close(sock);
6005         return -1;
6006     }
6007     addr.sin6_port=htons(port);
6008     addr.sin6_family=AF_INET6;
6009     addr.sin6_flowinfo=0;
6010     addr.sin6_scope_id=IPV6_ADDR_SCOPE_GLOBAL;
6011 
6012     h = gethostbyname2(hostname, AF_INET6);
6013     if(h)
6014     {
6015         memcpy(&addr.sin6_addr, h->h_addr, h->h_length);
6016         con = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
6017         perror("con");
6018     }
6019     else if(!h || (con && con != EINPROGRESS))
6020     {
6021         h = gethostbyname2(hostname, AF_INET);
6022         if(h)
6023         {
6024             CREATE_IPV6_MAPPED(&addr.sin6_addr, *((u_int32_t *)h->h_addr_list[0]));
6025             con = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
6026         }
6027     }
6028     endhostent();
6029 
6030     if (pTarget)
6031         memcpy(pTarget, &addr, sizeof(*pTarget));
6032 
6033     return (!con || (con == -1 && errno == EINPROGRESS))
6034            ? sock
6035            : (close(sock),-1);
6036 } /* open_ipv6_conn() */
6037 
6038 #endif /* USE_IPV6 */
6039 
6040 /*-------------------------------------------------------------------------*/
6041 static string_t *
6042 lookup_ip_entry (struct in_addr addr, Bool useErq)
6043 
6044 /* Lookup the IP address <addr> and return an uncounted pointer to
6045  * a shared string with the hostname. The function looks first in the
6046  * iptable[], then, if not found there and <useErq> is true, asks the ERQ.
6047  * If the hostname can not be found, NULL is returned.
6048  */
6049 
6050 {
6051     int i;
6052     string_t *ipname;
6053     struct in_addr tmp;
6054 
6055     /* Search for the address backwards from the last added entry,
6056      * hoping that its one of the more recently added ones.
6057      */
6058     i = ipcur;
6059     do {
6060         i--;
6061         if (i < 0)
6062             i += IPSIZE;
6063 
6064         if (!memcmp(&(iptable[i].addr.s_addr), &addr.s_addr, sizeof(iptable[i].addr.s_addr))
6065          && iptable[i].name)
6066         {
6067             return iptable[i].name;
6068         }
6069     } while (i != ipcur );
6070 
6071     /* The address is new to us.
6072      * Add a temporary entry into the iptable[] to bridge
6073      * the time until the erq has finished the lookup.
6074      * This also handles the case of an unresolvable hostname.
6075      */
6076 
6077     iptable[ipcur].addr = addr;
6078     if (iptable[ipcur].name)
6079         free_mstring(iptable[ipcur].name);
6080 
6081     memcpy(&tmp, &addr, sizeof(tmp));
6082 #ifndef USE_IPV6
6083     ipname = new_tabled(inet_ntoa(tmp));
6084 #else
6085     ipname = new_tabled(inet6_ntoa(tmp));
6086 #endif
6087 
6088     iptable[ipcur].name = ipname;
6089 
6090     ipcur = (ipcur+1) % IPSIZE;
6091 
6092     /* If we have the erq and may use it, lookup the real hostname */
6093     if (erq_demon >= 0 && useErq)
6094     {
6095 #ifndef USE_IPV6
6096         send_erq(ERQ_HANDLE_RLOOKUP, ERQ_RLOOKUP, (char *)&addr.s_addr, sizeof(addr.s_addr));
6097 #else
6098         send_erq(ERQ_HANDLE_RLOOKUPV6, ERQ_RLOOKUPV6, get_txt(ipname)
6099                 , mstrsize(ipname));
6100 #endif
6101     }
6102 
6103     return iptable[ipcur].name;
6104 }
6105 
6106 #endif /* ERQ_DEMON */
6107 
6108 /* End of ERQ Support */
6109 /*=========================================================================*/
6110 
6111 /*-------------------------------------------------------------------------*/
6112 void
6113 remove_stale_player_data (void)
6114 
6115 /* GC and statistics support: Remove all input_to and prompt infos
6116  * referencing destructed objects.
6117  */
6118 
6119 {
6120     int i;
6121 
6122     for(i = 0 ; i < MAX_PLAYERS; i++)
6123     {
6124         input_t * ih, * prev;
6125         object_t *ob;
6126 
6127         if (all_players[i] == NULL)
6128             continue;
6129 
6130         /* Remove stale input_to data */
6131         for ( prev = NULL, ih = all_players[i]->input_handler; ih != NULL; )
6132             if (ih->type == INPUT_TO)
6133             {
6134                 input_to_t *tmp = (input_to_t*) ih;
6135                 ob = callback_object(&(tmp->fun));
6136                 if (ob)
6137                 {
6138                     prev = ih;
6139                     ih = ih->next;
6140                 }
6141                 else
6142                 {
6143                     /* The object has selfdestructed */
6144 
6145                     if (prev == NULL)
6146                     {
6147                         set_noecho(all_players[i]
6148                                   , ih->next ? ih->next->noecho : 0
6149                                   , ih->next ? ih->next->local : MY_FALSE
6150                                   , MY_TRUE);
6151                         all_players[i]->input_handler = ih->next;
6152                     }
6153                     else
6154                     {
6155                         prev->next = ih->next;
6156                     }
6157 
6158                     ih = ih->next;
6159 
6160                     free_input_to(tmp);
6161                 }
6162             }
6163             else
6164             {
6165                 prev = ih;
6166                 ih = ih->next;
6167             }
6168 
6169         /* Remove stale snooping monsters */
6170         ob = all_players[i]->snoop_by;
6171         if (ob && !O_IS_INTERACTIVE(ob) && !check_object(ob))
6172         {
6173             free_object(ob, "remove_stale_player_data");
6174             all_players[i]->snoop_by = NULL;
6175         }
6176 
6177         /* Remove a stale modify_command object */
6178         ob = all_players[i]->modify_command;
6179         if (ob && !check_object(ob))
6180         {
6181             free_object(ob, "remove_stale_player_data");
6182             all_players[i]->modify_command = NULL;
6183         }
6184     } /* for (i) */
6185 } /* remove_stale_player_data() */
6186 
6187 /*-------------------------------------------------------------------------*/
6188 size_t
6189 show_comm_status (strbuf_t * sbuf, Bool verbose UNUSED)
6190 
6191 /* Return the amount of memory used by the comm module.
6192  */
6193 
6194 {
6195 #if defined(__MWERKS__)
6196 #    pragma unused(verbose)
6197 #endif
6198     size_t sum;
6199     int i;
6200 
6201     remove_stale_player_data();
6202 
6203     sum = 0;
6204 
6205     for (i = 0; i <= max_player; i++)
6206     {
6207         interactive_t *pl;
6208         input_t *ih;
6209 
6210         pl = all_players[i];
6211         if (!pl)
6212             continue;
6213 
6214         sum += sizeof(*pl);
6215 
6216         for (ih = pl->input_handler; ih != NULL; ih = ih->next)
6217             switch(ih->type)
6218             {
6219             case INPUT_TO:
6220                 sum += sizeof(input_to_t);
6221                 break;
6222             case INPUT_ED:
6223                 sum += ed_buffer_size(ih);
6224                 break;
6225             }
6226     }
6227 
6228     if (sbuf)
6229         strbuf_addf(sbuf, "Comm structures\t\t\t\t %9zu\n", sum);
6230     return sum;
6231 } /* show_comm_status() */
6232 
6233 #ifdef GC_SUPPORT
6234 
6235 /*-------------------------------------------------------------------------*/
6236 void
6237 clear_comm_refs (void)
6238 
6239 /* GC support: Clear all refs the module might have.
6240  */
6241 
6242 {
6243     int i;
6244 
6245     for (i = 0; i < MAX_OUTCONN; i++)
6246     {
6247         if (outconn[i].status != ocNotUsed)
6248         {
6249             if (outconn[i].curr_obj)
6250                 clear_object_ref(outconn[i].curr_obj);
6251         }
6252     }
6253 
6254 #ifdef ERQ_DEMON
6255     for (i = sizeof (pending_erq) / sizeof (*pending_erq); --i >= 0;)
6256     {
6257         clear_ref_in_vector(&pending_erq[i].fun, 1);
6258     }
6259 #endif /* ERQ_DEMON */
6260 } /* clear_comm_refs() */
6261 
6262 /*-------------------------------------------------------------------------*/
6263 void
6264 count_comm_refs (void)
6265 
6266 /* GC support: count any ref the module has.
6267  */
6268 
6269 {
6270     int i;
6271 
6272     for (i = 0; i < MAX_OUTCONN; i++)
6273     {
6274         if (outconn[i].status != ocNotUsed)
6275         {
6276             if (outconn[i].curr_obj)
6277             {
6278                 svalue_t sv;
6279 
6280                 put_object(&sv, outconn[i].curr_obj);
6281                 count_ref_in_vector(&sv, 1);
6282             }
6283         }
6284     }
6285 
6286 #ifdef ERQ_DEMON
6287     for(i = 0; i < IPSIZE; i++) {
6288         if (iptable[i].name)
6289             count_ref_from_string(iptable[i].name);
6290     }
6291 
6292     for (i = sizeof (pending_erq) / sizeof (*pending_erq); --i >= 0;)
6293     {
6294         count_ref_in_vector(&pending_erq[i].fun, 1);
6295     }
6296 #endif /* ERQ_DEMON */
6297 } /* count_comm_refs() */
6298 
6299 /*-------------------------------------------------------------------------*/
6300 void
6301 clear_input_refs (input_t *i)
6302 
6303 /* GC Support: Clear all references from input_t <i>.
6304  */
6305 
6306 {
6307     switch (i->type)
6308     {
6309     case INPUT_TO:
6310         {
6311             input_to_t *it = (input_to_t*) i;
6312 
6313             clear_ref_in_callback(&(it->fun));
6314             clear_ref_in_vector(&(it->input.prompt), 1);
6315 
6316             break;
6317         }
6318     case INPUT_ED:
6319        clear_ed_buffer_refs(i);
6320        break;
6321     }
6322 } /* clear_input_refs() */
6323 
6324 /*-------------------------------------------------------------------------*/
6325 void
6326 count_input_refs (input_t *i)
6327 
6328 /* GC Support: Count  all references from input_t <i>.
6329  */
6330 
6331 {
6332     switch (i->type)
6333     {
6334     case INPUT_TO:
6335         {
6336             input_to_t *it = (input_to_t*) i;
6337 
6338             count_ref_in_callback(&(it->fun));
6339             count_ref_in_vector(&(it->input.prompt), 1);
6340 
6341             break;
6342         }
6343     case INPUT_ED:
6344         count_ed_buffer_refs(i);
6345         break;
6346     }
6347 } /* count_input_refs() */
6348 
6349 #endif /* GC_SUPPORT */
6350 
6351 
6352 /*=========================================================================*/
6353 
6354 /*-------------------------------------------------------------------------*/
6355 static svalue_t *
6356 query_ip_name (svalue_t *sp, Bool lookup)
6357 
6358 /* Lookup the IP address (<lookup> is false) or IP hostname (<lookup> is
6359  * true) of object <sp> and return it. If <sp> is the number 0 or a
6360  * non-interactive object, the number 0 is returned.
6361  *
6362  * The hostname is read from the iptable[], so if it hasn't been
6363  * resolved yet, we return the number in any case.
6364  *
6365  * If <sp> is a reference to an interactive object, it will be replaced
6366  * on return with an array of integers with the full sockaddr_in:
6367  *    array[0.. 1]: sin_family
6368  *    array[2.. 3]: sin_port
6369  *    array[4.. 7]: sin_addr
6370  *    array[8..15]: undefined (ideally 0).
6371  *
6372  * The function is used to implement the efuns query_ip_number() and
6373  * query_ip_name().
6374  */
6375 
6376 {
6377     object_t *ob;
6378     int i;
6379     interactive_t *ip;
6380     string_t *str;
6381 
6382     /* Set <ob> to the object passed on the stack. */
6383 
6384     if (sp->type != T_OBJECT)
6385     {
6386         svalue_t *svp;
6387 
6388         if (sp->type == T_NUMBER && !sp->u.number)
6389             return sp;
6390         svp = sp;
6391         while (svp->type == T_LVALUE || svp->type == T_PROTECTED_LVALUE)
6392             svp = svp->u.lvalue;
6393         if (svp->type != T_OBJECT)
6394         {
6395             errorf("Bad arg 1 to query_ip_number(): expected object/object&, got %s&.\n"
6396                  , typename(svp->type));
6397             /* NOTREACHED */
6398         }
6399         ob = svp->u.ob;
6400     }
6401     else
6402     {
6403         ob = sp->u.ob;
6404         deref_object(ob, "query_ip_name");
6405         sp->type = T_INVALID;
6406     }
6407 
6408     /* Return 0 for non-interactive objects */
6409     if (!(O_SET_INTERACTIVE(ip, ob)))
6410     {
6411         free_svalue(sp);
6412         put_number(sp, 0);
6413         return sp;
6414     }
6415 
6416     /* If the object was passed as reference, replace it with an array
6417      * with the full sockaddr_in.
6418      */
6419     if (sp->type == T_LVALUE)
6420     {
6421         svalue_t array, *svp;
6422         vector_t *v;
6423         char *cp;
6424 
6425         v = allocate_array(sizeof ip->addr);
6426         if (v)
6427         {
6428             put_array(&array, v);
6429             i = sizeof ip->addr;
6430             svp = v->item;
6431             cp = (char *)&ip->addr;
6432             do {
6433                 svp->u.number = *cp++;
6434                 svp++;
6435             } while(--i);
6436             transfer_svalue(sp, &array);
6437         }
6438         else
6439         {
6440             assign_svalue(sp, &const0);
6441         }
6442 
6443         return sp;
6444     }
6445 
6446     /* If the hostname is requested and we indeed have it in our table,
6447      * return it.
6448      */
6449     if (lookup)
6450     {
6451 #ifdef ERQ_DEMON
6452         string_t * hname;
6453 
6454         hname = lookup_ip_entry(ip->addr.sin_addr, MY_FALSE);
6455         if (hname)
6456         {
6457             put_ref_string(sp, hname);
6458             return sp;
6459         }
6460 #else
6461         /* The if(lookup) gets rid of a 'lookup unused' warning. */
6462 #endif
6463     }
6464 
6465     /* Return the IP address as string.
6466      */
6467 
6468 #ifndef USE_IPV6
6469     str = new_mstring(inet_ntoa(ip->addr.sin_addr));
6470 #else
6471     str = new_mstring(inet6_ntoa(ip->addr.sin_addr));
6472 #endif
6473     if (!str)
6474     {
6475         inter_sp = sp - 1;
6476         errorf("Out of memory for IP address\n");
6477     }
6478     put_string(sp, str);
6479     return sp;
6480 } /* query_ip_number() */
6481 
6482 /*-------------------------------------------------------------------------*/
6483 char *
6484 query_host_name (void)
6485 
6486 /* Return the hostname (and just the hostname, not the full domain name).
6487  * The result is a pointer to a static array!
6488  * Called by lex.c, main.c and swap.c .
6489  */
6490 
6491 {
6492     return host_name;
6493 } /* query_host_name() */
6494 
6495 /*-------------------------------------------------------------------------*/
6496 char *
6497 get_host_ip_number (void)
6498 
6499 /* Return the IP address of the host.
6500  * The result is a newly allocated string.
6501  * Called by lex.c .
6502  */
6503 
6504 {
6505 #ifndef USE_IPV6
6506     char buf[INET_ADDRSTRLEN+3];
6507 
6508     sprintf(buf, "\"%s\"", inet_ntoa(host_ip_number));
6509 #else
6510     char buf[INET6_ADDRSTRLEN+3];
6511 
6512     sprintf(buf, "\"%s\"", inet6_ntoa(host_ip_number));
6513 #endif
6514     return string_copy(buf);
6515 } /* query_host_ip_number() */
6516 
6517 /*-------------------------------------------------------------------------*/
6518 svalue_t *
6519 f_query_snoop (svalue_t *sp)
6520 
6521 /* EFUN: query_snoop()
6522  *
6523  *   object query_snoop(object victim)
6524  *
6525  * Return the object which is snooping <victim>, or 0 if there is none.
6526  * The call must be allowed by master->valid_query_snoop().
6527  */
6528 
6529 {
6530     svalue_t *arg1;
6531     object_t *ob;
6532 
6533     /* Do some test and set ob to the snooper (if any) */
6534     switch (0) /* try {...} */
6535     {
6536       default:
6537         ob = sp->u.ob;
6538         if ((ob->flags & (O_DESTRUCTED|O_SHADOW)) != O_SHADOW
6539          || O_GET_SHADOW(ob)->ip == NULL)
6540         {
6541             zero_object_svalue(sp);
6542             return sp;
6543         }
6544         inter_sp = sp;
6545         assert_master_ob_loaded();
6546         if (current_object != master_ob)
6547         {
6548             assign_eval_cost();
6549             arg1 = apply_master(STR_VALID_QSNOOP, 1);
6550             if (arg1 == 0 || arg1->type != T_NUMBER || !arg1->u.number)
6551             {
6552                 ob = NULL;
6553                 break;
6554             }
6555         }
6556         else
6557         {
6558             deref_object(ob, "query_snoop");
6559         }
6560         ob = O_GET_INTERACTIVE(ob)->snoop_by;
6561     }
6562 
6563     /* Return the result */
6564     if (ob)
6565         put_ref_object(sp, ob, "query_snoop");
6566     else
6567         put_number(sp, 0);
6568     return sp;
6569 } /* f_query_snoop() */
6570 
6571 /*-------------------------------------------------------------------------*/
6572 svalue_t *
6573 f_query_idle (svalue_t *sp)
6574 
6575 /* EFUN: query_idle()
6576  *
6577  *   int query_idle(object ob)
6578  *
6579  * Return how many seconds a user object has been idle.
6580  */
6581 
6582 {
6583     int i;
6584     object_t *ob;
6585 
6586     ob = sp->u.ob;
6587     if (!O_IS_INTERACTIVE(ob))
6588     {
6589         inter_sp = sp;
6590         errorf("query_idle() of non-interactive object.\n");
6591         return sp;
6592     }
6593 
6594     i = current_time - O_GET_INTERACTIVE(ob)->last_time;
6595     deref_object(ob, "query_idle");
6596     put_number(sp, i);
6597     return sp;
6598 } /* f_query_idle() */
6599 
6600 /*-------------------------------------------------------------------------*/
6601 svalue_t *
6602 f_remove_interactive (svalue_t *sp)
6603 
6604 /* EFUN: remove_interactive()
6605  *
6606  *   void remove_interactive(object ob)
6607  *
6608  * Close the connection to the interactive object ob.
6609  *
6610  * In fact, the connection is only flushed and marked for closing,
6611  * as a remove_interactive() here can upset some other code.
6612  * The actual remove will be done by get_message().
6613  */
6614 
6615 {
6616     interactive_t *victim;
6617 
6618     if (O_SET_INTERACTIVE(victim, sp->u.ob)
6619      && !victim->closing
6620      && !victim->do_close)
6621     {
6622         if (victim->message_length) {
6623             command_giver = victim->ob;
6624             add_message(message_flush);
6625 
6626             /* message_flush takes always directly effect on the
6627              * socket. No apply() is involved.
6628              */
6629         }
6630         victim->do_close = FLAG_DO_CLOSE;
6631     }
6632     free_svalue(sp);
6633     return sp - 1;
6634 } /* f_remove_interactive() */
6635 
6636 /*-------------------------------------------------------------------------*/
6637 #ifdef DEBUG
6638 
6639 void
6640 count_comm_extra_refs (void)
6641 
6642 /* Count all the refs to verify the normal refcounting. */
6643 
6644 {
6645     int i;
6646 
6647 #ifdef ERQ_DEMON
6648     for (i = sizeof(pending_erq) / sizeof(*pending_erq); --i >= 0; )
6649         count_extra_ref_in_vector(&pending_erq[i].fun, 1);
6650 #endif /* ERQ_DEMON */
6651 
6652     for (i = 0; i < MAX_PLAYERS; i++)
6653     {
6654         object_t *ob;
6655         input_t *ih;
6656 
6657         if (all_players[i] == 0)
6658             continue;
6659         all_players[i]->ob->extra_ref++;
6660         if ( NULL != (ob = all_players[i]->snoop_by) ) {
6661             interactive_t *ip;
6662 
6663             if (!(O_SET_INTERACTIVE(ip, ob)))
6664             {
6665                 /* snooping monster */
6666                 ob->extra_ref++;
6667             }
6668         } /* end of snoop-processing */
6669 
6670         for ( ih = all_players[i]->input_handler; ih; ih = ih->next)
6671             switch(ih->type)
6672             {
6673             case INPUT_TO:
6674                 {
6675                     input_to_t *it = (input_to_t*) ih;
6676                     count_callback_extra_refs(&(it->fun));
6677                     count_extra_ref_in_vector(&it->input.prompt, 1);
6678                     break;
6679                 }
6680             case INPUT_ED:
6681                 count_ed_buffer_extra_refs(ih);
6682                 break;
6683             }
6684 
6685         if ( NULL != (ob = all_players[i]->modify_command) )
6686             count_extra_ref_in_object(ob);
6687         count_extra_ref_in_vector(&all_players[i]->prompt, 1);
6688     }
6689 } /* count_comm_extra_refs() */
6690 
6691 #endif /* DEBUG */
6692 
6693 /*-------------------------------------------------------------------------*/
6694 svalue_t *
6695 f_send_udp (svalue_t *sp)
6696 
6697 /* EFUN: send_udp()
6698  *
6699  *   int send_udp(string host, int port, string message)
6700  *   int send_udp(string host, int port, int * message)
6701  *
6702  * Sends The message in an UDP packet to the given host and port
6703  * number. Causes a privilege violation.
6704  * The message can be given either as string, or as array of
6705  * bytes. The latter variant allows to send binary data as well.
6706  * Returns 1 on success, 0 on failure.
6707  *
6708  * Note: On some machines a failed send_imp() will not be registered
6709  * until the next send_imp() - the latter one might return '0' even
6710  * if itself was successful.
6711  */
6712 
6713 {
6714     char *to_host = NULL;
6715     int to_port;
6716     char *msg;
6717     size_t msglen;
6718 #ifndef USE_IPV6
6719     int ip1, ip2, ip3, ip4;
6720 #endif /* USE_IPV6 */
6721     struct sockaddr_in name;
6722     struct hostent *hp;
6723     int ret = 0;
6724     svalue_t *firstarg; /* store the first argument */
6725 
6726     firstarg = sp-2;  /* hostname */
6727 
6728     switch(0) { default: /* try {...} */
6729 
6730         /* Set msg/msglen to the data of the message to send */
6731 
6732         if (sp->type == T_STRING)
6733         {
6734             msg = get_txt(sp->u.str);
6735             msglen = mstrsize(sp->u.str);
6736         }
6737         else /* it's an array */
6738         {
6739             vector_t *v;
6740             svalue_t *svp;
6741             char *cp;
6742             p_int j;
6743 
6744             v = sp->u.vec;
6745             msglen = VEC_SIZE(v);
6746             /* allocate memory and push error handler onto stack */
6747             cp = msg = xalloc_with_error_handler(msglen);
6748             if (!msg) {
6749                 errorf("Out of memory (%zu bytes) in send_udp() for "
6750                        "temporary buffer.\n", msglen);
6751             }
6752             sp = inter_sp;
6753 
6754             svp = &v->item[0];
6755             for (j = (p_int)msglen; --j >= 0; )
6756                 *cp++ = (char)(*svp++).u.number;
6757         }
6758 
6759         /* Is this call valid? */
6760 
6761         if (!privilege_violation(STR_SEND_UDP, firstarg, sp))
6762             break;
6763 
6764         if (udp_s < 0)
6765             break;
6766 
6767         /* Determine the destination address */
6768 
6769         {
6770             size_t adrlen;
6771 
6772             adrlen = mstrsize(firstarg->u.str);
6773             /* as there are no runtime error raised below, we just xallocate
6774              * and don't bother with an error handler. */
6775             to_host = xalloc(adrlen+1);
6776             if (!to_host)
6777             {
6778                 errorf("Out of memory (%zu bytes) in send_udp() for host address\n"
6779                      , (adrlen+1));
6780                 /* NOTREACHED */
6781             }
6782             memcpy(to_host, get_txt(firstarg->u.str), adrlen);
6783             to_host[adrlen] = '\0';
6784         }
6785         to_port = (sp-1)->u.number;
6786 
6787 #ifndef USE_IPV6
6788         if (sscanf(to_host, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4) == 4)
6789         {
6790             name.sin_addr.s_addr = inet_addr(to_host);
6791             name.sin_family = AF_INET;
6792         }
6793         else
6794         {
6795             /* TODO: Uh-oh, blocking DNS in the execution thread */
6796             hp = gethostbyname(to_host);
6797             if (hp == 0)
6798                 break;
6799             memcpy(&name.sin_addr, hp->h_addr, (size_t)hp->h_length);
6800             name.sin_family = AF_INET;
6801         }
6802 
6803 #else /* USE_IPV6 */
6804 
6805         /* TODO: Uh-oh, blocking DNS in the execution thread */
6806         hp = gethostbyname2(to_host, AF_INET6);
6807         if (hp == 0) hp = gethostbyname2(to_host, AF_INET);
6808         if (hp == 0) break;
6809         memcpy(&name.sin_addr, hp->h_addr, (size_t)hp->h_length);
6810 
6811         if (hp->h_addrtype == AF_INET)
6812         {
6813             CREATE_IPV6_MAPPED(&name.sin_addr, (u_int32_t)hp->h_addr_list[0]);
6814         }
6815         name.sin_family = AF_INET6;
6816 #endif /* USE_IPV6 */
6817 
6818         name.sin_port = htons(to_port);
6819 
6820         /* Send the message. */
6821 #ifndef SENDTO_BROKEN
6822         if (sendto(udp_s, msg, msglen, 0,
6823                (struct sockaddr *)&name, sizeof(name)) != (int)msglen)
6824 #endif
6825             break;
6826         ret = 1;
6827     }
6828     /* Cleanup - an allocated buffer for the message will be on the stack
6829      * above the arguments, therefore clean everything from the first argument
6830      * (including) to sp.
6831      */
6832     sp = pop_n_elems((sp-firstarg)+1, sp);
6833     xfree(to_host);
6834 
6835     /*Return the result */
6836     sp++;
6837     put_number(sp, ret);
6838     return sp;
6839 
6840 } /* f_send_udp() */
6841 
6842 /*-------------------------------------------------------------------------*/
6843 svalue_t *
6844 f_set_buffer_size (svalue_t *sp)
6845 
6846 /* EFUN: set_buffer_size()
6847  *
6848  *   int set_buffer_size(int size)
6849  *
6850  * Changes the socket buffer size for this_interactive() to size,
6851  * up to a preconfigured maximum, result is the old buffer size
6852  * (or -1 on systems which aren't able to change the socket
6853  * buffer).
6854  * Modifying the buffer size may result in a better IO
6855  * throughput, but can also worsen it.
6856  */
6857 
6858 {
6859     int new;
6860 
6861     /* Get the desired buffer size */
6862 
6863     if (sp->u.number > SET_BUFFER_SIZE_MAX)
6864     {
6865         errorf("Bad arg 1 to set_buffer_size(): value %"PRIdPINT" exceeds maximum %ld\n"
6866              , sp->u.number, (long) SET_BUFFER_SIZE_MAX);
6867         /* NOTREACHED */
6868         return sp;
6869     }
6870     new = sp->u.number;
6871 
6872     sp->u.number = -1; /* Default result */
6873 
6874 #ifdef SO_SNDBUF
6875     {
6876         int old;
6877         length_t optlen;
6878         interactive_t *ip;
6879 
6880         if (!(O_SET_INTERACTIVE(ip, current_object))
6881          || ip->do_close)
6882         {
6883             return sp;
6884         }
6885 
6886 
6887         optlen = sizeof old;
6888         if (getsockopt(ip->socket, SOL_SOCKET, SO_SNDBUF, (char *)&old, &optlen) < 0)
6889             return sp;
6890         if (setsockopt(ip->socket, SOL_SOCKET, SO_SNDBUF, (char *)&new, sizeof new) < 0)
6891             return sp;
6892         sp->u.number = old;
6893     }
6894 #endif /* SO_SNDBUF */
6895 
6896     return sp;
6897 } /* f_set_buffer_size() */
6898 
6899 /*-------------------------------------------------------------------------*/
6900 svalue_t *
6901 f_binary_message (svalue_t *sp)
6902 
6903 /* EFUN: binary_message()
6904  *
6905  *   int binary_message(int *|string message, int flags)
6906  *
6907  * Flush output and send output directly with write WITHOUT IAC QUOTING.
6908  * The message may contain zeroes if given as int *.
6909  * The messages goes to this_object(), but only if interactive.
6910  * Returned value: number of characters actually written.
6911  * Any 'allowed charset' setting is ignored.
6912  *
6913  * Flag settings are interpreted bitwise and may be ored
6914  * together:
6915  *
6916  *   Bit 0 (value 1): when set, add_message() is used instead of
6917  *     write(). Thus no previous flushing of the buffer is
6918  *     needed, but the output is not immediate, nor can the
6919  *     number of bytes actually sent be determined - the return
6920  *     value is undefined.
6921  *   Bit 1 (value 2): The buffer is flushed _after_ adding the
6922  *     message. Useful only in conjunction with Bit 0.
6923  *
6924  * The idea behind the flag settings is that sending command
6925  * codes for colours and other things needs to bypass the allowed
6926  * charset filters, but isn't important enough to waste bandwith
6927  * on a synchronous transmission.
6928  */
6929 
6930 {
6931     string_t *msg;
6932     mp_int wrote = 0, i;
6933     svalue_t *svp;
6934     interactive_t *ip;
6935     object_t *save_command_giver;
6936 
6937     /* Set message to the data to be sent, and size to its length. */
6938 
6939     if (sp[-1].type == T_POINTER)
6940     {
6941         char *p;
6942         size_t size;
6943 
6944         size = VEC_SIZE(sp[-1].u.vec);
6945         msg = alloc_mstring(size);
6946         if (!msg)
6947           errorf("Out of memory (%zu bytes) in binary_message()",size);
6948         for (i = (mp_int)size, svp = sp[-1].u.vec->item, p = get_txt(msg)
6949             ; --i >= 0; svp++)
6950         {
6951             if (svp->type != T_NUMBER)
6952             {
6953                 free_mstring(msg);
6954                 errorf("Bad arg 1 to binary_message(): got %s*, "
6955                       "expected string/int*.\n", typename(svp->type));
6956                 /* NOTREACHED */
6957                 return sp;
6958             }
6959             *p++ = (char)svp->u.number;
6960         }
6961     }
6962     else /* it's a string */
6963     {
6964         msg = ref_mstring(sp[-1].u.str);
6965     }
6966 
6967     /* Send the message */
6968 
6969     i = 0;
6970     if (O_SET_INTERACTIVE(ip, current_object)
6971      && !ip->do_close)
6972     {
6973         save_command_giver = command_giver;
6974         command_giver = current_object;
6975 
6976         if (sp->u.number & 1)
6977         {
6978             /* Write before flush... */
6979 
6980             sending_telnet_command = MY_TRUE; /* turn of IAC quoting */
6981 
6982             add_message(FMT_STRING, msg);
6983 
6984             sending_telnet_command = MY_FALSE;
6985 
6986             if (sp->u.number & 2)
6987                 add_message(message_flush);
6988 
6989             wrote = mstrsize(msg);
6990         }
6991         else
6992         {
6993             /* Flush, then write. */
6994             add_message(message_flush);
6995 
6996             /* Since all pending data was flushed, we can write directly
6997              * to the socket now.
6998              */
6999 
7000             if (comm_socket_write(get_txt(msg), mstrsize(msg), ip, 0))
7001                 wrote = mstrsize(msg);
7002 
7003         } /* if (type of write) */
7004 
7005         command_giver = save_command_giver;
7006     } /* end if interactive */
7007 
7008     sp--;
7009     free_mstring(msg);
7010     free_svalue(sp);
7011     put_number(sp, wrote);
7012     return sp;
7013 } /* f_binary_message() */
7014 
7015 /*-------------------------------------------------------------------------*/
7016 svalue_t *
7017 f_exec (svalue_t *sp)
7018 
7019 /* EFUN exec()
7020  *
7021  *   object exec(object new, object old)
7022  *
7023  * Switch the network connection from <old> to <new>. If <new> is already
7024  * interactive, its connection will be switched to <old>.
7025  *
7026  * It is used to load different "user objects" or to reconnect
7027  * link dead users.
7028  *
7029  * If <old> was command_giver, <news> will be the new command_giver.
7030  *
7031  * The call is validated by master->valid_exec() and returns 0 on
7032  * failure, and 1 on success.
7033  */
7034 
7035 {
7036     int rc;
7037     object_t *ob;
7038     object_t *obfrom;
7039 
7040     rc = 0;
7041 
7042     ob = sp[-1].u.ob;
7043     obfrom = sp[0].u.ob;
7044 
7045     do {
7046         svalue_t *v;
7047         interactive_t *stale_interactive, *ip;
7048         object_t *save_command;
7049 
7050         /* Ask the master if this exec() is ok. */
7051         push_ref_string(inter_sp, current_prog->name);
7052           /* TODO: FinalFrontier suggests 'current_object->prog->name' */
7053         push_ref_object(inter_sp, ob, "exec");
7054         push_ref_object(inter_sp, obfrom, "exec");
7055         v = apply_master(STR_VALID_EXEC, 3);
7056         if (!v || v->type != T_NUMBER || v->u.number == 0)
7057             break;
7058 
7059         /* stale_interactive becomes the former interactive _if_ it
7060          * still is an interactive_t.
7061          */
7062         if (!(O_SET_INTERACTIVE(stale_interactive, ob)))
7063         {
7064             stale_interactive = NULL;
7065         }
7066 
7067         if (!(O_SET_INTERACTIVE(ip, obfrom)))
7068             errorf("Bad argument 2 to exec(): not interactive.\n");
7069 
7070         /* When we have to have an out of memory error, have it before pointers
7071          * get changed.
7072          */
7073         assert_shadow_sent(ob);
7074 
7075         save_command = command_giver;
7076 
7077         /* If <ob> has a connection, flush it */
7078         if (stale_interactive)
7079         {
7080             if (stale_interactive->message_length)
7081             {
7082                 command_giver = ob;
7083                 add_message(message_flush);
7084             }
7085         }
7086 
7087         /* Flush the connection of <obfrom> */
7088 
7089         if (ip->message_length) {
7090             command_giver = obfrom;
7091             add_message(message_flush);
7092         }
7093         command_giver = save_command;
7094 
7095         /* Switch a possible snooper */
7096 
7097         if (ip->snoop_on)
7098             ip->snoop_on->snoop_by = ob;
7099 
7100         /* Switch the interactive */
7101 
7102         O_GET_INTERACTIVE(ob) = ip;
7103         O_GET_INTERACTIVE(obfrom) = NULL;
7104         ob->flags |= O_ONCE_INTERACTIVE;
7105         ip->ob = ob;
7106         ip->catch_tell_activ = MY_TRUE;
7107 
7108         if (stale_interactive)
7109         {
7110             /* Tie <ob>s stale connection to <obfrom>. */
7111 
7112             O_GET_INTERACTIVE(obfrom) = stale_interactive;
7113             stale_interactive->ob = obfrom;
7114             if (stale_interactive->snoop_on)
7115                 stale_interactive->snoop_on->snoop_by = obfrom;
7116             stale_interactive->catch_tell_activ = MY_TRUE;
7117         }
7118         else
7119         {
7120             /* Clean up <obfrom> after the loss of connection */
7121 
7122             obfrom->flags &= ~O_ONCE_INTERACTIVE;
7123             check_shadow_sent(obfrom);
7124 
7125             ref_object(ob, "exec");
7126             free_object(obfrom, "exec");
7127         }
7128 
7129         /* If this_player() or this_interactive() point to one of the
7130          * involved objects, switch it too.
7131          */
7132         if (obfrom == command_giver)
7133             command_giver = ob;
7134         else if (ob == command_giver)
7135             command_giver = obfrom;
7136 
7137         if (obfrom == current_interactive)
7138             current_interactive = ob;
7139         else if (ob == current_interactive)
7140             current_interactive = obfrom;
7141 
7142         rc = 1;
7143     }while(0);
7144 
7145     free_svalue(sp--);
7146     free_svalue(sp); /* object might have been destructed */
7147     put_number(sp, rc);
7148 
7149     return sp;
7150 } /* f_exec() */
7151 
7152 /*-------------------------------------------------------------------------*/
7153 svalue_t *
7154 f_interactive (svalue_t *sp)
7155 
7156 /* EFUN interactive()
7157  *
7158  *   int interactive(object ob)
7159  *
7160  * Return non-zero if ob, or when the argument is omitted, this
7161  * object(), is an interactive user. Will return 1 if the
7162  * object is interactive, else 0.
7163  */
7164 
7165 {
7166     int i;
7167     object_t *ob;
7168     interactive_t *ip;
7169 
7170     ob = sp->u.ob;
7171     (void)O_SET_INTERACTIVE(ip, ob);
7172     i = ip && !ip->do_close;
7173     deref_object(ob, "interactive");
7174     put_number(sp, i);
7175 
7176     return sp;
7177 } /* f_interactive() */
7178 
7179 /*-------------------------------------------------------------------------*/
7180 svalue_t *
7181 v_input_to (svalue_t *sp, int num_arg)
7182 
7183 /* EFUN input_to()
7184  *
7185  *   void input_to(string fun)
7186  *   void input_to(string fun, int flag, ...)
7187  *
7188  * Enable next line of user input to be sent to the local
7189  * function fun as an argument. The input line will not be
7190  * parsed, only when it starts with a "!" (like a kind of shell
7191  * escape) (this feature may be disabled).
7192  * The function <fun> may be static, but must not be private (or
7193  * it won't be found).
7194  *
7195  * Note that fun is not called immediately but after pressing the
7196  * RETURN key.
7197  *
7198  * If input_to() is called more than once in the same execution,
7199  * only the first call has any effect.
7200  *
7201  * The optional 3rd and following args will be passed as second and
7202  * subsequent args to the function fun. (This feature is was
7203  * added only recently, to avoid the need for global variables)
7204  */
7205 
7206 {
7207     svalue_t *arg;       /* Pointer to the arguments of the efun */
7208     svalue_t *extra_arg; /* Pointer to the extra arguments of the efun */
7209     int iflags;          /* The flags passed to input_to() */
7210     int flags;           /* The flags as required for .noecho */
7211     input_to_t *it;
7212     int extra;           /* Number of extra arguments */
7213     int error_index;
7214 
7215     arg = sp - num_arg + 1;
7216 
7217     /* Extract the arguments */
7218 
7219     iflags = 0;
7220     extra = 0;
7221     extra_arg = arg + 1;
7222 
7223     if (arg[0].type != T_CLOSURE && arg[0].type != T_STRING)
7224     {
7225         vefun_bad_arg(1, sp);
7226         /* NOTREACHED */
7227         return NULL;
7228     }
7229 
7230     if (num_arg > 1)
7231     {
7232         if (arg[1].type != T_NUMBER)
7233         {
7234             vefun_bad_arg(2, sp);
7235             /* NOTREACHED */
7236             return NULL;
7237         }
7238 
7239         iflags = arg[1].u.number;
7240         extra = num_arg - 2;
7241         extra_arg = arg + 2;
7242     }
7243 
7244     {
7245         interactive_t *ip;
7246 
7247         if (command_giver != NULL
7248          && O_SET_INTERACTIVE(ip, command_giver)
7249          && !ip->tn_enabled
7250            )
7251         {
7252             if (!(iflags & INPUT_NOECHO) != !(ip->noecho & NOECHO_MASK))
7253             {
7254                 warnf("input_to(): Change in NOECHO mode requested for object '%s' "
7255                       "with telnet disabled.\n"
7256                      , get_txt(command_giver->name)
7257                      );
7258             }
7259 
7260             if (!(iflags & INPUT_CHARMODE) != !(ip->noecho & CHARMODE_MASK)
7261              && (iflags & INPUT_NO_TELNET) == 0
7262                )
7263             {
7264                 warnf("input_to(): Change in CHARMODE mode requested for object '%s' "
7265                       "with telnet disabled.\n"
7266                      , get_txt(command_giver->name)
7267                      );
7268             }
7269         }
7270     }
7271 
7272     /* Setup the flags required for 'noecho' */
7273     flags =   ((iflags & INPUT_NOECHO)      ? NOECHO_REQ   : 0)
7274             | ((iflags & INPUT_CHARMODE)    ? CHARMODE_REQ : 0)
7275             | ((iflags & INPUT_IGNORE_BANG) ? IGNORE_BANG  : 0)
7276           ;
7277 
7278     /* Check the arguments */
7279 
7280     if (iflags & INPUT_PROMPT)
7281     {
7282         if (num_arg <= 2)
7283         {
7284             errorf("Missing prompt argument to input_to().\n");
7285             /* NOTREACHED */
7286         }
7287 
7288         if (arg[2].type != T_STRING && arg[2].type != T_CLOSURE)
7289         {
7290             vefun_bad_arg(3, sp);
7291             /* NOTREACHED */
7292         }
7293     }
7294 
7295     if ((flags & IGNORE_BANG)
7296      && !privilege_violation4(STR_INPUT_TO, command_giver, 0, flags, sp))
7297     {
7298         do
7299         {
7300             free_svalue(sp--);
7301         } while (--num_arg);
7302 
7303         put_number(arg, 0); /* arg should equal sp+1 */
7304         return arg;
7305     }
7306 
7307     /* There is a chance that the privilege_violation() method destructed
7308      * the current object or the command_giver - return as if the call was
7309      * denied.
7310      */
7311     if (!check_object(current_object) || !check_object(command_giver))
7312     {
7313 	do
7314 	{
7315 	    free_svalue(sp--);
7316 	} while (--num_arg);
7317 
7318 	put_number(arg, 0); /* arg should equal sp+1 */
7319 	return arg;
7320     }
7321 
7322     /* Allocate and setup the input_to structure */
7323 
7324     xallocate(it, sizeof *it, "new input_to");
7325     init_empty_callback(&(it->fun));
7326     put_number(&(it->input.prompt), 0);
7327 
7328     /* If SET_PROMPT was specified, collect it */
7329 
7330     if (iflags & INPUT_PROMPT)
7331     {
7332         transfer_svalue(&(it->input.prompt), arg+2);
7333         extra--;
7334         extra_arg++;
7335     }
7336 
7337     /* Parse the extra args for the call */
7338 
7339     if (arg[0].type == T_STRING)
7340     {
7341         error_index = setup_function_callback(&(it->fun), current_object
7342                                              , arg[0].u.str
7343                                              , extra, extra_arg
7344                                              , MY_TRUE
7345                                              );
7346         free_string_svalue(arg);
7347     }
7348     else if (arg[0].type == T_CLOSURE)
7349         error_index = setup_closure_callback(&(it->fun), arg
7350                                             , extra, extra_arg
7351                                             , MY_TRUE
7352                                             );
7353     else
7354         error_index = 1;
7355 
7356     if (error_index >= 0)
7357     {
7358         free_input_to(it);
7359         vefun_bad_arg(error_index + num_arg - extra + 1, arg-1);
7360         /* NOTREACHED */
7361         return arg-1;
7362     }
7363 
7364     /* At this point the call back should be bound to an existing object - but
7365      * as a sanity check we test it.
7366      */
7367     if (NULL == callback_object(&(it->fun)))
7368     {
7369         free_input_to(it);
7370 	put_number(arg, 0); /* arg should equal sp+1 */
7371 	return arg;
7372     }
7373 
7374     /* Try setting the input_to. On success, return 1. */
7375 
7376     if (set_call( command_giver, it, (char)flags
7377                 , (iflags & INPUT_NO_TELNET) != 0
7378                 , (iflags & INPUT_APPEND) != 0
7379                 )
7380        )
7381     {
7382         put_number(arg, 1);
7383         return arg;
7384     }
7385 
7386     /* input_to() was not allowed - return 0. */
7387 
7388     free_input_to(it);
7389     put_number(arg, 0);
7390     return arg;
7391 } /* v_input_to() */
7392 
7393 /*-------------------------------------------------------------------------*/
7394 static void
7395 free_input_to (input_to_t *it)
7396 
7397 /* Deallocate the input_to structure <it> and all referenced memory.
7398  */
7399 
7400 {
7401     free_callback(&(it->fun));
7402     free_svalue(&(it->input.prompt));
7403     xfree(it);
7404 } /* free_input_to() */
7405 
7406 /*-------------------------------------------------------------------------*/
7407 static void
7408 free_input_handler (input_t *ih)
7409 
7410 /* Deallocate the input_t structure <ih> and all referenced memory.
7411  */
7412 
7413 {
7414     switch (ih->type)
7415     {
7416     case INPUT_TO:
7417         free_input_to((input_to_t*) ih);
7418         break;
7419 
7420     case INPUT_ED:
7421         free_ed_buffer(ih);
7422         break;
7423     }
7424 
7425 } /* free_input_handler() */
7426 
7427 /*-------------------------------------------------------------------------*/
7428 void
7429 abort_input_handler (interactive_t *ip)
7430 
7431 /* Called from destruct_object to finish some input handlers,
7432  * specifically save all ed sessions.
7433  */
7434 {
7435     input_t ** ptr = &(ip->input_handler);
7436 
7437     while (*ptr)
7438     {
7439         switch ((*ptr)->type)
7440         {
7441         case INPUT_ED:
7442             {
7443                 input_t * ed_buf = *ptr;
7444 
7445                 *ptr = (*ptr)->next;
7446                 save_ed_buffer(ed_buf);
7447                 break;
7448             }
7449 
7450         default:
7451             ptr = &((*ptr)->next);
7452             break;
7453         }
7454     }
7455 } /* abort_input_handler() */
7456 
7457 /*-------------------------------------------------------------------------*/
7458 void
7459 add_input_handler (interactive_t *ip, input_t *ih, Bool append)
7460 
7461 /* Put the input handler <ih> in front of the input handler list of
7462  * the interactive <ip>.
7463  * If <append> is TRUE, the handler is appended to the list.
7464  */
7465 {
7466     if (!append || ip->input_handler == NULL)
7467     {
7468         ih->next = ip->input_handler;
7469         ip->input_handler = ih;
7470     }
7471     else
7472     {
7473         input_t * ptr = ip->input_handler;
7474 
7475         while (ptr->next != NULL)
7476             ptr = ptr->next;
7477 
7478         ptr->next = ih;
7479         ih->next = NULL;
7480     }
7481 
7482     if (ih->noecho || ip->noecho)
7483         set_noecho(ip, ih->noecho, ih->local, MY_FALSE);
7484 
7485 } /* add_input_handler() */
7486 
7487 /*-------------------------------------------------------------------------*/
7488 void
7489 remove_input_handler (interactive_t *ip, input_t *ih)
7490 
7491 /* Remove the input handler <ih> from the input handler list of
7492  * the interactive <ip>. <ih> is not freed.
7493  */
7494 {
7495     input_t * ptr = ip->input_handler;
7496 
7497     if (ptr == ih)
7498     {
7499         ip->input_handler = ih->next;
7500         return;
7501     }
7502 
7503     while (ptr)
7504     {
7505         if (ptr->next == ih)
7506         {
7507             ptr->next = ih->next;
7508             break;
7509         }
7510         ptr = ptr->next;
7511     }
7512 
7513 } /* remove_input_handler() */
7514 
7515 /*-------------------------------------------------------------------------*/
7516 input_t *
7517 get_input_handler (interactive_t *ip, input_type_t type)
7518 
7519 /* Returns the first input handler from <ip> of type <type>.
7520  */
7521 {
7522     input_t *ih;
7523 
7524     for (ih = ip->input_handler; ih; ih = ih->next)
7525         if (ih->type == type)
7526             return ih;
7527 
7528     return NULL;
7529 } /* get_input_handler */
7530 
7531 /*-------------------------------------------------------------------------*/
7532 svalue_t *
7533 f_query_input_pending (svalue_t *sp)
7534 
7535 /* EFUN query_input_pending()
7536  *
7537  *   object query_input_pending(object ob)
7538  *
7539  * If ob is interactive and currently has an input_to() pending,
7540  * the object that has called the input_to() is returned,
7541  * else 0.
7542  */
7543 
7544 {
7545     object_t *ob, *cb;
7546     interactive_t *ip;
7547 
7548     ob = sp->u.ob;
7549     if (O_SET_INTERACTIVE(ip, ob) && ip->input_handler)
7550     {
7551         input_t *ih = ip->input_handler;
7552 
7553         while (ih && ih->type != INPUT_TO)
7554             ih = ih->next;
7555 
7556         if (ih)
7557         {
7558             cb = callback_object(&(((input_to_t*)ih)->fun));
7559             if (cb)
7560                 sp->u.ob = ref_object(cb, "query_input_pending");
7561             else
7562                 put_number(sp, 0);
7563         }
7564         else
7565             put_number(sp, 0);
7566     }
7567     else
7568     {
7569         put_number(sp, 0);
7570     }
7571 
7572     deref_object(ob, "query_input_pending");
7573 
7574     return sp;
7575 } /* f_query_input_pending() */
7576 
7577 /*-------------------------------------------------------------------------*/
7578 svalue_t *
7579 v_find_input_to (svalue_t *sp, int num_arg)
7580 
7581 /* EFUN: find_input_to()
7582  *
7583  *   int find_input_to (object player, string|closure|object fun)
7584  *   int find_input_to (object player, object ob, string fun)
7585  *
7586  * Find the input_to most recently added to the interactive <player> object
7587  * matching the <fun> argument:
7588  *  - <fun> is a string: the input_to functionname has to match
7589  *  - <fun> is an object: the object the input_to function is bound to has
7590  *                        to match
7591  *  - <fun> is a closure: the input_to closure has to match.
7592  * If both <ob> and <fun> are specified, both the object and the function name
7593  * have to match.
7594  *
7595  * Return -1 if not found, or the position in the input_to stack (0 being
7596  * _least_ recently added input_to).
7597  */
7598 
7599 {
7600     svalue_t *arg;  /* Pointer to the arguments of the efun */
7601     int       rc;   /* Resultvalue */
7602 
7603     arg = sp - num_arg + 1;
7604 
7605     if (num_arg > 2)
7606     {
7607         if (arg[1].type == T_OBJECT && num_arg > 2 && arg[2].type != T_STRING)
7608         {
7609             vefun_bad_arg(3, sp);
7610             /* NOTREACHED */
7611             return NULL;
7612         }
7613 
7614         if (arg[1].type != T_OBJECT
7615            )
7616         {
7617             vefun_bad_arg(2, sp);
7618             /* NOTREACHED */
7619             return NULL;
7620         }
7621     }
7622 
7623     /* Process the command, terminating out when possible */
7624     do
7625     {
7626         input_t       *ih;
7627         interactive_t *ip;
7628 
7629         /* Get the interactive object.
7630          * If there is none, or if it is closing down or doesn't have
7631          * an input_to set, fail.
7632          */
7633         if (!(O_SET_INTERACTIVE(ip, arg[0].u.ob))
7634          || ip->closing || ip->input_handler == NULL
7635            )
7636         {
7637             rc = -1;
7638             break;
7639         }
7640 
7641         /* Search for the right input_to */
7642 
7643         for ( ih = ip->input_handler
7644             ; ih != NULL
7645             ; ih = ih->next)
7646         {
7647             input_to_t *it;
7648             Bool found = MY_FALSE;
7649 
7650             if (ih->type != INPUT_TO)
7651                 continue;
7652             it = (input_to_t*) ih;
7653 
7654             switch (arg[1].type)
7655             {
7656             case T_STRING:
7657                 if (!it->fun.is_lambda
7658                  && mstreq(it->fun.function.named.name, arg[1].u.str))
7659                     found = MY_TRUE;
7660                 break;
7661 
7662             case T_OBJECT:
7663                 if (num_arg > 2)
7664                 {
7665                     if (callback_object(&(it->fun)) == arg[1].u.ob
7666                      && !it->fun.is_lambda
7667                      && it->fun.function.named.name == arg[2].u.str
7668                        )
7669                         found = MY_TRUE;
7670                 }
7671                 else
7672                 {
7673                     if (callback_object(&(it->fun)) == arg[1].u.ob)
7674                         found = MY_TRUE;
7675                 }
7676                 break;
7677 
7678             case T_CLOSURE:
7679                 if (it->fun.is_lambda
7680                  && closure_eq(&(it->fun.function.lambda), arg+1))
7681                     found = MY_TRUE;
7682                 break;
7683 
7684             default:
7685                 /* TODO: Wouldn't errorf() suffice? */
7686                 fatal("Unsupported argument type %d\n", arg[1].type);
7687                 break;
7688             }
7689 
7690             if (found)
7691                 break;
7692         }
7693 
7694         if (ih != NULL)
7695         {
7696             /* We found the input_to: now count at which position it is */
7697             for ( rc = 0; ih->next != NULL; ih = ih->next)
7698                 if (ih->type == INPUT_TO)
7699                     rc++;
7700             break;
7701         }
7702 
7703         /* At this point, we didn't find the input_to */
7704         rc = -1;
7705     } while (0);
7706 
7707     /* Return the result */
7708     sp = pop_n_elems(num_arg, sp);
7709     sp++;
7710     put_number(sp, rc);
7711 
7712     return sp;
7713 } /* f_find_input_to() */
7714 
7715 /*-------------------------------------------------------------------------*/
7716 svalue_t *
7717 v_remove_input_to (svalue_t *sp, int num_arg)
7718 
7719 /* EFUN: remove_input_to()
7720  *
7721  *   int remove_input_to (object player)
7722  *   int remove_input_to (object player, string|closure|object fun)
7723  *   int remove_input_to (object player, object ob, string fun)
7724  *
7725  * Remove a pending input_to from the interactive <player> object.
7726  * If the optional <fun> is not given, the most recently added input_to
7727  * is removed.
7728  *
7729  * If the optional <fun> is given, the efun tries to find and remove the
7730  * most recently added input_to matching the <fun> argument:
7731  *  - <fun> is a string: the input_to functionname has to match
7732  *  - <fun> is an object: the object the input_to function is bound to has
7733  *                        to match
7734  *  - <fun> is a closure: the input_to closure has to match.
7735  * If both <ob> and <fun> are specified, both the object and the function name
7736  * have to match.
7737  *
7738  * Return 1 on success, or 0 on failure (no input_to found, object is not
7739  * interactive or has no input_to pending).
7740  */
7741 
7742 {
7743     svalue_t      *arg;  /* Pointer to the arguments of the efun */
7744     int            rc;   /* Resultvalue */
7745     interactive_t *ip;
7746     Bool           removedFirst;
7747 
7748     /* Get the arguments */
7749     arg = sp - num_arg + 1;
7750 
7751     if (num_arg > 2)
7752     {
7753         if (arg[1].type == T_OBJECT && arg[2].type != T_STRING)
7754         {
7755             vefun_bad_arg(3, sp);
7756             /* NOTREACHED */
7757             return NULL;
7758         }
7759         if (arg[1].type != T_OBJECT)
7760         {
7761             vefun_bad_arg(2, sp);
7762             /* NOTREACHED */
7763             return NULL;
7764         }
7765     }
7766 
7767 
7768     /* Process the command, bailing out whenever necessary */
7769     do
7770     {
7771         input_t * prev;
7772         input_t    *ih;
7773 
7774         removedFirst = MY_FALSE;
7775 
7776         /* Get the interactive object.
7777          * If there is none, or if it is closing down or doesn't have
7778          * an input_to set, fail.
7779          */
7780         if (!(O_SET_INTERACTIVE(ip, arg[0].u.ob))
7781          || ip->closing || ip->input_handler == NULL
7782            )
7783         {
7784             rc = 0;
7785             break;
7786         }
7787 
7788         /* Search for the right input_to */
7789 
7790         for (prev = NULL, ih = ip->input_handler
7791             ; ih != NULL
7792             ; prev = ih, ih = ih->next)
7793         {
7794             input_to_t *it;
7795             Bool found = MY_FALSE;
7796 
7797             if (ih->type != INPUT_TO)
7798                 continue;
7799             it = (input_to_t*) ih;
7800 
7801             /* If no filter argument has been given, just remove
7802              * the first input to.
7803              */
7804             if (num_arg < 2)
7805                 break;
7806 
7807             switch (arg[1].type)
7808             {
7809             case T_STRING:
7810                 if (!it->fun.is_lambda
7811                  && mstreq(it->fun.function.named.name, arg[1].u.str))
7812                     found = MY_TRUE;
7813                 break;
7814 
7815             case T_OBJECT:
7816                 if (num_arg > 2)
7817                 {
7818                     if (callback_object(&(it->fun)) == arg[1].u.ob
7819                      && !it->fun.is_lambda
7820                      && it->fun.function.named.name == arg[2].u.str
7821                        )
7822                         found = MY_TRUE;
7823                 }
7824                 else
7825                 {
7826                     if (callback_object(&(it->fun)) == arg[1].u.ob)
7827                         found = MY_TRUE;
7828                 }
7829                 break;
7830 
7831             case T_CLOSURE:
7832                 if (it->fun.is_lambda
7833                  && closure_eq(&(it->fun.function.lambda), arg+1))
7834                     found = MY_TRUE;
7835                 break;
7836 
7837             default:
7838                 /* TODO: Wouldn't errorf() suffice? */
7839                 fatal("Unsupported argument type %d\n", arg[1].type);
7840                 break;
7841             }
7842 
7843             if (found)
7844                 break;
7845         }
7846 
7847         if (ih != NULL)
7848         {
7849             /* We found the input_to: remove it */
7850             if (prev == NULL)
7851             {
7852                 ip->input_handler = ih->next;
7853                 removedFirst = MY_TRUE;
7854             }
7855             else
7856                 prev->next = ih->next;
7857 
7858             free_input_to((input_to_t*)ih);
7859             rc = 1;
7860             break;
7861         }
7862 
7863         /* At this point, nothing worked: failure */
7864         rc = 0;
7865     } while (0);
7866 
7867     if (rc && removedFirst)
7868     {
7869         if (ip->noecho)
7870             ip->noecho |= NOECHO_STALE;
7871         set_noecho(ip, ip->input_handler ? ip->input_handler->noecho : ip->noecho
7872                      , ip->input_handler ? ip->input_handler->local : MY_FALSE
7873                      , MY_FALSE
7874                   );
7875     }
7876 
7877     /* Return the result */
7878     sp = pop_n_elems(num_arg, sp);
7879     push_number(sp, rc);
7880 
7881     return sp;
7882 } /* v_remove_input_to() */
7883 
7884 /*-------------------------------------------------------------------------*/
7885 svalue_t  *
7886 f_input_to_info (svalue_t *sp)
7887 
7888 /* EFUN: input_to_info()
7889  *
7890  *   mixed * input_to_info (object player)
7891  *
7892  * Construct an array of all input_to's pending for this interactive <player>.
7893  * The first entry in the array is the least recently added input_to, the
7894  * last element the most recently added one.
7895  * Every item in the array is itself an array of 2 or more entries:
7896  *  0:   The object (only if the function is a string).
7897  *  1:   The function (string or closure).
7898  *  2..: The argument(s).
7899  */
7900 {
7901     vector_t      *v;
7902     int            num_pending;
7903     input_t       *ih;
7904     interactive_t *ip;
7905 
7906     /* Get the interactive object.
7907      * If there is none, or if it is closing down or doesn't have
7908      * an input_to set, the efun will return the empty array.
7909      */
7910     if (!(O_SET_INTERACTIVE(ip, sp->u.ob))
7911      || ip->closing || ip->input_handler == NULL
7912        )
7913     {
7914         num_pending = 0;
7915     }
7916     else
7917     {
7918         /* Count the number of pending input_tos.
7919          */
7920         for ( num_pending = 0, ih = ip->input_handler
7921             ; ih != NULL
7922             ; ih = ih->next)
7923             if (ih->type == INPUT_TO)
7924                 num_pending++;
7925     }
7926 
7927     /* Allocate the result arrray and fill it in */
7928     v = allocate_array(num_pending);
7929 
7930     if (num_pending > 0)
7931     {
7932         int i;
7933 
7934         for (i = num_pending, ih = ip->input_handler
7935             ; --i >= 0
7936             ; ih = ih->next
7937             )
7938         {
7939             vector_t   *vv;
7940             object_t   *ob;
7941             input_to_t *it;
7942 
7943             if (ih->type != INPUT_TO)
7944             {
7945                 i++;
7946                 continue;
7947             }
7948 
7949             it = (input_to_t*) ih;
7950 
7951             ob = callback_object(&(it->fun));
7952             if (!ob)
7953                 continue;
7954 
7955             /* Get the subarray */
7956 
7957             vv = allocate_array(2 + it->fun.num_arg);
7958 
7959             if (it->fun.is_lambda)
7960             {
7961                 if (it->fun.function.lambda.x.closure_type == CLOSURE_LFUN)
7962                     put_ref_object( vv->item
7963                                   , it->fun.function.lambda.u.lambda->function.lfun.ob
7964                                   , "input_to_info");
7965                 else
7966                     put_ref_object(vv->item, ob, "input_to_info");
7967                 assign_svalue_no_free(&vv->item[1], &it->fun.function.lambda);
7968             }
7969             else
7970             {
7971                 put_ref_object(vv->item, ob, "input_to_info");
7972                 put_ref_string(vv->item + 1, it->fun.function.named.name);
7973             }
7974 
7975             if (it->fun.num_arg > 0)
7976             {
7977                 svalue_t *source, *dest;
7978                 int nargs;
7979 
7980                 nargs = it->fun.num_arg;
7981                 if (nargs > 1)
7982                     source = it->fun.arg.u.lvalue;
7983                 else
7984                     source = &(it->fun.arg);
7985                 dest = &vv->item[2];
7986                 do {
7987                     assign_svalue_no_free(dest++, source++);
7988                 } while (--nargs);
7989             }
7990 
7991             put_array(v->item + i, vv);
7992         }
7993     }
7994 
7995     /* Return the result */
7996     free_svalue(sp);
7997     put_array(sp, v);
7998 
7999     return sp;
8000 } /* f_input_to_info() */
8001 
8002 /*-------------------------------------------------------------------------*/
8003 svalue_t *
8004 f_query_ip_name (svalue_t *sp)
8005 
8006 /* EFUN query_ip_name()
8007  *
8008  *   string query_ip_name(object ob)
8009  *
8010  * Give the ip-name for user the current user or for the optional
8011  * argument ob. An asynchronous process 'erq' is used to find
8012  * out these names in parallel. If there are any failures to find
8013  * the ip-name, then the ip-number is returned instead.
8014  */
8015 
8016 {
8017     return query_ip_name(sp, MY_TRUE);
8018 } /* f_query_ip_name() */
8019 
8020 /*-------------------------------------------------------------------------*/
8021 svalue_t *
8022 f_query_ip_number (svalue_t *sp)
8023 
8024 /* EFUN query_ip_number()
8025  *
8026  *   string query_ip_number(object  ob)
8027  *   string query_ip_number(mixed & ob)
8028  *
8029  * Give the ip-number for the current user or the optional
8030  * argument ob.
8031  *
8032  * If ob is given as reference (and it must be a valid object
8033  * then), it will upon return be set to the struct sockaddr_in of
8034  * the queried object, represented by an array of integers, one
8035  * integer per address byte:
8036  *   ob[0.. 1]: sin_family
8037  *   ob[2.. 3]: sin_port
8038  *   ob[4.. 7]: sin_addr
8039  *   ob[8..15]: undefined.
8040  */
8041 
8042 {
8043     return query_ip_name(sp, MY_FALSE);
8044 } /* f_query_ip_number() */
8045 
8046 /*-------------------------------------------------------------------------*/
8047 svalue_t *
8048 f_query_mud_port (svalue_t *sp)
8049 
8050 /* EFUN: query_mud_port()
8051  *
8052  * Returns the port number the parser uses for user connections.
8053  *
8054  *   int query_mud_port(void)
8055  *
8056  * If no argument is given, the port for this_player() is
8057  * returned. If this_player() is not existing or not interactive,
8058  * the first port number open for connections is returned.
8059  *
8060  *   int query_mud_port(object user)
8061  *   int query_mud_port(int num)
8062  *
8063  * If an user object is given, the port used for its connection
8064  * is returned.
8065  * If a positive number is given, the <num>th port number the
8066  * parser uses for connections is returned (given that there are
8067  * that many ports).
8068  * If -1 is given, the number of ports open for connections is
8069  * returned.
8070  */
8071 
8072 {
8073     object_t *ob;
8074     interactive_t *ip;
8075     struct sockaddr_in addr;
8076     length_t length;
8077 
8078     length = sizeof(addr);
8079 
8080     if (sp->type == T_NUMBER)
8081     {
8082         if (sp->u.number < -1 || sp->u.number >= numports)
8083         {
8084             errorf("Bad arg 1 to query_mud_port(): value %"PRIdPINT" out of range.\n"
8085                  , sp->u.number);
8086             /* NOTREACHED */
8087         }
8088         sp->u.number = sp->u.number < 0 ? numports : port_numbers[sp->u.number];
8089         return sp;
8090     }
8091 
8092     ob = sp->u.ob;
8093     deref_object(ob, "query_ip_port");
8094 
8095     if ( !(O_SET_INTERACTIVE(ip, ob))) {
8096         put_number(sp, port_numbers[0]);
8097         return sp;
8098     }
8099 
8100     getsockname(ip->socket, (struct sockaddr *)&addr, &length);
8101     put_number(sp, ntohs(addr.sin_port));
8102     return sp;
8103 } /* f_query_mud_port() */
8104 
8105 /*-------------------------------------------------------------------------*/
8106 
8107 
8108 static inline void translate_bit(char c, int i, int length, string_t *rc, unsigned int bitno)
8109 /* static helper function to translatin bits to characters in get_charset */
8110 {
8111   if (c & (1 << bitno))
8112     get_txt(rc)[length++] = (char)(i * 8 + bitno);
8113 } /* translate_bit */
8114 
8115 static void
8116 get_charset (svalue_t * sp, p_int mode, char charset[32])
8117 
8118 /* Translate the <charset> into an svalue and store it into <sp>:
8119  *   <mode> == CHARSET_VECTOR: result is a bitvector array
8120  *   <mode> == CHARSET_STRING: result is a string.
8121  */
8122 
8123 {
8124     put_number(sp, 0);
8125     switch (mode)
8126     {
8127     default:
8128         fatal("(get_charset): Illegal mode value %"PRIdPINT"\n", mode);
8129         /* NOTREACHED */
8130         break;
8131 
8132     case CHARSET_VECTOR:
8133       {
8134         vector_t * rc;
8135         int i;
8136 
8137         rc = allocate_uninit_array(32);
8138         if (!rc)
8139         {
8140             outofmemory("result array");
8141             /* NOTREACHED */
8142             break;
8143         }
8144 
8145         for (i = 0; i < 32; i++)
8146             put_number(rc->item+i, (unsigned char)charset[i]);
8147 
8148         put_array(sp, rc);
8149         break;
8150       }
8151 
8152     case CHARSET_STRING:
8153       {
8154         string_t * rc;
8155         int length, i;
8156 
8157         /* Count the number of bits set in the charset */
8158         for (i = length = 0; i < 32; i++)
8159         {
8160             char c = charset[i];
8161             length +=   ((c & 0x80) ? 1 : 0)
8162                       + ((c & 0x40) ? 1 : 0)
8163                       + ((c & 0x20) ? 1 : 0)
8164                       + ((c & 0x10) ? 1 : 0)
8165                       + ((c & 0x08) ? 1 : 0)
8166                       + ((c & 0x04) ? 1 : 0)
8167                       + ((c & 0x02) ? 1 : 0)
8168                       + ((c & 0x01) ? 1 : 0);
8169         }
8170 
8171         rc = alloc_mstring(length);
8172         if (!rc)
8173         {
8174             outofmemory("result string");
8175             /* NOTREACHED */
8176             break;
8177         }
8178 
8179         /* Translate the bits into characters */
8180         for (i = length = 0; i < 32; i++)
8181         {
8182             char c = charset[i];
8183 
8184             translate_bit(c, i, length, rc, 0);
8185             translate_bit(c, i, length, rc, 1);
8186             translate_bit(c, i, length, rc, 2);
8187             translate_bit(c, i, length, rc, 3);
8188             translate_bit(c, i, length, rc, 4);
8189             translate_bit(c, i, length, rc, 5);
8190             translate_bit(c, i, length, rc, 6);
8191             translate_bit(c, i, length, rc, 7);
8192         }
8193 
8194         put_string(sp, rc);
8195         break;
8196       } /* case CHARSET_STRING */
8197     } /* switch(mode) */
8198 } /* get_charset() */
8199 
8200 /*-------------------------------------------------------------------------*/
8201 svalue_t *
8202 f_get_combine_charset (svalue_t *sp)
8203 
8204 /* TEFUN: get_combine_charset()
8205  *
8206  *   mixed get_combine_charset (int mode)
8207  *
8208  * Return the combine charset of the current interactive in the form requested
8209  * by <mode>:
8210  *   <mode> == CHARSET_VECTOR: return as bitvector
8211  *   <mode> == CHARSET_STRING: return as string
8212  *
8213  * The bitvector is interpreted as an array of 8-bit-values and might
8214  * contain up to 32 elements. Character n is "combinable"
8215  * if sizeof(bitvector) > n/8 && bitvector[n/8] & (1 << n%8) .
8216  *
8217  * If there is no current interactive, the function returns 0.
8218  */
8219 
8220 {
8221     p_int mode;
8222     interactive_t *ip;
8223 
8224     mode = sp->u.number;
8225     if (mode != CHARSET_VECTOR && mode != CHARSET_STRING)
8226     {
8227         errorf("Bad arg 1 to get_combine_charset(): %"PRIdPINT", "
8228               "expected CHARSET_VECTOR (%d) or CHARSET_STRING (%d)\n"
8229              , mode, CHARSET_VECTOR, CHARSET_STRING);
8230         /* NOTREACHED */
8231         return sp;
8232     }
8233 
8234     if (current_interactive && O_SET_INTERACTIVE(ip, current_interactive))
8235         get_charset(sp, mode, ip->combine_cset);
8236     else
8237         put_number(sp, 0);
8238 
8239     return sp;
8240 } /* f_get_combine_charset() */
8241 
8242 /*-------------------------------------------------------------------------*/
8243 svalue_t *
8244 f_set_combine_charset (svalue_t *sp)
8245 
8246 /* EFUN: set_combine_charset()
8247  *
8248  *   void set_combine_charset (int* bitvector)
8249  *   void set_combine_charset (string chars)
8250  *   void set_combine_charset (0)
8251  *
8252  * Set the set of characters which can be combined into a single string
8253  * when received en-bloc in charmode from the current interactive user.
8254  * Non-combinable characters and single received characters are returned
8255  * in separate strings as usual. The function must be called with the
8256  * interactive user being the command giver.
8257  *
8258  * The newline '\n' and the NUL character '\0' are always non-combinable.
8259  *
8260  * The charset can be given either directly as a string, or indirectly
8261  * as a bitvector. If the charset is given as the number 0, the default
8262  * charset is re-established.
8263  *
8264  * The bitvector is interpreted as an array of 8-bit-values and might
8265  * contain up to 32 elements. Character n is "combinable"
8266  * if sizeof(bitvector) > n/8 && bitvector[n/8] & (1 << n%8) .
8267  */
8268 
8269 {
8270     mp_int i;
8271     svalue_t *svp;
8272     char *p;
8273     interactive_t *ip;
8274 
8275     i = 0;
8276     if (sp->type == T_POINTER && (i = (mp_int)VEC_SIZE(sp->u.vec)) > 32)
8277     {
8278         errorf("Bad arg 1 to set_combine_charset(): int[] too long (%"PRIdMPINT")\n"
8279              , i);
8280         /* NOTREACHED */
8281         return sp;
8282     }
8283 
8284     if (current_interactive && O_SET_INTERACTIVE(ip, current_interactive))
8285     {
8286         if (sp->type == T_NUMBER)
8287         {
8288             set_default_combine_charset(ip->combine_cset);
8289         }
8290         else if (sp->type == T_STRING)
8291         {
8292             memset(ip->combine_cset, 0, sizeof ip->combine_cset);
8293             for ( i = mstrsize(sp->u.str), p = get_txt(sp->u.str)
8294                 ; i > 0
8295                 ; i--, p++)
8296                 ip->combine_cset[(*p & 0xff) / 8] |= 1 << (*p % 8);
8297         }
8298         else
8299         {
8300             /* i was set in the typecheck above */
8301             for ( svp = sp->u.vec->item, p = ip->combine_cset
8302                 ; --i >= 0
8303                 ; svp++, p++)
8304             {
8305                 if (svp->type == T_NUMBER)
8306                     *p = (char)svp->u.number;
8307             }
8308             memset(p, 0, (size_t)(&ip->combine_cset[sizeof ip->combine_cset] - p));
8309         }
8310 
8311         ip->combine_cset['\n'/8] &= ~(1 << '\n' % 8);
8312         ip->combine_cset['\0'/8] &= ~(1 << '\0' % 8);
8313     }
8314     free_svalue(sp);
8315     sp--;
8316     return sp;
8317 } /* f_set_combine_charset() */
8318 
8319 /*-------------------------------------------------------------------------*/
8320 svalue_t *
8321 f_get_connection_charset (svalue_t *sp)
8322 
8323 /* TEFUN: get_connection_charset()
8324  *
8325  *   mixed get_connection_charset (int mode)
8326  *
8327  * Return the combine charset of the current interactive in the form requested
8328  * by <mode>:
8329  *   <mode> == CHARSET_VECTOR: return as bitvector
8330  *   <mode> == CHARSET_STRING: return as string
8331  *
8332  * Alternatively, the status of the IAC quoting can be returned:
8333  *   <mode> == CHARSET_QUOTE_IAC: return 0 if IACs are not quoted,
8334  *                                return 1 if they are.
8335  *
8336  * The bitvector is interpreted as an array of 8-bit-values and might
8337  * contain up to 32 elements. Character n is "combinable"
8338  * if sizeof(bitvector) > n/8 && bitvector[n/8] & (1 << n%8) .
8339  *
8340  * If there is no current interactive, the function returns 0.
8341  */
8342 
8343 {
8344     p_int mode;
8345     interactive_t *ip;
8346 
8347     mode = sp->u.number;
8348     if (mode != CHARSET_VECTOR && mode != CHARSET_STRING
8349      && mode != CHARSET_QUOTE_IAC)
8350     {
8351         errorf("Bad arg 1 to get_connection_charset(): %"PRIdPINT", "
8352               "expected CHARSET_VECTOR (%d), _STRING (%d), "
8353               "or _QUOTE_IAC (%d)\n"
8354              , mode, CHARSET_VECTOR, CHARSET_STRING, CHARSET_QUOTE_IAC);
8355         /* NOTREACHED */
8356         return sp;
8357     }
8358 
8359     if (current_interactive && O_SET_INTERACTIVE(ip, current_interactive))
8360     {
8361         if (mode == CHARSET_QUOTE_IAC)
8362             put_number(sp, ip->quote_iac != 0);
8363         else
8364             get_charset(sp, mode, ip->charset);
8365     }
8366     else
8367         put_number(sp, 0);
8368 
8369     return sp;
8370 } /* f_get_connection_charset() */
8371 
8372 /*-------------------------------------------------------------------------*/
8373 svalue_t *
8374 f_set_connection_charset (svalue_t *sp)
8375 
8376 /* EFUN: set_connection_charset()
8377  *
8378  *   void set_connection_charset (int* bitvector, int quote_iac)
8379  *   void set_connection_charset (string charset, int quote_iac)
8380  *   void set_connection_charset (0, int quote_iac)
8381  *
8382  * Set the set of characters that can be output to the interactive user
8383  * (this does not apply to binary_message() ). The function must be called
8384  * by the interactive user object itself.
8385  *
8386  * The charset can be given either directly as a string, or indirectly
8387  * as a bitvector. If the charset is given as 0, the default connection
8388  * charset is re-established.
8389  *
8390  * The bitvector is interpreted as an array of 8-bit-values and might
8391  * contain up to 32 elements. Character n is allowed to be output
8392  * if sizeof(bitvector) > n/8 && bitvector[n/8] & (1 << n%8) .
8393  *
8394  * If quote_iac is 0 and char 255 is allowed to be output, IAC
8395  * will be output unmodified.
8396  * If quote_iac is 1 and char 255 is allowed to be output,
8397  * char 255 will be quoted so that it is not interpreted as IAC
8398  * by the telnet protocol.
8399  */
8400 
8401 {
8402     mp_int i;
8403     svalue_t *svp;
8404     char *p;
8405     interactive_t *ip;
8406 
8407     i = 0;
8408     if (sp[-1].type == T_POINTER && (i = (mp_int)VEC_SIZE(sp[-1].u.vec)) > 32)
8409     {
8410         errorf("Bad arg 1 to set_connection_charset(): array too big (%"
8411              PRIdMPINT")\n", i);
8412         /* NOTREACHED */
8413         return sp;
8414     }
8415 
8416     if (O_SET_INTERACTIVE(ip, current_object))
8417     {
8418         if (sp[-1].type == T_NUMBER)
8419         {
8420             set_default_conn_charset(ip->charset);
8421         }
8422         else if (sp[-1].type == T_STRING)
8423         {
8424             memset(ip->charset, 0, sizeof ip->charset);
8425             for ( i = mstrsize((sp-1)->u.str), p = get_txt(sp[-1].u.str)
8426                 ; i > 0
8427                 ; i--, p++)
8428                 ip->charset[(*p & 0xff) / 8] |= 1 << (*p % 8);
8429         }
8430         else
8431         {
8432             /* i was set in the typecheck above */
8433             for ( svp = sp[-1].u.vec->item, p = ip->charset
8434                 ; --i >= 0
8435                 ; svp++, p++)
8436             {
8437                 if (svp->type == T_NUMBER)
8438                     *p = (char)svp->u.number;
8439             }
8440             memset(p, 0, (size_t)(&ip->charset[sizeof ip->charset] - p));
8441         }
8442 
8443         ip->quote_iac = (char)sp->u.number;
8444     }
8445     sp--;
8446     free_svalue(sp);
8447     sp--;
8448     return sp;
8449 } /* f_set_connection_charset() */
8450 
8451 /*-------------------------------------------------------------------------*/
8452 svalue_t *
8453 f_set_prompt (svalue_t *sp)
8454 
8455 /* EFUN set_prompt()
8456  *
8457  *       string set_prompt(mixed prompt, object ob)
8458  *
8459  * Set the prompt given by the first argument for the interactive object
8460  * instead of the default ``> ''. If the second argument is omitted,
8461  * this_player() is used as default. The first arg can be a string or a
8462  * closure. If the <prompt> arg is 0, the prompt is not changed.
8463  * TODO: Remove the acceptance of -1 here.
8464  *
8465  * The result returned is the old prompt.
8466  */
8467 
8468 {
8469     svalue_t *prompt;
8470     interactive_t *ip;
8471 
8472     /* Make sure the object is interactive */
8473     if (!(O_SET_INTERACTIVE(ip, sp->u.ob))
8474      || ip->closing)
8475     {
8476         errorf("Bad arg 2 to set_prompt(): object not interactive.\n");
8477         return sp;
8478     }
8479 
8480     /* Get the address of the prompt svalue */
8481     prompt = &O_GET_INTERACTIVE(sp->u.ob)->prompt;
8482 
8483     free_object_svalue(sp);
8484     sp--;
8485 
8486     if (sp->type == T_STRING || sp->type == T_CLOSURE)
8487     {
8488         if (sp->type == T_CLOSURE && sp->x.closure_type == CLOSURE_UNBOUND_LAMBDA)
8489         {
8490             inter_sp = sp;
8491             errorf("Bad arg 1 for set_prompt(): lambda closure not bound\n");
8492             /* NOTREACHED */
8493         }
8494 
8495         if (sp->type == T_STRING)
8496         {
8497             string_t *str = make_tabled_from(sp->u.str);
8498 
8499             if (!str)
8500             {
8501                 inter_sp = sp;
8502                 errorf("(set_prompt) Out of memory (%zu bytes) for prompt\n"
8503                      , mstrsize(sp->u.str));
8504             }
8505             else
8506             {
8507                 free_mstring(sp->u.str);
8508                 sp->u.str = str;
8509             }
8510         }
8511 
8512         /* Three-way exchange to set the new prompt and put
8513          * the old one onto the stack.
8514          */
8515         sp[1] = *prompt;
8516         *prompt = *sp;
8517         *sp = sp[1];
8518     }
8519     else /* It's a number */
8520     {
8521         if (sp->u.number == 0 || sp->u.number == -1)
8522             assign_svalue(sp, prompt);
8523         else
8524         {
8525             errorf("Bad int arg 1 to set_prompt(): got %"PRIdPINT", expected 0 or -1.\n"
8526                  , sp->u.number);
8527             /* NOTREACHED */
8528             return sp;
8529         }
8530     }
8531 
8532     return sp;
8533 } /* f_set_prompt() */
8534 
8535 /*-------------------------------------------------------------------------*/
8536 svalue_t *
8537 v_snoop (svalue_t *sp, int num_arg)
8538 
8539 /* EFUN snoop()
8540  *
8541  *   object snoop(object snooper)
8542  *   object snoop(object snooper, object snoopee)
8543  *
8544  * Starts a snoop from 'snooper' on 'snoopee', or if 'snoopee' is not
8545  * given, terminates any snoop from 'snooper'.
8546  * On success, 'snoopee' is returned, else 0.
8547  *
8548  * The snoop is checked with the master object for validity.
8549  * It will also fail if the 'snoopee' is being snooped already or
8550  * if a snoop would result in a recursive snoop action.
8551  */
8552 
8553 {
8554     int i;
8555 
8556     if (num_arg == 1)
8557     {
8558         i = set_snoop(sp->u.ob, 0);
8559     }
8560     else
8561     {
8562         i = set_snoop((sp-1)->u.ob, sp->u.ob);
8563         free_svalue(sp--);
8564     }
8565     free_svalue(sp);
8566     put_number(sp, i);
8567 
8568     return sp;
8569 } /* v_snoop() */
8570 
8571 /*-------------------------------------------------------------------------*/
8572 svalue_t *
8573 f_users (svalue_t *sp)
8574 
8575 /* EFUN users()
8576  *
8577  * Return a (possibly empty) vector of all interactive user objects.
8578  */
8579 
8580 {
8581     object_t *ob;
8582     int n, num;
8583     vector_t *ret;
8584     interactive_t **user;
8585     svalue_t *svp;
8586 
8587     /* Count the active users */
8588     num = 0;
8589     user = all_players;
8590     for (n = max_player + 2; --n; user++)
8591     {
8592         if (*user && !((*user)->ob->flags & O_DESTRUCTED))
8593             num++;
8594     }
8595 
8596     /* Get the result array and fill it */
8597 
8598     ret = allocate_array(num);
8599     svp = ret->item;
8600     user = all_players;
8601     for (n = max_player + 2; --n; user++)
8602     {
8603         if (*user && !((ob = (*user)->ob)->flags & O_DESTRUCTED))
8604         {
8605             put_ref_object(svp, ob, "users");
8606             svp++;
8607         }
8608     }
8609 
8610     push_array(sp, ret);
8611 
8612     return sp;
8613 } /* f_users() */
8614 
8615 /*-------------------------------------------------------------------------*/
8616 svalue_t *
8617 f_query_udp_port (svalue_t *sp)
8618 
8619 /* EFUN query_udp_port()
8620  *
8621  *   int query_udp_port(void)
8622  *
8623  * Returns the port number that is used for the inter mud
8624  * protocol.
8625  */
8626 
8627 {
8628     push_number(sp, udp_port);
8629 
8630     return sp;
8631 } /* f_query_udp_port() */
8632 
8633 /*-------------------------------------------------------------------------*/
8634 svalue_t *
8635 f_get_max_commands (svalue_t *sp)
8636 
8637 /* TEFUN: get_max_commands()
8638  *
8639  *   int get_max_commands ()
8640  *   int get_max_commands (object obj)
8641  *
8642  * Return the max number of commands (read: line resp. char inputs) the
8643  * interactive <obj> (default is the current interactive) is allowed to
8644  * execute per second. A negative result means 'unlimited'.
8645  * For non-interactive objects the result is 0.
8646  */
8647 
8648 {
8649     p_int rc;
8650     interactive_t *ip;
8651 
8652     rc = 0;
8653     if (O_SET_INTERACTIVE(ip, sp->u.ob))
8654         rc = ip->maxNumCmds;
8655 
8656     free_svalue(sp);
8657     put_number(sp, rc);
8658 
8659     return sp;
8660 } /* f_get_max_commands() */
8661 
8662 /*-------------------------------------------------------------------------*/
8663 svalue_t *
8664 f_set_max_commands (svalue_t *sp)
8665 
8666 /* TEFUN: set_max_commands()
8667  *
8668  *   void set_max_commands (int num)
8669  *   void set_max_commands (int num, object obj)
8670  *
8671  * Set the max number of commands (read: line resp. char inputs) the
8672  * interactive <obj> (default is the current interactive) is allowed to
8673  * execute per second to <num>. A negative result means 'unlimited'.
8674  * For non-interactive objects the function raises an error.
8675  *
8676  * The function raises a privilege_violation ("set_max_commands", obj, num).
8677  * If the privilege is denied, the call is ignored.
8678  */
8679 
8680 {
8681     p_int num;
8682     interactive_t *ip;
8683 
8684     num = sp[-1].u.number;
8685     if (num < 0)
8686         num = -1;
8687 
8688     if (!O_SET_INTERACTIVE(ip, sp->u.ob))
8689     {
8690         errorf("Bad arg 2 to set_max_commands(): Object is not interactive.\n");
8691         /* NOTREACHED */
8692     }
8693 
8694     if (privilege_violation4(STR_SET_MAX_CMDS, sp->u.ob, NULL, num, sp))
8695         ip->maxNumCmds = num;
8696 
8697     free_svalue(sp--);
8698     free_svalue(sp--);
8699     return sp;
8700 } /* f_set_max_commands() */
8701 
8702 /*-------------------------------------------------------------------------*/
8703 svalue_t *
8704 f_enable_telnet (svalue_t *sp)
8705 
8706 /* TEFUN: enable_telnet()
8707  *
8708  *   int enable_telnet (int num)
8709  *   int enable_telnet (int num, object obj)
8710  *
8711  * Enable or disable the telnet machine for the interactive object <obj>.
8712  * Return the previous state of the telnet machine as result.
8713  *
8714  * <num> > 0 : enable telnet machine (default)
8715  *       = 0 : disable telnet machine
8716  *       < 0 : just query the current state of the telnet machine.
8717  * <obj> : the interactive object, default is the current interactive.
8718  *         For non-interactive objects the function raises an error.
8719  *
8720  * The function raises a privilege_violation ("enable_telnet", obj, num)
8721  * if <num> is >= 0. If the privilege is denied, the call is ignored.
8722  *
8723  * WARNING: Careless use of this efun can cause great confusion for both
8724  * driver and clients!
8725  */
8726 
8727 {
8728     p_int num;
8729     p_int rc;
8730     interactive_t *ip;
8731 
8732     num = sp[-1].u.number;
8733     if (num < 0)
8734         num = -1;
8735 
8736     if (!O_SET_INTERACTIVE(ip, sp->u.ob))
8737     {
8738         errorf("Bad arg 2 to enable_telnet(): Object '%s' is not interactive.\n"
8739              , get_txt(sp->u.ob->name)
8740              );
8741         /* NOTREACHED */
8742         return sp; /* flow control hint */
8743     }
8744 
8745     rc = (ip->tn_enabled != 0);
8746     if (num >= 0
8747      && privilege_violation4(STR_ENABLE_TELNET, sp->u.ob, NULL, num, sp))
8748         ip->tn_enabled = (num != 0);
8749 
8750     free_svalue(sp--);
8751     free_svalue(sp);
8752 
8753     put_number(sp, rc);
8754     return sp;
8755 } /* f_enable_telnet() */
8756 
8757 /*-------------------------------------------------------------------------*/
8758 void
8759 check_for_out_connections (void)
8760 
8761 /* Check the list of pending outgoing connections if the connections
8762  * are still pending.
8763  * Activate those who succeeded, remove those which failed.
8764  *
8765  * To be called regularily from the backend.
8766  */
8767 
8768 {
8769     int i, ret;
8770     object_t *user;
8771 
8772     for (i = 0; i < MAX_OUTCONN; i++)
8773     {
8774         if (outconn[i].status == ocNotUsed)
8775             continue;
8776 
8777         if (!outconn[i].curr_obj) /* shouldn't happen */
8778         {
8779             socket_close(outconn[i].socket);
8780             outconn[i].status = ocNotUsed;
8781             continue;
8782         }
8783 
8784         if (outconn[i].status == ocLoggingOn)
8785         {
8786             /* LPC logon threw an error - clean up */
8787             debug_message("%s Error in net_connect(): logon "
8788                           "object '%s' threw an error.\n"
8789                          , time_stamp()
8790                          , outconn[i].curr_obj
8791                            ? get_txt(outconn[i].curr_obj->name)
8792                            : "<null>"
8793                          );
8794 
8795             outconn[i].status = ocNotUsed;
8796             if (outconn[i].curr_obj)
8797             {
8798                 if (O_IS_INTERACTIVE(outconn[i].curr_obj))
8799                     remove_interactive(outconn[i].curr_obj, MY_FALSE);
8800                 free_object(outconn[i].curr_obj, "net_connect");
8801             }
8802             socket_close(outconn[i].socket);
8803             continue;
8804         }
8805 
8806         if (outconn[i].curr_obj && (outconn[i].curr_obj->flags & O_DESTRUCTED))
8807         {
8808             socket_close(outconn[i].socket);
8809             free_object(outconn[i].curr_obj, "net_connect");
8810             outconn[i].status = ocNotUsed;
8811             continue;
8812         }
8813 
8814         ret = connect(outconn[i].socket, (struct sockaddr*) &outconn[i].target
8815                      , sizeof(outconn[i].target));
8816         if (ret == -1)
8817         {
8818             switch(errno)
8819             {
8820             case EALREADY: /* still trying */
8821                 continue;
8822             case EISCONN: /* we are connected! */
8823                 break;
8824             default:
8825                 /* Error with connection, call logon() with the failure flag
8826                  */
8827                 outconn[i].status = ocLoggingOn;
8828                 push_number(inter_sp, -1);
8829                 logon_object(outconn[i].curr_obj);
8830 
8831                 outconn[i].status = ocNotUsed;
8832                 free_object(outconn[i].curr_obj, "net_connect");
8833                 socket_close(outconn[i].socket);
8834 
8835                 continue;
8836             }
8837         }
8838 
8839         /* connection successful */
8840         outconn[i].status = ocLoggingOn;
8841 
8842         user = command_giver;
8843         new_player( outconn[i].curr_obj, outconn[i].socket
8844                   , &outconn[i].target, sizeof(outconn[i].target), 0);
8845         command_giver = user;
8846 
8847         free_object(outconn[i].curr_obj, "net_connect");
8848         outconn[i].status = ocNotUsed;
8849     }
8850 } /* check_for_out_connections() */
8851 
8852 /*-------------------------------------------------------------------------*/
8853 svalue_t *
8854 f_net_connect (svalue_t *sp)
8855 
8856 /* EFUN net_connect()
8857  *
8858  *   int net_connect(string host, int port)
8859  *
8860  * Open a non-blocking TCP network connection to <host> and <port>.
8861  * On success, the connection is bound to the current object and the
8862  * lfun logon() is called in the object.
8863  *
8864  * If the connection can't be established immediately, the efun returns
8865  * 'success' and the driver will check in the background for the progress
8866  * of the connection. When it is established, logon() will be called in
8867  * the object. If the connection fails, logon(-1) will be called in the
8868  * object.
8869  *
8870  * The efun raises a privilege violation ("net_connect", host, port).
8871  *
8872  * Return 0 on success, and a Unix ERRNO on failure.
8873  */
8874 
8875 {
8876     char * host;
8877     int    port;
8878     int    rc;
8879 
8880     /* get the arguments */
8881 
8882     host = get_txt(sp[-1].u.str);
8883     port = sp->u.number;
8884 
8885     if (!privilege_violation4(STR_NET_CONNECT, NULL, sp[-1].u.str, port, sp))
8886     {
8887         sp = pop_n_elems(2, sp);
8888         push_number(sp, -1);
8889         return sp;
8890     }
8891 
8892     /* Try the connection */
8893     rc = 0;
8894     do{
8895         int d, n, ret;
8896         object_t *user;
8897         struct sockaddr_in target;
8898 
8899 #ifndef USE_IPV6
8900 
8901         struct hostent *h;
8902 
8903 #endif
8904 
8905         /* Find a place to store the pending connection,
8906          * store the index in n
8907          */
8908         Bool stored = MY_FALSE;
8909         for (n = 0; n < MAX_OUTCONN; n++)
8910         {
8911             if (outconn[n].status == ocNotUsed)
8912             {
8913                 stored = MY_TRUE;
8914                 break;
8915             }
8916         }
8917 
8918         if (!stored)
8919         {
8920             rc = EMFILE;
8921             break;
8922         }
8923 
8924 #ifndef USE_IPV6
8925 
8926         /* Attempt the connection */
8927 
8928         target.sin_port = htons(port);
8929         /* TODO: Uh-oh, blocking DNS in the execution thread.
8930          * TODO:: Better would be to start an ERQ lookup and fill in the
8931          * TODO:: data in the background.
8932          */
8933         h = gethostbyname(host);
8934         target.sin_addr.s_addr = h ? ** (uint32 **) (h -> h_addr_list)
8935                                    : inet_addr(host);
8936         if (!target.sin_addr.s_addr)
8937         {
8938             rc = -1;
8939             break;
8940         }
8941 
8942         target.sin_family = h ? h -> h_addrtype : AF_INET;
8943         d = socket (target.sin_family, SOCK_STREAM, 0);
8944         if (d == -1) {
8945             perror ("socket");
8946             rc = errno;
8947             break;
8948         }
8949 
8950         set_socket_nonblocking(d);
8951 
8952         /* On multihomed machines it is important to bind the socket to
8953          * the proper IP address.
8954          */
8955         ret = bind(d, (struct sockaddr *) &host_ip_addr_template, sizeof(host_ip_addr_template));
8956         if (ret == -1) {
8957             perror("bind during net_connect");
8958             rc = errno;
8959             break;
8960         }
8961 
8962         ret = connect(d, (struct sockaddr *) &target, sizeof(target));
8963 #else
8964         d = ret = open_ipv6_conn(host, port, &target);
8965 #endif
8966         if (ret == -1 && errno != EINPROGRESS)
8967         {
8968             /* error with connection */
8969             perror("net_connect");
8970             socket_close(d);
8971             rc = errno;
8972             break;
8973         }
8974 
8975         rc = 0;
8976 
8977         /* Store the connection in the outconn[] table even if
8978          * we can complete it immediately. For the reason see below.
8979          */
8980         outconn[n].socket = d;
8981         outconn[n].target = target;
8982         outconn[n].curr_obj = ref_object(current_object, "net_conect");
8983 
8984         if (errno == EINPROGRESS)
8985         {
8986             /* Can't complete right now */
8987             outconn[n].status = ocUsed;
8988             break;
8989         }
8990 
8991         /* Attempt the logon. By setting the outconn[].status to
8992          * ocLoggingOn, any subsequent call to check_for_out_connections()
8993          * will clean up for us.
8994          */
8995         outconn[n].status = ocLoggingOn;
8996 
8997         user = command_giver;
8998         inter_sp = sp;
8999         new_player(current_object, d, &target, sizeof(target), 0);
9000         command_giver = user;
9001 
9002         /* All done - clean up */
9003         outconn[n].status = ocNotUsed;
9004         free_object(outconn[n].curr_obj, "net_connect");
9005     }while(0);
9006 
9007     /* Return the result */
9008     sp = pop_n_elems(2, sp);
9009     push_number(sp, rc);
9010 
9011     return sp;
9012 } /* f_net_connect() */
9013 
9014 /*-------------------------------------------------------------------------*/
9015 svalue_t *
9016 f_configure_interactive (svalue_t *sp)
9017 
9018 /* EFUN configure_interactive()
9019  *
9020  *   void configure_interactive(object ob, int what, mixed data)
9021  *
9022  * Sets the option <what> to the value <data> on the interactive <ob>
9023  * or the default for all interactives if <ob> is 0.
9024  *
9025  * <what> == IC_MAX_WRITE_BUFFER_SIZE
9026  *
9027  * If the first argument <ob> is not this_object(), the privilege violation
9028  * ("configure_interactive", this_object(), ob, what, data) occurs.
9029  */
9030 
9031 {
9032     object_t *ob;
9033     interactive_t *ip;
9034 
9035     if (sp[-2].type == T_OBJECT)
9036     {
9037         ob = sp[-2].u.ob;
9038 
9039         if (!O_SET_INTERACTIVE(ip, ob))
9040         {
9041             errorf("Bad arg 1 to configure_interactive(): "
9042                    "Object '%s' is not interactive.\n"
9043                  , get_txt(ob->name)
9044                  );
9045             return sp; /* NOTREACHED */
9046         }
9047     }
9048     else
9049     {
9050         ob = NULL;
9051         ip = NULL;
9052     }
9053 
9054     if (ob != current_object
9055      && !privilege_violation_n(STR_CONFIGURE_INTERACTIVE, ob, sp, 2))
9056     {
9057         sp = pop_n_elems(3, sp);
9058         return sp;
9059     }
9060 
9061     switch(sp[-1].u.number)
9062     {
9063     default:
9064         errorf("Illegal value %"PRIdPINT" for configure_interactive().\n", sp[-1].u.number);
9065         return sp; /* NOTREACHED */
9066 
9067     case IC_MAX_WRITE_BUFFER_SIZE:
9068         {
9069             int max;
9070 
9071             if (sp->type != T_NUMBER)
9072                 efun_exp_arg_error(3, TF_NUMBER, sp->type, sp);
9073 
9074             max = sp->u.number;
9075             if (max < 0)
9076                 max = -1;
9077 
9078             if (!ip)
9079                 write_buffer_max_size = max;
9080             else
9081                 ip->write_max_size = max;
9082             break;
9083         }
9084     }
9085 
9086     sp = pop_n_elems(3, sp);
9087     return sp;
9088 } /* f_configure_interactive() */
9089 
9090 /***************************************************************************/
9091