#ifndef IRC_PROTO_H
#define IRC_PROTO_H
/**
* @file
*
* General IRC protocol things, such as prefix/nickmask/nickname parsing
*/
#include "error.h"
#include <stddef.h>
/**
* Default TCP port for normal connections
*/
#define IRC_PORT "6667"
/**
* Default TCP port for SSL connections
*/
#define IRC_SSL_PORT "6697"
/**
* Maximum length of an IRC nickname including terminating NUL.
*/
#define IRC_NICK_MAX (30 + 1)
/**
* Maximum length of an IRC prefix/nickmask string, including any termianting NULs.
*
* XXX: currently this is pretty large, but does it really matter? We have more than 4k stack...
*/
#define IRC_PREFIX_MAX 510
/**
* Maximum length of an IRC nickname channel flags prefix, including any terminating NUL
*/
#define IRC_CHANFLAGS_MAX (8 + 1)
/**
* The set of characters that are considered nickname channel flag prefixes (i.e. op, voice, etc).
*
* XXX: many IRCd's have more than these, should use the 005 reply instead.
*/
#define IRC_CHANFLAGS "@+"
/**
* Parsed nickmask. For normal user prefixes, all fields will be non-NULL. For server prefixes, nickname and username
* will be NULL, and hostname will be the server name.
*/
struct irc_nm {
/** Nickname, not normalized */
const char *nickname;
/** Username, including any ident-related prefix from the network */
const char *username;
/** Hostname, either reverse DNS hostname, literal IPv4, literal IPv6, or something else... */
const char *hostname;
};
/**
* Parse a full nickmask from a prefix, mutating the value of the given buffer, and returning pointers into the buffer
* inside \a nm.
*/
err_t irc_nm_parse_buf (struct irc_nm *nm, char *prefix);
/**
* Same as irc_nm_parse_buf(), but copies the prefix into the given mutable buffer of at least IRC_PREFIX_MAX bytes and
* returns pointers into that instead.
*/
err_t irc_nm_parse (struct irc_nm *nm, char *buf, const char *prefix);
/**
* Compare two nicknames for equality, with standard cmp() semantics.
*/
int irc_cmp_nick (const char *nick1, const char *nick2);
/**
* Compare up to the first n chars of the two nickname strings for equality, with standard cmp() semantics.
*/
int irc_ncmp_nick (const char *nick1, const char *nick2, size_t n);
/**
* Parse the nickname portion of a prefix, storing it in the given buffer of IRC_NICK_MAX bytes.
*/
err_t irc_prefix_parse_nick (const char *prefix, char nick[IRC_NICK_MAX]);
/**
* Compare the nickname in the given prefix and with the given nickname for equality.
*
* @return -err for invalid prefix, 0 for match, >0 for non-match.
*/
int irc_prefix_cmp_nick (const char *prefix, const char *nick);
/**
* Copy the prefixed flags from the given nickname into the given flags buffer (of at least IRC_CHANFLAGS_MAX bytes) and
* NUL-terminate it. Returns a pointer to the actual nickname itself.
*
* @param nickname the nickname including prefixed chanflags
* @param chanflags buffer to store the parsed chanflags into
* @return a pointer to the first char of the actual nickname
*/
const char* irc_nick_chanflags (const char *nickname, char chanflags[IRC_CHANFLAGS_MAX]);
/**
* @defgroup IRC_RPL_ IRC command numerics
* @{
*/
/**
* 001 <nick> "Welcome to the Internet Relay Network <nick>!<user>@<host>"
*
* The first "official" reply sent by the server after the NICK/USER registration was accepted.
*/
#define IRC_RPL_WELCOME "001"
/**
* 353 <nick> ( "=" | "*" | "@" ) <channel> ( [ "@" | "+" ] <nick> [ " " ... ] )
*
* Sent by the server after a JOIN/NAMES command to give the full list of users currently on a channel. The list may
* be split into multiple messages RPL_NAMREPLY messages, which are then terminated by a RPL_ENDOFNAMES reply.
*
* The first argument char denotes the "channel type", and is, apparently, one of the following, for those who care:
* @ secret
* * private
* = others (public)
*/
#define IRC_RPL_NAMREPLY "353"
/**
* 366 <nick> <channel> "End of NAMES list"
*
* Sent by the server to terminate a sequence of zero or more RPL_NAMREPLY messages from a JOIN/NAMES command.
*/
#define IRC_RPL_ENDOFNAMES "366"
// @}
#endif