]>
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 if (!( node
-> exts
[ pnode_ext
])) {
90 node
-> exts
[ pnode_ext
] = getpatricianick ();
93 hash
= pn_getidenthash ( np
-> ident
);
94 np
-> exts
[ pnick_ext
] = (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
];
95 (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
] = np
;
98 void deletenickfromnode ( patricia_node_t
* node
, nick
* np
) {
104 for ( tnp
= &((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ pn_getidenthash ( np
-> ident
)]); * tnp
; tnp
= ( nick
**)(&((* tnp
)-> exts
[ pnick_ext
]))) {
106 * tnp
= np
-> exts
[ pnick_ext
];
113 Error ( "patricianick" , ERR_ERROR
, "Could not remove %s ! %s from %s " , np
-> nick
, np
-> ident
, IPtostr ( node
-> prefix
-> sin
));
117 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
118 if ((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ i
]) {
123 freepatricianick ( node
-> exts
[ pnode_ext
]);
124 node
-> exts
[ pnode_ext
]= NULL
;
127 void freepatricianick ( patricianick_t
* pnp
) {
128 pnp
-> identhash
[ 0 ]=( nick
*) freepatricianicks
;
129 freepatricianicks
= pnp
;
132 void pn_hook_newuser ( int hook
, void * arg
) {
133 nick
* np
= ( nick
*) arg
;
135 addnicktonode ( np
-> ipnode
, np
);
138 void pn_hook_lostuser ( int hook
, void * arg
) {
139 nick
* np
= ( nick
*) arg
;
141 deletenickfromnode ( np
-> ipnode
, np
);
144 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
) {
145 nick
* np
=( nick
*) source
;
146 struct irc_in_addr sin
;
148 unsigned int count
, i
;
149 patricia_node_t
* head
, * node
;
157 if ( ipmask_parse ( cargv
[ 0 ], & sin
, & bits
) == 0 ) {
158 controlreply ( np
, "Invalid mask." );
162 head
= refnode ( iptree
, & sin
, bits
);
165 PATRICIA_WALK ( head
, node
)
167 pnp
= node
-> exts
[ pnode_ext
];
169 if ( count
< PATRICIANICK_MAXRESULTS
) {
170 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
171 for ( npp
= pnp
-> identhash
[ i
]; npp
; npp
= npp
-> exts
[ pnick_ext
]) {
172 controlreply ( np
, " %s ! %s @ %s%s%s ( %s )" , npp
-> nick
, npp
-> ident
, npp
-> host
-> name
-> content
, IsAccount ( npp
) ? "/" : "" , npp
-> authname
, IPtostr ( node
-> prefix
-> sin
));
176 count
+= node
-> usercount
;
178 if ( count
>= PATRICIANICK_MAXRESULTS
) {
179 controlreply ( np
, "Too many results, output truncated" );
182 count
+= node
-> usercount
;
187 derefnode ( iptree
, head
);
189 controlreply ( np
, "Total users on %s : %d " , cargv
[ 0 ], count
);