3 #include "../control/control.h"
4 #include "../lib/irc_string.h"
5 #include "../lib/strlfunc.h"
6 #include "../core/nsmalloc.h"
7 #include "../irc/irc.h"
8 #include "../newsearch/newsearch.h"
9 #include "../glines/glines.h"
11 #include "newsearch/trusts_newsearch.h"
13 static void registercommands(int, void *);
14 static void deregistercommands(int, void *);
16 extern void printnick_channels(searchCtx
*, nick
*, nick
*);
18 void calculatespaces(int spaces
, int width
, char *str
, char **_prebuf
, char **_postbuf
) {
19 static char prebuf
[512], postbuf
[512];
22 if(spaces
+ 5 >= sizeof(prebuf
)) {
23 prebuf
[0] = prebuf
[1] = '\0';
25 memset(prebuf
, ' ', spaces
);
26 prebuf
[spaces
] = '\0';
29 spacelen
= width
- (strlen(str
) + spaces
);
30 if(spacelen
<= 0 || spacelen
+ 5 >= sizeof(postbuf
)) {
31 postbuf
[0] = postbuf
[1] = '\0';
33 memset(postbuf
, ' ', spacelen
);
34 postbuf
[spacelen
] = '\0';
41 static void traverseandmark(unsigned int marker
, trusthost
*th
) {
44 for(th
=th
->children
;th
;th
=th
->nextbychild
) {
46 traverseandmark(marker
, th
);
50 static void insertth(array
*parents
, trusthost
*th
) {
52 trusthost
**p2
= (trusthost
**)(parents
->content
);
54 /* this eliminates common subtrees */
55 for(i
=0;i
<parents
->cursi
;i
++)
59 if(i
== parents
->cursi
) {
60 int pos
= array_getfreeslot(parents
);
61 ((trusthost
**)(parents
->content
))[pos
] = th
;
65 static void marktree(array
*parents
, unsigned int marker
, trusthost
*th
) {
69 for(pth
=th
->parent
;pth
;pth
=pth
->parent
) {
70 insertth(parents
, pth
);
76 insertth(parents
, th
);
78 /* sadly we need to recurse down */
79 traverseandmark(marker
, th
);
82 static void outputtree(nick
*np
, unsigned int marker
, trustgroup
*originalgroup
, trusthost
*th
, int depth
) {
83 char *cidrstr
, *prespacebuf
, *postspacebuf
, parentbuf
[512];
85 if(th
->marker
!= marker
)
88 cidrstr
= trusts_cidr2str(&th
->ip
, th
->bits
);
89 calculatespaces(depth
+ 1, 30 + 1, cidrstr
, &prespacebuf
, &postspacebuf
);
91 if(th
->group
== originalgroup
) {
96 /* show the ids of other groups */
98 snprintf(parentbuf
, sizeof(parentbuf
), "%-10d %s", th
->group
->id
, th
->group
->name
->content
);
101 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
);
103 /* Make sure we're not seeing this subtree again. */
106 for(th
=th
->children
;th
;th
=th
->nextbychild
)
107 outputtree(np
, marker
, originalgroup
, th
, depth
+ 1);
110 static void displaygroup(nick
*sender
, trustgroup
*tg
) {
115 time_t t
= getnettime();
117 /* abusing the ternary operator a bit :( */
118 controlreply(sender
, "Name: : %s", tg
->name
->content
);
119 controlreply(sender
, "Trusted for : %d", tg
->trustedfor
);
120 controlreply(sender
, "Currently using : %d", tg
->count
);
121 controlreply(sender
, "Clients per user : %d (%senforcing ident)", tg
->maxperident
, (tg
->flags
& TRUST_ENFORCE_IDENT
)?"":"not ");
122 controlreply(sender
, "Contact: : %s", tg
->contact
->content
);
123 controlreply(sender
, "Expires in : %s", (tg
->expires
)?((tg
->expires
>t
)?longtoduration(tg
->expires
- t
, 2):"the past (will be removed during next cleanup)"):"never");
124 controlreply(sender
, "CIDR cleanup : %s", (tg
->flags
& TRUST_NO_CLEANUP
)?"disabled":"enabled");
125 controlreply(sender
, "Protected : %s", (tg
->flags
& TRUST_PROTECTED
)?"protected":"not protected");
126 controlreply(sender
, "Created by : %s", tg
->createdby
->content
);
127 controlreply(sender
, "Comment: : %s", tg
->comment
->content
);
128 controlreply(sender
, "ID: : %u", tg
->id
);
129 controlreply(sender
, "Last used : %s", (tg
->count
>0)?"(now)":((tg
->lastseen
>0)?trusts_timetostr(tg
->lastseen
):"(never)"));
130 controlreply(sender
, "Max usage : %d", tg
->maxusage
);
131 controlreply(sender
, "Last max reset : %s", tg
->lastmaxusereset
?trusts_timetostr(tg
->lastmaxusereset
):"(never)");
133 controlreply(sender
, "Host Current Max Last seen Max per Node Node Mask Group ID Group name");
135 marker
= nextthmarker();
136 array_init(&parents
, sizeof(trusthost
*));
138 for(th
=tg
->hosts
;th
;th
=th
->next
)
139 marktree(&parents
, marker
, th
);
141 p2
= (trusthost
**)(parents
.content
);
142 for(i
=0;i
<parents
.cursi
;i
++)
143 outputtree(sender
, marker
, tg
, p2
[i
], 0);
145 array_free(&parents
);
147 controlreply(sender
, "End of list.");
150 static int trusts_cmdtrustlist(void *source
, int cargc
, char **cargv
) {
151 nick
*sender
= source
;
152 trustgroup
*tg
= NULL
;
153 int found
= 0, remaining
= 50;
156 struct irc_in_addr ip
;
164 tg
= tg_strtotg(name
);
167 displaygroup(sender
, tg
);
171 if(ipmask_parse(name
, &ip
, &bits
)) {
172 th
= th_getbyhost(&ip
);
175 controlreply(sender
, "Specified IP address is not trusted.");
179 displaygroup(sender
, th
->group
);
183 for(tg
=tglist
;tg
;tg
=tg
->next
) {
184 if(match(name
, tg
->name
->content
))
187 displaygroup(sender
, tg
);
188 if(--remaining
== 0) {
189 controlreply(sender
, "Maximum number of matches reached.");
196 controlreply(sender
, "No matches found.");
201 static int comparetgs(const void *_a
, const void *_b
) {
202 const trustgroup
*a
= _a
;
203 const trustgroup
*b
= _b
;
212 static int trusts_cmdtrustdump(void *source
, int argc
, char **argv
) {
214 trustgroup
*tg
, **atg
;
215 unsigned int wanted
, max
, maxid
, totalcount
, i
, groupcount
, linecount
;
218 if((argc
< 2) || (argv
[0][0] != '#'))
221 wanted
= atoi(&argv
[0][1]);
224 for(maxid
=totalcount
=0,tg
=tglist
;tg
;tg
=tg
->next
) {
225 if(totalcount
== 0 || tg
->id
> maxid
)
231 if(maxid
> totalcount
) {
232 controlreply(np
, "Start ID cannot exceed current maximum group ID (#%u)", maxid
);
236 atg
= nsmalloc(POOL_TRUSTS
, sizeof(trusthost
*) * totalcount
);
238 controlreply(np
, "Memory error.");
242 for(i
=0,tg
=tglist
;i
<totalcount
&&tg
;tg
=tg
->next
,i
++)
245 qsort(atg
, totalcount
, sizeof(trustgroup
*), comparetgs
);
247 for(i
=0;i
<totalcount
;i
++)
248 if(atg
[i
]->id
>= wanted
)
251 for(groupcount
=linecount
=0;i
<totalcount
;i
++) {
255 controlreply(np
, "G,%s", dumptg(atg
[i
], 1));
257 for(th
=atg
[i
]->hosts
;th
;th
=th
->next
) {
259 controlreply(np
, "H,%s", dumpth(th
, 1));
265 nsfree(POOL_TRUSTS
, atg
);
267 controlreply(np
, "End of list, %u groups and %u lines returned.", groupcount
, linecount
);
271 static void trusts_suggestgline_cb(const char *mask
, int hits
, void *uarg
) {
274 controlreply(sender
, "mask: %s, hits: %d", mask
, hits
);
277 static int trusts_cmdtrustglinesuggest(void *source
, int cargc
, char **cargv
) {
278 nick
*sender
= source
;
280 char *p
, *user
, *host
;
281 struct irc_in_addr ip
;
288 strncpy(mask
, cargv
[0], sizeof(mask
));
290 p
= strchr(mask
, '@');
299 if(!ipmask_parse(host
, &ip
, &bits
)) {
300 controlreply(sender
, "Invalid CIDR.");
304 count
= glinesuggestbyip(user
, &ip
, 128, 0, trusts_suggestgline_cb
, sender
);
306 controlreply(sender
, "Total hits: %d", count
);
311 static int trusts_cmdtrustspew(void *source
, int cargc
, char **cargv
) {
312 nick
*sender
= source
;
318 tree
= NSASTNode(tgroup_parse
, NSASTLiteral(cargv
[0]));
319 return ast_nicksearch(&tree
, controlreply
, sender
, NULL
, printnick_channels
, NULL
, NULL
, 2000);
322 static int commandsregistered
;
324 static void registercommands(int hooknum
, void *arg
) {
325 if(commandsregistered
)
327 commandsregistered
= 1;
329 registercontrolhelpcmd("trustlist", NO_OPER
, 1, trusts_cmdtrustlist
, "Usage: trustlist <#id|name|IP>\nShows trust data for the specified trust group.");
330 registercontrolhelpcmd("trustdump", NO_OPER
, 2, trusts_cmdtrustdump
, "Usage: trustdump <#id> <number>");
331 registercontrolhelpcmd("trustglinesuggest", NO_OPER
, 1, trusts_cmdtrustglinesuggest
, "Usage: trustglinesuggest <user@host>\nSuggests glines for the specified hostmask.");
332 registercontrolhelpcmd("trustspew", NO_OPER
, 1, trusts_cmdtrustspew
, "Usage: trustspew <#id|name>\nShows currently connected users for the specified trust group.");
335 static void deregistercommands(int hooknum
, void *arg
) {
336 if(!commandsregistered
)
338 commandsregistered
= 0;
340 deregistercontrolcmd("trustlist", trusts_cmdtrustlist
);
341 deregistercontrolcmd("trustdump", trusts_cmdtrustdump
);
342 deregistercontrolcmd("trustglinesuggest", trusts_cmdtrustglinesuggest
);
343 deregistercontrolcmd("trustspew", trusts_cmdtrustspew
);
347 registerhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
348 registerhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
351 registercommands(0, NULL
);
355 deregisterhook(HOOK_TRUSTS_DB_LOADED
, registercommands
);
356 deregisterhook(HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
358 deregistercommands(0, NULL
);