]>
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
);
50 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." );
54 nsfreeall ( POOL_PATRICIANICK
);
56 if ( pnode_ext
!= - 1 ) {
57 releasenodeext ( pnode_ext
);
60 if ( pnick_ext
!= - 1 ) {
61 releasenickext ( pnick_ext
);
64 deregisterhook ( HOOK_NICK_NEWNICK
, & pn_hook_newuser
);
65 deregisterhook ( HOOK_NICK_LOSTNICK
, & pn_hook_lostuser
);
67 deregistercontrolcmd ( "nodeuserlist" , & pn_cmd_nodeuserlist
);
70 patricianick_t
* getpatricianick () {
74 if ( freepatricianicks
== NULL
) {
75 freepatricianicks
=( patricianick_t
*) nsmalloc ( POOL_PATRICIANICK
, ALLOCUNIT
* sizeof ( patricianick_t
));
76 for ( i
= 0 ; i
< ALLOCUNIT
- 1 ; i
++) {
77 freepatricianicks
[ i
]. identhash
[ 0 ]=( nick
*)&( freepatricianicks
[ i
+ 1 ]);
79 freepatricianicks
[ ALLOCUNIT
- 1 ]. identhash
[ 0 ]= NULL
;
82 pnp
= freepatricianicks
;
83 freepatricianicks
=( patricianick_t
*) pnp
-> identhash
[ 0 ];
85 memset ( pnp
, 0 , sizeof ( patricianick_t
));
89 void addnicktonode ( patricia_node_t
* node
, nick
* np
) {
92 patricia_ref_prefix ( node
-> prefix
);
94 if (!( node
-> exts
[ pnode_ext
])) {
95 node
-> exts
[ pnode_ext
] = getpatricianick ();
98 hash
= pn_getidenthash ( np
-> ident
);
99 np
-> exts
[ pnick_ext
] = (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
];
100 (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
] = np
;
103 void deletenickfromnode ( patricia_node_t
* node
, nick
* np
) {
109 for ( tnp
= &((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ pn_getidenthash ( np
-> ident
)]); * tnp
; tnp
= ( nick
**)(&((* tnp
)-> exts
[ pnick_ext
]))) {
111 * tnp
= np
-> exts
[ pnick_ext
];
118 Error ( "patricianick" , ERR_ERROR
, "Could not remove %s ! %s from %s " , np
-> nick
, np
-> ident
, IPtostr ( node
-> prefix
-> sin
));
122 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
123 if ((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ i
]) {
128 freepatricianick ( node
-> exts
[ pnode_ext
]);
129 node
-> exts
[ pnode_ext
]= NULL
;
132 void freepatricianick ( patricianick_t
* pnp
) {
133 pnp
-> identhash
[ 0 ]=( nick
*) freepatricianicks
;
134 freepatricianicks
= pnp
;
137 void pn_hook_newuser ( int hook
, void * arg
) {
138 nick
* np
= ( nick
*) arg
;
140 addnicktonode ( np
-> ipnode
, np
);
143 void pn_hook_lostuser ( int hook
, void * arg
) {
144 nick
* np
= ( nick
*) arg
;
146 deletenickfromnode ( np
-> ipnode
, np
);
149 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
) {
150 nick
* np
=( nick
*) source
;
151 struct irc_in_addr sin
;
153 unsigned int count
, i
;
154 patricia_node_t
* head
, * node
;
162 if ( ipmask_parse ( cargv
[ 0 ], & sin
, & bits
) == 0 ) {
163 controlreply ( np
, "Invalid mask." );
167 head
= refnode ( iptree
, & sin
, bits
);
170 PATRICIA_WALK ( head
, node
)
172 pnp
= node
-> exts
[ pnode_ext
];
174 if ( count
< PATRICIANICK_MAXRESULTS
) {
175 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
176 for ( npp
= pnp
-> identhash
[ i
]; npp
; npp
= npp
-> exts
[ pnick_ext
]) {
177 controlreply ( np
, " %s ! %s @ %s%s%s ( %s )" , npp
-> nick
, npp
-> ident
, npp
-> host
-> name
-> content
, IsAccount ( npp
) ? "/" : "" , npp
-> authname
, IPtostr ( node
-> prefix
-> sin
));
181 count
+= node
-> usercount
;
183 if ( count
>= PATRICIANICK_MAXRESULTS
) {
184 controlreply ( np
, "Too many results, output truncated" );
187 count
+= node
-> usercount
;
192 derefnode ( iptree
, head
);
194 controlreply ( np
, "Total users on %s : %d " , cargv
[ 0 ], count
);