1 /* modules/m_alias.c - main module for aliases
2 * Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice is present in all copies.
8 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
9 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
11 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
12 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
13 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
14 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
15 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
16 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
17 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
18 * POSSIBILITY OF SUCH DAMAGE.
35 static const char alias_desc
[] = "Provides the system for services aliases";
37 static int _modinit(void);
38 static void _moddeinit(void);
39 static int reload_aliases(hook_data
*);
40 static void m_alias(struct MsgBuf
*, struct Client
*, struct Client
*, int, const char **);
42 mapi_hfn_list_av1 alias_hfnlist
[] = {
43 { "rehash", (hookfn
)reload_aliases
},
47 DECLARE_MODULE_AV2(alias
, _modinit
, _moddeinit
, NULL
, NULL
, alias_hfnlist
, NULL
, NULL
, alias_desc
);
49 static rb_dlink_list alias_messages
;
50 static const struct MessageEntry alias_msgtab
[] =
51 {{m_alias
, 2}, {m_alias
, 2}, mg_ignore
, mg_ignore
, mg_ignore
, {m_alias
, 2}};
56 rb_dictionary_iter iter
;
57 struct alias_entry
*alias
;
59 s_assert(rb_dlink_list_length(&alias_messages
) > 0);
61 RB_DICTIONARY_FOREACH(alias
, &iter
, alias_dict
)
63 struct Message
*message
= rb_malloc(sizeof(struct Message
));
65 message
->cmd
= alias
->name
;
66 memcpy(message
->handlers
, alias_msgtab
, sizeof(alias_msgtab
));
69 rb_dlinkAddAlloc(message
, &alias_messages
);
76 rb_dlink_node
*ptr
, *nptr
;
78 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, alias_messages
.head
)
80 mod_del_cmd((struct Message
*)ptr
->data
);
82 rb_dlinkDestroy(ptr
, &alias_messages
);
100 reload_aliases(hook_data
*data
)
102 destroy_aliases(); /* Clear old aliases */
107 /* The below was mostly taken from the old do_alias */
109 m_alias(struct MsgBuf
*msgbuf
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
111 struct Client
*target_p
;
112 struct alias_entry
*aptr
= rb_dictionary_retrieve(alias_dict
, msgbuf
->cmd
);
117 /* This shouldn't happen... */
118 if(IsPerson(client_p
))
119 sendto_one(client_p
, form_str(ERR_UNKNOWNCOMMAND
),
120 me
.name
, client_p
->name
, msgbuf
->cmd
);
126 sendto_one(client_p
, form_str(ERR_NEEDMOREPARAMS
),
128 EmptyString(client_p
->name
) ? "*" : client_p
->name
,
133 if(!IsFloodDone(client_p
) && client_p
->localClient
->receiveM
> 20)
134 flood_endgrace(client_p
);
136 p
= strchr(aptr
->target
, '@');
140 target_p
= find_server(NULL
, p
+ 1);
141 if(target_p
!= NULL
&& IsMe(target_p
))
146 /* nick, must be +S */
147 target_p
= find_named_person(aptr
->target
);
148 if(target_p
!= NULL
&& !IsService(target_p
))
154 sendto_one_numeric(client_p
, ERR_SERVICESDOWN
, form_str(ERR_SERVICESDOWN
), aptr
->target
);
158 if(EmptyString(parv
[1]))
160 sendto_one(client_p
, form_str(ERR_NOTEXTTOSEND
), me
.name
, target_p
->name
);
164 /* increment the hitcounter on this alias */
167 sendto_one(target_p
, ":%s PRIVMSG %s :%s",
168 get_id(client_p
, target_p
),
169 p
!= NULL
? aptr
->target
: get_id(target_p
, target_p
),