/* msg_client() * * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC * say NOTICE must not auto reply * - pointer to source_p source (struct Client *) * - pointer to target_p target (struct Client *) * - pointer to text * output - NONE * side effects - message given channel either chanop or voice */ static void msg_client(int p_or_n, struct Client *source_p, struct Client *target_p, const char *text) { if (MyClient(source_p)) { if (target_p->away[0] && p_or_n != NOTICE) sendto_one_numeric(source_p, &me, RPL_AWAY, target_p->name, target_p->away); if (HasUMode(target_p, UMODE_REGONLY) && target_p != source_p) { if (!HasUMode(source_p, UMODE_REGISTERED | UMODE_OPER)) { if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, ERR_NONONREG, target_p->name); return; } } } if (MyClient(target_p) && IsClient(source_p)) { if (HasUMode(target_p, UMODE_CALLERID | UMODE_SOFTCALLERID) && !accept_message(source_p, target_p)) { const int callerid = !!HasUMode(target_p, UMODE_CALLERID); /* check for accept, flag recipient incoming message */ if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, RPL_TARGUMODEG, target_p->name, callerid ? "+g" : "+G", callerid ? "server side ignore" : "server side ignore with the exception of common channels"); if ((target_p->connection->last_caller_id_time + ConfigGeneral.caller_id_wait) < CurrentTime) { if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, RPL_TARGNOTIFY, target_p->name); sendto_one_numeric(target_p, &me, RPL_UMODEGMSG, source_p->name, source_p->username, source_p->host, callerid ? "+g" : "+G"); target_p->connection->last_caller_id_time = CurrentTime; } /* Only so opers can watch for floods */ flood_attack_client(NOTICE, source_p, target_p); return; } if (flood_attack_client(p_or_n, source_p, target_p)) return; } sendto_anywhere(target_p, source_p, command[p_or_n], ":%s", text); }
/* msg_client() * * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC * say NOTICE must not auto reply * - pointer to command, "PRIVMSG" or "NOTICE" * - pointer to source_p source (struct Client *) * - pointer to target_p target (struct Client *) * - pointer to text * output - NONE * side effects - message given channel either chanop or voice */ static void msg_client(int p_or_n, const char *command, struct Client *source_p, struct Client *target_p, const char *text) { if (MyClient(source_p)) { if (target_p->away[0] && p_or_n != NOTICE) sendto_one_numeric(source_p, &me, RPL_AWAY, target_p->name, target_p->away); if (HasUMode(target_p, UMODE_REGONLY) && target_p != source_p) { if (!HasUMode(source_p, UMODE_REGISTERED|UMODE_OPER)) { if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, ERR_NONONREG, target_p->name); return; } } } if (MyClient(target_p)) { if (!IsServer(source_p) && HasUMode(target_p, UMODE_CALLERID|UMODE_SOFTCALLERID)) { /* Here is the anti-flood bot/spambot code -db */ if (HasFlag(source_p, FLAGS_SERVICE) || accept_message(source_p, target_p) || (HasUMode(source_p, UMODE_OPER) && ConfigGeneral.opers_bypass_callerid)) { sendto_one(target_p, ":%s!%s@%s %s %s :%s", source_p->name, source_p->username, source_p->host, command, target_p->name, text); } else { int callerid = !!HasUMode(target_p, UMODE_CALLERID); /* check for accept, flag recipient incoming message */ if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, RPL_TARGUMODEG, target_p->name, callerid ? "+g" : "+G", callerid ? "server side ignore" : "server side ignore with the exception of common channels"); if ((target_p->connection->last_caller_id_time + ConfigGeneral.caller_id_wait) < CurrentTime) { if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, RPL_TARGNOTIFY, target_p->name); sendto_one_numeric(target_p, &me, RPL_UMODEGMSG, get_client_name(source_p, HIDE_IP), callerid ? "+g" : "+G"); target_p->connection->last_caller_id_time = CurrentTime; } /* Only so opers can watch for floods */ flood_attack_client(p_or_n, source_p, target_p); } } else { /* * If the client is remote, we dont perform a special check for * flooding.. as we wouldn't block their message anyway.. this means * we dont give warnings.. we then check if theyre opered * (to avoid flood warnings), lastly if theyre our client * and flooding -- fl */ if (!MyClient(source_p) || HasUMode(source_p, UMODE_OPER) || !flood_attack_client(p_or_n, source_p, target_p)) sendto_anywhere(target_p, source_p, command, ":%s", text); } } else if (!MyClient(source_p) || HasUMode(source_p, UMODE_OPER) || !flood_attack_client(p_or_n, source_p, target_p)) sendto_anywhere(target_p, source_p, command, ":%s", text); }
static int m_cmessage(int p_or_n, const char *command, struct Client *client_p, struct Client *source_p, int parc, const char *parv[]) { struct Client *target_p; struct Channel *chptr; struct membership *msptr; if(!IsFloodDone(source_p)) flood_endgrace(source_p); if((target_p = find_named_person(parv[1])) == NULL) { if(p_or_n != NOTICE) sendto_one_numeric(source_p, ERR_NOSUCHNICK, form_str(ERR_NOSUCHNICK), parv[1]); return 0; } if((chptr = find_channel(parv[2])) == NULL) { if(p_or_n != NOTICE) sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), parv[2]); return 0; } if((msptr = find_channel_membership(chptr, source_p)) == NULL) { if(p_or_n != NOTICE) sendto_one_numeric(source_p, ERR_NOTONCHANNEL, form_str(ERR_NOTONCHANNEL), chptr->chname); return 0; } if(!is_chanop_voiced(msptr)) { if(p_or_n != NOTICE) sendto_one(source_p, form_str(ERR_VOICENEEDED), me.name, source_p->name, chptr->chname); return 0; } if(!IsMember(target_p, chptr)) { if(p_or_n != NOTICE) sendto_one_numeric(source_p, ERR_USERNOTINCHANNEL, form_str(ERR_USERNOTINCHANNEL), target_p->name, chptr->chname); return 0; } if(MyClient(target_p) && (IsSetCallerId(target_p) || (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0])) && !accept_message(source_p, target_p) && !IsOper(source_p)) { if (IsSetRegOnlyMsg(target_p) && !source_p->user->suser[0]) { if (p_or_n != NOTICE) sendto_one_numeric(source_p, ERR_NONONREG, form_str(ERR_NONONREG), target_p->name); return 0; } if(p_or_n != NOTICE) sendto_one_numeric(source_p, ERR_TARGUMODEG, form_str(ERR_TARGUMODEG), target_p->name); if((target_p->localClient->last_caller_id_time + ConfigFileEntry.caller_id_wait) < rb_current_time()) { if(p_or_n != NOTICE) sendto_one_numeric(source_p, RPL_TARGNOTIFY, form_str(RPL_TARGNOTIFY), target_p->name); sendto_one(target_p, form_str(RPL_UMODEGMSG), me.name, target_p->name, source_p->name, source_p->username, source_p->host); target_p->localClient->last_caller_id_time = rb_current_time(); } return 0; } if(p_or_n != NOTICE) source_p->localClient->last = rb_current_time(); sendto_anywhere(target_p, source_p, command, ":%s", parv[3]); return 0; }
/* * handle_opers * * inputs - server pointer * - client pointer * - nick stuff to grok for opers * - text to send if grok * output - none * side effects - all the traditional oper type messages are parsed here. * i.e. "/msg #some.host." * However, syntax has been changed. * previous syntax "/msg #some.host.mask" * now becomes "/msg $#some.host.mask" * previous syntax of: "/msg $some.server.mask" remains * This disambiguates the syntax. */ static void handle_opers(int p_or_n, char *command, struct Client *client_p, struct Client *source_p, char *nick, char *text) { struct Client *target_p; char *host; char *server; char *s; int count; /* * the following two cases allow masks in NOTICEs * (for OPERs only) * * Armin, 8Jun90 ([email protected]) */ if(*nick == '$') { if((*(nick+1) == '$' || *(nick+1) == '#')) nick++; else if(MyOper(source_p)) { sendto_one(source_p, ":%s NOTICE %s :The command %s %s is no longer supported, please use $%s", me.name, source_p->name, command, nick, nick); return; } if ((s = strrchr(nick, '.')) == NULL) { sendto_one(source_p, form_str(source_p,ERR_NOTOPLEVEL), me.name, source_p->name, nick); return; } while (*++s) if (*s == '.' || *s == '*' || *s == '?') break; if (*s == '*' || *s == '?') { sendto_one(source_p, form_str(source_p,ERR_WILDTOPLEVEL), me.name, source_p->name, nick); return; } sendto_match_butone(IsServer(client_p) ? client_p : NULL, source_p, nick + 1, (*nick == '#') ? MATCH_HOST : MATCH_SERVER, "%s $%s :%s", command, nick, text); if ((p_or_n != NOTICE) && source_p->user) source_p->user->last = CurrentTime; return; } /* * user[%host]@server addressed? */ if ((server = strchr(nick, '@')) && (target_p = find_server(server + 1))) { count = 0; /* * Not destined for a user on me :-( */ if (!IsMe(target_p)) { sendto_one(target_p, ":%s %s %s :%s", source_p->name, command, nick, text); if ((p_or_n != NOTICE) && source_p->user) source_p->user->last = CurrentTime; return; } *server = '\0'; if ((host = strchr(nick, '%')) != NULL) *host++ = '\0'; /* Check if someones msg'ing [email protected] */ if (strcmp(nick, "opers") == 0) { sendto_realops_flags(FLAGS_ALL, L_ALL, "To opers: From: %s: %s", source_p->name, text); return; } /* * Look for users which match the destination host * (no host == wildcard) and if one and one only is * found connected to me, deliver message! */ target_p = find_userhost(nick, host, &count); if (target_p != NULL) { if (server != NULL) *server = '@'; if (host != NULL) *--host = '%'; if (count == 1) { sendto_anywhere(target_p, source_p, "%s %s :%s", command, nick, text); if ((p_or_n != NOTICE) && source_p->user) source_p->user->last = CurrentTime; } else sendto_one(source_p, form_str(source_p,ERR_TOOMANYTARGETS), me.name, source_p->name, nick); } } else if (server && *(server+1) && (target_p == NULL)) sendto_one(source_p, form_str(source_p,ERR_NOSUCHSERVER), me.name, source_p->name, server+1); else if (server && (target_p == NULL)) sendto_one(source_p, form_str(source_p,ERR_NOSUCHNICK), me.name, source_p->name, nick); }
/* * msg_client * * inputs - flag 0 if PRIVMSG 1 if NOTICE. RFC * say NOTICE must not auto reply * - pointer to command, "PRIVMSG" or "NOTICE" * - pointer to source_p source (struct Client *) * - pointer to target_p target (struct Client *) * - pointer to text * output - NONE * side effects - message given channel either chanop or voice */ static void msg_client(int p_or_n, char *command, struct Client *source_p, struct Client *target_p, char *text) { if (MyClient(source_p)) { /* reset idle time for message only if its not to self * and its not a notice */ if ((p_or_n != NOTICE) && (source_p != target_p) && source_p->user) source_p->user->last = CurrentTime; if (IsSetSSLaccept(target_p)) { #ifdef HAVE_LIBCRYPTO int fd = source_p->localClient->fd; fde_t *F = (fd > -1)? &fd_table[fd] : NULL; if (F && !F->ssl) { #endif sendto_one(source_p, form_str(source_p,ERR_SSLACCEPTONLY), me.name, source_p->name, target_p->name); return; #ifdef HAVE_LIBCRYPTO } #endif } } if (MyConnect(source_p) && (p_or_n != NOTICE) && target_p->user && target_p->user->away) sendto_one(source_p, form_str(source_p,RPL_AWAY), me.name, source_p->name, target_p->name, target_p->user->away); if (MyClient(target_p)) { if (IsSetRegAccept(target_p) && !(source_p->svsflags & FLAGS_SVS_IDENT)) { if (p_or_n != NOTICE) sendto_one(source_p, form_str(source_p,ERR_REGACCEPTONLY), me.name, source_p->name, target_p->name); return; } if (ConfigFileEntry.spam_wait && (p_or_n != NOTICE) && ((target_p->localClient->last_join_time + ConfigFileEntry.spam_wait > CurrentTime) || (target_p->localClient->last_leave_time + ConfigFileEntry.spam_wait > CurrentTime))) { sendto_anywhere(source_p, target_p, "NOTICE %s :*** I'm joining/leaving a chan, please try again in a few seconds.", source_p->name); return; } if (!IsServer(source_p) && IsSetCallerId(target_p)) { /* Here is the anti-flood bot/spambot code -db */ if (accept_message(source_p, target_p) || (source_p == target_p) || find_z_conf((char *)source_p->user->server)) { sendto_one(target_p, ":%s!%s@%s %s %s :%s", source_p->name, source_p->username, source_p->host, command, target_p->name, translate(target_p, text)); } else { /* check for accept, flag recipient incoming message */ if (p_or_n != NOTICE) sendto_anywhere(source_p, target_p, "NOTICE %s :*** I'm in +g mode (server side ignore).", source_p->name); if ((target_p->localClient->last_caller_id_time + ConfigFileEntry.caller_id_wait) < CurrentTime) { if (p_or_n != NOTICE) sendto_anywhere(source_p, target_p, "NOTICE %s :*** I've been informed you messaged me.", source_p->name); sendto_one(target_p, ":%s NOTICE %s :*** Client %s [%s@%s] is messaging you and you are +g", me.name, target_p->name, source_p->name, source_p->username, source_p->host); target_p->localClient->last_caller_id_time = CurrentTime; } /* Only so opers can watch for floods */ (void)flood_attack_client(p_or_n, source_p, target_p); } } else { /* If the client is remote, we dont perform a special check for * flooding.. as we wouldnt block their message anyway.. this means * we dont give warnings.. we then check if theyre opered * (to avoid flood warnings), lastly if theyre our client * and flooding -- fl */ if (!MyClient(source_p) || IsOper(source_p) || (MyClient(source_p) && !flood_attack_client(p_or_n, source_p, target_p))) sendto_anywhere(target_p, source_p, "%s %s :%s", command, target_p->name, translate(target_p, text)); } } else /* The target is a remote user.. same things apply -- fl */ if (!MyClient(source_p) || IsOper(source_p) || (MyClient(source_p) && !flood_attack_client(p_or_n, source_p, target_p))) sendto_anywhere(target_p, source_p, "%s %s :%s", command, target_p->name, text); return; }