]> jfr.im git - solanum.git/blob - extensions/cap_realhost.c
m_stats: z: remove unnecessary casting and fix format strings
[solanum.git] / extensions / cap_realhost.c
1 /*
2 * Copyright (C) 2020 Ed Kellett
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA
18 */
19
20 #include <stdinc.h>
21 #include <modules.h>
22 #include <capability.h>
23 #include <s_serv.h>
24 #include <s_newconf.h>
25 #include <client.h>
26 #include <msgbuf.h>
27
28 static char cap_realhost_desc[] = "Provides the solanum.chat/realhost oper-only capability";
29
30 static bool cap_oper_realhost_visible(struct Client *);
31 static void cap_realhost_outbound_msgbuf(void *);
32 static void cap_realhost_umode_changed(void *);
33 static void cap_realhost_cap_change(void *);
34
35 static unsigned CLICAP_REALHOST;
36 static unsigned CLICAP_OPER_REALHOST;
37
38 static struct ClientCapability capdata_oper_realhost = {
39 .visible = cap_oper_realhost_visible,
40 };
41
42 mapi_cap_list_av2 cap_realhost_caps[] = {
43 { MAPI_CAP_CLIENT, "solanum.chat/realhost", NULL, &CLICAP_REALHOST },
44 { MAPI_CAP_CLIENT, "?oper_realhost", &capdata_oper_realhost, &CLICAP_OPER_REALHOST },
45 { 0, NULL, NULL, NULL },
46 };
47
48 mapi_hfn_list_av1 cap_realhost_hfnlist[] = {
49 { "outbound_msgbuf", cap_realhost_outbound_msgbuf, HOOK_NORMAL },
50 { "umode_changed", cap_realhost_umode_changed, HOOK_MONITOR },
51 { "cap_change", cap_realhost_cap_change, HOOK_MONITOR },
52 { NULL, NULL, 0 },
53 };
54
55 static bool
56 cap_oper_realhost_visible(struct Client *client)
57 {
58 return false;
59 }
60
61 static void
62 cap_realhost_outbound_msgbuf(void *data_)
63 {
64 hook_data *data = data_;
65 struct MsgBuf *msgbuf = data->arg1;
66
67 if (data->client == NULL || !IsPerson(data->client))
68 return;
69
70 if (!IsIPSpoof(data->client) && !EmptyString(data->client->sockhost) && strcmp(data->client->sockhost, "0"))
71 {
72 msgbuf_append_tag(msgbuf, "solanum.chat/ip", data->client->sockhost,
73 IsDynSpoof(data->client) ? CLICAP_OPER_REALHOST : CLICAP_REALHOST);
74 }
75
76 if (!EmptyString(data->client->orighost))
77 msgbuf_append_tag(msgbuf, "solanum.chat/realhost", data->client->orighost, CLICAP_OPER_REALHOST);
78 }
79
80 static inline void
81 update_clicap_oper_realhost(struct Client *client)
82 {
83 client->localClient->caps &= ~CLICAP_OPER_REALHOST;
84 if (client->localClient->caps & CLICAP_REALHOST && HasPrivilege(client, "auspex:hostname"))
85 {
86 client->localClient->caps |= CLICAP_OPER_REALHOST;
87 }
88 }
89
90 static void
91 cap_realhost_umode_changed(void *data_)
92 {
93 hook_data_umode_changed *data = data_;
94
95 if (!MyClient(data->client))
96 return;
97
98 update_clicap_oper_realhost(data->client);
99 }
100
101 static void
102 cap_realhost_cap_change(void *data_)
103 {
104 hook_data_cap_change *data = data_;
105
106 update_clicap_oper_realhost(data->client);
107 }
108
109 static int
110 modinit(void)
111 {
112 rb_dlink_node *ptr;
113
114 RB_DLINK_FOREACH(ptr, lclient_list.head)
115 {
116 struct Client *client = ptr->data;
117
118 update_clicap_oper_realhost(client);
119 }
120
121 return 0;
122 }
123
124 DECLARE_MODULE_AV2(cap_realhost, modinit, NULL, NULL, NULL, cap_realhost_hfnlist, cap_realhost_caps, NULL, cap_realhost_desc);