52 |
* 't' points -> [MessageTree *] 'r' -> [MessageTree *] -> 'i' |
* 't' points -> [MessageTree *] 'r' -> [MessageTree *] -> 'i' |
53 |
* -> [MessageTree *] -> [MessageTree *] -> 'e' and matches |
* -> [MessageTree *] -> [MessageTree *] -> 'e' and matches |
54 |
* |
* |
55 |
* 'i' -> [MessageTree *] -> 'e' and matches |
* 'i' -> [MessageTree *] -> 'e' and matches |
56 |
* |
* |
57 |
* BUGS (Limitations!) |
* BUGS (Limitations!) |
58 |
* |
* |
70 |
* Diane Bruce (Dianora), June 6 2003 |
* Diane Bruce (Dianora), June 6 2003 |
71 |
*/ |
*/ |
72 |
|
|
73 |
#define MAXPTRLEN 32 |
#define MAXPTRLEN 32 |
74 |
/* Must be a power of 2, and |
/* Must be a power of 2, and |
75 |
* larger than 26 [a-z]|[A-Z] |
* larger than 26 [a-z]|[A-Z] |
76 |
* its used to allocate the set |
* its used to allocate the set |
90 |
struct MessageTree |
struct MessageTree |
91 |
{ |
{ |
92 |
int links; /* Count of all pointers (including msg) at this node |
int links; /* Count of all pointers (including msg) at this node |
93 |
* used as reference count for deletion of _this_ node. |
* used as reference count for deletion of _this_ node. |
94 |
*/ |
*/ |
95 |
struct Message *msg; |
struct Message *msg; |
96 |
struct MessageTree *pointers[MAXPTRLEN]; |
struct MessageTree *pointers[MAXPTRLEN]; |
97 |
}; |
}; |
102 |
* NOTE: parse() should not be called recursively by other functions! |
* NOTE: parse() should not be called recursively by other functions! |
103 |
*/ |
*/ |
104 |
static char *sender; |
static char *sender; |
105 |
static char *para[MAXPARA + 1]; |
static char *para[IRCD_MAXPARA + 1]; |
106 |
static char buffer[1024]; |
static char buffer[1024]; |
107 |
|
|
108 |
static int cancel_clients(struct Client *, struct Client *, char *); |
static int cancel_clients(struct Client *, struct Client *, char *); |
115 |
|
|
116 |
/* turn a string into a parc/parv pair */ |
/* turn a string into a parc/parv pair */ |
117 |
static inline int |
static inline int |
118 |
string_to_array(char *string, char *parv[MAXPARA]) |
string_to_array(char *string, char *parv[]) |
119 |
{ |
{ |
120 |
char *p; |
char *p; |
121 |
char *buf = string; |
char *buf = string; |
157 |
|
|
158 |
if (*buf == '\0') |
if (*buf == '\0') |
159 |
return(x); |
return(x); |
160 |
} while (x < MAXPARA - 1); |
} while (x < IRCD_MAXPARA - 1); |
161 |
|
|
162 |
if (*p == ':') |
if (*p == ':') |
163 |
p++; |
p++; |
221 |
{ |
{ |
222 |
from = find_server(sender); |
from = find_server(sender); |
223 |
|
|
224 |
if (from == NULL && IsCapable(client_p, CAP_TS6) && |
if (from == NULL && IsCapable(client_p, CAP_TS6) && |
225 |
client_p->name[0] == '*' && IsDigit(*sender) && strlen(sender) == 3) |
client_p->name[0] == '*' && IsDigit(*sender) && strlen(sender) == 3) |
226 |
{ |
{ |
227 |
/* Dirty hack to allow messages from masked SIDs (i.e. the ones |
/* Dirty hack to allow messages from masked SIDs (i.e. the ones |
228 |
* hidden by fakename="..."). It shouldn't break anything, since |
* hidden by fakename="..."). It shouldn't break anything, since |
229 |
* unknown SIDs don't happen during normal ircd work --adx |
* unknown SIDs don't happen during normal ircd work --adx |
230 |
*/ |
*/ |
231 |
from = client_p; |
from = client_p; |
232 |
} |
} |
233 |
} |
} |
234 |
|
|
235 |
/* Hmm! If the client corresponding to the |
/* |
236 |
|
* Hmm! If the client corresponding to the |
237 |
* prefix is not found--what is the correct |
* prefix is not found--what is the correct |
238 |
* action??? Now, I will ignore the message |
* action??? Now, I will ignore the message |
239 |
* (old IRC just let it through as if the |
* (old IRC just let it through as if the |
279 |
{ |
{ |
280 |
mptr = NULL; |
mptr = NULL; |
281 |
numeric = ch; |
numeric = ch; |
282 |
paramcount = MAXPARA; |
paramcount = IRCD_MAXPARA; |
283 |
++ServerStats.is_num; |
++ServerStats.is_num; |
284 |
s = ch + 3; /* I know this is ' ' from above if */ |
s = ch + 3; /* I know this is ' ' from above if */ |
285 |
*s++ = '\0'; /* blow away the ' ', and point s to next part */ |
*s++ = '\0'; /* blow away the ' ', and point s to next part */ |
349 |
*/ |
*/ |
350 |
static void |
static void |
351 |
handle_command(struct Message *mptr, struct Client *client_p, |
handle_command(struct Message *mptr, struct Client *client_p, |
352 |
struct Client *from, unsigned int i, char *hpara[MAXPARA]) |
struct Client *from, unsigned int i, char *hpara[]) |
353 |
{ |
{ |
354 |
MessageHandler handler = 0; |
MessageHandler handler = 0; |
355 |
|
|
438 |
if (*cmd == '\0') |
if (*cmd == '\0') |
439 |
{ |
{ |
440 |
mtree_p->msg = msg_p; |
mtree_p->msg = msg_p; |
441 |
mtree_p->links++; /* Have msg pointer, so up ref count */ |
mtree_p->links++; /* Have msg pointer, so up ref count */ |
442 |
} |
} |
443 |
else |
else |
444 |
{ |
{ |
453 |
ntree_p = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree)); |
ntree_p = (struct MessageTree *)MyMalloc(sizeof(struct MessageTree)); |
454 |
mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = ntree_p; |
mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = ntree_p; |
455 |
|
|
456 |
mtree_p->links++; /* Have new pointer, so up ref count */ |
mtree_p->links++; /* Have new pointer, so up ref count */ |
457 |
} |
} |
458 |
|
|
459 |
add_msg_element(ntree_p, msg_p, cmd+1); |
add_msg_element(ntree_p, msg_p, cmd+1); |
460 |
} |
} |
461 |
} |
} |
488 |
{ |
{ |
489 |
struct MessageTree *ntree_p; |
struct MessageTree *ntree_p; |
490 |
|
|
491 |
/* In case this is called for a nonexistent command |
/* |
492 |
|
* In case this is called for a nonexistent command |
493 |
* check that there is a msg pointer here, else links-- goes -ve |
* check that there is a msg pointer here, else links-- goes -ve |
494 |
* -db |
* -db |
495 |
*/ |
*/ |
|
|
|
496 |
if ((*cmd == '\0') && (mtree_p->msg != NULL)) |
if ((*cmd == '\0') && (mtree_p->msg != NULL)) |
497 |
{ |
{ |
498 |
mtree_p->msg = NULL; |
mtree_p->msg = NULL; |
503 |
if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN-1)]) != NULL) |
if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN-1)]) != NULL) |
504 |
{ |
{ |
505 |
del_msg_element(ntree_p, cmd+1); |
del_msg_element(ntree_p, cmd+1); |
506 |
|
|
507 |
if (ntree_p->links == 0) |
if (ntree_p->links == 0) |
508 |
{ |
{ |
509 |
mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = NULL; |
mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = NULL; |
510 |
mtree_p->links--; |
mtree_p->links--; |
511 |
MyFree(ntree_p); |
MyFree(ntree_p); |
512 |
} |
} |
513 |
} |
} |
514 |
} |
} |
803 |
*/ |
*/ |
804 |
num = atoi(numeric); |
num = atoi(numeric); |
805 |
|
|
806 |
if ((num != ERR_NOSUCHNICK)) |
if (num != ERR_NOSUCHNICK) |
807 |
sendto_realops_flags(UMODE_ALL, L_ADMIN, |
sendto_realops_flags(UMODE_ALL, L_ADMIN, |
808 |
"*** %s(via %s) sent a %s numeric to me: %s", |
"*** %s(via %s) sent a %s numeric to me: %s", |
809 |
source_p->name, client_p->name, numeric, buffer); |
source_p->name, client_p->name, numeric, buffer); |
810 |
return; |
return; |
811 |
} |
} |
812 |
else if (target_p->from == client_p) |
else if (target_p->from == client_p) |
833 |
} |
} |
834 |
else if ((chptr = hash_find_channel(parv[1])) != NULL) |
else if ((chptr = hash_find_channel(parv[1])) != NULL) |
835 |
sendto_channel_local(ALL_MEMBERS, NO, chptr, |
sendto_channel_local(ALL_MEMBERS, NO, chptr, |
836 |
":%s %s %s %s", |
":%s %s %s %s", |
837 |
source_p->name, |
source_p->name, |
838 |
numeric, chptr->chname, buffer); |
numeric, chptr->chname, buffer); |
839 |
} |
} |
840 |
|
|
841 |
/* m_not_oper() |
/* m_not_oper() |