PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/send.c

https://bitbucket.org/rizon/ircd/
C | 1221 lines | 731 code | 148 blank | 342 comment | 177 complexity | 963502739f881782cfe56accad8cc456 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. /*
  2. * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
  3. * send.c: Functions for sending messages.
  4. *
  5. * Copyright (C) 2002 by the past and present ircd coders, and others.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  20. * USA
  21. *
  22. * $Id: send.c 493 2007-07-07 17:45:14Z jon $
  23. */
  24. #include "stdinc.h"
  25. #include "tools.h"
  26. #include "send.h"
  27. #include "channel.h"
  28. #include "client.h"
  29. #include "common.h"
  30. #include "dbuf.h"
  31. #include "irc_string.h"
  32. #include "ircd.h"
  33. #include "handlers.h"
  34. #include "numeric.h"
  35. #include "fdlist.h"
  36. #include "s_bsd.h"
  37. #include "s_serv.h"
  38. #include "sprintf_irc.h"
  39. #include "s_conf.h"
  40. #include "list.h"
  41. #include "s_log.h"
  42. #include "memory.h"
  43. #include "hook.h"
  44. #include "irc_getnameinfo.h"
  45. #include "packet.h"
  46. #define LOG_BUFSIZE 2048
  47. struct Callback *iosend_cb = NULL;
  48. struct Callback *iosendctrl_cb = NULL;
  49. static void send_message(struct Client *, char *, int);
  50. static void send_message_remote(struct Client *, struct Client *, char *, int);
  51. static unsigned long current_serial = 0L;
  52. /* send_format()
  53. *
  54. * inputs - buffer to format into
  55. * - size of the buffer
  56. * - format pattern to use
  57. * - var args
  58. * output - number of bytes formatted output
  59. * side effects - modifies sendbuf
  60. */
  61. static inline int
  62. send_format(char *lsendbuf, int bufsize, const char *pattern, va_list args)
  63. {
  64. int len;
  65. /*
  66. * from rfc1459
  67. *
  68. * IRC messages are always lines of characters terminated with a CR-LF
  69. * (Carriage Return - Line Feed) pair, and these messages shall not
  70. * exceed 512 characters in length, counting all characters
  71. * including the trailing CR-LF.
  72. * Thus, there are 510 characters maximum allowed
  73. * for the command and its parameters. There is no provision for
  74. * continuation message lines. See section 7 for more details about
  75. * current implementations.
  76. */
  77. len = vsnprintf(lsendbuf, bufsize - 1, pattern, args);
  78. if(len > bufsize - 2)
  79. len = bufsize - 2; /* required by some versions of vsnprintf */
  80. lsendbuf[len++] = '\r';
  81. lsendbuf[len++] = '\n';
  82. return (len);
  83. }
  84. /*
  85. * iosend_default - append a packet to the client's sendq.
  86. */
  87. void *
  88. iosend_default(va_list args)
  89. {
  90. struct Client *to = va_arg(args, struct Client *);
  91. int length = va_arg(args, int);
  92. char *buf = va_arg(args, char *);
  93. dbuf_put(&to->localClient->buf_sendq, buf, length);
  94. return NULL;
  95. }
  96. /*
  97. ** send_message
  98. ** Internal utility which appends given buffer to the sockets
  99. ** sendq.
  100. */
  101. static void
  102. send_message(struct Client *to, char *buf, int len)
  103. {
  104. assert(!IsMe(to));
  105. assert(to != &me);
  106. if(dbuf_length(&to->localClient->buf_sendq) + len > get_sendq(to))
  107. {
  108. if(IsServer(to))
  109. sendto_realops_flags(UMODE_ALL, L_ALL,
  110. "Max SendQ limit exceeded for %s: %lu > %lu",
  111. get_client_name(to, HIDE_IP),
  112. (unsigned
  113. long) (dbuf_length(&to->localClient->buf_sendq) +
  114. len), get_sendq(to));
  115. if(IsClient(to))
  116. SetSendQExceeded(to);
  117. dead_link_on_write(to, 0);
  118. return;
  119. }
  120. execute_callback(iosend_cb, to, len, buf);
  121. /*
  122. ** Update statistics. The following is slightly incorrect
  123. ** because it counts messages even if queued, but bytes
  124. ** only really sent. Queued bytes get updated in SendQueued.
  125. */
  126. ++to->localClient->send.messages;
  127. ++me.localClient->send.messages;
  128. if(dbuf_length(&to->localClient->buf_sendq) >
  129. (IsServer(to) ? (unsigned int) 1024 : (unsigned int) 4096))
  130. send_queued_write(to);
  131. }
  132. /* send_message_remote()
  133. *
  134. * inputs - pointer to client from message is being sent
  135. * - pointer to client to send to
  136. * - pointer to preformatted buffer
  137. * - length of input buffer
  138. * output - none
  139. * side effects - Despite the function name, this only sends to directly
  140. * connected clients.
  141. *
  142. */
  143. static void
  144. send_message_remote(struct Client *to, struct Client *from, char *buf, int len)
  145. {
  146. if(!MyConnect(to))
  147. {
  148. sendto_realops_flags(UMODE_ALL, L_ALL,
  149. "server send message to %s [%s] dropped from %s(Not local server)",
  150. to->name, to->from->name, from->name);
  151. return;
  152. }
  153. if(ServerInfo.hub && IsCapable(to, CAP_LL))
  154. {
  155. if(((from->lazyLinkClientExists & to->localClient->serverMask) == 0))
  156. client_burst_if_needed(to, from);
  157. }
  158. /* Optimize by checking if (from && to) before everything */
  159. /* we set to->from up there.. */
  160. if(!MyClient(from) && IsClient(to) && (to == from->from))
  161. {
  162. if(IsServer(from))
  163. {
  164. sendto_realops_flags(UMODE_ALL, L_ALL,
  165. "Send message to %s [%s] dropped from %s(Fake Dir)",
  166. to->name, to->from->name, from->name);
  167. return;
  168. }
  169. sendto_realops_flags(UMODE_ALL, L_ALL,
  170. "Ghosted: %s[%s@%s] from %s[%s@%s] (%s)",
  171. to->name, to->username, to->host,
  172. from->name, from->username, from->host, to->from->name);
  173. sendto_server(NULL, to, NULL, CAP_TS6, NOCAPS, NOFLAGS,
  174. ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
  175. me.id, to->name, me.name, to->name,
  176. to->username, to->host, to->from->name);
  177. sendto_server(NULL, to, NULL, NOCAPS, CAP_TS6, NOFLAGS,
  178. ":%s KILL %s :%s (%s[%s@%s] Ghosted %s)",
  179. me.name, to->name, me.name, to->name,
  180. to->username, to->host, to->from->name);
  181. SetKilled(to);
  182. if(IsClient(from))
  183. sendto_one(from, form_str(ERR_GHOSTEDCLIENT),
  184. me.name, from->name, to->name, to->username, to->host, to->from);
  185. exit_client(to, &me, "Ghosted client");
  186. return;
  187. }
  188. send_message(to, buf, len);
  189. }
  190. /*
  191. ** sendq_unblocked
  192. ** Called when a socket is ready for writing.
  193. */
  194. void
  195. sendq_unblocked(fde_t * fd, struct Client *client_p)
  196. {
  197. ClearSendqBlocked(client_p);
  198. /* let send_queued_write be executed by send_queued_all */
  199. #ifdef HAVE_LIBCRYPTO
  200. if(fd->flags.pending_read)
  201. {
  202. fd->flags.pending_read = 0;
  203. read_packet(fd, client_p);
  204. }
  205. #endif
  206. }
  207. /*
  208. ** slinkq_unblocked
  209. ** Called when a server control socket is ready for writing.
  210. */
  211. static void
  212. slinkq_unblocked(fde_t * fd, struct Client *client_p)
  213. {
  214. ClearSlinkqBlocked(client_p);
  215. send_queued_slink_write(client_p);
  216. }
  217. /*
  218. ** send_queued_write
  219. ** This is called when there is a chance that some output would
  220. ** be possible. This attempts to empty the send queue as far as
  221. ** possible, and then if any data is left, a write is rescheduled.
  222. */
  223. void
  224. send_queued_write(struct Client *to)
  225. {
  226. int retlen;
  227. struct dbuf_block *first;
  228. /*
  229. ** Once socket is marked dead, we cannot start writing to it,
  230. ** even if the error is removed...
  231. */
  232. if(IsDead(to) || IsSendqBlocked(to))
  233. return; /* no use calling send() now */
  234. /* Next, lets try to write some data */
  235. if(dbuf_length(&to->localClient->buf_sendq))
  236. {
  237. do
  238. {
  239. first = to->localClient->buf_sendq.blocks.head->data;
  240. #ifdef HAVE_LIBCRYPTO
  241. if(to->localClient->fd.ssl)
  242. {
  243. retlen = SSL_write(to->localClient->fd.ssl, first->data,
  244. first->size);
  245. /* translate openssl error codes, sigh */
  246. if(retlen < 0)
  247. switch (SSL_get_error(to->localClient->fd.ssl, retlen))
  248. {
  249. case SSL_ERROR_WANT_READ:
  250. return; /* retry later, don't register for write events */
  251. case SSL_ERROR_WANT_WRITE:
  252. errno = EWOULDBLOCK;
  253. case SSL_ERROR_SYSCALL:
  254. break;
  255. case SSL_ERROR_SSL:
  256. if(errno == EAGAIN)
  257. break;
  258. default:
  259. retlen = errno = 0; /* either an SSL-specific error or EOF */
  260. }
  261. }
  262. else
  263. #endif
  264. retlen = send(to->localClient->fd.fd, first->data, first->size, 0);
  265. if(retlen <= 0)
  266. {
  267. #ifdef _WIN32
  268. errno = WSAGetLastError();
  269. #endif
  270. break;
  271. }
  272. dbuf_delete(&to->localClient->buf_sendq, retlen);
  273. /* We have some data written .. update counters */
  274. to->localClient->send.bytes += retlen;
  275. me.localClient->send.bytes += retlen;
  276. }
  277. while(dbuf_length(&to->localClient->buf_sendq));
  278. if((retlen < 0) && (ignoreErrno(errno)))
  279. {
  280. /* we have a non-fatal error, reschedule a write */
  281. SetSendqBlocked(to);
  282. comm_setselect(&to->localClient->fd, COMM_SELECT_WRITE,
  283. (PF *) sendq_unblocked, (void *) to, 0);
  284. }
  285. else if(retlen <= 0)
  286. {
  287. dead_link_on_write(to, errno);
  288. return;
  289. }
  290. }
  291. }
  292. /*
  293. ** send_queued_slink_write
  294. ** This is called when there is a chance the some output would
  295. ** be possible. This attempts to empty the send queue as far as
  296. ** possible, and then if any data is left, a write is rescheduled.
  297. */
  298. void
  299. send_queued_slink_write(struct Client *to)
  300. {
  301. int retlen;
  302. /*
  303. ** Once socket is marked dead, we cannot start writing to it,
  304. ** even if the error is removed...
  305. */
  306. if(IsDead(to) || IsSlinkqBlocked(to))
  307. return; /* no use calling send() now */
  308. /* Next, lets try to write some data */
  309. if(to->localClient->slinkq != NULL)
  310. {
  311. retlen = send(to->localClient->ctrlfd.fd,
  312. to->localClient->slinkq + to->localClient->slinkq_ofs,
  313. to->localClient->slinkq_len, 0);
  314. if(retlen < 0)
  315. {
  316. /* If we have a fatal error */
  317. if(!ignoreErrno(errno))
  318. {
  319. dead_link_on_write(to, errno);
  320. return;
  321. }
  322. }
  323. else if(retlen == 0)
  324. {
  325. /* 0 bytes is an EOF .. */
  326. dead_link_on_write(to, 0);
  327. return;
  328. }
  329. else
  330. {
  331. execute_callback(iosendctrl_cb, to, retlen,
  332. to->localClient->slinkq + to->localClient->slinkq_ofs);
  333. to->localClient->slinkq_len -= retlen;
  334. assert(to->localClient->slinkq_len >= 0);
  335. if(to->localClient->slinkq_len)
  336. to->localClient->slinkq_ofs += retlen;
  337. else
  338. {
  339. to->localClient->slinkq_ofs = 0;
  340. MyFree(to->localClient->slinkq);
  341. to->localClient->slinkq = NULL;
  342. }
  343. }
  344. /* Finally, if we have any more data, reschedule a write */
  345. if(to->localClient->slinkq_len)
  346. {
  347. SetSlinkqBlocked(to);
  348. comm_setselect(&to->localClient->ctrlfd, COMM_SELECT_WRITE,
  349. (PF *) slinkq_unblocked, (void *) to, 0);
  350. }
  351. }
  352. }
  353. /* send_queued_all()
  354. *
  355. * input - NONE
  356. * output - NONE
  357. * side effects - try to flush sendq of each client
  358. */
  359. void
  360. send_queued_all(void)
  361. {
  362. dlink_node *ptr;
  363. /* Servers are processed first, mainly because this can generate
  364. * a notice to opers, which is to be delivered by this function.
  365. */
  366. DLINK_FOREACH(ptr, serv_list.head) send_queued_write((struct Client *) ptr->data);
  367. DLINK_FOREACH(ptr, unknown_list.head) send_queued_write((struct Client *) ptr->data);
  368. DLINK_FOREACH(ptr, local_client_list.head) send_queued_write((struct Client *) ptr->data);
  369. /* NOTE: This can still put clients on aborted_list; unfortunately,
  370. * exit_aborted_clients takes precedence over send_queued_all,
  371. * because exiting clients can generate server/oper traffic.
  372. * The easiest approach is dealing with aborted clients in the next I/O lap.
  373. * -adx
  374. */
  375. }
  376. /* sendto_one()
  377. *
  378. * inputs - pointer to destination client
  379. * - var args message
  380. * output - NONE
  381. * side effects - send message to single client
  382. */
  383. void
  384. sendto_one(struct Client *to, const char *pattern, ...)
  385. {
  386. va_list args;
  387. char buffer[IRCD_BUFSIZE];
  388. int len;
  389. if(to->from != NULL)
  390. to = to->from;
  391. if(IsDead(to))
  392. return; /* This socket has already been marked as dead */
  393. va_start(args, pattern);
  394. len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
  395. va_end(args);
  396. send_message(to, buffer, len);
  397. }
  398. /* sendto_channel_butone()
  399. *
  400. * inputs - pointer to client(server) to NOT send message to
  401. * - pointer to client that is sending this message
  402. * - pointer to channel being sent to
  403. * - vargs message
  404. * output - NONE
  405. * side effects - message as given is sent to given channel members.
  406. *
  407. * WARNING - +D clients are ignored
  408. */
  409. void
  410. sendto_channel_butone(struct Client *one, struct Client *from,
  411. struct Channel *chptr, const char *command, const char *pattern, ...)
  412. {
  413. va_list alocal, aremote, auid;
  414. char local_buf[IRCD_BUFSIZE];
  415. char remote_buf[IRCD_BUFSIZE];
  416. char uid_buf[IRCD_BUFSIZE];
  417. int local_len, remote_len, uid_len;
  418. dlink_node *ptr;
  419. dlink_node *ptr_next;
  420. struct Client *target_p;
  421. int is_ctcp = NO;
  422. const char *message;
  423. if(IsServer(from))
  424. local_len = ircsprintf(local_buf, ":%s %s %s ", from->name, command, chptr->chname);
  425. else
  426. local_len = ircsprintf(local_buf, ":%s!%s@%s %s %s ",
  427. from->name, from->username, from->host,
  428. command, chptr->chname);
  429. remote_len = ircsprintf(remote_buf, ":%s %s %s ", from->name, command, chptr->chname);
  430. uid_len = ircsprintf(uid_buf, ":%s %s %s ", ID(from), command, chptr->chname);
  431. va_start(alocal, pattern);
  432. va_start(aremote, pattern);
  433. va_start(auid, pattern);
  434. message = &local_buf[local_len] + 1;
  435. local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len, pattern, alocal);
  436. remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len,
  437. pattern, aremote);
  438. uid_len += send_format(&uid_buf[uid_len], IRCD_BUFSIZE - uid_len, pattern, auid);
  439. va_end(auid);
  440. va_end(aremote);
  441. va_end(alocal);
  442. ++current_serial;
  443. if(msg_is_ctcp(message))
  444. is_ctcp = YES;
  445. DLINK_FOREACH_SAFE(ptr, ptr_next, chptr->members.head)
  446. {
  447. target_p = ((struct Membership *) ptr->data)->client_p;
  448. assert(target_p != NULL);
  449. if(IsDefunct(target_p) || IsDeaf(target_p) || is_bwsave(chptr, target_p) ||
  450. (is_ctcp && is_noctcp(from, target_p)) || target_p->from == one)
  451. continue;
  452. if(MyClient(target_p))
  453. {
  454. if(target_p->serial != current_serial)
  455. {
  456. send_message(target_p, local_buf, local_len);
  457. target_p->serial = current_serial;
  458. }
  459. }
  460. else
  461. {
  462. /* Now check whether a message has been sent to this
  463. * remote link already
  464. */
  465. if(target_p->from->serial != current_serial)
  466. {
  467. if(IsCapable(target_p->from, CAP_TS6))
  468. send_message_remote(target_p->from, from, uid_buf, uid_len);
  469. else
  470. send_message_remote(target_p->from, from, remote_buf,
  471. remote_len);
  472. target_p->from->serial = current_serial;
  473. }
  474. }
  475. }
  476. }
  477. /* sendto_server()
  478. *
  479. * inputs - pointer to client to NOT send to
  480. * - pointer to source client required by LL (if any)
  481. * - pointer to channel required by LL (if any)
  482. * - caps or'd together which must ALL be present
  483. * - caps or'd together which must ALL NOT be present
  484. * - LL flags: LL_ICLIENT | LL_ICHAN
  485. * - printf style format string
  486. * - args to format string
  487. * output - NONE
  488. * side effects - Send a message to all connected servers, except the
  489. * client 'one' (if non-NULL), as long as the servers
  490. * support ALL capabs in 'caps', and NO capabs in 'nocaps'.
  491. * If the server is a lazylink client, then it must know
  492. * about source_p if non-NULL (unless LL_ICLIENT is specified,
  493. * when source_p will be introduced where required) and
  494. * chptr if non-NULL (unless LL_ICHANNEL is specified, when
  495. * chptr will be introduced where required).
  496. * Note: nothing will be introduced to a LazyLeaf unless
  497. * the message is actually sent.
  498. *
  499. * This function was written in an attempt to merge together the other
  500. * billion sendto_*serv*() functions, which sprung up with capabs,
  501. * lazylinks, uids, etc.
  502. * -davidt
  503. */
  504. void
  505. sendto_server(struct Client *one, struct Client *source_p,
  506. struct Channel *chptr, unsigned long caps,
  507. unsigned long nocaps, unsigned long llflags, const char *format, ...)
  508. {
  509. va_list args;
  510. struct Client *client_p;
  511. dlink_node *ptr;
  512. char buffer[IRCD_BUFSIZE];
  513. int len;
  514. if(chptr != NULL)
  515. {
  516. if(chptr->chname[0] != '#')
  517. return;
  518. }
  519. va_start(args, format);
  520. len = send_format(buffer, IRCD_BUFSIZE, format, args);
  521. va_end(args);
  522. DLINK_FOREACH(ptr, serv_list.head)
  523. {
  524. client_p = ptr->data;
  525. /* If dead already skip */
  526. if(IsDead(client_p))
  527. continue;
  528. /* check against 'one' */
  529. if(one != NULL && (client_p == one->from))
  530. continue;
  531. /* check we have required capabs */
  532. if((client_p->localClient->caps & caps) != caps)
  533. continue;
  534. /* check we don't have any forbidden capabs */
  535. if((client_p->localClient->caps & nocaps) != 0)
  536. continue;
  537. if(ServerInfo.hub && IsCapable(client_p, CAP_LL))
  538. {
  539. /* check LL channel */
  540. if(chptr != NULL &&
  541. ((chptr->lazyLinkChannelExists &
  542. client_p->localClient->serverMask) == 0))
  543. {
  544. /* Only introduce the channel if we really will send this message */
  545. if(!(llflags & LL_ICLIENT) && source_p &&
  546. ((source_p->lazyLinkClientExists &
  547. client_p->localClient->serverMask) == 0))
  548. continue; /* we can't introduce the unknown source_p, skip */
  549. if(llflags & LL_ICHAN)
  550. burst_channel(client_p, chptr);
  551. else
  552. continue; /* we can't introduce the unknown chptr, skip */
  553. }
  554. /* check LL client */
  555. if(source_p &&
  556. ((source_p->lazyLinkClientExists &
  557. client_p->localClient->serverMask) == 0))
  558. {
  559. if(llflags & LL_ICLIENT)
  560. client_burst_if_needed(client_p, source_p);
  561. else
  562. continue; /* we can't introduce the unknown source_p, skip */
  563. }
  564. }
  565. send_message(client_p, buffer, len);
  566. }
  567. }
  568. /* sendto_common_channels_local()
  569. *
  570. * inputs - pointer to client
  571. * - pattern to send
  572. * output - NONE
  573. * side effects - Sends a message to all people on local server who are
  574. * in same channel with user.
  575. * used by m_nick.c and exit_one_client.
  576. */
  577. void
  578. sendto_common_channels_local(struct Client *user, int touser, const char *pattern, ...)
  579. {
  580. va_list args;
  581. dlink_node *uptr;
  582. dlink_node *cptr;
  583. struct Channel *chptr;
  584. struct Membership *ms;
  585. struct Client *target_p;
  586. char buffer[IRCD_BUFSIZE];
  587. int len;
  588. va_start(args, pattern);
  589. len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
  590. va_end(args);
  591. ++current_serial;
  592. DLINK_FOREACH(cptr, user->channel.head)
  593. {
  594. chptr = ((struct Membership *) cptr->data)->chptr;
  595. assert(chptr != NULL);
  596. DLINK_FOREACH(uptr, chptr->members.head)
  597. {
  598. ms = uptr->data;
  599. target_p = ms->client_p;
  600. assert(target_p != NULL);
  601. if(!MyConnect(target_p) || target_p == user || IsDefunct(target_p) ||
  602. target_p->serial == current_serial)
  603. continue;
  604. target_p->serial = current_serial;
  605. send_message(target_p, buffer, len);
  606. }
  607. }
  608. if(touser && MyConnect(user) && !IsDead(user) && user->serial != current_serial)
  609. send_message(user, buffer, len);
  610. }
  611. /* sendto_channel_local()
  612. *
  613. * inputs - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE
  614. * - whether to ignore +D clients (YES/NO)
  615. * - pointer to channel to send to
  616. * - var args pattern
  617. * output - NONE
  618. * side effects - Send a message to all members of a channel that are
  619. * locally connected to this server.
  620. */
  621. void
  622. sendto_channel_local(int type, int nodeaf, struct Channel *chptr, const char *pattern, ...)
  623. {
  624. va_list args;
  625. char buffer[IRCD_BUFSIZE];
  626. int len;
  627. dlink_node *ptr;
  628. struct Membership *ms;
  629. struct Client *target_p;
  630. va_start(args, pattern);
  631. len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
  632. va_end(args);
  633. DLINK_FOREACH(ptr, chptr->members.head)
  634. {
  635. ms = ptr->data;
  636. target_p = ms->client_p;
  637. if(type != 0 && (ms->flags & type) == 0)
  638. continue;
  639. if(!MyConnect(target_p) || IsDefunct(target_p) ||
  640. (nodeaf && (IsDeaf(target_p) || is_bwsave(chptr, target_p))))
  641. continue;
  642. send_message(target_p, buffer, len);
  643. }
  644. }
  645. /* sendto_channel_local_butone()
  646. *
  647. * inputs - pointer to client to NOT send message to
  648. * - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE
  649. * - whether to ignore +D clients (YES/NO)
  650. * - pointer to channel to send to
  651. * - var args pattern
  652. * output - NONE
  653. * side effects - Send a message to all members of a channel that are
  654. * locally connected to this server except one.
  655. *
  656. */
  657. void
  658. sendto_channel_local_butone(struct Client *one, int type, int nodeaf,
  659. struct Channel *chptr, const char *pattern, ...)
  660. {
  661. va_list args;
  662. char buffer[IRCD_BUFSIZE];
  663. int len;
  664. struct Client *target_p;
  665. struct Membership *ms;
  666. dlink_node *ptr;
  667. va_start(args, pattern);
  668. len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
  669. va_end(args);
  670. DLINK_FOREACH(ptr, chptr->members.head)
  671. {
  672. ms = ptr->data;
  673. target_p = ms->client_p;
  674. if(type != 0 && (ms->flags & type) == 0)
  675. continue;
  676. if(!MyConnect(target_p) || target_p == one || IsDefunct(target_p)
  677. || (nodeaf && (IsDeaf(target_p) || is_bwsave(chptr, target_p))))
  678. continue;
  679. send_message(target_p, buffer, len);
  680. }
  681. }
  682. /* sendto_channel_remote()
  683. *
  684. * inputs - Client not to send towards
  685. * - Client from whom message is from
  686. * - member status mask, e.g. CHFL_CHANOP | CHFL_VOICE
  687. * - pointer to channel to send to
  688. * - var args pattern
  689. * output - NONE
  690. * side effects - Send a message to all members of a channel that are
  691. * remote to this server.
  692. */
  693. void
  694. sendto_channel_remote(struct Client *one, struct Client *from, int type, int caps,
  695. int nocaps, struct Channel *chptr, const char *pattern, ...)
  696. {
  697. va_list args;
  698. char buffer[IRCD_BUFSIZE];
  699. int len;
  700. dlink_node *ptr;
  701. struct Client *target_p;
  702. struct Membership *ms;
  703. va_start(args, pattern);
  704. len = send_format(buffer, IRCD_BUFSIZE, pattern, args);
  705. va_end(args);
  706. ++current_serial;
  707. DLINK_FOREACH(ptr, chptr->members.head)
  708. {
  709. ms = ptr->data;
  710. target_p = ms->client_p;
  711. if(type != 0 && (ms->flags & type) == 0)
  712. continue;
  713. if(MyConnect(target_p))
  714. continue;
  715. target_p = target_p->from;
  716. if(target_p == one->from ||
  717. ((target_p->from->localClient->caps & caps) != caps) ||
  718. ((target_p->from->localClient->caps & nocaps) != 0))
  719. continue;
  720. if(target_p->from->serial != current_serial)
  721. {
  722. send_message(target_p, buffer, len);
  723. target_p->from->serial = current_serial;
  724. }
  725. }
  726. }
  727. /*
  728. ** match_it() and sendto_match_butone() ARE only used
  729. ** to send a msg to all ppl on servers/hosts that match a specified mask
  730. ** (used for enhanced PRIVMSGs) for opers
  731. **
  732. ** addition -- Armin, 8jun90 (gruner@informatik.tu-muenchen.de)
  733. **
  734. */
  735. /* match_it()
  736. *
  737. * inputs - client pointer to match on
  738. * - actual mask to match
  739. * - what to match on, HOST or SERVER
  740. * output - 1 or 0 if match or not
  741. * side effects - NONE
  742. */
  743. static int
  744. match_it(const struct Client *one, const char *mask, int what)
  745. {
  746. if(what == MATCH_HOST)
  747. return (match(mask, one->host));
  748. return (match(mask, one->servptr->name));
  749. }
  750. /* sendto_match_butone()
  751. *
  752. * Send to all clients which match the mask in a way defined on 'what';
  753. * either by user hostname or user servername.
  754. *
  755. * ugh. ONLY used by m_message.c to send an "oper magic" message. ugh.
  756. */
  757. void
  758. sendto_match_butone(struct Client *one, struct Client *from, char *mask,
  759. int what, const char *pattern, ...)
  760. {
  761. va_list alocal, aremote;
  762. struct Client *client_p;
  763. dlink_node *ptr, *ptr_next;
  764. char local_buf[IRCD_BUFSIZE], remote_buf[IRCD_BUFSIZE];
  765. int local_len = ircsprintf(local_buf, ":%s!%s@%s ", from->name,
  766. from->username, from->host);
  767. int remote_len = ircsprintf(remote_buf, ":%s ", from->name);
  768. va_start(alocal, pattern);
  769. va_start(aremote, pattern);
  770. local_len += send_format(&local_buf[local_len], IRCD_BUFSIZE - local_len, pattern, alocal);
  771. remote_len += send_format(&remote_buf[remote_len], IRCD_BUFSIZE - remote_len,
  772. pattern, aremote);
  773. va_end(aremote);
  774. va_end(alocal);
  775. /* scan the local clients */
  776. DLINK_FOREACH(ptr, local_client_list.head)
  777. {
  778. client_p = ptr->data;
  779. if(client_p != one && !IsDefunct(client_p) && match_it(client_p, mask, what))
  780. send_message(client_p, local_buf, local_len);
  781. }
  782. /* Now scan servers */
  783. DLINK_FOREACH_SAFE(ptr, ptr_next, serv_list.head)
  784. {
  785. client_p = ptr->data;
  786. /*
  787. * The old code looped through every client on the
  788. * network for each server to check if the
  789. * server (client_p) has at least 1 client matching
  790. * the mask, using something like:
  791. *
  792. * for (target_p = GlobalClientList; target_p; target_p = target_p->next)
  793. * if (IsRegisteredUser(target_p) &&
  794. * match_it(target_p, mask, what) &&
  795. * (target_p->from == client_p))
  796. * vsendto_prefix_one(client_p, from, pattern, args);
  797. *
  798. * That way, we wouldn't send the message to
  799. * a server who didn't have a matching client.
  800. * However, on a network such as EFNet, that
  801. * code would have looped through about 50
  802. * servers, and in each loop, loop through
  803. * about 50k clients as well, calling match()
  804. * in each nested loop. That is a very bad
  805. * thing cpu wise - just send the message
  806. * to every connected server and let that
  807. * server deal with it.
  808. * -wnder
  809. */
  810. if(client_p != one && !IsDefunct(client_p))
  811. send_message_remote(client_p, from, remote_buf, remote_len);
  812. }
  813. }
  814. /* sendto_match_servs()
  815. *
  816. * inputs - source client
  817. * - mask to send to
  818. * - capab needed
  819. * - data
  820. * outputs - none
  821. * side effects - data sent to servers matching with capab
  822. */
  823. void
  824. sendto_match_servs(struct Client *source_p, const char *mask, int cap, const char *pattern, ...)
  825. {
  826. va_list args;
  827. struct Client *target_p;
  828. dlink_node *ptr;
  829. char buffer[IRCD_BUFSIZE];
  830. int found = 0;
  831. va_start(args, pattern);
  832. vsnprintf(buffer, sizeof(buffer), pattern, args);
  833. va_end(args);
  834. current_serial++;
  835. DLINK_FOREACH(ptr, global_serv_list.head)
  836. {
  837. target_p = ptr->data;
  838. /* Do not attempt to send to ourselves, or the source */
  839. if(IsMe(target_p) || target_p->from == source_p->from)
  840. continue;
  841. if(target_p->from->serial == current_serial)
  842. continue;
  843. if(match(mask, target_p->name))
  844. {
  845. /*
  846. * if we set the serial here, then we'll never do a
  847. * match() again, if !IsCapable()
  848. */
  849. target_p->from->serial = current_serial;
  850. found++;
  851. if(!IsCapable(target_p->from, cap))
  852. continue;
  853. sendto_anywhere(target_p, source_p, "%s", buffer);
  854. }
  855. }
  856. }
  857. /* sendto_anywhere()
  858. *
  859. * inputs - pointer to dest client
  860. * - pointer to from client
  861. * - varags
  862. * output - NONE
  863. * side effects - less efficient than sendto_remote and sendto_one
  864. * but useful when one does not know where target "lives"
  865. */
  866. void
  867. sendto_anywhere(struct Client *to, struct Client *from, const char *pattern, ...)
  868. {
  869. va_list args;
  870. char buffer[IRCD_BUFSIZE];
  871. int len;
  872. struct Client *send_to = (to->from != NULL ? to->from : to);
  873. if(IsDead(send_to))
  874. return;
  875. if(MyClient(to))
  876. {
  877. if(IsServer(from))
  878. {
  879. if(IsCapable(to, CAP_TS6) && HasID(from))
  880. len = ircsprintf(buffer, ":%s ", from->id);
  881. else
  882. len = ircsprintf(buffer, ":%s ", from->name);
  883. }
  884. else
  885. len = ircsprintf(buffer, ":%s!%s@%s ",
  886. from->name, from->username, from->host);
  887. }
  888. else
  889. len = ircsprintf(buffer, ":%s ", ID_or_name(from, send_to));
  890. va_start(args, pattern);
  891. len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
  892. va_end(args);
  893. if(MyClient(to))
  894. send_message(send_to, buffer, len);
  895. else
  896. send_message_remote(send_to, from, buffer, len);
  897. }
  898. /* sendto_realops_flags()
  899. *
  900. * inputs - flag types of messages to show to real opers
  901. * - flag indicating opers/admins
  902. * - var args input message
  903. * output - NONE
  904. * side effects - Send to *local* ops only but NOT +s nonopers.
  905. */
  906. void
  907. sendto_realops_flags(unsigned int flags, int level, const char *pattern, ...)
  908. {
  909. struct Client *client_p;
  910. char nbuf[IRCD_BUFSIZE];
  911. dlink_node *ptr;
  912. va_list args;
  913. va_start(args, pattern);
  914. vsnprintf(nbuf, IRCD_BUFSIZE, pattern, args);
  915. va_end(args);
  916. DLINK_FOREACH(ptr, oper_list.head)
  917. {
  918. client_p = ptr->data;
  919. assert(client_p->umodes & UMODE_OPER);
  920. /* If we're sending it to opers and theyre an admin, skip.
  921. * If we're sending it to admins, and theyre not, skip.
  922. */
  923. if(((level == L_ADMIN) && !IsAdmin(client_p)) ||
  924. ((level == L_OPER) && IsAdmin(client_p)))
  925. continue;
  926. if(client_p->umodes & flags)
  927. sendto_one(client_p, ":%s NOTICE %s :*** Notice -- %s",
  928. me.name, client_p->name, nbuf);
  929. }
  930. }
  931. /* sendto_wallops_flags()
  932. *
  933. * inputs - flag types of messages to show to real opers
  934. * - client sending request
  935. * - var args input message
  936. * output - NONE
  937. * side effects - Send a wallops to local opers
  938. */
  939. void
  940. sendto_wallops_flags(unsigned int flags, struct Client *source_p, const char *pattern, ...)
  941. {
  942. struct Client *client_p;
  943. dlink_node *ptr;
  944. va_list args;
  945. char buffer[IRCD_BUFSIZE];
  946. int len;
  947. if(IsClient(source_p))
  948. len = ircsprintf(buffer, ":%s!%s@%s WALLOPS :",
  949. source_p->name, source_p->username, source_p->host);
  950. else
  951. len = ircsprintf(buffer, ":%s WALLOPS :", source_p->name);
  952. va_start(args, pattern);
  953. len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
  954. va_end(args);
  955. DLINK_FOREACH(ptr, oper_list.head)
  956. {
  957. client_p = ptr->data;
  958. assert(client_p->umodes & UMODE_OPER);
  959. if((client_p->umodes & flags) && !IsDefunct(client_p))
  960. send_message(client_p, buffer, len);
  961. }
  962. }
  963. /* ts_warn()
  964. *
  965. * inputs - var args message
  966. * output - NONE
  967. * side effects - Call sendto_realops_flags, with some flood checking
  968. * (at most 5 warnings every 5 seconds)
  969. */
  970. void
  971. ts_warn(const char *pattern, ...)
  972. {
  973. va_list args;
  974. char buffer[LOG_BUFSIZE];
  975. static time_t last = 0;
  976. static int warnings = 0;
  977. /*
  978. ** if we're running with TS_WARNINGS enabled and someone does
  979. ** something silly like (remotely) connecting a nonTS server,
  980. ** we'll get a ton of warnings, so we make sure we don't send
  981. ** more than 5 every 5 seconds. -orabidoo
  982. */
  983. if(CurrentTime - last < 5)
  984. {
  985. if(++warnings > 5)
  986. return;
  987. }
  988. else
  989. {
  990. last = CurrentTime;
  991. warnings = 0;
  992. }
  993. va_start(args, pattern);
  994. vsprintf_irc(buffer, pattern, args);
  995. va_end(args);
  996. sendto_realops_flags(UMODE_ALL, L_ALL, "%s", buffer);
  997. ilog(L_CRIT, "%s", buffer);
  998. }
  999. /* kill_client()
  1000. *
  1001. * inputs - client to send kill towards
  1002. * - pointer to client to kill
  1003. * - reason for kill
  1004. * output - NONE
  1005. * side effects - NONE
  1006. */
  1007. void
  1008. kill_client(struct Client *client_p, struct Client *diedie, const char *pattern, ...)
  1009. {
  1010. va_list args;
  1011. char buffer[IRCD_BUFSIZE];
  1012. int len;
  1013. if(client_p->from != NULL)
  1014. client_p = client_p->from;
  1015. if(IsDead(client_p))
  1016. return;
  1017. len = ircsprintf(buffer, ":%s KILL %s :", ID_or_name(&me, client_p->from),
  1018. ID_or_name(diedie, client_p));
  1019. va_start(args, pattern);
  1020. len += send_format(&buffer[len], IRCD_BUFSIZE - len, pattern, args);
  1021. va_end(args);
  1022. send_message(client_p, buffer, len);
  1023. }
  1024. /* kill_client_ll_serv_butone()
  1025. *
  1026. * inputs - pointer to client to not send to
  1027. * - pointer to client to kill
  1028. * output - NONE
  1029. * side effects - Send a KILL for the given client
  1030. * message to all connected servers
  1031. * except the client 'one'. Also deal with
  1032. * client being unknown to leaf, as in lazylink...
  1033. */
  1034. void
  1035. kill_client_ll_serv_butone(struct Client *one, struct Client *source_p, const char *pattern, ...)
  1036. {
  1037. va_list args;
  1038. int have_uid = 0;
  1039. struct Client *client_p;
  1040. dlink_node *ptr;
  1041. char buf_uid[IRCD_BUFSIZE], buf_nick[IRCD_BUFSIZE];
  1042. int len_uid = 0, len_nick;
  1043. if(HasID(source_p) && (me.id[0] != '\0'))
  1044. {
  1045. have_uid = 1;
  1046. va_start(args, pattern);
  1047. len_uid = ircsprintf(buf_uid, ":%s KILL %s :", me.id, ID(source_p));
  1048. len_uid += send_format(&buf_uid[len_uid], IRCD_BUFSIZE - len_uid, pattern, args);
  1049. va_end(args);
  1050. }
  1051. va_start(args, pattern);
  1052. len_nick = ircsprintf(buf_nick, ":%s KILL %s :", me.name, source_p->name);
  1053. len_nick += send_format(&buf_nick[len_nick], IRCD_BUFSIZE - len_nick, pattern, args);
  1054. va_end(args);
  1055. DLINK_FOREACH(ptr, serv_list.head)
  1056. {
  1057. client_p = ptr->data;
  1058. if(one != NULL && (client_p == one->from))
  1059. continue;
  1060. if(IsDefunct(client_p))
  1061. continue;
  1062. /* XXX perhaps IsCapable should test for localClient itself ? -db */
  1063. if(client_p->localClient == NULL || !IsCapable(client_p, CAP_LL) ||
  1064. !ServerInfo.hub ||
  1065. (source_p->lazyLinkClientExists & client_p->localClient->serverMask))
  1066. {
  1067. if(have_uid && IsCapable(client_p, CAP_TS6))
  1068. send_message(client_p, buf_uid, len_uid);
  1069. else
  1070. send_message(client_p, buf_nick, len_nick);
  1071. }
  1072. }
  1073. }