]>
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"
16 patricianick_t
* freepatricianicks
;
20 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
);
26 pnode_ext
= registernodeext ( "patricianick" );
27 if ( pnode_ext
== - 1 ) {
28 Error ( "patricianick" , ERR_FATAL
, "Could not register a required node extension" );
32 pnick_ext
= registernickext ( "patricianick" );
33 if ( pnick_ext
== - 1 ) {
34 Error ( "patricianick" , ERR_FATAL
, "Could not register a required nick extension" );
38 for ( i
= 0 ; i
< NICKHASHSIZE
; i
++)
39 for ( np
= nicktable
[ i
]; np
; np
= nnp
) {
41 addnicktonode ( np
-> ipnode
, np
);
44 registerhook ( HOOK_NICK_NEWNICK
, & pn_hook_newuser
);
45 registerhook ( HOOK_NICK_LOSTNICK
, & pn_hook_lostuser
);
47 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." );
51 nsfreeall ( POOL_PATRICIANICK
);
53 if ( pnode_ext
!= - 1 ) {
54 releasenodeext ( pnode_ext
);
57 if ( pnick_ext
!= - 1 ) {
58 releasenickext ( pnick_ext
);
61 deregisterhook ( HOOK_NICK_NEWNICK
, & pn_hook_newuser
);
62 deregisterhook ( HOOK_NICK_LOSTNICK
, & pn_hook_lostuser
);
64 deregistercontrolcmd ( "nodeuserlist" , & pn_cmd_nodeuserlist
);
67 patricianick_t
* getpatricianick () {
71 if ( freepatricianicks
== NULL
) {
72 freepatricianicks
=( patricianick_t
*) nsmalloc ( POOL_PATRICIANICK
, ALLOCUNIT
* sizeof ( patricianick_t
));
73 for ( i
= 0 ; i
< ALLOCUNIT
- 1 ; i
++) {
74 freepatricianicks
[ i
]. identhash
[ 0 ]=( nick
*)&( freepatricianicks
[ i
+ 1 ]);
76 freepatricianicks
[ ALLOCUNIT
- 1 ]. identhash
[ 0 ]= NULL
;
79 pnp
= freepatricianicks
;
80 freepatricianicks
=( patricianick_t
*) pnp
-> identhash
[ 0 ];
82 memset ( pnp
, 0 , sizeof ( patricianick_t
));
86 void addnicktonode ( patricia_node_t
* node
, nick
* np
) {
89 patricia_ref_prefix ( node
-> prefix
);
91 if (!( node
-> exts
[ pnode_ext
])) {
92 node
-> exts
[ pnode_ext
] = getpatricianick ();
95 hash
= pn_getidenthash ( np
-> ident
);
96 np
-> exts
[ pnick_ext
] = (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
];
97 (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
] = np
;
100 void deletenickfromnode ( patricia_node_t
* node
, nick
* np
) {
106 for ( tnp
= &((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ pn_getidenthash ( np
-> ident
)]); * tnp
; tnp
= ( nick
**)(&((* tnp
)-> exts
[ pnick_ext
]))) {
108 * tnp
= np
-> exts
[ pnick_ext
];
115 Error ( "patricianick" , ERR_ERROR
, "Could not remove %s ! %s from %s " , np
-> nick
, np
-> ident
, IPtostr ( node
-> prefix
-> sin
));
119 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
120 if ((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ i
]) {
125 freepatricianick ( node
-> exts
[ pnode_ext
]);
126 node
-> exts
[ pnode_ext
]= NULL
;
129 void freepatricianick ( patricianick_t
* pnp
) {
130 pnp
-> identhash
[ 0 ]=( nick
*) freepatricianicks
;
131 freepatricianicks
= pnp
;
134 void pn_hook_newuser ( int hook
, void * arg
) {
135 nick
* np
= ( nick
*) arg
;
137 addnicktonode ( np
-> ipnode
, np
);
140 void pn_hook_lostuser ( int hook
, void * arg
) {
141 nick
* np
= ( nick
*) arg
;
143 deletenickfromnode ( np
-> ipnode
, np
);
146 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
) {
147 nick
* np
=( nick
*) source
;
148 struct irc_in_addr sin
;
150 unsigned int count
, i
;
151 patricia_node_t
* head
, * node
;
159 if ( ipmask_parse ( cargv
[ 0 ], & sin
, & bits
) == 0 ) {
160 controlreply ( np
, "Invalid mask." );
164 head
= refnode ( iptree
, & sin
, bits
);
167 PATRICIA_WALK ( head
, node
)
169 pnp
= node
-> exts
[ pnode_ext
];
171 if ( count
< PATRICIANICK_MAXRESULTS
) {
172 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
173 for ( npp
= pnp
-> identhash
[ i
]; npp
; npp
= npp
-> exts
[ pnick_ext
]) {
174 controlreply ( np
, " %s ! %s @ %s%s%s ( %s )" , npp
-> nick
, npp
-> ident
, npp
-> host
-> name
-> content
, IsAccount ( npp
) ? "/" : "" , npp
-> authname
, IPtostr ( node
-> prefix
-> sin
));
178 count
+= node
-> usercount
;
180 if ( count
>= PATRICIANICK_MAXRESULTS
) {
181 controlreply ( np
, "Too many results, output truncated" );
184 count
+= node
-> usercount
;
189 derefnode ( iptree
, head
);
191 controlreply ( np
, "Total users on %s : %d " , cargv
[ 0 ], count
);