]> jfr.im git - solanum.git/blobdiff - src/send.c
ssld: use uint64_t explicitly when we want 64-bit counters
[solanum.git] / src / send.c
index 5cdd232c961dbe38df7d5ec909e9132419a78f6e..cb2112054a73e6d673a6f7583f263a51ecb3ddb6 100644 (file)
@@ -76,19 +76,16 @@ _send_linebuf(struct Client *to, buf_head_t *linebuf)
                        sendto_realops_snomask(SNO_GENERAL, L_ALL,
                                             "Max SendQ limit exceeded for %s: %u > %lu",
                                             to->name,
-                                            rb_linebuf_len(&to->localClient->buf_sendq), 
+                                            rb_linebuf_len(&to->localClient->buf_sendq),
                                             get_sendq(to));
 
                        ilog(L_SERVER, "Max SendQ limit exceeded for %s: %u > %lu",
                             log_client_name(to, SHOW_IP),
-                            rb_linebuf_len(&to->localClient->buf_sendq), 
+                            rb_linebuf_len(&to->localClient->buf_sendq),
                             get_sendq(to));
                }
 
-               if(IsClient(to))
-                       to->flags |= FLAGS_SENDQEX;
-
-               dead_link(to);
+               dead_link(to, 1);
                return -1;
        }
        else
@@ -180,7 +177,7 @@ send_queued(struct Client *to)
                                         ((buf_line_t *) to->localClient->buf_sendq.list.head->
                                          data)->buf + to->localClient->buf_sendq.writeofs;
 #endif
-     
+
 
                        ClearFlush(to);
 
@@ -200,7 +197,7 @@ send_queued(struct Client *to)
 
                if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
                {
-                       dead_link(to);
+                       dead_link(to, 0);
                        return;
                }
        }
@@ -244,7 +241,7 @@ send_queued_write(rb_fde_t *F, void *data)
  *
  * inputs      - client to send to, va_args
  * outputs     - client has message put into its queue
- * side effects - 
+ * side effects -
  */
 void
 sendto_one(struct Client *target_p, const char *pattern, ...)
@@ -396,7 +393,7 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
 
 /*
  * sendto_server
- * 
+ *
  * inputs       - pointer to client to NOT send to
  *              - caps or'd together which must ALL be present
  *              - caps or'd together which must ALL NOT be present
@@ -406,7 +403,7 @@ sendto_one_numeric(struct Client *target_p, int numeric, const char *pattern, ..
  * side effects - Send a message to all connected servers, except the
  *                client 'one' (if non-NULL), as long as the servers
  *                support ALL capabs in 'caps', and NO capabs in 'nocaps'.
- *            
+ *
  * This function was written in an attempt to merge together the other
  * billion sendto_*serv*() functions, which sprung up with capabs, uids etc
  * -davidt
@@ -490,7 +487,7 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
        else
                rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
                               ":%s!%s@%s %s",
-                              source_p->name, source_p->username, 
+                              source_p->name, source_p->username,
                               source_p->host, buf);
 
        rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
@@ -563,7 +560,7 @@ sendto_channel_opmod(struct Client *one, struct Client *source_p,
        else
                rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
                               ":%s!%s@%s %s %s :%s",
-                              source_p->name, source_p->username, 
+                              source_p->name, source_p->username,
                               source_p->host, command, chptr->chname, text);
 
        if (chptr->mode.mode & MODE_MODERATED)
@@ -634,9 +631,9 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
        struct Client *target_p;
        rb_dlink_node *ptr;
        rb_dlink_node *next_ptr;
-       
-       rb_linebuf_newbuf(&linebuf); 
-       
+
+       rb_linebuf_newbuf(&linebuf);
+
        va_start(args, pattern);
        rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
        va_end(args);
@@ -658,38 +655,35 @@ sendto_channel_local(int type, struct Channel *chptr, const char *pattern, ...)
        rb_linebuf_donebuf(&linebuf);
 }
 
-/* sendto_channel_local_butone()
+/*
+ * _sendto_channel_local_with_capability_butone()
  *
- * inputs      - flags to send to, channel to send to, va_args
- *             - user to ignore when sending
- * outputs     - message to local channel members
- * side effects -
+ * Shared implementation of sendto_channel_local_with_capability and sendto_channel_local_with_capability_butone
  */
-void
-sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
+static void
+_sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr,
+       const char *pattern, va_list * args)
 {
-       va_list args;
        buf_head_t linebuf;
        struct membership *msptr;
        struct Client *target_p;
        rb_dlink_node *ptr;
        rb_dlink_node *next_ptr;
-       
-       rb_linebuf_newbuf(&linebuf); 
-       
-       va_start(args, pattern);
-       rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
-       va_end(args);
+
+       rb_linebuf_newbuf(&linebuf);
+       rb_linebuf_putmsg(&linebuf, pattern, args, NULL);
 
        RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
        {
                msptr = ptr->data;
                target_p = msptr->client_p;
 
-               if(target_p == one)
+               if (target_p == one)
                        continue;
 
-               if(IsIOError(target_p))
+               if(IsIOError(target_p) ||
+                  !IsCapable(target_p, caps) ||
+                  !NotCapable(target_p, negcaps))
                        continue;
 
                if(type && ((msptr->flags & type) == 0))
@@ -701,139 +695,98 @@ sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr,
        rb_linebuf_donebuf(&linebuf);
 }
 
-/*
- * sendto_common_channels_local()
+/* sendto_channel_local_with_capability()
  *
- * inputs      - pointer to client
- *             - pattern to send
- * output      - NONE
- * side effects        - Sends a message to all people on local server who are
- *               in same channel with user. 
- *               used by m_nick.c and exit_one_client.
+ * inputs      - flags to send to, caps, negate caps, channel to send to, va_args
+ * outputs     - message to local channel members
+ * side effects -
  */
 void
-sendto_common_channels_local(struct Client *user, const char *pattern, ...)
+sendto_channel_local_with_capability(int type, int caps, int negcaps, struct Channel *chptr, const char *pattern, ...)
 {
        va_list args;
-       rb_dlink_node *ptr;
-       rb_dlink_node *next_ptr;
-       rb_dlink_node *uptr;
-       rb_dlink_node *next_uptr;
-       struct Channel *chptr;
-       struct Client *target_p;
-       struct membership *msptr;
-       struct membership *mscptr;
-       buf_head_t linebuf;
 
-       rb_linebuf_newbuf(&linebuf);
        va_start(args, pattern);
-       rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
+       _sendto_channel_local_with_capability_butone(NULL, type, caps, negcaps, chptr, pattern, &args);
        va_end(args);
+}
 
-       ++current_serial;
-
-       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
-       {
-               mscptr = ptr->data;
-               chptr = mscptr->chptr;
-
-               RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
-               {
-                       msptr = uptr->data;
-                       target_p = msptr->client_p;
-
-                       if(IsIOError(target_p) ||
-                          target_p->serial == current_serial)
-                               continue;
-
-                       target_p->serial = current_serial;
-                       send_linebuf(target_p, &linebuf);
-               }
-       }
 
-       /* this can happen when the user isnt in any channels, but we still
-        * need to send them the data, ie a nick change
-        */
-       if(MyConnect(user) && (user->serial != current_serial))
-               send_linebuf(user, &linebuf);
+/* sendto_channel_local_with_capability()
+ *
+ * inputs      - flags to send to, caps, negate caps, channel to send to, va_args
+ * outputs     - message to local channel members
+ * side effects -
+ */
+void
+sendto_channel_local_with_capability_butone(struct Client *one, int type, int caps, int negcaps, struct Channel *chptr,
+               const char *pattern, ...)
+{
+       va_list args;
 
-       rb_linebuf_donebuf(&linebuf);
+       va_start(args, pattern);
+       _sendto_channel_local_with_capability_butone(one, type, caps, negcaps, chptr, pattern, &args);
+       va_end(args);
 }
 
-/*
- * sendto_common_channels_local_with_capability()
+
+/* sendto_channel_local_butone()
  *
- * inputs      - pointer to client
- *              - capability
- *             - pattern to send
- * output      - NONE
- * side effects        - Sends a message to all people on local server who are
- *               in same channel with user. 
- *               used by m_nick.c and exit_one_client.
+ * inputs      - flags to send to, channel to send to, va_args
+ *             - user to ignore when sending
+ * outputs     - message to local channel members
+ * side effects -
  */
 void
-sendto_common_channels_local_with_capability(struct Client *user, int capability, const char *pattern, ...)
+sendto_channel_local_butone(struct Client *one, int type, struct Channel *chptr, const char *pattern, ...)
 {
        va_list args;
+       buf_head_t linebuf;
+       struct membership *msptr;
+       struct Client *target_p;
        rb_dlink_node *ptr;
        rb_dlink_node *next_ptr;
-       rb_dlink_node *uptr;
-       rb_dlink_node *next_uptr;
-       struct Channel *chptr;
-       struct Client *target_p;
-       struct membership *msptr;
-       struct membership *mscptr;
-       buf_head_t linebuf;
 
        rb_linebuf_newbuf(&linebuf);
+
        va_start(args, pattern);
        rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
        va_end(args);
 
-       ++current_serial;
-
-       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
+       RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
        {
-               mscptr = ptr->data;
-               chptr = mscptr->chptr;
+               msptr = ptr->data;
+               target_p = msptr->client_p;
 
-               RB_DLINK_FOREACH_SAFE(uptr, next_uptr, chptr->locmembers.head)
-               {
-                       msptr = uptr->data;
-                       target_p = msptr->client_p;
+               if(target_p == one)
+                       continue;
 
-                       if(!IsCapable(target_p, capability))
-                               continue;
+               if(IsIOError(target_p))
+                       continue;
 
-                       if(IsIOError(target_p) ||
-                          target_p->serial == current_serial)
-                               continue;
+               if(type && ((msptr->flags & type) == 0))
+                       continue;
 
-                       target_p->serial = current_serial;
-                       send_linebuf(target_p, &linebuf);
-               }
+               _send_linebuf(target_p, &linebuf);
        }
 
-       /* this can happen when the user isnt in any channels, but we still
-        * need to send them the data, ie a nick change
-        */
-       if(MyConnect(user) && (user->serial != current_serial))
-               send_linebuf(user, &linebuf);
-
        rb_linebuf_donebuf(&linebuf);
 }
 
 /*
- * sendto_common_channels_local_butone()
+ * sendto_common_channels_local()
  *
  * inputs      - pointer to client
+ *              - capability mask
+ *             - negated capability mask
  *             - pattern to send
  * output      - NONE
  * side effects        - Sends a message to all people on local server who are
- *               in same channel with user, except for user itself.
+ *               in same channel with user.
+ *               used by m_nick.c and exit_one_client.
  */
 void
-sendto_common_channels_local_butone(struct Client *user, const char *pattern, ...)
+sendto_common_channels_local(struct Client *user, int cap, int negcap, const char *pattern, ...)
 {
        va_list args;
        rb_dlink_node *ptr;
@@ -852,8 +805,6 @@ sendto_common_channels_local_butone(struct Client *user, const char *pattern, ..
        va_end(args);
 
        ++current_serial;
-       /* Skip them -- jilles */
-       user->serial = current_serial;
 
        RB_DLINK_FOREACH_SAFE(ptr, next_ptr, user->user->channel.head)
        {
@@ -866,7 +817,9 @@ sendto_common_channels_local_butone(struct Client *user, const char *pattern, ..
                        target_p = msptr->client_p;
 
                        if(IsIOError(target_p) ||
-                          target_p->serial == current_serial)
+                          target_p->serial == current_serial ||
+                          !IsCapable(target_p, cap) ||
+                          !NotCapable(target_p, negcap))
                                continue;
 
                        target_p->serial = current_serial;
@@ -874,22 +827,28 @@ sendto_common_channels_local_butone(struct Client *user, const char *pattern, ..
                }
        }
 
+       /* this can happen when the user isnt in any channels, but we still
+        * need to send them the data, ie a nick change
+        */
+       if(MyConnect(user) && (user->serial != current_serial))
+               send_linebuf(user, &linebuf);
+
        rb_linebuf_donebuf(&linebuf);
 }
 
 /*
- * sendto_common_channels_local_with_capability_butone()
+ * sendto_common_channels_local_butone()
  *
  * inputs      - pointer to client
- *              - capability
+ *              - capability mask
+ *             - negated capability mask
  *             - pattern to send
  * output      - NONE
  * side effects        - Sends a message to all people on local server who are
- *               in same channel with user, except the user themselves.
- *               used by m_nick.c and exit_one_client.
+ *               in same channel with user, except for user itself.
  */
 void
-sendto_common_channels_local_with_capability_butone(struct Client *user, int capability, const char *pattern, ...)
+sendto_common_channels_local_butone(struct Client *user, int cap, int negcap, const char *pattern, ...)
 {
        va_list args;
        rb_dlink_node *ptr;
@@ -921,11 +880,10 @@ sendto_common_channels_local_with_capability_butone(struct Client *user, int cap
                        msptr = uptr->data;
                        target_p = msptr->client_p;
 
-                       if(!IsCapable(target_p, capability))
-                               continue;
-
                        if(IsIOError(target_p) ||
-                          target_p->serial == current_serial)
+                          target_p->serial == current_serial ||
+                          !IsCapable(target_p, cap) ||
+                          !NotCapable(target_p, negcap))
                                continue;
 
                        target_p->serial = current_serial;
@@ -933,16 +891,9 @@ sendto_common_channels_local_with_capability_butone(struct Client *user, int cap
                }
        }
 
-       /* this can happen when the user isnt in any channels, but we still
-        * need to send them the data, ie a nick change
-        */
-       if(MyConnect(user) && (user->serial != current_serial))
-               send_linebuf(user, &linebuf);
-
        rb_linebuf_donebuf(&linebuf);
 }
 
-
 /* sendto_match_butone()
  *
  * inputs      - server not to send to, source, mask, type of mask, va_args
@@ -974,7 +925,7 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
        else
                rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
                               ":%s!%s@%s %s",
-                              source_p->name, source_p->username, 
+                              source_p->name, source_p->username,
                               source_p->host, buf);
 
        rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, ":%s %s", use_id(source_p), buf);
@@ -1016,11 +967,11 @@ sendto_match_butone(struct Client *one, struct Client *source_p,
 /* sendto_match_servs()
  *
  * inputs       - source, mask to send to, caps needed, va_args
- * outputs      - 
+ * outputs      -
  * side effects - message is sent to matching servers with caps.
  */
 void
-sendto_match_servs(struct Client *source_p, const char *mask, int cap, 
+sendto_match_servs(struct Client *source_p, const char *mask, int cap,
                        int nocap, const char *pattern, ...)
 {
        static char buf[BUFSIZE];
@@ -1038,7 +989,7 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap,
        rb_vsnprintf(buf, sizeof(buf), pattern, args);
        va_end(args);
 
-       rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL, 
+       rb_linebuf_putmsg(&rb_linebuf_id, NULL, NULL,
                        ":%s %s", use_id(source_p), buf);
 
        current_serial++;
@@ -1074,6 +1025,39 @@ sendto_match_servs(struct Client *source_p, const char *mask, int cap,
        rb_linebuf_donebuf(&rb_linebuf_id);
 }
 
+/* sendto_local_clients_with_capability()
+ *
+ * inputs       - caps needed, pattern, va_args
+ * outputs      -
+ * side effects - message is sent to matching local clients with caps.
+ */
+void
+sendto_local_clients_with_capability(int cap, const char *pattern, ...)
+{
+       va_list args;
+       rb_dlink_node *ptr;
+       struct Client *target_p;
+       buf_head_t linebuf;
+
+       rb_linebuf_newbuf(&linebuf);
+
+       va_start(args, pattern);
+       rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
+       va_end(args);
+
+       RB_DLINK_FOREACH(ptr, lclient_list.head)
+       {
+               target_p = ptr->data;
+
+               if(IsIOError(target_p) || !IsCapable(target_p, cap))
+                       continue;
+
+               send_linebuf(target_p, &linebuf);
+       }
+
+       rb_linebuf_donebuf(&linebuf);
+}
+
 /* sendto_monitor()
  *
  * inputs      - monitor nick to send to, format, va_args
@@ -1088,9 +1072,9 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...)
        struct Client *target_p;
        rb_dlink_node *ptr;
        rb_dlink_node *next_ptr;
-       
-       rb_linebuf_newbuf(&linebuf); 
-       
+
+       rb_linebuf_newbuf(&linebuf);
+
        va_start(args, pattern);
        rb_linebuf_putmsg(&linebuf, pattern, &args, NULL);
        va_end(args);
@@ -1115,7 +1099,7 @@ sendto_monitor(struct monitor *monptr, const char *pattern, ...)
  * side effects - client is sent message with correct prefix.
  */
 void
-sendto_anywhere(struct Client *target_p, struct Client *source_p, 
+sendto_anywhere(struct Client *target_p, struct Client *source_p,
                const char *command, const char *pattern, ...)
 {
        va_list args;
@@ -1129,11 +1113,11 @@ sendto_anywhere(struct Client *target_p, struct Client *source_p,
        {
                if(IsServer(source_p))
                        rb_linebuf_putmsg(&linebuf, pattern, &args, ":%s %s %s ",
-                                      source_p->name, command, 
+                                      source_p->name, command,
                                       target_p->name);
                else
-                       rb_linebuf_putmsg(&linebuf, pattern, &args, 
-                                      ":%s!%s@%s %s %s ", 
+                       rb_linebuf_putmsg(&linebuf, pattern, &args,
+                                      ":%s!%s@%s %s %s ",
                                       source_p->name, source_p->username,
                                       source_p->host, command,
                                       target_p->name);
@@ -1179,7 +1163,7 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
                va_start(args, pattern);
                rb_vsnprintf(buf, sizeof(buf), pattern, args);
                va_end(args);
-               rb_linebuf_putmsg(&linebuf, pattern, NULL, 
+               rb_linebuf_putmsg(&linebuf, pattern, NULL,
                                ":%s NOTICE * :*** Notice -- %s", me.name, buf);
                snobuf = construct_snobuf(flags);
                if (snobuf[1] != '\0')
@@ -1193,14 +1177,14 @@ sendto_realops_snomask(int flags, int level, const char *pattern, ...)
                va_start(args, pattern);
                rb_vsnprintf(buf, sizeof(buf), pattern, args);
                va_end(args);
-               rb_linebuf_putmsg(&linebuf, pattern, NULL, 
+               rb_linebuf_putmsg(&linebuf, pattern, NULL,
                                ":%s NOTICE * :*** Notice -- %s", me.name, buf);
                sendto_one_notice(remote_rehash_oper_p, ":*** Notice -- %s", buf);
        }
        else
        {
                va_start(args, pattern);
-               rb_linebuf_putmsg(&linebuf, pattern, &args, 
+               rb_linebuf_putmsg(&linebuf, pattern, &args,
                                ":%s NOTICE * :*** Notice -- ", me.name);
                va_end(args);
        }
@@ -1242,7 +1226,7 @@ sendto_realops_snomask_from(int flags, int level, struct Client *source_p,
        rb_linebuf_newbuf(&linebuf);
 
        va_start(args, pattern);
-       rb_linebuf_putmsg(&linebuf, pattern, &args, 
+       rb_linebuf_putmsg(&linebuf, pattern, &args,
                       ":%s NOTICE * :*** Notice -- ", source_p->name);
        va_end(args);
 
@@ -1352,7 +1336,7 @@ kill_client_serv_butone(struct Client *one, struct Client *target_p, const char
        buf_head_t rb_linebuf_id;
 
        rb_linebuf_newbuf(&rb_linebuf_id);
-       
+
        va_start(args, pattern);
        rb_vsnprintf(buf, sizeof(buf), pattern, args);
        va_end(args);