3 #include "../lib/version.h"
4 #include "../control/control.h"
5 #include "../lib/irc_string.h"
6 #include "../lib/strlfunc.h"
7 #include "../core/nsmalloc.h"
8 #include "../irc/irc.h"
9 #include "../newsearch/newsearch.h"
10 #include "../glines/glines.h"
12 #include "newsearch/trusts_newsearch.h"
16 static void registercommands(int, void *);
17 static void deregistercommands(int, void *);
19 extern void printnick_channels(searchCtx
*, nick
*, nick
*);
21 void calculatespaces(int spaces
, int width
, const char *str
, char **_prebuf
, char **_postbuf
) {
22 static char prebuf
[512], postbuf
[512];
25 if(spaces
+ 5 >= sizeof(prebuf
)) {
26 prebuf
[0] = prebuf
[1] = '\0';
28 memset(prebuf
, ' ', spaces
);
29 prebuf
[spaces
] = '\0';
32 spacelen
= width
- (strlen(str
) + spaces
);
33 if(spacelen
<= 0 || spacelen
+ 5 >= sizeof(postbuf
)) {
34 postbuf
[0] = postbuf
[1] = '\0';
36 memset(postbuf
, ' ', spacelen
);
37 postbuf
[spacelen
] = '\0';
44 static void traverseandmark(unsigned int marker
, trusthost
*th
, int markchildren
) {
48 for(th
=th
->children
;th
;th
=th
->nextbychild
) {
50 traverseandmark(marker
, th
, markchildren
);
55 static void insertth(array
*parents
, trusthost
*th
) {
57 trusthost
**p2
= (trusthost
**)(parents
->content
);
59 /* this eliminates common subtrees */
60 for(i
=0;i
<parents
->cursi
;i
++)
64 if(i
== parents
->cursi
) {
65 int pos
= array_getfreeslot(parents
);
66 ((trusthost
**)(parents
->content
))[pos
] = th
;
70 static void marktree(array
*parents
, unsigned int marker
, trusthost
*th
, int showchildren
) {
74 for(pth
=th
->parent
;pth
;pth
=pth
->parent
) {
75 insertth(parents
, pth
);
81 insertth(parents
, th
);
83 /* sadly we need to recurse down */
84 traverseandmark(marker
, th
, showchildren
);
87 static void outputtree(nick
*np
, unsigned int marker
, trustgroup
*originalgroup
, trusthost
*th
, int depth
, int showchildren
) {
89 char *prespacebuf
, *postspacebuf
, parentbuf
[512];
91 if(th
->marker
!= marker
)
94 cidrstr
= CIDRtostr(th
->ip
, th
->bits
);
95 calculatespaces(depth
+ 2, 30 + 1, cidrstr
, &prespacebuf
, &postspacebuf
);
97 if(th
->group
== originalgroup
) {
98 if(!showchildren
&& th
->group
== originalgroup
&& th
->children
)
101 prespacebuf
[0] = ' ';
103 prespacebuf
[1] = '>';
107 /* show the ids of other groups */
109 snprintf(parentbuf
, sizeof(parentbuf
), "%-10d %s", th
->group
->id
, th
->group
->name
->content
);
112 controlreply(np
, "%s%s%s %-10d %-10d %-21s %-15d /%-14d%s", prespacebuf
, cidrstr
, postspacebuf
, th
->count
, th
->maxusage
, (th
->count
>0)?"(now)":((th
->lastseen
>0)?trusts_timetostr(th
->lastseen
):"(never)"), th
->maxpernode
, (irc_in_addr_is_ipv4(&th
->ip
))?(th
->nodebits
- 96):th
->nodebits
, parentbuf
);
114 /* Make sure we're not seeing this subtree again. */
117 for(th
=th
->children
;th
;th
=th
->nextbychild
)
118 outputtree(np
, marker
, originalgroup
, th
, depth
+ 1, showchildren
);
121 static char *formatflags(int flags
) {
122 static char buf
[512];
126 if(flags
& TRUST_ENFORCE_IDENT
)
127 strncat(buf
, "enforcing ident", 512);
129 if(flags
& TRUST_NO_CLEANUP
) {
131 strncat(buf
, ", ", 512);
133 strncat(buf
, "exempt from cleanup", 512);
136 if(flags
& TRUST_PROTECTED
) {
138 strncat(buf
, ", ", 512);
140 strncat(buf
, "protected", 512);
143 if(flags
& TRUST_RELIABLE_USERNAME
) {
145 strncat(buf
, ", ", 512);
147 strncat(buf
, "reliable username", 512);
155 static char *formatlimit(unsigned int limit
) {
159 snprintf(buf
, sizeof(buf
), "%u", limit
);
161 strncpy(buf
, "unlimited", sizeof(buf
));
166 static void displaygroup(nick
*sender
, trustgroup
*tg
, int showchildren
) {
171 time_t t
= getnettime();
173 /* abusing the ternary operator a bit :( */
174 controlreply(sender
, "Name: : %s", tg
->name
->content
);
175 controlreply(sender
, "Trusted for : %s", formatlimit(tg
->trustedfor
));
176 controlreply(sender
, "Currently using : %d", tg
->count
);
177 controlreply(sender
, "Clients per user : %s", formatlimit(tg
->maxperident
));
178 controlreply(sender
, "Flags : %s", formatflags(tg
->flags
));
179 controlreply(sender
, "Contact: : %s", tg
->contact
->content
);
180 controlreply(sender
, "Expires in : %s", (tg
->expires
)?((tg
->expires
>t
)?longtoduration(tg
->expires
- t
, 2):"the past (will be removed during next cleanup)"):"never");
181 controlreply(sender
, "Created by : %s", tg
->createdby
->content
);
182 controlreply(sender
, "Comment: : %s", tg
->comment
->content
);
183 controlreply(sender
, "ID: : %u", tg
->id
);
184 controlreply(sender
, "Last used : %s", (tg
->count
>0)?"(now)":((tg
->lastseen
>0)?trusts_timetostr(tg
->lastseen
):"(never)"));
185 controlreply(sender
, "Max usage : %d", tg
->maxusage
);
186 controlreply(sender
, "Last max reset : %s", tg
->lastmaxusereset
?trusts_timetostr(tg
->lastmaxusereset
):"(never)");
188 controlreply(sender
, "---");
189 controlreply(sender
, "Attributes: * (has hidden children, show with -v), > (belongs to this trust group)");
190 controlreply(sender
, "Host Current Max Last seen Max per Node Node Mask Group ID Group name");
192 marker
= nextthmarker();
193 array_init(&parents
, sizeof(trusthost
*));
195 for(th
=tg
->hosts
;th
;th
=th
->next
)
196 marktree(&parents
, marker
, th
, showchildren
);
198 p2
= (trusthost
**)(parents
.content
);
199 for(i
=0;i
<parents
.cursi
;i
++)
200 outputtree(sender
, marker
, tg
, p2
[i
], 0, showchildren
);
202 array_free(&parents
);
204 controlreply(sender
, "End of list.");
207 static int trusts_cmdtrustlist(void *source
, int cargc
, char **cargv
) {
208 nick
*sender
= source
;
209 trustgroup
*tg
= NULL
;
210 int found
= 0, remaining
= 50;
213 struct irc_in_addr ip
;
220 if(strcmp(cargv
[0], "-v") == 0) {
231 tg
= tg_strtotg(name
);
234 displaygroup(sender
, tg
, showchildren
);
238 if(ipmask_parse(name
, &ip
, &bits
)) {
239 th
= th_getbyhost(&ip
);
242 controlreply(sender
, "Specified IP address is not trusted.");
246 displaygroup(sender
, th
->group
, showchildren
);
250 for(tg
=tglist
;tg
;tg
=tg
->next
) {
251 if(match(name
, tg
->name
->content
))
254 displaygroup(sender
, tg
, showchildren
);
255 if(--remaining
== 0) {
256 controlreply(sender
, "Maximum number of matches reached.");
263 controlreply(sender
, "No matches found.");
268 static int trusts_cmdtrustglinesuggest(void *source
, int cargc
, char **cargv
) {
269 nick
*sender
= source
;
271 char *p
, *user
, *host
;
272 struct irc_in_addr ip
;
281 strncpy(mask
, cargv
[0], sizeof(mask
));
283 p
= strchr(mask
, '@');
292 if(!ipmask_parse(host
, &ip
, &bits
)) {
293 controlreply(sender
, "Invalid CIDR.");
297 snprintf(creator
, sizeof(creator
), "#%s", sender
->authname
);
299 glinebufinit(&gbuf
, 0);
300 glinebufaddbyip(&gbuf
, user
, &ip
, 128, 0, creator
, "Simulate", getnettime(), getnettime(), getnettime());
301 glinebufcounthits(&gbuf
, &count
, NULL
);
302 glinebufspew(&gbuf
, sender
);
303 glinebufabort(&gbuf
);
305 controlreply(sender
, "Total hits: %d", count
);
310 static int trusts_cmdtrustspew(void *source
, int cargc
, char **cargv
) {
311 nick
*sender
= source
;
317 tree
= NSASTNode(tgroup_parse
, NSASTLiteral(cargv
[0]));
318 return ast_nicksearch(&tree
, controlreply
, sender
, NULL
, printnick_channels
, NULL
, NULL
, 2000);
321 static int commandsregistered
;
323 static void registercommands(int hooknum
, void *arg
) {
324 if(commandsregistered
)
326 commandsregistered
= 1;
328 registercontrolhelpcmd("trustlist", NO_OPER
, 2, trusts_cmdtrustlist
, "Usage: trustlist [-v] <#id|name|IP>\nShows trust data for the specified trust group.");
329 registercontrolhelpcmd("trustglinesuggest", NO_OPER
, 1, trusts_cmdtrustglinesuggest
, "Usage: trustglinesuggest <user@host>\nSuggests glines for the specified hostmask.");
330 registercontrolhelpcmd("trustspew", NO_OPER
, 1, trusts_cmdtrustspew
, "Usage: trustspew <#id|name>\nShows currently connected users for the specified trust group.");
333 static void deregistercommands(int hooknum
, void *arg
) {
334 if(!commandsregistered
)
336 commandsregistered
= 0;
338 deregistercontrolcmd("trustlist", trusts_cmdtrustlist
);
339 deregistercontrolcmd("trustglinesuggest", trusts_cmdtrustglinesuggest
);
340 deregistercontrolcmd("trustspew", trusts_cmdtrustspew
);
344 registerhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
345 registerhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
348 registercommands(0, NULL
);
352 deregisterhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
353 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
355 deregistercommands(0, NULL
);