anachronism
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:An RFC-compliant implementation of the Telnet protocol
# Anachronism
Anachronism is a fully-compliant implementation of [the Telnet protocol][wiki-telnet]. Fallen
out of favor in this day and age, most people only know it as a command-line
tool for debugging HTTP. Today, Telnet is most commonly used in the realm of
[MUDs][wiki-muds], though there are still a few other niches filled by Telnet.

Anachronism offers a simple API for translating between streams of data and
events, and is completely network-agnostic. Anachronism also offers **channels**, an
abstraction layer which treats Telnet as a data multiplexer. Channels make it
extremely easy to build reusable modules for Telnet sub-protocols such
as MCCP (MUD Client Compression Protocol), which can be written once and plugged
into any application that wants to include support.

[wiki-telnet]: http://en.wikipedia.org/wiki/Telnet (Telnet at Wikipedia)
[wiki-muds]: http://en.wikipedia.org/wiki/MUD (MUDs at Wikipedia)

## Installation
While Anachronism has no dependencies and is theoretically cross-platform, I've
only written a Makefile for Linux. Help would be appreciated for making this
work across more platforms.

    make
    sudo make install

This will install Anachronism's shared and static libraries to /usr/local/lib,
and its header files to /usr/local/include/anachronism/. You may also need to
run `ldconfig` to make Anachronism available to your project's compiler/linker.

## Usage
The anachronism/nvt.h header can be consulted for more complete documentation.

### Basic usage
The core type exposed by Anachronism is the telnet\_nvt, which represents the
Telnet RFC's "Network Virtual Terminal". An NVT is created using
telnet\_nvt\_new(). When creating an NVT, you must provide it with a set of
callbacks to send events to, and an optional void\* to store as the event
handler's context. You can use telnet\_recv() to process incoming data, and
the telnet\_send\_\*() set of functions to emit outgoing data.

    #include 
    #include 
    
    void on_event(telnet_nvt* nvt, telnet_event* event)
    {
      switch (event->type)
      {
        // A data event (normal text received)
        case TELNET_EV_DATA:
        {
          telnet_data_event* ev = (telnet_data_event*)event;
          printf("[IN]: %.*s\n", ev->length, ev->data);
          break;
        }
        
        // Outgoing data emitted by the NVT
        case TELNET_EV_SEND:
        {
          telnet_send_event* ev = (telnet_send_event*)event;
          printf("[OUT]: %.*s\n", ev->length, ev->data);
          break;
        }
      }
    }
    
    int main()
    {
      // Create an NVT
      telnet_nvt* nvt = telnet_nvt_new(NULL, &on_event, NULL, NULL);
      
      // Process some incoming data
      const char* data = "foo bar baz";
      telnet_receive(nvt, (const telnet_byte*)data, strlen(data), NULL);
      
      // Free the NVT
      telnet_nvt_free(nvt);
      return 0;
    }

### Telopts
Anachronism provides an easy-to-use interface to Telnet's "telopt" functionality
via the telnet\_telopt\_*() set of functions. As telopts are negotiated and
utilized, events are sent to the telopt callback provided to telnet_nvt_new().

    #include 
    #include 
    
    void on_event(telnet_nvt* nvt, telnet_event* event)
    {
      switch (event->type)
      {
        // Outgoing data emitted by the NVT
        case TELNET_EV_SEND:
        {
          telnet_send_event* ev = (telnet_send_event*)event;
          printf("[OUT]: %.*s\n", ev->length, ev->data);
          break;
        }
      }
    }
    
    void on_telopt_event(telnet_nvt* nvt, telnet_byte telopt, telnet_telopt_event* event)
    {
      // telopt is the telopt this event was triggered for
      
      switch (event->type)
      {
        case TELNET_EV_TELOPT_TOGGLE:
          telnet_telopt_toggle_event* ev = (telnet_telopt_toggle_event*)event;
          // ev->where is TELNET_TELOPT_LOCAL or TELNET_TELOPT_REMOTE,
          //     corresponding to Telnet's WILL/WONT and DO/DONT commands.
          // ev->status is TELNET_TELOPT_ON or TELNET_TELOPT_OFF.
          break;
        case TELNET_EV_TELOPT_FOCUS:
          telnet_telopt_focus_event* ev = (telnet_telopt_focus_event*)event;
          // ev->focus is 1 or 0 depending on if a subnegotiation packet has
          //     begun or ended.
          break;
        case TELNET_EV_TELOPT_DATA:
          telnet_telopt_data_event* ev = (telnet_telopt_data_event*)event;
          // ev->data is a pointer to the received data.
          // ev->length is the length of the data buffer.
          break;
      }
    }
    
    int main()
    {
      // Create an NVT
      telnet_nvt* nvt = telnet_nvt_new(NULL, &on_event, &on_telopt_event, NULL);
      
      // Ask to enable a telopt locally (a WILL command)
      telnet_request_enable(nvt, 230, TELNET_LOCAL);
      
      // Process some incoming data
      const char* data = "\xFF\xFD\xE6" // IAC DO 230  (turn channel on)
                         "\xFF\xFA\xE6" // IAC SB 230  (switch to channel)
                         "foo bar baz"                 (send data)
                         "\xFF\xF0";    // IAC SE      (switch to main)
      telnet_receive(nvt, (const telnet_byte*)data, strlen(data), NULL);
      
      // Free the NVT
      telnet_nvt_free(nvt);
      return 0;
    }

### Interrupting
    TODO: Explain how to interrupt the parser.

## Alternatives
* [libtelnet][github-libtelnet], by Elanthis
It incorporates a number of (rather MUD-specific) protocols by default, though its API is quite different. [github-libtelnet]: https://github.com/elanthis/libtelnet (libtelnet on GitHub) ## Credits Someone from #startups on Freenode IRC suggested the name (I'm sure as a joke). If you read this, remind me who you are so I can credit you properly!

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。