]>
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"
14 #define ALLOCUNIT 1000
16 patricianick_t
*freepatricianicks
;
20 int pn_cmd_dumpnodenicks(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 registercontrolcmd("dumpnodenicks", NO_DEVELOPER
, 1, &pn_cmd_dumpnodenicks
);
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("dumpnodenicks", &pn_cmd_dumpnodenicks
);
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
].np
=(nick
*)&(freepatricianicks
[i
+1]);
76 freepatricianicks
[ALLOCUNIT
-1].np
=NULL
;
79 pnp
=freepatricianicks
;
80 freepatricianicks
=(patricianick_t
*)pnp
->np
;
87 void addnicktonode(patricia_node_t
*node
, nick
*np
) {
88 if ( !(node
->exts
[pnode_ext
]) ) {
89 node
->exts
[pnode_ext
] = getpatricianick();
92 np
->exts
[pnick_ext
] = ((patricianick_t
*)node
->exts
[pnode_ext
])->np
;
93 ((patricianick_t
*)node
->exts
[pnode_ext
])->np
= np
;
96 void deletenickfromnode(patricia_node_t
*node
, nick
*np
) {
100 for ( tnp
= &(((patricianick_t
*)node
->exts
[pnode_ext
])->np
); *tnp
; tnp
= (nick
**)(&((*tnp
)->exts
[pnick_ext
])) ) {
102 *tnp
= np
->exts
[pnick_ext
];
112 if (!(((patricianick_t
*)node
->exts
[pnode_ext
])->np
)) {
113 freepatricianick(node
->exts
[pnode_ext
]);
114 node
->exts
[pnode_ext
]= NULL
;
119 void freepatricianick(patricianick_t
*pnp
) {
120 pnp
->np
=(nick
*)freepatricianicks
;
121 freepatricianicks
=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_dumpnodenicks(void *source
, int cargc
, char **cargv
) {
137 nick
*np
=(nick
*)source
;
138 struct irc_in_addr sin
;
140 patricia_node_t
*head
, *node
;
146 controlreply(np
, "Syntax: dumpnodenicks <ipv4|ipv6|cidr4|cidr6>");
150 if (ipmask_parse(cargv
[0], &sin
, &bits
) == 0) {
151 controlreply(np
, "Invalid mask.");
155 head
= refnode(iptree
, &sin
, bits
);
157 PATRICIA_WALK(head
, node
)
159 pnp
= node
->exts
[pnode_ext
];
165 if ( limit
< PATRICIANICK_MAXRESULTS
)
166 controlreply(np
, "%s!%s@%s%s%s (%s)", npp
->nick
, npp
->ident
, npp
->host
->name
->content
, IsAccount(npp
) ? "/" : "", npp
->authname
, IPtostr(node
->prefix
->sin
));
167 else if ( limit
== PATRICIANICK_MAXRESULTS
)
168 controlreply(np
, "Too many Results, truncated..");
169 npp
=npp
->exts
[pnick_ext
];
174 controlreply(np
, "Nick Count: %d", limit
);