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; }
char *get_client_host(aClient *cptr) { static char nbuf[HOSTLEN * 2 + USERLEN + 5]; if (!MyConnect(cptr)) return cptr->name; if (!cptr->user) return get_client_name(cptr, TRUE); #ifdef UNIXPORT if (IsUnixSocket(cptr)) sprintf(nbuf, "%s[%s]", cptr->name, ME); else #endif (void)sprintf(nbuf, "%s[%-.*s@%-.*s]", cptr->name, USERLEN, (!(cptr->flags & FLAGS_GOTID)) ? "" : cptr->auth, HOSTLEN, cptr->user->sip); return nbuf; }
static void vsendto_prefix_one(struct Client *to, struct Client *from, char *pattern, va_list vlorig) { va_list vl; va_copy(vl,vlorig); if (to && from && MyUser(to) && IsUser(from)) { static char sender[HOSTLEN + NICKLEN + USERLEN + 5]; char *par; int flag = 0; Reg3 anUser *user = from->cli_user; par = va_arg(vl, char *); strcpy(sender, from->name); #if defined(ESNET_NEG) if (user && !(to->cli_connect->negociacion & USER_TOK)) #else if (user) #endif { if (user->username) { strcat(sender, "!"); strcat(sender, user->username); } if (user->host && !MyConnect(from)) { strcat(sender, "@"); #if defined(BDD_VIP) strcat(sender, get_visiblehost(from, NULL)); #else strcat(sender, user->host); #endif flag = 1; } } /* * Flag is used instead of strchr(sender, '@') for speed and * also since username/nick may have had a '@' in them. -avalon */ #if defined(ESNET_NEG) if (!flag && MyConnect(from) && user->host && !(to->cli_connect->negociacion & USER_TOK)) #else if (!flag && MyConnect(from) && user->host) #endif { strcat(sender, "@"); #if defined(BDD_VIP) strcat(sender, get_visiblehost(from, NULL)); #else if (IsUnixSocket(from)) strcat(sender, user->host); else strcat(sender, from->sockhost); #endif } *sendbuf = ':'; strcpy(&sendbuf[1], sender); /* Assuming 'pattern' always starts with ":%s ..." */ vsprintf_irc(sendbuf + strlen(sendbuf), &pattern[3], vl); } else
/* ** exit_client ** This is old "m_bye". Name changed, because this is not a ** protocol function, but a general server utility function. ** ** This function exits a client of *any* type (user, server, etc) ** from this server. Also, this generates all necessary prototol ** messages that this exit may cause. ** ** 1) If the client is a local client, then this implicitly ** exits all other clients depending on this connection (e.g. ** remote clients having 'from'-field that points to this. ** ** 2) If the client is a remote client, then only this is exited. ** ** For convenience, this function returns a suitable value for ** m_funtion return value: ** ** FLUSH_BUFFER if (cptr == sptr) ** 0 if (cptr != sptr) ** ** Parameters: ** ** aClient *cptr ** The local client originating the exit or NULL, if this ** exit is generated by this server for internal reasons. ** This will not get any of the generated messages. ** aClient *sptr ** Client exiting ** aClient *from ** Client firing off this Exit, never NULL! ** char *comment ** Reason for the exit */ int exit_client(aClient *cptr, aClient *sptr, aClient *from, const char *comment) { char comment1[HOSTLEN + HOSTLEN + 2]; if (MyConnect(sptr)) { if (sptr->flags & FLAGS_KILLED) { sendto_flag(SCH_NOTICE, "Killed: %s.", get_client_name(sptr, TRUE)); sptr->exitc = EXITC_KILL; } sptr->flags |= FLAGS_CLOSING; #if (defined(FNAME_USERLOG) || defined(FNAME_CONNLOG) \ || defined(USE_SERVICES)) \ || (defined(USE_SYSLOG) && (defined(SYSLOG_USERS) || defined(SYSLOG_CONN))) if (IsPerson(sptr)) { # if defined(FNAME_USERLOG) || defined(USE_SERVICES) || \ (defined(USE_SYSLOG) && defined(SYSLOG_USERS)) sendto_flog(sptr, EXITC_REG, sptr->user->username, sptr->user->host); # endif # if defined(CLIENTS_CHANNEL) && (CLIENTS_CHANNEL_LEVEL & CCL_QUIT) sendto_flag(SCH_CLIENT, "%s %s %s %s QUIT %c" # if (CLIENTS_CHANNEL_LEVEL & CCL_QUITINFO) " :%s" # endif , sptr->user->uid, sptr->name, sptr->user->username, sptr->user->host, sptr->exitc # if (CLIENTS_CHANNEL_LEVEL & CCL_QUITINFO) , comment # endif ); # endif } else if (!IsService(sptr)) { # if defined(FNAME_CONNLOG) || defined(USE_SERVICES) || \ (defined(USE_SYSLOG) && defined(SYSLOG_CONN)) if (sptr->exitc == '\0' || sptr->exitc == EXITC_REG) { sptr->exitc = EXITC_UNDEF; } sendto_flog(sptr, sptr->exitc, sptr->user && sptr->user->username ? sptr->user->username : "", #ifdef UNIXPORT (IsUnixSocket(sptr)) ? me.sockhost : #endif ((sptr->hostp) ? sptr->hostp->h_name : sptr->sockhost)); # endif } #endif if (MyConnect(sptr)) { if (IsPerson(sptr)) { istat.is_myclnt--; } else if (IsServer(sptr)) { istat.is_myserv--; } else if (IsService(sptr)) { istat.is_myservice--; } else { istat.is_unknown--; } if (istat.is_myclnt % CLCHNO == 0 && istat.is_myclnt != istat.is_l_myclnt) { sendto_flag(SCH_NOTICE, "Local %screase from %d to %d clients " "in %d seconds", istat.is_myclnt>istat.is_l_myclnt?"in":"de", istat.is_l_myclnt, istat.is_myclnt, timeofday - istat.is_l_myclnt_t); istat.is_l_myclnt_t = timeofday; istat.is_l_myclnt = istat.is_myclnt; } /* Send SQUIT message to 2.11 servers to tell them * the squit reason for rebroadcast on the other side * - jv */ if (IsServer(sptr)) { sendto_one(sptr, ":%s SQUIT %s :%s", me.serv->sid, sptr->serv->sid, comment); } if (cptr != NULL && sptr != cptr) { sendto_one(sptr, "ERROR :Closing Link: " "%s %s (%s)", get_client_name(sptr,FALSE), cptr->name, comment); } else { sendto_one(sptr, "ERROR :Closing Link: %s (%s)", get_client_name(sptr,FALSE), comment); } if (sptr->auth != sptr->username) { istat.is_authmem -= strlen(sptr->auth) + 1; istat.is_auth -= 1; MyFree(sptr->auth); sptr->auth = sptr->username; } } /* ** Currently only server connections can have ** depending remote clients here, but it does no ** harm to check for all local clients. In ** future some other clients than servers might ** have remotes too... ** now, I think it harms big client servers... - krys ** ** Close the Client connection first and mark it ** so that no messages are attempted to send to it. ** (The following *must* make MyConnect(sptr) == FALSE!). ** It also makes sptr->from == NULL, thus it's unnecessary ** to test whether "sptr != acptr" in the following loops. */ close_connection(sptr); } /* if (MyConnect(sptr) */ if (IsServer(sptr)) { /* Remove all dependent servers and clients. */ if (!IsMasked(sptr)) { sprintf(comment1, "%s %s", sptr->serv->up->name, sptr->name); } else { /* It was a masked server, the squit reason should ** give the right quit reason for clients. */ strncpyzt(comment1, comment, sizeof(comment1)); } /* cptr != sptr means non-local server */ if (cptr != sptr && nextconnect == 0 && find_conf_name(sptr->name, (CONF_CONNECT_SERVER|CONF_ZCONNECT_SERVER))) { /* try AC */ nextconnect = timeofday + HANGONRETRYDELAY; } exit_server(sptr, sptr, from, comment, comment1); check_split(); if ((cptr == sptr)) { /* It serves no purpose. --B. sendto_flag(SCH_SERVER, "Sending SQUIT %s (%s)", cptr->name, comment); */ return FLUSH_BUFFER; } return 0; } /* ** Try to guess from comment if the client is exiting ** normally (KILL or issued QUIT), or if it is splitting ** It requires comment for splitting users to be ** "server.some.where splitting.some.where" */ comment1[0] = '\0'; if ((sptr->flags & FLAGS_KILLED) == 0) { if (comment[0] == '"') { /* definitely user quit, see m_quit */ sptr->flags |= FLAGS_QUIT; } else { const char *c = comment; int i = 0; while (*c && *c != ' ') if (*c++ == '.') i++; if (*c++ && i) { i = 0; while (*c && *c != ' ') if (*c++ == '.') i++; if (!i || *c) sptr->flags |= FLAGS_QUIT; } else { sptr->flags |= FLAGS_QUIT; } } if (sptr == cptr && !(sptr->flags & FLAGS_QUIT)) { /* ** This will avoid nick delay to be abused by ** letting local users put a comment looking ** like a server split. */ strncpyzt(comment1, comment, HOSTLEN + HOSTLEN); strcat(comment1, " "); sptr->flags |= FLAGS_QUIT; } } exit_one_client(cptr, sptr, from, (*comment1) ? comment1 : comment); /* XXX: we probably should not call it every client exit */ /* checking every server quit should suffice --B. */ /* check_split(); */ return cptr == sptr ? FLUSH_BUFFER : 0; }