/* void report_adns_servers(struct Client *source_p) * Input: A client to send a list of DNS servers to. * Output: None * Side effects: Sends a list of DNS servers to source_p */ void report_adns_servers(struct Client *source_p) { int x; char buf[16]; /* XXX: adns only deals with ipv4 dns servers so this is okay */ for(x = 0; x < dns_state->nservers; x++) { inetntop(AF_INET, &dns_state->servers[x].addr.s_addr, buf, 16); sendto_one(source_p, form_str(RPL_STATSALINE), me.name, source_p->name, buf); } }
/* void report_adns_servers(struct Client *source_p) * Input: A client to send a list of DNS servers to. * Output: None * Side effects: Sends a list of DNS servers to source_p */ void report_adns_servers(struct Client *source_p) { int x; char buf[16]; /* XXX: adns only deals with ipv4 dns servers so this is okay */ for (x = 0; x < dns_state->nservers; x++) { inetntop(AF_INET, &dns_state->servers[x].addr.s_addr, buf, 16); sendto_one_numeric(source_p, RPL_STATSDEBUG, "A %s", buf); } }
char *get_client_name(aClient *sptr, int showip) { static char nbuf[HOSTLEN * 2 + USERLEN + 5]; if (MyConnect(sptr)) { #ifdef UNIXPORT if (IsUnixSocket(sptr)) { if (showip) sprintf(nbuf, "%s[%s]", sptr->name, sptr->sockhost); else sprintf(nbuf, "%s[%s]", sptr->name, me.sockhost); } else #endif { if (showip) (void)sprintf(nbuf, "%s[%.*s@%s]", sptr->name, USERLEN, (!(sptr->flags & FLAGS_GOTID)) ? "" : sptr->auth, sptr->user ? sptr->user->sip : #ifdef INET6 inetntop(AF_INET6, (char *)&sptr->ip, ipv6string, sizeof(ipv6string)) #else inetntoa((char *)&sptr->ip) #endif ); else { if (mycmp(sptr->name, sptr->sockhost)) /* Show username for clients and * ident for others. */ sprintf(nbuf, "%s[%.*s@%s]", sptr->name, USERLEN, IsPerson(sptr) ? sptr->user->username : sptr->auth, IsPerson(sptr) ? sptr->user->host : sptr->sockhost); else return sptr->name; } } return nbuf; } return sptr->name; }
void remove_ipv6_mapping(struct irc_ssaddr *addr) { if (addr->ss.ss_family == AF_INET6) { struct sockaddr_in6 *v6; v6 = (struct sockaddr_in6*)addr; if (IN6_IS_ADDR_V4MAPPED(&v6->sin6_addr)) { char v4ip[HOSTIPLEN]; struct sockaddr_in *v4 = (struct sockaddr_in*)addr; inetntop(AF_INET6, &v6->sin6_addr, v4ip, HOSTIPLEN); inet_pton(AF_INET, v4ip, &v4->sin_addr); addr->ss.ss_family = AF_INET; addr->ss_len = sizeof(struct sockaddr_in); } else addr->ss_len = sizeof(struct sockaddr_in6); } else addr->ss_len = sizeof(struct sockaddr_in); }
static int inetport(struct Listener *listener) { int fd; int opt = 1; /* * At first, open a new socket */ fd = comm_socket(listener->addr.ss_family, SOCK_STREAM, 0, "Listener socket"); #ifdef IPV6 if(listener->addr.ss_family == AF_INET6) { struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &listener->addr; if(!IN6_ARE_ADDR_EQUAL(&in6->sin6_addr, &in6addr_any)) { inetntop(AF_INET6, &in6->sin6_addr, listener->vhost, sizeof(listener->vhost)); listener->name = listener->vhost; } } else #endif { struct sockaddr_in *in = (struct sockaddr_in *) &listener->addr; if(in->sin_addr.s_addr != INADDR_ANY) { inetntop(AF_INET, &in->sin_addr, listener->vhost, sizeof(listener->vhost)); listener->name = listener->vhost; } } if(fd == -1) { report_error("opening listener socket %s:%s", get_listener_name(listener), get_listener_name(listener), errno); return 0; } else if((maxconnections - 10) < fd) { report_error("no more connections left for listener %s:%s", get_listener_name(listener), get_listener_name(listener), errno); comm_close(fd); return 0; } /* * XXX - we don't want to do all this crap for a listener * set_sock_opts(listener); */ if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt))) { report_error("setting SO_REUSEADDR for listener %s:%s", get_listener_name(listener), get_listener_name(listener), errno); comm_close(fd); return 0; } /* * Bind a port to listen for new connections if port is non-null, * else assume it is already open and try get something from it. */ if(bind(fd, (struct sockaddr *) &listener->addr, GET_SS_LEN(listener->addr))) { report_error("binding listener socket %s:%s", get_listener_name(listener), get_listener_name(listener), errno); comm_close(fd); return 0; } if(listen(fd, RATBOX_SOMAXCONN)) { report_error("listen failed for %s:%s", get_listener_name(listener), get_listener_name(listener), errno); comm_close(fd); return 0; } listener->fd = fd; /* Listen completion events are READ events .. */ accept_connection(fd, listener); return 1; }
static int inetport(struct Listener* listener) { struct irc_sockaddr lsin; int fd; int opt = 1; /* * At first, open a new socket */ fd = comm_open(DEF_FAM, SOCK_STREAM, 0, "Listener socket"); #ifdef IPV6 if (!IN6_ARE_ADDR_EQUAL((struct in6_addr *)&listener->addr, &in6addr_any)) { #else if (INADDR_ANY != listener->addr.sins.sin.s_addr) { #endif inetntop(DEF_FAM, &IN_ADDR(listener->addr), listener->vhost, HOSTLEN); listener->name = listener->vhost; } if (fd == -1) { report_error(L_ALL, "opening listener socket %s:%s", get_listener_name(listener), errno); return 0; } else if ((HARD_FDLIMIT - 10) < fd) { report_error(L_ALL, "no more connections left for listener %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } /* * XXX - we don't want to do all this crap for a listener * set_sock_opts(listener); */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(opt))) { report_error(L_ALL, "setting SO_REUSEADDR for listener %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } /* * Bind a port to listen for new connections if port is non-null, * else assume it is already open and try get something from it. */ memset(&lsin, 0, sizeof(struct irc_sockaddr)); S_FAM(lsin) = DEF_FAM; copy_s_addr(S_ADDR(lsin), IN_ADDR(listener->addr)); S_PORT(lsin) = htons(listener->port); if (bind(fd, (struct sockaddr*) &SOCKADDR(lsin), sizeof(struct irc_sockaddr))) { report_error(L_ALL, "binding listener socket %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } if (listen(fd, HYBRID_SOMAXCONN)) { report_error(L_ALL, "listen failed for %s:%s", get_listener_name(listener), errno); fd_close(fd); return 0; } /* * XXX - this should always work, performance will suck if it doesn't */ if (!set_non_blocking(fd)) report_error(L_ALL, NONB_ERROR_MSG, get_listener_name(listener), errno); listener->fd = fd; /* Listen completion events are READ events .. */ accept_connection(fd, listener); return 1; } static struct Listener* find_listener(int port, struct irc_inaddr *addr) { struct Listener* listener = NULL; struct Listener* last_closed = NULL; for (listener = ListenerPollList; listener; listener = listener->next) { if ( (port == listener->port) && (!memcmp(&PIN_ADDR(addr), &IN_ADDR(listener->addr), sizeof(struct irc_inaddr)))) { /* Try to return an open listener, otherwise reuse a closed one */ if (listener->fd == -1) last_closed = listener; else return listener; } } return last_closed; } /* * add_listener- create a new listener * port - the port number to listen on * vhost_ip - if non-null must contain a valid IP address string in * the format "255.255.255.255" */ void add_listener(int port, const char* vhost_ip) { struct Listener* listener; struct irc_inaddr vaddr; /* * if no port in conf line, don't bother */ if (port == 0) return; #ifdef IPV6 copy_s_addr(IN_ADDR(vaddr), &in6addr_any); #else copy_s_addr(IN_ADDR(vaddr), INADDR_ANY); #endif if (vhost_ip) { if(inetpton(DEF_FAM, vhost_ip, &IN_ADDR(vaddr)) <= 0) return; } if ((listener = find_listener(port, &vaddr))) { if (listener->fd > -1) return; } else { listener = make_listener(port, &vaddr); listener->next = ListenerPollList; ListenerPollList = listener; } listener->fd = -1; if (inetport(listener)) listener->active = 1; else close_listener(listener); } /* * close_listener - close a single listener */ void close_listener(struct Listener* listener) { assert(listener != NULL); if(listener == NULL) return; if (listener->fd >= 0) { fd_close(listener->fd); listener->fd = -1; } listener->active = 0; if (listener->ref_count) return; free_listener(listener); }
static int inetport(struct Listener* listener) { struct SOCKADDR_IN port_sin; int fd; int opt = 1; /* * At first, open a new socket */ fd = socket(AFINET, SOCK_STREAM, 0); if (-1 == fd) { report_error("opening listener socket %s:%s", get_listener_name(listener), errno); return 0; } else if ((HARD_FDLIMIT - 10) < fd) { report_error("no more connections left for listener %s:%s", get_listener_name(listener), errno); CLOSE(fd); return 0; } /* * XXX - we don't want to do all this crap for a listener * set_sock_opts(listener); */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*) &opt, sizeof(opt))) { report_error("setting SO_REUSEADDR for listener %s:%s", get_listener_name(listener), errno); CLOSE(fd); return 0; } /* * Bind a port to listen for new connections if port is non-null, * else assume it is already open and try get something from it. */ memset(&port_sin, 0, sizeof(port_sin)); port_sin.SIN_FAMILY = AFINET; port_sin.SIN_PORT = htons(listener->port); #ifdef __CYGWIN__ port_sin.sin_addr = listener->addr; if (INADDR_ANY != listener->addr.S_ADDR) { strncpy_irc(listener->vhost, inetntoa((char *)&listener->addr), HOSTLEN); listener->name = listener->vhost; } #else #ifdef IPV6 bcopy((const char*)listener->addr.S_ADDR, (char*)port_sin.SIN_ADDR.S_ADDR, sizeof(struct IN_ADDR)); if ( bcmp((char*)listener->addr.S_ADDR, &INADDRANY, sizeof(struct IN_ADDR)) == 0 ) #else port_sin.sin_addr = listener->addr; if (INADDRANY != listener->addr.s_addr) #endif { struct addrinfo *ans; int ret; char port[5]; char tmp[HOSTLEN]; /* * XXX - blocking call to getaddrinfo */ sprintf( port, "%d", listener->port); #ifdef IPV6 inetntop(AFINET, &listener->addr, tmp, HOSTLEN); #else inet_ntop(AF_INET, &listener->addr, tmp, HOSTLEN); #endif ret = getaddrinfo(tmp, port, NULL, &ans ); if( ret == 0 && ans->ai_canonname) strncpy_irc(listener->vhost, ans->ai_canonname, HOSTLEN); } #endif if (bind(fd, (struct sockaddr*) &port_sin, sizeof(port_sin))) { report_error("binding listener socket %s:%s", get_listener_name(listener), errno); CLOSE(fd); return 0; } if (listen(fd, HYBRID_SOMAXCONN)) { report_error("listen failed for %s:%s", get_listener_name(listener), errno); CLOSE(fd); return 0; } /* * XXX - this should always work, performance will suck if it doesn't */ if (!set_non_blocking(fd)) report_error(NONB_ERROR_MSG, get_listener_name(listener), errno); listener->fd = fd; return 1; }
/* * start_auth * * Flag the client to show that an attempt to contact the ident server on * the client's host. The connect and subsequently the socket are all put * into 'non-blocking' mode. Should the connect or any later phase of the * identifing process fail, it is aborted and the user is given a username * of "unknown". */ void start_auth(aClient *cptr) { #ifndef NO_IDENT struct SOCKADDR_IN us, them; SOCK_LEN_TYPE ulen, tlen; # if defined(USE_IAUTH) if ((iauth_options & XOPT_REQUIRED) && adfd < 0) return; # endif Debug((DEBUG_NOTICE,"start_auth(%x) fd %d status %d", cptr, cptr->fd, cptr->status)); if ((cptr->authfd = socket(AFINET, SOCK_STREAM, 0)) == -1) { # ifdef USE_SYSLOG syslog(LOG_ERR, "Unable to create auth socket for %s:%m", get_client_name(cptr,TRUE)); # endif Debug((DEBUG_ERROR, "Unable to create auth socket for %s:%s", get_client_name(cptr, TRUE), strerror(get_sockerr(cptr)))); ircstp->is_abad++; return; } if (cptr->authfd >= (MAXCONNECTIONS - 2)) { sendto_flag(SCH_ERROR, "Can't allocate fd for auth on %s", get_client_name(cptr, TRUE)); (void)close(cptr->authfd); return; } set_non_blocking(cptr->authfd, cptr); /* get remote host peer - so that we get right interface -- jrg */ tlen = ulen = sizeof(us); if (getpeername(cptr->fd, (struct sockaddr *)&them, &tlen) < 0) { /* we probably don't need this error message -kalt */ report_error("getpeername for auth request %s:%s", cptr); close(cptr->authfd); cptr->authfd = -1; return; } them.SIN_FAMILY = AFINET; /* We must bind the local end to the interface that they connected to: The local system might have more than one network address, and RFC931 check only sends port numbers: server takes IP addresses from query socket -- jrg */ (void)getsockname(cptr->fd, (struct sockaddr *)&us, &ulen); us.SIN_FAMILY = AFINET; # if defined(USE_IAUTH) if (adfd >= 0) { char abuf[BUFSIZ]; # ifdef INET6 sprintf(abuf, "%d C %s %u ", cptr->fd, inetntop(AF_INET6, (char *)&them.sin6_addr, ipv6string, sizeof(ipv6string)), ntohs(them.SIN_PORT)); sprintf(abuf+strlen(abuf), "%s %u", inetntop(AF_INET6, (char *)&us.sin6_addr, ipv6string, sizeof(ipv6string)), ntohs(us.SIN_PORT)); # else sprintf(abuf, "%d C %s %u ", cptr->fd, inetntoa((char *)&them.sin_addr),ntohs(them.SIN_PORT)); sprintf(abuf+strlen(abuf), "%s %u", inetntoa((char *)&us.sin_addr), ntohs(us.SIN_PORT)); # endif if (sendto_iauth(abuf) == 0) { close(cptr->authfd); cptr->authfd = -1; cptr->flags |= FLAGS_XAUTH; return; } } # endif # ifdef INET6 Debug((DEBUG_NOTICE,"auth(%x) from %s %x %x", cptr, inet_ntop(AF_INET6, (char *)&us.sin6_addr, ipv6string, sizeof(ipv6string)), us.sin6_addr.s6_addr[14], us.sin6_addr.s6_addr[15])); # else Debug((DEBUG_NOTICE,"auth(%x) from %s", cptr, inetntoa((char *)&us.sin_addr))); # endif them.SIN_PORT = htons(113); us.SIN_PORT = htons(0); /* bind assigns us a port */ if (bind(cptr->authfd, (struct SOCKADDR *)&us, ulen) >= 0) { (void)getsockname(cptr->fd, (struct SOCKADDR *)&us, &ulen); # ifdef INET6 Debug((DEBUG_NOTICE,"auth(%x) to %s", cptr, inet_ntop(AF_INET6, (char *)&them.sin6_addr, ipv6string, sizeof(ipv6string)))); # else Debug((DEBUG_NOTICE,"auth(%x) to %s", cptr, inetntoa((char *)&them.sin_addr))); # endif (void)alarm((unsigned)4); if (connect(cptr->authfd, (struct SOCKADDR *)&them, tlen) == -1 && errno != EINPROGRESS) { # ifdef INET6 Debug((DEBUG_ERROR, "auth(%x) connect failed to %s - %d", cptr, inet_ntop(AF_INET6, (char *)&them.sin6_addr, ipv6string, sizeof(ipv6string)), errno)); # else Debug((DEBUG_ERROR, "auth(%x) connect failed to %s - %d", cptr, inetntoa((char *)&them.sin_addr), errno)); # endif ircstp->is_abad++; /* * No error report from this... */ (void)alarm((unsigned)0); (void)close(cptr->authfd); cptr->authfd = -1; return; } (void)alarm((unsigned)0); } else { report_error("binding stream socket for auth request %s:%s", cptr); # ifdef INET6 Debug((DEBUG_ERROR,"auth(%x) bind failed on %s port %d - %d", cptr, inet_ntop(AF_INET6, (char *)&us.sin6_addr, ipv6string, sizeof(ipv6string)), ntohs(us.SIN_PORT), errno)); # else Debug((DEBUG_ERROR,"auth(%x) bind failed on %s port %d - %d", cptr, inetntoa((char *)&us.sin_addr), ntohs(us.SIN_PORT), errno)); # endif } cptr->flags |= (FLAGS_WRAUTH|FLAGS_AUTH); if (cptr->authfd > highest_fd) highest_fd = cptr->authfd; #endif return; }
/* * read_iauth * * read and process data from the authentication slave process. */ void read_iauth(void) { static char obuf[READBUF_SIZE+1], last = '?'; static int olen = 0, ia_dbg = 0; char buf[READBUF_SIZE+1], *start, *end, tbuf[BUFSIZ]; aClient *cptr; int i; if (adfd == -1) { olen = 0; return; } while (1) { if (olen) bcopy(obuf, buf, olen); if ((i = recv(adfd, buf+olen, READBUF_SIZE-olen, 0)) <= 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { sendto_flag(SCH_AUTH, "Aiiie! lost slave authentication process (errno = %d)", errno); close(adfd); adfd = -1; olen = 0; start_iauth(0); } break; } olen += i; buf[olen] = '\0'; start = buf; while ((end = index(start, '\n'))) { *end++ = '\0'; last = *start; if (*start == '>') { sendto_flag(SCH_AUTH, "%s", start+1); start = end; continue; } if (*start == 'G') { ia_dbg = atoi(start+2); if (ia_dbg) sendto_flag(SCH_AUTH,"ia_dbg = %d",ia_dbg); start = end; continue; } if (*start == 'O') /* options */ { iauth_options = 0; if (strchr(start+2, 'A')) iauth_options |= XOPT_EARLYPARSE; if (strchr(start+2, 'R')) iauth_options |= XOPT_REQUIRED; if (strchr(start+2, 'T')) iauth_options |= XOPT_NOTIMEOUT; if (strchr(start+2, 'W')) iauth_options |= XOPT_EXTWAIT; if (iauth_options) sendto_flag(SCH_AUTH, "iauth options: %x", iauth_options); start = end; continue; } if (*start == 'V') /* version */ { if (iauth_version) MyFree(iauth_version); iauth_version = mystrdup(start+2); sendto_flag(SCH_AUTH, "iauth version %s running.", iauth_version); start = end; sendto_iauth("0 M %s", me.name); continue; } if (*start == 'a') { aExtCf *ectmp; while ((ectmp = iauth_conf)) { iauth_conf = iauth_conf->next; MyFree(ectmp->line); MyFree(ectmp); } /* little lie.. ;) */ sendto_flag(SCH_AUTH, "New iauth configuration."); start = end; continue; } if (*start == 'A') { aExtCf **ectmp = &iauth_conf; while (*ectmp) ectmp = &((*ectmp)->next); *ectmp = (aExtCf *) MyMalloc(sizeof(aExtCf)); (*ectmp)->line = mystrdup(start+2); (*ectmp)->next = NULL; start = end; continue; } if (*start == 's') { aExtData *ectmp; while ((ectmp = iauth_stats)) { iauth_stats = iauth_stats->next; MyFree(ectmp->line); MyFree(ectmp); } iauth_stats = (aExtData *) MyMalloc(sizeof(aExtData)); iauth_stats->line = MyMalloc(60); sprintf(iauth_stats->line, "iauth modules statistics (%s)", myctime(timeofday)); iauth_stats->next = (aExtData *) MyMalloc(sizeof(aExtData)); iauth_stats->next->line = MyMalloc(60); sprintf(iauth_stats->next->line, "spawned: %d, current options: %X (%.11s)", iauth_spawn, iauth_options, (iauth_version) ? iauth_version : "???"); iauth_stats->next->next = NULL; start = end; continue; } if (*start == 'S') { aExtData **ectmp = &iauth_stats; while (*ectmp) ectmp = &((*ectmp)->next); *ectmp = (aExtData *) MyMalloc(sizeof(aExtData)); (*ectmp)->line = mystrdup(start+2); (*ectmp)->next = NULL; start = end; continue; } if (*start != 'U' && *start != 'u' && *start != 'o' && *start != 'K' && *start != 'k' && *start != 'D') { sendto_flag(SCH_AUTH, "Garbage from iauth [%s]", start); sendto_iauth("-1 E Garbage [%s]", start); /* ** The above should never happen, but i've seen it ** occasionnally, so let's try to get more info ** about it! -kalt */ sendto_flag(SCH_AUTH, "last=%u start=%x end=%x buf=%x olen=%d i=%d", last, start, end, buf, olen, i); sendto_iauth( "-1 E last=%u start=%x end=%x buf=%x olen=%d i=%d", last, start, end, buf, olen, i); start = end; continue; } if ((cptr = local[i = atoi(start+2)]) == NULL) { /* this is fairly common and can be ignored */ if (ia_dbg) { sendto_flag(SCH_AUTH, "Client %d is gone.", i); sendto_iauth("%d E Gone [%s]", i, start); } start = end; continue; } #ifndef INET6 sprintf(tbuf, "%c %d %s %u ", start[0], i, inetntoa((char *)&cptr->ip), cptr->port); #else sprintf(tbuf, "%c %d %s %u ", start[0], i, inetntop(AF_INET6, (char *)&cptr->ip, ipv6string, sizeof(ipv6string)), cptr->port); #endif if (strncmp(tbuf, start, strlen(tbuf))) { /* this is fairly common and can be ignored */ if (ia_dbg) { sendto_flag(SCH_AUTH, "Client mismatch: %d [%s] != [%s]", i, start, tbuf); sendto_iauth("%d E Mismatch [%s] != [%s]", i, start, tbuf); } start = end; continue; } if (start[0] == 'U') { if (*(start+strlen(tbuf)) == '\0') { sendto_flag(SCH_AUTH, "Null U message! %d [%s]", i, start); sendto_iauth("%d E Null U [%s]", i, start); start = end; continue; } if (cptr->auth != cptr->username) { istat.is_authmem -= strlen(cptr->auth) + 1; istat.is_auth -= 1; MyFree(cptr->auth); } cptr->auth = mystrdup(start+strlen(tbuf)); set_clean_username(cptr); cptr->flags |= FLAGS_GOTID; } else if (start[0] == 'u') { if (*(start+strlen(tbuf)) == '\0') { sendto_flag(SCH_AUTH, "Null u message! %d [%s]", i, start); sendto_iauth("%d E Null u [%s]", i, start); start = end; continue; } if (cptr->auth != cptr->username) { istat.is_authmem -= strlen(cptr->auth) + 1; istat.is_auth -= 1; MyFree(cptr->auth); } cptr->auth = MyMalloc(strlen(start+strlen(tbuf)) + 2); *cptr->auth = '-'; strcpy(cptr->auth+1, start+strlen(tbuf)); set_clean_username(cptr); cptr->flags |= FLAGS_GOTID; } else if (start[0] == 'o') { if (!WaitingXAuth(cptr)) { sendto_flag(SCH_AUTH, "Early o message discarded!"); sendto_iauth("%d E Early o [%s]", i,start); start = end; continue; } if (cptr->user == NULL) { /* just to be safe */ sendto_flag(SCH_AUTH, "Ack! cptr->user is NULL"); start = end; continue; } strncpyzt(cptr->user->username, tbuf, USERLEN+1); } else if (start[0] == 'D') { /*authentication finished*/ ClearXAuth(cptr); SetDoneXAuth(cptr); if (WaitingXAuth(cptr)) { ClearWXAuth(cptr); register_user(cptr, cptr, cptr->name, cptr->user->username); } else ClearWXAuth(cptr); } else { char *reason; /* Copy kill reason received from iauth */ reason = strstr(start, " :"); if (reason && (reason + 2 != '\0')) { if (cptr->reason) { MyFree(cptr->reason); } cptr->reason = mystrdup(reason + 2); } /* ** mark for kill, because it cannot be killed ** yet: we don't even know if this is a server ** or a user connection! */ if (start[0] == 'K') cptr->exitc = EXITC_AREF; else cptr->exitc = EXITC_AREFQ; /* should also check to make sure it's still an unregistered client.. */ /* Finally, working after registration. --B. */ if (IsRegisteredUser(cptr)) { if (cptr->exitc == EXITC_AREF) { sendto_flag(SCH_LOCAL, "Denied after connection " "from %s.", get_client_host(cptr)); } (void) exit_client(cptr, cptr, &me, cptr->reason ? cptr->reason : "Denied access"); } } start = end; } olen -= start - buf; if (olen) memcpy(obuf, start, olen); } }