]>
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"
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 () {
68 patricianick_t
* pnp
= nsmalloc ( POOL_PATRICIANICK
, sizeof ( patricianick_t
));
73 memset ( pnp
, 0 , sizeof ( patricianick_t
));
77 void addnicktonode ( patricia_node_t
* node
, nick
* np
) {
80 patricia_ref_prefix ( node
-> prefix
);
82 if (!( node
-> exts
[ pnode_ext
])) {
83 node
-> exts
[ pnode_ext
] = getpatricianick ();
86 hash
= pn_getidenthash ( np
-> ident
);
87 np
-> exts
[ pnick_ext
] = (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
];
88 (( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ hash
] = np
;
91 void deletenickfromnode ( patricia_node_t
* node
, nick
* np
) {
97 for ( tnp
= &((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ pn_getidenthash ( np
-> ident
)]); * tnp
; tnp
= ( nick
**)(&((* tnp
)-> exts
[ pnick_ext
]))) {
99 * tnp
= np
-> exts
[ pnick_ext
];
106 Error ( "patricianick" , ERR_ERROR
, "Could not remove %s ! %s from %s " , np
-> nick
, np
-> ident
, IPtostr ( node
-> prefix
-> sin
));
110 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
111 if ((( patricianick_t
*) node
-> exts
[ pnode_ext
])-> identhash
[ i
]) {
116 freepatricianick ( node
-> exts
[ pnode_ext
]);
117 node
-> exts
[ pnode_ext
]= NULL
;
120 void freepatricianick ( patricianick_t
* pnp
) {
121 nsfree ( POOL_PATRICIANICK
, pnp
);
124 void pn_hook_newuser ( int hook
, void * arg
) {
125 nick
* np
= ( nick
*) arg
;
127 addnicktonode ( np
-> ipnode
, np
);
130 void pn_hook_lostuser ( int hook
, void * arg
) {
131 nick
* np
= ( nick
*) arg
;
133 deletenickfromnode ( np
-> ipnode
, np
);
136 int pn_cmd_nodeuserlist ( void * source
, int cargc
, char ** cargv
) {
137 nick
* np
=( nick
*) source
;
138 struct irc_in_addr sin
;
140 unsigned int count
, i
;
141 patricia_node_t
* head
, * node
;
149 if ( ipmask_parse ( cargv
[ 0 ], & sin
, & bits
) == 0 ) {
150 controlreply ( np
, "Invalid mask." );
154 head
= refnode ( iptree
, & sin
, bits
);
157 PATRICIA_WALK ( head
, node
)
159 pnp
= node
-> exts
[ pnode_ext
];
161 if ( count
< PATRICIANICK_MAXRESULTS
) {
162 for ( i
= 0 ; i
< PATRICIANICK_HASHSIZE
; i
++) {
163 for ( npp
= pnp
-> identhash
[ i
]; npp
; npp
= npp
-> exts
[ pnick_ext
]) {
164 controlreply ( np
, " %s ! %s @ %s%s%s ( %s )" , npp
-> nick
, npp
-> ident
, npp
-> host
-> name
-> content
, IsAccount ( npp
) ? "/" : "" , npp
-> authname
, IPtostr ( node
-> prefix
-> sin
));
168 count
+= node
-> usercount
;
170 if ( count
>= PATRICIANICK_MAXRESULTS
) {
171 controlreply ( np
, "Too many results, output truncated" );
174 count
+= node
-> usercount
;
179 derefnode ( iptree
, head
);
181 controlreply ( np
, "Total users on %s : %d " , cargv
[ 0 ], count
);