aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ssl_client.h
blob: dcbf9a0149b545defe90ebd3ca650855aff89e8d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  /********************************************************************\
  * BitlBee -- An IRC to other IM-networks gateway                     *
  *                                                                    *
  * Copyright 2002-2004 Wilmer van der Gaast and others                *
  \********************************************************************/

/* SSL module                                                           */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License with
  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  Suite 330, Boston, MA  02111-1307  USA
*/

/* ssl_client makes it easier to open SSL connections to servers. (It
   doesn't offer SSL server functionality yet, but it could be useful
   to add it later.) Different ssl_client modules are available, and
   ssl_client tries to make them all behave the same. It's very simple
   and basic, it just imitates the proxy_connect() function from the
   Gaim libs and passes the socket to the program once the handshake
   is completed. */

#include <glib.h>
#include "proxy.h"

/* Some generic error codes. Especially SSL_AGAIN is important if you
   want to do asynchronous I/O. */
#define SSL_OK            0
#define SSL_NOHANDSHAKE   1
#define SSL_AGAIN         2

extern int ssl_errno;

/* This is what your callback function should look like. */
typedef gboolean (*ssl_input_function)(gpointer, void*, b_input_condition);


/* Connect to host:port, call the given function when the connection is
   ready to be used for SSL traffic. This is all done asynchronously, no
   blocking I/O! (Except for the DNS lookups, for now...) */
G_MODULE_EXPORT void *ssl_connect( char *host, int port, ssl_input_function func, gpointer data );

/* Start an SSL session on an existing fd. Useful for STARTTLS functionality,
   for example in Jabber. */
G_MODULE_EXPORT void *ssl_starttls( int fd, ssl_input_function func, gpointer data );

/* Obviously you need special read/write functions to read data. */
G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );
G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );

/* Abort the SSL connection and disconnect the socket. Do not use close()
   directly, both the SSL library and the peer will be unhappy! */
G_MODULE_EXPORT void ssl_disconnect( void *conn_ );

/* Get the fd for this connection, you will usually need it for event
   handling. */
G_MODULE_EXPORT int ssl_getfd( void *conn );

/* This function returns GAIM_INPUT_READ/WRITE. With SSL connections it's
   possible that something has to be read while actually were trying to
   write something (think about key exchange/refresh/etc). So when an
   SSL operation returned SSL_AGAIN, *always* use this function when
   adding an event handler to the queue. (And it should perform exactly
   the same action as the handler that just received the SSL_AGAIN.) */
G_MODULE_EXPORT b_input_condition ssl_getdirection( void *conn );
n129'>129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
module RDoc; end

module RDoc::DOT

  TAB = '  '
  TAB2 = TAB * 2

  # options for node declaration
  NODE_OPTS = [
    'bgcolor',
    'color',
    'fontcolor',
    'fontname',
    'fontsize',
    'height',
    'width',
    'label',
    'layer',
    'rank',
    'shape',
    'shapefile',
    'style',
    'URL',
  ]

  # options for edge declaration
  EDGE_OPTS = [
    'color',
    'decorate',
    'dir',
    'fontcolor',
    'fontname',
    'fontsize',
    'id',
    'label',
    'layer',
    'lhead',
    'ltail',
    'minlen',
    'style',
    'weight'
  ]

  # options for graph declaration
  GRAPH_OPTS = [
    'bgcolor',
    'center',
    'clusterrank',
    'color',
    'compound',
    'concentrate',
    'fillcolor',
    'fontcolor',
    'fontname',
    'fontsize',
    'label',
    'layerseq',
    'margin',
    'mclimit',
    'nodesep',
    'nslimit',
    'ordering',
    'orientation',
    'page',
    'rank',
    'rankdir',
    'ranksep',
    'ratio',
    'size',
    'style',
    'URL'
  ]

  # a root class for any element in dot notation
  class SimpleElement
    attr_accessor :name

    def initialize( params = {} )
      @label = params['name'] ? params['name'] : ''
    end

    def to_s
      @name
    end
  end

  # an element that has options ( node, edge or graph )
  class Element < SimpleElement
    #attr_reader :parent
    attr_accessor :name, :options

    def initialize( params = {}, option_list = [] )
      super( params )
      @name = params['name'] ? params['name'] : nil
      @parent = params['parent'] ? params['parent'] : nil
      @options = {}
      option_list.each{ |i|
        @options[i] = params[i] if params[i]
      }
      @options['label'] ||= @name if @name != 'node'
    end

    def each_option
      @options.each{ |i| yield i }
    end

    def each_option_pair
      @options.each_pair{ |key, val| yield key, val }
    end

    #def parent=( thing )
    #    @parent.delete( self ) if defined?( @parent ) and @parent
    #    @parent = thing
    #end
  end


  # this is used when we build nodes that have shape=record
  # ports don't have options :)
  class Port < SimpleElement
    attr_accessor :label

    def initialize( params = {} )
      super( params )
      @name = params['label'] ? params['label'] : ''
    end
    def to_s
      ( @name && @name != "" ? "<#{@name}>" : "" ) + "#{@label}"
    end
  end

  # node element
  class Node < Element

    def initialize( params = {}, option_list = NODE_OPTS )
      super( params, option_list )
      @ports = params['ports'] ? params['ports'] : []
    end

    def each_port
      @ports.each{ |i| yield i }
    end

    def << ( thing )
      @ports << thing
    end

    def push ( thing )
      @ports.push( thing )
    end

    def pop
      @ports.pop
    end

    def to_s( t = '' )

      label = @options['shape'] != 'record' && @ports.length == 0 ?
        @options['label'] ?
        t + TAB + "label = \"#{@options['label']}\"\n" :
                    '' :
                    t + TAB + 'label = "' + " \\\n" +
                    t + TAB2 + "#{@options['label']}| \\\n" +
                    @ports.collect{ |i|
        t + TAB2 + i.to_s
      }.join( "| \\\n" ) + " \\\n" +
        t + TAB + '"' + "\n"

        t + "#{@name} [\n" +
        @options.to_a.collect{ |i|
        i[1] && i[0] != 'label' ?
          t + TAB + "#{i[0]} = #{i[1]}" : nil
      }.compact.join( ",\n" ) + ( label != '' ? ",\n" : "\n" ) +
        label +
        t + "]\n"
    end
  end

  # subgraph element is the same to graph, but has another header in dot
  # notation
  class Subgraph < Element

    def initialize( params = {}, option_list = GRAPH_OPTS )
      super( params, option_list )
      @nodes = params['nodes'] ? params['nodes'] : []
      @dot_string = 'subgraph'
    end

    def each_node
      @nodes.each{ |i| yield i }
    end

    def << ( thing )
      @nodes << thing
    end

    def push( thing )
      @nodes.push( thing )
    end

    def pop
      @nodes.pop
    end

    def to_s( t = '' )
      hdr = t + "#{@dot_string} #{@name} {\n"

      options = @options.to_a.collect{ |name, val|
        val && name != 'label' ?
          t + TAB + "#{name} = #{val}" :
        name ? t + TAB + "#{name} = \"#{val}\"" : nil
      }.compact.join( "\n" ) + "\n"

      nodes = @nodes.collect{ |i|
        i.to_s( t + TAB )
      }.join( "\n" ) + "\n"
      hdr + options + nodes + t + "}\n"
    end
  end

  # this is graph
  class Digraph < Subgraph
    def initialize( params = {}, option_list = GRAPH_OPTS )
      super( params, option_list )
      @dot_string = 'digraph'
    end
  end

  # this is edge
  class Edge < Element
    attr_accessor :from, :to
    def initialize( params = {}, option_list = EDGE_OPTS )
      super( params, option_list )
      @from = params['from'] ? params['from'] : nil
      @to = params['to'] ? params['to'] : nil
    end

    def to_s( t = '' )
      t + "#{@from} -> #{to} [\n" +
        @options.to_a.collect{ |i|
        i[1] && i[0] != 'label' ?
          t + TAB + "#{i[0]} = #{i[1]}" :
        i[1] ? t + TAB + "#{i[0]} = \"#{i[1]}\"" : nil
      }.compact.join( "\n" ) + "\n" + t + "]\n"
    end
  end

end