mirror of
https://github.com/matrix-construct/construct
synced 2024-10-01 21:28:53 +02:00
Revert "Implement the netsplit batch type."
This needs more work, see
https://github.com/ircv3/ircv3-specifications/issues/253
This reverts commit 2373891299
.
This commit is contained in:
parent
2373891299
commit
7445ece1d1
8 changed files with 1 additions and 346 deletions
|
@ -1,47 +0,0 @@
|
||||||
/* ircd/batch.h - batch management
|
|
||||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice is present in all copies.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
||||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdinc.h"
|
|
||||||
#include "client.h"
|
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BATCH_NETSPLIT,
|
|
||||||
BATCH_NETJOIN,
|
|
||||||
BATCH_LAST,
|
|
||||||
} batch_type;
|
|
||||||
|
|
||||||
/* Used for netsplits/netjoins */
|
|
||||||
struct Batch
|
|
||||||
{
|
|
||||||
batch_type batch; /* Type of batch */
|
|
||||||
char id[8]; /* Id of batch */
|
|
||||||
void *data; /* Batch-specific data */
|
|
||||||
void *pdata; /* Private data */
|
|
||||||
int parc; /* Batch parameter count */
|
|
||||||
char **parv; /* Batch parameters */
|
|
||||||
|
|
||||||
rb_dlink_node node;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Batch *start_batch(batch_type batch, void *data, int parc, ...);
|
|
||||||
void finish_batch(struct Batch *batch_p);
|
|
||||||
|
|
||||||
struct Batch *find_batch(batch_type batch, void *data);
|
|
|
@ -68,7 +68,6 @@ extern unsigned int CLICAP_USERHOST_IN_NAMES;
|
||||||
extern unsigned int CLICAP_CAP_NOTIFY;
|
extern unsigned int CLICAP_CAP_NOTIFY;
|
||||||
extern unsigned int CLICAP_CHGHOST;
|
extern unsigned int CLICAP_CHGHOST;
|
||||||
extern unsigned int CLICAP_ECHO_MESSAGE;
|
extern unsigned int CLICAP_ECHO_MESSAGE;
|
||||||
extern unsigned int CLICAP_BATCH;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX: this is kind of ugly, but this allows us to have backwards
|
* XXX: this is kind of ugly, but this allows us to have backwards
|
||||||
|
|
|
@ -18,10 +18,9 @@ if MINGW
|
||||||
EXTRA_FLAGS = -Wl,--enable-runtime-pseudo-reloc -export-symbols-regex '*'
|
EXTRA_FLAGS = -Wl,--enable-runtime-pseudo-reloc -export-symbols-regex '*'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libircd_la_SOURCES = \
|
libircd_la_SOURCES = \
|
||||||
authproc.c \
|
authproc.c \
|
||||||
bandbi.c \
|
bandbi.c \
|
||||||
batch.c \
|
|
||||||
cache.c \
|
cache.c \
|
||||||
capability.c \
|
capability.c \
|
||||||
channel.c \
|
channel.c \
|
||||||
|
|
202
ircd/batch.c
202
ircd/batch.c
|
@ -1,202 +0,0 @@
|
||||||
/* ircd/batch.c - batch management
|
|
||||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice is present in all copies.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
||||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdinc.h"
|
|
||||||
#include "batch.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "s_serv.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "channel.h"
|
|
||||||
#include "hash.h"
|
|
||||||
#include "s_assert.h"
|
|
||||||
#include "rb_radixtree.h"
|
|
||||||
|
|
||||||
/* Multiple batches may be in progress for each slot. */
|
|
||||||
rb_dlink_list batches[BATCH_LAST];
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
generate_batch_id(char *ptr, size_t len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
const char batchchars[65] =
|
|
||||||
"\0._0123456789" /* Zero-indexed */
|
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
|
|
||||||
len--; /* Room for \0 */
|
|
||||||
for(i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
char r;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
r = batchchars[rand() & 0x7F]; /* random int between 0-64 */
|
|
||||||
|
|
||||||
if(r == '\0' && i > 3)
|
|
||||||
/* We have enough chars */
|
|
||||||
goto end;
|
|
||||||
} while(r == '\0');
|
|
||||||
|
|
||||||
ptr[i] = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
ptr[i] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Batch *
|
|
||||||
start_batch(batch_type batch, void *data, int parc, ...)
|
|
||||||
{
|
|
||||||
struct Batch *batch_p = rb_malloc(sizeof(struct Batch));
|
|
||||||
|
|
||||||
batch_p->batch = batch;
|
|
||||||
generate_batch_id(batch_p->id, sizeof(batch_p->id));
|
|
||||||
batch_p->data = data;
|
|
||||||
batch_p->parc = parc;
|
|
||||||
if(parc > 0)
|
|
||||||
{
|
|
||||||
/* Get the argument list */
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
batch_p->parv = rb_malloc(sizeof(char *) * parc);
|
|
||||||
|
|
||||||
va_start(args, parc);
|
|
||||||
for(size_t i = 0; i < parc; i++)
|
|
||||||
batch_p->parv[i] = va_arg(args, char *);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Batch-type specific processing */
|
|
||||||
switch(batch)
|
|
||||||
{
|
|
||||||
case BATCH_NETSPLIT:
|
|
||||||
case BATCH_NETJOIN:
|
|
||||||
{
|
|
||||||
/* Build list of channels affected by the batch */
|
|
||||||
rb_dlink_list *clist;
|
|
||||||
rb_radixtree_iteration_state iter;
|
|
||||||
struct Channel *chptr;
|
|
||||||
|
|
||||||
batch_p->pdata = clist = rb_malloc(sizeof(rb_dlink_list));
|
|
||||||
|
|
||||||
/* Look for channels we need to send the batch to */
|
|
||||||
RB_RADIXTREE_FOREACH(chptr, &iter, channel_tree)
|
|
||||||
{
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
|
|
||||||
if(rb_dlink_list_length(&chptr->locmembers) == 0)
|
|
||||||
/* They're all remotes, so don't send a batch */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Hunt for members in the channel from the target server
|
|
||||||
* If we find one, send the channel a BATCH message */
|
|
||||||
RB_DLINK_FOREACH(ptr, chptr->members.head)
|
|
||||||
{
|
|
||||||
struct Client *client_p = ptr->data;
|
|
||||||
|
|
||||||
if(client_p->from == data)
|
|
||||||
{
|
|
||||||
rb_dlinkAddAlloc(rb_strdup(chptr->chname), clist);
|
|
||||||
sendto_channel_local_with_capability(ALL_MEMBERS, CLICAP_BATCH, NOCAPS,
|
|
||||||
chptr, ":%s BATCH +%s %s %s",
|
|
||||||
me.name,
|
|
||||||
batch == BATCH_NETSPLIT ? "netsplit" : "netjoin",
|
|
||||||
batch_p->parv[0], batch_p->parv[1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_dlinkAdd(batch_p, &batch_p->node, &batches[batch]);
|
|
||||||
|
|
||||||
return batch_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
finish_batch(struct Batch *batch_p)
|
|
||||||
{
|
|
||||||
if(batch_p == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Batch type-specific processing */
|
|
||||||
switch(batch_p->batch)
|
|
||||||
{
|
|
||||||
case BATCH_NETSPLIT:
|
|
||||||
case BATCH_NETJOIN:
|
|
||||||
{
|
|
||||||
rb_dlink_list *clist = batch_p->pdata;
|
|
||||||
rb_dlink_node *ptr, *nptr;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH_SAFE(ptr, nptr, clist->head)
|
|
||||||
{
|
|
||||||
struct Channel *chptr = find_channel(ptr->data);
|
|
||||||
|
|
||||||
if(chptr != NULL) /* Shouldn't be but just in case... */
|
|
||||||
{
|
|
||||||
sendto_channel_local_with_capability(ALL_MEMBERS, CLICAP_BATCH, NOCAPS,
|
|
||||||
chptr, ":%s BATCH -%s %s %s",
|
|
||||||
me.name,
|
|
||||||
batch_p->batch == BATCH_NETSPLIT ? "netsplit" : "netjoin",
|
|
||||||
batch_p->parv[0], batch_p->parv[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_free(ptr->data);
|
|
||||||
rb_dlinkDestroy(ptr, clist);
|
|
||||||
}
|
|
||||||
|
|
||||||
rb_free(clist);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s_assert(0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free all the strings */
|
|
||||||
for(size_t i = 0; i < (batch_p->parc - 1); i++)
|
|
||||||
rb_free(batch_p->parv[i]);
|
|
||||||
|
|
||||||
rb_free(batch_p->parv);
|
|
||||||
|
|
||||||
rb_dlinkDelete(&batch_p->node, &batches[batch_p->batch]);
|
|
||||||
rb_free(batch_p);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Batch *
|
|
||||||
find_batch(batch_type batch, void *data)
|
|
||||||
{
|
|
||||||
rb_dlink_node *ptr;
|
|
||||||
|
|
||||||
RB_DLINK_FOREACH(ptr, batches[batch].head)
|
|
||||||
{
|
|
||||||
struct Batch *batch_p = ptr->data;
|
|
||||||
|
|
||||||
if(batch_p->data == data)
|
|
||||||
return batch_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -53,7 +53,6 @@
|
||||||
#include "sslproc.h"
|
#include "sslproc.h"
|
||||||
#include "wsproc.h"
|
#include "wsproc.h"
|
||||||
#include "s_assert.h"
|
#include "s_assert.h"
|
||||||
#include "batch.h"
|
|
||||||
|
|
||||||
#define DEBUG_EXITED_CLIENTS
|
#define DEBUG_EXITED_CLIENTS
|
||||||
|
|
||||||
|
@ -1386,25 +1385,14 @@ exit_remote_server(struct Client *client_p, struct Client *source_p, struct Clie
|
||||||
static char comment1[(HOSTLEN*2)+2];
|
static char comment1[(HOSTLEN*2)+2];
|
||||||
static char newcomment[BUFSIZE];
|
static char newcomment[BUFSIZE];
|
||||||
struct Client *target_p;
|
struct Client *target_p;
|
||||||
struct Batch *batch_p;
|
|
||||||
|
|
||||||
if(ConfigServerHide.flatten_links)
|
if(ConfigServerHide.flatten_links)
|
||||||
{
|
|
||||||
strcpy(comment1, "*.net *.split");
|
strcpy(comment1, "*.net *.split");
|
||||||
|
|
||||||
/* rb_strdup since they are later freed */
|
|
||||||
batch_p = start_batch(BATCH_NETSPLIT, source_p, 2,
|
|
||||||
rb_strdup("*.net"), rb_strdup("*.split"));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(comment1, source_p->servptr->name);
|
strcpy(comment1, source_p->servptr->name);
|
||||||
strcat(comment1, " ");
|
strcat(comment1, " ");
|
||||||
strcat(comment1, source_p->name);
|
strcat(comment1, source_p->name);
|
||||||
|
|
||||||
batch_p = start_batch(BATCH_NETSPLIT, source_p, 2,
|
|
||||||
rb_strdup(source_p->servptr->name),
|
|
||||||
rb_strdup(source_p->name));
|
|
||||||
}
|
}
|
||||||
if (IsPerson(from))
|
if (IsPerson(from))
|
||||||
snprintf(newcomment, sizeof(newcomment), "by %s: %s",
|
snprintf(newcomment, sizeof(newcomment), "by %s: %s",
|
||||||
|
@ -1442,7 +1430,6 @@ exit_remote_server(struct Client *client_p, struct Client *source_p, struct Clie
|
||||||
#else
|
#else
|
||||||
rb_dlinkAddAlloc(source_p, &dead_list);
|
rb_dlinkAddAlloc(source_p, &dead_list);
|
||||||
#endif
|
#endif
|
||||||
finish_batch(batch_p);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1476,7 +1463,6 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien
|
||||||
static char comment1[(HOSTLEN*2)+2];
|
static char comment1[(HOSTLEN*2)+2];
|
||||||
static char newcomment[BUFSIZE];
|
static char newcomment[BUFSIZE];
|
||||||
unsigned int sendk, recvk;
|
unsigned int sendk, recvk;
|
||||||
struct Batch *batch_p;
|
|
||||||
|
|
||||||
rb_dlinkDelete(&source_p->localClient->tnode, &serv_list);
|
rb_dlinkDelete(&source_p->localClient->tnode, &serv_list);
|
||||||
rb_dlinkFindDestroy(source_p, &global_serv_list);
|
rb_dlinkFindDestroy(source_p, &global_serv_list);
|
||||||
|
@ -1507,18 +1493,12 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien
|
||||||
close_connection(source_p);
|
close_connection(source_p);
|
||||||
|
|
||||||
if(ConfigServerHide.flatten_links)
|
if(ConfigServerHide.flatten_links)
|
||||||
{
|
|
||||||
strcpy(comment1, "*.net *.split");
|
strcpy(comment1, "*.net *.split");
|
||||||
batch_p = start_batch(BATCH_NETSPLIT, source_p, 2,
|
|
||||||
rb_strdup("*.net"), rb_strdup("*.split"));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(comment1, source_p->servptr->name);
|
strcpy(comment1, source_p->servptr->name);
|
||||||
strcat(comment1, " ");
|
strcat(comment1, " ");
|
||||||
strcat(comment1, source_p->name);
|
strcat(comment1, source_p->name);
|
||||||
batch_p = start_batch(BATCH_NETSPLIT, source_p, 2,
|
|
||||||
rb_strdup(source_p->servptr->name), rb_strdup(source_p->name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source_p->serv != NULL)
|
if(source_p->serv != NULL)
|
||||||
|
@ -1540,7 +1520,6 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien
|
||||||
|
|
||||||
SetDead(source_p);
|
SetDead(source_p);
|
||||||
rb_dlinkAddAlloc(source_p, &dead_list);
|
rb_dlinkAddAlloc(source_p, &dead_list);
|
||||||
finish_batch(batch_p);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,6 @@ unsigned int CLICAP_USERHOST_IN_NAMES;
|
||||||
unsigned int CLICAP_CAP_NOTIFY;
|
unsigned int CLICAP_CAP_NOTIFY;
|
||||||
unsigned int CLICAP_CHGHOST;
|
unsigned int CLICAP_CHGHOST;
|
||||||
unsigned int CLICAP_ECHO_MESSAGE;
|
unsigned int CLICAP_ECHO_MESSAGE;
|
||||||
unsigned int CLICAP_BATCH;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize our builtin capability table. --nenolod
|
* initialize our builtin capability table. --nenolod
|
||||||
|
@ -148,7 +147,6 @@ init_builtin_capabs(void)
|
||||||
CLICAP_CAP_NOTIFY = capability_put(cli_capindex, "cap-notify", NULL);
|
CLICAP_CAP_NOTIFY = capability_put(cli_capindex, "cap-notify", NULL);
|
||||||
CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", NULL);
|
CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", NULL);
|
||||||
CLICAP_ECHO_MESSAGE = capability_put(cli_capindex, "echo-message", NULL);
|
CLICAP_ECHO_MESSAGE = capability_put(cli_capindex, "echo-message", NULL);
|
||||||
CLICAP_BATCH = capability_put(cli_capindex, "batch", NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static CNCB serv_connect_callback;
|
static CNCB serv_connect_callback;
|
||||||
|
|
|
@ -9,7 +9,6 @@ auto_load_moddir=@moduledir@/autoload
|
||||||
|
|
||||||
auto_load_mod_LTLIBRARIES = \
|
auto_load_mod_LTLIBRARIES = \
|
||||||
cap_account_tag.la \
|
cap_account_tag.la \
|
||||||
cap_batch.la \
|
|
||||||
cap_server_time.la \
|
cap_server_time.la \
|
||||||
chm_nocolour.la \
|
chm_nocolour.la \
|
||||||
chm_noctcp.la \
|
chm_noctcp.la \
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
* charybdis: an advanced ircd.
|
|
||||||
* cap_batch.c: implement the batch IRCv3.2 capability
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice is present in all copies.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
||||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
||||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "stdinc.h"
|
|
||||||
#include "modules.h"
|
|
||||||
#include "hook.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "ircd.h"
|
|
||||||
#include "send.h"
|
|
||||||
#include "s_conf.h"
|
|
||||||
#include "s_user.h"
|
|
||||||
#include "s_serv.h"
|
|
||||||
#include "numeric.h"
|
|
||||||
#include "chmode.h"
|
|
||||||
#include "batch.h"
|
|
||||||
#include "inline/stringops.h"
|
|
||||||
|
|
||||||
static const char cap_batch_desc[] =
|
|
||||||
"Provides the batch client capability";
|
|
||||||
|
|
||||||
static void cap_batch_process(hook_data *);
|
|
||||||
|
|
||||||
mapi_hfn_list_av1 cap_batch_hfnlist[] = {
|
|
||||||
{ "outbound_msgbuf", (hookfn) cap_batch_process },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
cap_batch_process(hook_data *data)
|
|
||||||
{
|
|
||||||
struct MsgBuf *msgbuf = data->arg1;
|
|
||||||
struct Client *client_p = data->client;
|
|
||||||
struct Batch *batch_p;
|
|
||||||
|
|
||||||
if(rb_strcasecmp(msgbuf->cmd, "quit") == 0)
|
|
||||||
{
|
|
||||||
if(!IsClient(client_p) || MyConnect(client_p))
|
|
||||||
/* Remote users only please */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Now find our batch... */
|
|
||||||
if((batch_p = find_batch(BATCH_NETSPLIT, client_p->from)) == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Boom */
|
|
||||||
msgbuf_append_tag(msgbuf, "batch", batch_p->id, CLICAP_BATCH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_MODULE_AV2(cap_batch, NULL, NULL, NULL, NULL, cap_batch_hfnlist, NULL, NULL, cap_batch_desc);
|
|
Loading…
Reference in a new issue