rendered paste body/* Main processing code for Services.
* Auspice Services is copyright (c) 2000-2001 In Mean.
* E-mail: <inmean@auspice.org>
*
* SirvNET Services is copyright (c) 1998-2000 Trevor Klingbeil.
* E-mail: <priority1@dal.net>
* Originally based on EsperNet Services(c) by Andy Church.
* This program is free but copyrighted software; see the file LICENSE for
* details.
*/
#include "../inc/services.h"
#include "version.h"
char **textinfo2 = giveinfo;
char **textcred = givecredit;
void m_info(char *source, int ac, char **av);
void m_credits(char *source, int ac, char **av);
void m_realcredits(const char *source);
void m_realinfo(const char *source);
/*************************************************************************/
/* Response to the VERSION message. */
void m_version(char *source, int ac, char **av)
{
User *u = finduser(source);
int isn = nofork + debug;
char buf2[512];
send_cmd(server_name, "351 %s Running Auspice%s%s. %s :%s%s%s %s [%s]",
source, version_number, version_dec, server_name, debug?"D":"", nofork?"N":"",
isn?"":"Normal", version_build, IRCD);
strscpy(buf2, "", sizeof(buf2));
#ifdef DEFHALFOP
strcat(buf2, "HALFOP");
#endif
#ifdef DEFPROTECT
strcat(buf2, " PROTECT");
#endif
#ifdef DEFHOSTSERV
strcat(buf2, " HOSTSERV");
#endif
#ifdef SVSJOIN
strcat(buf2, " SVSJOIN=");
strcat(buf2, SVSJOIN);
#endif
#ifdef ALLOWUMODE
strcat(buf2, " UMODE=");
strcat(buf2, ALLOWUMODE);
#endif
#ifdef BOTMODE
strcat(buf2, " BOTMODE=");
strcat(buf2, BOTMODE);
#endif
#ifdef ALLOW_GLINE
strcat(buf2, " GLINE");
#endif
#ifdef CYGWIN
strcat(buf2, " WIN32");
#endif
send_cmd(server_name, "351 %s %s \2Using\2: %s ", source, server_name, buf2);
if (u)
do_update_flood(u, 1);
}
/*************************************************************************/
void m_sendmotd(const char *source)
{
int tmpnow;
tmpnow = time(NULL) - start_time;
send_cmd (server_name, "372 %s :***** \2\37Services Info\37\2 *****",source);
send_cmd (server_name, "372 %s :Welcome to %s IRC Network", source, NETWORK_NAME);
send_cmd (server_name, "372 %s :%s Running Auspice%s\2(%s)\2
%s",source, server_name, version_number, version_dec,
version_build);
send_cmd (server_name, "372 %s :Services On-Line %d day%s, %d:%02d:%02d ", source,
tmpnow/86400, (tmpnow/86400 == 1) ? "" : "s", (tmpnow/3600)%24, (tmpnow/60)%60, tmpnow%60);
send_cmd (server_name, "372 %s :Default Services help channel is: \2%s\2", source, tokn[17]);
send_cmd (server_name, "372 %s :Type \2/MOTD %s\2 for Password Admin.", source, server_name);
send_cmd (server_name, "372 %s :Type \2/Msg HelpServ CREDITS\2 for Credits peoples", source);
send_cmd (server_name, "372 %s :***** \2End Services Info\2 *****", source);
}
/*************************************************************************/
void m_smartinfo(const char *source)
{
int tmpnow;
long count, mem;
tmpnow = time(NULL) - start_time;
notice(s_Agent, source, "***** \2Services Report\2 *****");
notice(s_Agent, source, "===============");
notice(s_Agent, source, "Services Version: Auspice%s%s",
version_number, version_dec);
notice(s_Agent, source, "Services On-Line: %d day%s, %d:%02d:%02d", tmpnow/86400, (tmpnow/86400 == 1) ? "" : "s",
(tmpnow/3600)%24, (tmpnow/60)%60, tmpnow%60);
notice(s_Agent, source, "Current User : %d (%d ops); maximum %d", usercnt, opcnt, maxusercnt);
notice(s_Agent, source, "Channels : %d", channel_form());
get_nickserv_stats(&count, &mem);
notice(s_Agent, source, "Registered Nicks: %d", count);
get_chanserv_stats(&count, &mem);
notice(s_Agent, source, "Registered Chans: %d", count);
notice(s_Agent, source, "Total Connect in: %li", connectscnt);
notice(s_Agent, source, "Total akill mask: %d", nakill);
notice(s_Agent, source, "There are \2%d\2 servers linked.", numserver);
notice(s_Agent, source, "***** \2End Report\2 *****");
}
/*************************************************************************/
void make_netstats_html(void)
{
FILE *fp;
int tmpnow;
long count, mem, count2, mem2;
tmpnow = time(NULL) - start_time;
if (ishtml == 0)
return;
fp = fopen(netstats_path, "w");
if (fp) {
get_nickserv_stats(&count, &mem);
get_chanserv_stats(&count2, &mem2);
fprintf (fp, "<h1>Network Statistic</h1>\n");
fprintf (fp, "<p>Services Version: <B>Auspice</B>%s%s<br>",
version_number,version_dec);
fprintf (fp, "Services On-Line: %d day%s, %d:%02d:%02d<br>", tmpnow/86400,
(tmpnow/86400 == 1) ? "" : "s", (tmpnow/3600)%24, (tmpnow/60)%60, tmpnow%60);
fprintf (fp, "Current User : %d (%d ops); maximum %d<br>", usercnt, opcnt, maxusercnt);
fprintf (fp, "There are <B> %d </B> channels form<br>", channel_form());
fprintf (fp, "Total Connect in: %li<br>", connectscnt);
fprintf (fp, "There are <B>%d</B> servers linked.</p>", numserver);
fprintf (fp, "<p>Registered Nicks: %lu<br>", count);
fprintf (fp, "Registered Chans: %lu<br>", count2);
fclose (fp);
}
}
/*************************************************************************/
/* Response Admin message */
void m_admin(char *source, int ac, char **av)
{
if (source) {
send_cmd(server_name, "256 %s :Administrative info about %s", source, server_name);
send_cmd(server_name, "257 %s :Admin Name: %s", source, tokn[27]);
send_cmd(server_name, "258 %s :Admin Nick: %s", source, SERVICES_MASTER);
send_cmd(server_name, "259 %s :Admin Email: %s", source, tokn[28]);
}
}
/*************************************************************************/
void m_info(char *source, int ac, char **av)
{
m_realinfo(source);
}
/*************************************************************************/
void m_realinfo(const char *source)
{
struct tm tm;
char timebuf[64];
char **textinfo = textinfo2;
tm = *localtime(&start_time);
strftime(timebuf, sizeof(timebuf), "%b %d %Y at %H:%M:%S %Z", &tm);
timebuf[sizeof(timebuf)-1] = 0;
send_cmd (server_name, "373 %s :Auspice IRC Services %s%s", source,
version_number, version_dec);
while (*textinfo) {
send_cmd (server_name, "371 %s :%s", source, *textinfo++);
}
send_cmd (server_name, "371 %s :Auspice services %s", source,
version_number);
send_cmd (server_name, "371 %s :Birth Date: %s, compile # %s", source, timebuf, version_build);
send_cmd (server_name, "371 %s :On-line since %s", source, ctime (&start_time));
send_cmd (server_name, "374 %s :End of /INFO list.", source);
}
/*************************************************************************/
void m_realcredits(const char *source)
{
struct tm tm;
char timebuf[64];
char **text = textcred;
tm = *localtime(&start_time);
strftime(timebuf, sizeof(timebuf), "%b %d %Y at %H:%M:%S %Z", &tm);
timebuf[sizeof(timebuf)-1] = 0;
while (*text) {
send_cmd (server_name, "371 %s :%s", source, *text++);
}
send_cmd (server_name, "371 %s :Auspice services %s%s", source,
version_number, version_dec);
send_cmd (server_name, "371 %s :Birth Date: %s, compile # %s", source, timebuf, version_build);
send_cmd (server_name, "371 %s :On-line since %s", source, ctime (&start_time));
send_cmd (server_name, "374 %s :End of /CREDITS list.", source);
}
/*************************************************************************/
void m_credits(char *source, int ac, char **av)
{
m_realcredits(source);
}
/***********************************************************************/
void do_version(const char *source)
{
notice(s_OperServ, source, "Version: %s%s", version_number, version_dec);
notice(s_OperServ, source, "Build: %s", version_build);
notice(s_OperServ, source, "DataBase Version: \2%d\2", FILE_VERSION);
notice(s_OperServ, source, "Coder(s): \2Auspice\2");
notice(s_OperServ, source, "Auspice Services copyright (c) 2000-2002 In Mean.");
notice(s_OperServ, source, "\2END OF VERSION\2");
}
/***********************************************************************/
/* Channel to suspend (hashed by first character of chan). */
C_SuspendData *c_suspend[256];
/*************************************************************************/
/* Updates flood levels of a user. If exceeds max, warn, if continues,
kill user */
int do_update_flood(User *u, unsigned short idflood)
{
time_t now = CTime;
if (u->flood_time < now) {
u->flood_time = now + F_RESET;
u->floodlev = 0;
} else if (u->flood_time > now) {
u->flood_time = now + F_RESET;
u->floodlev += 1;
}
if (idflood == 2)
u->motd += 1;
else if (idflood == 1)
u->version += 1;
if ((u->motd == 30) || (u->version == 30)
|| (u->motd == 50) || (u->version == 50)) {
wallops(SERVER_NAME, "WARNING: User %s!%s@%s has been found "
"sending atleast %d %s requests to services",
u->nick, u->username, u->host,
u->motd == 30 ? u->motd : u->version,
u->motd == 30 ? "MOTD" : "VERSION");
notice(s_GlobalNoticer, u->nick,
"You have been constantly flooding services with %s "
"requests. Please stop immediately.",
u->motd == 30 ? "MOTD" : "VERSION");
notice(s_GlobalNoticer, u->nick,
"You have been constantly flooding services with %s "
"requests. Please stop immediately.",
u->motd == 30 ? "MOTD" : "VERSION");
}
if ((u->floodlev == 5) && (u->floodlev2 == 3)) {
u->floodlev2 = 4;
if (is_oper(u->nick)) {
wallops(SERVER_NAME, "Oper %s has been SEVERELY flooding services", u->nick);
} else {
kill_user(s_OperServ, u->nick, "Stop flooding services");
return 1;
}
} else if ((u->floodlev == F_TLEV) && (u->floodlev2 == 2)) {
u->floodlev2 = 3;
u->floodlev = 1;
notice(s_OperServ, u->nick, "You have been warned twice. STOP FLOODING SERVICES");
if (!is_oper(u->nick))
wallops(SERVER_NAME, "Services are being \2SEVERELY\2 flooded by %s!%s@%s",
u->nick, u->username, u->host);
} else if ((u->floodlev == F_TLEV) && (u->floodlev2 == 1)) {
u->floodlev2 = 2;
u->floodlev = 1;
notice(s_OperServ, u->nick, "You are flooding services, please slow down");
if (!is_oper(u->nick))
wallops(SERVER_NAME, "Services are being flooded by %s!%s@%s",
u->nick, u->username, u->host);
} else if ((u->floodlev == 8) && (u->floodlev2 == 0)) {
u->floodlev2 = 1;
}
return 0;
}
/*************************************************************************/
/* add_c_suspend: Add a channel to the suspend list for the next `delta'
* seconds.
*/
void add_c_suspend(const char *wchan, time_t delta)
{
C_SuspendData *c_spn;
char chan[CHANMAX];
time_t now = time(NULL);
C_SuspendData **whichlist = &c_suspend[tolower(wchan[0])];
strscpy(chan, wchan, CHANMAX);
for (c_spn = *whichlist; c_spn; c_spn = c_spn->next) {
if (stricmp(c_spn->chan, chan) == 0)
break;
}
if (c_spn) {
if (c_spn->time > now)
c_spn->time += delta;
else
c_spn->time = now + delta;
} else {
c_spn = smalloc(sizeof(*c_spn));
strcpy(c_spn->chan, chan);
c_spn->time = now + delta;
c_spn->next = *whichlist;
*whichlist = c_spn;
}
}
/*************************************************************************/
/* get_c_suspend: Retrieve a suspend record for a chan. If the chan isn't
* being suspended, return NULL and flush the record from the
* in-core list if it exists (i.e. suspend timed out).
*/
C_SuspendData *get_c_suspend(const char *chan)
{
C_SuspendData *c_spn, *prev;
time_t now = time(NULL);
C_SuspendData **whichlist = &c_suspend[tolower(chan[0])];
for (c_spn = *whichlist, prev = NULL; c_spn; prev = c_spn, c_spn = c_spn->next) {
if (stricmp(c_spn->chan, chan) == 0)
break;
}
if (c_spn && c_spn->time <= now) {
if (prev)
prev->next = c_spn->next;
else
*whichlist = c_spn->next;
free(c_spn);
c_spn = NULL;
}
return c_spn;
}
/*************************************************************************/
/* split_buf: Split a buffer into arguments and store the arguments in an
* argument vector pointed to by argv (which will be malloc'd
* as necessary); return the argument count. If colon_special
* is non-zero, then treat a parameter with a leading ':' as
* the last parameter of the line, per the IRC RFC. Destroys
* the buffer by side effect.
*/
int split_buf(char *buf, char ***argv, int colon_special)
{
int argvsize = 8;
int argc;
char *s;
*argv = smalloc(sizeof(char *) * argvsize);
argc = 0;
while (*buf) {
if (argc == argvsize) {
argvsize += 8;
*argv = srealloc(*argv, sizeof(char *) * argvsize);
}
if (*buf == ':') {
(*argv)[argc++] = buf+1;
buf = "";
} else {
s = strpbrk(buf, " ");
if (s) {
*s++ = 0;
while (isspace(*s))
s++;
} else {
s = buf + strlen(buf);
}
(*argv)[argc++] = buf;
buf = s;
}
}
return argc;
}
/*************************************************************************/
/* process: Main processing routine. Takes the string in inbuf (global
* variable) and does something appropriate with it. */
void process()
{
char source[64];
char cmd[64];
char buf[512]; /* Longest legal IRC command line */
char *s;
int ac; /* Parameters for the command */
char **av;
Message *m;
/* If debugging, log the buffer. */
if (debug)
log("debug: Received: %s", inbuf);
/* First make a copy of the buffer so we have the original in case we
* crash - in that case, we want to know what we crashed on. */
strscpy(buf, inbuf, sizeof(buf));
/* Split the buffer into pieces. */
if (*buf == ':') {
s = strpbrk(buf, " ");
if (!s)
return;
*s = 0;
while (isspace(*++s))
;
strscpy(source, buf+1, sizeof(source));
strcpy(buf, s);
} else {
*source = 0;
}
if (!*buf)
return;
s = strpbrk(buf, " ");
if (s) {
*s = 0;
while (isspace(*++s))
;
} else
s = buf + strlen(buf);
strscpy(cmd, buf, sizeof(cmd));
ac = split_buf(s, &av, 1);
/* Do something with the message. */
m = find_message(cmd);
if (m) {
if (m->func) {
m->func(source, ac, av);
}
} else {
log("unknown message from server (%s)", inbuf);
}
/* Free argument list we created */
free(av);
}
/*************************************************************************/