Page MenuHomeDevCentral

comm.c
No OneTemporary

/*
* Copyright (C) 1996 Darkbot Project.
* This program is free software, you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2. This
* program is distributed in the hope that it will be useful, but without
* any warranty, without even the implied warranty of merchantability or
* fitness for a particular purpose. See the COPYING file for details.
*/
#include "defines.h"
#include "vars.h"
#include "prototypes.h"
#include "utils/sasl.h"
/**
* Delete one or more elements from the sendq
* 1 = delete all pri/not's
* 0 = delete first in queue
* 6/23/00 Dan
* - Updated to use head and tail pointer queue
* - All variables now initialized when declared
* - Optimized the main while loop a bit, reduced amount of code
*/
void
del_sendq (long toggle)
{
struct sendq *pNode = sendqhead, *pPrev = 0;
if (NULL == sendqhead)
{
return;
}
if (toggle == 0)
{
/* Just delete the head */
pNode = sendqhead;
sendqhead = sendqhead->next;
free (pNode);
}
else
{
/* Iterate through the queue and delete each element which is
* a PRIVMSG or NOTICE
*/
for (; pNode != NULL; pPrev = pNode, pNode = pNode->next)
{
if (0 == strncmp (pNode->data, "PRI", 3) || 0 == strncmp (pNode->data, "NOT", 3))
{
/* Found one, let's delete it */
if (pPrev != NULL)
{
pPrev->next = pNode->next;
}
else
{
sendqhead = pNode->next;
}
free (pNode);
pNode = NULL;
break;
}
} /* for */
} /* else */
/* Update the tail pointer if needed */
if (NULL == sendqhead)
{
sendqtail = NULL;
}
}
int
get_sendq_count (long toggle)
{
struct sendq *c;
long i = 0, x = 0;
c = sendqhead;
while (c != NULL)
{
i++;
if (c->data[0] == 'P' && c->data[1] == 'R' && c->data[2] == 'I')
x++;
else if (c->data[0] == 'N' && c->data[1] == 'O' && c->data[2] == 'T')
x++;
c = c->next;
}
if (toggle == 1)
clear_sendq (i, 1);
if (toggle == 2)
return i;
if (i < OUTPUT1_COUNT)
SEND_DELAY = OUTPUT1_DELAY;
else if (i < OUTPUT2_COUNT)
SEND_DELAY = OUTPUT2_DELAY;
else
SEND_DELAY = OUTPUT3_DELAY;
if (x > OUTPUT_PURGE_COUNT)
clear_sendq (x, 0);
return i;
}
void
clear_sendq (long count, long toggle)
{
long i = 0;
i = count;
while (i > 1)
{
i--;
del_sendq (1);
}
send_tog = 1;
if (toggle != 1)
L090 (CHAN, count);
}
long
setinfo_lastcomm (char *rest)
{ /* Disallows joins to more than one channel (or the same chan)
* to artificially raise join counters */
long c_uptime = 0;
if (strcasecmp (rest, slc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, slc2) == 0)
return 1;
if (strcasecmp (rest, slc3) == 0)
return 1;
if (strcasecmp (rest, slc4) == 0)
return 1;
if (*slc1 == '0')
{ /* init lastcomms */
strncpy (slc1, rest, sizeof (slc1));
slcn1 = time (NULL);
}
if (*slc2 == '0')
{
strncpy (slc2, rest, sizeof (slc2));
slcn2 = time (NULL);
}
if (*slc3 == '0')
{
strncpy (slc3, rest, sizeof (slc3));
slcn3 = time (NULL);
}
if (*slc4 == '0')
{
strncpy (slc4, rest, sizeof (slc4));
slcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - slcn1) > SLASTCOMM_TIME)
{ /* reinit old data */
slcn1 = 0;
*slc1 = '0';
}
if ((c_uptime = time (NULL) - slcn2) > SLASTCOMM_TIME)
{
slcn2 = 0;
*slc2 = '0';
}
if ((c_uptime = time (NULL) - slcn3) > SLASTCOMM_TIME)
{
slcn3 = 0;
*slc3 = '0';
}
if ((c_uptime = time (NULL) - slcn4) > SLASTCOMM_TIME)
{
slcn4 = 0;
*slc4 = '0';
}
strncpy (slc4, slc3, sizeof (slc4)); /* no matches, move em on
down */
strncpy (slc3, slc2, sizeof (slc3));
strncpy (slc2, slc1, sizeof (slc2));
strncpy (slc1, rest, sizeof (slc1));
slcn4 = slcn3;
slcn3 = slcn2;
slcn2 = slcn1;
slcn1 = time (NULL);
return 0;
}
long
do_lastcomm (char *nick, char *target, char *rest)
{
long c_uptime = 0;
if (strcasecmp (rest, lc1) == 0)
return 1; /* don't reply if already asked in LASTCOMM_TIME sec */
if (strcasecmp (rest, lc2) == 0)
return 1;
if (strcasecmp (rest, lc3) == 0)
return 1;
if (strcasecmp (rest, lc4) == 0)
return 1;
if (*lc1 == '0')
{ /* init lastcomms */
strncpy (lc1, rest, sizeof (lc1));
lcn1 = time (NULL);
}
if (*lc2 == '0')
{
strncpy (lc2, rest, sizeof (lc2));
lcn2 = time (NULL);
}
if (*lc3 == '0')
{
strncpy (lc3, rest, sizeof (lc3));
lcn3 = time (NULL);
}
if (*lc4 == '0')
{
strncpy (lc4, rest, sizeof (lc4));
lcn4 = time (NULL);
}
if ((c_uptime = time (NULL) - lcn1) > LASTCOMM_TIME)
{ /* reinit old data */
lcn1 = 0;
*lc1 = '0';
}
if ((c_uptime = time (NULL) - lcn2) > LASTCOMM_TIME)
{
lcn2 = 0;
*lc2 = '0';
}
if ((c_uptime = time (NULL) - lcn3) > LASTCOMM_TIME)
{
lcn3 = 0;
*lc3 = '0';
}
if ((c_uptime = time (NULL) - lcn4) > LASTCOMM_TIME)
{
lcn4 = 0;
*lc4 = '0';
}
strncpy (lc4, lc3, sizeof (lc4)); /* no matches, move em on
down */
strncpy (lc3, lc2, sizeof (lc3));
strncpy (lc2, lc1, sizeof (lc2));
strncpy (lc1, rest, sizeof (lc1));
lcn4 = lcn3;
lcn3 = lcn2;
lcn2 = lcn1;
lcn1 = time (NULL);
return 0;
}
void
prepare_bot (void)
{
int esc = 0;
while (!esc)
{
gs26 ();
printf (".: Connecting to %s:%ld\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
socketfd = create_connection (BS, VHOST, BP);
switch (socketfd)
{
case ERR_TIMED_OUT:
printf (".: Connection to %s:%ld timed out!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_CONN_REFUSED:
printf (".: Connection to %s:%ld was refused!\t\r", BS, BP);
fflush (stdout);
db_sleep (2);
break;
case ERR_NOT_ADDR:
printf ("Address not in range!\n");
exit (1);
case ERR_NO_REACH:
printf ("Address not reachable!\n");
exit (1);
default:
esc = 1;
printf
(".: Connected to %s:%ld! [%ld]\t\n", BS, BP, (long) getpid ());
fflush (stdout);
db_sleep (5);
break;
}
}
/* set the socket to BLOCK */
if (fcntl (socketfd, F_SETFL, 0) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
}
int
create_connection (char *server, char *virtualhost, long port)
{
struct sockaddr_in name;
struct hostent *hostname;
struct timeval timeout;
fd_set set;
int sock = 0, vhost = 1, sockerr = 0,
optlen = sizeof (sockerr);
if ((!virtualhost) || (strlen (virtualhost) < 1))
vhost = 0;
if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0)
return -1;
memset (&name, 0, sizeof (struct sockaddr_in));
setsockopt (sock, SOL_SOCKET, SO_LINGER, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 0, 0);
setsockopt (sock, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
name.sin_family = AF_INET;
name.sin_addr.s_addr = (vhost ? inet_addr (virtualhost) : INADDR_ANY);
if ((name.sin_addr.s_addr == -1) && vhost)
{
hostname = gethostbyname (virtualhost);
if (hostname)
{
name.sin_addr = *(struct in_addr *) hostname->h_addr;
}
else
{
name.sin_addr.s_addr = INADDR_ANY;
}
}
if (bind (sock, (struct sockaddr *) &name, sizeof (struct sockaddr_in)) < 0)
{
printf ("\n");
perror ("bind");
close (sock);
exit (EXIT_FAILURE);
}
memset (&name, 0, sizeof (struct sockaddr_in));
name.sin_family = AF_INET;
name.sin_port = htons (port);
if(!(hostname = gethostbyname (server)))
{
printf ("\nCan't create the connection!\n");
// FIXME: This is obsolete, and solaris doesn't know about it.
// herror ("hostname");
exit (EXIT_FAILURE);
}
name.sin_addr = *(struct in_addr *) hostname->h_addr;
/* set the file descriptor to non blocking mode so that connect()
returns immediately.
*/
if (fcntl (sock, F_SETFL, O_NONBLOCK) < 0)
{
printf ("\n");
perror ("fcntl");
exit (EXIT_FAILURE);
}
if (connect (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
{
if ((errno != EINPROGRESS) && (errno != ENOENT))
{
printf ("\n");
perror ("connect");
exit (EXIT_FAILURE);
}
}
alarm (0);
while (1)
{
/* set the timeout */
timeout.tv_sec = CONNECT_WAIT_TIMEOUT;
timeout.tv_usec = 0;
/* set the file descriptor to be empty */
FD_ZERO (&set);
/* add our socket to the file descriptor set */
FD_SET (sock, &set);
/* select will let us know when our socket is ready (connected) */
switch (select (FD_SETSIZE, (fd_set *) NULL, &set, (fd_set *) NULL, &timeout))
{
/* if select returns 0, our timeout was reached */
case 0:
alarm (AIL);
return ERR_TIMED_OUT;
/* -1 means we are not connected */
case -1:
break;
/* we MIGHT be connected */
default:
/* get the socket errno so we can check if we are connected */
switch (getsockopt (sock, SOL_SOCKET, SO_ERROR, &sockerr, &optlen))
{
case -1:
alarm (AIL);
return ERR_SOCK_OPT;
case 0:
switch (sockerr)
{
case ECONNREFUSED:
alarm (AIL);
return ERR_CONN_REFUSED;
case EADDRNOTAVAIL:
alarm (AIL);
return ERR_NOT_ADDR;
case ENETUNREACH:
alarm (AIL);
return ERR_NO_REACH;
case SUCCESS:
alarm (AIL);
return sock;
}
}
}
}
}
void
register_bot (void)
{
get_sendq_count (1);
// SASL nickserv authentication needs to be done as soon as connected
// to the server, before registering with NICK and USER, PASS commands.
if (strlen(SASL_USER) > 0 && strlen(SASL_PASS) > 0) {
char* sasl_plain_string = build_sasl_plain_string(SASL_USER, SASL_USER, SASL_PASS);
Snow ("CAP REQ :SASL\n");
Snow ("CAP END\n");
Snow ("AUTHENTICATE PLAIN\n");
Snow ("AUTHENTICATE %s\n", sasl_plain_string);
free(sasl_plain_string);
}
Snow ("NICK %s\n", Mynick);
strlwr (UID);
Snow ("USER %s %d %d :%s \2%d\2\n", UID, time (NULL), time (NULL), REALNAME, NUM_HELPER);
if (BPASS != NULL)
Snow ("PASS :%s\n", BPASS);
}

File Metadata

Mime Type
text/x-c
Expires
Sat, Oct 11, 20:08 (14 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3063920
Default Alt Text
comm.c (9 KB)

Event Timeline