]>
jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_commands.c
3 #include "../control/control.h"
4 #include "../lib/irc_string.h"
5 #include "../lib/strlfunc.h"
8 static void registercommands ( int , void *);
9 static void deregistercommands ( int , void *);
11 void calculatespaces ( int spaces
, int width
, char * str
, char ** _prebuf
, char ** _postbuf
) {
12 static char prebuf
[ 512 ], postbuf
[ 512 ];
15 if ( spaces
+ 5 >= sizeof ( prebuf
)) {
16 prebuf
[ 0 ] = prebuf
[ 1 ] = '\0' ;
18 memset ( prebuf
, ' ' , spaces
);
19 prebuf
[ spaces
] = '\0' ;
22 spacelen
= width
- ( strlen ( str
) + spaces
);
23 if ( spacelen
<= 0 || spacelen
+ 5 >= sizeof ( postbuf
)) {
24 postbuf
[ 0 ] = postbuf
[ 1 ] = '\0' ;
26 memset ( postbuf
, ' ' , spacelen
);
27 postbuf
[ spacelen
] = '\0' ;
34 static void traverseandmark ( unsigned int marker
, trusthost
* th
) {
37 for ( th
= th
-> children
; th
; th
= th
-> nextbychild
) {
39 traverseandmark ( marker
, th
);
43 static void marktree ( array
* parents
, unsigned int marker
, trusthost
* th
) {
46 for ( pth
= th
-> parent
; pth
; pth
= pth
-> next
) {
47 trusthost
** p2
= ( trusthost
**)( parents
-> content
);
50 /* this eliminates common subtrees */
51 for ( i
= 0 ; i
< parents
-> cursi
; i
++)
55 if ( i
== parents
-> cursi
) {
56 int pos
= array_getfreeslot ( parents
);
57 (( trusthost
**)( parents
-> content
))[ pos
] = pth
;
63 /* sadly we need to recurse down */
64 traverseandmark ( marker
, th
);
67 static void outputtree ( nick
* np
, unsigned int marker
, trustgroup
* originalgroup
, trusthost
* th
, int depth
) {
68 char * cidrstr
, * prespacebuf
, * postspacebuf
, parentbuf
[ 512 ];
70 if ( th
-> marker
!= marker
)
73 cidrstr
= trusts_cidr2str ( th
-> ip
, th
-> mask
);
74 calculatespaces ( depth
+ 1 , 20 + 1 , cidrstr
, & prespacebuf
, & postspacebuf
);
76 if ( th
-> group
== originalgroup
) {
81 /* show the ids of other groups */
83 snprintf ( parentbuf
, sizeof ( parentbuf
), "%-10d %s " , th
-> group
-> id
, th
-> group
-> name
-> content
);
86 controlreply ( np
, " %s%s%s %-10d %-10d %-20s %s " , prespacebuf
, cidrstr
, postspacebuf
, th
-> count
, th
-> maxusage
, ( th
-> count
> 0 )? "(now)" :(( th
-> lastseen
> 0 )? trusts_timetostr ( th
-> lastseen
): "(never)" ), parentbuf
);
88 for ( th
= th
-> children
; th
; th
= th
-> nextbychild
)
89 outputtree ( np
, marker
, originalgroup
, th
, depth
+ 1 );
92 static int trusts_cmdtrustlist ( void * source
, int cargc
, char ** cargv
) {
93 nick
* sender
= source
;
104 tg
= tg_strtotg ( cargv
[ 0 ]);
106 controlreply ( sender
, "Couldn't find a trustgroup with that id." );
112 /* abusing the ternary operator a bit :( */
113 controlreply ( sender
, "Name: : %s " , tg
-> name
-> content
);
114 controlreply ( sender
, "Trusted for : %d " , tg
-> trustedfor
);
115 controlreply ( sender
, "Currently using : %d " , tg
-> count
);
116 controlreply ( sender
, "Clients per user : %d ( %s enforcing ident)" , tg
-> maxperident
, tg
-> mode
? "" : "not " );
117 controlreply ( sender
, "Contact: : %s " , tg
-> contact
-> content
);
118 controlreply ( sender
, "Expires in : %s " , ( tg
-> expires
> t
)? longtoduration ( tg
-> expires
- t
, 2 ): "(the past -- BUG)" );
119 controlreply ( sender
, "Last changed by : %s " , tg
-> createdby
-> content
);
120 controlreply ( sender
, "Comment: : %s " , tg
-> comment
-> content
);
121 controlreply ( sender
, "ID: : %u " , tg
-> id
);
122 controlreply ( sender
, "Last used : %s " , ( tg
-> count
> 0 )? "(now)" :(( tg
-> lastseen
> 0 )? trusts_timetostr ( tg
-> lastseen
): "(never)" ));
123 controlreply ( sender
, "Max usage : %d " , tg
-> maxusage
);
124 controlreply ( sender
, "Last max reset : %s " , tg
-> lastmaxuserreset
? trusts_timetostr ( tg
-> lastmaxuserreset
): "(never)" );
126 controlreply ( sender
, "Host Current Max Last seen Group ID Group name" );
128 marker
= nextthmarker ();
129 array_init (& parents
, sizeof ( trusthost
*));
131 for ( th
= tg
-> hosts
; th
; th
= th
-> next
)
132 marktree (& parents
, marker
, th
);
134 p2
= ( trusthost
**)( parents
. content
);
135 for ( i
= 0 ; i
< parents
. cursi
; i
++)
136 outputtree ( sender
, marker
, tg
, p2
[ i
], 0 );
138 array_free (& parents
);
140 controlreply ( sender
, "End of list." );
145 static int trusts_cmdtrustadd ( void * source
, int cargc
, char ** cargv
) {
147 nick
* sender
= source
;
150 trusthost
* th
, * superset
, * subset
;
155 tg
= tg_strtotg ( cargv
[ 0 ]);
157 controlreply ( sender
, "Couldn't look up trustgroup." );
162 if (! trusts_str2cidr ( host
, & ip
, & mask
)) {
163 controlreply ( sender
, "Invalid host." );
167 /* OKAY! Lots of checking here!
170 * - host isn't already covered by given group (reject if it is)
171 * - host doesn't already exist exactly already (reject if it does)
172 * - host is more specific than an existing one (warn if it is, fix up later)
173 * - host is less specific than an existing one (warn if it is, don't need to do anything special)
176 for ( th
= tg
-> hosts
; th
; th
= th
-> next
) {
177 if ( th
-> ip
== ( ip
& th
-> mask
)) {
178 controlreply ( sender
, "This host (or part of it) is already covered in the given group." );
183 if ( th_getbyhostandmask ( ip
, mask
)) {
184 controlreply ( sender
, "This host already exists in another group with the same mask." );
188 /* this function will set both to NULL if it's equal, hence the check above */
189 th_getsuperandsubsets ( ip
, mask
, & superset
, & subset
);
191 /* a superset exists for us, we will be more specific than one existing host */
193 controlreply ( sender
, "Warning: this host already exists in another group, but this new host will override it as it has a smaller prefix." );
196 /* a subset of us exists, we will be less specific than some existing hosts */
198 controlreply ( sender
, "Warning: this host already exists in at least one other group, the new host has a larger prefix and therefore will not override those hosts." );
200 if ( superset
|| subset
)
201 controlreply ( sender
, "Adding anyway..." );
203 th
= th_new ( tg
, host
);
205 controlreply ( sender
, "An error occured adding the host to the group." );
209 controlreply ( sender
, "Host added." );
210 /* TODO: controlwall */
215 static int trusts_cmdtrustgroupadd ( void * source
, int cargc
, char ** cargv
) {
216 nick
* sender
= source
;
217 char * name
, * contact
, * comment
, createdby
[ ACCOUNTLEN
+ 2 ];
218 unsigned int howmany
, maxperident
, enforceident
;
226 howmany
= strtoul ( cargv
[ 1 ], NULL
, 10 );
227 if (! howmany
|| ( howmany
> 50000 )) {
228 controlreply ( sender
, "Bad value maximum number of clients." );
232 howlong
= durationtolong ( cargv
[ 2 ]);
233 if (( howlong
<= 0 ) || ( howlong
> 365 * 86400 * 20 )) {
234 controlreply ( sender
, "Invalid duration supplied." );
238 maxperident
= strtoul ( cargv
[ 3 ], NULL
, 10 );
239 if (! howmany
|| ( maxperident
> 1000 )) {
240 controlreply ( sender
, "Bad value for max per ident." );
244 if ( cargv
[ 4 ][ 0 ] != '1' && cargv
[ 4 ][ 0 ] != '0' ) {
245 controlreply ( sender
, "Bad value for enforce ident (use 0 or 1)." );
248 enforceident
= cargv
[ 4 ][ 0 ] == '1' ;
253 comment
= "(no comment)" ;
258 /* don't allow #id or id forms */
259 if (( name
[ 0 ] == '#' ) || strtoul ( name
, NULL
, 10 )) {
260 controlreply ( sender
, "Invalid trustgroup name." );
264 tg
= tg_strtotg ( name
);
266 controlreply ( sender
, "A group with that name already exists" );
270 snprintf ( createdby
, sizeof ( createdby
), "# %s " , sender
-> authname
);
272 tg
= tg_new ( name
, howmany
, enforceident
, maxperident
, howlong
+ time ( NULL
), createdby
, contact
, comment
);
274 controlreply ( sender
, "An error occured adding the trustgroup." );
278 controlreply ( sender
, "Group added." );
279 /* TODO: controlwall */
284 static int commandsregistered
;
286 static void registercommands ( int hooknum
, void * arg
) {
287 if ( commandsregistered
)
289 commandsregistered
= 1 ;
291 registercontrolhelpcmd ( "trustlist" , NO_OPER
, 1 , trusts_cmdtrustlist
, "Usage: trustlist <#id|name|id> \n Shows trust data for the specified trust group." );
292 registercontrolhelpcmd ( "trustgroupadd" , NO_OPER
, 6 , trusts_cmdtrustgroupadd
, "Usage: trustgroupadd <name> <howmany> <howlong> <maxperident> <enforceident> <contact> ?comment?" );
293 registercontrolhelpcmd ( "trustadd" , NO_OPER
, 2 , trusts_cmdtrustadd
, "Usage: trustadd <#id|name|id> <host>" );
296 static void deregistercommands ( int hooknum
, void * arg
) {
297 if (! commandsregistered
)
299 commandsregistered
= 0 ;
301 deregistercontrolcmd ( "trustlist" , trusts_cmdtrustlist
);
302 deregistercontrolcmd ( "trustgroupadd" , trusts_cmdtrustgroupadd
);
303 deregistercontrolcmd ( "trustadd" , trusts_cmdtrustadd
);
307 registerhook ( HOOK_TRUSTS_DB_LOADED
, registercommands
);
308 registerhook ( HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
311 registercommands ( 0 , NULL
);
315 deregisterhook ( HOOK_TRUSTS_DB_LOADED
, registercommands
);
316 deregisterhook ( HOOK_TRUSTS_DB_CLOSED
, deregistercommands
);
318 deregistercommands ( 0 , NULL
);