]>
jfr.im git - irc/quakenet/newserv.git/blob - patricianick/patricianick.c
3 #include "patricianick.h"
4 #include "../irc/irc_config.h"
5 #include "../lib/irc_string.h"
6 #include "../core/error.h"
7 #include "../core/nsmalloc.h"
8 #include "../control/control.h"
9 #include "../core/schedule.h"
10 #include "../lib/version.h"
19 patricianick_t
* freepatricianicks
;
23 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
);
29 pnode_ext
= registernodeext ( "patricianick" );
30 if ( pnode_ext
== - 1 ) {
31 Error ( "patricianick" , ERR_FATAL
, "Could not register a required node extension" );
35 pnick_ext
= registernickext ( "patricianick" );
36 if ( pnick_ext
== - 1 ) {
37 Error ( "patricianick" , ERR_FATAL
, "Could not register a required nick extension" );
41 for ( i
= 0 ; i
< NICKHASHSIZE
; i
++)
42 for ( np
= nicktable
[ i
]; np
; np
= nnp
) {
44 addnicktonode ( np
-> ipnode
, np
);
47 registerhook ( HOOK_NICK_NEWNICK
, & pn_hook_newuser
);
48 registerhook ( HOOK_NICK_LOSTNICK
, & pn_hook_lostuser
);
49 registerhook ( HOOK_NICK_MOVENODE
, & pn_hook_nodemoveuser
);
51 registercontrolhelpcmd ( "nodeuserlist" , NO_OPER
, 1 , & pn_cmd_nodeuserlist
, "Usage: nodeuserlist <ipv4|ipv6|cidr4|cidr6> \n Lists all users on a given IP address or CIDR range." );
55 nsfreeall ( POOL_PATRICIANICK
);
57 if ( pnode_ext
!= - 1 ) {
58 releasenodeext ( pnode_ext
);
61 if ( pnick_ext
!= - 1 ) {
62 releasenickext ( pnick_ext
);
65 deregisterhook ( HOOK_NICK_NEWNICK
, & pn_hook_newuser
);
66 deregisterhook ( HOOK_NICK_LOSTNICK
, & pn_hook_lostuser
);
67 deregisterhook ( HOOK_NICK_MOVENODE
, & pn_hook_nodemoveuser
);
69 deregistercontrolcmd ( "nodeuserlist" , & pn_cmd_nodeuserlist
);
72 patricianick_t
* getpatricianick () {
76 if ( freepatricianicks
== NULL
) {
77 freepatricianicks
=( patricianick_t
*) nsmalloc ( POOL_PATRICIANICK
, ALLOCUNIT
* sizeof ( patricianick_t
));
78 for ( i
= 0 ; i
< ALLOCUNIT
- 1 ; i
++) {
79 freepatricianicks
[ i
]. identhash
[ 0 ]=( nick
*)&( freepatricianicks
[ i
+ 1 ]);
81 freepatricianicks
[ ALLOCUNIT
- 1 ]. identhash
[ 0 ]= NULL
;
84 pnp
= freepatricianicks
;
85 freepatricianicks
=( patricianick_t
*) pnp
-> identhash
[ 0 ];
87 memset ( pnp
, 0 , sizeof ( patricianick_t
));
91 void addnicktonode ( patricia_node_t
* node
, nick
* np
) {
94 patricia_ref_prefix ( node
-> prefix
);
96 if (!( node
-> exts
[ pnode_ext
])) {
97 node
-> exts
[ pnode_ext
] = getpatricianick ();
100 hash
= pn_getidenthash ( np
-> ident
);
101 np
-> exts
[ pnick_ext
] = (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
];
102 (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
] = np
;
105 void deletenickfromnode ( patricia_node_t
* node
, nick
* np
) {
111 for ( tnp
= &((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ pn_getidenthash ( np
-> ident
)]); * tnp
; tnp
= ( nick
**)(&((* tnp
)-> exts
[ pnick_ext
]))) {
113 * tnp
= np
-> exts
[ pnick_ext
];
120 Error ( "patricianick" , ERR_ERROR
, "Could not remove %s ! %s from %s " , np
-> nick
, np
-> ident
, IPtostr ( node
-> prefix
-> sin
));
124 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
125 if ((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ i
]) {
130 freepatricianick ( node
-> exts
[ pnode_ext
]);
131 node
-> exts
[ pnode_ext
]= NULL
;
134 void freepatricianick ( patricianick_t
* pnp
) {
135 pnp
-> identhash
[ 0 ]=( nick
*) freepatricianicks
;
136 freepatricianicks
= pnp
;
139 void pn_hook_newuser ( int hook
, void * arg
) {
140 nick
* np
= ( nick
*) arg
;
142 addnicktonode ( np
-> ipnode
, np
);
145 void pn_hook_lostuser ( int hook
, void * arg
) {
146 nick
* np
= ( nick
*) arg
;
148 deletenickfromnode ( np
-> ipnode
, np
);
151 void pn_hook_nodemoveuser ( int hook
, void * arg
) {
152 nick
* np
= (( void **) arg
)[ 0 ];
153 patricia_node_t
* oldnode
= (( void **) arg
)[ 1 ];
155 deletenickfromnode ( oldnode
, np
);
156 addnicktonode ( np
-> ipnode
, np
);
159 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
) {
160 nick
* np
=( nick
*) source
;
161 struct irc_in_addr sin
;
163 unsigned int count
, i
;
164 patricia_node_t
* head
, * node
;
172 if ( ipmask_parse ( cargv
[ 0 ], & sin
, & bits
) == 0 ) {
173 controlreply ( np
, "Invalid mask." );
177 head
= refnode ( iptree
, & sin
, bits
);
180 PATRICIA_WALK ( head
, node
)
182 pnp
= node
-> exts
[ pnode_ext
];
184 if ( count
< PATRICIANICK_MAXRESULTS
) {
185 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
186 for ( npp
= pnp
-> identhash
[ i
]; npp
; npp
= npp
-> exts
[ pnick_ext
]) {
187 controlreply ( np
, " %s ! %s @ %s%s%s ( %s )" , npp
-> nick
, npp
-> ident
, npp
-> host
-> name
-> content
, IsAccount ( npp
) ? "/" : "" , npp
-> authname
, IPtostr ( node
-> prefix
-> sin
));
191 count
+= node
-> usercount
;
193 if ( count
>= PATRICIANICK_MAXRESULTS
) {
194 controlreply ( np
, "Too many results, output truncated" );
197 count
+= node
-> usercount
;
202 derefnode ( iptree
, head
);
204 controlreply ( np
, "Total users on %s : %d " , cargv
[ 0 ], count
);