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(*message
) + strlen(alias
->name
) + 1);
64 char *cmd
= (void*)message
+ sizeof(*message
);
66 /* copy the alias name as it will be freed early on a rehash */
67 strcpy(cmd
, alias
->name
);
69 memcpy(message
->handlers
, alias_msgtab
, sizeof(alias_msgtab
));
72 rb_dlinkAddAlloc(message
, &alias_messages
);
79 rb_dlink_node
*ptr
, *nptr
;
81 RB_DLINK_FOREACH_SAFE(ptr
, nptr
, alias_messages
.head
)
83 mod_del_cmd((struct Message
*)ptr
->data
);
85 rb_dlinkDestroy(ptr
, &alias_messages
);
103 reload_aliases(hook_data
*data
)
105 destroy_aliases(); /* Clear old aliases */
110 /* The below was mostly taken from the old do_alias */
112 m_alias(struct MsgBuf
*msgbuf
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char **parv
)
114 struct Client
*target_p
;
115 struct alias_entry
*aptr
= rb_dictionary_retrieve(alias_dict
, msgbuf
->cmd
);
120 /* This shouldn't happen... */
121 if(IsPerson(client_p
))
122 sendto_one(client_p
, form_str(ERR_UNKNOWNCOMMAND
),
123 me
.name
, client_p
->name
, msgbuf
->cmd
);
128 if(!IsFloodDone(client_p
) && client_p
->localClient
->receiveM
> 20)
129 flood_endgrace(client_p
);
131 p
= strchr(aptr
->target
, '@');
135 target_p
= find_server(NULL
, p
+ 1);
136 if(target_p
!= NULL
&& IsMe(target_p
))
141 /* nick, must be +S */
142 target_p
= find_named_person(aptr
->target
);
143 if(target_p
!= NULL
&& !IsService(target_p
))
149 sendto_one_numeric(client_p
, ERR_SERVICESDOWN
, form_str(ERR_SERVICESDOWN
), aptr
->target
);
153 str
= reconstruct_parv(parc
- 1, &parv
[1]);
156 sendto_one(client_p
, form_str(ERR_NOTEXTTOSEND
), me
.name
, target_p
->name
);
160 sendto_one(target_p
, ":%s PRIVMSG %s :%s",
161 get_id(client_p
, target_p
),
162 p
!= NULL
? aptr
->target
: get_id(target_p
, target_p
),