]> jfr.im git - solanum.git/blame - modules/m_alias.c
Combine stats A output parameters (#35)
[solanum.git] / modules / m_alias.c
CommitLineData
b663a807
EM
1/* modules/m_alias.c - main module for aliases
2 * Copyright (c) 2016 Elizabeth Myers <elizabeth@interlinked.me>
3 *
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.
7 *
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.
19 */
20
21#include "stdinc.h"
22#include "client.h"
23#include "parse.h"
24#include "msg.h"
25#include "modules.h"
26#include "s_conf.h"
27#include "s_serv.h"
28#include "hash.h"
29#include "ircd.h"
30#include "match.h"
31#include "numeric.h"
32#include "send.h"
33#include "packet.h"
169a1c35 34#include "s_assert.h"
b663a807
EM
35
36static const char alias_desc[] = "Provides the system for services aliases";
37
38static int _modinit(void);
39static void _moddeinit(void);
40static int reload_aliases(hook_data *);
41static void m_alias(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
42
43mapi_hfn_list_av1 alias_hfnlist[] = {
44 { "rehash", (hookfn)reload_aliases },
45 { NULL, NULL },
46};
47
48DECLARE_MODULE_AV2(alias, _modinit, _moddeinit, NULL, NULL, alias_hfnlist, NULL, NULL, alias_desc);
49
50static rb_dlink_list alias_messages;
51static const struct MessageEntry alias_msgtab[] =
52 {{m_alias, 2}, {m_alias, 2}, mg_ignore, mg_ignore, mg_ignore, {m_alias, 2}};
53
54static inline void
55create_aliases(void)
56{
57 rb_dictionary_iter iter;
58 struct alias_entry *alias;
59
9620c6d6 60 s_assert(rb_dlink_list_length(&alias_messages) == 0);
b663a807
EM
61
62 RB_DICTIONARY_FOREACH(alias, &iter, alias_dict)
63 {
00039dcd 64 struct Message *message = rb_malloc(sizeof(*message) + strlen(alias->name) + 1);
d8f0b5d7 65 char *cmd = (char*)message + sizeof(*message);
b663a807 66
00039dcd
SA
67 /* copy the alias name as it will be freed early on a rehash */
68 strcpy(cmd, alias->name);
69 message->cmd = cmd;
b663a807
EM
70 memcpy(message->handlers, alias_msgtab, sizeof(alias_msgtab));
71
72 mod_add_cmd(message);
73 rb_dlinkAddAlloc(message, &alias_messages);
74 }
75}
76
77static inline void
78destroy_aliases(void)
79{
80 rb_dlink_node *ptr, *nptr;
81
82 RB_DLINK_FOREACH_SAFE(ptr, nptr, alias_messages.head)
83 {
84 mod_del_cmd((struct Message *)ptr->data);
85 rb_free(ptr->data);
86 rb_dlinkDestroy(ptr, &alias_messages);
87 }
88}
89
90static int
91_modinit(void)
92{
93 create_aliases();
94 return 0;
95}
96
97static void
98_moddeinit(void)
99{
100 destroy_aliases();
101}
102
103static int
dd598516 104reload_aliases(hook_data *data)
b663a807
EM
105{
106 destroy_aliases(); /* Clear old aliases */
107 create_aliases();
108 return 0;
109}
110
111/* The below was mostly taken from the old do_alias */
112static void
113m_alias(struct MsgBuf *msgbuf, struct Client *client_p, struct Client *source_p, int parc, const char **parv)
114{
115 struct Client *target_p;
116 struct alias_entry *aptr = rb_dictionary_retrieve(alias_dict, msgbuf->cmd);
4e14f9a4 117 char *p;
b663a807
EM
118
119 if(aptr == NULL)
120 {
dd598516
EM
121 /* This shouldn't happen... */
122 if(IsPerson(client_p))
123 sendto_one(client_p, form_str(ERR_UNKNOWNCOMMAND),
124 me.name, client_p->name, msgbuf->cmd);
b663a807
EM
125
126 return;
127 }
b663a807 128
dd598516
EM
129 if(!IsFloodDone(client_p) && client_p->localClient->receiveM > 20)
130 flood_endgrace(client_p);
b663a807
EM
131
132 p = strchr(aptr->target, '@');
133 if(p != NULL)
134 {
135 /* user@server */
136 target_p = find_server(NULL, p + 1);
137 if(target_p != NULL && IsMe(target_p))
138 target_p = NULL;
139 }
140 else
141 {
142 /* nick, must be +S */
143 target_p = find_named_person(aptr->target);
144 if(target_p != NULL && !IsService(target_p))
145 target_p = NULL;
146 }
147
148 if(target_p == NULL)
149 {
dd598516 150 sendto_one_numeric(client_p, ERR_SERVICESDOWN, form_str(ERR_SERVICESDOWN), aptr->target);
b663a807
EM
151 return;
152 }
153
4e14f9a4
EK
154 msgbuf_reconstruct_tail(msgbuf, 1);
155 if(EmptyString(parv[1]))
b663a807 156 {
dd598516 157 sendto_one(client_p, form_str(ERR_NOTEXTTOSEND), me.name, target_p->name);
b663a807
EM
158 return;
159 }
160
b663a807 161 sendto_one(target_p, ":%s PRIVMSG %s :%s",
dd598516 162 get_id(client_p, target_p),
b663a807 163 p != NULL ? aptr->target : get_id(target_p, target_p),
4e14f9a4 164 parv[1]);
b663a807 165}