]>
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"
11 unsigned int activeprofiles
;
12 struct chanprofile
* cptable
[ CPHASHSIZE
];
14 struct chanprofile
* getcprec ( nick
* np
) {
15 unsigned int hash
= 0 , mhash
;
16 unsigned int ccount
= 0 ;
19 struct chanprofile
* cpp
;
21 struct channel
** cs
=( np
-> channels
-> content
);
23 ccount
= np
-> channels
-> cursi
;
25 for ( i
= 0 ; i
< np
-> channels
-> cursi
; i
++) {
26 clen
+= cs
[ i
]-> index
-> name
-> length
;
27 hash
^= ( unsigned long ) cs
[ i
];
30 mhash
= hash%CPHASHSIZE
;
32 for ( cpp
= cptable
[ mhash
]; cpp
; cpp
= cpp
-> next
) {
33 if (( cpp
-> hashval
== hash
) && ( cpp
-> ccount
== ccount
) &&
38 cpp
= malloc ( sizeof ( struct chanprofile
));
45 cpp
-> next
= cptable
[ mhash
];
55 struct chanprofile
* cpp
;
58 /* Create the chanprofile records and count clones for each profile */
59 for ( i
= 0 ; i
< NICKHASHSIZE
; i
++) {
60 for ( np
= nicktable
[ i
]; np
; np
= np
-> next
) {
66 /* Allocate space for nick array in each profile */
67 for ( i
= 0 ; i
< CPHASHSIZE
; i
++) {
68 for ( cpp
= cptable
[ i
]; cpp
; cpp
= cpp
-> next
) {
69 cpp
-> nicks
=( nick
**) malloc ( cpp
-> clones
* sizeof ( nick
*));
74 /* Populate the nick arrays */
75 for ( i
= 0 ; i
< NICKHASHSIZE
; i
++) {
76 for ( np
= nicktable
[ i
]; np
; np
= np
-> next
) {
78 cpp
-> nicks
[ cpp
-> clones
++]= np
;
83 void clearprofiles () {
85 struct chanprofile
* cpp
, * ncpp
;
87 for ( i
= 0 ; i
< CPHASHSIZE
; i
++) {
88 for ( cpp
= cptable
[ i
]; cpp
; cpp
= ncpp
) {
99 int cpcompare ( const void * a
, const void * b
) {
100 const struct chanprofile
** cpa
=( const struct chanprofile
**) a
, ** cpb
=( const struct chanprofile
**) b
;
102 return (* cpb
)-> clones
- (* cpa
)-> clones
;
105 void reportprofile ( nick
* sender
, struct chanprofile
* cpp
) {
110 unsigned int repwidth
= 80 ;
114 controlreply ( sender
, "============================================================" );
116 if ( cpp
-> ccount
== 0 ) {
117 controlreply ( sender
, "(no channels): %u users" , cpp
-> clones
);
121 controlreply ( sender
, "Channels ( %u ):" , cpp
-> ccount
);
124 cps
= np
-> channels
-> content
;
126 for ( i
= 0 ; i
< np
-> channels
-> cursi
; i
++) {
128 if ( bufpos
&& (( bufpos
+ cp
-> index
-> name
-> length
) > repwidth
)) {
129 controlreply ( sender
, " %s " , buf
);
133 bufpos
+= sprintf ( buf
+ bufpos
, " %s " , cp
-> index
-> name
-> content
);
137 controlreply ( sender
, " %s " , buf
);
139 controlreply ( sender
, "Users ( %u ):" , cpp
-> clones
);
141 ctx
. reply
= controlreply
;
142 for ( i
= 0 ; i
< cpp
-> clones
; i
++) {
143 printnick (& ctx
, sender
, cpp
-> nicks
[ i
]);
147 int reportprofiles ( void * source
, int cargc
, char ** cargv
) {
149 struct chanprofile
** cpary
, * cpp
;
150 unsigned int repnum
= 20 ;
154 repnum
= strtoul ( cargv
[ 0 ], NULL
, 10 );
158 /* Make a big fat array */
159 cpary
= malloc ( activeprofiles
* sizeof ( struct chanprofile
*));
160 for ( i
= 0 , j
= 0 ; i
< CPHASHSIZE
; i
++)
161 for ( cpp
= cptable
[ i
]; cpp
; cpp
= cpp
-> next
)
164 controlreply ( sender
, "Populated array, lest number= %u (should be %u )" , j
, activeprofiles
);
166 qsort ( cpary
, activeprofiles
, sizeof ( struct chanprofile
*), cpcompare
);
168 controlreply ( sender
, "Top %u channel profiles ( %u total):" , repnum
, activeprofiles
);
170 for ( i
= 0 ; i
< repnum
; i
++) {
171 reportprofile ( sender
, cpary
[ i
]);
174 controlreply ( sender
, "--- End of list." );
182 memset ( cptable
, 0 , sizeof ( cptable
));
183 registercontrolhelpcmd ( "chanprofiles" , NO_DEVELOPER
, 1 , reportprofiles
, "Usage: chanprofiles [count] \n Displays the most common channel profiles. count defaults to 20." );
187 deregistercontrolcmd ( "chanprofiles" , reportprofiles
);