X-Git-Url: https://jfr.im/git/irc/rqf/shadowircd.git/blobdiff_plain/a55e57248b809678d3ac3ac716972def07c2c493..3d11239c22e55435ce1c7a2d2fe4e18492c9149e:/src/send.c diff --git a/src/send.c b/src/send.c index 1489886..e82acd9 100644 --- a/src/send.c +++ b/src/send.c @@ -21,7 +21,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * - * $Id: send.c 3520 2007-06-30 22:15:35Z jilles $ */ #include "stdinc.h" @@ -30,14 +29,13 @@ #include "class.h" #include "client.h" #include "common.h" -#include "irc_string.h" +#include "match.h" #include "ircd.h" #include "numeric.h" #include "s_serv.h" -#include "sprintf_irc.h" #include "s_conf.h" #include "s_newconf.h" -#include "s_log.h" +#include "logger.h" #include "hook.h" #include "monitor.h" @@ -50,6 +48,8 @@ static void send_queued_write(rb_fde_t *F, void *data); unsigned long current_serial = 0L; +struct Client *remote_rehash_oper_p; + /* send_linebuf() * * inputs - client to send to, linebuf to attach @@ -74,7 +74,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf) { sendto_realops_snomask(SNO_GENERAL, L_ALL, "Max SendQ limit exceeded for %s: %u > %lu", - get_server_name(to, HIDE_IP), + to->name, rb_linebuf_len(&to->localClient->buf_sendq), get_sendq(to)); @@ -84,10 +84,7 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf) get_sendq(to)); } - if(IsClient(to)) - to->flags |= FLAGS_SENDQEX; - - dead_link(to); + dead_link(to, 1); return -1; } else @@ -149,6 +146,14 @@ send_queued(struct Client *to) if(IsIOError(to)) return; + /* Something wants us to not send anything currently */ + /* if(IsCork(to)) + return; */ + + /* try to flush later when the write event resets this */ + if(IsFlush(to)) + return; + #ifdef USE_IODEBUG_HOOKS hd.client = to; if(to->localClient->buf_sendq.list.head) @@ -173,6 +178,8 @@ send_queued(struct Client *to) #endif + ClearFlush(to); + to->localClient->sendB += retlen; me.localClient->sendB += retlen; if(to->localClient->sendB > 1023) @@ -189,13 +196,30 @@ send_queued(struct Client *to) if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno))) { - dead_link(to); + dead_link(to, 0); return; } } + if(rb_linebuf_len(&to->localClient->buf_sendq)) - rb_setselect(to->localClient->F, RB_SELECT_WRITE, + { + SetFlush(to); + rb_setselect(to->localClient->F, RB_SELECT_WRITE, send_queued_write, to); + } + else + ClearFlush(to); +} + +void +send_pop_queue(struct Client *to) +{ + if(to->from != NULL) + to = to->from; + if(!MyConnect(to) || IsIOError(to)) + return; + if(rb_linebuf_len(&to->localClient->buf_sendq) > 0) + send_queued(to); } /* send_queued_write() @@ -208,73 +232,10 @@ static void send_queued_write(rb_fde_t *F, void *data) { struct Client *to = data; - /*ClearFlush(to);*/ + ClearFlush(to); send_queued(to); } -/* send_queued_slink_write() - * - * inputs - fd to have queue sent, client we're sending to - * outputs - contents of queue - * side effects - write is rescheduled if queue isnt emptied - */ -void -send_queued_slink_write(int fd, void *data) -{ - struct Client *to = data; - int retlen; - - /* - ** Once socket is marked dead, we cannot start writing to it, - ** even if the error is removed... - */ - if(IsIOError(to)) - return; - - /* Next, lets try to write some data */ - if(to->localClient->slinkq) - { - retlen = write(to->localClient->ctrlfd, - to->localClient->slinkq + to->localClient->slinkq_ofs, - to->localClient->slinkq_len); - - if(retlen < 0) - { - /* If we have a fatal error */ - if(!rb_ignore_errno(errno)) - { - dead_link(to); - return; - } - } - /* 0 bytes is an EOF .. */ - else if(retlen == 0) - { - dead_link(to); - return; - } - else - { - to->localClient->slinkq_len -= retlen; - - s_assert(to->localClient->slinkq_len >= 0); - if(to->localClient->slinkq_len) - to->localClient->slinkq_ofs += retlen; - else - { - to->localClient->slinkq_ofs = 0; - MyFree(to->localClient->slinkq); - to->localClient->slinkq = NULL; - } - } - } - - /* if we have any more data, reschedule a write */ - if(to->localClient->slinkq_len) - rb_setselect(to->localClient->ctrlfd, - RB_SELECT_WRITE, send_queued_slink_write, to); -} - /* sendto_one() * * inputs - client to send to, va_args @@ -453,7 +414,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps, va_list args; struct Client *target_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; buf_head_t linebuf; /* noone to send to.. */ @@ -468,7 +429,7 @@ sendto_server(struct Client *one, struct Channel *chptr, unsigned long caps, rb_linebuf_putmsg(&linebuf, format, &args, NULL); va_end(args); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, serv_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) { target_p = ptr->data; @@ -504,15 +465,13 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p, static char buf[BUFSIZE]; va_list args; buf_head_t rb_linebuf_local; - buf_head_t rb_linebuf_name; buf_head_t rb_linebuf_id; struct Client *target_p; struct membership *msptr; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; rb_linebuf_newbuf(&rb_linebuf_local); - rb_linebuf_newbuf(&rb_linebuf_name); rb_linebuf_newbuf(&rb_linebuf_id); current_serial++; @@ -530,10 +489,9 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p, source_p->name, source_p->username, source_p->host, buf); - rb_linebuf_putmsg(&rb_linebuf_name, NULL, NULL, ":%s %s", source_p->name, buf); rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, chptr->members.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head) { msptr = ptr->data; target_p = msptr->client_p; @@ -557,11 +515,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p, if(target_p->from->serial != current_serial) { - if(has_id(target_p->from)) - send_linebuf_remote(target_p, source_p, &rb_linebuf_id); - else - send_linebuf_remote(target_p, source_p, &rb_linebuf_name); - + send_linebuf_remote(target_p, source_p, &rb_linebuf_id); target_p->from->serial = current_serial; } } @@ -570,10 +524,96 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p, } rb_linebuf_donebuf(&rb_linebuf_local); - rb_linebuf_donebuf(&rb_linebuf_name); rb_linebuf_donebuf(&rb_linebuf_id); } +/* sendto_channel_flags() + * + * inputs - server not to send to, flags needed, source, channel, va_args + * outputs - message is sent to channel members + * side effects - + */ +void +sendto_channel_opmod(struct Client *one, struct Client *source_p, + struct Channel *chptr, const char *command, + const char *text) +{ + buf_head_t rb_linebuf_local; + buf_head_t rb_linebuf_old; + buf_head_t rb_linebuf_new; + struct Client *target_p; + struct membership *msptr; + rb_dlink_node *ptr; + rb_dlink_node *next_ptr; + + rb_linebuf_newbuf(&rb_linebuf_local); + rb_linebuf_newbuf(&rb_linebuf_old); + rb_linebuf_newbuf(&rb_linebuf_new); + + current_serial++; + + if(IsServer(source_p)) + rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, + ":%s %s %s :%s", + source_p->name, command, chptr->chname, text); + else + rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL, + ":%s!%s@%s %s %s :%s", + source_p->name, source_p->username, + source_p->host, command, chptr->chname, text); + + if (chptr->mode.mode & MODE_MODERATED) + rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL, + ":%s %s %s :%s", + use_id(source_p), command, chptr->chname, text); + else + rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL, + ":%s NOTICE @%s :<%s:%s> %s", + use_id(source_p->servptr), chptr->chname, + source_p->name, chptr->chname, text); + rb_linebuf_putmsg(&rb_linebuf_new, NULL, NULL, + ":%s %s =%s :%s", + use_id(source_p), command, chptr->chname, text); + + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head) + { + msptr = ptr->data; + target_p = msptr->client_p; + + if(IsIOError(target_p->from) || target_p->from == one) + continue; + + if(!is_any_op(msptr)) + continue; + + if(IsDeaf(target_p)) + continue; + + if(!MyClient(target_p)) + { + /* if we've got a specific type, target must support + * CHW.. --fl + */ + if(NotCapable(target_p->from, CAP_CHW)) + continue; + + if(target_p->from->serial != current_serial) + { + if (IsCapable(target_p->from, CAP_EOPMOD)) + send_linebuf_remote(target_p, source_p, &rb_linebuf_new); + else + send_linebuf_remote(target_p, source_p, &rb_linebuf_old); + target_p->from->serial = current_serial; + } + } + else + _send_linebuf(target_p, &rb_linebuf_local); + } + + rb_linebuf_donebuf(&rb_linebuf_local); + rb_linebuf_donebuf(&rb_linebuf_old); + rb_linebuf_donebuf(&rb_linebuf_new); +} /* sendto_channel_local() * @@ -589,7 +629,7 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) struct membership *msptr; struct Client *target_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; rb_linebuf_newbuf(&linebuf); @@ -597,7 +637,7 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); va_end(args); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, chptr->locmembers.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) { msptr = ptr->data; target_p = msptr->client_p; @@ -605,7 +645,12 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...) if(IsIOError(target_p)) continue; - if(type && ((msptr->flags & type) == 0)) + if(type == ONLY_OPERS) + { + if(!IsOper(target_p)) + continue; + } + else if(type && ((msptr->flags & type) == 0)) continue; _send_linebuf(target_p, &linebuf); @@ -629,7 +674,7 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, struct membership *msptr; struct Client *target_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; rb_linebuf_newbuf(&linebuf); @@ -637,7 +682,7 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); va_end(args); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, chptr->locmembers.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head) { msptr = ptr->data; target_p = msptr->client_p; @@ -672,7 +717,7 @@ sendto_common_channels_local(struct Client *user, const char *pattern, ...) { va_list args; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; rb_dlink_node *uptr; rb_dlink_node *next_uptr; struct Channel *chptr; @@ -688,7 +733,7 @@ sendto_common_channels_local(struct Client *user, const char *pattern, ...) ++current_serial; - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, user->user->channel.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head) { mscptr = ptr->data; chptr = mscptr->chptr; @@ -730,7 +775,7 @@ sendto_common_channels_local_butone(struct Client *user, const char *pattern, .. { va_list args; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; rb_dlink_node *uptr; rb_dlink_node *next_uptr; struct Channel *chptr; @@ -748,7 +793,7 @@ sendto_common_channels_local_butone(struct Client *user, const char *pattern, .. /* Skip them -- jilles */ user->serial = current_serial; - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, user->user->channel.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head) { mscptr = ptr->data; chptr = mscptr->chptr; @@ -784,13 +829,11 @@ sendto_match_butone(struct Client *one, struct Client *source_p, va_list args; struct Client *target_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; buf_head_t rb_linebuf_local; - buf_head_t rb_linebuf_name; buf_head_t rb_linebuf_id; rb_linebuf_newbuf(&rb_linebuf_local); - rb_linebuf_newbuf(&rb_linebuf_name); rb_linebuf_newbuf(&rb_linebuf_id); va_start(args, pattern); @@ -806,12 +849,11 @@ sendto_match_butone(struct Client *one, struct Client *source_p, source_p->name, source_p->username, source_p->host, buf); - rb_linebuf_putmsg(&rb_linebuf_name, NULL, NULL, ":%s %s", source_p->name, buf); rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); if(what == MATCH_HOST) { - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, lclient_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head) { target_p = ptr->data; @@ -822,7 +864,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p, /* what = MATCH_SERVER, if it doesnt match us, just send remote */ else if(match(mask, me.name)) { - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, lclient_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head) { target_p = ptr->data; _send_linebuf(target_p, &rb_linebuf_local); @@ -836,15 +878,11 @@ sendto_match_butone(struct Client *one, struct Client *source_p, if(target_p == one) continue; - if(has_id(target_p)) - send_linebuf_remote(target_p, source_p, &rb_linebuf_id); - else - send_linebuf_remote(target_p, source_p, &rb_linebuf_name); + send_linebuf_remote(target_p, source_p, &rb_linebuf_id); } rb_linebuf_donebuf(&rb_linebuf_local); rb_linebuf_donebuf(&rb_linebuf_id); - rb_linebuf_donebuf(&rb_linebuf_name); } /* sendto_match_servs() @@ -862,13 +900,11 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap, rb_dlink_node *ptr; struct Client *target_p; buf_head_t rb_linebuf_id; - buf_head_t rb_linebuf_name; if(EmptyString(mask)) return; rb_linebuf_newbuf(&rb_linebuf_id); - rb_linebuf_newbuf(&rb_linebuf_name); va_start(args, pattern); rb_vsnprintf(buf, sizeof(buf), pattern, args); @@ -876,8 +912,6 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap, rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf); - rb_linebuf_putmsg(&rb_linebuf_name, NULL, NULL, - ":%s %s", source_p->name, buf); current_serial++; @@ -905,15 +939,11 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap, if(nocap && !NotCapable(target_p->from, nocap)) continue; - if(has_id(target_p->from)) - _send_linebuf(target_p->from, &rb_linebuf_id); - else - _send_linebuf(target_p->from, &rb_linebuf_name); + _send_linebuf(target_p->from, &rb_linebuf_id); } } rb_linebuf_donebuf(&rb_linebuf_id); - rb_linebuf_donebuf(&rb_linebuf_name); } /* sendto_monitor() @@ -929,7 +959,7 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...) buf_head_t linebuf; struct Client *target_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; rb_linebuf_newbuf(&linebuf); @@ -937,7 +967,7 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...) rb_linebuf_putmsg(&linebuf, pattern, &args, NULL); va_end(args); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, monptr->users.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, monptr->users.head) { target_p = ptr->data; @@ -994,46 +1024,6 @@ sendto_anywhere(struct Client *target_p, struct Client *source_p, rb_linebuf_donebuf(&linebuf); } -/* sendto_realops_flags() - * - * inputs - umode needed, level (opers/admin), va_args - * output - - * side effects - message is sent to opers with matching umodes - */ -void -sendto_realops_flags(int flags, int level, const char *pattern, ...) -{ - struct Client *client_p; - rb_dlink_node *ptr; - rb_dlink_node *rb_free(; - va_list args; - buf_head_t linebuf; - - rb_linebuf_newbuf(&linebuf); - - va_start(args, pattern); - rb_linebuf_putmsg(&linebuf, pattern, &args, - ":%s NOTICE * :*** Notice -- ", me.name); - va_end(args); - - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, local_oper_list.head) - { - client_p = ptr->data; - - /* If we're sending it to opers and theyre an admin, skip. - * If we're sending it to admins, and theyre not, skip. - */ - if(((level == L_ADMIN) && !IsOperAdmin(client_p)) || - ((level == L_OPER) && IsOperAdmin(client_p))) - continue; - - if(client_p->umodes & flags) - _send_linebuf(client_p, &linebuf); - } - - rb_linebuf_donebuf(&linebuf); -} - /* sendto_realops_snomask() * * inputs - snomask needed, level (opers/admin), va_args @@ -1047,7 +1037,7 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...) char *snobuf; struct Client *client_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; va_list args; buf_head_t linebuf; @@ -1065,14 +1055,19 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...) ":%s NOTICE * :*** Notice -- %s", me.name, buf); snobuf = construct_snobuf(flags); if (snobuf[1] != '\0') - { sendto_server(NULL, NULL, CAP_ENCAP|CAP_TS6, NOCAPS, ":%s ENCAP * SNOTE %c :%s", me.id, snobuf[1], buf); - sendto_server(NULL, NULL, CAP_ENCAP, CAP_TS6, - ":%s ENCAP * SNOTE %c :%s", - me.name, snobuf[1], buf); - } + } + else if (remote_rehash_oper_p != NULL) + { + /* rather a lot of copying around, oh well -- jilles */ + va_start(args, pattern); + rb_vsnprintf(buf, sizeof(buf), pattern, args); + va_end(args); + rb_linebuf_putmsg(&linebuf, pattern, NULL, + ":%s NOTICE * :*** Notice -- %s", me.name, buf); + sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf); } else { @@ -1083,7 +1078,7 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...) } level &= ~L_NETWIDE; - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, local_oper_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head) { client_p = ptr->data; @@ -1112,7 +1107,7 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p, { struct Client *client_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; va_list args; buf_head_t linebuf; @@ -1123,7 +1118,7 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p, ":%s NOTICE * :*** Notice -- ", source_p->name); va_end(args); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, local_oper_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, local_oper_list.head) { client_p = ptr->data; @@ -1155,7 +1150,7 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, .. { struct Client *client_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; va_list args; buf_head_t linebuf; @@ -1172,7 +1167,7 @@ sendto_wallops_flags(int flags, struct Client *source_p, const char *pattern, .. va_end(args); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, IsPerson(source_p) && flags == UMODE_WALLOP ? lclient_list.head : local_oper_list.head) { client_p = ptr->data; @@ -1225,23 +1220,19 @@ kill_client_serv_butone(struct Client *one, struct Client *target_p, const char va_list args; struct Client *client_p; rb_dlink_node *ptr; - rb_dlink_node *rb_free(; + rb_dlink_node *next_ptr; buf_head_t rb_linebuf_id; - buf_head_t rb_linebuf_name; - rb_linebuf_newbuf(&rb_linebuf_name); rb_linebuf_newbuf(&rb_linebuf_id); va_start(args, pattern); rb_vsnprintf(buf, sizeof(buf), pattern, args); va_end(args); - rb_linebuf_putmsg(&rb_linebuf_name, NULL, NULL, ":%s KILL %s :%s", - me.name, target_p->name, buf); rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s KILL %s :%s", use_id(&me), use_id(target_p), buf); - RB_DLINK_FOREACH_SAFE(ptr, rb_free(, serv_list.head) + RB_DLINK_FOREACH_SAFE(ptr, next_ptr, serv_list.head) { client_p = ptr->data; @@ -1252,12 +1243,8 @@ kill_client_serv_butone(struct Client *one, struct Client *target_p, const char (!has_id(client_p) || !has_id(target_p))) continue; - if(has_id(client_p)) - _send_linebuf(client_p, &rb_linebuf_id); - else - _send_linebuf(client_p, &rb_linebuf_name); + _send_linebuf(client_p, &rb_linebuf_id); } rb_linebuf_donebuf(&rb_linebuf_id); - rb_linebuf_donebuf(&rb_linebuf_name); }