00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "stdinc.h"
00028 #include "handlers.h"
00029 #include "client.h"
00030 #include "ircd.h"
00031 #include "numeric.h"
00032 #include "common.h"
00033 #include "s_conf.h"
00034 #include "s_serv.h"
00035 #include "send.h"
00036 #include "msg.h"
00037 #include "parse.h"
00038 #include "modules.h"
00039 #include "channel.h"
00040 #include "channel_mode.h"
00041 #include "irc_string.h"
00042 #include "hash.h"
00043 #include "packet.h"
00044
00045 struct entity
00046 {
00047 void *ptr;
00048 int type;
00049 int flags;
00050 };
00051
00052 static int build_target_list(int p_or_n, const char *command,
00053 struct Client *client_p,
00054 struct Client *source_p,
00055 char *nicks_channels, char *text);
00056
00057 static int flood_attack_client(int p_or_n, struct Client *source_p,
00058 struct Client *target_p);
00059 static int flood_attack_channel(int p_or_n, struct Client *source_p,
00060 struct Channel *chptr, char *chname);
00061 static struct Client* find_userhost (char *, char *, int *);
00062
00063 static int has_ctrl_chars(char *msg);
00064 static int has_colors(char *msg);
00065
00066 #define ENTITY_NONE 0
00067 #define ENTITY_CHANNEL 1
00068 #define ENTITY_CHANOPS_ON_CHANNEL 2
00069 #define ENTITY_CLIENT 3
00070
00071 static struct entity targets[512];
00072 static int ntargets = 0;
00073
00074 static int duplicate_ptr(void *);
00075
00076 static void m_message(int, const char *, struct Client *,
00077 struct Client *, int, char **);
00078
00079 static void m_privmsg(struct Client *, struct Client *, int, char **);
00080 static void m_notice(struct Client *, struct Client *, int, char **);
00081
00082 static void msg_channel(int p_or_n, const char *command,
00083 struct Client *client_p,
00084 struct Client *source_p,
00085 struct Channel *chptr, char *text);
00086
00087 static void msg_channel_flags(int p_or_n, const char *command,
00088 struct Client *client_p,
00089 struct Client *source_p,
00090 struct Channel *chptr, int flags, char *text);
00091
00092 static void msg_client(int p_or_n, const char *command,
00093 struct Client *source_p, struct Client *target_p,
00094 char *text);
00095
00096 static void handle_special(int p_or_n, const char *command,
00097 struct Client *client_p,
00098 struct Client *source_p, char *nick, char *text);
00099
00100 struct Message privmsg_msgtab = {
00101 "PRIVMSG", 0, 0, 1, 0, MFLG_SLOW | MFLG_UNREG, 0L,
00102 {m_unregistered, m_privmsg, m_privmsg, m_ignore, m_privmsg, m_ignore}
00103 };
00104
00105 struct Message notice_msgtab = {
00106 "NOTICE", 0, 0, 1, 0, MFLG_SLOW, 0L,
00107 {m_unregistered, m_notice, m_notice, m_ignore, m_notice, m_ignore}
00108 };
00109
00110 #ifndef STATIC_MODULES
00111 struct Callback *client_message;
00112 struct Callback *channel_message;
00113
00114 void
00115 _modinit(void)
00116 {
00117 mod_add_cmd(&privmsg_msgtab);
00118 mod_add_cmd(¬ice_msgtab);
00119 client_message = register_callback("client_message", NULL);
00120 channel_message = register_callback("channel_message", NULL);
00121 }
00122
00123 void
00124 _moddeinit(void)
00125 {
00126 mod_del_cmd(&privmsg_msgtab);
00127 mod_del_cmd(¬ice_msgtab);
00128 }
00129
00130 const char *_version = "$Revision: 666 $";
00131 #endif
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 #define PRIVMSG 0
00153 #define NOTICE 1
00154
00155 static void
00156 m_privmsg(struct Client *client_p, struct Client *source_p,
00157 int parc, char *parv[])
00158 {
00159
00160
00161
00162 if (!IsClient(source_p))
00163 return;
00164
00165 m_message(PRIVMSG, "PRIVMSG", client_p, source_p, parc, parv);
00166 }
00167
00168 static void
00169 m_notice(struct Client *client_p, struct Client *source_p,
00170 int parc, char *parv[])
00171 {
00172 m_message(NOTICE, "NOTICE", client_p, source_p, parc, parv);
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182 static void
00183 m_message(int p_or_n, const char *command, struct Client *client_p,
00184 struct Client *source_p, int parc, char *parv[])
00185 {
00186 int i;
00187
00188 if (parc < 2 || EmptyString(parv[1]))
00189 {
00190 if (p_or_n != NOTICE)
00191 sendto_one(source_p, form_str(ERR_NORECIPIENT),
00192 ID_or_name(&me, client_p),
00193 ID_or_name(source_p, client_p), command);
00194 return;
00195 }
00196
00197 if (parc < 3 || EmptyString(parv[2]))
00198 {
00199 if (p_or_n != NOTICE)
00200 sendto_one(source_p, form_str(ERR_NOTEXTTOSEND),
00201 ID_or_name(&me, client_p),
00202 ID_or_name(source_p, client_p));
00203 return;
00204 }
00205
00206
00207 if (MyClient(source_p) && !IsFloodDone(source_p))
00208 #if 0
00209 &&
00210 irccmp(source_p->name, parv[1]) != 0)
00211
00212
00213
00214
00215
00216
00217 #endif
00218 flood_endgrace(source_p);
00219
00220 if (build_target_list(p_or_n, command, client_p, source_p, parv[1],
00221 parv[2]) < 0)
00222 {
00223
00224 if (!ServerInfo.hub && (uplink != NULL))
00225 sendto_one(uplink, ":%s %s %s :%s",
00226 source_p->name, command, parv[1], parv[2]);
00227 return;
00228 }
00229
00230 for (i = 0; i < ntargets; i++)
00231 {
00232 switch (targets[i].type)
00233 {
00234 case ENTITY_CHANNEL:
00235 msg_channel(p_or_n, command, client_p, source_p,
00236 (struct Channel *)targets[i].ptr, parv[2]);
00237 break;
00238
00239 case ENTITY_CHANOPS_ON_CHANNEL:
00240 msg_channel_flags(p_or_n, command, client_p, source_p,
00241 (struct Channel *)targets[i].ptr,
00242 targets[i].flags, parv[2]);
00243 break;
00244
00245 case ENTITY_CLIENT:
00246 msg_client(p_or_n, command, source_p,
00247 (struct Client *)targets[i].ptr, parv[2]);
00248 break;
00249 }
00250 }
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 static int
00270 build_target_list(int p_or_n, const char *command, struct Client *client_p,
00271 struct Client *source_p, char *nicks_channels, char *text)
00272 {
00273 int type;
00274 char *p, *nick, *target_list, ncbuf[IRCD_BUFSIZE];
00275 struct Channel *chptr = NULL;
00276 struct Client *target_p = NULL;
00277
00278
00279 if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
00280 {
00281 strlcpy(ncbuf, nicks_channels, sizeof(ncbuf));
00282 target_list = ncbuf;
00283 }
00284 else
00285 target_list = nicks_channels;
00286
00287 ntargets = 0;
00288
00289 for (nick = strtoken(&p, target_list, ","); nick;
00290 nick = strtoken(&p, NULL, ","))
00291 {
00292 char *with_prefix;
00293
00294
00295
00296
00297
00298 if (IsChanPrefix(*nick))
00299 {
00300
00301 if (*nick == '&' && IsServer(client_p))
00302 continue;
00303
00304 if ((chptr = hash_find_channel(nick)) != NULL)
00305 {
00306 if (!duplicate_ptr(chptr))
00307 {
00308 if (ntargets >= ConfigFileEntry.max_targets)
00309 {
00310 sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
00311 ID_or_name(&me, client_p),
00312 ID_or_name(source_p, client_p), nick,
00313 ConfigFileEntry.max_targets);
00314 return (1);
00315 }
00316 targets[ntargets].ptr = (void *)chptr;
00317 targets[ntargets++].type = ENTITY_CHANNEL;
00318 }
00319 }
00320 else
00321 {
00322 if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
00323 return -1;
00324 else if (p_or_n != NOTICE)
00325 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
00326 ID_or_name(&me, client_p),
00327 ID_or_name(source_p, client_p), nick);
00328 }
00329 continue;
00330 }
00331
00332
00333 if ((target_p = find_person(client_p, nick)) != NULL)
00334 {
00335 if (!duplicate_ptr(target_p))
00336 {
00337 if (ntargets >= ConfigFileEntry.max_targets)
00338 {
00339 sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
00340 ID_or_name(&me, client_p),
00341 ID_or_name(source_p, client_p), nick,
00342 ConfigFileEntry.max_targets);
00343 return (1);
00344 }
00345 targets[ntargets].ptr = (void *)target_p;
00346 targets[ntargets].type = ENTITY_CLIENT;
00347 targets[ntargets++].flags = 0;
00348 }
00349 continue;
00350 }
00351
00352
00353
00354 type = 0;
00355 with_prefix = nick;
00356
00357 for (; ;)
00358 {
00359 if (*nick == '@')
00360 type |= CHFL_CHANOP;
00361 #ifdef HALFOPS
00362 else if (*nick == '%')
00363 type |= CHFL_CHANOP | CHFL_HALFOP;
00364 #endif
00365 else if (*nick == '+')
00366 type |= CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE;
00367 else
00368 break;
00369 nick++;
00370 }
00371
00372 if (type != 0)
00373 {
00374
00375 if (*nick == '\0')
00376 {
00377 sendto_one(source_p, form_str(ERR_NORECIPIENT),
00378 ID_or_name(&me, client_p),
00379 ID_or_name(source_p, client_p), command);
00380 continue;
00381 }
00382
00383
00384
00385
00386
00387 if ((chptr = hash_find_channel(nick)) != NULL)
00388 {
00389 if (!has_member_flags(find_channel_link(source_p, chptr),
00390 CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE))
00391 {
00392 sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
00393 ID_or_name(&me, client_p),
00394 ID_or_name(source_p, client_p), with_prefix);
00395 return(-1);
00396 }
00397
00398 if (!duplicate_ptr(chptr))
00399 {
00400 if (ntargets >= ConfigFileEntry.max_targets)
00401 {
00402 sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
00403 ID_or_name(&me, client_p),
00404 ID_or_name(source_p, client_p), nick,
00405 ConfigFileEntry.max_targets);
00406 return(1);
00407 }
00408 targets[ntargets].ptr = (void *)chptr;
00409 targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL;
00410 targets[ntargets++].flags = type;
00411 }
00412 }
00413 else
00414 {
00415 if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
00416 return -1;
00417 else if (p_or_n != NOTICE)
00418 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
00419 ID_or_name(&me, client_p),
00420 ID_or_name(source_p, client_p), nick);
00421 }
00422 continue;
00423 }
00424
00425 if ((*nick == '$') || strchr(nick, '@') != NULL)
00426 {
00427 handle_special(p_or_n, command, client_p, source_p, nick, text);
00428 }
00429 else
00430 {
00431 if (!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL))
00432 return -1;
00433 else if (p_or_n != NOTICE)
00434 {
00435 if (!IsDigit(*nick) || MyClient(source_p))
00436 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
00437 ID_or_name(&me, client_p),
00438 ID_or_name(source_p, client_p), nick);
00439 }
00440 }
00441
00442 }
00443
00444 return(1);
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 static int
00457 duplicate_ptr(void *ptr)
00458 {
00459 int i;
00460
00461 for (i = 0; i < ntargets; i++)
00462 {
00463 if (targets[i].ptr == ptr)
00464 return(1);
00465 }
00466
00467 return(0);
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 static void
00481 msg_channel(int p_or_n, const char *command, struct Client *client_p,
00482 struct Client *source_p, struct Channel *chptr, char *text)
00483 {
00484 int result;
00485
00486 if (MyClient(source_p))
00487 {
00488
00489 if (p_or_n != NOTICE)
00490 source_p->localClient->last = CurrentTime;
00491 }
00492
00493 #ifndef STATIC_MODULES
00494 execute_callback(channel_message, source_p, chptr, text);
00495 #endif
00496
00497
00498 if ((chptr->mode.mode & MODE_ASCIIONLY ) && has_ctrl_chars(text))
00499 {
00500 if (p_or_n != NOTICE)
00501 sendto_one(source_p, form_str(ERR_NOCONTROLSONCHAN),
00502 ID_or_name(&me, client_p),
00503 ID_or_name(source_p, client_p), chptr->chname, chptr->chname);
00504
00505 return;
00506 }
00507 else if ((chptr->mode.mode & MODE_COLORLESS) && has_colors(text))
00508 {
00509 if (p_or_n != NOTICE)
00510 sendto_one(source_p, form_str(ERR_NOCOLORSONCHAN),
00511 ID_or_name(&me, client_p),
00512 ID_or_name(source_p, client_p), chptr->chname, chptr->chname);
00513 return;
00514 }
00515
00516
00517 if ((result = can_send(chptr, source_p, NULL)))
00518 {
00519 if (result == CAN_SEND_OPV ||
00520 !flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
00521 {
00522 sendto_channel_butone(client_p, source_p, chptr, command, ":%s", text);
00523 }
00524 }
00525 else
00526 {
00527 if (p_or_n != NOTICE)
00528 sendto_one(source_p, form_str(ERR_CANNOTSENDTOCHAN),
00529 ID_or_name(&me, client_p),
00530 ID_or_name(source_p, client_p), chptr->chname);
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 static void
00548 msg_channel_flags(int p_or_n, const char *command, struct Client *client_p,
00549 struct Client *source_p, struct Channel *chptr,
00550 int flags, char *text)
00551 {
00552 int type;
00553 char c;
00554
00555 if (flags & CHFL_VOICE)
00556 {
00557 type = CHFL_VOICE|CHFL_HALFOP|CHFL_CHANOP;
00558 c = '+';
00559 }
00560 #ifdef HALFOPS
00561 else if (flags & CHFL_HALFOP)
00562 {
00563 type = CHFL_HALFOP|CHFL_CHANOP;
00564 c = '%';
00565 }
00566 #endif
00567 else
00568 {
00569 type = CHFL_CHANOP;
00570 c = '@';
00571 }
00572
00573 if (MyClient(source_p))
00574 {
00575
00576 if (p_or_n != NOTICE)
00577 source_p->localClient->last = CurrentTime;
00578
00579 sendto_channel_local_butone(source_p, type, chptr, ":%s!%s@%s %s %c%s :%s",
00580 source_p->name, source_p->username,
00581 source_p->host, command, c, chptr->chname, text);
00582 }
00583 else
00584 {
00585
00586
00587
00588
00589 sendto_channel_local(type, YES, chptr, ":%s!%s@%s %s %c%s :%s",
00590 source_p->name, source_p->username,
00591 source_p->host, command, c, chptr->chname, text);
00592 }
00593
00594 if (chptr->chname[0] != '#')
00595 return;
00596
00597 sendto_channel_remote(source_p, client_p, type, CAP_CHW, CAP_TS6, chptr,
00598 ":%s %s %c%s :%s", source_p->name, command, c, chptr->chname, text);
00599 sendto_channel_remote(source_p, client_p, type, CAP_CHW|CAP_TS6, NOCAPS, chptr,
00600 ":%s %s %c%s :%s", ID(source_p), command, c, chptr->chname, text);
00601
00602 }
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615 static void
00616 msg_client(int p_or_n, const char *command, struct Client *source_p,
00617 struct Client *target_p, char *text)
00618 {
00619 if (MyClient(source_p))
00620 {
00621
00622
00623
00624
00625
00626
00627
00628
00629 if ((p_or_n != NOTICE) && (source_p != target_p))
00630 source_p->localClient->last = CurrentTime;
00631 }
00632
00633 #ifndef STATIC_MODULES
00634 execute_callback(client_message, source_p, target_p, text);
00635 #endif
00636
00637 if (MyConnect(source_p) && (p_or_n != NOTICE) && target_p->away)
00638 sendto_one(source_p, form_str(RPL_AWAY), me.name,
00639 source_p->name, target_p->name, target_p->away);
00640
00641 if (MyClient(target_p))
00642 {
00643 if (!IsServer(source_p) && IsSetCallerId(target_p))
00644 {
00645
00646 if (source_p == target_p || accept_message(source_p, target_p) ||
00647 (IsOper(source_p) && (ConfigFileEntry.opers_bypass_callerid == 1)))
00648 {
00649 sendto_one(target_p, ":%s!%s@%s %s %s :%s",
00650 source_p->name, source_p->username,
00651 source_p->host, command, target_p->name, text);
00652 }
00653 else
00654 {
00655
00656 if (p_or_n != NOTICE)
00657 sendto_one(source_p, form_str(RPL_TARGUMODEG),
00658 ID_or_name(&me, source_p->from),
00659 ID_or_name(source_p, source_p->from), target_p->name);
00660
00661 if ((target_p->localClient->last_caller_id_time +
00662 ConfigFileEntry.caller_id_wait) < CurrentTime)
00663 {
00664 if (p_or_n != NOTICE)
00665 sendto_one(source_p, form_str(RPL_TARGNOTIFY),
00666 ID_or_name(&me, source_p->from),
00667 ID_or_name(source_p, source_p->from), target_p->name);
00668
00669 sendto_one(target_p, form_str(RPL_UMODEGMSG),
00670 me.name, target_p->name,
00671 get_client_name(source_p, HIDE_IP));
00672
00673 target_p->localClient->last_caller_id_time = CurrentTime;
00674
00675 }
00676
00677 flood_attack_client(p_or_n, source_p, target_p);
00678 }
00679 }
00680 else
00681 {
00682
00683
00684
00685
00686
00687 if (!MyClient(source_p) || IsOper(source_p) ||
00688 (MyClient(source_p) &&
00689 !flood_attack_client(p_or_n, source_p, target_p)))
00690 sendto_anywhere(target_p, source_p, "%s %s :%s",
00691 command, target_p->name, text);
00692 }
00693 }
00694 else
00695
00696 if (!MyClient(source_p) || IsOper(source_p) ||
00697 (MyClient(source_p)
00698 && !flood_attack_client(p_or_n, source_p, target_p)))
00699 sendto_anywhere(target_p, source_p, "%s %s :%s", command, target_p->name,
00700 text);
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 static int
00713 flood_attack_client(int p_or_n, struct Client *source_p,
00714 struct Client *target_p)
00715 {
00716 int delta;
00717
00718 if (GlobalSetOptions.floodcount && MyConnect(target_p)
00719 && IsClient(source_p) && !IsConfCanFlood(source_p))
00720 {
00721 if ((target_p->localClient->first_received_message_time + 1)
00722 < CurrentTime)
00723 {
00724 delta =
00725 CurrentTime - target_p->localClient->first_received_message_time;
00726 target_p->localClient->received_number_of_privmsgs -= delta;
00727 target_p->localClient->first_received_message_time = CurrentTime;
00728 if (target_p->localClient->received_number_of_privmsgs <= 0)
00729 {
00730 target_p->localClient->received_number_of_privmsgs = 0;
00731 target_p->localClient->flood_noticed = 0;
00732 }
00733 }
00734
00735 if ((target_p->localClient->received_number_of_privmsgs >=
00736 GlobalSetOptions.floodcount) || target_p->localClient->flood_noticed)
00737 {
00738 if (target_p->localClient->flood_noticed == 0)
00739 {
00740 sendto_realops_flags(UMODE_BOTS, L_ALL,
00741 "Possible Flooder %s on %s target: %s",
00742 get_client_name(source_p, HIDE_IP),
00743 source_p->servptr->name, target_p->name);
00744 target_p->localClient->flood_noticed = 1;
00745
00746 target_p->localClient->received_number_of_privmsgs += 2;
00747 }
00748
00749 if (MyClient(source_p) && (p_or_n != NOTICE))
00750 sendto_one(source_p,
00751 ":%s NOTICE %s :*** Message to %s throttled due to flooding",
00752 me.name, source_p->name, target_p->name);
00753 return(1);
00754 }
00755 else
00756 target_p->localClient->received_number_of_privmsgs++;
00757 }
00758
00759 return(0);
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 static int
00772 flood_attack_channel(int p_or_n, struct Client *source_p,
00773 struct Channel *chptr, char *chname)
00774 {
00775 int delta;
00776
00777 if (GlobalSetOptions.floodcount && !IsConfCanFlood(source_p))
00778 {
00779 if ((chptr->first_received_message_time + 1) < CurrentTime)
00780 {
00781 delta = CurrentTime - chptr->first_received_message_time;
00782 chptr->received_number_of_privmsgs -= delta;
00783 chptr->first_received_message_time = CurrentTime;
00784 if (chptr->received_number_of_privmsgs <= 0)
00785 {
00786 chptr->received_number_of_privmsgs = 0;
00787 ClearFloodNoticed(chptr);
00788 }
00789 }
00790
00791 if ((chptr->received_number_of_privmsgs >= GlobalSetOptions.floodcount)
00792 || IsSetFloodNoticed(chptr))
00793 {
00794 if (!IsSetFloodNoticed(chptr))
00795 {
00796 sendto_realops_flags(UMODE_BOTS, L_ALL,
00797 "Possible Flooder %s on %s target: %s",
00798 get_client_name(source_p, HIDE_IP),
00799 source_p->servptr->name, chptr->chname);
00800 SetFloodNoticed(chptr);
00801
00802
00803 chptr->received_number_of_privmsgs += 2;
00804 }
00805 if (MyClient(source_p) && (p_or_n != NOTICE))
00806 sendto_one(source_p,
00807 ":%s NOTICE %s :*** Message to %s throttled due to flooding",
00808 me.name, source_p->name, chname);
00809 return(1);
00810 }
00811 else
00812 chptr->received_number_of_privmsgs++;
00813 }
00814
00815 return(0);
00816 }
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 static void
00840 handle_special(int p_or_n, const char *command, struct Client *client_p,
00841 struct Client *source_p, char *nick, char *text)
00842 {
00843 struct Client *target_p;
00844 char *host;
00845 char *server;
00846 char *s;
00847 int count;
00848
00849
00850
00851
00852 if ((server = strchr(nick, '@')) != NULL)
00853 {
00854 count = 0;
00855
00856 if ((host = strchr(nick, '%')) && !IsOper(source_p))
00857 {
00858 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
00859 ID_or_name(&me, client_p),
00860 ID_or_name(source_p, client_p));
00861 return;
00862 }
00863
00864 if ((target_p = find_server(server + 1)) != NULL)
00865 {
00866 if (!IsMe(target_p))
00867 {
00868
00869
00870
00871 sendto_one(target_p, ":%s %s %s :%s",
00872 ID_or_name(source_p, target_p->from),
00873 command, nick, text);
00874 if ((p_or_n != NOTICE) && MyClient(source_p))
00875 source_p->localClient->last = CurrentTime;
00876 return;
00877 }
00878
00879 *server = '\0';
00880
00881 if (host != NULL)
00882 *host++ = '\0';
00883
00884
00885 if (strcmp(nick, "opers") == 0)
00886 {
00887 if (!IsOper(source_p))
00888 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
00889 ID_or_name(&me, client_p),
00890 ID_or_name(source_p, client_p));
00891 else
00892 sendto_realops_flags(UMODE_ALL, L_ALL, "To opers: From: %s: %s",
00893 source_p->name, text);
00894 return;
00895 }
00896
00897
00898
00899
00900
00901
00902 target_p = find_userhost(nick, host, &count);
00903
00904 if (target_p != NULL)
00905 {
00906 if (server != NULL)
00907 *server = '@';
00908 if (host != NULL)
00909 *--host = '%';
00910
00911 if (count == 1)
00912 {
00913 sendto_one(target_p, ":%s!%s@%s %s %s :%s",
00914 source_p->name, source_p->username, source_p->host,
00915 command, nick, text);
00916 if ((p_or_n != NOTICE) && MyClient(source_p))
00917 source_p->localClient->last = CurrentTime;
00918 }
00919 else
00920 sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
00921 ID_or_name(&me, client_p),
00922 ID_or_name(source_p, client_p), nick,
00923 ConfigFileEntry.max_targets);
00924 }
00925 }
00926 else if (server && *(server+1) && (target_p == NULL))
00927 sendto_one(source_p, form_str(ERR_NOSUCHSERVER),
00928 ID_or_name(&me, client_p),
00929 ID_or_name(source_p, client_p), server+1);
00930 else if (server && (target_p == NULL))
00931 sendto_one(source_p, form_str(ERR_NOSUCHNICK),
00932 ID_or_name(&me, client_p),
00933 ID_or_name(source_p, client_p), nick);
00934 return;
00935 }
00936
00937 if (!IsOper(source_p))
00938 {
00939 sendto_one(source_p, form_str(ERR_NOPRIVILEGES),
00940 ID_or_name(&me, client_p),
00941 ID_or_name(source_p, client_p));
00942 return;
00943 }
00944
00945
00946
00947
00948
00949
00950
00951 if (*nick == '$')
00952 {
00953 if ((*(nick+1) == '$' || *(nick+1) == '#'))
00954 nick++;
00955 else if(MyOper(source_p))
00956 {
00957 sendto_one(source_p,
00958 ":%s NOTICE %s :The command %s %s is no longer supported, please use $%s",
00959 me.name, source_p->name, command, nick, nick);
00960 return;
00961 }
00962
00963 if ((s = strrchr(nick, '.')) == NULL)
00964 {
00965 sendto_one(source_p, form_str(ERR_NOTOPLEVEL),
00966 me.name, source_p->name, nick);
00967 return;
00968 }
00969
00970 while (*++s)
00971 if (*s == '.' || *s == '*' || *s == '?')
00972 break;
00973
00974 if (*s == '*' || *s == '?')
00975 {
00976 sendto_one(source_p, form_str(ERR_WILDTOPLEVEL),
00977 ID_or_name(&me, client_p),
00978 ID_or_name(source_p, client_p), nick);
00979 return;
00980 }
00981
00982 sendto_match_butone(IsServer(client_p) ? client_p : NULL, source_p,
00983 nick + 1, (*nick == '#') ? MATCH_HOST : MATCH_SERVER,
00984 "%s $%s :%s", command, nick, text);
00985
00986 if ((p_or_n != NOTICE) && MyClient(source_p))
00987 source_p->localClient->last = CurrentTime;
00988
00989 return;
00990 }
00991 }
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 static struct Client *
01004 find_userhost(char *user, char *host, int *count)
01005 {
01006 struct Client *c2ptr;
01007 struct Client *res = NULL;
01008 dlink_node *lc2ptr;
01009
01010 *count = 0;
01011
01012 if (collapse(user) != NULL)
01013 {
01014 DLINK_FOREACH(lc2ptr, local_client_list.head)
01015 {
01016 c2ptr = lc2ptr->data;
01017
01018 if (!IsClient(c2ptr))
01019 continue;
01020
01021 if ((!host || match(host, c2ptr->host)) &&
01022 irccmp(user, c2ptr->username) == 0)
01023 {
01024 (*count)++;
01025 res = c2ptr;
01026 }
01027 }
01028 }
01029
01030 return(res);
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 static int
01042 has_ctrl_chars(char *msg)
01043 {
01044 char *c;
01045
01046 if (msg == NULL)
01047 return 0;
01048
01049 for (c = msg; *c != '\0'; ++c)
01050 {
01051
01052 if (*c > 31)
01053 continue;
01054
01055
01056 if (*c == 1)
01057 continue;
01058
01059
01060 if (*c == 27)
01061 {
01062
01063 if (c[1] == '$' || c[1] == '(')
01064 {
01065 c++;
01066 continue;
01067 }
01068 }
01069
01070
01071 break;
01072 }
01073
01074 if (*c != '\0')
01075 return 1;
01076
01077 return 0;
01078 }
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 static int
01089 has_colors(char *msg)
01090 {
01091 char *c;
01092 if (msg == NULL)
01093 return 0;
01094
01095 c = msg;
01096 while(*c)
01097 {
01098 if(*c == '\003' || *c == '\033')
01099 break;
01100 else
01101 c++;
01102 }
01103
01104 if(*c)
01105 return 1;
01106
01107 return 0;
01108 }