src/irc_proto.h
author Tero Marttila <terom@fixme.fi>
Thu, 28 May 2009 01:17:36 +0300
branchnew-lib-errors
changeset 219 cefec18b8268
parent 100 cfb7776bd6f0
permissions -rw-r--r--
some of the lib/transport stuff compiles
#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