Author: Run <carlo@alinoe.com>
[ircu2.10.12-pk.git] / ircd / s_bsd.c
1 /*
2  * IRC - Internet Relay Chat, ircd/s_bsd.c
3  * Copyright (C) 1990 Jarkko Oikarinen and
4  *                    University of Oulu, Computing Center
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 1, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20
21 #include "sys.h"
22 #include <stdlib.h>
23 #include <sys/socket.h>
24 #if HAVE_SYS_FILE_H
25 #include <sys/file.h>
26 #endif
27 #if HAVE_SYS_IOCTL_H
28 #include <sys/ioctl.h>
29 #endif
30 #ifdef SOL2
31 #include <sys/filio.h>
32 #endif
33 #ifdef UNIXPORT
34 #include <sys/un.h>
35 #endif
36 #include <stdio.h>
37 #ifdef USE_POLL
38 #ifndef HAVE_POLL_H
39 #undef USE_POLL
40 #else /* HAVE_POLL_H */
41 #ifdef HAVE_STROPTS_H
42 #include <stropts.h>
43 #endif
44 #include <poll.h>
45 #endif /* HAVE_POLL_H */
46 #endif /* USE_POLL */
47 #include <signal.h>
48 #if HAVE_FCNTL_H
49 #include <fcntl.h>
50 #endif
51 #if HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54 #include <sys/stat.h>
55 #include <utmp.h>
56 #include <sys/resource.h>
57 #ifdef USE_SYSLOG
58 #include <syslog.h>
59 #endif
60 #include <sys/utsname.h>
61 #include <netinet/in.h>
62 #include <arpa/inet.h>
63 #include <arpa/nameser.h>
64 #include <resolv.h>
65 #include "h.h"
66 #include "res.h"
67 #include "struct.h"
68 #include "s_bsd.h"
69 #include "s_serv.h"
70 #include "numeric.h"
71 #include "send.h"
72 #include "s_conf.h"
73 #include "s_misc.h"
74 #include "s_bsd.h"
75 #include "hash.h"
76 #include "s_err.h"
77 #include "ircd.h"
78 #include "support.h"
79 #include "s_auth.h"
80 #include "class.h"
81 #include "packet.h"
82 #include "s_ping.h"
83 #include "channel.h"
84 #include "version.h"
85 #include "parse.h"
86 #include "common.h"
87 #include "bsd.h"
88 #include "numnicks.h"
89 #include "s_user.h"
90 #include "sprintf_irc.h"
91 #include "querycmds.h"
92 #include "IPcheck.h"
93
94 RCSTAG_CC("$Id$");
95
96 #ifndef IN_LOOPBACKNET
97 #define IN_LOOPBACKNET  0x7f
98 #endif
99
100 aClient *loc_clients[MAXCONNECTIONS];
101 int highest_fd = 0, udpfd = -1, resfd = -1;
102 unsigned int readcalls = 0;
103 static struct sockaddr_in mysk;
104 static void polludp();
105
106 static struct sockaddr *connect_inet(aConfItem *, aClient *, int *);
107 static int completed_connection(aClient *);
108 static int check_init(aClient *, char *);
109 static void do_dns_async(), set_sock_opts(int, aClient *);
110 #ifdef  UNIXPORT
111 static struct sockaddr *connect_unix(aConfItem *, aClient *, int *);
112 static void add_unixconnection(aClient *, int);
113 static char unixpath[256];
114 #endif
115 static char readbuf[8192];
116 #ifdef USE_POLL
117 static struct pollfd poll_fds[MAXCONNECTIONS + 1];
118 static aClient *poll_cptr[MAXCONNECTIONS + 1];
119 #endif /* USE_POLL */
120 struct sockaddr_in vserv;       /* Default address/interface to bind listen sockets to.
121                                    This is set with the -w commandline option OR whatever
122                                    the name in the M: line resolves to OR INADDR_ANY. */
123 struct sockaddr_in cserv;       /* Default address/interface to bind connecting sockets to.
124                                    This is set with the -w commandline option OR whatever
125                                    the name in the M: line resolves to OR the first
126                                    interface specified in the ircd.conf file for the
127                                    server port. */
128 static int running_in_background;
129
130 #ifdef GODMODE
131 #ifndef NOFLOODCONTROL
132 #define NOFLOODCONTROL
133 #endif
134 #endif
135
136 /*
137  * Try and find the correct name to use with getrlimit() for setting the max.
138  * number of files allowed to be open by this process.
139  */
140 #ifdef RLIMIT_FDMAX
141 #define RLIMIT_FD_MAX   RLIMIT_FDMAX
142 #else
143 #ifdef RLIMIT_NOFILE
144 #define RLIMIT_FD_MAX RLIMIT_NOFILE
145 #else
146 #ifdef RLIMIT_OPEN_MAX
147 #define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
148 #else
149 #undef RLIMIT_FD_MAX
150 #endif
151 #endif
152 #endif
153
154 #if !defined(USE_POLL)
155 #if FD_SETSIZE < (MAXCONNECTIONS + 4)
156 /*
157  * Sanity check
158  *
159  * All operating systems work when MAXCONNECTIONS <= 252.
160  * Most operating systems work when MAXCONNECTIONS <= 1020 and FD_SETSIZE is
161  *   updated correctly in the system headers (on BSD systems our sys.h has
162  *   defined FD_SETSIZE to MAXCONNECTIONS+4 before including the system's headers 
163  *   but sys/types.h might have abruptly redefined it so the check is still 
164  *   done), you might already need to recompile your kernel.
165  * For larger FD_SETSIZE your milage may vary (kernel patches may be needed).
166  * The check is _NOT_ done if we will not use FD_SETS at all (USE_POLL)
167  */
168 #error "FD_SETSIZE is too small or MAXCONNECTIONS too large."
169 #endif
170 #endif
171
172 /*
173  * Cannot use perror() within daemon. stderr is closed in
174  * ircd and cannot be used. And, worse yet, it might have
175  * been reassigned to a normal connection...
176  */
177
178 /*
179  * report_error
180  *
181  * This a replacement for perror(). Record error to log and
182  * also send a copy to all *LOCAL* opers online.
183  *
184  * text    is a *format* string for outputting error. It must
185  *         contain only two '%s', the first will be replaced
186  *         by the sockhost from the cptr, and the latter will
187  *         be taken from sys_errlist[errno].
188  *
189  * cptr    if not NULL, is the *LOCAL* client associated with
190  *         the error.
191  */
192 void report_error(char *text, aClient *cptr)
193 {
194   Reg1 int errtmp = errno;      /* debug may change 'errno' */
195   Reg2 char *host;
196 #if defined(SO_ERROR) && !defined(SOL2)
197   int err;
198   size_t len = sizeof(err);
199 #endif
200
201   host = (cptr) ? get_client_name(cptr, FALSE) : "";
202
203   Debug((DEBUG_ERROR, text, host, strerror(errtmp)));
204
205   /*
206    * Get the *real* error from the socket (well try to anyway..).
207    * This may only work when SO_DEBUG is enabled but its worth the
208    * gamble anyway.
209    */
210 #if defined(SO_ERROR) && !defined(SOL2)
211   if (cptr && !IsMe(cptr) && cptr->fd >= 0)
212     if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
213       if (err)
214         errtmp = err;
215 #endif
216   sendto_ops(text, host, strerror(errtmp));
217 #ifdef USE_SYSLOG
218   syslog(LOG_WARNING, text, host, strerror(errtmp));
219 #endif
220   if (!running_in_background)
221   {
222     fprintf(stderr, text, host, strerror(errtmp));
223     fprintf(stderr, "\n");
224     fflush(stderr);
225   }
226   return;
227 }
228
229 /*
230  * inetport
231  *
232  * Create a socket in the AF_INET domain, bind it to the port given in
233  * 'port' and listen to it.  Connections are accepted to this socket
234  * depending on the IP# mask given by 'name'.  Returns the fd of the
235  * socket created or -1 on error.
236  */
237 int inetport(aClient *cptr, char *name, char *bind_addr, unsigned short int port)
238 {
239   unsigned short int sin_port;
240   int ad[4], opt;
241   char ipname[20];
242
243 #ifdef TESTNET
244     sin_port = htons(port + 10000);
245 #else
246     sin_port = htons(port);
247 #endif
248
249   ad[0] = ad[1] = ad[2] = ad[3] = 0;
250
251   /*
252    * do it this way because building ip# from separate values for each
253    * byte requires endian knowledge or some nasty messing. Also means
254    * easy conversion of "*" to 0.0.0.0 or 134.* to 134.0.0.0 :-)
255    */
256   sscanf(name, "%d.%d.%d.%d", &ad[0], &ad[1], &ad[2], &ad[3]);
257   sprintf_irc(ipname, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
258
259   if (cptr != &me)
260   {
261     sprintf(cptr->sockhost, "%-.42s.%u", name, port);
262     strcpy(cptr->name, me.name);
263   }
264   /*
265    * At first, open a new socket
266    */
267   if (cptr->fd == -1)
268   {
269     alarm(2);
270     cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
271     alarm(0);
272     if (cptr->fd < 0 && errno == EAGAIN)
273     {
274       sendto_ops("opening stream socket %s: No more sockets",
275           get_client_name(cptr, TRUE));
276       return -1;
277     }
278   }
279   if (cptr->fd < 0)
280   {
281     report_error("opening stream socket %s: %s", cptr);
282     return -1;
283   }
284   else if (cptr->fd >= MAXCLIENTS)
285   {
286     sendto_ops("No more connections allowed (%s)", cptr->name);
287     close(cptr->fd);
288     return -1;
289   }
290
291   opt = 1;
292   setsockopt(cptr->fd, SOL_SOCKET, SO_REUSEADDR, (OPT_TYPE *)&opt, sizeof(opt));
293
294   /*
295    * Bind a port to listen for new connections if port is non-null,
296    * else assume it is already open and try get something from it.
297    */
298   if (port)
299   {
300     struct sockaddr_in bindaddr;
301     memset(&bindaddr, 0, sizeof(struct sockaddr_in));
302     if (*bind_addr == '*' && bind_addr[1] == 0)
303       bindaddr.sin_addr.s_addr = htonl(INADDR_ANY);     /* Bind to all interfaces */
304     else if (*bind_addr)
305     {
306       bindaddr.sin_addr.s_addr = inet_addr(bind_addr);  /* Use name from P: line */
307       /* If server port and bind_addr isn't localhost: */
308       if (port == portnum && strcmp("127.0.0.1", bind_addr))
309         cserv.sin_addr.s_addr = bindaddr.sin_addr.s_addr;       /* Initialize /connect port */
310     }
311     else
312       bindaddr.sin_addr = vserv.sin_addr;               /* Default */
313     bindaddr.sin_family = AF_INET;
314     bindaddr.sin_port = sin_port;
315     if (bind(cptr->fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
316     {
317       report_error("binding stream socket %s: %s", cptr);
318       close(cptr->fd);
319       return -1;
320     }
321   }
322
323   if (cptr == &me)              /* KLUDGE to get it work... */
324   {
325     char buf[1024];
326     sprintf_irc(buf, rpl_str(RPL_MYPORTIS), me.name, "*", port);
327     write(1, buf, strlen(buf));
328   }
329   if (cptr->fd > highest_fd)
330     highest_fd = cptr->fd;
331   cptr->ip.s_addr = inet_addr(ipname);
332   cptr->port = port;
333   listen(cptr->fd, 128);        /* Use listen port backlog of 128 */
334   loc_clients[cptr->fd] = cptr;
335
336   return 0;
337 }
338
339 #ifdef  UNIXPORT
340 /*
341  * unixport
342  *
343  * Create a socket and bind it to a filename which is comprised of the path
344  * (directory where file is placed) and port (actual filename created).
345  * Set directory permissions as rwxr-xr-x so other users can connect to the
346  * file which is 'forced' to rwxrwxrwx (different OS's have different need of
347  * modes so users can connect to the socket).
348  */
349 int unixport(aClient *cptr, char *path, unsigned short int port)
350 {
351   struct sockaddr_un un;
352
353   alarm(2);
354   cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
355   alarm(0);
356   if (cptr->fd == -1 && errno == EAGAIN)
357   {
358     sendto_ops("error opening unix domain socket %s: No more sockets",
359         get_client_name(cptr, TRUE));
360     return -1;
361   }
362   if (cptr->fd == -1)
363   {
364     report_error("error opening unix domain socket %s: %s", cptr);
365     return -1;
366   }
367   else if (cptr->fd >= MAXCLIENTS)
368   {
369     sendto_ops("No more connections allowed (%s)", cptr->name);
370     close(cptr->fd);
371     cptr->fd = -1;
372     return -1;
373   }
374
375   un.sun_family = AF_UNIX;
376 #if HAVE_MKDIR
377   mkdir(path, 0755);
378 #else
379   if (chmod(path, 0755) == -1)
380   {
381     sendto_ops("error 'chmod 0755 %s': %s", path, strerror(errno));
382 #ifdef USE_SYSLOG
383     syslog(LOG_WARNING, "error 'chmod 0755 %s': %s", path, strerror(errno));
384 #endif
385     close(cptr->fd);
386     cptr->fd = -1;
387     return -1;
388   }
389 #endif
390   sprintf_irc(unixpath, "%s/%u", path, port);
391   unlink(unixpath);
392   strncpy(un.sun_path, unixpath, sizeof(un.sun_path) - 1);
393   un.sun_path[sizeof(un.sun_path) - 1] = 0;
394   strcpy(cptr->name, me.name);
395   errno = 0;
396   get_sockhost(cptr, unixpath);
397
398   if (bind(cptr->fd, (struct sockaddr *)&un, strlen(unixpath) + 2) == -1)
399   {
400     report_error("error binding unix socket %s: %s", cptr);
401     close(cptr->fd);
402     return -1;
403   }
404   if (cptr->fd > highest_fd)
405     highest_fd = cptr->fd;
406   listen(cptr->fd, 5);
407   chmod(unixpath, 0777);
408   cptr->flags |= FLAGS_UNIX;
409   cptr->port = 0;
410   loc_clients[cptr->fd] = cptr;
411
412   return 0;
413 }
414 #endif
415
416 /*
417  * add_listener
418  *
419  * Create a new client which is essentially the stub like 'me' to be used
420  * for a socket that is passive (listen'ing for connections to be accepted).
421  */
422 int add_listener(aConfItem *aconf)
423 {
424   aClient *cptr;
425
426   cptr = make_client(NULL, STAT_ME);
427   cptr->flags = FLAGS_LISTEN;
428   cptr->acpt = cptr;
429   cptr->from = cptr;
430   strncpy(cptr->name, aconf->host, sizeof(cptr->name) - 1);
431   cptr->name[sizeof(cptr->name) - 1] = 0;
432 #ifdef  UNIXPORT
433   if (*aconf->host == '/')
434   {
435     if (unixport(cptr, aconf->host, aconf->port))
436       cptr->fd = -2;
437   }
438   else
439 #endif
440   if (inetport(cptr, aconf->host, aconf->passwd, aconf->port))
441     cptr->fd = -2;
442
443   if (cptr->fd >= 0)
444   {
445     cptr->confs = make_link();
446     cptr->confs->next = NULL;
447     cptr->confs->value.aconf = aconf;
448     set_non_blocking(cptr->fd, cptr);
449     if (aconf->port == portnum)
450       have_server_port = 1;
451   }
452   else
453     free_client(cptr);
454   return 0;
455 }
456
457 /*
458  * close_listeners
459  *
460  * Close and free all clients which are marked as having their socket open
461  * and in a state where they can accept connections.  Unix sockets have
462  * the path to the socket unlinked for cleanliness.
463  */
464 void close_listeners(void)
465 {
466   Reg1 aClient *cptr;
467   Reg2 int i;
468   Reg3 aConfItem *aconf;
469
470   /*
471    * close all 'extra' listening ports we have and unlink the file
472    * name if it was a unix socket.
473    */
474   for (i = highest_fd; i >= 0; i--)
475   {
476     if (!(cptr = loc_clients[i]))
477       continue;
478     if (!IsMe(cptr) || cptr == &me || !IsListening(cptr))
479       continue;
480     aconf = cptr->confs->value.aconf;
481
482     if (IsIllegal(aconf) && aconf->clients == 0)
483     {
484 #ifdef  UNIXPORT
485       if (IsUnixSocket(cptr))
486       {
487         sprintf_irc(unixpath, "%s/%u", aconf->host, aconf->port);
488         unlink(unixpath);
489       }
490 #endif
491       close_connection(cptr);
492     }
493   }
494 }
495
496 /*
497  * init_sys
498  */
499 void init_sys(void)
500 {
501   Reg1 int fd;
502 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX)
503   struct rlimit limit;
504
505   if (!getrlimit(RLIMIT_FD_MAX, &limit))
506   {
507 #ifdef  pyr
508     if (limit.rlim_cur < MAXCONNECTIONS)
509 #else
510     if (limit.rlim_max < MAXCONNECTIONS)
511 #endif
512     {
513       fprintf(stderr, "ircd fd table too big\n");
514       fprintf(stderr, "Hard Limit: " LIMIT_FMT " IRC max: %d\n",
515 #ifdef pyr
516           limit.rlim_cur,
517 #else
518           limit.rlim_max,
519 #endif
520           (int)MAXCONNECTIONS);
521       fprintf(stderr, "Fix MAXCONNECTIONS\n");
522       exit(-1);
523     }
524 #ifndef pyr
525     limit.rlim_cur = limit.rlim_max;    /* make soft limit the max */
526     if (setrlimit(RLIMIT_FD_MAX, &limit) == -1)
527     {
528       fprintf(stderr, "error setting max fd's to " LIMIT_FMT "\n",
529           limit.rlim_cur);
530       exit(-1);
531     }
532 #endif
533   }
534 #endif /* defined(HAVE_SETRLIMIT) && defined(RLIMIT_FD_MAX) */
535 #ifdef DEBUGMODE
536   if (1)
537   {
538     static char logbuf[BUFSIZ];
539 #if SETVBUF_REVERSED
540     setvbuf(stderr, _IOLBF, logbuf, sizeof(logbuf));
541 #else
542     setvbuf(stderr, logbuf, _IOLBF, sizeof(logbuf));
543 #endif
544   }
545 #endif
546
547   for (fd = 3; fd < MAXCONNECTIONS; fd++)
548   {
549     close(fd);
550     loc_clients[fd] = NULL;
551   }
552   loc_clients[1] = NULL;
553   close(1);
554
555   if (bootopt & BOOT_TTY)       /* debugging is going to a tty */
556     goto init_dgram;
557   if (!(bootopt & BOOT_DEBUG))
558     close(2);
559
560   if (((bootopt & BOOT_CONSOLE) || isatty(0)) &&
561       !(bootopt & BOOT_INETD))
562   {
563     if (fork())
564       exit(0);
565     running_in_background = 1;
566 #ifdef TIOCNOTTY
567     if ((fd = open("/dev/tty", O_RDWR)) >= 0)
568     {
569       ioctl(fd, TIOCNOTTY, (char *)NULL);
570       close(fd);
571     }
572 #endif
573 #if defined(HPUX) || defined(SOL2) || defined(_SEQUENT_) || \
574     defined(_POSIX_SOURCE) || defined(SVR4)
575     setsid();
576 #else
577     setpgid(0, 0);
578 #endif
579     close(0);                   /* fd 0 opened by inetd */
580     loc_clients[0] = NULL;
581   }
582 init_dgram:
583   resfd = init_resolver();
584
585   return;
586 }
587
588 void write_pidfile(void)
589 {
590 #ifdef PPATH
591   int fd;
592   char buff[20];
593   if ((fd = open(PPATH, O_CREAT | O_WRONLY, 0600)) >= 0)
594   {
595     memset(buff, 0, sizeof(buff));
596     sprintf(buff, "%5d\n", (int)getpid());
597     if (write(fd, buff, strlen(buff)) == -1)
598       Debug((DEBUG_NOTICE, "Error writing to pid file %s", PPATH));
599     close(fd);
600     return;
601   }
602 #ifdef  DEBUGMODE
603   else
604     Debug((DEBUG_NOTICE, "Error opening pid file \"%s\": %s",
605         PPATH, strerror(errno)));
606 #endif
607 #endif
608 }
609
610 /*
611  * Initialize the various name strings used to store hostnames. This is set
612  * from either the server's sockhost (if client fd is a tty or localhost)
613  * or from the ip# converted into a string. 0 = success, -1 = fail.
614  */
615 static int check_init(aClient *cptr, char *sockn)
616 {
617   struct sockaddr_in sk;
618   size_t len = sizeof(struct sockaddr_in);
619   sockn[HOSTLEN] = 0;
620
621 #ifdef  UNIXPORT
622   if (IsUnixSocket(cptr))
623   {
624     strncpy(sockn, cptr->acpt->sockhost, HOSTLEN);
625     get_sockhost(cptr, sockn);
626     return 0;
627   }
628 #endif
629
630   /* If descriptor is a tty, special checking... */
631   if (isatty(cptr->fd))
632   {
633     strncpy(sockn, me.sockhost, HOSTLEN);
634     memset(&sk, 0, sizeof(struct sockaddr_in));
635   }
636   else if (getpeername(cptr->fd, (struct sockaddr *)&sk, &len) == -1)
637   {
638     report_error("connect failure: %s %s", cptr);
639     return -1;
640   }
641   strcpy(sockn, inetntoa(sk.sin_addr));
642   if (inet_netof(sk.sin_addr) == IN_LOOPBACKNET)
643   {
644     cptr->hostp = NULL;
645     strncpy(sockn, me.sockhost, HOSTLEN);
646   }
647   memcpy(&cptr->ip, &sk.sin_addr, sizeof(struct in_addr));
648 #ifdef TESTNET
649   cptr->port = ntohs(sk.sin_port) - 10000;
650 #else
651   cptr->port = ntohs(sk.sin_port);
652 #endif
653
654   return 0;
655 }
656
657 /*
658  * Ordinary client access check. Look for conf lines which have the same
659  * status as the flags passed.
660  */
661 enum AuthorizationCheckResult check_client(aClient *cptr)
662 {
663   static char sockname[HOSTLEN + 1];
664   Reg2 struct hostent *hp = NULL;
665   Reg3 int i;
666   enum AuthorizationCheckResult acr;
667
668   ClearAccess(cptr);
669   Debug((DEBUG_DNS, "ch_cl: check access for %s[%s]",
670       cptr->name, inetntoa(cptr->ip)));
671
672   if (check_init(cptr, sockname))
673     return ACR_BAD_SOCKET;
674
675   if (!IsUnixSocket(cptr))
676     hp = cptr->hostp;
677   /*
678    * Verify that the host to ip mapping is correct both ways and that
679    * the ip#(s) for the socket is listed for the host.
680    */
681   if (hp)
682   {
683     for (i = 0; hp->h_addr_list[i]; i++)
684       if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
685         break;
686     if (!hp->h_addr_list[i])
687     {
688       sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
689           inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
690       hp = NULL;
691     }
692   }
693
694   if ((acr = attach_Iline(cptr, hp, sockname)))
695   {
696     Debug((DEBUG_DNS, "ch_cl: access denied: %s[%s]", cptr->name, sockname));
697     return acr;
698   }
699
700   Debug((DEBUG_DNS, "ch_cl: access ok: %s[%s]", cptr->name, sockname));
701
702   if (inet_netof(cptr->ip) == IN_LOOPBACKNET || IsUnixSocket(cptr) ||
703       inet_netof(cptr->ip) == inet_netof(mysk.sin_addr))
704   {
705     ircstp->is_loc++;
706     cptr->flags |= FLAGS_LOCAL;
707   }
708   return ACR_OK;
709 }
710
711 #define CFLAG   CONF_CONNECT_SERVER
712 #define NFLAG   CONF_NOCONNECT_SERVER
713
714 /*
715  * check_server()
716  *
717  * Check access for a server given its name (passed in cptr struct).
718  * Must check for all C/N lines which have a name which matches the
719  * name given and a host which matches. A host alias which is the
720  * same as the server name is also acceptable in the host field of a
721  * C/N line.
722  *
723  * Returns
724  *  0 = Success
725  * -1 = Access denied
726  * -2 = Bad socket.
727  */
728 int check_server(aClient *cptr)
729 {
730   Reg1 const char *name;
731   Reg2 aConfItem *c_conf = NULL, *n_conf = NULL;
732   struct hostent *hp = NULL;
733   Link *lp;
734   char abuff[HOSTLEN + USERLEN + 2];
735   char sockname[HOSTLEN + 1], fullname[HOSTLEN + 1];
736   int i;
737
738   name = cptr->name;
739   Debug((DEBUG_DNS, "sv_cl: check access for %s[%s]", name, cptr->sockhost));
740
741   if (IsUnknown(cptr) && !attach_confs(cptr, name, CFLAG | NFLAG))
742   {
743     Debug((DEBUG_DNS, "No C/N lines for %s", name));
744     return -1;
745   }
746   lp = cptr->confs;
747   /*
748    * We initiated this connection so the client should have a C and N
749    * line already attached after passing through the connec_server()
750    * function earlier.
751    */
752   if (IsConnecting(cptr) || IsHandshake(cptr))
753   {
754     c_conf = find_conf(lp, name, CFLAG);
755     n_conf = find_conf(lp, name, NFLAG);
756     if (!c_conf || !n_conf)
757     {
758       sendto_ops("Connecting Error: %s[%s]", name, cptr->sockhost);
759       det_confs_butmask(cptr, 0);
760       return -1;
761     }
762   }
763 #ifdef  UNIXPORT
764   if (IsUnixSocket(cptr))
765   {
766     if (!c_conf)
767       c_conf = find_conf(lp, name, CFLAG);
768     if (!n_conf)
769       n_conf = find_conf(lp, name, NFLAG);
770   }
771 #endif
772
773   /*
774    * If the servername is a hostname, either an alias (CNAME) or
775    * real name, then check with it as the host. Use gethostbyname()
776    * to check for servername as hostname.
777    */
778   if (!IsUnixSocket(cptr) && !cptr->hostp)
779   {
780     Reg1 aConfItem *aconf;
781
782     aconf = count_cnlines(lp);
783     if (aconf)
784     {
785       Reg1 char *s;
786       Link lin;
787
788       /*
789        * Do a lookup for the CONF line *only* and not
790        * the server connection else we get stuck in a
791        * nasty state since it takes a SERVER message to
792        * get us here and we cant interrupt that very well.
793        */
794       ClearAccess(cptr);
795       lin.value.aconf = aconf;
796       lin.flags = ASYNC_CONF;
797       nextdnscheck = 1;
798       if ((s = strchr(aconf->host, '@')))
799         s++;
800       else
801         s = aconf->host;
802       Debug((DEBUG_DNS, "sv_ci:cache lookup (%s)", s));
803       hp = gethost_byname(s, &lin);
804     }
805   }
806
807   lp = cptr->confs;
808
809   ClearAccess(cptr);
810   if (check_init(cptr, sockname))
811     return -2;
812
813 check_serverback:
814   if (hp)
815   {
816     for (i = 0; hp->h_addr_list[i]; i++)
817       if (!memcmp(hp->h_addr_list[i], &cptr->ip, sizeof(struct in_addr)))
818         break;
819     if (!hp->h_addr_list[i])
820     {
821       sendto_op_mask(SNO_IPMISMATCH, "IP# Mismatch: %s != %s[%08x]",
822           inetntoa(cptr->ip), hp->h_name, *((unsigned int *)hp->h_addr));
823       hp = NULL;
824     }
825   }
826   else if (cptr->hostp)
827   {
828     hp = cptr->hostp;
829     goto check_serverback;
830   }
831
832   if (hp)
833     /*
834      * If we are missing a C or N line from above, search for
835      * it under all known hostnames we have for this ip#.
836      */
837     for (i = 0, name = hp->h_name; name; name = hp->h_aliases[i++])
838     {
839       strncpy(fullname, name, sizeof(fullname) - 1);
840       fullname[sizeof(fullname) - 1] = 0;
841       add_local_domain(fullname, HOSTLEN - strlen(fullname));
842       Debug((DEBUG_DNS, "sv_cl: gethostbyaddr: %s->%s", sockname, fullname));
843       sprintf_irc(abuff, "%s@%s", cptr->username, fullname);
844       if (!c_conf)
845         c_conf = find_conf_host(lp, abuff, CFLAG);
846       if (!n_conf)
847         n_conf = find_conf_host(lp, abuff, NFLAG);
848       if (c_conf && n_conf)
849       {
850         get_sockhost(cptr, fullname);
851         break;
852       }
853     }
854   name = cptr->name;
855
856   /*
857    * Check for C and N lines with the hostname portion the ip number
858    * of the host the server runs on. This also checks the case where
859    * there is a server connecting from 'localhost'.
860    */
861   if (IsUnknown(cptr) && (!c_conf || !n_conf))
862   {
863     sprintf_irc(abuff, "%s@%s", cptr->username, sockname);
864     if (!c_conf)
865       c_conf = find_conf_host(lp, abuff, CFLAG);
866     if (!n_conf)
867       n_conf = find_conf_host(lp, abuff, NFLAG);
868   }
869   /*
870    * Attach by IP# only if all other checks have failed.
871    * It is quite possible to get here with the strange things that can
872    * happen when using DNS in the way the irc server does. -avalon
873    */
874   if (!hp)
875   {
876     if (!c_conf)
877       c_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, CFLAG);
878     if (!n_conf)
879       n_conf = find_conf_ip(lp, (char *)&cptr->ip, cptr->username, NFLAG);
880   }
881   else
882     for (i = 0; hp->h_addr_list[i]; i++)
883     {
884       if (!c_conf)
885         c_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, CFLAG);
886       if (!n_conf)
887         n_conf = find_conf_ip(lp, hp->h_addr_list[i], cptr->username, NFLAG);
888     }
889   /*
890    * detach all conf lines that got attached by attach_confs()
891    */
892   det_confs_butmask(cptr, 0);
893   /*
894    * if no C or no N lines, then deny access
895    */
896   if (!c_conf || !n_conf)
897   {
898     get_sockhost(cptr, sockname);
899     Debug((DEBUG_DNS, "sv_cl: access denied: %s[%s@%s] c %p n %p",
900         name, cptr->username, cptr->sockhost, c_conf, n_conf));
901     return -1;
902   }
903   /*
904    * attach the C and N lines to the client structure for later use.
905    */
906   attach_conf(cptr, n_conf);
907   attach_conf(cptr, c_conf);
908   attach_confs(cptr, name, CONF_HUB | CONF_LEAF | CONF_UWORLD);
909
910   if ((c_conf->ipnum.s_addr == INADDR_NONE) && !IsUnixSocket(cptr))
911     memcpy(&c_conf->ipnum, &cptr->ip, sizeof(struct in_addr));
912   if (!IsUnixSocket(cptr))
913     get_sockhost(cptr, c_conf->host);
914
915   Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", name, cptr->sockhost));
916   return 0;
917 }
918 #undef  CFLAG
919 #undef  NFLAG
920
921 /*
922  * completed_connection
923  *
924  * Complete non-blocking connect()-sequence. Check access and
925  * terminate connection, if trouble detected.
926  *
927  * Return  TRUE, if successfully completed
928  *        FALSE, if failed and ClientExit
929  */
930 static int completed_connection(aClient *cptr)
931 {
932   aConfItem *aconf;
933   time_t newts;
934   aClient *acptr;
935   int i;
936
937   aconf = find_conf(cptr->confs, cptr->name, CONF_CONNECT_SERVER);
938   if (!aconf)
939   {
940     sendto_ops("Lost C-Line for %s", get_client_name(cptr, FALSE));
941     return -1;
942   }
943   if (!BadPtr(aconf->passwd))
944     sendto_one(cptr, "PASS :%s", aconf->passwd);
945
946   aconf = find_conf(cptr->confs, cptr->name, CONF_NOCONNECT_SERVER);
947   if (!aconf)
948   {
949     sendto_ops("Lost N-Line for %s", get_client_name(cptr, FALSE));
950     return -1;
951   }
952   make_server(cptr);
953   /* Create a unique timestamp */
954   newts = TStime();
955   for (i = highest_fd; i >= 0; i--)
956   {
957     if (!(acptr = loc_clients[i]) || (!IsServer(acptr) && !IsHandshake(acptr)))
958       continue;
959     if (acptr->serv->timestamp >= newts)
960       newts = acptr->serv->timestamp + 1;
961   }
962   cptr->serv->timestamp = newts;
963   SetHandshake(cptr);
964   /* Make us timeout after twice the timeout for DNS look ups */
965   cptr->lasttime = now;
966   cptr->flags |= FLAGS_PINGSENT;
967   sendto_one(cptr, "SERVER %s 1 " TIME_T_FMT " " TIME_T_FMT " J%s %s%s :%s",
968       my_name_for_link(me.name, aconf), me.serv->timestamp,
969       newts, MAJOR_PROTOCOL, NumServCap(&me), me.info);
970   if (!IsDead(cptr))
971     start_auth(cptr);
972
973   return (IsDead(cptr)) ? -1 : 0;
974 }
975
976 /*
977  * close_connection
978  *
979  * Close the physical connection. This function must make
980  * MyConnect(cptr) == FALSE, and set cptr->from == NULL.
981  */
982 void close_connection(aClient *cptr)
983 {
984   Reg1 aConfItem *aconf;
985   Reg2 int i, j;
986   int empty = cptr->fd;
987
988   if (IsServer(cptr))
989   {
990     ircstp->is_sv++;
991     ircstp->is_sbs += cptr->sendB;
992     ircstp->is_sbr += cptr->receiveB;
993     ircstp->is_sks += cptr->sendK;
994     ircstp->is_skr += cptr->receiveK;
995     ircstp->is_sti += now - cptr->firsttime;
996     if (ircstp->is_sbs > 1023)
997     {
998       ircstp->is_sks += (ircstp->is_sbs >> 10);
999       ircstp->is_sbs &= 0x3ff;
1000     }
1001     if (ircstp->is_sbr > 1023)
1002     {
1003       ircstp->is_skr += (ircstp->is_sbr >> 10);
1004       ircstp->is_sbr &= 0x3ff;
1005     }
1006   }
1007   else if (IsUser(cptr))
1008   {
1009     ircstp->is_cl++;
1010     ircstp->is_cbs += cptr->sendB;
1011     ircstp->is_cbr += cptr->receiveB;
1012     ircstp->is_cks += cptr->sendK;
1013     ircstp->is_ckr += cptr->receiveK;
1014     ircstp->is_cti += now - cptr->firsttime;
1015     if (ircstp->is_cbs > 1023)
1016     {
1017       ircstp->is_cks += (ircstp->is_cbs >> 10);
1018       ircstp->is_cbs &= 0x3ff;
1019     }
1020     if (ircstp->is_cbr > 1023)
1021     {
1022       ircstp->is_ckr += (ircstp->is_cbr >> 10);
1023       ircstp->is_cbr &= 0x3ff;
1024     }
1025   }
1026   else
1027     ircstp->is_ni++;
1028
1029   /*
1030    * Remove outstanding DNS queries.
1031    */
1032   del_queries((char *)cptr);
1033   /*
1034    * If the connection has been up for a long amount of time, schedule
1035    * a 'quick' reconnect, else reset the next-connect cycle.
1036    */
1037
1038   if ((aconf = find_conf_exact(cptr->name, cptr->username,
1039       cptr->sockhost, CONF_CONNECT_SERVER)))
1040   {
1041     /*
1042      * Reschedule a faster reconnect, if this was a automaticly
1043      * connected configuration entry. (Note that if we have had
1044      * a rehash in between, the status has been changed to
1045      * CONF_ILLEGAL). But only do this if it was a "good" link.
1046      */
1047     aconf->hold = now;
1048     aconf->hold += (aconf->hold - cptr->since > HANGONGOODLINK) ?
1049         HANGONRETRYDELAY : ConfConFreq(aconf);
1050     if (nextconnect > aconf->hold)
1051       nextconnect = aconf->hold;
1052   }
1053
1054   if (cptr->authfd >= 0)
1055     close(cptr->authfd);
1056
1057   if (cptr->fd >= 0)
1058   {
1059     flush_connections(cptr->fd);
1060     loc_clients[cptr->fd] = NULL;
1061     close(cptr->fd);
1062     cptr->fd = -2;
1063   }
1064
1065   DBufClear(&cptr->sendQ);
1066   DBufClear(&cptr->recvQ);
1067   memset(cptr->passwd, 0, sizeof(cptr->passwd));
1068   set_snomask(cptr, 0, SNO_SET);
1069   /*
1070    * Clean up extra sockets from P-lines which have been discarded.
1071    */
1072   if (cptr->acpt != &me && cptr->acpt != cptr)
1073   {
1074     aconf = cptr->acpt->confs->value.aconf;
1075     if (aconf->clients > 0)
1076       aconf->clients--;
1077     if (!aconf->clients && IsIllegal(aconf))
1078       close_connection(cptr->acpt);
1079   }
1080
1081   for (; highest_fd > 0; highest_fd--)
1082     if (loc_clients[highest_fd])
1083       break;
1084
1085   det_confs_butmask(cptr, 0);
1086
1087   /*
1088    * fd remap to keep loc_clients[i] filled at the bottom.
1089    */
1090   if (empty > 0)
1091     if ((j = highest_fd) > (i = empty) && !IsLog(loc_clients[j]))
1092     {
1093       if (IsListening(loc_clients[j]))
1094         return;
1095       if (dup2(j, i) == -1)
1096         return;
1097       loc_clients[i] = loc_clients[j];
1098       loc_clients[i]->fd = i;
1099       loc_clients[j] = NULL;
1100       close(j);
1101       while (!loc_clients[highest_fd])
1102         highest_fd--;
1103     }
1104
1105   return;
1106 }
1107
1108 /*
1109  *  set_sock_opts
1110  */
1111 static void set_sock_opts(int fd, aClient *cptr)
1112 {
1113   size_t opt;
1114 #ifdef SO_REUSEADDR
1115   opt = 1;
1116   if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
1117       (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1118     report_error("setsockopt(SO_REUSEADDR) %s: %s", cptr);
1119 #endif
1120 #ifdef  SO_USELOOPBACK
1121   opt = 1;
1122   if (setsockopt(fd, SOL_SOCKET, SO_USELOOPBACK,
1123       (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1124     report_error("setsockopt(SO_USELOOPBACK) %s: %s", cptr);
1125 #endif
1126 #ifdef  SO_RCVBUF
1127   opt = 8192;
1128   if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1129     report_error("setsockopt(SO_RCVBUF) %s: %s", cptr);
1130 #endif
1131 #ifdef SO_SNDBUF
1132 #ifdef _SEQUENT_
1133 /*
1134  * Seems that Sequent freezes up if the receving buffer is a different size
1135  * to the sending buffer (maybe a tcp window problem too).
1136  */
1137   opt = 8192;
1138 #else
1139   opt = 8192;
1140 #endif
1141   if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (OPT_TYPE *)&opt, sizeof(opt)) < 0)
1142     report_error("setsockopt(SO_SNDBUF) %s: %s", cptr);
1143 #endif
1144 #if defined(IP_OPTIONS) && defined(IPPROTO_IP)
1145   {
1146     char *s = readbuf, *t = readbuf + sizeof(readbuf) / 2;
1147
1148     opt = sizeof(readbuf) / 8;
1149     if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)t, &opt) < 0)
1150       report_error("getsockopt(IP_OPTIONS) %s: %s", cptr);
1151     else if (opt > 0 && opt != sizeof(readbuf) / 8)
1152     {
1153       for (*readbuf = '\0'; opt > 0; opt--, s += 3)
1154         sprintf(s, "%02x:", *t++);
1155       *s = '\0';
1156       sendto_ops("Connection %s using IP opts: (%s)",
1157           get_client_name(cptr, TRUE), readbuf);
1158     }
1159     if (setsockopt(fd, IPPROTO_IP, IP_OPTIONS, (OPT_TYPE *)NULL, 0) < 0)
1160       report_error("setsockopt(IP_OPTIONS) %s: %s", cptr);
1161   }
1162 #endif
1163 }
1164
1165 int get_sockerr(aClient *cptr)
1166 {
1167   int errtmp = errno;
1168 #if defined(SO_ERROR) && !defined(SOL2)
1169   int err = 0;
1170   size_t len = sizeof(err);
1171   if (cptr->fd >= 0)
1172     if (!getsockopt(cptr->fd, SOL_SOCKET, SO_ERROR, (OPT_TYPE *)&err, &len))
1173       if (err)
1174         errtmp = err;
1175 #endif
1176   return errtmp;
1177 }
1178
1179 /*
1180  * set_non_blocking
1181  *
1182  * Set the client connection into non-blocking mode. If your
1183  * system doesn't support this, you can make this a dummy
1184  * function (and get all the old problems that plagued the
1185  * blocking version of IRC--not a problem if you are a
1186  * lightly loaded node...)
1187  */
1188 void set_non_blocking(int fd, aClient *cptr)
1189 {
1190   int res;
1191 #ifndef NBLOCK_SYSV
1192   int nonb = 0;
1193 #endif
1194
1195   /*
1196    * NOTE: consult ALL your relevant manual pages *BEFORE* changing
1197    * these ioctl's. There are quite a few variations on them,
1198    * as can be seen by the PCS one. They are *NOT* all the same.
1199    * Heed this well. - Avalon.
1200    */
1201 #ifdef  NBLOCK_POSIX
1202   nonb |= O_NONBLOCK;
1203 #endif
1204 #ifdef  NBLOCK_BSD
1205   nonb |= O_NDELAY;
1206 #endif
1207 #ifdef  NBLOCK_SYSV
1208   /* This portion of code might also apply to NeXT. -LynX */
1209   res = 1;
1210
1211   if (ioctl(fd, FIONBIO, &res) < 0)
1212     report_error("ioctl(fd,FIONBIO) failed for %s: %s", cptr);
1213 #else
1214   if ((res = fcntl(fd, F_GETFL, 0)) == -1)
1215     report_error("fcntl(fd, F_GETFL) failed for %s: %s", cptr);
1216   else if (fcntl(fd, F_SETFL, res | nonb) == -1)
1217     report_error("fcntl(fd, F_SETL, nonb) failed for %s: %s", cptr);
1218 #endif
1219   return;
1220 }
1221
1222 /*
1223  * Creates a client which has just connected to us on the given fd.
1224  * The sockhost field is initialized with the ip# of the host.
1225  * The client is added to the linked list of clients but isnt added to any
1226  * hash tables yet since it doesn't have a name.
1227  */
1228 aClient *add_connection(aClient *cptr, int fd, int type)
1229 {
1230   Link lin;
1231   aClient *acptr;
1232   aConfItem *aconf = NULL;
1233   acptr =
1234       make_client(NULL,
1235       (cptr->port == portnum) ? STAT_UNKNOWN_SERVER : STAT_UNKNOWN_USER);
1236
1237   if (cptr != &me)
1238     aconf = cptr->confs->value.aconf;
1239   /*
1240    * Removed preliminary access check. Full check is performed in
1241    * m_server and m_user instead. Also connection time out help to
1242    * get rid of unwanted connections.
1243    */
1244   if (type == ADCON_TTY)        /* If descriptor is a tty,
1245                                    special checking... */
1246     get_sockhost(acptr, cptr->sockhost);
1247   else
1248   {
1249     Reg1 char *s, *t;
1250     struct sockaddr_in addr;
1251     size_t len = sizeof(struct sockaddr_in);
1252
1253     if (getpeername(fd, (struct sockaddr *)&addr, &len) == -1)
1254     {
1255       report_error("Failed in connecting to %s: %s", cptr);
1256     add_con_refuse:
1257       ircstp->is_ref++;
1258       acptr->fd = -2;
1259       free_client(acptr);
1260       close(fd);
1261       return NULL;
1262     }
1263     /* Don't want to add "Failed in connecting to" here.. */
1264     if (aconf && IsIllegal(aconf))
1265       goto add_con_refuse;
1266     /*
1267      * Copy ascii address to 'sockhost' just in case. Then we
1268      * have something valid to put into error messages...
1269      */
1270     get_sockhost(acptr, inetntoa(addr.sin_addr));
1271     memcpy(&acptr->ip, &addr.sin_addr, sizeof(struct in_addr));
1272 #ifdef TESTNET
1273     acptr->port = ntohs(addr.sin_port) - 10000;
1274 #else
1275     acptr->port = ntohs(addr.sin_port);
1276 #endif
1277
1278     /*
1279      * Check that this socket (client) is allowed to accept
1280      * connections from this IP#.
1281      */
1282     for (s = (char *)&cptr->ip, t = (char *)&acptr->ip, len = 4;
1283         len > 0; len--, s++, t++)
1284     {
1285       if (!*s)
1286         continue;
1287       if (*s != *t)
1288         break;
1289     }
1290
1291     if (len)
1292       goto add_con_refuse;
1293
1294     lin.flags = ASYNC_CLIENT;
1295     lin.value.cptr = acptr;
1296     Debug((DEBUG_DNS, "lookup %s", inetntoa(addr.sin_addr)));
1297     acptr->hostp = gethost_byaddr(&acptr->ip, &lin);
1298     if (!acptr->hostp)
1299       SetDNS(acptr);
1300     nextdnscheck = 1;
1301   }
1302
1303   if (aconf)
1304     aconf->clients++;
1305   acptr->fd = fd;
1306   if (fd > highest_fd)
1307     highest_fd = fd;
1308   loc_clients[fd] = acptr;
1309   acptr->acpt = cptr;
1310   Count_newunknown(nrof);
1311   add_client_to_list(acptr);
1312   set_non_blocking(acptr->fd, acptr);
1313   set_sock_opts(acptr->fd, acptr);
1314
1315   /*
1316    * Add this local client to the IPcheck registry.
1317    * If it is a connection to a user port and if the site has been throttled,
1318    * reject the user.
1319    */
1320   if (IPcheck_local_connect(acptr) == -1 && IsUserPort(acptr))
1321   {
1322     ircstp->is_ref++;
1323     exit_client(cptr, acptr, &me,
1324         "Your host is trying to (re)connect too fast -- throttled");
1325     return NULL;
1326   }
1327
1328   start_auth(acptr);
1329   return acptr;
1330 }
1331
1332 #ifdef  UNIXPORT
1333 static void add_unixconnection(aClient *cptr, int fd)
1334 {
1335   aClient *acptr;
1336   aConfItem *aconf = NULL;
1337
1338   acptr = make_client(NULL, STAT_UNKNOWN);
1339
1340   /*
1341    * Copy ascii address to 'sockhost' just in case. Then we
1342    * have something valid to put into error messages...
1343    */
1344   get_sockhost(acptr, me.sockhost);
1345   if (cptr != &me)
1346     aconf = cptr->confs->value.aconf;
1347   if (aconf)
1348   {
1349     if (IsIllegal(aconf))
1350     {
1351       ircstp->is_ref++;
1352       acptr->fd = -2;
1353       free_client(acptr);
1354       close(fd);
1355       return;
1356     }
1357     else
1358       aconf->clients++;
1359   }
1360   acptr->fd = fd;
1361   if (fd > highest_fd)
1362     highest_fd = fd;
1363   loc_clients[fd] = acptr;
1364   acptr->acpt = cptr;
1365   SetUnixSock(acptr);
1366   memcpy(&acptr->ip, &me.ip, sizeof(struct in_addr));
1367
1368   Count_newunknown(nrof);
1369   add_client_to_list(acptr);
1370   set_non_blocking(acptr->fd, acptr);
1371   set_sock_opts(acptr->fd, acptr);
1372   SetAccess(acptr);
1373   return;
1374 }
1375 #endif
1376
1377 /*
1378  * select/poll convert macro's by Run.
1379  *
1380  * The names are chosen to reflect what they means when NOT using poll().
1381  */
1382 #ifndef USE_POLL
1383 typedef fd_set *fd_setp_t;
1384 #define RFD_ISSET(fd, rfd, index) FD_ISSET((fd), (rfd))
1385 #define WFD_ISSET(fd, wfd, index) FD_ISSET((fd), (wfd))
1386 #define RFD_SET(fd, rfd, index, cptr) FD_SET((fd), (rfd))
1387 #define WFD_SET(fd, wfd, index, cptr) FD_SET((fd), (wfd))
1388 #define RWFD_SET(fd, wfd, index) FD_SET((fd), (wfd))
1389 #define RFD_CLR_OUT(fd, rfd, index) FD_CLR((fd), (rfd))
1390 #define WFD_CLR_OUT(fd, wfd, index) FD_CLR((fd), (wfd))
1391 #define LOC_FD(index) (index)
1392 #define LOC_CLIENTS(index) loc_clients[index]
1393 #define HIGHEST_INDEX highest_fd
1394 #else /* USE_POLL */
1395 typedef unsigned int fd_setp_t; /* Actually, an index to poll_fds[] */
1396 #ifdef _AIX
1397 #define POLLREADFLAGS (POLLIN|POLLMSG)
1398 #else
1399 #  if defined(POLLMSG) && defined(POLLIN) && defined(POLLRDNORM)
1400 #    define POLLREADFLAGS (POLLMSG|POLLIN|POLLRDNORM)
1401 #  else
1402 #    if defined(POLLIN) && defined(POLLRDNORM)
1403 #      define POLLREADFLAGS (POLLIN|POLLRDNORM)
1404 #    else
1405 #      if defined(POLLIN)
1406 #        define POLLREADFLAGS POLLIN
1407 #      else
1408 #        if defined(POLLRDNORM)
1409 #          define POLLREADFLAGS POLLRDNORM
1410 #        endif
1411 #      endif
1412 #    endif
1413 #  endif
1414 #endif
1415 #if defined(POLLOUT) && defined(POLLWRNORM)
1416 #define POLLWRITEFLAGS (POLLOUT|POLLWRNORM)
1417 #else
1418 #  if defined(POLLOUT)
1419 #    define POLLWRITEFLAGS POLLOUT
1420 #  else
1421 #    if defined(POLLWRNORM)
1422 #      define POLLWRITEFLAGS POLLWRNORM
1423 #    endif
1424 #  endif
1425 #endif
1426 #ifdef POLLHUP
1427 #define POLLERRORS (POLLHUP|POLLERR)
1428 #else
1429 #define POLLERRORS POLLERR
1430 #endif
1431 #define RFD_ISSET(fd, rfd, index) \
1432   ((poll_fds[index].revents & POLLREADFLAGS) || \
1433   ((poll_fds[index].events & POLLREADFLAGS) && \
1434     (poll_fds[index].revents & POLLERRORS)))
1435 #define WFD_ISSET(fd, wfd, index) \
1436   ((poll_fds[index].revents & POLLWRITEFLAGS) || \
1437   ((poll_fds[index].events & POLLWRITEFLAGS) && \
1438     (poll_fds[index].revents & POLLERRORS)))
1439 #define RFD_SET(fdes, rfd, index, cptr) \
1440   do { \
1441     poll_fds[index].fd = fdes; \
1442     poll_cptr[index] = cptr; \
1443     poll_fds[index].events = POLLREADFLAGS; \
1444     added = TRUE; \
1445   } while(0)
1446 #define WFD_SET(fdes, wfd, index, cptr) \
1447   do { \
1448     poll_fds[index].fd = fdes; \
1449     poll_cptr[index] = cptr; \
1450     if (added) \
1451       poll_fds[index].events |= POLLWRITEFLAGS; \
1452     else \
1453     { \
1454       poll_fds[index].events = POLLWRITEFLAGS; \
1455       added = TRUE; \
1456     } \
1457   } while(0)
1458 /* This identical to WFD_SET() when used after a call to RFD_SET(): */
1459 #define RWFD_SET(fd, wfd, index) poll_fds[index].events |= POLLWRITEFLAGS
1460 /* [RW]FD_CLR_OUT() clears revents, not events */
1461 #define RFD_CLR_OUT(fd, rfd, index) poll_fds[index].revents &= ~POLLREADFLAGS
1462 #define WFD_CLR_OUT(fd, wfd, index) poll_fds[index].revents &= ~POLLWRITEFLAGS
1463 #define LOC_FD(index) (poll_fds[index].fd)
1464 #define LOC_CLIENTS(index) (poll_cptr[index])
1465 #define HIGHEST_INDEX (currfd_index - 1)
1466 #endif /* USE_POLL */
1467
1468 /*
1469  * read_packet
1470  *
1471  * Read a 'packet' of data from a connection and process it.  Read in 8k
1472  * chunks to give a better performance rating (for server connections).
1473  * Do some tricky stuff for client connections to make sure they don't do
1474  * any flooding >:-) -avalon
1475  */
1476 static int read_packet(aClient *cptr, fd_setp_t rfd)
1477 {
1478   size_t dolen = 0;
1479   int length = 0;
1480   int done;
1481
1482   if (RFD_ISSET(cptr->fd, rfd, rfd) &&
1483       !(IsUser(cptr) && DBufLength(&cptr->recvQ) > 6090))
1484   {
1485     errno = 0;
1486     length = recv(cptr->fd, readbuf, sizeof(readbuf), 0);
1487
1488     cptr->lasttime = now;
1489     if (cptr->lasttime > cptr->since)
1490       cptr->since = cptr->lasttime;
1491     cptr->flags &= ~(FLAGS_PINGSENT | FLAGS_NONL);
1492     /*
1493      * If not ready, fake it so it isnt closed
1494      */
1495     if (length == -1 && ((errno == EWOULDBLOCK) || (errno == EAGAIN)))
1496       return 1;
1497     if (length <= 0)
1498       return length;
1499   }
1500
1501   /*
1502    * For server connections, we process as many as we can without
1503    * worrying about the time of day or anything :)
1504    */
1505   if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr))
1506   {
1507     if (length > 0)
1508       if ((done = dopacket(cptr, readbuf, length)))
1509         return done;
1510   }
1511   else
1512   {
1513     /*
1514      * Before we even think of parsing what we just read, stick
1515      * it on the end of the receive queue and do it when its
1516      * turn comes around.
1517      */
1518     if (!dbuf_put(&cptr->recvQ, readbuf, length))
1519       return exit_client(cptr, cptr, &me, "dbuf_put fail");
1520
1521 #ifndef NOFLOODCONTROL
1522     if (IsUser(cptr) && DBufLength(&cptr->recvQ) > CLIENT_FLOOD)
1523       return exit_client(cptr, cptr, &me, "Excess Flood");
1524 #endif
1525
1526     while (DBufLength(&cptr->recvQ) && !NoNewLine(cptr)
1527 #ifndef NOFLOODCONTROL
1528         && (IsTrusted(cptr) || cptr->since - now < 10)
1529 #endif
1530         )
1531     {
1532       /*
1533        * If it has become registered as a Server
1534        * then skip the per-message parsing below.
1535        */
1536       if (IsServer(cptr))
1537       {
1538         /*
1539          * XXX - this blindly deletes data if no cr/lf is received at
1540          * the end of a lot of messages and the data stored in the 
1541          * dbuf is greater than sizeof(readbuf)
1542          */
1543         dolen = dbuf_get(&cptr->recvQ, readbuf, sizeof(readbuf));
1544         if (0 == dolen)
1545           break;
1546         if ((done = dopacket(cptr, readbuf, dolen)))
1547           return done;
1548         break;
1549       }
1550       dolen = dbuf_getmsg(&cptr->recvQ, cptr->buffer, BUFSIZE);
1551       /*
1552        * Devious looking...whats it do ? well..if a client
1553        * sends a *long* message without any CR or LF, then
1554        * dbuf_getmsg fails and we pull it out using this
1555        * loop which just gets the next 512 bytes and then
1556        * deletes the rest of the buffer contents.
1557        * -avalon
1558        */
1559       if (0 == dolen)
1560       {
1561         if (DBufLength(&cptr->recvQ) < 510)
1562         {
1563           cptr->flags |= FLAGS_NONL;
1564           break;
1565         }
1566         DBufClear(&cptr->recvQ);
1567         break;
1568       }
1569       else if (CPTR_KILLED == client_dopacket(cptr, dolen))
1570         return CPTR_KILLED;
1571     }
1572   }
1573   return 1;
1574 }
1575
1576 /*
1577  * Check all connections for new connections and input data that is to be
1578  * processed. Also check for connections with data queued and whether we can
1579  * write it out.
1580  *
1581  * Don't ever use ZERO for `delay', unless you mean to poll and then
1582  * you have to have sleep/wait somewhere else in the code.--msa
1583  */
1584 int read_message(time_t delay)
1585 {
1586   Reg1 aClient *cptr;
1587   Reg2 int nfds;
1588   struct timeval wait;
1589 #ifdef  pyr
1590   struct timeval nowt;
1591   unsigned long us;
1592 #endif
1593   time_t delay2 = delay;
1594   unsigned long usec = 0;
1595   int res, length, fd, i;
1596   int auth = 0, ping = 0;
1597 #ifndef USE_POLL
1598   fd_set read_set, write_set;
1599 #else /* USE_POLL */
1600   unsigned int currfd_index = 0;
1601   unsigned int udpfdindex = 0;
1602   unsigned int resfdindex = 0;
1603   unsigned long timeout;
1604   int added;
1605 #endif /* USE_POLL */
1606
1607 #ifdef  pyr
1608   gettimeofday(&nowt, NULL);
1609   now = nowt.tv_sec;
1610 #endif
1611
1612   for (res = 0;;)
1613   {
1614 #ifndef USE_POLL
1615     FD_ZERO(&read_set);
1616     FD_ZERO(&write_set);
1617 #endif /* not USE_POLL */
1618     for (i = highest_fd; i >= 0; i--)
1619     {
1620 #ifdef USE_POLL
1621       added = FALSE;
1622 #endif /* USE_POLL */
1623       if (!(cptr = loc_clients[i]))
1624         continue;
1625       if (IsLog(cptr))
1626         continue;
1627       if (DoingAuth(cptr))
1628       {
1629         auth++;
1630         Debug((DEBUG_NOTICE, "auth on %p %d", cptr, i));
1631         RFD_SET(cptr->authfd, &read_set, currfd_index, cptr);
1632         if (cptr->flags & FLAGS_WRAUTH)
1633           RWFD_SET(cptr->authfd, &write_set, currfd_index);
1634       }
1635       if (IsPing(cptr))
1636       {
1637         ping++;
1638         Debug((DEBUG_NOTICE, "open ping on %p %d", cptr, i));
1639         if (!cptr->firsttime || now <= cptr->firsttime)
1640         {
1641           RFD_SET(i, &read_set, currfd_index, cptr);
1642           delay2 = 1;
1643           if (DoPing(cptr) && now > cptr->lasttime)
1644             RWFD_SET(i, &write_set, currfd_index);
1645         }
1646         else
1647         {
1648           del_queries((char *)cptr);
1649           end_ping(cptr);
1650         }
1651 #ifdef USE_POLL
1652         if (added)
1653           currfd_index++;
1654 #endif /* USE_POLL */
1655         continue;
1656       }
1657       if (DoingDNS(cptr) || DoingAuth(cptr))
1658       {
1659 #ifdef USE_POLL
1660         if (added)
1661           currfd_index++;
1662 #endif /* USE_POLL */
1663         continue;
1664       }
1665       if (IsMe(cptr) && IsListening(cptr))
1666         RFD_SET(i, &read_set, currfd_index, cptr);
1667       else if (!IsMe(cptr))
1668       {
1669         if (DBufLength(&cptr->recvQ) && delay2 > 2)
1670           delay2 = 1;
1671         if (DBufLength(&cptr->recvQ) < 4088)
1672           RFD_SET(i, &read_set, currfd_index, cptr);
1673         if (DBufLength(&cptr->sendQ) || IsConnecting(cptr) ||
1674             (cptr->listing && DBufLength(&cptr->sendQ) < 2048))
1675 #ifndef pyr
1676           WFD_SET(i, &write_set, currfd_index, cptr);
1677 #else /* pyr */
1678         {
1679           if (!(cptr->flags & FLAGS_BLOCKED))
1680             WFD_SET(i, &write_set, currfd_index, cptr);
1681           else
1682             delay2 = 0, usec = 500000;
1683         }
1684         if (now - cptr->lw.tv_sec && nowt.tv_usec - cptr->lw.tv_usec < 0)
1685           us = 1000000;
1686         else
1687           us = 0;
1688         us += nowt.tv_usec;
1689         if (us - cptr->lw.tv_usec > 500000)
1690           cptr->flags &= ~FLAGS_BLOCKED;
1691 #endif /* pyr */
1692       }
1693 #ifdef USE_POLL
1694       if (added)
1695         currfd_index++;
1696 #endif /* USE_POLL */
1697     }
1698
1699     if (udpfd >= 0)
1700     {
1701       RFD_SET(udpfd, &read_set, currfd_index, NULL);
1702 #ifdef USE_POLL
1703       udpfdindex = currfd_index;
1704       currfd_index++;
1705 #endif /* USE_POLL */
1706     }
1707     if (resfd >= 0)
1708     {
1709       RFD_SET(resfd, &read_set, currfd_index, NULL);
1710 #ifdef USE_POLL
1711       resfdindex = currfd_index;
1712       currfd_index++;
1713 #endif /* USE_POLL */
1714     }
1715
1716     wait.tv_sec = MIN(delay2, delay);
1717     wait.tv_usec = usec;
1718 #ifndef USE_POLL
1719 #ifdef  HPUX
1720     nfds = select(FD_SETSIZE, (int *)&read_set, (int *)&write_set, 0, &wait);
1721 #else
1722     nfds = select(FD_SETSIZE, &read_set, &write_set, 0, &wait);
1723 #endif
1724 #else /* USE_POLL */
1725     timeout = (wait.tv_sec * 1000) + (wait.tv_usec / 1000);
1726     nfds = poll(poll_fds, currfd_index, timeout);
1727 #endif /* USE_POLL */
1728     now = time(NULL);
1729     if (nfds == -1 && errno == EINTR)
1730       return -1;
1731     else if (nfds >= 0)
1732       break;
1733     report_error("select %s: %s", &me);
1734     res++;
1735     if (res > 5)
1736       restart("too many select errors");
1737     sleep(10);
1738     now += 10;
1739   }
1740
1741   if (udpfd >= 0 && RFD_ISSET(udpfd, &read_set, udpfdindex))
1742   {
1743     polludp();
1744     nfds--;
1745     RFD_CLR_OUT(udpfd, &read_set, udpfdindex);
1746   }
1747   /*
1748    * Check fd sets for the ping fd's (if set and valid!) first
1749    * because these can not be processed using the normal loops below.
1750    * And we want them to be as fast as possible.
1751    * -Run
1752    */
1753   for (i = HIGHEST_INDEX; (ping > 0) && (i >= 0); i--)
1754   {
1755     if (!(cptr = LOC_CLIENTS(i)))
1756       continue;
1757     if (!IsPing(cptr))
1758       continue;
1759     ping--;
1760     if ((nfds > 0) && RFD_ISSET(cptr->fd, &read_set, i))
1761     {
1762       nfds--;
1763       RFD_CLR_OUT(cptr->fd, &read_set, i);
1764       read_ping(cptr);          /* This can RunFree(cptr) ! */
1765     }
1766     else if ((nfds > 0) && WFD_ISSET(cptr->fd, &write_set, i))
1767     {
1768       nfds--;
1769       cptr->lasttime = now;
1770       WFD_CLR_OUT(cptr->fd, &write_set, i);
1771       send_ping(cptr);          /* This can RunFree(cptr) ! */
1772     }
1773   }
1774   if (resfd >= 0 && RFD_ISSET(resfd, &read_set, resfdindex))
1775   {
1776     do_dns_async();
1777     nfds--;
1778     RFD_CLR_OUT(resfd, &read_set, resfdindex);
1779   }
1780   /*
1781    * Check fd sets for the auth fd's (if set and valid!) first
1782    * because these can not be processed using the normal loops below.
1783    * -avalon
1784    */
1785   for (i = HIGHEST_INDEX; (auth > 0) && (i >= 0); i--)
1786   {
1787     if (!(cptr = LOC_CLIENTS(i)))
1788       continue;
1789     if (cptr->authfd < 0)
1790       continue;
1791     auth--;
1792     if ((nfds > 0) && WFD_ISSET(cptr->authfd, &write_set, i))
1793     {
1794       nfds--;
1795       send_authports(cptr);
1796     }
1797     else if ((nfds > 0) && RFD_ISSET(cptr->authfd, &read_set, i))
1798     {
1799       nfds--;
1800       read_authports(cptr);
1801     }
1802   }
1803   for (i = HIGHEST_INDEX; i >= 0; i--)
1804     if ((cptr = LOC_CLIENTS(i)) && RFD_ISSET(i, &read_set, i) &&
1805         IsListening(cptr))
1806     {
1807       RFD_CLR_OUT(i, &read_set, i);
1808       nfds--;
1809       cptr->lasttime = now;
1810       /*
1811        * There may be many reasons for error return, but
1812        * in otherwise correctly working environment the
1813        * probable cause is running out of file descriptors
1814        * (EMFILE, ENFILE or others?). The man pages for
1815        * accept don't seem to list these as possible,
1816        * although it's obvious that it may happen here.
1817        * Thus no specific errors are tested at this
1818        * point, just assume that connections cannot
1819        * be accepted until some old is closed first.
1820        */
1821       if ((fd = accept(LOC_FD(i), NULL, NULL)) < 0)
1822       {
1823         if (errno != EWOULDBLOCK)
1824           report_error("accept() failed%s: %s", NULL);
1825         break;
1826       }
1827 #if defined(USE_SYSLOG) && defined(SYSLOG_CONNECTS)
1828       {                         /* get an early log of all connections   --dl */
1829         static struct sockaddr_in peer;
1830         static int len;
1831         len = sizeof(peer);
1832         getpeername(fd, (struct sockaddr *)&peer, &len);
1833         syslog(LOG_DEBUG, "Conn: %s", inetntoa(peer.sin_addr));
1834       }
1835 #endif
1836       ircstp->is_ac++;
1837       if (fd >= MAXCLIENTS)
1838       {
1839         /* Don't send more messages then one every 10 minutes */
1840         static int count;
1841         static time_t last_time;
1842         ircstp->is_ref++;
1843         ++count;
1844         if (last_time < now - (time_t) 600)
1845         {
1846           if (count > 0)
1847           {
1848             if (!last_time)
1849               last_time = me.since;
1850             sendto_ops
1851                 ("All connections in use!  Had to refuse %d clients in the last "
1852                 STIME_T_FMT " minutes", count, (now - last_time) / 60);
1853           }
1854           else
1855             sendto_ops("All connections in use. (%s)", get_client_name(cptr,
1856                 TRUE));
1857           count = 0;
1858           last_time = now;
1859         }
1860         send(fd, "ERROR :All connections in use\r\n", 32, 0);
1861         close(fd);
1862         break;
1863       }
1864       /*
1865        * Use of add_connection (which never fails :) meLazy
1866        */
1867 #ifdef  UNIXPORT
1868       if (IsUnixSocket(cptr))
1869         add_unixconnection(cptr, fd);
1870       else
1871 #endif
1872       if (!add_connection(cptr, fd, ADCON_SOCKET))
1873         continue;
1874       nextping = now;
1875       if (!cptr->acpt)
1876         cptr->acpt = &me;
1877     }
1878
1879   for (i = HIGHEST_INDEX; i >= 0; i--)
1880   {
1881     if (!(cptr = LOC_CLIENTS(i)) || IsMe(cptr))
1882       continue;
1883 #ifdef USE_POLL
1884     if (DoingDNS(cptr) || DoingAuth(cptr) || !(cptr = loc_clients[LOC_FD(i)]))
1885       continue;
1886 #endif /* USE_POLL */
1887 #ifdef DEBUGMODE
1888     if (IsLog(cptr))
1889       continue;
1890 #endif
1891     if (WFD_ISSET(i, &write_set, i))
1892     {
1893       int write_err = 0;
1894       nfds--;
1895       /*
1896        *  ...room for writing, empty some queue then...
1897        */
1898       cptr->flags &= ~FLAGS_BLOCKED;
1899       if (IsConnecting(cptr))
1900         write_err = completed_connection(cptr);
1901       if (!write_err)
1902       {
1903         if (cptr->listing && DBufLength(&cptr->sendQ) < 2048)
1904           list_next_channels(cptr, 64);
1905         send_queued(cptr);
1906       }
1907       if (IsDead(cptr) || write_err)
1908       {
1909       deadsocket:
1910         if (RFD_ISSET(i, &read_set, i))
1911         {
1912           nfds--;
1913           RFD_CLR_OUT(i, &read_set, i);
1914         }
1915         exit_client(cptr, cptr, &me,
1916             IsDead(cptr) ? LastDeadComment(cptr) : strerror(get_sockerr(cptr)));
1917         continue;
1918       }
1919     }
1920     length = 1;                 /* for fall through case */
1921     if ((!NoNewLine(cptr) || RFD_ISSET(i, &read_set, i)) && !IsDead(cptr))
1922 #ifndef USE_POLL
1923       length = read_packet(cptr, &read_set);
1924 #else /* USE_POLL */
1925       length = read_packet(cptr, i);
1926 #endif /* USE_POLL */
1927 #if 0
1928     /* Bullshit, why would we want to flush sockets while using non-blocking?
1929      * This uses > 4% cpu! --Run */
1930     if (length > 0)
1931       flush_connections(LOC_FD(i));
1932 #endif
1933     if ((length != CPTR_KILLED) && IsDead(cptr))
1934       goto deadsocket;
1935     if (!RFD_ISSET(i, &read_set, i) && length > 0)
1936       continue;
1937     nfds--;
1938     readcalls++;
1939     if (length > 0 || length == CPTR_KILLED)
1940       continue;
1941
1942     /*
1943      * ...hmm, with non-blocking sockets we might get
1944      * here from quite valid reasons, although.. why
1945      * would select report "data available" when there
1946      * wasn't... So, this must be an error anyway...  --msa
1947      * actually, EOF occurs when read() returns 0 and
1948      * in due course, select() returns that fd as ready
1949      * for reading even though it ends up being an EOF. -avalon
1950      */
1951     Debug((DEBUG_ERROR, "READ ERROR: fd = %d %d %d", LOC_FD(i), errno, length));
1952
1953     if ((IsServer(cptr) || IsHandshake(cptr)) && errno == 0 && length == 0)
1954       exit_client_msg(cptr, cptr, &me, "Server %s closed the connection (%s)",
1955           get_client_name(cptr, FALSE), cptr->serv->last_error_msg);
1956     else
1957       exit_client_msg(cptr, cptr, &me, "Read error to %s: %s",
1958           get_client_name(cptr, FALSE), (length < 0) ?
1959           strerror(get_sockerr(cptr)) : "EOF from client");
1960   }
1961   return 0;
1962 }
1963
1964 /*
1965  * connect_server
1966  */
1967 int connect_server(aConfItem *aconf, aClient *by, struct hostent *hp)
1968 {
1969   Reg1 struct sockaddr *svp;
1970   Reg2 aClient *cptr, *c2ptr;
1971   Reg3 char *s;
1972   int errtmp, len;
1973
1974   Debug((DEBUG_NOTICE, "Connect to %s[%s] @%s",
1975       aconf->name, aconf->host, inetntoa(aconf->ipnum)));
1976
1977   if ((c2ptr = FindClient(aconf->name)))
1978   {
1979     if (IsServer(c2ptr) || IsMe(c2ptr))
1980     {
1981       sendto_ops("Server %s already present from %s",
1982           aconf->name, c2ptr->from->name);
1983       if (by && IsUser(by) && !MyUser(by))
1984       {
1985 #ifndef NO_PROTOCOL9
1986         if (Protocol(by->from) < 10)
1987           sendto_one(by, ":%s NOTICE %s :Server %s already present from %s",
1988               me.name, by->name, aconf->name, c2ptr->from->name);
1989         else
1990 #endif
1991           sendto_one(by, "%s NOTICE %s%s :Server %s already present from %s",
1992               NumServ(&me), NumNick(by), aconf->name, c2ptr->from->name);
1993       }
1994       return -1;
1995     }
1996     else if (IsHandshake(c2ptr) || IsConnecting(c2ptr))
1997     {
1998       if (by && IsUser(by))
1999       {
2000         if (MyUser(by) || Protocol(by->from) < 10)
2001           sendto_one(by, ":%s NOTICE %s :Connection to %s already in progress",
2002               me.name, by->name, get_client_name(c2ptr, TRUE));
2003         else
2004           sendto_one(by,
2005               "%s NOTICE %s%s :Connection to %s already in progress",
2006               NumServ(&me), NumNick(by), get_client_name(c2ptr, TRUE));
2007       }
2008       return -1;
2009     }
2010   }
2011
2012   /*
2013    * If we dont know the IP# for this host and itis a hostname and
2014    * not a ip# string, then try and find the appropriate host record.
2015    */
2016   if ((!aconf->ipnum.s_addr)
2017 #ifdef UNIXPORT
2018       && ((aconf->host[2]) != '/')      /* needed for Unix domain -- dl */
2019 #endif
2020       )
2021   {
2022     Link lin;
2023
2024     lin.flags = ASYNC_CONNECT;
2025     lin.value.aconf = aconf;
2026     nextdnscheck = 1;
2027     s = strchr(aconf->host, '@');
2028     s++;                        /* should NEVER be NULL */
2029     if ((aconf->ipnum.s_addr = inet_addr(s)) == INADDR_NONE)
2030     {
2031       aconf->ipnum.s_addr = INADDR_ANY;
2032       hp = gethost_byname(s, &lin);
2033       Debug((DEBUG_NOTICE, "co_sv: hp %p ac %p na %s ho %s",
2034           hp, aconf, aconf->name, s));
2035       if (!hp)
2036         return 0;
2037       memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2038     }
2039   }
2040   cptr = make_client(NULL, STAT_UNKNOWN);
2041   cptr->hostp = hp;
2042   /*
2043    * Copy these in so we have something for error detection.
2044    */
2045   strncpy(cptr->name, aconf->name, sizeof(cptr->name) - 1);
2046   cptr->name[sizeof(cptr->name) - 1] = 0;
2047   strncpy(cptr->sockhost, aconf->host, HOSTLEN);
2048   cptr->sockhost[HOSTLEN] = 0;
2049
2050 #ifdef  UNIXPORT
2051   if (aconf->host[2] == '/')    /* (/ starts a 2), Unix domain -- dl */
2052     svp = connect_unix(aconf, cptr, &len);
2053   else
2054     svp = connect_inet(aconf, cptr, &len);
2055 #else
2056   svp = connect_inet(aconf, cptr, &len);
2057 #endif
2058
2059   if (!svp)
2060   {
2061     if (cptr->fd >= 0)
2062       close(cptr->fd);
2063     cptr->fd = -2;
2064     if (by && IsUser(by) && !MyUser(by))
2065     {
2066 #ifndef NO_PROTOCOL9
2067       if (Protocol(by->from) < 10)
2068         sendto_one(by, ":%s NOTICE %s :Couldn't connect to %s",
2069             me.name, by->name, get_client_name(cptr, TRUE));
2070       else
2071 #endif
2072         sendto_one(by, "%s NOTICE %s%s :Couldn't connect to %s",
2073             NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
2074     }
2075     free_client(cptr);
2076     return -1;
2077   }
2078
2079   set_non_blocking(cptr->fd, cptr);
2080   set_sock_opts(cptr->fd, cptr);
2081   signal(SIGALRM, dummy);
2082   alarm(4);
2083   if (connect(cptr->fd, svp, len) < 0 && errno != EINPROGRESS)
2084   {
2085     int err = get_sockerr(cptr);
2086     errtmp = errno;             /* other system calls may eat errno */
2087     alarm(0);
2088     report_error("Connect to host %s failed: %s", cptr);
2089     if (by && IsUser(by) && !MyUser(by))
2090     {
2091 #ifndef NO_PROTOCOL9
2092       if (Protocol(by->from) < 10)
2093         sendto_one(by, ":%s NOTICE %s :Connect to host %s failed: %s",
2094             me.name, by->name, get_client_name(cptr, TRUE), strerror(err));
2095       else
2096 #endif
2097         sendto_one(by, "%s NOTICE %s%s :Connect to host %s failed: %s",
2098             NumServ(&me), NumNick(by), get_client_name(cptr, TRUE),
2099             strerror(err));
2100     }
2101     close(cptr->fd);
2102     cptr->fd = -2;
2103     free_client(cptr);
2104     errno = errtmp;
2105     if (errno == EINTR)
2106       errno = ETIMEDOUT;
2107     return -1;
2108   }
2109   alarm(0);
2110
2111   /*
2112    * Attach config entries to client here rather than in
2113    * completed_connection. This to avoid null pointer references
2114    * when name returned by gethostbyaddr matches no C lines
2115    * (could happen in 2.6.1a when host and servername differ).
2116    * No need to check access and do gethostbyaddr calls.
2117    * There must at least be one as we got here C line...  meLazy
2118    */
2119   attach_confs_host(cptr, aconf->host,
2120       CONF_NOCONNECT_SERVER | CONF_CONNECT_SERVER);
2121
2122   if (!find_conf_host(cptr->confs, aconf->host, CONF_NOCONNECT_SERVER) ||
2123       !find_conf_host(cptr->confs, aconf->host, CONF_CONNECT_SERVER))
2124   {
2125     sendto_ops("Host %s is not enabled for connecting:no C/N-line",
2126         aconf->host);
2127     if (by && IsUser(by) && !MyUser(by))
2128     {
2129 #ifndef NO_PROTOCOL9
2130       if (Protocol(by->from) < 10)
2131         sendto_one(by,
2132             ":%s NOTICE %s :Connect to host %s failed: no C/N-lines",
2133             me.name, by->name, get_client_name(cptr, TRUE));
2134       else
2135 #endif
2136         sendto_one(by,
2137             "%s NOTICE %s%s :Connect to host %s failed: no C/N-lines",
2138             NumServ(&me), NumNick(by), get_client_name(cptr, TRUE));
2139     }
2140     det_confs_butmask(cptr, 0);
2141     close(cptr->fd);
2142     cptr->fd = -2;
2143     free_client(cptr);
2144     return (-1);
2145   }
2146   /*
2147    * The socket has been connected or connect is in progress.
2148    */
2149   make_server(cptr);
2150   if (by && IsUser(by))
2151   {
2152     sprintf_irc(cptr->serv->by, "%s%s", NumNick(by));
2153     if (cptr->serv->user)
2154       free_user(cptr->serv->user, NULL);
2155     cptr->serv->user = by->user;
2156     by->user->refcnt++;
2157   }
2158   else
2159   {
2160     *cptr->serv->by = '\0';
2161     if (cptr->serv->user)
2162       free_user(cptr->serv->user, NULL);
2163     cptr->serv->user = NULL;
2164   }
2165   cptr->serv->up = &me;
2166   if (cptr->fd > highest_fd)
2167     highest_fd = cptr->fd;
2168   loc_clients[cptr->fd] = cptr;
2169   cptr->acpt = &me;
2170   SetConnecting(cptr);
2171
2172   get_sockhost(cptr, aconf->host);
2173   Count_newunknown(nrof);
2174   add_client_to_list(cptr);
2175   hAddClient(cptr);
2176   nextping = now;
2177
2178   return 0;
2179 }
2180
2181 static struct sockaddr *connect_inet(aConfItem *aconf, aClient *cptr, int *lenp)
2182 {
2183   static struct sockaddr_in server;
2184   Reg3 struct hostent *hp;
2185   struct sockaddr_in bindaddr;
2186
2187   /*
2188    * Might as well get sockhost from here, the connection is attempted
2189    * with it so if it fails its useless.
2190    */
2191   alarm(2);
2192   cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
2193   alarm(0);
2194   if (cptr->fd == -1 && errno == EAGAIN)
2195   {
2196     sendto_ops("opening stream socket to server %s: No more sockets",
2197         get_client_name(cptr, TRUE));
2198     return NULL;
2199   }
2200   if (cptr->fd == -1)
2201   {
2202     report_error("opening stream socket to server %s: %s", cptr);
2203     return NULL;
2204   }
2205   if (cptr->fd >= MAXCLIENTS)
2206   {
2207     sendto_ops("No more connections allowed (%s)", cptr->name);
2208     return NULL;
2209   }
2210   mysk.sin_port = 0;
2211   memset(&server, 0, sizeof(server));
2212   server.sin_family = AF_INET;
2213   get_sockhost(cptr, aconf->host);
2214
2215   /*
2216    * Bind to a local IP# (with unknown port - let unix decide) so
2217    * we have some chance of knowing the IP# that gets used for a host
2218    * with more than one IP#.
2219    */
2220   memcpy(&bindaddr, &cserv, sizeof(bindaddr));
2221   if (aconf->ipnum.s_addr == 0x100007f)
2222     bindaddr.sin_addr.s_addr = 0x100007f;       /* bind with localhost when we are connecting to localhost */
2223   if (bind(cptr->fd, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) == -1)
2224   {
2225     report_error("error binding to local port for %s: %s", cptr);
2226     return NULL;
2227   }
2228
2229   /*
2230    * By this point we should know the IP# of the host listed in the
2231    * conf line, whether as a result of the hostname lookup or the ip#
2232    * being present instead. If we dont know it, then the connect fails.
2233    */
2234   if (isDigit(*aconf->host) && (aconf->ipnum.s_addr == INADDR_NONE))
2235     aconf->ipnum.s_addr = inet_addr(aconf->host);
2236   if (aconf->ipnum.s_addr == INADDR_NONE)
2237   {
2238     hp = cptr->hostp;
2239     if (!hp)
2240     {
2241       Debug((DEBUG_FATAL, "%s: unknown host", aconf->host));
2242       return NULL;
2243     }
2244     memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2245   }
2246   memcpy(&server.sin_addr, &aconf->ipnum, sizeof(struct in_addr));
2247   memcpy(&cptr->ip, &aconf->ipnum, sizeof(struct in_addr));
2248 #ifdef TESTNET
2249   server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum) + 10000);
2250 #else
2251   server.sin_port = htons(((aconf->port > 0) ? aconf->port : portnum));
2252 #endif
2253   *lenp = sizeof(server);
2254   return (struct sockaddr *)&server;
2255 }
2256
2257 #ifdef  UNIXPORT
2258 /*
2259  * connect_unix
2260  *
2261  * Build a socket structure for cptr so that it can connet to the unix
2262  * socket defined by the conf structure aconf.
2263  */
2264 static struct sockaddr *connect_unix(aConfItem *aconf, aClient *cptr, int *lenp)
2265 {
2266   static struct sockaddr_un sock;
2267
2268   alarm(2);
2269   cptr->fd = socket(AF_UNIX, SOCK_STREAM, 0);
2270   alarm(0);
2271   if (cptr->fd == -1 && errno == EAGAIN)
2272   {
2273     sendto_ops("Unix domain connect to host %s failed: No more sockets",
2274         get_client_name(cptr, TRUE));
2275     return NULL;
2276   }
2277   if (cptr->fd == -1)
2278   {
2279     report_error("Unix domain connect to host %s failed: %s", cptr);
2280     return NULL;
2281   }
2282   else if (cptr->fd >= MAXCLIENTS)
2283   {
2284     sendto_ops("No more connections allowed (%s)", cptr->name);
2285     return NULL;
2286   }
2287
2288   get_sockhost(cptr, aconf->host);
2289   /* +2 needed for working Unix domain -- dl */
2290   strncpy(sock.sun_path, aconf->host + 2, sizeof(sock.sun_path) - 1);
2291   sock.sun_path[sizeof(sock.sun_path) - 1] = 0;
2292   sock.sun_family = AF_UNIX;
2293   *lenp = strlen(sock.sun_path) + 2;
2294
2295   SetUnixSock(cptr);
2296   return (struct sockaddr *)&sock;
2297 }
2298
2299 #endif
2300
2301 /*
2302  * Find the real hostname for the host running the server (or one which
2303  * matches the server's name) and its primary IP#.  Hostname is stored
2304  * in the client structure passed as a pointer.
2305  */
2306 void get_my_name(aClient *cptr, char *name, size_t len)
2307 {
2308   static char tmp[HOSTLEN + 1];
2309 #if HAVE_UNAME
2310   struct utsname utsn;
2311 #endif
2312   struct hostent *hp;
2313   char *cname = cptr->name;
2314   size_t len2;
2315
2316   /*
2317    * Setup local socket structure to use for binding to.
2318    */
2319   memset(&mysk, 0, sizeof(mysk));
2320   mysk.sin_family = AF_INET;
2321
2322 #if HAVE_UNAME
2323   if (uname(&utsn) == -1)
2324     return;
2325   len2 = strlen(utsn.nodename);
2326   if (len2 > len)
2327     len2 = len;
2328   strncpy(name, utsn.nodename, len2);
2329 #else /* HAVE_GETHOSTNAME */
2330   if (gethostname(name, len) == -1)
2331     return;
2332 #endif
2333   name[len] = '\0';
2334
2335   /* Assume that a name containing '.' is a FQDN */
2336   if (!strchr(name, '.'))
2337     add_local_domain(name, len - strlen(name));
2338
2339   /*
2340    * If hostname gives another name than cname, then check if there is
2341    * a CNAME record for cname pointing to hostname. If so accept
2342    * cname as our name.   meLazy
2343    */
2344   if (BadPtr(cname))
2345     return;
2346   if ((hp = gethostbyname(cname)) || (hp = gethostbyname(name)))
2347   {
2348     const char *hname;
2349     int i = 0;
2350
2351     for (hname = hp->h_name; hname; hname = hp->h_aliases[i++])
2352     {
2353       strncpy(tmp, hname, sizeof(tmp) - 1);
2354       add_local_domain(tmp, sizeof(tmp) - 1 - strlen(tmp));
2355
2356       /*
2357        * Copy the matching name over and store the
2358        * 'primary' IP# as 'myip' which is used
2359        * later for making the right one is used
2360        * for connecting to other hosts.
2361        */
2362       if (!strCasediff(me.name, tmp))
2363         break;
2364     }
2365     if (strCasediff(me.name, tmp))
2366       strncpy(name, hp->h_name, len);
2367     else
2368       strncpy(name, tmp, len);
2369     memcpy(&mysk.sin_addr, hp->h_addr, sizeof(struct in_addr));
2370     Debug((DEBUG_DEBUG, "local name is %s", get_client_name(&me, TRUE)));
2371   }
2372   return;
2373 }
2374
2375 /*
2376  * Setup a UDP socket and listen for incoming packets
2377  */
2378 int setup_ping(void)
2379 {
2380   struct sockaddr_in from;
2381   int on = 1;
2382
2383   memset(&from, 0, sizeof(from));
2384   from.sin_addr = cserv.sin_addr;
2385 #ifdef TESTNET
2386   from.sin_port = htons(atoi(UDP_PORT) + 10000);
2387 #else
2388   from.sin_port = htons(atoi(UDP_PORT));
2389 #endif
2390   from.sin_family = AF_INET;
2391
2392   if ((udpfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
2393   {
2394     Debug((DEBUG_ERROR, "socket udp : %s", strerror(errno)));
2395     return -1;
2396   }
2397   if (setsockopt(udpfd, SOL_SOCKET, SO_REUSEADDR,
2398       (OPT_TYPE *)&on, sizeof(on)) == -1)
2399   {
2400 #ifdef  USE_SYSLOG
2401     syslog(LOG_ERR, "setsockopt udp fd %d : %m", udpfd);
2402 #endif
2403     Debug((DEBUG_ERROR, "setsockopt so_reuseaddr : %s", strerror(errno)));
2404     close(udpfd);
2405     udpfd = -1;
2406     return -1;
2407   }
2408   on = 0;
2409   setsockopt(udpfd, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on));
2410   if (bind(udpfd, (struct sockaddr *)&from, sizeof(from)) == -1)
2411   {
2412 #ifdef  USE_SYSLOG
2413     syslog(LOG_ERR, "bind udp.%d fd %d : %m", from.sin_port, udpfd);
2414 #endif
2415     Debug((DEBUG_ERROR, "bind : %s", strerror(errno)));
2416     close(udpfd);
2417     udpfd = -1;
2418     return -1;
2419   }
2420   if (fcntl(udpfd, F_SETFL, FNDELAY) == -1)
2421   {
2422     Debug((DEBUG_ERROR, "fcntl fndelay : %s", strerror(errno)));
2423     close(udpfd);
2424     udpfd = -1;
2425     return -1;
2426   }
2427   return udpfd;
2428 }
2429
2430 /*
2431  * max # of pings set to 15/sec.
2432  */
2433 static void polludp(void)
2434 {
2435   Reg1 char *s;
2436   struct sockaddr_in from;
2437   int n;
2438   size_t fromlen = sizeof(from);
2439   static time_t last = 0;
2440   static int cnt = 0, mlen = 0;
2441
2442   /*
2443    * find max length of data area of packet.
2444    */
2445   if (!mlen)
2446   {
2447     mlen = sizeof(readbuf) - strlen(me.name) - strlen(version);
2448     mlen -= 6;
2449     if (mlen < 0)
2450       mlen = 0;
2451   }
2452   Debug((DEBUG_DEBUG, "udp poll"));
2453
2454   n = recvfrom(udpfd, readbuf, mlen, 0, (struct sockaddr *)&from, &fromlen);
2455   if (now == last)
2456     if (++cnt > 14)
2457       return;
2458   cnt = 0;
2459   last = now;
2460
2461   if (n == -1)
2462   {
2463     if ((errno == EWOULDBLOCK) || (errno == EAGAIN))
2464       return;
2465     else
2466     {
2467       report_error("udp port recvfrom (%s): %s", &me);
2468       return;
2469     }
2470   }
2471   ircstp->is_udp++;
2472   if (n < 19)
2473     return;
2474
2475   s = readbuf + n;
2476   /*
2477    * attach my name and version for the reply
2478    */
2479   *readbuf |= 1;
2480   strcpy(s, me.name);
2481   s += strlen(s) + 1;
2482   strcpy(s, version);
2483   s += strlen(s);
2484   sendto(udpfd, readbuf, s - readbuf, 0,
2485       (struct sockaddr *)&from, sizeof(from));
2486   return;
2487 }
2488
2489 /*
2490  * do_dns_async
2491  *
2492  * Called when the fd returned from init_resolver() has been selected for
2493  * reading.
2494  */
2495 static void do_dns_async(void)
2496 {
2497   static Link ln;
2498   aClient *cptr;
2499   aConfItem *aconf;
2500   struct hostent *hp;
2501
2502   ln.flags = ASYNC_NONE;
2503   hp = get_res((char *)&ln);
2504
2505   Debug((DEBUG_DNS, "%p = get_res(%d,%p)", hp, ln.flags, ln.value.cptr));
2506
2507   switch (ln.flags)
2508   {
2509     case ASYNC_NONE:
2510       /*
2511        * No reply was processed that was outstanding or had a client
2512        * still waiting.
2513        */
2514       break;
2515     case ASYNC_CLIENT:
2516       if ((cptr = ln.value.cptr))
2517       {
2518         del_queries((char *)cptr);
2519         ClearDNS(cptr);
2520         if (!DoingAuth(cptr))
2521           SetAccess(cptr);
2522         cptr->hostp = hp;
2523       }
2524       break;
2525     case ASYNC_CONNECT:
2526       aconf = ln.value.aconf;
2527       if (hp && aconf)
2528       {
2529         memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2530         connect_server(aconf, NULL, hp);
2531       }
2532       else
2533         sendto_ops("Connect to %s failed: host lookup",
2534             (aconf) ? aconf->host : "unknown");
2535       break;
2536     case ASYNC_PING:
2537       cptr = ln.value.cptr;
2538       del_queries((char *)cptr);
2539       if (hp)
2540       {
2541         memcpy(&cptr->ip, hp->h_addr, sizeof(struct in_addr));
2542         if (ping_server(cptr) == -1)
2543           end_ping(cptr);
2544       }
2545       else
2546       {
2547         sendto_ops("Udp ping to %s failed: host lookup", cptr->sockhost);
2548         end_ping(cptr);
2549       }
2550       break;
2551     case ASYNC_CONF:
2552       aconf = ln.value.aconf;
2553       if (hp && aconf)
2554         memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
2555       break;
2556     default:
2557       break;
2558   }
2559 }