#include "channel.h"
#include "../server/server.h"
#include "../nick/nick.h"
-#include "../miscreply/numeric.h"
#include "../lib/irc_string.h"
#include "../irc/irc_config.h"
#include "../parser/parser.h"
sstring *name;
unsigned long *num;
int i;
- void **args = (void **)arg;
- nick *sender = (nick *)args[0], *target = (nick *)args[1];
-
- if(IsService(target) || IsHideChan(target))
+ char **args = (char **)arg;
+ nick *sender = (nick *)args[0]; /* sender nick */
+ nick *target = (nick *)args[1]; /* target nick */
+ char *sourcenum = args[2]; /* source numeric */
+
+ /* do not show channels for +k service clients or IRC Operators
+ * do not show channels for +n users
+ * unless they whois themselves
+ */
+ if ((IsService(target) || IsHideChan(target)) && sender != target)
return;
chans = (channel **)(target->channels->content);
* "irc.netsplit.net 319 foobar barfoo :-@#chan1 -+#chan2 -#chan3"
*/
if(buffer[0] == '\0')
- bufpos=snprintf(buffer, sizeof(buffer), "%s %d %s %s :", getmynumeric(), RPL_WHOISCHANNELS, longtonumeric(sender->numeric, 5), target->nick);
+ bufpos=snprintf(buffer, sizeof(buffer), "%s 319 %s %s :", getmynumeric(), sourcenum, target->nick);
num = getnumerichandlefromchanhash(chans[i]->users, target->numeric);
#define HOOK_NICK_NEWNICK 300 /* Argument is nick* */
#define HOOK_NICK_RENAME 301 /* Argument is nick* */
#define HOOK_NICK_LOSTNICK 302 /* Argument is nick* */
-#define HOOK_NICK_WHOISCHANNELS 303 /* Argument is nick*[2] (sender, target) */
+#define HOOK_NICK_WHOISCHANNELS 303 /* Argument is void*[3] (sender, target, sourcenum) */
#define HOOK_NICK_ACCOUNT 304 /* Argument is nick* */
#define HOOK_NICK_QUIT 305 /* Argument is void*[2] (nick, reason) */
#define HOOK_NICK_SETHOST 306 /* Argument is nick* */
#include "../lib/version.h"
#include "../lib/irc_string.h"
#include "../lib/strlfunc.h"
-#include "../miscreply/numeric.h"
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
/* list stats commands / m to a user
*
- * targetnum stats request for server numeric
* sourcenum numeric of the user requesting the listing
*/
-void stats_commands(char *targetnum, char *sourcenum) {
+void stats_commands(char *sourcenum) {
Command *cmds[500];
unsigned int c,i;
* 212 RPL_STATSCOMMANDS "source 212 target command used_count bytes_count"
* "irc.netsplit.net 212 foobar ACCOUNT 41 462"
*/
- irc_send("%s %d %s %s %u 0", targetnum, RPL_STATSCOMMANDS, sourcenum, cmds[i]->command->content, cmds[i]->calls);
+ irc_send("%s 212 %s %s %u 0", getmynumeric(), sourcenum, cmds[i]->command->content, cmds[i]->calls);
}
}
char *getmynumeric();
time_t getnettime();
void setnettime(time_t newtime);
-void stats_commands(char *targetnum, char *sourcenum);
+void stats_commands(char *sourcenum);
/* Functions from irchandlers.c */
int handleping(void *sender, int cargc, char **cargv);
.PHONY: all
all: miscreply.so
-miscreply.so: miscreply.o admin.o links.o privs.o rping.o rpong.o stats.o time.o trace.o version.o whois.o
+miscreply.so: miscreply.o admin.o privs.o rping.o rpong.o stats.o time.o trace.o version.o whois.o
/* admin.c */
#include "miscreply.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
-#include <string.h>
-
-/* TODO: grab admin info from conf */
-
/* handle remote admin request
*
* <source numeric> ADMIN/AD <target server numeric>
*/
int handleadminmsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source nick */
-
- int i; /* index for serverlist[] */
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *servernum; /* server numeric parameter */
- char *servername = myserver->content; /* servername */
+ nick *snick; /* struct nick for source nick */
+ char *sourcenum = (char *)source; /* source user numeric */
/* check parameters */
if (cargc < 1) {
return CMD_OK;
}
- /* get the parameter */
- servernum = cargv[0];
-
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
-
/* find source user */
if (!(snick = miscreply_finduser(sourcenum, "ADMIN")))
return CMD_OK;
- /* not for me */
- if (!IsMeNum(servernum)) {
-
- /* find the server */
- if ((i = miscreply_findservernum(sourcenum, servernum, "ADMIN")) == -1)
- return CMD_OK;
-
- targetnum = longtonumeric(i, 2);
- servername = serverlist[i].name->content;
-
- /* tell user */
- send_snotice(sourcenum, "ADMIN: Server %s is not a real server.", servername);
- /*
- * 423 ERR_NOADMININFO "source 423 target server :No administrative info available"
- * "irc.netsplit.net 423 foobar irc.netsplit.net :No administrative info available"
- */
- send_reply(targetnum, ERR_NOADMININFO, sourcenum, "%s :No administrative info available", servername);
- }
-
- /* for me */
- else {
-
- /*
- * 256 RPL_ADMINME "source 256 target :Administrative info about server"
- * "irc.netsplit.net 256 foobar :Administrative info about irc.netsplit.net"
- */
- send_reply(targetnum, RPL_ADMINME, sourcenum, ":Administrative info about %s", servername);
-
- /*
- * 257 RPL_ADMINLOC1 "source 257 target :text"
- * "irc.netsplit.net 257 foobar :The NetSplit IRC Network"
- */
- send_reply(targetnum, RPL_ADMINLOC1, sourcenum, ":The NetSplit IRC Network");
-
- /*
- * 258 RPL_ADMINLOC2 "source 258 target :text"
- * "irc.netsplit.net 258 foobar :NetSplit IRC Server"
- */
- send_reply(targetnum, RPL_ADMINLOC2, sourcenum, ":NetSplit IRC Server");
-
- /*
- * 259 RPL_ADMINEMAIL "source 259 target :text"
- * "irc.netsplit.net 259 foobar :IRC Admins <mail@host>"
- */
- send_reply(targetnum, RPL_ADMINEMAIL, sourcenum, ":IRC Admins <mail@host>");
- }
+ /*
+ * 256 RPL_ADMINME "source 256 target :Administrative info about server"
+ * "irc.netsplit.net 256 foobar :Administrative info about irc.netsplit.net"
+ */
+ irc_send("%s 256 %s :Administrative info about %s", getmynumeric(), sourcenum, myserver->content);
+
+ /*
+ * 257 RPL_ADMINLOC1 "source 257 target :text"
+ * "irc.netsplit.net 257 foobar :Located at someplace"
+ */
+ irc_send("%s 257 %s :%s", getmynumeric(), sourcenum, admin1->content);
+
+ /*
+ * 258 RPL_ADMINLOC2 "source 258 target :text"
+ * "irc.netsplit.net 258 foobar :NetSplit IRC Server"
+ */
+ irc_send("%s 258 %s :%s", getmynumeric(), sourcenum, admin2->content);
+
+ /*
+ * 259 RPL_ADMINEMAIL "source 259 target :text"
+ * "irc.netsplit.net 259 foobar :IRC Admins <mail@host>"
+ */
+ irc_send("%s 259 %s :%s", getmynumeric(), sourcenum, admin3->content);
return CMD_OK;
}
/* miscreply.c */
-
#include "miscreply.h"
-#include "msg.h"
-#include "numeric.h"
#include "../core/error.h"
+#include "../core/config.h"
#include "../irc/irc.h"
#include "../lib/irc_string.h"
#include "../lib/version.h"
#include <stdarg.h>
#include <stdio.h>
+#include <string.h>
/* module version */
-MODULE_VERSION("0.0.1");
-
-/* TODO: what module name? miscreply remotereply .. ? */
-/* TODO: what includes are required ? */
-/* TODO: add proper descriptions, maybe readme file ? */
-/* TODO: use serve instead of accessing serverlist[] directly ? */
-/* TODO: default.c handle there all remote requests we dont support ? */
-/* TODO: how to handle remote requests not for ourself but for other servers we have (juped ones or whatever) ? */
-/* TODO: check requests we receive are for me or my servers ? */
-/* TODO: remote requests:
- * ASLL CHECK CONNECT INFO LUSERS MOTD NAMES UPING WHOWAS
- * ADMIN LINKS PRIVS RPING RPONG STATS TRACE TIME VERSION WHOIS (done)
- * GLINE JUPE SETTIME (already handled in other places)
+MODULE_VERSION(MISCREPLY_VERSION);
+
+
+
+/*
+ * This module handles the following remote IRC commands
+ *
+ * ADMIN
+ * PRIVS
+ * RPING
+ * RPONG
+ * STATS
+ * TRACE
+ * TIME
+ * VERSION
+ * WHOIS
+ *
*/
+/* admin info */
+sstring *admin1;
+sstring *admin2;
+sstring *admin3;
+
+
+
/* init */
void _init() {
-
+
+ /* get the admin info from the config
+ * mix in some references to Quake and Doom in the defaults
+ */
+ admin1 = getcopyconfigitem("miscreply", "admin1", "Located at the Union Aerospace Corp. facility, Stroggos", BUFSIZE);
+ admin2 = getcopyconfigitem("miscreply", "admin2", "Network IRC Service", BUFSIZE);
+ admin3 = getcopyconfigitem("miscreply", "admin3", "No administrative info available", BUFSIZE);
+
/* add server handlers */
- registerserverhandler(TOK_ADMIN, &handleadminmsg, 1); /* ADMIN */
- registerserverhandler(TOK_LINKS, &handlelinksmsg, 2); /* LINKS */
- registerserverhandler(TOK_PRIVS, &handleprivsmsg, 1); /* PRIVS */
- registerserverhandler(TOK_RPING, &handlerpingmsg, 3); /* RPING */
- registerserverhandler(TOK_RPONG, &handlerpongmsg, 4); /* RPONG */
- registerserverhandler(TOK_STATS, &handlestatsmsg, 2); /* STATS */
- registerserverhandler(TOK_TIME, &handletimemsg, 1); /* TIME */
- registerserverhandler(TOK_TRACE, &handletracemsg, 2); /* TRACE */
- registerserverhandler(TOK_VERSION, &handleversionmsg, 1); /* VERSION */
- registerserverhandler(TOK_WHOIS, &handlewhoismsg, 2); /* WHOIS */
+ registerserverhandler("AD", &handleadminmsg, 1); /* ADMIN */
+ registerserverhandler("PR", &handleprivsmsg, 1); /* PRIVS */
+ registerserverhandler("RI", &handlerpingmsg, 3); /* RPING */
+ registerserverhandler("RO", &handlerpongmsg, 4); /* RPONG */
+ registerserverhandler("R", &handlestatsmsg, 2); /* STATS */
+ registerserverhandler("TI", &handletimemsg, 1); /* TIME */
+ registerserverhandler("TR", &handletracemsg, 2); /* TRACE */
+ registerserverhandler("V", &handleversionmsg, 1); /* VERSION */
+ registerserverhandler("W", &handlewhoismsg, 2); /* WHOIS */
}
void _fini() {
/* remove server handlers */
- deregisterserverhandler(TOK_ADMIN, &handleadminmsg); /* ADMIN */
- deregisterserverhandler(TOK_LINKS, &handlelinksmsg); /* LINKS */
- deregisterserverhandler(TOK_PRIVS, &handleprivsmsg); /* PRIVS */
- deregisterserverhandler(TOK_RPING, &handlerpingmsg); /* RPING */
- deregisterserverhandler(TOK_RPONG, &handlerpongmsg); /* RPONG */
- deregisterserverhandler(TOK_STATS, &handlestatsmsg); /* STATS */
- deregisterserverhandler(TOK_TIME, &handletimemsg); /* TIME */
- deregisterserverhandler(TOK_TRACE, &handletracemsg); /* TRACE */
- deregisterserverhandler(TOK_VERSION, &handleversionmsg); /* VERSION */
- deregisterserverhandler(TOK_WHOIS, &handlewhoismsg); /* WHOIS */
+ deregisterserverhandler("AD", &handleadminmsg); /* ADMIN */
+ deregisterserverhandler("PR", &handleprivsmsg); /* PRIVS */
+ deregisterserverhandler("RI", &handlerpingmsg); /* RPING */
+ deregisterserverhandler("RO", &handlerpongmsg); /* RPONG */
+ deregisterserverhandler("R", &handlestatsmsg); /* STATS */
+ deregisterserverhandler("TI", &handletimemsg); /* TIME */
+ deregisterserverhandler("TR", &handletracemsg); /* TRACE */
+ deregisterserverhandler("V", &handleversionmsg); /* VERSION */
+ deregisterserverhandler("W", &handlewhoismsg); /* WHOIS */
+
+}
+
+
+
+/* from_server
+ * if valid server numeric return 1
+ * else return 0 and log error
+ */
+static int from_server(char *sourcenum, char *command) {
+ /* valid server numeric */
+ if (strlen(sourcenum) == 2)
+ return 1;
+
+ Error("miscreply", ERR_WARNING, "Received %s request from non-server numeric %s", command, sourcenum);
+ return 0;
+}
+
+
+
+/* from_user
+ * if valid user numeric return 1
+ * else return 0 and log error
+ */
+static int from_user(char *sourcenum, char *command) {
+
+ /* valid user numeric */
+ if (strlen(sourcenum) == 5)
+ return 1;
+
+ Error("miscreply", ERR_WARNING, "Received %s request from non-user numeric %s", command, sourcenum);
+ return 0;
}
/* needmoreparams
- * return error to source user and log if we did not get enough parameters
+ * reply error to source user
+ * log error
*/
void miscreply_needmoreparams(char *sourcenum, char *command) {
/*
* 461 ERR_NEEDMOREPARAMS "source 461 target command :Not enough parameters"
* "irc.netsplit.net 461 foobar JOIN :Not enough parameters"
*/
- send_reply(getmynumeric(), ERR_NEEDMOREPARAMS, sourcenum, "%s :Not enough parameters", command);
- Error("miscreply", ERR_WARNING, "%s request without enough parameters from %s", command, sourcenum);
+ irc_send("%s 461 %s %s :Not enough parameters", getmynumeric(), sourcenum, command);
+ Error("miscreply", ERR_WARNING, "Received %s request without enough parameters from %s", command, sourcenum);
}
/* findserver
- * return error to log if source server numeric cannot be found
- * returns server longnumeric
- * returns -1 when not found
+ * if found return server longnumeric
+ * else return -1 and log error
*/
-int miscreply_findserver(char *sourcenum, char *command) {
- int i = numerictolong(sourcenum, 2);
+long miscreply_findserver(char *sourcenum, char *command) {
+ long i = numerictolong(sourcenum, 2);
- if (serverlist[i].maxusernum == 0) {
- Error("miscreply", ERR_WARNING, "%s request from unknown server numeric %s", command, sourcenum);
+ /* check source is a valid server numeric */
+ if (!from_server(sourcenum, command))
return -1;
- }
-
- return i;
-}
-
+ if (serverlist[i].linkstate != LS_INVALID)
+ return i;
-/* findservernum
- * return error to source user and log if server numeric cannot be found
- * returns server longnumeric
- * returns -1 when not found
- */
-int miscreply_findservernum(char *sourcenum, char *servernum, char *command) {
- int i = numerictolong(servernum, 2);
-
- if (serverlist[i].maxusernum == 0) {
- /*
- * 402 RPL_NOSUCHSERVER "source 402 target * :Server has disconnected"
- * "irc.netsplit.net 402 foobar * :Server has disconnected"
- */
- send_reply(getmynumeric(), ERR_NOSUCHSERVER, sourcenum, "* :Server has disconnected");
- Error("miscreply", ERR_WARNING, "%s request for unknown server numeric %s from numeric %s", command, servernum, sourcenum);
- return -1;
- }
-
- return i;
+ Error("miscreply", ERR_WARNING, "Received %s request from unknown server numeric %s", command, sourcenum);
+ return -1;
}
/* findservermatch
- * return error to source user if no servers matching the servermask can be found
- * returns server longnumeric
- * returns -1 when not found
+ * if found return server longnumeric
+ * else return -1 and reply error to source user
*/
-int miscreply_findservermatch(char *sourcenum, char *servermask) {
- int i;
+long miscreply_findservermatch(char *sourcenum, char *servermask) {
+ long i;
/* go over all servers */
for (i = 0; i < MAXSERVERS; i++) {
- if (serverlist[i].maxusernum == 0) /* not linked */
+ if (serverlist[i].linkstate == LS_INVALID) /* not linked */
continue;
if (!match2strings(servermask, serverlist[i].name->content)) /* no match */
continue;
* 402 RPL_NOSUCHSERVER "source 402 target server :No such server"
* "irc.netsplit.net 402 foobar hub* :No such server"
*/
- send_reply(getmynumeric(), ERR_NOSUCHSERVER, sourcenum, "%s :No such server", servermask);
+ irc_send("%s 402 %s %s :No such server", getmynumeric(), sourcenum, servermask);
return -1;
}
-/* finduser
- * return error to log if user numeric cannot be found
+/* finduser
+ * if found return nick for source numeric
+ * else return NULL and log error
*/
nick *miscreply_finduser(char *sourcenum, char *command) {
nick *nick;
- if (!(nick = getnickbynumericstr(sourcenum)))
- Error("miscreply", ERR_WARNING, "%s request from unknown user numeric %s", command, sourcenum);
-
- return nick;
-}
-
-
-
-/* TODO: should it be long intead of int ? */
-/* myserver
- *
- * return 2 if the server is one of my downlinks (juped servers?),
- * return 1 if the server is me, else
- * return 0
- */
-int miscreply_myserver(int numeric) {
-
- /* it is me */
- if (IsMeLong(numeric))
- return 1;
-
- /* while parent server is not me */
- while (!IsMeLong(serverlist[numeric].parent))
- numeric = serverlist[numeric].parent;
-
- /* numeric is my hub,
- * so the start server is behind it,
- * and not one of mine
- */
- if (numeric == myhub)
- return 0;
-
- return 2;
-}
-
-
-
-/* send_reply
- *
- * send server numeric reply to user
- *
- */
-void send_reply(char *sourcenum, int numeric, char *targetnum, char *pattern, ...) {
- char buf[BUFSIZE];
- va_list val;
-
- /* negative numeric? */
- if (numeric < 0)
- return;
-
- va_start(val, pattern);
- vsnprintf(buf, sizeof(buf), pattern, val);
- va_end(val);
-
- /*
- * Reserve numerics 000-099 for server-client connections where the client
- * is local to the server. If any server is passed a numeric in this range
- * from another server then it is remapped to 100-199. -avalon
- *
- * from ircu ircd/numeric.h
- */
- /* just in case we are about to send a numeric in the reserved range, remap it */
- if (numeric < 100)
- numeric =+ 100;
-
- irc_send("%s %d %s %s", sourcenum, numeric, targetnum, buf);
-}
-
-
-
-/* send_snotice
- *
- * send server notice to user
- *
- */
-void send_snotice(char *targetnum, char *pattern, ...) {
- char buf[BUFSIZE];
- va_list val;
+ /* check source is a valid user numeric */
+ if (!from_user(sourcenum, command))
+ return NULL;
- va_start(val, pattern);
- vsnprintf(buf, sizeof(buf), pattern, val);
- va_end(val);
+ if ((nick = getnickbynumericstr(sourcenum)))
+ return nick;
- irc_send("%s %s %s :%s", getmynumeric(), TOK_NOTICE, targetnum, buf);
+ Error("miscreply", ERR_WARNING, "Received %s request from unknown user numeric %s", command, sourcenum);
+ return NULL;
}
#include "../nick/nick.h"
-/* TODO: this should be moved to nick.h ? if approved */
-/* char to use in case no opername is known */
-#define NOOPERNAMECHARACTER "-"
+
+#define MISCREPLY_VERSION "1.0.0"
+
+
+/* admin info */
+extern sstring *admin1;
+extern sstring *admin2;
+extern sstring *admin3;
+
/* remote request handle functions */
int handleadminmsg(void *source, int cargc, char **cargv); /* ADMIN */
-int handlelinksmsg(void *source, int cargc, char **cargv); /* LINKS */
int handleprivsmsg(void *source, int cargc, char **cargv); /* PRIVS */
int handlerpingmsg(void *source, int cargc, char **cargv); /* RPING */
int handlerpongmsg(void *source, int cargc, char **cargv); /* RPONG */
int handleversionmsg(void *source, int cargc, char **cargv); /* VERSION */
int handlewhoismsg(void *source, int cargc, char **cargv); /* WHOIS */
+
/* helper functions */
void miscreply_needmoreparams(char *sourcenum, char *command);
-int miscreply_findserver(char *sourcenum, char *command);
-int miscreply_findservernum(char *sourcenum, char *servernum, char *command);
-int miscreply_findservermatch(char *sourcenum, char *servermask);
-int miscreply_myserver(int numeric);
+long miscreply_findserver(char *sourcenum, char *command);
+long miscreply_findservermatch(char *sourcenum, char *servermask);
nick *miscreply_finduser(char *sourcenum, char *command);
-/* TODO: these should be moved to irc.c irc.h ? if approved */
-void send_reply(char *sourcenum, int numeric, char *targetnum, char *pattern, ...) __attribute__ ((format (printf, 4, 5)));
-void send_snotice(char *targetnum, char *pattern, ...) __attribute__ ((format (printf, 2, 3)));
-
-/* TODO: these should be moved to irc.h and nick.h ? if approved */
-/* test if servername is me */
-#define IsMeStr(x) (!strcmp((x), myserver->content)
-/* test if numeric is me */
-#define IsMeNum(x) (!strcmp((x), getmynumeric()))
-/* test if long numeric is me */
-#define IsMeLong(x) ((x) == mylongnum)
-/* test if a numeric is a user */
-#define IsUser(x) (strlen((x)) == 5)
-/* test if a numeric is a server */
-#define IsServer(x) (strlen((x)) == 2)
-/* test if a nick is my user */
-#define MyUser(x) (IsMeLong(homeserver((x)->numeric)))
-/* test if a user has an opername */
-#define HasOperName(x) ((x)->opername && strcmp((x)->opername->content, NOOPERNAMECHARACTER))
-/* test if a user has a hidden host (mode +rx) */
-#define HasHiddenHost(x) (IsAccount((x)) && IsHideHost((x)))
-/* test if a user is away */
-#define IsAway(x) ((x)->away)
-
-/* TODO: this should be moved to irc.h ? if approved */
-/* maximum length of a protocol message, including \r\n */
-#define BUFSIZE 512
#endif
+++ /dev/null
-/* msg.h */
-
-#ifndef __MSG_H
-#define __MSG_H
-
-/* TODO: this should be somewhere central */
-
-/* IRC commands and P10 tokens */
-
-#define MSG_ACCOUNT "ACCOUNT" /* ACCOUNT */
-#define TOK_ACCOUNT "AC"
-
-#define MSG_ADMIN "ADMIN" /* ADMIN */
-#define TOK_ADMIN "AD"
-
-#define MSG_ASLL "ASLL" /* ASLL */
-#define TOK_ASLL "LL"
-
-#define MSG_AWAY "AWAY" /* AWAY */
-#define TOK_AWAY "A"
-
-#define MSG_BURST "BURST" /* BURST */
-#define TOK_BURST "B"
-
-#define MSG_CHECK "CHECK" /* CHECK */
-#define TOK_CHECK "CC"
-
-#define MSG_CLEARMODE "CLEARMODE" /* CLEARMODE */
-#define TOK_CLEARMODE "CM"
-
-#define MSG_CONNECT "CONNECT" /* CONNECT */
-#define TOK_CONNECT "CO"
-
-#define MSG_CREATE "CREATE" /* CREATE */
-#define TOK_CREATE "C"
-
-#define MSG_DESTRUCT "DESTRUCT" /* DESTRUCT */
-#define TOK_DESTRUCT "DE"
-
-#define MSG_DESYNCH "DESYNCH" /* DESYNCH */
-#define TOK_DESYNCH "DS"
-
-#define MSG_END_OF_BURST "END_OF_BURST" /* END_OF_BURST */
-#define TOK_END_OF_BURST "EB"
-
-#define MSG_END_OF_BURST_ACK "EOB_ACK" /* END_OF_BURST_ACK */
-#define TOK_END_OF_BURST_ACK "EA"
-
-#define MSG_ERROR "ERROR" /* ERROR */
-#define TOK_ERROR "Y"
-
-#define MSG_GLINE "GLINE" /* GLINES */
-#define TOK_GLINE "GL"
-
-#define MSG_INFO "INFO" /* INFO */
-#define TOK_INFO "F"
-
-#define MSG_INVITE "INVITE" /* INVITE */
-#define TOK_INVITE "I"
-
-#define MSG_JOIN "JOIN" /* JOIN */
-#define TOK_JOIN "J"
-
-#define MSG_JUPE "JUPE" /* JUPE */
-#define TOK_JUPE "JU"
-
-#define MSG_KICK "KICK" /* KICK */
-#define TOK_KICK "K"
-
-#define MSG_KILL "KILL" /* KILL */
-#define TOK_KILL "D"
-
-#define MSG_LINKS "LINKS" /* LINKS */
-#define TOK_LINKS "LI"
-
-#define MSG_LUSERS "LUSERS" /* LUSERS */
-#define TOK_LUSERS "LU"
-
-#define MSG_MODE "MODE" /* MODE */
-#define TOK_MODE "M"
-
-#define MSG_MOTD "MOTD" /* MOTD */
-#define TOK_MOTD "MO"
-
-#define MSG_NAMES "NAMES" /* NAMES */
-#define TOK_NAMES "E"
-
-#define MSG_NICK "NICK" /* NICK */
-#define TOK_NICK "N"
-
-#define MSG_NOTICE "NOTICE" /* NOTICE */
-#define TOK_NOTICE "O"
-
-#define MSG_OPMODE "OPMODE" /* OPMODE */
-#define TOK_OPMODE "OM"
-
-#define MSG_PART "PART" /* PART */
-#define TOK_PART "L"
-
-#define MSG_PASS "PASS" /* PASS */
-#define TOK_PASS "PA"
-
-#define MSG_PING "PING" /* PING */
-#define TOK_PING "G"
-
-#define MSG_PONG "PONG" /* PONG */
-#define TOK_PONG "Z"
-
-#define MSG_PRIVATE "PRIVMSG" /* PRIVMSG */
-#define TOK_PRIVATE "P"
-
-#define MSG_PRIVS "PRIVS" /* PRIVS */
-#define TOK_PRIVS "PR"
-
-#define MSG_QUIT "QUIT" /* QUIT */
-#define TOK_QUIT "Q"
-
-#define MSG_REBURST "REBURST" /* REBURST */
-#define TOK_REBURST "RB"
-
-#define MSG_RPING "RPING" /* RPING */
-#define TOK_RPING "RI"
-
-#define MSG_RPONG "RPONG" /* RPONG */
-#define TOK_RPONG "RO"
-
-#define MSG_SERVER "SERVER" /* SERVER */
-#define TOK_SERVER "S"
-
-#define MSG_SETHOST "SETHOST" /* SETHOST */
-#define TOK_SETHOST "SH"
-
-#define MSG_SETTIME "SETTIME" /* SETTIME */
-#define TOK_SETTIME "SE"
-
-#define MSG_SILENCE "SILENCE" /* SILENCE */
-#define TOK_SILENCE "U"
-
-#define MSG_SQUIT "SQUIT" /* SQUIT */
-#define TOK_SQUIT "SQ"
-
-#define MSG_STATS "STATS" /* STATS */
-#define TOK_STATS "R"
-
-#define MSG_TIME "TIME" /* TIME */
-#define TOK_TIME "TI"
-
-#define MSG_TOPIC "TOPIC" /* TOPIC */
-#define TOK_TOPIC "T"
-
-#define MSG_TRACE "TRACE" /* TRACE */
-#define TOK_TRACE "TR"
-
-#define MSG_UPING "UPING" /* UPING */
-#define TOK_UPING "UP"
-
-#define MSG_VERSION "VERSION" /* VERSION */
-#define TOK_VERSION "V"
-
-#define MSG_WALLCHOPS "WALLCHOPS" /* WALLCHOPS */
-#define TOK_WALLCHOPS "WC"
-
-#define MSG_WALLOPS "WALLOPS" /* WALLOPS */
-#define TOK_WALLOPS "WA"
-
-#define MSG_WALLUSERS "WALLUSERS" /* WALLUSERS */
-#define TOK_WALLUSERS "WU"
-
-#define MSG_WALLVOICES "WALLVOICES" /* WALLVOICES */
-#define TOK_WALLVOICES "WV"
-
-#define MSG_WHOIS "WHOIS" /* WHOIS */
-#define TOK_WHOIS "W"
-
-#define MSG_WHOWAS "WHOWAS" /* WHOWAS */
-#define TOK_WHOWAS "X"
-
-#define MSG_XQUERY "XQUERY" /* XQUERY */
-#define TOK_XQUERY "XQ"
-
-#define MSG_XREPLY "XREPLY" /* XREPLY */
-#define TOK_XREPLY "XR"
-
-
-#endif
+++ /dev/null
-/* numeric.h */
-
-#ifndef __NUMERIC_H
-#define __NUMERIC_H
-
-/* TODO: this should be somewhere central */
-
-/* server reply numerics */
-
-#define RPL_TRACELINK 200
-#define RPL_TRACECONNECTING 201
-#define RPL_TRACEHANDSHAKE 202
-#define RPL_TRACEUNKNOWN 203
-#define RPL_TRACEOPERATOR 204
-#define RPL_TRACEUSER 205
-#define RPL_TRACESERVER 206
-#define RPL_TRACENEWTYPE 208
-#define RPL_TRACECLASS 209
-#define RPL_STATSCOMMANDS 212
-#define RPL_STATSPLINE 217
-#define RPL_ENDOFSTATS 219
-#define RPL_STATSFLINE 238
-#define RPL_STATSUPTIME 242
-#define RPL_STATSCONN 250
-#define RPL_ADMINME 256
-#define RPL_ADMINLOC1 257
-#define RPL_ADMINLOC2 258
-#define RPL_ADMINEMAIL 259
-#define RPL_TRACEEND 262
-#define RPL_PRIVS 270
-
-
-#define RPL_AWAY 301
-#define RPL_WHOISUSER 311
-#define RPL_WHOISSERVER 312
-#define RPL_WHOISOPERATOR 313
-#define RPL_WHOISIDLE 317
-#define RPL_ENDOFWHOIS 318
-#define RPL_WHOISCHANNELS 319
-#define RPL_WHOISACCOUNT 330
-#define RPL_WHOISACTUALLY 338
-#define RPL_WHOISOPERNAME 343
-#define RPL_VERSION 351
-#define RPL_LINKS 364
-#define RPL_ENDOFLINKS 365
-#define RPL_TIME 391
-
-
-
-#define ERR_NOSUCHNICK 401
-#define ERR_NOSUCHSERVER 402
-#define ERR_NOADMININFO 423
-#define ERR_NEEDMOREPARAMS 461
-
-#endif
/* privs.c */
#include "miscreply.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
-
-#include <string.h>
*/
int handleprivsmsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source nick */
- nick *tnick; /* struct nick for target nick */
-
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *privs = "IDDQD IDKFA IDCLIP IDDT IDCHOPPERS"; /* privileges */
+ nick *snick; /* struct nick for source nick */
+ nick *tnick; /* struct nick for target nick */
+ char *sourcenum = (char *)source; /* source user numeric */
+ char *targetnum; /* target user numeric */
+ char *privs = "IDDQD IDKFA IDCLIP IDDT IDCHOPPERS"; /* privileges */
/*
* cheat codes from DOOM I & II
/* get the parameter */
targetnum = cargv[0];
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
-
/* find source user */
if (!(snick = miscreply_finduser(sourcenum, "PRIVS")))
return CMD_OK;
return CMD_OK;
}
- /* get numeric of target's server */
- targetnum = longtonumeric(homeserver((tnick)->numeric), 2);
-
if (!IsOper(tnick))
privs = "";
* 270 RPL_PRIVS "source 270 target nick :privs"
* "irc.netsplit.net 270 foobar barfoo :CHAN_LIMIT SHOW_INVIS SHOW_ALL_INVIS KILL"
*/
- send_reply(targetnum, RPL_PRIVS, sourcenum, "%s :%s", tnick->nick, privs);
+ irc_send("%s 270 %s %s :%s", getmynumeric(), sourcenum, tnick->nick, privs);
return CMD_OK;
}
/* rping.c */
#include "miscreply.h"
-#include "msg.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
-#include "../server/server.h"
#include <stdio.h>
#include <string.h>
*
* cargv[0] = server
* server(mask) as given by user
- * a * indicates the request is for all servers (possible snircd extension)
+ * a * indicates the request is for all servers (future snircd extension?)
* cargv[1] = target server numeric
* cargv[2] = comment
*
* <start server numeric> RPING/RI <target server numeric> <requesting user numeric> <start seconds> <start milliseconds> :<comment>
*
* cargv[0] = target server numeric
- * can be a * in which case the request is for all servers (possible snircd extension)
+ * can be a * in which case the request is for all servers (future snircd extension?)
* cargv[1] = requesting user numeric
* cargv[2] = start time in seconds
* cargv[3] = start time in milliseconds
*/
int handlerpingmsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source (oper) nick */
-
- int i; /* index for serverlist[] */
- int m; /* result of myserver lookup */
- char *sourcenum = (char *)source; /* source numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *server; /* target server parameter */
- char *servername = myserver->content; /* servername */
- char *destserver; /* destination server mask */
- char *destnum; /* destination server numeric */
- char *sourceoper; /* requesting oper numeric */
- char *time_s; /* time in seconds */
- char *time_us; /* time in milliseconds */
- char *comment; /* comment by client */
- struct timeval tv; /* get start time in seconds and milliseconds */
+ nick *snick; /* struct nick for source nick */
+ long i; /* index for serverlist[] */
+ char *sourcenum = (char *)source; /* source numeric */
+ char *server; /* target server parameter */
+ char *destserver; /* destination server mask */
+ char *destnum; /* destination server numeric */
+ char *sourceoper; /* requesting operator numeric */
+ char *time_s; /* time in seconds */
+ char *time_us; /* time in milliseconds */
+ char *comment; /* comment by client */
+ struct timeval tv; /* get start time in seconds and milliseconds */
/* from server */
- if (IsServer(sourcenum)) {
+ if (strlen(sourcenum) == 2) {
/* check parameters */
if (cargc < 5) {
return CMD_OK;
}
- /* set the parameters */
+ /* get the parameters */
server = cargv[0];
sourceoper = cargv[1];
time_s = cargv[2];
if (!(snick = miscreply_finduser(sourceoper, "RPING")))
return CMD_OK;
- /* request is not for * (all servers) */
- if (!(server[0] == '*' && server[1] == '\0')) {
-
- /* destination server not found */
- if ((i = miscreply_findservernum(sourceoper, server, "RPING")) == -1)
- return CMD_OK;
-
- targetnum = longtonumeric(i, 2);
- servername = serverlist[i].name->content;
-
- /* not me, tell user */
- if (!IsMeNum(targetnum))
- send_snotice(sourceoper, "RPING: Server %s is not a real server.", servername);
- }
-
- /* send */
- irc_send("%s %s %s %s %s %s :%s", targetnum, TOK_RPONG, sourcenum,
+ /* send RPONG to operator */
+ irc_send("%s RO %s %s %s %s :%s", getmynumeric(), sourcenum,
sourceoper, time_s, time_us, comment);
}
/* from user */
- else if (IsUser(sourcenum)) {
+ else if (strlen(sourcenum) == 5) {
/* check parameters */
if (cargc < 3) {
return CMD_OK;
}
- /* set the parameters */
+ /* get the parameters */
destserver = cargv[0];
server = cargv[1];
comment = cargv[2];
else if ((i = miscreply_findservermatch(sourcenum, destserver)) == -1)
return CMD_OK;
- /* destination one of my servers? */
- else if ((m = miscreply_myserver(i))) {
- servername = serverlist[i].name->content;
-
- /* tell user, and return RPONG with delay 0 */
- if (m == 1)
- send_snotice(sourcenum, "RPING: Server %s is me.", servername);
- else
- send_snotice(sourcenum, "RPING: Server %s is not a real server.", servername);
- irc_send("%s %s %s %s 0 :%s", targetnum, TOK_RPONG, sourcenum, servername, comment);
+ /* destination is me
+ * do the same as ircu in this case, nothing
+ */
+ else if (i == mylongnum)
return CMD_OK;
- }
/* found valid destination server */
else
/* get starttime */
gettimeofday(&tv, NULL);
- /* send */
- irc_send("%s %s %s %s %lu %lu :%s", targetnum, TOK_RPING, destnum,
+ /* send RPING to server */
+ irc_send("%s RI %s %s %lu %lu :%s", getmynumeric(), destnum,
sourcenum, tv.tv_sec, tv.tv_usec, comment);
}
-
- /* trouble not from server and not from user numeric? */
- else {
- Error("miscreply", ERR_WARNING,
- "RPING from odd numeric source %s (not a server and not user numeric)", sourcenum);
- return CMD_OK;
- }
-
return CMD_OK;
}
/* rpong.c */
#include "miscreply.h"
-#include "msg.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
#include "../server/server.h"
#include <stdio.h>
-#include <string.h>
#include <sys/time.h>
*/
int handlerpongmsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source oper nick */
-
- int i; /* index for serverlist[] */
- char *sourcenum = (char *)source; /* source numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *server; /* target server parameter */
- char *servername = myserver->content; /* servername */
- char *sourceoper; /* requesting oper numeric */
- char *time_s; /* time in seconds */
- char *time_us; /* time in milliseconds */
- char *rping; /* ping returned to my client? */
- char *comment; /* comment by client */
- struct timeval tv; /* get time */
- static char ping[18]; /* elapsed time */
-
- /* not from server? */
- if (!IsServer(sourcenum))
- return CMD_OK;
+ nick *snick; /* struct nick for source oper nick */
+ long i; /* index for serverlist[] */
+ char *sourcenum = (char *)source; /* source numeric */
+ char *sourceoper; /* requesting operator numeric */
+ char *time_s; /* time in seconds */
+ char *time_us; /* time in milliseconds */
+ char *comment; /* comment by client */
+ char *servername; /* name of source server */
+ struct timeval tv; /* get time */
+ static char ping[18]; /* elapsed time */
/* check parameters */
if (cargc < 4) {
/* from pinged server to source server */
if (cargc > 4) {
- /* set the parameters */
- server = cargv[0];
+ /* get the parameters */
sourceoper = cargv[1];
time_s = cargv[2];
time_us = cargv[3];
comment = cargv[4];
/* find source server */
- if (miscreply_findserver(sourcenum, "RPING") == -1)
+ if ((i = miscreply_findserver(sourcenum, "RPING")) == -1)
return CMD_OK;
+ servername = serverlist[i].name->content;
/* find requesting oper */
if (!(snick = miscreply_finduser(sourceoper, "RPONG")))
return CMD_OK;
- /* find destination server */
- else if ((i = miscreply_findservermatch(sourceoper, server)) == -1)
- return CMD_OK;
-
- targetnum = longtonumeric(i, 2);
- servername = serverlist[i].name->content;
-
/* get time */
gettimeofday(&tv, NULL);
sprintf(ping, "%ld", (tv.tv_sec - atoi(time_s)) * 1000 + (tv.tv_usec - atoi(time_us)) / 1000);
/* send */
- irc_send("%s %s %s %s %s :%s", targetnum, TOK_RPONG, sourceoper,
+ irc_send("%s RO %s %s %s :%s", getmynumeric(), sourceoper,
servername, ping, comment);
}
- /* returned from source server to client */
- else {
-
- sourceoper = cargv[0];
- servername = cargv[1];
- rping = cargv[2];
- comment = cargv[3];
-
- /* should not happen, unless a client on my server sent RPING */
- Error("miscreply", ERR_WARNING,
- "RPONG returned from source server to client? %s RPONG %s %s %s :%s",
- sourcenum, sourceoper, servername, rping, comment);
- }
-
return CMD_OK;
}
/* stats.c */
#include "miscreply.h"
-#include "msg.h"
-#include "numeric.h"
#include "../lib/irc_string.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
#include <string.h>
#include <strings.h>
*/
int handlestatsmsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source nick */
-
- int i; /* index for serverlist[] */
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *statstype; /* stats paramenter */
- char *servernum; /* server numeric parameter */
- char *servername; /* servername */
+ nick *snick; /* struct nick for source nick */
+ char *sourcenum = (char *)source; /* source user numeric */
+ char *statstype; /* stats paramenter */
/* check parameters */
if (cargc < 2) {
/* get the parameters */
statstype = cargv[0];
- servernum = cargv[1];
-
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
/* find source user */
if (!(snick = miscreply_finduser(sourcenum, "STATS")))
return CMD_OK;
- /* not for me */
- if (!IsMeNum(servernum)) {
-
- /* find the server */
- if ((i = miscreply_findservernum(sourcenum, servernum, "STATS")) == -1)
- return CMD_OK;
-
- targetnum = longtonumeric(i, 2);
- servername = serverlist[i].name->content;
-
- /* tell user */
- send_snotice(sourcenum, "STATS: Server %s is not a real server.", servername);
-
- }
-
/* stats commands */
if (!strcmp(statstype, "m") || !strcasecmp(statstype, "commands")) {
- stats_commands(targetnum, sourcenum);
+ stats_commands(sourcenum);
}
/* stats features */
else if (!strcasecmp(statstype, "f") ||
- !strcasecmp(statstype, "features") || !strcasecmp(statstype, "features")) {
+ !strcasecmp(statstype, "features") || !strcasecmp(statstype, "featuresall")) {
/*
* 238 RPL_STATSFLINE "source 238 target F feature value"
* "irc.netsplit.net 217 foobar F HIDDEN_HOST users.quakenet.org"
*/
if (HIS_HIDDENHOST)
- send_reply(targetnum, RPL_STATSFLINE, sourcenum, "F HIDDEN_HOST %s", HIS_HIDDENHOST);
+ irc_send("%s 238 %s F HIDDEN_HOST %s", getmynumeric(), sourcenum, HIS_HIDDENHOST);
if (HIS_SERVERNAME)
- send_reply(targetnum, RPL_STATSFLINE, sourcenum, "F HIS_SERVERNAME %s", HIS_SERVERNAME);
+ irc_send("%s 238 %s F HIS_SERVERNAME %s", getmynumeric(), sourcenum, HIS_SERVERNAME);
if (HIS_SERVERDESC)
- send_reply(targetnum, RPL_STATSFLINE, sourcenum, "F HIS_SERVERINFO %s", HIS_SERVERDESC);
+ irc_send("%s 238 %s F HIS_SERVERINFO %s", getmynumeric(), sourcenum, HIS_SERVERDESC);
}
- /* stats ports */
+ /* stats ports
+ * NOTE: operserv uses this for lag check prior to sending out SETTIME
+ * as long as operserv is used, newserv must reply to STATS p
+ */
else if (!strcasecmp(statstype, "p") || !strcasecmp(statstype, "ports")) {
/*
* 217 RPL_STATSPLINE "source 217 target P port connection_count flags state"
* "irc.netsplit.net 217 foobar P 6667 10435 C active"
*/
- send_reply(targetnum, RPL_STATSPLINE, sourcenum, "P none 0 :0x2000");
+ irc_send("%s 217 %s P none 0 :0x2000", getmynumeric(), sourcenum);
}
* 242 RPL_STATSUPTIME "source 242 target :Server Up N days HH:NN:SS"
* "irc.netsplit.net 217 foobar :Server Up 0 days, 0:28:56"
*/
- send_reply(targetnum, RPL_STATSUPTIME, sourcenum, ":Server Up %s", longtoduration(time(NULL)-starttime, 0));
+ irc_send("%s 242 %s :Server Up %s", getmynumeric(), sourcenum, longtoduration(time(NULL)-starttime, 0));
/*
* 250 RPL_STATSCONN "source 250 target :Highest connection count: count (count_clients clients)"
* "irc.netsplit.net 250 foobar :Highest connection count: 25001 (25000 clients)"
*/
- send_reply(targetnum, RPL_STATSCONN, sourcenum, ":Highest connection count: 10 (9 clients)");
+ irc_send("%s 250 %s :Highest connection count: 10 (9 clients)", getmynumeric(), sourcenum);
}
/* tell user what stats we have */
else {
statstype = "*";
- send_snotice(sourcenum, "m (commands) - Message usage information.");
- send_snotice(sourcenum, "f (features) - Feature settings.");
- send_snotice(sourcenum, "p (ports) - Listening ports.");
- send_snotice(sourcenum, "u (uptime) - Current uptime & highest connection count.");
+ /* NOTICE/O */
+ irc_send("%s O %s :m (commands) - Message usage information.", getmynumeric(), sourcenum);
+ irc_send("%s O %s :f (features) - Feature settings.", getmynumeric(), sourcenum);
+ irc_send("%s O %s :p (ports) - Listening ports.", getmynumeric(), sourcenum);
+ irc_send("%s O %s :u (uptime) - Current uptime & highest connection count.", getmynumeric(), sourcenum);
}
* 219 RPL_ENDOFSTATS "source 219 target type :End of /STATS report"
* "irc.netsplit.net 391 foobar P :End of /STATS report"
*/
- send_reply(targetnum, RPL_ENDOFSTATS, sourcenum, "%s :End of /STATS report", statstype);
+ irc_send("%s 219 %s %s :End of /STATS report", getmynumeric(), sourcenum, statstype);
return CMD_OK;
}
/* time.c */
#include "miscreply.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
#include <stdio.h>
-#include <string.h>
* where the last part is the timezone offset
*
*/
-char *timelongdate(void)
-{
+static char *timelongdate(void) {
static char buf[64];
unsigned int off;
struct tm *tmp;
*/
int handletimemsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source nick */
-
- int i; /* index for serverlist[] */
- long unsigned int timestamp = getnettime(); /* current nettime */
- long unsigned int offset = timestamp - time(NULL); /* offset nettime to system clock */
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *servernum; /* server numeric parameter */
- char *servername = myserver->content; /* servername */
+ nick *snick; /* struct nick for source nick */
+ long unsigned int timestamp = getnettime(); /* current nettime */
+ long unsigned int offset = timestamp - time(NULL); /* offset nettime to system clock */
+ char *sourcenum = (char *)source; /* source user numeric */
/* check parameters */
if (cargc < 1) {
return CMD_OK;
}
- /* get the parameter */
- servernum = cargv[0];
-
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
-
/* find source user */
if (!(snick = miscreply_finduser(sourcenum, "TIME")))
return CMD_OK;
- /* request is not me and not for * (all servers) */
- if (!IsMeNum(servernum) && !(servernum[0] == '*' && servernum[1] == '\0')) {
-
- /* find the server */
- if ((i = miscreply_findservernum(sourcenum, servernum, "TIME")) == -1)
- return CMD_OK;
-
- targetnum = longtonumeric(i, 2);
- servername = serverlist[i].name->content;
-
- /* tell user */
- send_snotice(sourcenum, "TIME: Server %s is not a real server.", servername);
- }
-
/*
* 391 RPL_TIME "source 391 target servername timestamp offset :longdate"
* "irc.netsplit.net 391 foobar irc.netsplit.net 1269713493 0 :Saturday March 27 2010 -- 19:11 +01:00"
*/
- send_reply(targetnum, RPL_TIME, sourcenum, "%s %lu %lu :%s", servername, timestamp, offset, timelongdate());
+ irc_send("%s 391 %s %s %lu %ld :%s", getmynumeric(), sourcenum, myserver->content, timestamp, offset, timelongdate());
return CMD_OK;
}
/* trace.c */
#include "miscreply.h"
-#include "numeric.h"
#include "../core/error.h"
#include "../irc/irc.h"
#include "../lib/irc_string.h"
-#include "../nick/nick.h"
#include "../server/server.h"
#include <string.h>
-/* TODO: make server module keep state of link TS ? */
-/* TODO: make trace_server and trace_user function */
-/* TODO: trace link,
- * loop back from target server til we find ourself, send trace links along the way
+/* trace_user
+ *
*/
+static void trace_user(char *sourcenum, nick *tnick) {
+ if (IsOper(tnick)) {
+ /*
+ * 204 RPL_TRACEOPERATOR "source 204 target Oper class nick[user@IP] last_parse"
+ * "irc.netsplit.net 204 foobar Oper barfoo[fish@127.0.0.1] 0"
+ *
+ * note: no info available on how long ago we last parsed something from this user -> 0 (not idle time)
+ */
+ irc_send("%s 204 %s Oper opers %s[%s@%s] 0", getmynumeric(), sourcenum, tnick->nick,
+ tnick->ident[0] != '~' ? tnick->ident : "", IPtostr(tnick->p_ipaddr));
+ } else {
+ /*
+ * 205 RPL_TRACEUSER "source 205 target User class nick[user@IP] last_parse"
+ * "irc.netsplit.net 205 foobar User barfoo[fish@127.0.0.1] 0"
+ */
+ irc_send("%s 205 %s User users %s[%s@%s] 0", getmynumeric(), sourcenum, tnick->nick,
+ tnick->ident[0] != '~' ? tnick->ident : "", IPtostr(tnick->p_ipaddr));
+ }
+}
+
+
+
+/* trace_server
+ * return number of matched servers
+ */
+static int trace_server(char *sourcenum, char *target, int doall) {
+
+ /* do not show all and no match for my hub */
+ if (!doall && !match2strings(target, serverlist[myhub].name->content))
+ return 0;
+
+ /*
+ * 206 RPL_TRACESERVER "source 206 target Serv class NS NC server connected_by last_parse connected_for"
+ * "irc.netsplit.net 206 foobar Server 2S 6C irc.netsplit.net *!user@host 34 92988"
+ *
+ * note: no info available on how many servers or clients are linked through this server link -> 0S 0C
+ * no info available on who/what established the link, pretend it is by us -> *!*@myservername
+ * no info available on how long ago we last parsed something from this link -> 0
+ * no info available on how long this server has been linked -> 0
+ */
+ irc_send("%s 206 %s Serv servers 0S 0C %s *!*@%s 0 0", getmynumeric(), sourcenum,
+ serverlist[myhub].name->content, myserver->content);
+
+ return 1;
+}
+
+
/* handle remote trace request
*
*/
int handletracemsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source nick */
- nick *tnick; /* struct nick for target nick */
- nick **lnick; /* struct nick for looping local users */
+ nick *snick; /* struct nick for source nick */
+ nick *tnick; /* struct nick for target nick */
+ nick **lnick; /* struct nick for looping local users */
+ int c; /* loop variable */
+ int opers = 0; /* number of operators */
+ int users = 0; /* number of users */
+ int servers = 0; /* number of servers */
+ int doall, wilds, dow; /* determine what to show */
+ char *sourcenum = (char *)source; /* source user numeric */
+ char *target; /* target parameter - as given by the source user */
- int i; /* index for serverlist[] */
- int showall = 0; /* show all local server links */
- int opers = 0; /* number of opers */
- int users = 0; /* number of users */
- int servers = 0; /* number of servers */
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *target; /* target parameter - as given by the source user */
- char *servernum; /* destination server numeric parameter */
/* check parameters */
if (cargc < 2) {
/* get the parameters */
target = cargv[0];
- servernum = cargv[1];
-
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
/* find source user */
if (!(snick = miscreply_finduser(sourcenum, "TRACE")))
return CMD_OK;
- /* TODO: trace here down to target server first? */
-
- /* for me */
- if (IsMeNum(servernum)) {
-
- /* find target user */
- if ((tnick = getnickbynick(target))) {
-
- /* my user? */
- if (MyUser(tnick)) {
- if (IsOper(tnick)) {
- /*
- * 204 RPL_TRACEOPERATOR "source 204 target Oper class nick[user@IP] last_parse"
- * "irc.netsplit.net 204 foobar Oper barfoo[fish@127.0.0.1] 0"
- *
- * note: no info available on how long ago we last parsed something from this user -> 0 (not idle time)
- */
- send_reply(targetnum, RPL_TRACEOPERATOR, sourcenum, "Oper opers %s[%s@%s] 0", tnick->nick,
- tnick->ident[0] != '~' ? tnick->ident : "", IPtostr(tnick->p_ipaddr));
- } else {
- /*
- * 205 RPL_TRACEUSER "source 205 target User class nick[user@IP] last_parse"
- * "irc.netsplit.net 205 foobar User barfoo[fish@127.0.0.1] 0"
- */
- send_reply(targetnum, RPL_TRACEUSER, sourcenum, "User users %s[%s@%s] 0", tnick->nick,
- tnick->ident[0] != '~' ? tnick->ident : "", IPtostr(tnick->p_ipaddr));
- }
- }
- }
- else {
+ /* doall, wilds, dow */
+ doall = match2strings(target, myserver->content);
+ wilds = strchr(target, '*') || strchr(target, '?');
+ dow = wilds || doall;
- /* target is my server,
- * show all local server links
- */
- if (match2strings(target, myserver->content))
- showall = 1;
- /* go over all servers */
- for (i = 0; i < MAXSERVERS; i++) {
- if (serverlist[i].maxusernum == 0) /* not linked */
+ /* find target user */
+ if ((tnick = getnickbynick(target))) {
+
+ /* my user */
+ if (mylongnum == homeserver(tnick->numeric))
+ trace_user(sourcenum, tnick);
+ }
+
+
+ /* source user is an operator */
+ else if (IsOper(snick)) {
+
+ /* show servers */
+ servers = trace_server(sourcenum, target, doall);
+
+ /* do all or wilds */
+ if (dow) {
+
+ /* loop over all local users */
+ lnick = servernicks[mylongnum];
+ for (c = 0; c < serverlist[mylongnum].maxusernum; c++) {
+
+ if (lnick[c] == NULL) /* no user */
continue;
- if (!IsMeLong(serverlist[i].parent) && i != myhub) /* not my server and not my hub */
+
+ /* target is invisible (mode +i), target is not an operator */
+ if (IsInvisible(lnick[c]) && dow && !IsOper(lnick[c]))
continue;
- servers++;
- if (!showall && !match2strings(target, serverlist[i].name->content)) /* do not show all and no match */
+
+ /* dont show all, do wildcards and no match */
+ if (!doall && wilds && !match2strings(target, lnick[c]->nick))
continue;
- /*
- * 206 RPL_TRACESERVER "source 206 target Serv class NS NC server connected_by last_parse connected_for"
- * "irc.netsplit.net 206 foobar Server 2S 6C irc.netsplit.net *!user@host 34 92988"
- *
- * note: no info available on how many servers or clients are linked through this server link -> 0S 0C
- * no info available on who/what established the link, pretend it is by us -> *!*@myservername
- * no info available on how long ago we last parsed something from this link -> 0
- * no info available on how long this server has been linked -> 0
- */
- send_reply(targetnum, RPL_TRACESERVER, sourcenum, "Serv servers 0S 0C %s *!*@%s 0 0",
- serverlist[i].name->content, myserver->content);
- }
- /* show my users, show class total */
- if (showall) {
-
- /* loop over all local users */
- lnick = servernicks[mylongnum];
- for (i = 0; i < MAXLOCALUSER; i++) {
-
- if (lnick[i] == NULL) /* no user */
- continue;
-
- if (!match2strings(target, lnick[i]->nick)) /* no match */
- continue;
-
- if (IsOper(lnick[i])) {
- opers++;
- /* 204 RPL_TRACEOPERATOR see above */
- send_reply(targetnum, RPL_TRACEOPERATOR, sourcenum, "Oper opers %s[%s@%s] 0", lnick[i]->nick,
- lnick[i]->ident[0] != '~' ? lnick[i]->ident : "", IPtostr(lnick[i]->p_ipaddr));
- } else {
- users++;
- /* TODO: perhaps do show +k and/or +X clients? */
- /* ircd does not show all local users in remote trace - might be too many users with trojan scan / nickjupes? */
- continue;
- /* 205 RPL_TRACEUSER see above */
- send_reply(targetnum, RPL_TRACEUSER, sourcenum, "User users %s[%s@%s] 0", lnick[i]->nick,
- lnick[i]->ident[0] != '~' ? lnick[i]->ident : "", IPtostr(lnick[i]->p_ipaddr));
- }
- }
- /*
- * class has no meaning here,
- * but showing the total count for users/opers/servers might be useful anyway
- *
- * 209 RPL_TRACECLASS "source 209 target Class class count"
- * "irc.netsplit.net 209 foobar Class users 2"
- */
- if (users)
- send_reply(targetnum, RPL_TRACECLASS, sourcenum, "Class users %d", users);
- if (opers)
- send_reply(targetnum, RPL_TRACECLASS, sourcenum, "Class opers %d", opers);
- /* should always be true - we are connected so at least 1 local server link */
- if (servers)
- send_reply(targetnum, RPL_TRACECLASS, sourcenum, "Class servers %d", servers);
+ if (IsOper(lnick[c]))
+ opers++;
+ else
+ users++;
+ trace_user(sourcenum, lnick[c]);
}
+ /*
+ * class has no meaning here,
+ * but showing the total count for users/opers/servers might be useful anyway
+ *
+ * 209 RPL_TRACECLASS "source 209 target Class class count"
+ * "irc.netsplit.net 209 foobar Class users 2"
+ */
+ if (users)
+ irc_send("%s 209 %s Class users %d", getmynumeric(), sourcenum, users);
+ if (opers)
+ irc_send("%s 209 %s Class opers %d", getmynumeric(), sourcenum, opers);
+ if (servers)
+ irc_send("%s 209 %s Class servers %d", getmynumeric(), sourcenum, servers);
}
}
+
/*
* 262 RPL_TRACEEND "source 262 target :End of TRACE"
* "irc.netsplit.net 262 foobar :End of TRACE"
*/
- send_reply(targetnum, RPL_TRACEEND, sourcenum, ":End of TRACE");
+ irc_send("%s 262 %s :End of TRACE", getmynumeric(), sourcenum);
return CMD_OK;
}
/* version.c */
#include "miscreply.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
-#include "../nick/nick.h"
-#include <string.h>
-
-/* TODO: grab version info from conf or elsewhere */
-/* TODO: grab configuration string from elsewhere? */
-
/* handle remote version request
*
* <source numeric> VERSION/V <target server numeric>
*/
int handleversionmsg(void *source, int cargc, char **cargv) {
- nick *snick; /* struct nick for source nick */
-
- int i; /* index for serverlist[] */
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *servernum; /* server numeric parameter */
- char *servername = myserver->content; /* servername */
- char *version = "newserv2.10.12."; /* version */
- char *info = "B0HM6"; /* configuration string */
+ nick *snick; /* struct nick for source nick */
+ char *sourcenum = (char *)source; /* source user numeric */
/* check parameters */
if (cargc < 1) {
return CMD_OK;
}
- /* get the parameter */
- servernum = cargv[0];
-
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
-
/* find source user */
if (!(snick = miscreply_finduser(sourcenum, "VERSION")))
return CMD_OK;
- /* request is not for me and not for * (all servers) */
- if (!IsMeNum(servernum) && !(servernum[0] == '*' && servernum[1] == '\0')) {
-
- /* find the server */
- if ((i = miscreply_findservernum(sourcenum, servernum, "VERSION")) == -1)
- return CMD_OK;
-
- targetnum = longtonumeric(i, 2);
- servername = serverlist[i].name->content;
-
- /* tell user */
- send_snotice(sourcenum, "VERSION: Server %s is not a real server.", servername);
- }
-
/*
* 351 RPL_VERSION "source 351 target version server :info"
- * "irc.netsplit.net 351 foobar u2.10.12.12+snircd(1.3.4a). irc.netsplit.net :B128AHMU6"
+ * "irc.netsplit.net 351 foobar u2.10.12.12+snircd(1.3.4a). irc.netsplit.net :B96ADHMRU6"
*/
- send_reply(targetnum, RPL_VERSION, sourcenum, "%s %s :%s", version, servername, info);
+ irc_send("%s 351 %s newserv%s %s :Newserv IRC Service", getmynumeric(), sourcenum, MISCREPLY_VERSION, myserver->content);
return CMD_OK;
}
/* whois.c */
#include "miscreply.h"
-#include "msg.h"
-#include "numeric.h"
#include "../irc/irc.h"
#include "../core/error.h"
#include "../core/hooks.h"
-#include "../nick/nick.h"
+#include "../server/server.h"
#include <string.h>
-/* handle remote whois request
- *
- * <source numeric> WHOIS/W <target server numeric> <nick>
- *
- * cargv[0] = target server numeric
- * cargv[1] = nick as given by source
- * comma separated list of one or more nicks, may contain wildcards
- * multiple nicks and wildcards currently not supported here
+/* do whois
*
*/
-int handlewhoismsg(void *source, int cargc, char **cargv) {
+static void do_whois(char *sourcenum, nick *snick, nick *tnick) {
+
+ void *nicks[3]; /* nick array for whois channels hook */
- nick *snick; /* struct nick for source nick */
- nick *tnick; /* struct nick for target nick */
- nick *nicks[2]; /* struct nick for whois channels trigger */
- char *sourcenum = (char *)source; /* source user numeric */
- char *targetnum = getmynumeric(); /* target server numeric */
- char *servernum; /* server numeric parameter */
- char *nick; /* nick parameter */
+ /* user
+ *
+ * 311 RPL_WHOISUSER "source 311 target nick user host * :realname"
+ * "irc.netsplit.net 311 foobar bar foo host.com * :foobar"
+ */
+ /* sethost (usermode +h) */
+ if (IsSetHost(tnick)) {
+ irc_send("%s 311 %s %s %s %s * :%s", getmynumeric(), sourcenum, tnick->nick,
+ tnick->shident->content, tnick->sethost->content, tnick->realname->name->content);
+ /* account and hiddenhost (usermode +rx) */
+ } else if (IsAccount(tnick) && IsHideHost(tnick)) {
+ irc_send("%s 311 %s %s %s %s.%s * :%s", getmynumeric(), sourcenum, tnick->nick,
+ tnick->ident, tnick->authname, HIS_HIDDENHOST, tnick->realname->name->content);
+ /* not hidden */
+ } else {
+ irc_send("%s 311 %s %s %s %s * :%s", getmynumeric(), sourcenum, tnick->nick,
+ tnick->ident, tnick->host->name->content, tnick->realname->name->content);
+ }
- /* check parameters */
- if (cargc < 2) {
- miscreply_needmoreparams(sourcenum, "WHOIS");
- return CMD_OK;
+ /* channels
+ * show channels only when
+ * target user is not a service (usermode +k) AND
+ * target user is not hidechan (usermode +n)
+ * OR user WHOIS'ing himself
+ */
+ if ((!IsService(tnick) && !IsHideChan(tnick)) || snick == tnick) {
+ nicks[0] = (char *)snick;
+ nicks[1] = (char *)tnick;
+ nicks[2] = sourcenum;
+ triggerhook(HOOK_NICK_WHOISCHANNELS, nicks);
}
- /* get the parameters */
- servernum = cargv[0];
- nick = cargv[1];
- /* request not for my server
+ /* server
*
- * if newserv can have clients on its downlinks,
- * this will need to be changed,
- * else remote whois on those users wont work
+ * 312 RPL_WHOISSERVER "source 312 target nick server :description"
+ * "irc.netsplit.net 312 foobar barfoo *.netsplit.net :Netsplit Server"
*/
- if (!IsMeNum(servernum))
- return CMD_OK;
-
- /* from a server? */
- if (IsServer(sourcenum))
- return CMD_OK;
+ /* show server and description when
+ * user WHOIS'ing himself, OR to an IRC Operator, OR when HIS_SERVER is 0
+ */
+ if (snick == tnick || IsOper(snick) || !HIS_SERVER) {
+ irc_send("%s 312 %s %s %s :%s", getmynumeric(), sourcenum, tnick->nick,
+ serverlist[homeserver(tnick->numeric)].name->content,
+ serverlist[homeserver(tnick->numeric)].description->content);
+ /* show HIS server and description */
+ } else {
+ irc_send("%s 312 %s %s %s :%s", getmynumeric(), sourcenum, tnick->nick,
+ HIS_SERVERNAME,
+ HIS_SERVERDESC);
+ }
- /* find source user */
- if (!(snick = miscreply_finduser(sourcenum, "WHOIS")))
- return CMD_OK;
- /* find the target */
- if (!(tnick = getnickbynick(nick))) {
- /*
- * 401 ERR_NOSUCHNICK "source 401 target nick :No such nick"
- * "irc.netsplit.net 391 foobar barfoo :No such nick"
+ /* target user is away */
+ if ((tnick)->away) {
+ /*
+ * 301 RPL_AWAY "source 301 target nick :awaymsg"
+ * "irc.netsplit.net 301 foobar barfoo :afk."
*/
- send_reply(targetnum, ERR_NOSUCHNICK, sourcenum, "%s :No such nick", nick);
-
- } else {
+ irc_send("%s 301 %s %s :%s", getmynumeric(), sourcenum, tnick->nick, tnick->away->content);
+ }
- /* user
- *
- * 311 RPL_WHOISUSER "source 311 target nick user host * :realname"
- * "irc.netsplit.net 311 foobar bar foo host.com * :foobar"
+ /* target user is an IRC Operator */
+ if (IsOper(tnick)) {
+ /*
+ * 313 RPL_WHOISOPERATOR "source 313 target nick :is an IRC Operator"
+ * "irc.netsplit.net 313 foobar barfoo :is an IRC Operator"
*/
- /* sethost (mode +h) */
- if (IsSetHost(tnick)) {
- send_reply(targetnum, RPL_WHOISUSER, sourcenum, "%s %s %s * :%s", tnick->nick,
- tnick->shident->content, tnick->sethost->content, tnick->realname->name->content);
- /* account and hiddenhost (mode +rx) */
- } else if (HasHiddenHost(tnick)) {
- send_reply(targetnum, RPL_WHOISUSER, sourcenum, "%s %s %s.%s * :%s", tnick->nick,
- tnick->ident, tnick->authname, HIS_HIDDENHOST, tnick->realname->name->content);
- /* not hidden */
- } else {
- send_reply(targetnum, RPL_WHOISUSER, sourcenum, "%s %s %s * :%s", tnick->nick,
- tnick->ident, tnick->host->name->content, tnick->realname->name->content);
- }
+ irc_send("%s 313 %s %s :is an IRC Operator", getmynumeric(), sourcenum, tnick->nick);
+ /* source user is an IRC Operator, show opername if we have it */
+ if (IsOper(snick) && (tnick->opername && strcmp(tnick->opername->content, "-")))
+ /*
+ * 343 RPL_WHOISOPERNAME "source 343 target nick opername :is opered as"
+ * "irc.netsplit.net 343 foobar barfoo fish :is opered as"
+ *
+ * note: snircd extension
+ */
+ irc_send("%s 343 %s %s %s :is opered as", getmynumeric(), sourcenum, tnick->nick, tnick->opername->content);
+ }
- /* TODO: these checks are in handlewhoischannels in channel/channelhandlers.c also .. */
- /* TODO: move whois channels here? */
- /* channels
- * show channels only when
- * target user is not a service (mode +k) AND
- * target user is not hidechan (mode +n)
- * OR user WHOIS'ing himself
- */
- if ((!IsService(tnick) && !IsHideChan(tnick)) || snick == tnick) {
- nicks[0] = snick;
- nicks[1] = tnick;
- triggerhook(HOOK_NICK_WHOISCHANNELS, nicks);
- }
- /* server
+ /* target user got an account (usermode +r) */
+ if (IsAccount(tnick)) {
+ /*
+ * 330 RPL_WHOISACCOUNT "source 330 target nick account :is authed as"
+ * "irc.netsplit.net 330 foobar barfoo fish :is authed as"
*
- * 312 RPL_WHOISSERVER "source 312 target nick server :description"
- * "irc.netsplit.net 312 foobar barfoo *.netsplit.net :Netsplit Server"
- */
- /* show server and description when
- * user WHOIS'ing himself, OR to an operator, OR when HIS_SERVER is not set
+ * note: ircu shows "is logged in as" as text
*/
- if (snick == tnick || IsOper(snick) || !HIS_SERVER) {
- send_reply(targetnum, RPL_WHOISSERVER, sourcenum, "%s %s :%s", tnick->nick,
- serverlist[homeserver(tnick->numeric)].name->content,
- serverlist[homeserver(tnick->numeric)].description->content);
- /* show HIS server and description */
- } else {
- send_reply(targetnum, RPL_WHOISSERVER, sourcenum, "%s %s :%s", tnick->nick,
- HIS_SERVERNAME,
- HIS_SERVERDESC);
- }
-
+ irc_send("%s 330 %s %s %s :is authed as", getmynumeric(), sourcenum, tnick->nick, tnick->authname);
+ }
- /* target user is away */
- if (IsAway(tnick)) {
- /*
- * 301 RPL_AWAY "source 301 target nick :awaymsg"
- * "irc.netsplit.net 301 foobar barfoo :afk."
- */
- send_reply(targetnum, RPL_AWAY, sourcenum, "%s :%s", tnick->nick, tnick->away->content);
- }
- /* target user is an operator */
- if (IsOper(tnick)) {
- /*
- * 313 RPL_WHOISOPERATOR "source 313 target nick :is an IRC Operator"
- * "irc.netsplit.net 313 foobar barfoo :is an IRC Operator"
- */
- send_reply(targetnum, RPL_WHOISOPERATOR, sourcenum, "%s :is an IRC Operator", tnick->nick);
-
- /* source user is an operator, show opername if we have it */
- if (IsOper(snick) && HasOperName(tnick))
- /*
- * 343 RPL_WHOISOPERNAME "source 343 target nick opername :is opered as"
- * "irc.netsplit.net 343 foobar barfoo fish :is opered as"
- *
- * note: snircd extension
- */
- send_reply(targetnum, RPL_WHOISOPERNAME, sourcenum, "%s %s :is opered as", tnick->nick, tnick->opername->content);
- }
+ /* target user got a sethost (usermode +h) or has a hiddenhost (usermode +rx)
+ * show real host to user WHOIS'ing himself and to an IRC Operator
+ */
+ if ((snick == tnick || IsOper(snick)) && (IsSetHost(tnick) || (IsAccount(tnick) && IsHideHost(tnick)) )) {
+ /*
+ * 338 RPL_WHOISACTUALLY "source 338 target nick user@host IP :Actual user@host, Actual IP"
+ * "irc.netsplit.net 338 foobar barfoo foobar@localhost 127.0.0.1 :Actual user@host, Actual IP"
+ */
+ irc_send("%s 338 %s %s %s@%s %s :Actual user@host, Actual IP", getmynumeric(), sourcenum, tnick->nick,
+ tnick->ident, tnick->host->name->content, IPtostr(tnick->p_ipaddr));
+ }
- /* target user got an account (mode +r) */
- if (IsAccount(tnick)) {
- /*
- * 330 RPL_WHOISACCOUNT "source 330 target nick account :is authed as"
- * "irc.netsplit.net 330 foobar barfoo fish :is authed as"
- *
- * note: ircu shows "is logged in as" as text
- */
- send_reply(targetnum, RPL_WHOISACCOUNT, sourcenum, "%s %s :is authed as", tnick->nick, tnick->authname);
- }
+ /* my user,
+ * AND not a service (usermode +k), AND not hiding idle time (usermode +I)
+ * show idle and signon time
+ */
+ if (mylongnum == homeserver(tnick->numeric) && !IsService(tnick) && !IsHideIdle(tnick)) {
+ /*
+ * 317 RPL_WHOISIDLE "source 317 target nick idle signon :seconds idle, signon time"
+ * "irc.netsplit.net 317 foobar barfoo 5 1084458353"
+ */
+ irc_send("%s 317 %s %s %ld %ld :seconds idle, signon time", getmynumeric(), sourcenum, tnick->nick,
+ (getnettime() - tnick->timestamp) % (((tnick->numeric + tnick->timestamp) % 983) + 7), tnick->timestamp);
+ }
+}
- /* target user got a sethost (mode +h) or has a hiddenhost (mode +rx)
- * show real host to user WHOIS'ing himself and to an operator
- */
- if ((snick == tnick || IsOper(snick)) && (IsSetHost(tnick) || HasHiddenHost(tnick))) {
- /*
- * 338 RPL_WHOISACTUALLY "source 338 target nick user@host IP :Actual user@host, Actual IP"
- * "irc.netsplit.net 338 foobar barfoo foobar@localhost 127.0.0.1 :Actual user@host, Actual IP"
- */
- send_reply(targetnum, RPL_WHOISACTUALLY, sourcenum, "%s %s@%s %s :Actual user@host, Actual IP", tnick->nick,
- tnick->ident, tnick->host->name->content, IPtostr(tnick->p_ipaddr));
- }
+/* handle remote whois request
+ *
+ * <source numeric> WHOIS/W <target server numeric> <nick>
+ *
+ * cargv[0] = target server numeric
+ * cargv[1] = nick as given by source
+ * comma separated list of one or more nicks, may contain wildcards
+ * ircu does not do wildcard matches for remote whois, we dont either
+ *
+ */
+int handlewhoismsg(void *source, int cargc, char **cargv) {
+ nick *snick; /* struct nick for source nick */
+ nick *tnick; /* struct nick for target nick */
+ char *sourcenum = (char *)source; /* source user numeric */
+ char nicks[BUFSIZE]; /* nick parameter */
+ char *nick; /* loop nick */
+ /* check parameters */
+ if (cargc < 2) {
+ miscreply_needmoreparams(sourcenum, "WHOIS");
+ return CMD_OK;
+ }
- /* target user is paranoid */
- if (IsParanoid(tnick) && !IsOper(snick) && snick != tnick) {
- send_snotice(longtonumeric(tnick->numeric, 5), "whois: %s performed a /WHOIS on you.", snick->nick);
- }
+ /* get the parameters */
+ strcpy(nicks, cargv[1]);
+ /* find source user */
+ if (!(snick = miscreply_finduser(sourcenum, "WHOIS")))
+ return CMD_OK;
+ /* go through the list of nicks */
+ for (nick = strtok(nicks, ","); nick != NULL; nick = strtok(NULL, ",")) {
- /* target user is myuser, AND not a service (mode +k), AND not hiding idle time (mode +I)
- * show idle and signon time
- */
- if (MyUser(tnick) && !IsService(tnick) && !IsHideIdle(tnick)) {
- /*
- * 317 RPL_WHOISIDLE "source 317 target nick idle signon :seconds idle, signon time"
- * "irc.netsplit.net 317 foobar barfoo 5 1084458353"
+ /* find the target */
+ if (!(tnick = getnickbynick(nick))) {
+ /*
+ * 401 ERR_NOSUCHNICK "source 401 target nick :No such nick"
+ * "irc.netsplit.net 391 foobar barfoo :No such nick"
*/
- send_reply(targetnum, RPL_WHOISIDLE, sourcenum, "%s %ld %ld :seconds idle, signon time", tnick->nick,
- (getnettime() - tnick->timestamp) % (((tnick->numeric + tnick->timestamp) % 983) + 7), tnick->timestamp);
+ irc_send("%s 401 %s %s :No such nick", getmynumeric(), sourcenum, nick);
}
+
+ else
+ do_whois(sourcenum, snick, tnick);
}
* 318 RPL_ENDOFWHOIS "source 318 target nick :End of /WHOIS list."
* "irc.netsplit.net 318 foobar barfoo :End of /WHOIS list."
*/
- send_reply(targetnum, RPL_ENDOFWHOIS, sourcenum, "%s :End of /WHOIS list.", nick);
+ irc_send("%s 318 %s %s :End of /WHOIS list.", getmynumeric(), sourcenum, cargv[1]);
return CMD_OK;
}