All pastes #506344 Raw Edit

Untitled

public text v1 · immutable
·published 2007-05-23 22:31 UTC
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);
}
/*************************************************************************/