Пример #1
0
void
CycleServers()

{
	if (HubSock == NOSOCKET)
	{
		if (currenthub)
		{
			if (!currenthub->next)
				currenthub = ServList;
			else
				currenthub = currenthub->next;
		}
		else
			currenthub = ServList;

		SendUmode(OPERUMODE_Y,
		          "*** Cycling server list");

		while (currenthub)
		{
			/* Begin connection to server */
			if ((HubSock = ConnectHost(currenthub->hostname, currenthub->port)) >= 0)
			{
				currenthub->sockfd = HubSock;

				SetHubConnect(currenthub);

				break;
			}
			else
			{
				SendUmode(OPERUMODE_Y,
				          "*** Unable to connect to %s:%d (%s)",
				          currenthub->hostname,
				          currenthub->port,
				          strerror(errno));

				HubSock = NOSOCKET;
				currenthub = currenthub->next;
			}
		} /* while (currenthub) */
	} /* if (HubSock == NOSOCKET) */
} /* CycleServers() */
Пример #2
0
int
CompleteHubConnection(struct Servlist *hubptr)

{
	int errval;
	socklen_t errlen;

	assert(hubptr != 0);

	ClearHubConnect(hubptr);

	errval = 0;
	errlen = sizeof(errval);

	if (getsockopt(HubSock, SOL_SOCKET, SO_ERROR,
	               (void *)&errval, &errlen) == -1)
	{
		putlog(LOG1, "getsockopt(SO_ERROR) failed: %s", strerror(errno));
		return 0;
	}

	if (errval > 0)
	{
		putlog(LOG1,
		       "Error connecting to %s tcp/%d: %s",
		       hubptr->hostname, hubptr->port, strerror(errval));

		return 0;
	}

	signon();

	hubptr->connect_ts = current_ts;

#ifdef RECORD_RESTART_TS
	most_recent_sjoin = current_ts;
#endif

	SendUmode(OPERUMODE_Y, "*** Connected to %s tcp/%d",
	          hubptr->hostname, hubptr->port);
	putlog(LOG1, "Connected to %s tcp/%d", hubptr->hostname, hubptr->port);

	burst_complete = 0;

	return 1;
} /* CompleteHubConnection() */
Пример #3
0
void
RecordCommand(char *format, ...)

{
  va_list args;
  char buffer[MAXLINE * 2];

  va_start(args, format);

  vsprintf_irc(buffer, format, args);

  va_end(args);

  /* log the command */
  stripformatsymbols( buffer );
  putlog(LOG2, buffer);

  /* send it to opers with usermode +s */
  SendUmode(OPERUMODE_S, buffer);
} /* RecordCommand() */
Пример #4
0
void
DeleteClient(struct Luser *user)

{
	struct UserChannel *chnext;

#ifdef NICKSERVICES

	struct NickInfo *nptr, *realptr;

#ifdef CHANNELSERVICES

	struct aChannelPtr *fnext;
#endif

#endif /* NICKSERVICES */

	if (user == NULL)
		return;

	SendUmode(OPERUMODE_CAPE,
	          "*** Client exit: %s!%s@%s [%s]",
	          user->nick,
	          user->username,
	          user->hostname,
	          user->server ? user->server->name : "*unknown*");

#ifdef NICKSERVICES

	realptr = FindNick(user->nick);
	nptr = GetMaster(realptr);
	if (nptr && realptr)
	{

		if (LastSeenInfo && (realptr->flags & NS_IDENTIFIED))
		{
			/*
			 * Update last seen user@host info
			 */

			if (realptr->lastu)
				MyFree(realptr->lastu);
			if (realptr->lasth)
				MyFree(realptr->lasth);
			realptr->lastu = MyStrdup(user->username);
			realptr->lasth = MyStrdup(user->hostname);
		}

		/*
		 * they're quitting - unmark them as identified
		 */
		realptr->flags &= ~NS_IDENTIFIED;
	}

#ifdef CHANNELSERVICES
	while (user->founder_channels)
	{
		fnext = user->founder_channels->next;
		RemFounder(user, user->founder_channels->cptr);
		user->founder_channels = fnext;
	}
#endif

#endif /* NICKSERVICES */

#ifdef ALLOW_FUCKOVER
	/* check if user was a target of o_fuckover() */
	CheckFuckoverTarget(user, NULL);
#endif

	if (user->server)
		user->server->numusers--;

	while (user->firstchan)
	{
		chnext = user->firstchan->next;
		RemoveFromChannel(user->firstchan->chptr, user);
		user->firstchan = chnext;
	}

	HashDelClient(user, 0);

	/* keep oper count updated */
	if (user->umodes & UMODE_O)
	{
		Network->TotalOperators--;
		if (user->server)
			user->server->numopers--;
	}

#ifndef BLOCK_ALLOCATION
	MyFree(user->nick);
	MyFree(user->username);
	MyFree(user->hostname);
	MyFree(user->realname);
#endif /* BLOCK_ALLOCATION */

	if (user->prev)
		user->prev->next = user->next;
	else
		ClientList = user->next;

	if (user->next)
		user->next->prev = user->prev;

#ifdef BLOCK_ALLOCATION

	BlockSubFree(ClientHeap, user);

#else

	MyFree(user);

#endif /* BLOCK_ALLOCATION */

	Network->TotalUsers--;
} /* DeleteClient() */
Пример #5
0
void
UpdateUserModes(struct Luser *user, char *modes)

{
	int PLUS = 1;
	int umode;
	unsigned int ii;

	if (!modes || !user)
		return;

	for (ii = 0; ii < strlen(modes); ii++)
	{
		if (modes[ii] == '+')
		{
			PLUS = 1;
			continue;
		}
		if (modes[ii] == '-')
		{
			PLUS = 0;
			continue;
		}
		umode = 0;
		if (modes[ii] == 'i')
			umode = UMODE_I;
		if (modes[ii] == 's')
			umode = UMODE_S;
		if (modes[ii] == 'w')
			umode = UMODE_W;
		if (modes[ii] == 'o')
			umode = UMODE_O;
#ifdef DANCER

		if (modes[ii] == 'e')
			if (PLUS)
			{
				struct NickInfo* realptr = FindNick(user->nick);
				if (realptr)
				{
					realptr->flags |= NS_IDENTIFIED;
					RecordCommand("User %s has +e umode, marking as identified",user->nick);
					umode = UMODE_E;
				}
				else
				{
					/* Blech, who is screwing with us? */
					toserv(":%s MODE %s -e\r\n", Me.name, user->nick);
					RecordCommand("User %s has +e umode but is not known to me, setting -e",
					              user->nick);
					umode = 0;
				}
			}
#endif /* DANCER */

		if (!umode)
			continue;

		if (PLUS)
		{
			if ((umode == UMODE_O) && (!IsOperator(user)))
			{
#ifdef STATSERVICES
				char *hostname, *domain;
				struct HostHash *hosth, *domainh;
				time_t currtime = current_ts;
#endif

#ifdef NICKSERVICES

				CheckOper(user);
#endif

				Network->TotalOperators++;

				if (SafeConnect)
					SendUmode(OPERUMODE_O,
					          "*** New Operator: %s (%s@%s) [%s]",
					          user->nick,
					          user->username,
					          user->hostname,
					          user->server ? user->server->name : "*unknown*");

#ifdef STATSERVICES

				if (Network->TotalOperators > Network->MaxOperators)
				{
					Network->MaxOperators = Network->TotalOperators;
					Network->MaxOperators_ts = current_ts;

					if ((Network->MaxOperators % 5) == 0)
					{
						/* inform +y people of new max oper count */
						SendUmode(OPERUMODE_Y,
						          "*** New Max Operator Count: %ld",
						          Network->MaxOperators);
						putlog(LOG2, "New Max Operator Count: %ld",
								Network->MaxOperators);
					}
				}
				if (Network->TotalOperators > Network->MaxOperatorsT)
				{
					Network->MaxOperatorsT = Network->TotalOperators;
					Network->MaxOperatorsT_ts = current_ts;
				}
#endif

				if (user->server)
				{
					user->server->numopers++;

#ifdef STATSERVICES

					if (user->server->numopers > user->server->maxopers)
					{
						user->server->maxopers = user->server->numopers;
						user->server->maxopers_ts = current_ts;
					}
#endif

				}

#ifdef STATSERVICES
				hostname = user->hostname;

				if ((hosth = FindHost(hostname)))
				{
					hosth->curropers++;
					if (hosth->curropers > hosth->maxopers)
					{
						hosth->maxopers = hosth->curropers;
						hosth->maxopers_ts = currtime;
					}
				}

				if ((domain = GetDomain(hostname)))
				{
					if ((domainh = FindDomain(domain)))
					{
						domainh->curropers++;
						if (domainh->curropers > domainh->maxopers)
						{
							domainh->maxopers = domainh->curropers;
							domainh->maxopers_ts = currtime;
						}
					}
				}
#endif /* STATSERVICES */

			}
			user->umodes |= umode;
		}
		else
		{
			if ((umode == UMODE_O) && (IsOperator(user)))
			{
#ifdef STATSERVICES
				char *hostname, *domain;
				struct HostHash *hosth, *domainh;
#endif

				Network->TotalOperators--;
				if (user->server)
					user->server->numopers--;

#ifdef STATSERVICES

				hostname = user->hostname;

				if ((hosth = FindHost(hostname)))
					hosth->curropers--;

				if ((domain = GetDomain(hostname)))
					if ((domainh = FindDomain(domain)))
						domainh->curropers--;
#endif

			}
			user->umodes &= ~umode;
		}
	}
} /* UpdateUserModes() */
Пример #6
0
struct Luser *
			AddClient(char **line)

{
	char *ch;
	struct Luser *tempuser,
				*newptr;

#ifdef BLOCK_ALLOCATION

	tempuser = (struct Luser *) BlockSubAllocate(ClientHeap);
	if (!tempuser) /* shouldn't happen - but I'm paranoid :) */
		return (NULL);

	memset(tempuser, 0, sizeof(struct Luser));

	strlcpy(tempuser->nick, line[1], NICKLEN + 1);
	strlcpy(tempuser->username, line[5], USERLEN + 1);
	strlcpy(tempuser->hostname, line[6], HOSTLEN + 1);
	strlcpy(tempuser->realname, line[8] + 1, REALLEN + 1);

#else

	tempuser = (struct Luser *) MyMalloc(sizeof(struct Luser));
	memset(tempuser, 0, sizeof(struct Luser));

	tempuser->nick = MyStrdup(line[1]);
	tempuser->username = MyStrdup(line[5]);
	tempuser->hostname = MyStrdup(line[6]);
	tempuser->realname = MyStrdup(line[8] + 1);

#endif /* BLOCK_ALLOCATION */

	tempuser->since = atol(line[3]);

#ifdef NICKSERVICES

	tempuser->nick_ts = tempuser->since;

#if defined SVSNICK || defined FORCENICK
	tempuser->flags &= ~(UMODE_NOFORCENICK);
#endif

#endif /* NICKSERVICES */

	if ((tempuser->server = FindServer(line[7])))
{
		tempuser->server->numusers++;

#ifdef STATSERVICES

		if (tempuser->server->numusers > tempuser->server->maxusers)
		{
			tempuser->server->maxusers = tempuser->server->numusers;
			tempuser->server->maxusers_ts = current_ts;
		}
#endif

	}

	ch = &line[4][1];
	while (*ch)
	{
		switch (*ch)
		{
		case 'i':
		case 'I':
			{
				tempuser->umodes |= UMODE_I;
				break;
			}
		case 's':
		case 'S':
			{
				tempuser->umodes |= UMODE_S;
				break;
			}
		case 'w':
		case 'W':
			{
				tempuser->umodes |= UMODE_W;
				break;
			}
		case 'o':
		case 'O':
			{
				tempuser->umodes |= UMODE_O;

				Network->TotalOperators++;

#ifdef STATSERVICES

				if (Network->TotalOperators > Network->MaxOperators)
				{
					Network->MaxOperators = Network->TotalOperators;
					Network->MaxOperators_ts = current_ts;

					if ((Network->MaxOperators % 5) == 0)
					{
						/* inform +y people of new max oper count */
						SendUmode(OPERUMODE_Y,
						          "*** New Max Operator Count: %ld",
						          Network->MaxOperators);
						putlog(LOG2, "New Max Operator Count: %ld",
								Network->MaxOperators);
					}
				}
				if (Network->TotalOperators > Network->MaxOperatorsT)
				{
					Network->MaxOperatorsT = Network->TotalOperators;
					Network->MaxOperatorsT_ts = current_ts;
				}
#endif

				if (tempuser->server)
				{
					tempuser->server->numopers++;

#ifdef STATSERVICES

					if (tempuser->server->numopers > tempuser->server->maxopers)
					{
						tempuser->server->maxopers = tempuser->server->numopers;
						tempuser->server->maxopers_ts = current_ts;
					}
#endif

				}
				break;
			} /* case 'O' */
#ifdef DANCER
		case 'e':
		case 'E':
			{
				struct NickInfo *realptr;
				realptr = FindNick(tempuser->nick);
				if (realptr)
				{
					realptr->flags |= NS_IDENTIFIED;
					tempuser->umodes |= UMODE_E;
					RecordCommand("User %s has +e umode, marking as identified",
					              tempuser->nick);
				}
				else
				{
					/* Is it one of mine? */
					int mine = 0;
					struct aService *sptr;
					for (sptr = ServiceBots; sptr->name; ++sptr)
						if (!irccmp(tempuser->nick, *(sptr->name)))
						{
							mine = 1;
							break;
						}
					if (!mine)
					{
						/* Blech, who is screwing with us? */
						toserv(":%s MODE %s -e\r\n", Me.name, tempuser->nick);
						RecordCommand("User %s has +e umode but is not known to me, setting -e",
						              tempuser->nick);
					}
				}
				break;
			}
#endif /* DANCER */
		default:
			break;
		} /* switch (*ch) */
		ch++;
	}

	tempuser->next = ClientList;
	tempuser->prev = NULL;
	if (tempuser->next)
		tempuser->next->prev = tempuser;
	ClientList = tempuser;

	/* add client to the hash table */
	newptr = HashAddClient(ClientList, 0);

	Network->TotalUsers++;
#ifdef STATSERVICES

	if (Network->TotalUsers > Network->MaxUsers)
	{
		Network->MaxUsers = Network->TotalUsers;
		Network->MaxUsers_ts = current_ts;

		if ((Network->MaxUsers % 10) == 0)
		{
			/* notify +y people of new max user count */
			SendUmode(OPERUMODE_Y,
			          "*** New Max Client Count: %ld",
			          Network->MaxUsers);
			putlog(LOG2, "New Max Client Count: %ld",
					Network->MaxUsers);
		}
	}
	if (Network->TotalUsers > Network->MaxUsersT)
	{
		Network->MaxUsersT = Network->TotalUsers;
		Network->MaxUsersT_ts = current_ts;
	}
#endif /* STATSERVICES */

#ifdef ALLOW_GLINES
	/*
	 * It's possible the client won't exist anymore, because if the user
	 * is a clone and AutoKillClones is enabled, HashAddClient() would
	 * have already killed the user, in which case newptr will be
	 * NULL - CheckGlined() checks for null pointers
	 */
	CheckGlined(newptr); /* Check if new user is glined */
#endif

	return (tempuser);
} /* AddClient() */
Пример #7
0
int main(int argc, char *argv[])
{
#if !defined DEBUGMODE && !defined DAEMONTOOLS
	pid_t pid; /* pid of this process */
#endif /* !DEBUGMODE && !DAEMONTOOLS */

#ifdef GDB_DEBUG

	int GDBAttached = 0;
#endif /* GDB_DEBUG */

#if defined GIMMECORE || defined DEBUGMODE

	struct rlimit rlim; /* resource limits -kre */
#endif /* GIMMECORE || DEBUGMODE */

	FILE *pidfile; /* to write our pid */
	uid_t uid; /* real user id */
	uid_t euid; /* effective user id */

#if defined HAVE_BOEHM_GC
	GC_INIT();
#endif /* HAVE_BOEHM_GC */

	myargv = argv;

	/* Initialise current TS for services -kre */
	TimeStarted = current_ts = time(NULL);

	/* Be sure, be paranoid, be safe. -kre */
	umask(077);

	fprintf(stderr,
	        "Hybserv2 TS services version %s by Hybserv2 team\n"
#if defined __DATE__ && defined __TIME__
	        "Compiled at %s, %s\n",
#endif
	        hVersion
#if defined __DATE__ && defined __TIME__
	        , __DATE__, __TIME__
#endif
	       );

#ifdef GDB_DEBUG

	while (!GDBAttached)
		sleep(1);
#endif /* GDB_DEBUG */

	/*
	 * Load SETPATH (settings.conf) - this must be done
	 * before the config file is loaded, and before any
	 * putlog() calls are made, since LogFile is specified
	 * in settings.conf
	 */
	if (LoadSettings(0) == 0)
	{
		fprintf(stderr, "Fatal errors encountered parsing %s, exiting\n"
		        "Check logfile %s/%s\n", SETPATH, LogPath ? LogPath : "",
		        LogFile ?  LogFile : "*unknown*");
		return (0);
	}

	/*
	 * If they run ./shownicks or ./showchans rather than ./hybserv
	 * display nicknames/channels
	 */
	if (strstr(argv[0], "shownicks"))
	{
#ifdef NICKSERVICES
		ShowNicknames(argc, argv);
#endif /* NICKSERVICES */

		return (0);
	}
	else if (strstr(argv[0], "showchans"))
	{
#if defined(NICKSERVICES) && defined(CHANNELSERVICES)
		ShowChannels(argc, argv);
#endif /* defined(NICKSERVICES) && defined(CHANNELSERVICES) */

		return 0;
	}

	/* Check for running services -kre */
	if ((pidfile = fopen(PidFile, "r")) == NULL)
		fprintf(stderr, "WARNING: Unable to read pid file %s\n",
		        PidFile);
	else
	{
		pid_t mypid;
		char line[MAXLINE + 1];

		if (fgets(line, sizeof(line), pidfile) != NULL)
		{
			mypid = atoi(line);
			if (mypid && !kill(mypid, 0))
			{
				fprintf(stderr, "FATAL: Services are already running!\n");
				fclose(pidfile);
				exit(EXIT_FAILURE);
			}
		}
		fclose(pidfile);
	}

	uid = getuid(); /* the user id of the user who ran the process */
	euid = geteuid(); /* the effective id (different if setuid) */

	if (!uid || !euid)
	{
		fprintf(stderr,
		        "FATAL: Please don't run services as root. Now exiting.\n");
		exit(EXIT_FAILURE);
	}

	if (chdir(HPath) != 0)
	{
		fprintf(stderr,
		        "HPath is an invalid directory, please check %s\n",
		        SETPATH);
		exit(EXIT_FAILURE);
	}

	putlog(LOG1, "Hybserv2 TS services version %s started", hVersion);

	/* Get the offset from GMT (London time) */
	gmt_offset = GetTZOffset(TimeStarted);

	/*
	 * the Network list must be initialized before the config
	 * file is loaded
	 */
	InitLists();

	/* load server, jupe, gline, user, admin info */
	LoadConfig();

	/* load nick/chan/memo/stat databases */
	LoadData();

#ifdef GLOBALSERVICES

	if (LogonNews)
	{
		Network->LogonNewsFile.filename = LogonNews;
		ReadMessageFile(&Network->LogonNewsFile);
	}

#endif /* GLOBALSERVICES */

	if (LocalHostName)
		SetupVirtualHost();

#if !defined DEBUGMODE && !defined GDB_DEBUG

	/* Daemontools compatibility stuff */
#ifndef DAEMONTOOLS

	pid = fork();
	if (pid == -1)
	{
		printf("Unable to fork(), exiting.\n");
		exit(EXIT_FAILURE);
	}
	if (pid != 0)
	{
		printf("Running in background (pid: %d)\n", (int)pid);
		exit(EXIT_SUCCESS);
	}

	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	/* Make current process session leader -kre */
	if (setsid() == -1)
	{
		exit(EXIT_FAILURE);
	}
#else

	printf("Entering foreground debug mode\n");
#endif /* DEBUGMODE */
#endif /* DAEMONTOOLS */

#if defined GIMMECORE || defined DEBUGMODE

	printf("Setting corefile limit... ");
	/* Set corefilesize to maximum - therefore we ensure that core will be
	 * generated, no matter of shell limits -kre */
	getrlimit(RLIMIT_CORE, &rlim);
	rlim.rlim_cur = rlim.rlim_max;
	setrlimit(RLIMIT_CORE, &rlim);
	printf("done.\n");
#endif /* GIMMECORE || DEBUGMODE */

	/* Signals must be set up after fork(), since the parent exits */
	InitSignals();

	/* Initialise random number generator -kre */
	srandom(current_ts);
	srandom((unsigned int)random());

	/* Write our pid to a file */
	if ((pidfile = fopen(PidFile, "w")) == NULL)
		putlog(LOG1, "Unable to open %s", PidFile);
	else
	{
		char line[MAXLINE + 1];

		ircsprintf(line, "%d\n", getpid());
		fputs(line, pidfile);
		fclose(pidfile);
	}

	/* initialize tcm/user listening ports */
	InitListenPorts();

	/* initialize hash tables */
	ClearHashes(1);

#ifdef BLOCK_ALLOCATION

	InitHeaps();
#endif

	HubSock = NOSOCKET;
	CycleServers();

	while (1)
	{
		/* enter loop waiting for server info */
		ReadSocketInfo();

		if (Me.hub)
			SendUmode(OPERUMODE_Y, "*** Disconnected from %s", Me.hub->name);
		else
			SendUmode(OPERUMODE_Y, "*** Disconnected from hub server");

		if (currenthub)
		{
			if (currenthub->realname)
			{
				MyFree(currenthub->realname);
				currenthub->realname = NULL;
			}
			currenthub->connect_ts = 0;
		}

		close(HubSock); /* There was an error */
		HubSock = NOSOCKET;

		/*
		 * whenever Hybserv connects/reconnects to a server, clear
		 * users, servers, and chans
		 */
		ClearUsers();
		ClearChans();
		ClearServs();
		/*
		 * ClearHashes() must be called AFTER ClearUsers(),
		 * or StatServ's unique client counts will be off since
		 * cloneTable[] would be NULL while it was trying to find
		 * clones
		 */
		ClearHashes(0);

		PostCleanup();
	} /* while (1) */

	return 0;
} /* main() */
Пример #8
0
void
ReadSocketInfo(void)

{
	int SelectResult;
	struct timeval TimeOut;

	struct DccUser *dccptr;
	struct PortInfo *tempport;
	fd_set readfds,
	writefds;

	time_t curr_ts;
	time_t last_ts = current_ts;

	spill[0] = '\0';

	for (;;)
	{

		/*
		 * DoTimer() will be called from this code, and so we need curr_ts
		 * here. And we also need time setup here -kre
		 */
		curr_ts = current_ts = time(NULL);

#ifdef HIGHTRAFFIC_MODE

		if (HTM)
		{
			int htm_count;

			if (last_ts != curr_ts)
			{
				/*
				 * So DoTimer() doesn't get called a billion times when HTM is
				 * turned off
				 */
				last_ts = curr_ts;

				/*
				 * DoTimer() won't do anything other than update
				 * Network->CheckRecvB since we are in HTM
				 */
				DoTimer(curr_ts);
			} /* if (last_ts != curr_ts) */

			/* Check if HTM should be turned off */
			if ((curr_ts - HTM_ts) >= HTM_TIMEOUT)
			{
				float    currload;

				currload = ((float) (Network->RecvB - Network->CheckRecvB) /
				            (float) 1024) / (float) HTM_INTERVAL;

				if (currload >= (float) ReceiveLoad)
				{
					HTM_ts = curr_ts;
					putlog(LOG1, "Continuing high-traffic mode (%0.2f K/s)",
					       currload);
					SendUmode(OPERUMODE_Y,
					          "*** Continuing high-traffic mode (%0.2f K/s)",
					          currload);
				}
				else
				{
					HTM = HTM_ts = 0;
					putlog(LOG1, "Resuming standard traffic operations (%0.2f K/s)",
					       currload);
					SendUmode(OPERUMODE_Y,
					          "*** Resuming standard traffic operations (%0.2f K/s)",
					          currload);
				}
			}

			for (htm_count = 0; htm_count < HTM_RATIO; htm_count++)
				if (!ReadHub())
				{
					read_socket_done = 1;
					return;
				}

		} /* if (HTM) */
		else

#endif /* HIGHTRAFFIC_MODE */

			if (last_ts != curr_ts)
			{
				if (curr_ts > (last_ts + 1))
				{
					time_t  delta;
					/*
					 * we skipped at least 1 time interval - make up for it
					 * by calling DoTimer() how ever many intervals we missed
					 * (ie: if the TS went from 5 to 8, call DoTimer() twice
					 * since we missed 6 and 7)
					 */
					for (delta = (last_ts + 1); delta < curr_ts; delta++)
						DoTimer(delta);
				}
				last_ts = curr_ts;
				DoTimer(curr_ts);
			}

		FD_ZERO(&readfds);
		FD_ZERO(&writefds);

		TimeOut.tv_sec = 0L;
		TimeOut.tv_usec = 20000L;

		if (currenthub && (HubSock != NOSOCKET))
		{
			if (IsHubConnect(currenthub))
				FD_SET(HubSock, &writefds);
			else
				FD_SET(HubSock, &readfds);
		}

		for (dccptr = connections; dccptr; dccptr = dccptr->next)
		{
			if (IsDccConnect(dccptr))
				FD_SET(dccptr->socket, &writefds);
			else
			{
				FD_SET(dccptr->socket, &readfds);
				if (dccptr->authfd != NOSOCKET)
				{
					FD_SET(dccptr->authfd, &readfds);
					if (dccptr->flags & SOCK_WRID)
						FD_SET(dccptr->authfd, &writefds);
				}
			}
		}

		for (tempport = PortList; tempport; tempport = tempport->next)
			if (tempport->socket != NOSOCKET)
				FD_SET(tempport->socket, &readfds);

		SelectResult = select(FD_SETSIZE, &readfds, &writefds, NULL, &TimeOut);
		if (SelectResult > 0)
		{
			/* something happened */

			if (currenthub && (HubSock != NOSOCKET))
			{
				/* This is for info coming from the hub server */

				if (IsHubConnect(currenthub) && FD_ISSET(HubSock, &writefds))
				{
					if (!CompleteHubConnection(currenthub))
					{
						close(HubSock);
						currenthub->sockfd = HubSock = NOSOCKET;
					}
				}
				else if (FD_ISSET(HubSock, &readfds))
				{
					if (!ReadHub())
					{
						read_socket_done = 1;
						return; /* something bad happened */
					}
				}
			} /* if (currenthub && (HubSock != NOSOCKET)) */

			for (tempport = PortList; tempport; tempport = tempport->next)
			{
				if (tempport->socket == NOSOCKET)
					continue;

				if (FD_ISSET(tempport->socket, &readfds))
				{
					/*
					 * a client has connected on one of our listening ports
					 * (P: lines) - accept their connection, and perform
					 * ident etc
					 */

					ConnectClient(tempport);
				}
			}

			/* this is for info coming from a dcc/telnet/tcm client */
			for (dccptr = connections; dccptr != NULL; dccptr = dccnext)
			{
				assert(dccptr->socket != NOSOCKET);
				dccnext = dccptr->next;

				if (IsDccConnect(dccptr)
				        && FD_ISSET(dccptr->socket, &writefds))
				{
					if (!GreetDccUser(dccptr))
						DeleteDccClient(dccptr);

					continue;
				}

				if (dccptr->authfd >= 0)
				{
					if (FD_ISSET(dccptr->authfd, &writefds) &&
					        (dccptr->flags & SOCK_WRID))
						writeauth(dccptr); /* send ident request */

					if (FD_ISSET(dccptr->authfd, &readfds))
						readauth(dccptr); /* read ident reply */
				}

				if (dccptr->flags & SOCK_NEEDID)
					continue;

				if (FD_ISSET(dccptr->socket, &readfds))
				{
					/* read and parse any data from the socket */
					if (!ReadSock(dccptr))
					{
						CloseConnection(dccptr);
						continue;
					}
				} /* if (FD_ISSET(dccptr->socket, &readfds)) */
			} /* for (dccptr = connections; dccptr; dccptr = dccptr->next) */

			dccnext = NULL;   /* XXX */
		} /* if (SelectResult > 0) */
		else
		{
			/* Also check whether is errno set at all.. -kre */
			if ((SelectResult == (-1)) && errno && (errno != EINTR))
			{
#ifdef DEBUGMODE
				fprintf(stderr,
				        "Connection closed: %s\n",
				        strerror(errno));
#endif

				putlog(LOG1, "Lost connection to %s:%d (%s)",
				       currenthub->hostname,
				       currenthub->port,
				       strerror(errno));

				return;
			}
		}
	} /* for (;;) */
} /* ReadSocketInfo() */
Пример #9
0
void
UpdateChanModes(struct Luser *lptr, char *who, struct Channel *cptr,
                char *modes)

{
  int add;
  char *tmp, *p;
  register char ch;
  struct Luser *userptr;
#if defined(NICKSERVICES) && defined(CHANNELSERVICES)
  int cs_deoped = 0; /* was chanserv deoped? */
#endif

  char **modeargs; /* arguements to +l/k/o/v modes */
  char tempargs[MAXLINE];
  int argcnt; /* number of arguements */
  int argidx; /* current index in modeargs[] */

#ifndef SAVE_TS
  char sendstr[MAXLINE];
#endif

  if (!cptr)
    return;

  assert(lptr || who);

  if (lptr)
  {
    SendUmode(OPERUMODE_M,
      "*** %s: Mode [%s] by %s!%s@%s",
      cptr->name,
      modes,
      lptr->nick,
      lptr->username,
      lptr->hostname);

    putlog(LOG3,
      "%s: mode change \"%s\" by %s!%s@%s",
      cptr->name,
      modes,
      lptr->nick,
      lptr->username,
      lptr->hostname);
  }
  else
  {
    SendUmode(OPERUMODE_M,
      "*** %s: Mode [%s] by %s",
      cptr->name,
      modes,
      who);

    putlog(LOG3,
      "%s: mode change \"%s\" by %s",
      cptr->name,
      modes,
      who);
  }

  if ((tmp = strchr(modes, ' ')))
    strcpy(tempargs, *(tmp + 1) ? tmp + 1 : "");
  else
    tempargs[0] = '\0';

  argcnt = SplitBuf(tempargs, &modeargs);

  /*
   * This routine parses the given channel modes and keeps
   * the corresponding lists correctly updated - also make
   * sure OperServ and ChanServ remain opped
   */

  add = 0;
  argidx = (-1);

  for (tmp = modes; *tmp; ++tmp)
  {
    ch = *tmp;

    if (IsSpace(ch))
      break;

    switch (ch)
    {
      case ' ':
      case '\n':
      case '\r': break;

      case '-':
      {
        add = 0;
        break;
      }
      case '+':
      {
        add = 1;
        break;
      }

      /*
       * Op/DeOp
       */
      case 'o':
      {
        ++argidx;
        if (argidx >= argcnt)
        {
          /*
           * there are more 'o' flags than there are nicknames,
           * just break
           */
          break;
        }

        if (!(userptr = FindClient(modeargs[argidx])))
          break;

        SetChannelMode(cptr, add, MODE_O, userptr, 0);

        if (add)
        {
        #ifdef STATSERVICES
          if (lptr)
            ++lptr->numops;
        #endif
        } /* if (add) */
        else
        {
          if (userptr == Me.osptr)
          {
            if (!FloodCheck(cptr, lptr, Me.osptr, 0))
            {
	      #ifdef SAVE_TS
                os_part(cptr);
                os_join(cptr);
	      #else
                toserv(":%s MODE %s +o %s\n",
                  n_OperServ,
                  cptr->name,
                  n_OperServ);
	      #endif
            }

            if (!lptr)
            {
              putlog(LOG1, "%s: %s attempted to deop %s",
                cptr->name,
                who,
                n_OperServ);
            }
            else
            {
              putlog(LOG1, "%s: %s!%s@%s attempted to deop %s",
                cptr->name,
                lptr->nick,
                lptr->username,
                lptr->hostname,
                n_OperServ);
            }
          }
        #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
          else if (userptr == Me.csptr)
          {
            cs_deoped = 1;
          }
        #endif /* defined(NICKSERVICES) && defined(CHANNELSERVICES) */

        #ifdef STATSERVICES
          if (lptr)
            ++lptr->numdops;
        #endif
        } /* else if (!add) */

        #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
          cs_CheckModes(lptr,
            FindChan(cptr->name),
            !add,
            MODE_O,
            userptr);
        #endif

        break;
      } /* case 'o' */

      /*
       * Voice/DeVoice
       */
      case 'v':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

        if (!(userptr = FindClient(modeargs[argidx])))
          break;

        SetChannelMode(cptr, add, MODE_V, userptr, 0);

        if (add)
        {
        #ifdef STATSERVICES
          if (lptr)
            ++lptr->numvoices;
        #endif
        }
        else
        {
        #ifdef STATSERVICES
          if (lptr)
            ++lptr->numdvoices;
        #endif
        } /* else if (!add) */

      #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
        cs_CheckModes(lptr,
          FindChan(cptr->name),
          !add,
          MODE_V,
          userptr);
      #endif

        break;
      } /* case 'v' */

#ifdef HYBRID7
      /* HalfOp/DeHalfOp -Janos */
      case 'h':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

        if (!(userptr = FindClient(modeargs[argidx])))
          break;

        SetChannelMode(cptr, add, MODE_H, userptr, 0);

        if (add)
        {
#ifdef STATSERVICES
          if (lptr)
            ++lptr->numhops;
#endif
        }
        else
        {
#ifdef STATSERVICES
          if (lptr)
            ++lptr->numdhops;
#endif
        } /* else if (!add) */

#if defined(NICKSERVICES) && defined(CHANNELSERVICES)
        cs_CheckModes(lptr, FindChan(cptr->name), !add, MODE_H, userptr);
#endif
        break;
      } /* case 'h'*/
#endif /* HYBRID7 */

      /*
       * Channel limit
       */
      case 'l':
      {
        if (add)
        {
          ++argidx;
          if (argidx >= argcnt)
            break;

          cptr->limit = atoi(modeargs[argidx]);
        }
        else
          cptr->limit = 0;

      #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
        cs_CheckModes(lptr,
          FindChan(cptr->name),
          !add,
          MODE_L,
          0);
      #endif

        break;
      } /* case 'l' */

      /*
       * Channel key
       */
      case 'k':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

      #ifndef BLOCK_ALLOCATION
        if (cptr->key)
          MyFree(cptr->key);
      #endif

        if (add)
        {
        #ifdef BLOCK_ALLOCATION
          strncpy(cptr->key, modeargs[argidx], KEYLEN);
          cptr->key[KEYLEN] = '\0';
        #else
          cptr->key = MyStrdup(modeargs[argidx]);
        #endif /* BLOCK_ALLOCATION */
        }
        else
        {
        #ifdef BLOCK_ALLOCATION
          cptr->key[0] = '\0';
        #else
          cptr->key = 0;
        #endif /* BLOCK_ALLOCATION */
        }

      #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
        cs_CheckModes(lptr,
          FindChan(cptr->name),
          !add,
          MODE_K,
          0);
      #endif

        break;
      } /* case 'k' */

      /*
       * Channel forwarding target
       */
      case 'f':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

      #ifndef BLOCK_ALLOCATION
        if (cptr->forward)
          MyFree(cptr->forward);
      #endif

        if (add)
        {
        #ifdef BLOCK_ALLOCATION
          strncpy(cptr->forward, modeargs[argidx], CHANNELLEN);
          cptr->forward[CHANNELLEN] = '\0';
        #else
          cptr->forward = MyStrdup(modeargs[argidx]);
        #endif /* BLOCK_ALLOCATION */
        }
        else
        {
        #ifdef BLOCK_ALLOCATION
          cptr->forward[0] = '\0';
        #else
          cptr->forward = 0;
        #endif /* BLOCK_ALLOCATION */
        }

      #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
        cs_CheckModes(lptr,
          FindChan(cptr->name),
          !add,
          MODE_F,
          0);
      #endif

        break;
      } /* case 'f' */

      /*
       * Channel ban
       */
      case 'b':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

	/* if it's a forwarding ban like nick!ident@host!#channel
	 * just drop the forward channel
	 * found by CheeToS  -- jilles */
	p = strchr(modeargs[argidx], '!');
	if (p != NULL)
	{
	  p = strchr(p + 1, '!');
	  if (p != NULL)
	    *p = '\0';
	}

        if (add)
          AddBan(who, cptr, modeargs[argidx]);
        else
          DeleteBan(cptr, modeargs[argidx]);

	if (p != NULL)
	  *p = '!';

        break;
      } /* case 'b' */

#ifdef GECOSBANS
      /*
       * Channel deny
       */
      case 'd':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

        if (add)
          AddGecosBan(who, cptr, modeargs[argidx]);
        else
          DeleteGecosBan(cptr, modeargs[argidx]);

        break;
      } /* case 'd' */
#endif /* GECOSBANS */

      /*
       * Channel exception
       */
      case 'e':
      {
        ++argidx;
        if (argidx >= argcnt)
          break;

        if (add)
          AddException(who, cptr, modeargs[argidx]);
        else
          DeleteException(cptr, modeargs[argidx]);

        break;
      } /* case 'e' */

#ifdef HYBRID7
    /* Channel invite exception -Janos */
     case 'I':
     {
       ++argidx;
       if (argidx >= argcnt)
         break;

       if (add)
         AddInviteException(who, cptr, modeargs[argidx]);
       else
         DeleteInviteException(cptr, modeargs[argidx]);
       break;
     } /* case 'I' */
#endif /* HYBRID7 */

      default:
      {
        int modeflag = 0;

        if (ch == 's')
          modeflag = MODE_S;
        else if (ch == 'p')
          modeflag = MODE_P;
        else if (ch == 'n')
          modeflag = MODE_N;
        else if (ch == 't')
          modeflag = MODE_T;
        else if (ch == 'm')
          modeflag = MODE_M;
        else if (ch == 'i')
          modeflag = MODE_I;
        else if (ch == 'r')
          modeflag = MODE_R;
        else if (ch == 'z')
          modeflag = MODE_Z;
        else if (ch == 'P')
          modeflag = MODE_CAPP;
#if 0
        /* doesn't exist in 1.0.34 */
        else if (ch == 'F')
          modeflag = MODE_CAPF;
#endif
        else if (ch == 'Q')
          modeflag = MODE_CAPQ;
#ifdef HYBRID7
        else if (ch == 'a')
          modeflag = MODE_A;
#endif 
        else if (ch == 'c')
          modeflag = MODE_C;
        else if (ch == 'g')
          modeflag = MODE_G;
        else if (ch == 'L')
          modeflag = MODE_CAPL;
        else if (ch == 'R')
          modeflag = MODE_CAPR;

        if (modeflag)
        {
          if (add)
            cptr->modes |= modeflag;
          else
            cptr->modes &= ~modeflag;
        }

      #if defined(NICKSERVICES) && defined(CHANNELSERVICES)
        if (modeflag)
          cs_CheckModes(lptr,
            FindChan(cptr->name),
            !add,
            modeflag,
            0);
      #endif

        break;
      } /* default: */
    } /* switch (*tmp) */
  } /* for (tmp = modes; *tmp; ++tmp) */

  MyFree(modeargs);

#if defined(NICKSERVICES) && defined(CHANNELSERVICES)
  if ((cs_deoped) && (!FloodCheck(cptr, lptr, Me.csptr, 0)))
  {
    /* reop ChanServ */
    #ifdef SAVE_TS
      cs_part(cptr);
      cs_join(FindChan(cptr->name));
    #else
      toserv(":%s MODE %s +o %s\n",
        n_ChanServ,
        cptr->name,
        n_ChanServ);
    #endif

    if (!lptr)
      putlog(LOG1, "%s: %s attempted to deop %s",
        cptr->name,
        who,
        n_ChanServ);
    else
      putlog(LOG1, "%s: %s!%s@%s attempted to deop %s",
        cptr->name,
        lptr->nick,
        lptr->username,
        lptr->hostname,
        n_ChanServ);
  }
#endif /* defined(NICKSERVICES) && defined(CHANNELSERVICES) */

} /* UpdateChanModes() */
Пример #10
0
void
RemoveFromChannel(struct Channel *cptr, struct Luser *lptr)

{
  struct UserChannel *tempchan,
                     *prev = NULL;
  struct ChannelUser *tempuser,
                     *prev2 = NULL;

  if (!cptr || !lptr)
    return;

  SendUmode(OPERUMODE_P,
    "*** Channel part: %s (%s)",
    lptr->nick,
    cptr->name);

  /* Is this the contact? */
#ifdef CHANNELSERVICES
  {
    struct NickInfo *nptr;
    struct ChanInfo *ciptr;
    if ((nptr = FindNick(lptr->nick)) && (ciptr = FindChan(cptr->name)))
      {
	if (nptr->flags & NS_IDENTIFIED)
	  {
	    if (ciptr->contact && irccmp(lptr->nick, ciptr->contact) == 0)
	      /* That's the contact joining. Update activity timer */
	      ciptr->last_contact_active = current_ts;
	    if (ciptr->alternate && irccmp(lptr->nick, ciptr->alternate) == 0)
	      ciptr->last_alternate_active = current_ts;
	  }
      }
  }
#endif

  /* remove cptr from lptr's chan list */
  for (tempchan = lptr->firstchan; tempchan; tempchan = tempchan->next)
  {
    if (cptr == tempchan->chptr)
    {
      if (prev)
        prev->next = tempchan->next;
      else
        lptr->firstchan = tempchan->next;
      MyFree(tempchan);
      tempchan = NULL;
      break;
    }
    prev = tempchan;
  }

  /* remove lptr from cptr's nick list */
  for (tempuser = cptr->firstuser; tempuser; tempuser = tempuser->next)
  {
    if (lptr == tempuser->lptr)
    {
      if (prev2)
        prev2->next = tempuser->next;
      else
        cptr->firstuser = tempuser->next;
      MyFree(tempuser);
      tempuser = NULL;
      --cptr->numusers;
      break;
    }
    prev2 = tempuser;
  }

  if (cptr->numusers == 0)
    DeleteChannel(cptr); /* the last nick left the chan, erase it */
} /* RemoveFromChannel() */
Пример #11
0
struct Channel *
AddChannel(char **line, int nickcnt, char **nicks)

{
  char *names;
  char **anames;
  char *currnick;
  char modes[MAXLINE];
  struct Channel *chname, *cptr;
  struct Channel *tempchan;
  int ii, ncnt, acnt;

  ncnt = 5; /* default position for channel nicks, if no limit/key */
  strcpy(modes, line[4]);
  while (line[ncnt][0] != ':')
    {
      strcat(modes, " ");
      strcat(modes, line[ncnt]);
      ncnt++;
    }

  if (nickcnt > 0)
  {
    acnt = nickcnt;
    anames = nicks;
  }
  else
  {
    names = line[ncnt];
    names++; /* point past the leading : */

    ii = strlen(names);

    /* kill the \n char on the end */
    if (IsSpace(names[ii - 2]))
      names[ii - 2] = '\0';
    else if (IsSpace(names[ii - 1]))
      names[ii - 1] = '\0';

    acnt = SplitBuf(names, &anames);
  }

  if (!(cptr = FindChannel(line[3])))
  {
  #ifdef BLOCK_ALLOCATION

    tempchan = (struct Channel *) BlockSubAllocate(ChannelHeap);
    memset(tempchan, 0, sizeof(struct Channel));
    strncpy(tempchan->name, line[3], CHANNELLEN);

  #else

    tempchan = (struct Channel *) MyMalloc(sizeof(struct Channel));
    memset(tempchan, 0, sizeof(struct Channel));
    tempchan->name = MyStrdup(line[3]);

  #endif /* BLOCK_ALLOCATION */

    tempchan->since = atol(line[2]);
    tempchan->numusers = acnt;

    tempchan->next = ChannelList;
    tempchan->prev = NULL;
    if (tempchan->next)
      tempchan->next->prev = tempchan;

    HashAddChan(tempchan);

    ChannelList = tempchan;
    chname = ChannelList;

    ++Network->TotalChannels;
  #ifdef STATSERVICES
    if (Network->TotalChannels > Network->MaxChannels)
    {
      Network->MaxChannels = Network->TotalChannels;
      Network->MaxChannels_ts = current_ts;

      if ((Network->MaxChannels % 10) == 0)
      {
        /* notify +y people about new max channel count */
        SendUmode(OPERUMODE_Y,
          "*** New Max Channel Count: %ld",
          Network->MaxChannels);
      }
    }
    if (Network->TotalChannels > Network->MaxChannelsT)
    {
      Network->MaxChannelsT = Network->TotalChannels;
      Network->MaxChannelsT_ts = current_ts;
    }
  #endif /* STATSERVICES */
  }
  else /* it's an existing channel, but someone has joined it */
  {
    cptr->numusers += acnt;
    chname = cptr;
  }

  /* Add the channel to each nick's channel list */
  for (ii = 0; ii < acnt; ii++)
  {
    currnick = GetNick(anames[ii]);
    if (!currnick)
      continue;

    if (!IsChannelMember(chname, FindClient(currnick)))
    {
      /*
       * Use anames[ii] instead of currnick here so we get
       * the @/+ flags
       */
      AddToChannel(chname, anames[ii]);
    }
    else
      chname->numusers--;
  }
  
  /* finally, add the modes for the channel */
  UpdateChanModes(0, line[0] + 1, chname, modes);

  /*
   * Only free anames[] if there was no nick list
   * given
   */
  if (!nickcnt)
    MyFree(anames);

  return (chname);
} /* AddChannel() */