]> jfr.im git - irc/quakenet/newserv.git/blame - miscreply/miscreply.c
miscreply: new module that handles remote irc requests from users such as stats,...
[irc/quakenet/newserv.git] / miscreply / miscreply.c
CommitLineData
7bec4aeb 1/* miscreply.c */
2
3
4#include "miscreply.h"
5#include "msg.h"
6#include "numeric.h"
7#include "../core/error.h"
8#include "../irc/irc.h"
9#include "../lib/irc_string.h"
10#include "../lib/version.h"
11#include "../nick/nick.h"
12
13#include <stdarg.h>
14#include <stdio.h>
15
16/* module version */
17MODULE_VERSION("0.0.1");
18
19/* TODO: what module name? miscreply remotereply .. ? */
20/* TODO: what includes are required ? */
21/* TODO: add proper descriptions, maybe readme file ? */
22/* TODO: use serve instead of accessing serverlist[] directly ? */
23/* TODO: default.c handle there all remote requests we dont support ? */
24/* TODO: how to handle remote requests not for ourself but for other servers we have (juped ones or whatever) ? */
25/* TODO: check requests we receive are for me or my servers ? */
26/* TODO: remote requests:
27 * ASLL CHECK CONNECT INFO LUSERS MOTD NAMES UPING WHOWAS
28 * ADMIN LINKS PRIVS RPING RPONG STATS TRACE TIME VERSION WHOIS (done)
29 * GLINE JUPE SETTIME (already handled in other places)
30 */
31
32
33
34/* init */
35void _init() {
36
37 /* add server handlers */
38 registerserverhandler(TOK_ADMIN, &handleadminmsg, 1); /* ADMIN */
39 registerserverhandler(TOK_LINKS, &handlelinksmsg, 2); /* LINKS */
40 registerserverhandler(TOK_PRIVS, &handleprivsmsg, 1); /* PRIVS */
41 registerserverhandler(TOK_RPING, &handlerpingmsg, 3); /* RPING */
42 registerserverhandler(TOK_RPONG, &handlerpongmsg, 4); /* RPONG */
43 registerserverhandler(TOK_STATS, &handlestatsmsg, 2); /* STATS */
44 registerserverhandler(TOK_TIME, &handletimemsg, 1); /* TIME */
45 registerserverhandler(TOK_TRACE, &handletracemsg, 2); /* TRACE */
46 registerserverhandler(TOK_VERSION, &handleversionmsg, 1); /* VERSION */
47 registerserverhandler(TOK_WHOIS, &handlewhoismsg, 2); /* WHOIS */
48
49}
50
51
52
53/* fini */
54void _fini() {
55
56 /* remove server handlers */
57 deregisterserverhandler(TOK_ADMIN, &handleadminmsg); /* ADMIN */
58 deregisterserverhandler(TOK_LINKS, &handlelinksmsg); /* LINKS */
59 deregisterserverhandler(TOK_PRIVS, &handleprivsmsg); /* PRIVS */
60 deregisterserverhandler(TOK_RPING, &handlerpingmsg); /* RPING */
61 deregisterserverhandler(TOK_RPONG, &handlerpongmsg); /* RPONG */
62 deregisterserverhandler(TOK_STATS, &handlestatsmsg); /* STATS */
63 deregisterserverhandler(TOK_TIME, &handletimemsg); /* TIME */
64 deregisterserverhandler(TOK_TRACE, &handletracemsg); /* TRACE */
65 deregisterserverhandler(TOK_VERSION, &handleversionmsg); /* VERSION */
66 deregisterserverhandler(TOK_WHOIS, &handlewhoismsg); /* WHOIS */
67
68}
69
70
71
72/* needmoreparams
73 * return error to source user and log if we did not get enough parameters
74 */
75void miscreply_needmoreparams(char *sourcenum, char *command) {
76 /*
77 * 461 ERR_NEEDMOREPARAMS "source 461 target command :Not enough parameters"
78 * "irc.netsplit.net 461 foobar JOIN :Not enough parameters"
79 */
80 send_reply(getmynumeric(), ERR_NEEDMOREPARAMS, sourcenum, "%s :Not enough parameters", command);
81 Error("miscreply", ERR_WARNING, "%s request without enough parameters from %s", command, sourcenum);
82}
83
84
85
86/* findserver
87 * return error to log if source server numeric cannot be found
88 * returns server longnumeric
89 * returns -1 when not found
90 */
91int miscreply_findserver(char *sourcenum, char *command) {
92 int i = numerictolong(sourcenum, 2);
93
94 if (serverlist[i].maxusernum == 0) {
95 Error("miscreply", ERR_WARNING, "%s request from unknown server numeric %s", command, sourcenum);
96 return -1;
97 }
98
99 return i;
100}
101
102
103
104/* findservernum
105 * return error to source user and log if server numeric cannot be found
106 * returns server longnumeric
107 * returns -1 when not found
108 */
109int miscreply_findservernum(char *sourcenum, char *servernum, char *command) {
110 int i = numerictolong(servernum, 2);
111
112 if (serverlist[i].maxusernum == 0) {
113 /*
114 * 402 RPL_NOSUCHSERVER "source 402 target * :Server has disconnected"
115 * "irc.netsplit.net 402 foobar * :Server has disconnected"
116 */
117 send_reply(getmynumeric(), ERR_NOSUCHSERVER, sourcenum, "* :Server has disconnected");
118 Error("miscreply", ERR_WARNING, "%s request for unknown server numeric %s from numeric %s", command, servernum, sourcenum);
119 return -1;
120 }
121
122 return i;
123}
124
125
126
127/* findservermatch
128 * return error to source user if no servers matching the servermask can be found
129 * returns server longnumeric
130 * returns -1 when not found
131 */
132int miscreply_findservermatch(char *sourcenum, char *servermask) {
133 int i;
134
135 /* go over all servers */
136 for (i = 0; i < MAXSERVERS; i++) {
137 if (serverlist[i].maxusernum == 0) /* not linked */
138 continue;
139 if (!match2strings(servermask, serverlist[i].name->content)) /* no match */
140 continue;
141 return i;
142 }
143
144 /*
145 * 402 RPL_NOSUCHSERVER "source 402 target server :No such server"
146 * "irc.netsplit.net 402 foobar hub* :No such server"
147 */
148 send_reply(getmynumeric(), ERR_NOSUCHSERVER, sourcenum, "%s :No such server", servermask);
149
150 return -1;
151}
152
153
154
155/* finduser
156 * return error to log if user numeric cannot be found
157 */
158nick *miscreply_finduser(char *sourcenum, char *command) {
159 nick *nick;
160
161 if (!(nick = getnickbynumericstr(sourcenum)))
162 Error("miscreply", ERR_WARNING, "%s request from unknown user numeric %s", command, sourcenum);
163
164 return nick;
165}
166
167
168
169/* TODO: should it be long intead of int ? */
170/* myserver
171 *
172 * return 2 if the server is one of my downlinks (juped servers?),
173 * return 1 if the server is me, else
174 * return 0
175 */
176int miscreply_myserver(int numeric) {
177
178 /* it is me */
179 if (IsMeLong(numeric))
180 return 1;
181
182 /* while parent server is not me */
183 while (!IsMeLong(serverlist[numeric].parent))
184 numeric = serverlist[numeric].parent;
185
186 /* numeric is my hub,
187 * so the start server is behind it,
188 * and not one of mine
189 */
190 if (numeric == myhub)
191 return 0;
192
193 return 2;
194}
195
196
197
198/* send_reply
199 *
200 * send server numeric reply to user
201 *
202 */
203void send_reply(char *sourcenum, int numeric, char *targetnum, char *pattern, ...) {
204 char buf[BUFSIZE];
205 va_list val;
206
207 /* negative numeric? */
208 if (numeric < 0)
209 return;
210
211 va_start(val, pattern);
212 vsnprintf(buf, sizeof(buf), pattern, val);
213 va_end(val);
214
215 /*
216 * Reserve numerics 000-099 for server-client connections where the client
217 * is local to the server. If any server is passed a numeric in this range
218 * from another server then it is remapped to 100-199. -avalon
219 *
220 * from ircu ircd/numeric.h
221 */
222 /* just in case we are about to send a numeric in the reserved range, remap it */
223 if (numeric < 100)
224 numeric =+ 100;
225
226 irc_send("%s %d %s %s", sourcenum, numeric, targetnum, buf);
227}
228
229
230
231/* send_snotice
232 *
233 * send server notice to user
234 *
235 */
236void send_snotice(char *targetnum, char *pattern, ...) {
237 char buf[BUFSIZE];
238 va_list val;
239
240 va_start(val, pattern);
241 vsnprintf(buf, sizeof(buf), pattern, val);
242 va_end(val);
243
244 irc_send("%s %s %s :%s", getmynumeric(), TOK_NOTICE, targetnum, buf);
245}