[or-cvs] r15746: Document new TorCtl package, update example, remove old file (in torctl/trunk/python: . TorCtl)

mikeperry at seul.org mikeperry at seul.org
Tue Jul 8 05:07:19 UTC 2008


Author: mikeperry
Date: 2008-07-08 01:07:19 -0400 (Tue, 08 Jul 2008)
New Revision: 15746

Removed:
   torctl/trunk/python/TorCtl.py
   torctl/trunk/python/TorCtl0.py
   torctl/trunk/python/TorCtl1.py
Modified:
   torctl/trunk/python/README
   torctl/trunk/python/TorCtl/GeoIPSupport.py
   torctl/trunk/python/TorExample.py
Log:

Document new TorCtl package, update example, remove old
files.



Modified: torctl/trunk/python/README
===================================================================
--- torctl/trunk/python/README	2008-07-08 03:48:18 UTC (rev 15745)
+++ torctl/trunk/python/README	2008-07-08 05:07:19 UTC (rev 15746)
@@ -1,2 +1,44 @@
-We broke the version detection stuff in Tor 0.1.2.16 / 0.2.0.4-alpha.
-Go use the python libs in the torflow module; these are now obsolete. -RD
+                         TorCtl Python Bindings
+
+
+TorCtl is a python Tor controller with extensions to support path
+building and various constraints on node and path selection, as well as
+statistics gathering.
+
+Apps can hook into the TorCtl package at whatever level they wish. 
+
+The lowest level of interaction is to use the TorCtl module
+(TorCtl/TorCtl.py). Typically this is done by importing TorCtl.TorCtl
+and creating a TorCtl.Connection and extending from TorCtl.EventHandler.
+This class receives Tor controller events packaged into python classes
+from a TorCtl.Connection.
+
+The next level up is to use the TorCtl.PathSupport module. This is done
+by importing TorCtl.PathSupport and instantiating or extending from
+PathSupport.PathBuilder, which itself extends from TorCtl.EventHandler.
+This class handles circuit construction and stream attachment subject to
+policies defined by PathSupport.NodeRestrictor and
+PathSupport.PathRestrictor implementations.
+
+If you are interested in gathering statistics, you can instead
+instantiate or extend from StatsSupport.StatsHandler, which is
+again an event handler with hooks to record statistics on circuit
+creation, stream bandwidth, and circuit failure information.
+
+All of these modules are pydoced. For more detailed information than
+the above overview, you can do:
+
+# pydoc TorCtl.TorCtl
+# pydoc TorCtl.PathSupport
+# pydoc TorCtl.StatsSupport
+
+There is a minimalistic example of usage of the basic TorCtl.Connection
+and TorCtl.EventHandler in TorExample.py in this directory.
+
+For more extensive examples of the PathSupport and StatsSupport
+interfaces, see the TorFlow project at svn urls:
+
+https://tor-svn.freehaven.net/svn/torflow/trunk
+or
+https://tor-svn.freehaven.net/svn/torflow/branches/gsoc2008
+

Modified: torctl/trunk/python/TorCtl/GeoIPSupport.py
===================================================================
--- torctl/trunk/python/TorCtl/GeoIPSupport.py	2008-07-08 03:48:18 UTC (rev 15745)
+++ torctl/trunk/python/TorCtl/GeoIPSupport.py	2008-07-08 05:07:19 UTC (rev 15746)
@@ -2,14 +2,18 @@
 
 import struct
 import socket
-import GeoIP
 import TorCtl
 
 from TorUtil import plog
+try:
+  import GeoIP
+  # GeoIP data object: choose database here
+  geoip = GeoIP.new(GeoIP.GEOIP_STANDARD)
+  #geoip = GeoIP.open("./GeoLiteCity.dat", GeoIP.GEOIP_STANDARD)
+except:
+  plog("NOTICE", "No GeoIP library. GeoIPSupport.py will not work correctly")
+  # XXX: How do we bail entirely..  
 
-# GeoIP data object: choose database here
-geoip = GeoIP.new(GeoIP.GEOIP_STANDARD)
-#geoip = GeoIP.open("./GeoLiteCity.dat", GeoIP.GEOIP_STANDARD)
 
 class Continent:
   """ Continent class: The group attribute is to partition the continents

Deleted: torctl/trunk/python/TorCtl.py
===================================================================
--- torctl/trunk/python/TorCtl.py	2008-07-08 03:48:18 UTC (rev 15745)
+++ torctl/trunk/python/TorCtl.py	2008-07-08 05:07:19 UTC (rev 15746)
@@ -1,536 +0,0 @@
-#!/usr/bin/python
-# TorCtl.py -- Python module to interface with Tor Control interface.
-# Copyright 2005 Nick Mathewson -- See LICENSE for licensing information.
-#$Id$
-
-"""
-TorCtl -- Library to control Tor processes.  See TorCtlDemo.py for example use.
-"""
-
-import os
-import re
-import struct
-import sys
-import threading
-import Queue
-
-class TorCtlError(Exception):
-    "Generic error raised by TorControl code."
-    pass
-
-class TorCtlClosed(TorCtlError):
-    "Raised when the controller connection is closed by Tor (not by us.)"
-    pass
-
-class ProtocolError(TorCtlError):
-    "Raised on violations in Tor controller protocol"
-    pass
-
-class ErrorReply(TorCtlError):
-    "Raised when Tor controller returns an error"
-    pass
-
-class EventHandler:
-    """An 'EventHandler' wraps callbacks for the events Tor can return."""
-    def __init__(self):
-        """Create a new EventHandler."""
-        from TorCtl0 import EVENT_TYPE
-        self._map0 = {
-            EVENT_TYPE.CIRCSTATUS : self.circ_status,
-            EVENT_TYPE.STREAMSTATUS : self.stream_status,
-            EVENT_TYPE.ORCONNSTATUS : self.or_conn_status,
-            EVENT_TYPE.BANDWIDTH : self.bandwidth,
-            EVENT_TYPE.NEWDESC : self.new_desc,
-            EVENT_TYPE.DEBUG_MSG : self.msg,
-            EVENT_TYPE.INFO_MSG : self.msg,
-            EVENT_TYPE.NOTICE_MSG : self.msg,
-            EVENT_TYPE.WARN_MSG : self.msg,
-            EVENT_TYPE.ERR_MSG : self.msg,
-            }
-        self._map1 = {
-            "CIRC" : self.circ_status,
-            "STREAM" : self.stream_status,
-            "ORCONN" : self.or_conn_status,
-            "BW" : self.bandwidth,
-            "DEBUG" : self.msg,
-            "INFO" : self.msg,
-            "NOTICE" : self.msg,
-            "WARN" : self.msg,
-            "ERR" : self.msg,
-            "NEWDESC" : self.new_desc,
-            "ADDRMAP" : self.address_mapped
-            }
-
-    def handle0(self, evbody):
-        """Dispatcher: called from Connection when an event is received."""
-        evtype, args = self.decode0(evbody)
-        self._map0.get(evtype, self.unknown_event)(evtype, *args)
-
-    def decode0(self, body):
-        """Unpack an event message into a type/arguments-tuple tuple."""
-        if len(body)<2:
-            raise ProtocolError("EVENT body too short.")
-        evtype, = struct.unpack("!H", body[:2])
-        body = body[2:]
-        if evtype == EVENT_TYPE.CIRCSTATUS:
-            if len(body)<5:
-                raise ProtocolError("CIRCUITSTATUS event too short.")
-            status,ident = struct.unpack("!BL", body[:5])
-            path = _unterminate(body[5:]).split(",")
-            args = status, ident, path
-        elif evtype == EVENT_TYPE.STREAMSTATUS:
-            if len(body)<5:
-                raise ProtocolError("STREAMSTATUS event too short.")
-            status,ident = struct.unpack("!BL", body[:5])
-            target = _unterminate(body[5:])
-            args = status, ident, target
-        elif evtype == EVENT_TYPE.ORCONNSTATUS:
-            if len(body)<2:
-                raise ProtocolError("ORCONNSTATUS event too short.")
-            status = ord(body[0])
-            target = _unterminate(body[1:])
-            args = status, target
-        elif evtype == EVENT_TYPE.BANDWIDTH:
-            if len(body)<8:
-                raise ProtocolError("BANDWIDTH event too short.")
-            read, written = struct.unpack("!LL",body[:8])
-            args = read, written
-        elif evtype == EVENT_TYPE.OBSOLETE_LOG:
-            args = (_unterminate(body),)
-        elif evtype == EVENT_TYPE.NEWDESC:
-            args = (_unterminate(body).split(","),)
-        elif EVENT_TYPE.DEBUG_MSG <= evtype <= EVENT_TYPE.ERR_MSG:
-            args = (EVENT_TYPE.nameOf[evtype], _unterminate(body))
-        else:
-            args = (body,)
-
-        return evtype, args
-
-    def handle1(self, lines):
-        """Dispatcher: called from Connection when an event is received."""
-        for code, msg, data in lines:
-            evtype, args = self.decode1(msg)
-            self._map1.get(evtype, self.unknown_event)(evtype, *args)
-
-    def decode1(self, body):
-        """Unpack an event message into a type/arguments-tuple tuple."""
-        if " " in body:
-            evtype,body = body.split(" ",1)
-        else:
-            evtype,body = body,""
-        evtype = evtype.upper()
-        if evtype == "CIRC":
-            m = re.match(r"(\S+)\s+(\S+)(\s\S+)?", body)
-            if not m:
-                raise ProtocolError("CIRC event misformatted.")
-            status,ident,path = m.groups()
-            if path:
-                path = path.strip().split(",")
-            else:
-                path = []
-            args = status, ident, path
-        elif evtype == "STREAM":
-            m = re.match(r"(\S+)\s+(\S+)\s+(\S+)\s+(\S+)", body)
-            if not m:
-                raise ProtocolError("STREAM event misformatted.")
-            ident,status,circ,target = m.groups()
-            args = status, ident, target, circ
-        elif evtype == "ORCONN":
-            m = re.match(r"(\S+)\s+(\S+)", body)
-            if not m:
-                raise ProtocolError("ORCONN event misformatted.")
-            target, status = m.groups()
-            args = status, target
-        elif evtype == "BW":
-            m = re.match(r"(\d+)\s+(\d+)", body)
-            if not m:
-                raise ProtocolError("BANDWIDTH event misformatted.")
-            read, written = map(long, m.groups())
-            args = read, written
-        elif evtype in ("DEBUG", "INFO", "NOTICE", "WARN", "ERR"):
-            args = evtype, body
-        elif evtype == "NEWDESC":
-            args = ((" ".split(body)),)
-        elif evtype == "ADDRMAP":
-            m = re.match(r'(\S+)\s+(\S+)\s+(\"[^"]+\"|\w+)')
-            if not m:
-                raise ProtocolError("BANDWIDTH event misformatted.")
-            fromaddr, toaddr, when = m.groups()
-            if when.upper() == "NEVER":
-                when = None
-            else:
-                when = time.localtime(
-                    time.strptime(when[1:-1], "%Y-%m-%d %H:%M:%S"))
-            args = fromaddr, toaddr, when
-        else:
-            args = (body,)
-
-        return evtype, args
-
-    def unknown_event(self, eventtype, evtype, *args):
-        """Called when we get an event type we don't recognize.  This
-           is almost alwyas an error.
-        """
-        raise NotImplemented
-
-    def circ_status(self, eventtype, status, circID, path):
-        """Called when a circuit status changes if listening to CIRCSTATUS
-           events.  'status' is a member of CIRC_STATUS; circID is a numeric
-           circuit ID, and 'path' is the circuit's path so far as a list of
-           names.
-        """
-        raise NotImplemented
-
-    def stream_status(self, eventtype, status, streamID, target, circID="0"):
-        """Called when a stream status changes if listening to STREAMSTATUS
-           events.  'status' is a member of STREAM_STATUS; streamID is a
-           numeric stream ID, and 'target' is the destination of the stream.
-        """
-        raise NotImplemented
-
-    def or_conn_status(self, eventtype, status, target):
-        """Called when an OR connection's status changes if listening to
-           ORCONNSTATUS events. 'status' is a member of OR_CONN_STATUS; target
-           is the OR in question.
-        """
-        raise NotImplemented
-
-    def bandwidth(self, eventtype, read, written):
-        """Called once a second if listening to BANDWIDTH events.  'read' is
-           the number of bytes read; 'written' is the number of bytes written.
-        """
-        raise NotImplemented
-
-    def new_desc(self, eventtype, identities):
-        """Called when Tor learns a new server descriptor if listenting to
-           NEWDESC events.
-        """
-        raise NotImplemented
-
-    def msg(self, eventtype, severity, message):
-        """Called when a log message of a given severity arrives if listening
-           to INFO_MSG, NOTICE_MSG, WARN_MSG, or ERR_MSG events."""
-        raise NotImplemented
-
-    def address_mapped(self, eventtype, fromAddr, toAddr, expiry=None):
-        """Called when Tor adds a mapping for an address if listening
-           to ADDRESSMAPPED events.
-        """
-        raise NotImplemented
-
-class _ConnectionBase:
-    def __init__(self):
-        self._s = None
-        self._handler = None
-        self._handleFn = None
-        self._sendLock = threading.RLock()
-        self._queue = Queue.Queue()
-        self._thread = None
-        self._closedEx = None
-        self._closed = 0
-        self._closeHandler = None
-        self._eventThread = None
-        self._eventQueue = Queue.Queue()
-
-    def set_event_handler(self, handler):
-        """Cause future events from the Tor process to be sent to 'handler'.
-        """
-        raise NotImplemented
-
-    def set_close_handler(self, handler):
-        """Call 'handler' when the Tor process has closed its connection or
-           given us an exception.  If we close normally, no arguments are
-           provided; otherwise, it will be called with an exception as its
-           argument.
-        """
-        self._closeHandler = handler
-
-    def close(self):
-        """Shut down this controller connection"""
-        self._sendLock.acquire()
-        try:
-            self._queue.put("CLOSE")
-            self._eventQueue.put("CLOSE")
-            self._s.close()
-            self._s = None
-            self._closed = 1
-        finally:
-            self._sendLock.release()
-
-    def _read_reply(self):
-        """DOCDOC"""
-        raise NotImplementd
-
-    def launch_thread(self, daemon=1):
-        """Launch a background thread to handle messages from the Tor process."""
-        assert self._thread is None
-        t = threading.Thread(target=self._loop)
-        if daemon:
-            t.setDaemon(daemon)
-        t.start()
-        self._thread = t
-        t = threading.Thread(target=self._eventLoop)
-        if daemon:
-            t.setDaemon(daemon)
-        t.start()
-        self._eventThread = t
-        return self._thread
-
-    def _loop(self):
-        """Main subthread loop: Read commands from Tor, and handle them either
-           as events or as responses to other commands.
-        """
-        while 1:
-            ex = None
-            try:
-                isEvent, reply = self._read_reply()
-            except:
-                self._err(sys.exc_info())
-                return
-
-            if isEvent:
-                if self._handler is not None:
-                    self._eventQueue.put(reply)
-            else:
-                cb = self._queue.get()
-                cb(reply)
-
-    def _err(self, (tp, ex, tb), fromEventLoop=0):
-        """DOCDOC"""
-        if self._s:
-            try:
-                self.close()
-            except:
-                pass
-        self._sendLock.acquire()
-        try:
-            self._closedEx = ex
-            self._closed = 1
-        finally:
-            self._sendLock.release()
-        while 1:
-            try:
-                cb = self._queue.get(timeout=0)
-                if cb != "CLOSE":
-                    cb("EXCEPTION")
-            except Queue.Empty:
-                break
-        if self._closeHandler is not None:
-            self._closeHandler(ex)
-        return
-
-    def _eventLoop(self):
-        """DOCDOC"""
-        while 1:
-            reply = self._eventQueue.get()
-            if reply == "CLOSE":
-                return
-            try:
-                self._handleFn(reply)
-            except:
-                self._err(sys.exc_info(), 1)
-                return
-
-    def _sendImpl(self, sendFn, msg):
-        """DOCDOC"""
-        if self._thread is None:
-            self.launch_thread(1)
-        # This condition will get notified when we've got a result...
-        condition = threading.Condition()
-        # Here's where the result goes...
-        result = []
-
-        if self._closedEx is not None:
-            raise self._closedEx
-        elif self._closed:
-            raise TorCtl.TorCtlClosed()
-
-        def cb(reply,condition=condition,result=result):
-            condition.acquire()
-            try:
-                result.append(reply)
-                condition.notify()
-            finally:
-                condition.release()
-
-        # Sends a message to Tor...
-        self._sendLock.acquire()
-        try:
-            self._queue.put(cb)
-            sendFn(msg)
-        finally:
-            self._sendLock.release()
-
-        # Now wait till the answer is in...
-        condition.acquire()
-        try:
-            while not result:
-                condition.wait()
-        finally:
-            condition.release()
-
-        # ...And handle the answer appropriately.
-        assert len(result) == 1
-        reply = result[0]
-        if reply == "EXCEPTION":
-            raise self._closedEx
-
-        return reply
-
-class DebugEventHandler(EventHandler):
-    """Trivial event handler: dumps all events to stdout."""
-    def __init__(self, out=None):
-        if out is None:
-            out = sys.stdout
-        self._out = out
-
-    def handle0(self, body):
-        evtype, args = self.decode0(body)
-        print >>self._out,EVENT_TYPE.nameOf[evtype],args
-
-    def handle1(self, lines):
-        for code, msg, data in lines:
-            print >>self._out, msg
-
-def detectVersion(s):
-    """Helper: sends a trial command to Tor to tell whether it's running
-       the first or second version of the control protocol.
-    """
-    s.sendall("\x00\x00\r\n")
-    m = s.recv(4)
-    v0len, v0type = struct.unpack("!HH", m)
-    if v0type == '\x00\x00':
-        s.recv(v0len)
-        return 0
-    if '\n' not in m:
-        while 1:
-            c = s.recv(1)
-            if c == '\n':
-                break
-    return 1
-
-def parseHostAndPort(h):
-    """Given a string of the form 'address:port' or 'address' or
-       'port' or '', return a two-tuple of (address, port)
-    """
-    host, port = "localhost", 9100
-    if ":" in h:
-        i = h.index(":")
-        host = h[:i]
-        try:
-            port = int(h[i+1:])
-        except ValueError:
-            print "Bad hostname %r"%h
-            sys.exit(1)
-    elif h:
-        try:
-            port = int(h)
-        except ValueError:
-            host = h
-
-    return host, port
-
-def get_connection(sock):
-    """Given a socket attached to a Tor control port, detect the version of Tor
-       and return an appropriate 'Connection' object."""
-    v = detectVersion(sock)
-    if v == 0:
-        import TorCtl0
-        return TorCtl0.Connection(sock)
-    else:
-        import TorCtl1
-        return TorCtl1.Connection(sock)
-
-def secret_to_key(secret, s2k_specifier):
-    """Used to generate a hashed password string. DOCDOC."""
-    c = ord(s2k_specifier[8])
-    EXPBIAS = 6
-    count = (16+(c&15)) << ((c>>4) + EXPBIAS)
-
-    d = sha.new()
-    tmp = s2k_specifier[:8]+secret
-    slen = len(tmp)
-    while count:
-        if count > slen:
-            d.update(tmp)
-            count -= slen
-        else:
-            d.update(tmp[:count])
-            count = 0
-    return d.digest()
-
-def urandom_rng(n):
-    """Try to read some entropy from the platform entropy source."""
-    f = open('/dev/urandom', 'rb')
-    try:
-        return f.read(n)
-    finally:
-        f.close()
-
-def s2k_gen(secret, rng=None):
-    """DOCDOC"""
-    if rng is None:
-        if hasattr(os, "urandom"):
-            rng = os.urandom
-        else:
-            rng = urandom_rng
-    spec = "%s%s"%(rng(8), chr(96))
-    return "16:%s"%(
-        binascii.b2a_hex(spec + secret_to_key(secret, spec)))
-
-def s2k_check(secret, k):
-    """DOCDOC"""
-    assert k[:3] == "16:"
-
-    k =  binascii.a2b_hex(k[3:])
-    return secret_to_key(secret, k[:9]) == k[9:]
-
-def run_example(host,port):
-    print "host is %s:%d"%(host,port)
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    s.connect((host,port))
-    c = Connection(s)
-    c.set_event_handler(DebugEventHandler())
-    th = c.launchThread()
-    c.authenticate()
-    print "nick",`c.get_option("nickname")`
-    print c.get_option("DirFetchPeriod\n")
-    print `c.get_info("version")`
-    #print `c.get_info("desc/name/moria1")`
-    print `c.get_info("network-status")`
-    print `c.get_info("addr-mappings/all")`
-    print `c.get_info("addr-mappings/config")`
-    print `c.get_info("addr-mappings/cache")`
-    print `c.get_info("addr-mappings/control")`
-    print `c.map_address([("0.0.0.0", "Foobar.com"),
-                        ("1.2.3.4", "foobaz.com"),
-                        ("frebnitz.com", "5.6.7.8"),
-                        (".", "abacinator.onion")])`
-    print `c.extend_circuit(0,["moria1"])`
-    try:
-        print `c.extend_circuit(0,[""])`
-    except ErrorReply:
-        print "got error. good."
-    #send_signal(s,1)
-    #save_conf(s)
-
-    #set_option(s,"1")
-    #set_option(s,"bandwidthburstbytes 100000")
-    #set_option(s,"runasdaemon 1")
-    #set_events(s,[EVENT_TYPE.WARN])
-    c.set_events([EVENT_TYPE.ORCONNSTATUS, EVENT_TYPE.STREAMSTATUS,
-                  EVENT_TYPE.CIRCSTATUS, EVENT_TYPE.INFO_MSG,
-                  EVENT_TYPE.BANDWIDTH])
-
-    th.join()
-    return
-
-if __name__ == '__main__':
-    if len(sys.argv) > 2:
-        print "Syntax: TorControl.py torhost:torport"
-        sys.exit(0)
-    else:
-        sys.argv.append("localhost:9051")
-    sh,sp = parseHostAndPort(sys.argv[1])
-    run_example(sh,sp)
-

Deleted: torctl/trunk/python/TorCtl0.py
===================================================================
--- torctl/trunk/python/TorCtl0.py	2008-07-08 03:48:18 UTC (rev 15745)
+++ torctl/trunk/python/TorCtl0.py	2008-07-08 05:07:19 UTC (rev 15746)
@@ -1,446 +0,0 @@
-#!/usr/bin/python
-# TorCtl.py -- Python module to interface with Tor Control interface.
-# Copyright 2005 Nick Mathewson -- See LICENSE for licensing information.
-#$Id$
-
-"""
-TorCtl0 -- Library to control Tor processes.  See TorCtlDemo.py for example use.
-"""
-
-import binascii
-import os
-import sha
-import socket
-import struct
-import sys
-import TorCtl
-
-__all__ = [
-    "MSG_TYPE", "EVENT_TYPE", "CIRC_STATUS", "STREAM_STATUS",
-    "OR_CONN_STATUS", "SIGNAL", "ERR_CODES",
-    "TorCtlError", "ProtocolError", "ErrorReply", "Connection", "EventHandler",
-    ]
-
-class _Enum:
-    # Helper: define an ordered dense name-to-number 1-1 mapping.
-    def __init__(self, start, names):
-        self.nameOf = {}
-        idx = start
-        for name in names:
-            setattr(self,name,idx)
-            self.nameOf[idx] = name
-            idx += 1
-
-class _Enum2:
-    # Helper: define an ordered sparse name-to-number 1-1 mapping.
-    def __init__(self, **args):
-        self.__dict__.update(args)
-        self.nameOf = {}
-        for k,v in args.items():
-            self.nameOf[v] = k
-
-# Message types that client or server can send.
-MSG_TYPE = _Enum(0x0000,
-                 ["ERROR",
-                  "DONE",
-                  "SETCONF",
-                  "GETCONF",
-                  "CONFVALUE",
-                  "SETEVENTS",
-                  "EVENT",
-                  "AUTH",
-                  "SAVECONF",
-                  "SIGNAL",
-                  "MAPADDRESS",
-                  "GETINFO",
-                  "INFOVALUE",
-                  "EXTENDCIRCUIT",
-                  "ATTACHSTREAM",
-                  "POSTDESCRIPTOR",
-                  "FRAGMENTHEADER",
-                  "FRAGMENT",
-                  "REDIRECTSTREAM",
-                  "CLOSESTREAM",
-                  "CLOSECIRCUIT",
-                  ])
-
-# Make sure that the enumeration code is working.
-assert MSG_TYPE.SAVECONF == 0x0008
-assert MSG_TYPE.CLOSECIRCUIT == 0x0014
-
-# Types of "EVENT" message.
-EVENT_TYPE = _Enum(0x0001,
-                   ["CIRCSTATUS",
-                    "STREAMSTATUS",
-                    "ORCONNSTATUS",
-                    "BANDWIDTH",
-                    "OBSOLETE_LOG",
-                    "NEWDESC",
-                    "DEBUG_MSG",
-                    "INFO_MSG",
-                    "NOTICE_MSG",
-                    "WARN_MSG",
-                    "ERR_MSG",
-                    ])
-
-assert EVENT_TYPE.ERR_MSG == 0x000B
-assert EVENT_TYPE.OBSOLETE_LOG == 0x0005
-
-# Status codes for "CIRCSTATUS" events.
-CIRC_STATUS = _Enum(0x00,
-                    ["LAUNCHED",
-                     "BUILT",
-                     "EXTENDED",
-                     "FAILED",
-                     "CLOSED"])
-
-# Status codes for "STREAMSTATUS" events
-STREAM_STATUS = _Enum(0x00,
-                      ["SENT_CONNECT",
-                       "SENT_RESOLVE",
-                       "SUCCEEDED",
-                       "FAILED",
-                       "CLOSED",
-                       "NEW_CONNECT",
-                       "NEW_RESOLVE",
-                       "DETACHED"])
-
-# Status codes for "ORCONNSTATUS" events
-OR_CONN_STATUS = _Enum(0x00,
-                       ["LAUNCHED","CONNECTED","FAILED","CLOSED"])
-
-# Signal codes for "SIGNAL" events.
-SIGNAL = _Enum2(HUP=0x01,INT=0x02,USR1=0x0A,USR2=0x0C,TERM=0x0F)
-
-# Error codes for "ERROR" events.
-ERR_CODES = {
-  0x0000 : "Unspecified error",
-  0x0001 : "Internal error",
-  0x0002 : "Unrecognized message type",
-  0x0003 : "Syntax error",
-  0x0004 : "Unrecognized configuration key",
-  0x0005 : "Invalid configuration value",
-  0x0006 : "Unrecognized byte code",
-  0x0007 : "Unauthorized",
-  0x0008 : "Failed authentication attempt",
-  0x0009 : "Resource exhausted",
-  0x000A : "No such stream",
-  0x000B : "No such circuit",
-  0x000C : "No such OR"
-}
-
-def _unpack_singleton_msg(msg):
-    """Helper: unpack a single packet.  Return (None, minLength, body-so-far)
-       on incomplete packet or (type,body,rest) on somplete packet
-    """
-    if len(msg) < 4:
-        return None, 4, msg
-    length,type = struct.unpack("!HH",msg)
-    if len(msg) >= 4+length:
-        return type,msg[4:4+length],msg[4+length:]
-    else:
-        return None,4+length,msg
-
-def _minLengthToPack(bytes):
-    """Return the minimum number of bytes needed to pack the message 'smg'"""
-    whole,left = divmod(bytes,65535)
-    if left:
-        return whole*(65535+4)+4+left
-    else:
-        return whole*(65535+4)
-
-def _unpack_msg(msg):
-    "returns as for _unpack_singleton_msg"
-    tp,body,rest = _unpack_singleton_msg(msg)
-    if tp != MSG_TYPE.FRAGMENTHEADER:
-        return tp, body, rest
-
-    if len(body) < 6:
-        raise ProtocolError("FRAGMENTHEADER message too short")
-
-    realType,realLength = struct.unpack("!HL", body[:6])
-
-    # Okay; could the message _possibly_ be here?
-    minLength = _minLengthToPack(realLength+6)
-    if len(msg) < minLength:
-        return None,  minLength, msg
-
-    # Okay; optimistically try to build up the msg.
-    soFar = [ body[6:] ]
-    lenSoFarLen = len(body)-6
-    while len(rest)>=4 and lenSoFar < realLength:
-        ln, tp = struct.unpack("!HH", rest[:4])
-        if tp != MSG_TYPE.FRAGMENT:
-            raise ProtocolError("Missing FRAGMENT message")
-        soFar.append(rest[4:4+ln])
-        lenSoFar += ln
-        if 4+ln > len(rest):
-            rest = ""
-            leftInPacket = 4+ln-len(rest)
-        else:
-            rest = rest[4+ln:]
-            leftInPacket=0
-
-    if lenSoFar == realLength:
-        return realType, "".join(soFar), rest
-    elif lenSoFar > realLength:
-        raise ProtocolError("Bad fragmentation: message longer than declared")
-    else:
-        inOtherPackets = realLength-lenSoFar-leftInPacket
-        minLength = _minLengthToPack(inOtherPackets)
-        return None, len(msg)+leftInPacket+inOtherPackets, msg
-
-def _receive_singleton_msg(s):
-    """Read a single packet from the socket s.
-    """
-    body = ""
-    header = s.recv(4)
-    if not header:
-        raise TorCtl.TorCtlClosed()
-    length,type = struct.unpack("!HH",header)
-    if length:
-        while length > len(body):
-            more = s.recv(length-len(body))
-            if not more:
-                raise TorCtl.TorCtlClosed()
-            body += more
-    return length,type,body
-
-def _receive_message(s):
-    """Read a single message (possibly multi-packet) from the socket s."""
-    length, tp, body = _receive_singleton_msg(s)
-    if tp != MSG_TYPE.FRAGMENTHEADER:
-        return length, tp, body
-    if length < 6:
-        raise ProtocolError("FRAGMENTHEADER message too short")
-    realType,realLength = struct.unpack("!HL", body[:6])
-    data = [ body[6:] ]
-    soFar = len(data[0])
-    while 1:
-        length, tp, body = _receive_singleton_msg(s)
-        if tp != MSG_TYPE.FRAGMENT:
-            raise ProtocolError("Missing FRAGMENT message")
-        soFar += length
-        data.append(body)
-        if soFar == realLength:
-            return realLength, realType, "".join(data)
-        elif soFar > realLength:
-            raise ProtocolError("FRAGMENT message too long!")
-
-def pack_message(type, body=""):
-    """Given a message type and optional message body, generate a set of
-       packets to send.
-    """
-    length = len(body)
-    if length < 65536:
-        reqheader = struct.pack("!HH", length, type)
-        return "%s%s"%(reqheader,body)
-
-    fragheader = struct.pack("!HHHL",
-                             65535, MSG_TYPE.FRAGMENTHEADER, type, length)
-    msgs = [ fragheader, body[:65535-6] ]
-    body = body[65535-6:]
-    while body:
-        if len(body) > 65535:
-            fl = 65535
-        else:
-            fl = len(body)
-        fragheader = struct.pack("!HH", MSG_TYPE.FRAGMENT, fl)
-        msgs.append(fragheader)
-        msgs.append(body[:fl])
-        body = body[fl:]
-
-    return "".join(msgs)
-
-def _parseKV(body,sep=" ",term="\n"):
-    """Helper: parse a key/value list of the form [key sep value term]* .
-       Return a list of (k,v)."""
-    res = []
-    for line in body.split(term):
-        if not line: continue
-        k, v = line.split(sep,1)
-        res.append((k,v))
-    return res
-
-def _unterminate(s):
-    """Strip trailing NUL characters from s."""
-    if s[-1] == '\0':
-        return s[:-1]
-    else:
-        return s
-
-class Connection(TorCtl._ConnectionBase):
-    """A Connection represents a connection to the Tor process."""
-    def __init__(self, sock):
-        """Create a Connection to communicate with the Tor process over the
-           socket 'sock'.
-        """
-        TorCtl._ConnectionBase.__init__(self)
-        self._s = sock
-
-    def set_event_handler(self, handler):
-        """Cause future events from the Tor process to be sent to 'handler'.
-        """
-        self._handler = handler
-        self._handleFn = handler.handle0
-
-    def _doSend(self, (type, body)):
-        """Helper: Deliver a command of type 'type' and body 'body' to Tor.
-        """
-        self._s.sendall(pack_message(type, body))
-
-    def _read_reply(self):
-        length, tp, body = _receive_message(self._s)
-        return (tp == MSG_TYPE.EVENT), (tp, body)
-
-    def _sendAndRecv(self, tp, msg="", expectedTypes=(MSG_TYPE.DONE,)):
-        """Helper: Send a command of type 'tp' and body 'msg' to Tor,
-           and wait for a command in response.  If the response type is
-           in expectedTypes, return a (tp,body) tuple.  If it is an error,
-           raise ErrorReply.  Otherwise, raise ProtocolError.
-        """
-
-        tp, msg = self.sendImpl(self._doSend, (tp, msg))
-        if tp in expectedTypes:
-            return tp, msg
-        elif tp == MSG_TYPE.ERROR:
-            if len(msg)<2:
-                raise ProtocolError("(Truncated error message)")
-            errCode, = struct.unpack("!H", msg[:2])
-            raise ErrorReply((errCode,
-                              ERR_CODES.get(errCode,"[unrecognized]"),
-                              msg[2:]))
-        else:
-            raise ProtocolError("Unexpectd message type 0x%04x"%tp)
-
-    def authenticate(self, secret=""):
-        """Send an authenticating secret to Tor.  You'll need to call
-           this method before other commands.  You need to use a
-           password if Tor expects one.
-        """
-        self._sendAndRecv(MSG_TYPE.AUTH,secret)
-
-    def get_option(self,name):
-        """Get the value of the configuration option named 'name'.  To
-           retrieve multiple values, pass a list for 'name' instead of
-           a string.  Returns a list of (key,value) pairs.
-        """
-        if not isinstance(name, str):
-            name = "".join(["%s\n"%s for s in name])
-        tp,body = self._sendAndRecv(MSG_TYPE.GETCONF,name,[MSG_TYPE.CONFVALUE])
-        return _parseKV(body)
-
-    def set_option(self,key,value):
-        """Set the value of the configuration option 'key' to the
-           value 'value'.
-        """
-        self.set_options([key, value])
-
-    def set_options(self,kvlist):
-        """Given a list of (key,value) pairs, set them as configuration
-           options.
-        """
-        msg = "".join(["%s %s\n" for k,v in kvlist])
-        self._sendAndRecv(MSG_TYPE.SETCONF,msg)
-
-    def reset_options(self, keylist):
-        msg = "".join(["%s\n" for k in keylist])
-        self._sendAndRecv(MSG_TYPE.SETCONF,msg)
-
-    def get_info(self,name):
-        """Return the value of the internal information field named
-           'name'.  To retrieve multiple values, pass a list for
-           'name' instead of a string.  Returns a dictionary of
-           key->value mappings.
-        """
-        if not isinstance(name, str):
-            name = "".join(["%s\n"%s for s in name])
-        tp, body = self._sendAndRecv(MSG_TYPE.GETINFO,name,[MSG_TYPE.INFOVALUE])
-        kvs = body.split("\0")
-        d = {}
-        for i in xrange(0,len(kvs)-1,2):
-            d[kvs[i]] = kvs[i+1]
-        return d
-
-    def set_events(self,events):
-        """Change the list of events that the event handler is interested
-           in to those in 'events', which is a list of EVENT_TYPE members
-           or their corresponding strings.
-        """
-        evs = []
-        for ev in events:
-            if isinstance(ev, types.StringType):
-                evs.append(getattr(EVENT_TYPE, ev.upper()))
-            else:
-                evs.append(ev)
-        self._sendAndRecv(MSG_TYPE.SETEVENTS,
-                     "".join([struct.pack("!H", event) for event in events]))
-
-    def save_conf(self):
-        """Flush all configuration changes to disk.
-        """
-        self._sendAndRecv(MSG_TYPE.SAVECONF)
-
-    def send_signal(self, sig):
-        """Send the signal 'sig' to the Tor process; 'sig' must be a member of
-           SIGNAL or a corresponding string.
-        """
-        try:
-            sig = sig.upper()
-        except AttributeError:
-            pass
-        sig = { "HUP" : 0x01, "RELOAD" : 0x01,
-                "INT" : 0x02, "SHUTDOWN" : 0x02,
-                "DUMP" : 0x0A, "USR1" : 0x0A,
-                "USR2" : 0x0C, "DEBUG" : 0x0C,
-                "TERM" : 0x0F, "HALT" : 0x0F
-                }.get(sig,sig)
-        self._sendAndRecv(MSG_TYPE.SIGNAL,struct.pack("B",sig))
-
-    def map_address(self, kvList):
-        """Given a list of (old-address,new-address), have Tor redirect
-           streams from old-address to new-address.  Old-address can be in a
-           special "dont-care" form of "0.0.0.0" or ".".
-        """
-        msg = [ "%s %s\n"%(k,v) for k,v in kvList ]
-        tp, body = self._sendAndRecv(MSG_TYPE.MAPADDRESS,"".join(msg))
-        return _parseKV(body)
-
-    def extend_circuit(self, circid, hops):
-        """Tell Tor to extend the circuit identified by 'circid' through the
-           servers named in the list "hops".
-        """
-        msg = struct.pack("!L",long(circid)) + ",".join(hops) + "\0"
-        tp, body = self._sendAndRecv(MSG_TYPE.EXTENDCIRCUIT,msg)
-        if len(body) != 4:
-            raise ProtocolError("Extendcircuit reply too short or long")
-        return struct.unpack("!L",body)[0]
-
-    def redirect_stream(self, streamid, newtarget):
-        """Tell Tor to change the target address of the stream identified by
-           'streamid' from its old value to 'newtarget'."""
-        msg = struct.pack("!L",long(streamid)) + newtarget + "\0"
-        self._sendAndRecv(MSG_TYPE.REDIRECTSTREAM,msg)
-
-    def attach_stream(self, streamid, circid):
-        """Tell Tor To attach stream 'streamid' to circuit 'circid'."""
-        msg = struct.pack("!LL",long(streamid), long(circid))
-        self._sendAndRecv(MSG_TYPE.ATTACHSTREAM,msg)
-
-    def close_stream(self, streamid, reason=0, flags=()):
-        """Close the stream 'streamid'. """
-        msg = struct.pack("!LBB",long(streamid),reason,flags)
-        self._sendAndRecv(MSG_TYPE.CLOSESTREAM,msg)
-
-    def close_circuit(self, circid, flags=()):
-        """Close the circuit 'circid'."""
-        if "IFUNUSED" in flags:
-            flags=1
-        else:
-            flags=0
-        msg = struct.pack("!LB",long(circid),flags)
-        self._sendAndRecv(MSG_TYPE.CLOSECIRCUIT,msg)
-
-    def post_descriptor(self, descriptor):
-        """Tell Tor about a new descriptor in 'descriptor'."""
-        self._sendAndRecv(MSG_TYPE.POSTDESCRIPTOR,descriptor)

Deleted: torctl/trunk/python/TorCtl1.py
===================================================================
--- torctl/trunk/python/TorCtl1.py	2008-07-08 03:48:18 UTC (rev 15745)
+++ torctl/trunk/python/TorCtl1.py	2008-07-08 05:07:19 UTC (rev 15746)
@@ -1,338 +0,0 @@
-#!/usr/bin/python
-# TorCtl.py -- Python module to interface with Tor Control interface.
-# Copyright 2005 Nick Mathewson -- See LICENSE for licensing information.
-#$Id$
-
-import binascii
-import os
-import re
-import socket
-import sys
-import types
-import TorCtl
-
-def _quote(s):
-    return re.sub(r'([\r\n\\\"])', r'\\\1', s)
-
-def _escape_dots(s, translate_nl=1):
-    if translate_nl:
-        lines = re.split(r"\r?\n", s)
-    else:
-        lines = s.split("\r\n")
-    if lines and not lines[-1]:
-        del lines[-1]
-    for i in xrange(len(lines)):
-        if lines[i].startswith("."):
-            lines[i] = "."+lines[i]
-    lines.append(".\r\n")
-    return "\r\n".join(lines)
-
-def _unescape_dots(s, translate_nl=1):
-    lines = s.split("\r\n")
-
-    for i in xrange(len(lines)):
-        if lines[i].startswith("."):
-            lines[i] = lines[i][1:]
-
-    if lines and lines[-1]:
-        lines.append("")
-
-    if translate_nl:
-        return "\n".join(lines)
-    else:
-        return "\r\n".join(lines)
-
-class _BufSock:
-    def __init__(self, s):
-        self._s = s
-        self._buf = []
-
-    def readline(self):
-        if self._buf:
-            idx = self._buf[0].find('\n')
-            if idx >= 0:
-                result = self._buf[0][:idx+1]
-                self._buf[0] = self._buf[0][idx+1:]
-                return result
-
-        while 1:
-            s = self._s.recv(128)
-            if not s:
-                raise TorCtl.TorCtlClosed()
-            idx = s.find('\n')
-            if idx >= 0:
-                self._buf.append(s[:idx+1])
-                result = "".join(self._buf)
-                rest = s[idx+1:]
-                if rest:
-                    self._buf = [ rest ]
-                else:
-                    del self._buf[:]
-                return result
-            else:
-                self._buf.append(s)
-
-    def write(self, s):
-        self._s.send(s)
-
-    def close(self):
-        self._s.close()
-
-def _read_reply(f,debugFile=None):
-    lines = []
-    while 1:
-        line = f.readline().strip()
-        if debugFile:
-            debugFile.write("    %s\n" % line)
-        if len(line)<4:
-            raise TorCtl.ProtocolError("Badly formatted reply line: Too short")
-        code = line[:3]
-        tp = line[3]
-        s = line[4:]
-        if tp == "-":
-            lines.append((code, s, None))
-        elif tp == " ":
-            lines.append((code, s, None))
-            return lines
-        elif tp != "+":
-            raise TorCtl.ProtocolError("Badly formatted reply line: unknown type %r"%tp)
-        else:
-            more = []
-            while 1:
-                line = f.readline()
-                if debugFile and tp != "+":
-                    debugFile.write("    %s" % line)
-                if line in (".\r\n", ".\n"):
-                    break
-                more.append(line)
-            lines.append((code, s, _unescape_dots("".join(more))))
-
-class Connection(TorCtl._ConnectionBase):
-    """A Connection represents a connection to the Tor process."""
-    def __init__(self, sock):
-        """Create a Connection to communicate with the Tor process over the
-           socket 'sock'.
-        """
-        TorCtl._ConnectionBase.__init__(self)
-        self._s = _BufSock(sock)
-        self._debugFile = None
-
-    def debug(self, f):
-        """DOCDOC"""
-        self._debugFile = f
-
-    def set_event_handler(self, handler):
-        """Cause future events from the Tor process to be sent to 'handler'.
-        """
-        self._handler = handler
-        self._handleFn = handler.handle1
-
-    def _read_reply(self):
-        lines = _read_reply(self._s, self._debugFile)
-        isEvent = (lines and lines[0][0][0] == '6')
-        return isEvent, lines
-
-    def _doSend(self, msg):
-        if self._debugFile:
-            amsg = msg
-            lines = amsg.split("\n")
-            if len(lines) > 2:
-                amsg = "\n".join(lines[:2]) + "\n"
-            self._debugFile.write(">>> %s" % amsg)
-        self._s.write(msg)
-
-    def _sendAndRecv(self, msg="", expectedTypes=("250", "251")):
-        """Helper: Send a command 'msg' to Tor, and wait for a command
-           in response.  If the response type is in expectedTypes,
-           return a list of (tp,body,extra) tuples.  If it is an
-           error, raise ErrorReply.  Otherwise, raise TorCtl.ProtocolError.
-        """
-        if type(msg) == types.ListType:
-            msg = "".join(msg)
-        assert msg.endswith("\r\n")
-
-        lines = self._sendImpl(self._doSend, msg)
-        # print lines
-        for tp, msg, _ in lines:
-            if tp[0] in '45':
-                raise TorCtl.ErrorReply("%s %s"%(tp, msg))
-            if tp not in expectedTypes:
-                raise TorCtl.ProtocolError("Unexpectd message type %r"%tp)
-
-        return lines
-
-    def authenticate(self, secret=""):
-        """Send an authenticating secret to Tor.  You'll need to call this
-           method before Tor can start.
-        """
-        hexstr = binascii.b2a_hex(secret)
-        self._sendAndRecv("AUTHENTICATE %s\r\n"%hexstr)
-
-    def get_option(self, name):
-        """Get the value of the configuration option named 'name'.  To
-           retrieve multiple values, pass a list for 'name' instead of
-           a string.  Returns a list of (key,value) pairs.
-           Refer to section 3.3 of control-spec.txt for a list of valid names.
-        """
-        if not isinstance(name, str):
-            name = " ".join(name)
-        lines = self._sendAndRecv("GETCONF %s\r\n" % name)
-
-        r = []
-        for _,line,_ in lines:
-            try:
-                key, val = line.split("=", 1)
-                r.append((key,val))
-            except ValueError:
-                r.append((line, None))
-
-        return r
-
-    def set_option(self, key, value):
-        """Set the value of the configuration option 'key' to the value 'value'.
-        """
-        self.set_options([(key, value)])
-
-    def set_options(self, kvlist):
-        """Given a list of (key,value) pairs, set them as configuration
-           options.
-        """
-        if not kvlist:
-            return
-        msg = " ".join(["%s=%s"%(k,_quote(v)) for k,v in kvlist])
-        self._sendAndRecv("SETCONF %s\r\n"%msg)
-
-    def reset_options(self, keylist):
-        """Reset the options listed in 'keylist' to their default values.
-
-           Tor started implementing this command in version 0.1.1.7-alpha;
-           previous versions wanted you to set configuration keys to "".
-           That no longer works.
-        """
-        self._sendAndRecv("RESETCONF %s\r\n"%(" ".join(keylist)))
-
-    def get_info(self, name):
-        """Return the value of the internal information field named 'name'.
-           Refer to section 3.9 of control-spec.txt for a list of valid names.
-           DOCDOC
-        """
-        if not isinstance(name, str):
-            name = " ".join(name)
-        lines = self._sendAndRecv("GETINFO %s\r\n"%name)
-        d = {}
-        for _,msg,more in lines:
-            if msg == "OK":
-                break
-            try:
-                k,rest = msg.split("=",1)
-            except ValueError:
-                raise TorCtl.ProtocolError("Bad info line %r",msg)
-            if more:
-                d[k] = more
-            else:
-                d[k] = rest
-        return d
-
-    def set_events(self, events):
-        """Change the list of events that the event handler is interested
-           in to those in 'events', which is a list of event names.
-           Recognized event names are listed in section 3.3 of the control-spec
-        """
-        evs = []
-
-        # Translate options supported by old interface.
-        for e in events:
-            if e == 0x0001 or e == "CIRCSTATUS":
-                e = "CIRC"
-            elif e == 0x0002 or e == "STREAMSTATUS":
-                e = "STREAM"
-            elif e == 0x0003 or e == "ORCONNSTATUS":
-                e = "ORCONN"
-            elif e == 0x0004 or e == "BANDWIDTH":
-                e = "BW"
-            elif e == 0x0005 or e == "OBSOLETE_LOG":
-                coneinue
-            elif e == 0x0006 or e == "NEWDESC":
-                e = "NEWDESC"
-            elif e == 0x0007 or e == "DEBUG_MSG":
-                continue
-            elif e == 0x0008 or e == "INFO_MSG":
-                e = "INFO"
-            elif e == 0x0008 or e == "NOTICE_MSG":
-                e = "NOTICE"
-            elif e == 0x0008 or e == "WARN_MSG":
-                e = "WARN"
-            elif e == 0x0008 or e == "ERR_MSG":
-                e = "ERR"
-            evs.append(e)
-
-        self._sendAndRecv("SETEVENTS %s\r\n" % " ".join(evs))
-
-    def save_conf(self):
-        """Flush all configuration changes to disk.
-        """
-        self._sendAndRecv("SAVECONF\r\n")
-
-    def send_signal(self, sig):
-        """Send the signal 'sig' to the Tor process; The allowed values for
-           'sig' are listed in section 3.6 of control-spec.
-        """
-        sig = { 0x01 : "HUP",
-                0x02 : "INT",
-                0x0A : "USR1",
-                0x0C : "USR2",
-                0x0F : "TERM" }.get(sig,sig)
-        self._sendAndRecv("SIGNAL %s\r\n"%sig)
-
-    def map_address(self, kvList):
-        if not kvList:
-            return
-        m = " ".join([ "%s=%s" for k,v in kvList])
-        lines = self._sendAndRecv("MAPADDRESS %s\r\n"%m)
-        r = []
-        for _,line,_ in lines:
-            try:
-                key, val = line.split("=", 1)
-            except ValueError:
-                raise TorCtl.ProtocolError("Bad address line %r",v)
-            r.append((key,val))
-        return r
-
-    def extend_circuit(self, circid, hops):
-        """Tell Tor to extend the circuit identified by 'circid' through the
-           servers named in the list 'hops'.
-        """
-        if circid is None:
-            circid = "0"
-        lines = self._sendAndRecv("EXTENDCIRCUIT %s %s\r\n"
-                                  %(circid, ",".join(hops)))
-        tp,msg,_ = lines[0]
-        m = re.match(r'EXTENDED (\S*)', msg)
-        if not m:
-            raise TorCtl.ProtocolError("Bad extended line %r",msg)
-        return m.group(1)
-
-    def redirect_stream(self, streamid, newaddr, newport=""):
-        """DOCDOC"""
-        if newport:
-            self._sendAndRecv("REDIRECTSTREAM %s %s %s\r\n"%(streamid, newaddr, newport))
-        else:
-            self._sendAndRecv("REDIRECTSTREAM %s %s\r\n"%(streamid, newaddr))
-
-    def attach_stream(self, streamid, circid):
-        """DOCDOC"""
-        self._sendAndRecv("ATTACHSTREAM %s %s\r\n"%(streamid, circid))
-
-    def close_stream(self, streamid, reason=0, flags=()):
-        """DOCDOC"""
-        self._sendAndRecv("CLOSESTREAM %s %s %s\r\n"
-                          %(streamid, reason, "".join(flags)))
-
-    def close_circuit(self, circid, reason=0, flags=()):
-        """DOCDOC"""
-        self._sendAndRecv("CLOSECIRCUIT %s %s %s\r\n"
-                          %(circid, reason, "".join(flags)))
-
-    def post_descriptor(self, desc):
-        self._sendAndRecv("+POSTDESCRIPTOR\r\n%s"%_escape_dots(desc))
-

Modified: torctl/trunk/python/TorExample.py
===================================================================
--- torctl/trunk/python/TorExample.py	2008-07-08 03:48:18 UTC (rev 15745)
+++ torctl/trunk/python/TorExample.py	2008-07-08 05:07:19 UTC (rev 15746)
@@ -33,7 +33,7 @@
     If a socket is established, and the daemon paramter is True (the default),
     a thread is spawned to handle the communcation between us and the tor server.
     """
-    hostport = "localhost:9100"
+    hostport = "localhost:9051"
     verbose = 0
     while sys.argv[1][0] == '-':
         if sys.argv[1] == '--host':
@@ -46,18 +46,18 @@
             verbose = 1
             del sys.argv[1]
 
-    host,port = parseHostAndPort(hostport)
+    host,port = TorCtl.parseHostAndPort(hostport)
     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     try:
         s.connect((host,port))
     except socket.error, e:
         print "Connection failed: %s. Is the ControlPort enabled?"%e
         sys.exit(1)
-    conn = get_connection(s)
+    conn = TorCtl.Connection(s)
     if verbose and hasattr(conn, "debug"):
         conn.debug(sys.stdout)
     th = conn.launch_thread(daemon)
-    conn.authenticate("")
+    conn.authenticate("handsoffmytor")
     return conn
 
 def run():
@@ -83,7 +83,7 @@
         return
     try:
         fn()
-    except ErrorReply, e:
+    except TorCtl.ErrorReply, e:
         print "Request failed: %s"%e
 
 def run_set_config():
@@ -133,9 +133,8 @@
     in order to stop it
     """
     conn = getConnection(daemon=0)
-    events = []
     print "listening!"
-    conn.set_event_handler(DebugEventHandler())
+    conn.set_event_handler(TorCtl.DebugEventHandler())
     conn.set_events(sys.argv[1:])
 
 def run_signal():



More information about the tor-commits mailing list