]> jfr.im git - irc/quakenet/newserv.git/blame - nterface/nterfacer_control.c
Modified strlcat.c -> strlfunc.c and added strlcpy
[irc/quakenet/newserv.git] / nterface / nterfacer_control.c
CommitLineData
18f8bd28
CP
1/*
2 nterfacer newserv control module
3 Copyright (C) 2004 Chris Porter.
4
5 v1.05
6 - modified whois to take into account channels with ','
7 - made ison take multiple arguments
8 - added isaccounton
9 v1.04
10 - added status/onchan/servicesonchan
11 v1.03
12 - added multiple targets for channel/nick notice/message commands
13 v1.02
14 - added channel message, nick message/notice commands
15 - generalised error messages
16 v1.01
17 - whois fixed to notice BUF_OVER
18*/
19
20#include "../chanstats/chanstats.h"
21#include "../localuser/localuserchannel.h"
22#include "../channel/channel.h"
a4560bdf 23#include "../lib/strlfunc.h"
18f8bd28
CP
24#include "../control/control.h"
25#include "../core/hooks.h"
26#include "../lib/irc_string.h"
27
28#include "library.h"
29#include "nterfacer_control.h"
30
31struct service_node *node;
32
33int handle_chanstats(struct rline *li, int argc, char **argv);
34int handle_ison(struct rline *li, int argc, char **argv);
35int handle_whois(struct rline *li, int argc, char **argv);
36int handle_message(struct rline *li, int argc, char **argv);
37int handle_notice(struct rline *li, int argc, char **argv);
38int handle_channel(struct rline *li, int argc, char **argv);
39int handle_onchan(struct rline *li, int argc, char **argv);
40int handle_status(struct rline *li, int argc, char **argv);
41int handle_servicesonchan(struct rline *li, int argc, char **argv);
42int handle_isaccounton(struct rline *li, int argc, char **argv);
43
44struct rline *grli; /* used inline for status */
45
46void _init(void) {
47 node = register_service("N");
48 if(!node)
49 return;
50
51 register_handler(node, "chanstats", 1, handle_chanstats);
52 register_handler(node, "ison", 1, handle_ison);
53 register_handler(node, "whois", 1, handle_whois);
54 register_handler(node, "msg", 2, handle_message);
55 register_handler(node, "notice", 2, handle_notice);
56 register_handler(node, "chanmsg", 2, handle_channel);
57 register_handler(node, "onchan", 2, handle_onchan);
58 register_handler(node, "status", 0, handle_status);
59 register_handler(node, "servicesonchan", 1, handle_servicesonchan);
60 register_handler(node, "isaccounton", 1, handle_isaccounton);
61}
62
63void _fini(void) {
64 if(node)
65 deregister_service(node);
66}
67
68int handle_chanstats(struct rline *li, int argc, char **argv) {
69 chanstats *csp;
70 chanindex *cip;
71 int i,j,k,l;
72 int tot,emp;
73 int themax;
74 float details[13];
75
76 cip=findchanindex(argv[0]);
77
78 if (cip==NULL)
79 return ri_error(li, ERR_TARGET_NOT_FOUND, "Channel not found");
80
81 csp=cip->exts[csext];
82
83 if (csp==NULL)
84 return ri_error(li, ERR_CHANSTATS_STATS_NOT_FOUND, "Stats not found");
85
86 if (uponehour==0) {
87 details[0] = -1;
88 details[1] = -1;
89 } else {
90 tot=0; emp=0;
91 for(i=0;i<SAMPLEHISTORY;i++) {
92 tot+=csp->lastsamples[i];
93 if (csp->lastsamples[i]==0) {
94 emp++;
95 }
96 }
97 details[0] = tot/SAMPLEHISTORY;
98 details[1] = emp/SAMPLEHISTORY * 100;
99
100 }
101
102 details[2] = csp->todayusers/todaysamples;
103 details[3] = ((float)(todaysamples-csp->todaysamples)/todaysamples)*100;
104 details[4] = csp->todaymax;
105
106 themax=csp->lastmax[0];
107
108 details[5] = csp->lastdays[0]/10;
109 details[6] = ((float)(lastdaysamples[0]-csp->lastdaysamples[0])/lastdaysamples[0])*100;
110 details[7] = themax;
111
112 /* 7-day average */
113 j=k=l=0;
114 for (i=0;i<7;i++) {
115 j+=csp->lastdays[i];
116 k+=csp->lastdaysamples[i];
117 l+=lastdaysamples[i];
118 if (csp->lastmax[i]>themax) {
119 themax=csp->lastmax[i];
120 }
121 }
122
123 details[8] = j/70;
124 details[9] = ((l-k)*100)/l;
125 details[10] = themax;
126
127 /* 14-day average: continuation of last loop */
128 for (;i<14;i++) {
129 j+=csp->lastdays[i];
130 k+=csp->lastdaysamples[i];
131 l+=lastdaysamples[i];
132 if (csp->lastmax[i]>themax) {
133 themax=csp->lastmax[i];
134 }
135 }
136
137 details[11] = j/140;
138 details[12] = ((l-k)*100)/l;
139 details[13] = themax;
140
141 ri_append(li, "%.1f", details[0]);
142 ri_append(li, "%.1f%%", details[1]);
143 for(j=2;j<14;) {
144 ri_append(li, "%.1f", details[j++]);
145 ri_append(li, "%.1f%%", details[j++]);
146 ri_append(li, "%d%%", details[j++]);
147 }
148
149 return ri_final(li);
150}
151
152int handle_ison(struct rline *li, int argc, char **argv) {
153 int i;
154 for(i=0;i<argc;i++)
155 ri_append(li, "%d", getnickbynick(argv[i])?1:0);
156 return ri_final(li);
157}
158
159int handle_isaccounton(struct rline *li, int argc, char **argv) {
160 int i;
161 for(i=0;i<argc;i++)
162 ri_append(li, "%d", getnickbynick(argv[i])?1:0);
163 return ri_final(li);
164}
165
166int handle_whois(struct rline *li, int argc, char **argv) {
167 nick *np = getnickbynick(argv[0]);
168 channel **channels;
169
170 int i;
171
172 if(!np)
173 return ri_error(li, ERR_TARGET_NOT_FOUND, "User not online");
174
175 ri_append(li, "%s", np->nick);
176 ri_append(li, "%s", np->ident);
177 ri_append(li, "%s", np->host->name->content);
178 ri_append(li, "%s", np->realname->name->content);
179 ri_append(li, "%s", np->authname);
180
181 channels = np->channels->content;
182
183 for(i=0;i<np->channels->cursi;i++)
184 if(ri_append(li, "%s", channels[i]->index->name->content) == BF_OVER)
185 return ri_error(li, BF_OVER, "Buffer overflow");
186
187 return ri_final(li);
188}
189
190int handle_message(struct rline *li, int argc, char **argv) {
191 int realargc = abs(argc), i;
192 nick *np = getnickbynick(argv[0]);
193 if(!np)
194 return ri_error(li, ERR_TARGET_NOT_FOUND, "User not online");
195
196 for(i=1;i<realargc;i++) {
197 if(argc < 0) {
198 controlnotice(np, "%s", argv[i]);
199 } else {
200 controlreply(np, "%s", argv[i]);
201 }
202 }
203
204 ri_append(li, "Done.");
205 return ri_final(li);
206}
207
208int handle_notice(struct rline *li, int argc, char **argv) {
209 return handle_message(li, -argc, argv);
210}
211
212int handle_channel(struct rline *li, int argc, char **argv) {
213 int i;
214 channel *cp = findchannel(argv[0]);
215 if(!cp)
216 return ri_error(li, ERR_TARGET_NOT_FOUND, "Channel not found");
217
218 for(i=1;i<argc;i++)
219 controlchanmsg(cp, "%s", argv[i]);
220
221 ri_append(li, "Done.");
222 return ri_final(li);
223}
224
225int handle_onchan(struct rline *li, int argc, char **argv) {
226 int i;
227 nick *np = getnickbynick(argv[0]);
228 channel **channels;
229 channel *cp;
230 if(!np)
231 return ri_error(li, ERR_TARGET_NOT_FOUND, "Nickname not found");
232
233 cp = findchannel(argv[1]);
234 if(!cp)
235 return ri_error(li, ERR_TARGET_NOT_FOUND, "Channel not found");
236
237 channels = (channel **)np->channels->content;
238 for(i=0;i<np->channels->cursi;i++) {
239 if(channels[i]->index->channel == cp) {
240 ri_append(li, "1");
241 return ri_final(li);
242 }
243 }
244
245 ri_append(li, "0");
246 return ri_final(li);
247}
248
249void handle_nterfacerstats(int hooknum, void *arg) {
250 ri_append(grli, "%s", (char *)arg);
251}
252
253int handle_status(struct rline *li, int argc, char **argv) {
254 grli = li;
255
256 registerhook(HOOK_CORE_STATSREPLY, &handle_nterfacerstats);
257 triggerhook(HOOK_CORE_STATSREQUEST, (void *)5);
258 deregisterhook(HOOK_CORE_STATSREPLY, &handle_nterfacerstats);
259 return ri_final(li);
260}
261
262/* assumes services have a single char nickname and +k set */
263int handle_servicesonchan(struct rline *li, int argc, char **argv) {
264 int i;
265 nick *np;
266 channel *cp = findchannel(argv[0]);
267 if(!cp)
268 return ri_error(li, ERR_TARGET_NOT_FOUND, "Channel not found");
269
270#if NICKLEN >= 1 /* if not we have a buffer overflow */
271 for(i=0;i<=cp->users->hashsize;i++) {
272 if(cp->users->content[i] != nouser) {
273 np = getnickbynumeric(cp->users->content[i]);
274 if(np && IsService(np) && np->nick[0] && !np->nick[1])
275 ri_append(li, "%s", np->nick);
276 }
277 }
278#endif
279
280 return ri_final(li);
281}