]>
jfr.im git - irc/quakenet/newserv.git/blob - chanprofile/chanprofile.c
2 #include "chanprofile.h"
3 #include "../channel/channel.h"
4 #include "../control/control.h"
5 #include "../newsearch/newsearch.h"
6 #include "../lib/version.h"
14 unsigned int activeprofiles
;
15 struct chanprofile
* cptable
[ CPHASHSIZE
];
17 struct chanprofile
* getcprec ( nick
* np
) {
18 unsigned int hash
= 0 , mhash
;
19 unsigned int ccount
= 0 ;
22 struct chanprofile
* cpp
;
24 struct channel
** cs
=( np
-> channels
-> content
);
26 ccount
= np
-> channels
-> cursi
;
28 for ( i
= 0 ; i
< np
-> channels
-> cursi
; i
++) {
29 clen
+= cs
[ i
]-> index
-> name
-> length
;
30 hash
^= ( unsigned long ) cs
[ i
];
33 mhash
= hash%CPHASHSIZE
;
35 for ( cpp
= cptable
[ mhash
]; cpp
; cpp
= cpp
-> next
) {
36 if (( cpp
-> hashval
== hash
) && ( cpp
-> ccount
== ccount
) &&
41 cpp
= malloc ( sizeof ( struct chanprofile
));
48 cpp
-> next
= cptable
[ mhash
];
58 struct chanprofile
* cpp
;
61 /* Create the chanprofile records and count clones for each profile */
62 for ( i
= 0 ; i
< NICKHASHSIZE
; i
++) {
63 for ( np
= nicktable
[ i
]; np
; np
= np
-> next
) {
69 /* Allocate space for nick array in each profile */
70 for ( i
= 0 ; i
< CPHASHSIZE
; i
++) {
71 for ( cpp
= cptable
[ i
]; cpp
; cpp
= cpp
-> next
) {
72 cpp
-> nicks
=( nick
**) malloc ( cpp
-> clones
* sizeof ( nick
*));
77 /* Populate the nick arrays */
78 for ( i
= 0 ; i
< NICKHASHSIZE
; i
++) {
79 for ( np
= nicktable
[ i
]; np
; np
= np
-> next
) {
81 cpp
-> nicks
[ cpp
-> clones
++]= np
;
86 void clearprofiles () {
88 struct chanprofile
* cpp
, * ncpp
;
90 for ( i
= 0 ; i
< CPHASHSIZE
; i
++) {
91 for ( cpp
= cptable
[ i
]; cpp
; cpp
= ncpp
) {
102 int cpcompare ( const void * a
, const void * b
) {
103 const struct chanprofile
** cpa
=( const struct chanprofile
**) a
, ** cpb
=( const struct chanprofile
**) b
;
105 return (* cpb
)-> clones
- (* cpa
)-> clones
;
108 void reportprofile ( nick
* sender
, struct chanprofile
* cpp
) {
113 unsigned int repwidth
= 80 ;
117 controlreply ( sender
, "============================================================" );
119 if ( cpp
-> ccount
== 0 ) {
120 controlreply ( sender
, "(no channels): %u users" , cpp
-> clones
);
124 controlreply ( sender
, "Channels ( %u ):" , cpp
-> ccount
);
127 cps
= np
-> channels
-> content
;
129 for ( i
= 0 ; i
< np
-> channels
-> cursi
; i
++) {
131 if ( bufpos
&& (( bufpos
+ cp
-> index
-> name
-> length
) > repwidth
)) {
132 controlreply ( sender
, " %s " , buf
);
136 bufpos
+= sprintf ( buf
+ bufpos
, " %s " , cp
-> index
-> name
-> content
);
140 controlreply ( sender
, " %s " , buf
);
142 controlreply ( sender
, "Users ( %u ):" , cpp
-> clones
);
144 ctx
. reply
= controlreply
;
145 for ( i
= 0 ; i
< cpp
-> clones
; i
++) {
146 printnick (& ctx
, sender
, cpp
-> nicks
[ i
]);
150 int reportprofiles ( void * source
, int cargc
, char ** cargv
) {
152 struct chanprofile
** cpary
, * cpp
;
153 unsigned int repnum
= 20 ;
157 repnum
= strtoul ( cargv
[ 0 ], NULL
, 10 );
161 /* Make a big fat array */
162 cpary
= malloc ( activeprofiles
* sizeof ( struct chanprofile
*));
163 for ( i
= 0 , j
= 0 ; i
< CPHASHSIZE
; i
++)
164 for ( cpp
= cptable
[ i
]; cpp
; cpp
= cpp
-> next
)
167 controlreply ( sender
, "Populated array, lest number= %u (should be %u )" , j
, activeprofiles
);
169 qsort ( cpary
, activeprofiles
, sizeof ( struct chanprofile
*), cpcompare
);
171 controlreply ( sender
, "Top %u channel profiles ( %u total):" , repnum
, activeprofiles
);
173 for ( i
= 0 ; i
< repnum
; i
++) {
174 reportprofile ( sender
, cpary
[ i
]);
177 controlreply ( sender
, "--- End of list." );
185 memset ( cptable
, 0 , sizeof ( cptable
));
186 registercontrolhelpcmd ( "chanprofiles" , NO_DEVELOPER
, 1 , reportprofiles
, "Usage: chanprofiles [count] \n Displays the most common channel profiles. count defaults to 20." );
190 deregistercontrolcmd ( "chanprofiles" , reportprofiles
);