Exemplo n.º 1
0
void
handle_encap(struct Client *client_p, struct Client *source_p,
		const char *command, int parc, char *parv[])
{
	struct Message *mptr;
	MessageHandler handler = 0;

	parv[0] = source_p->name;

	mptr = hash_parse(command);

	if(mptr == NULL || mptr->cmd == NULL)
		return;

	handler = mptr->handlers[ENCAP_HANDLER];

	(*handler)(client_p, source_p, parc, parv);
}
Exemplo n.º 2
0
void
handle_encap(struct Client *client_p, struct Client *source_p,
	     const char *command, int parc, const char *parv[])
{
	struct Message *mptr;
	struct MessageEntry ehandler;
	MessageHandler handler = 0;

	parv[0] = source_p->name;

	mptr = hash_parse(command);

	if(mptr == NULL || mptr->cmd == NULL)
		return;

	ehandler = mptr->handlers[ENCAP_HANDLER];
	handler = ehandler.handler;

	if(parc < ehandler.min_para || 
	   (ehandler.min_para && EmptyString(parv[ehandler.min_para - 1])))
		return;

	(*handler) (client_p, source_p, parc, parv);
}
Exemplo n.º 3
0
/*
 * parse a buffer.
 *
 * NOTE: parse() should not be called recusively by any other functions!
 */
void
parse(struct Client *client_p, char *pbuffer, char *bufend)
{
	struct Client *from = client_p;
	char *ch;
	char *s;
	char *end;
	int i;
	int paramcount, mpara = 0;
	char *numeric = 0;
	struct Message *mptr;

	Debug((DEBUG_DEBUG, "Parsing %s:", pbuffer));

	s_assert(!IsDead(client_p));
	s_assert(client_p->localClient->fd >= 0);
	if(IsDead(client_p) || client_p->localClient->fd < 0)
		return;
	s_assert(bufend-pbuffer < 512);

	for (ch = pbuffer; *ch == ' '; ch++)	/* skip spaces */
		/* null statement */ ;

	para[0] = from->name;

	if(*ch == ':')
	{
		ch++;

		/*
		 * Copy the prefix to 'sender' assuming it terminates
		 * with SPACE (or NULL, which is an error, though).
		 */

		sender = ch;

		if((s = strchr(ch, ' ')))
		{
			*s = '\0';
			s++;
			ch = s;
		}

		i = 0;

		if(*sender && IsServer(client_p))
		{
			from = find_client(sender);
			if(from == NULL)
			{
				from = find_server(sender);
			}

			/* Hmm! If the client corresponding to the
			 * prefix is not found--what is the correct
			 * action??? Now, I will ignore the message
			 * (old IRC just let it through as if the
			 * prefix just wasn't there...) --msa
			 */
			if(from == NULL)
			{
				Debug((DEBUG_ERROR, "Unknown prefix (%s)(%s) from (%s)",
				       sender, pbuffer, client_p->name));
				ServerStats->is_unpf++;

				remove_unknown(client_p, sender, pbuffer);

				return;
			}

			para[0] = from->name;

			if(from->from != client_p)
			{
				ServerStats->is_wrdi++;
				Debug((DEBUG_ERROR, "Message (%s) coming from (%s)",
				       pbuffer, client_p->name));

				cancel_clients(client_p, from, pbuffer);
				return;
			}
		}
		while (*ch == ' ')
			ch++;
	}

	if(*ch == '\0')
	{
		ServerStats->is_empt++;
		Debug((DEBUG_NOTICE, "Empty message from host %s:%s", client_p->name, from->name));
		return;
	}

	/*
	 * Extract the command code from the packet.  Point s to the end
	 * of the command code and calculate the length using pointer
	 * arithmetic.  Note: only need length for numerics and *all*
	 * numerics must have parameters and thus a space after the command
	 * code. -avalon
	 */

	/* EOB is 3 chars long but is not a numeric */

	if(*(ch + 3) == ' ' &&	/* ok, lets see if its a possible numeric.. */
	   IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
	{
		mptr = (struct Message *) NULL;
		numeric = ch;
		paramcount = MAXPARA;
		ServerStats->is_num++;
		s = ch + 3;	/* I know this is ' ' from above if */
		*s++ = '\0';	/* blow away the ' ', and point s to next part */
	}
	else
	{
		int ii = 0;

		if((s = strchr(ch, ' ')))
			*s++ = '\0';

		mptr = hash_parse(ch);

		if(!mptr || !mptr->cmd)
		{
			/*
			 * Note: Give error message *only* to recognized
			 * persons. It's a nightmare situation to have
			 * two programs sending "Unknown command"'s or
			 * equivalent to each other at full blast....
			 * If it has got to person state, it at least
			 * seems to be well behaving. Perhaps this message
			 * should never be generated, though...  --msa
			 * Hm, when is the buffer empty -- if a command
			 * code has been found ?? -Armin
			 */
			if(pbuffer[0] != '\0')
			{
				if(IsPerson(from))
					sendto_one(from,
						   ":%s %d %s %s :Unknown command",
						   me.name, ERR_UNKNOWNCOMMAND, from->name, ch);
				Debug((DEBUG_ERROR, "Unknown (%s) from %s",
				       ch, get_client_name(client_p, HIDE_IP)));
			}
			ServerStats->is_unco++;
			return;
		}

		paramcount = mptr->parameters;
		mpara = mptr->maxpara;

		ii = bufend - ((s) ? s : ch);
		mptr->bytes += ii;
	}

	end = bufend - 1;

	/* XXX this should be done before parse() is called */
	if(*end == '\n')
		*end-- = '\0';
	if(*end == '\r')
		*end = '\0';

	i = 0;

	if(s != NULL)
		i = string_to_array(s, para);

	if(mptr == (struct Message *) NULL)
	{
		do_numeric(numeric, client_p, from, i, para);
		return;
	}

	if(handle_command(mptr, client_p, from, i, para) < -1)
	{
		char *p;
		for (p = pbuffer; p <= end; p += 8)
		{
			/* HACK HACK */
			/* Its expected this nasty code can be removed
			 * or rewritten later if still needed.
			 */
			if((unsigned long) (p + 8) > (unsigned long) end)
			{
				for (; p <= end; p++)
				{
					ilog(L_CRIT, "%02x |%c", p[0], p[0]);
				}
			}
			else
				ilog(L_CRIT,
				     "%02x %02x %02x %02x %02x %02x %02x %02x |%c%c%c%c%c%c%c%c",
				     p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
				     p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
		}
	}
}
Exemplo n.º 4
0
/* parse()
 *
 * given a raw buffer, parses it and generates parv, parc and sender
 */
void
parse(struct Client *client_p, char *pbuffer, char *bufend)
{
	struct Client *from = client_p;
	char *ch;
	char *s;
	char *end;
	int i = 1;
	char *numeric = 0;
	struct Message *mptr;

	s_assert(MyConnect(client_p));
	s_assert(client_p->localClient->fd >= 0);
	if(IsAnyDead(client_p))
		return;

	for (ch = pbuffer; *ch == ' '; ch++)	/* skip spaces */
		/* null statement */ ;

	para[0] = from->name;

	if(*ch == ':')
	{
		ch++;

		/* point sender to the sender param */
		sender = ch;

		if((s = strchr(ch, ' ')))
		{
			*s = '\0';
			s++;
			ch = s;
		}

		if(*sender && IsServer(client_p))
		{
			from = find_any_client(sender);

			/* didnt find any matching client, issue a kill */
			if(from == NULL)
			{
				ServerStats->is_unpf++;
				remove_unknown(client_p, sender, pbuffer);
				return;
			}

			para[0] = from->name;

			/* fake direction, hmm. */
			if(from->from != client_p)
			{
				ServerStats->is_wrdi++;
				cancel_clients(client_p, from, pbuffer);
				return;
			}
		}
		while (*ch == ' ')
			ch++;
	}

	if(*ch == '\0')
	{
		ServerStats->is_empt++;
		return;
	}

	/* at this point there must be some sort of command parameter */

	/*
	 * Extract the command code from the packet.  Point s to the end
	 * of the command code and calculate the length using pointer
	 * arithmetic.  Note: only need length for numerics and *all*
	 * numerics must have parameters and thus a space after the command
	 * code. -avalon
	 */

	/* EOB is 3 chars long but is not a numeric */

	if(*(ch + 3) == ' ' &&	/* ok, lets see if its a possible numeric.. */
	   IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
	{
		mptr = NULL;
		numeric = ch;
		ServerStats->is_num++;
		s = ch + 3;	/* I know this is ' ' from above if */
		*s++ = '\0';	/* blow away the ' ', and point s to next part */
	}
	else
	{
		int ii = 0;

		if((s = strchr(ch, ' ')))
			*s++ = '\0';

		mptr = hash_parse(ch);

		/* no command or its encap only, error */
		if(!mptr || !mptr->cmd)
		{
			/*
			 * Note: Give error message *only* to recognized
			 * persons. It's a nightmare situation to have
			 * two programs sending "Unknown command"'s or
			 * equivalent to each other at full blast....
			 * If it has got to person state, it at least
			 * seems to be well behaving. Perhaps this message
			 * should never be generated, though...  --msa
			 * Hm, when is the buffer empty -- if a command
			 * code has been found ?? -Armin
			 */
			if(pbuffer[0] != '\0')
			{
				if(IsPerson(from))
					sendto_one(from, form_str(ERR_UNKNOWNCOMMAND),
						   me.name, from->name, ch);
			}
			ServerStats->is_unco++;
			return;
		}

		ii = bufend - ((s) ? s : ch);
		mptr->bytes += ii;
	}

	end = bufend - 1;

	/* XXX this should be done before parse() is called */
	if(*end == '\n')
		*end-- = '\0';
	if(*end == '\r')
		*end = '\0';

	if(s != NULL)
		i = string_to_array(s, para);

	if(mptr == NULL)
	{
		do_numeric(numeric, client_p, from, i, para);
		return;
	}

	if(handle_command(mptr, client_p, from, i, /* XXX discards const!!! */ (const char **)para) < -1)
	{
		char *p;
		for (p = pbuffer; p <= end; p += 8)
		{
			/* HACK HACK */
			/* Its expected this nasty code can be removed
			 * or rewritten later if still needed.
			 */
			if((unsigned long) (p + 8) > (unsigned long) end)
			{
				for (; p <= end; p++)
				{
					ilog(L_MAIN, "%02x |%c", p[0], p[0]);
				}
			}
			else
				ilog(L_MAIN,
				     "%02x %02x %02x %02x %02x %02x %02x %02x |%c%c%c%c%c%c%c%c",
				     p[0], p[1], p[2], p[3], p[4], p[5],
				     p[6], p[7], p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
		}
	}

}