2 * Copyright (C) 2020 Ed Kellett
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.
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.
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
22 #include <capability.h>
24 #include <s_newconf.h>
28 static char cap_realhost_desc
[] = "Provides the solanum.chat/realhost oper-only capability";
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 *);
35 static unsigned CLICAP_REALHOST
;
36 static unsigned CLICAP_OPER_REALHOST
;
38 static struct ClientCapability capdata_oper_realhost
= {
39 .visible
= cap_oper_realhost_visible
,
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
},
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
},
56 cap_oper_realhost_visible(struct Client
*client
)
62 cap_realhost_outbound_msgbuf(void *data_
)
64 hook_data
*data
= data_
;
65 struct MsgBuf
*msgbuf
= data
->arg1
;
67 if (data
->client
== NULL
|| !IsPerson(data
->client
))
70 if (!IsIPSpoof(data
->client
) && !EmptyString(data
->client
->sockhost
) && strcmp(data
->client
->sockhost
, "0"))
72 msgbuf_append_tag(msgbuf
, "solanum.chat/ip", data
->client
->sockhost
,
73 IsDynSpoof(data
->client
) ? CLICAP_OPER_REALHOST
: CLICAP_REALHOST
);
76 if (!EmptyString(data
->client
->orighost
))
77 msgbuf_append_tag(msgbuf
, "solanum.chat/realhost", data
->client
->orighost
, CLICAP_OPER_REALHOST
);
81 update_clicap_oper_realhost(struct Client
*client
)
83 client
->localClient
->caps
&= ~CLICAP_OPER_REALHOST
;
84 if (client
->localClient
->caps
& CLICAP_REALHOST
&& HasPrivilege(client
, "auspex:hostname"))
86 client
->localClient
->caps
|= CLICAP_OPER_REALHOST
;
91 cap_realhost_umode_changed(void *data_
)
93 hook_data_umode_changed
*data
= data_
;
95 if (!MyClient(data
->client
))
98 update_clicap_oper_realhost(data
->client
);
102 cap_realhost_cap_change(void *data_
)
104 hook_data_cap_change
*data
= data_
;
106 update_clicap_oper_realhost(data
->client
);
114 RB_DLINK_FOREACH(ptr
, lclient_list
.head
)
116 struct Client
*client
= ptr
->data
;
118 update_clicap_oper_realhost(client
);
124 DECLARE_MODULE_AV2(cap_realhost
, modinit
, NULL
, NULL
, NULL
, cap_realhost_hfnlist
, cap_realhost_caps
, NULL
, cap_realhost_desc
);