General reorganization.
[mLib-python] / select.pyx
diff --git a/select.pyx b/select.pyx
deleted file mode 100644 (file)
index 28fe05d..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-# -*-pyrex-*-
-#
-# $Id$
-#
-# Selectery
-#
-# (c) 2005 Straylight/Edgeware
-#
-
-#----- Licensing notice -----------------------------------------------------
-#
-# This file is part of the Python interface to mLib.
-#
-# mLib/Python 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.
-# 
-# mLib/Python 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
-# along with mLib/Python; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-#----- External dependencies ------------------------------------------------
-
-cdef extern from 'stddef.h':
-  ctypedef int size_t
-cdef extern from 'string.h':
-  void memcpy(void *p, void *q, size_t n)
-cdef extern from 'errno.h':
-  int errno
-  enum:
-    EINTR
-    EAGAIN
-cdef extern from 'math.h':
-  double modf(double x, double *i)
-cdef extern from 'string.h':
-  char *strerror(int err)
-cdef extern from 'sys/time.h':
-  struct timeval:
-    int tv_sec
-    int tv_usec
-cdef extern from 'sys/types.h':
-  pass
-cdef extern from 'sys/socket.h':
-  struct sockaddr:
-    int sa_family
-  enum:
-    AF_INET
-  int getsockname(int fd, sockaddr *pa, size_t *psz)
-  int getpeername(int fd, sockaddr *pa, size_t *psz)
-cdef extern from 'arpa/inet.h':
-  struct in_addr:
-    int s_addr
-  int inet_aton(char *rp, in_addr *ia)
-  char *inet_ntoa(in_addr ia)
-cdef extern from 'netinet/in.h':
-  struct sockaddr_in:
-    int sin_family
-    in_addr sin_addr
-    int sin_port
-  int htons(int x)
-  int htonl(int x)
-  int ntohs(int x)
-  int ntohl(int x)
-cdef extern from 'netdb.h':
-  struct hostent:
-    char *h_name
-    char **h_aliases
-    int h_addrtype
-    int h_length
-    char **h_addr_list
-    char *h_addr
-  int h_errno
-
-cdef extern from 'mLib/sel.h':
-  ctypedef struct sel_state:
-    pass
-  ctypedef struct sel_file:
-    int fd
-  ctypedef struct sel_timer:
-    pass
-  enum:
-    SEL_READ
-    SEL_WRITE
-    SEL_EXC
-  void sel_init(sel_state *s)
-  void sel_initfile(sel_state *s, sel_file *f, int fd, unsigned mode,
-                    void (*func)(int fd, unsigned mode, void *arg),
-                    void *arg)
-  void sel_force(sel_file *f)
-  void sel_addfile(sel_file *f)
-  void sel_rmfile(sel_file *f)
-  void sel_addtimer(sel_state *s, sel_timer *t, timeval *tv,
-                    void (*func)(timeval *tv, void *arg),
-                    void *arg)
-  void sel_rmtimer(sel_timer *t)
-  int sel_select(sel_state *s) except *
-
-cdef extern from 'mLib/conn.h':
-  ctypedef struct conn:
-    pass
-  int conn_fd(conn *c, sel_state *s, int fd,
-              void (*func)(int fd, void *arg), void *arg)
-  void conn_kill(conn *c)
-
-cdef extern from 'mLib/bres.h':
-  ctypedef struct bres_client:
-    pass
-  void bres_byname(bres_client *r, char *name,
-                   void (*func)(hostent *h, void *arg), void *arg)
-  void bres_byaddr(bres_client *r, in_addr addr,
-                   void (*func)(hostent *h, void *arg), void *arg)
-  void bres_abort(bres_client *r)
-  void bres_exec(char *null)
-  void bres_init(sel_state *s)
-
-cdef extern from 'mLib/sig.h':
-  ctypedef struct sig:
-    pass
-  void sig_add(sig *s, int n, void (*func)(int n, void *arg), void *arg)
-  void sig_remove(sig *s)
-  void sig_init(sel_state *s)
-
-cdef extern from 'mLib/lbuf.h':
-  cdef struct lbuf:
-    int f
-    int delim
-    size_t sz
-  enum:
-    LBUF_ENABLE
-    LBUF_CRLF
-    LBUF_STRICTCRLF
-
-cdef extern from 'mLib/selbuf.h':
-  ctypedef struct selbuf:
-    sel_file reader
-    lbuf b
-  void selbuf_enable(selbuf *b)
-  void selbuf_disable(selbuf *b)
-  void selbuf_setsize(selbuf *b, size_t sz)
-  void selbuf_init(selbuf *b, sel_state *s, int fd,
-                   void (*func)(char *s, size_t len, void *arg), void *arg)
-  void selbuf_destroy(selbuf *b)
-
-cdef extern from 'mLib/pkbuf.h':
-  ctypedef struct pkbuf:
-    int f
-    int want
-  enum:
-    PKBUF_ENABLE
-
-cdef extern from 'mLib/selpk.h':
-  ctypedef struct selpk:
-    sel_file reader
-    pkbuf pk
-  void selpk_enable(selpk *b)
-  void selpk_disable(selpk *b)
-  void selpk_want(selpk *b, size_t sz)
-  void selpk_init(selpk *b, sel_state *s, int fd,
-                  void (*func)(unsigned char *p, size_t n,
-                               pkbuf *pk, size_t *keep, void *arg),
-                  void *arg)
-  void selpk_destroy(selpk *b)
-
-cdef extern from 'mLib/ident.h':
-  ctypedef struct ident_request:
-    pass
-  enum:
-    IDENT_USERID
-    IDENT_ERROR
-    IDENT_BAD
-  struct ident_userid:
-    char *os
-    char *user
-  union ident_u:
-    ident_userid userid
-    char *error
-  ctypedef struct ident_reply:
-    int sport
-    int dport
-    int type
-    ident_u u
-  void ident(ident_request *rq, sel_state *s,
-             sockaddr_in *local, sockaddr_in *remote,
-             void (*func)(ident_reply *r, void *arg),
-             void *arg)
-  void ident_abort(ident_request *rq)
-
-cdef extern from 'Python.h':
-  object PyString_FromStringAndSize(char *p, int len)
-  int PyString_AsStringAndSize(obj, char **p, int *len) except -1
-  int PyObject_AsReadBuffer(obj, void **buf, int *len) except -1
-  int PyObject_TypeCheck(obj, ty)
-
-cdef extern from 'grim.h':
-  int PSIZEOF(void *x)
-
-import socket
-import signal
-
-#----- Utility functions ----------------------------------------------------
-
-cdef _oserror():
-  raise OSError, (errno, strerror(errno))
-
-cdef object _tobool(int i):
-  if i:
-    return True
-  else:
-    return False
-
-cdef int _getfd(object fdobj):
-  try:
-    return fdobj
-  except TypeError:
-    return fdobj.fileno()
-
-#----- The global select state ----------------------------------------------
-
-cdef sel_state sel
-
-sel_init(&sel)
-bres_init(&sel)
-bres_exec(NULL)
-sig_init(&sel)
-
-def select():
-  if sel_select(&sel) and errno != EINTR and errno != EAGAIN:
-    _oserror()
-
-#----- File selectors -------------------------------------------------------
-
-READ = SEL_READ
-WRITE = SEL_WRITE
-EXCEPT = SEL_EXC
-
-cdef class File:
-  cdef sel_file f
-  cdef int _activep
-  cdef readonly unsigned mode
-  def __new__(me, fd, int mode = SEL_READ):
-    if (mode != SEL_READ and
-        mode != SEL_WRITE and
-        mode != SEL_EXC):
-      raise ValueError, 'bad select mode'
-    sel_initfile(&sel, &me.f, _getfd(fd), mode, _filefunc, <void *>me)
-    me._activep = 0
-    me.mode = mode
-  def __dealloc__(me):
-    if me._activep:
-      sel_rmfile(&me.f)
-  property fd:
-    def __get__(me):
-      return me.f.fd
-  property activep:
-    def __get__(me):
-      return _tobool(me._activep)
-  def enable(me):
-    if me._activep:
-      raise ValueError, 'already enabled'
-    sel_addfile(&me.f)
-    me._activep = 1
-    return me
-  def disable(me):
-    if not me._activep:
-      raise ValueError, 'already disabled'
-    sel_rmfile(&me.f)
-    me._activep = 0
-    return me
-  def force(me):
-    sel_force(&me.f)
-    return me
-  def ready(me):
-    pass
-
-cdef void _filefunc(int fd, unsigned mode, void *arg):
-  cdef File sf
-  sf = <File>arg
-  sf.ready()
-
-#----- Timer selectors ------------------------------------------------------
-
-cdef double _tvtofloat(timeval *tv):
-  return tv.tv_sec + (tv.tv_usec / 1000000)
-cdef void _floattotv(timeval *tv, double t):
-  cdef double s, us
-  us = modf(t, &s)
-  tv.tv_sec = s
-  tv.tv_usec = us * 1000000
-
-cdef class Timer:
-  cdef sel_timer t
-  cdef int _activep
-  cdef readonly double time
-  def __new__(me, double when):
-    cdef timeval tv
-    _floattotv(&tv, when)
-    sel_addtimer(&sel, &me.t, &tv, _timerfunc, <void *>me)
-    me._activep = 1
-    me.time = when
-  def __dealloc__(me):
-    if me._activep:
-      sel_rmtimer(&me.t)
-  property activep:
-    def __get__(me):
-      return _tobool(me._activep)
-  def kill(me):
-    if not me._activep:
-      raise ValueError, 'already dead'
-    sel_rmtimer(&me.t)
-    me._activep = 0
-    return me
-  def timer(me, now):
-    pass
-
-cdef void _timerfunc(timeval *now, void *arg):
-  cdef Timer st
-  st = <Timer>arg
-  st._activep = 0
-  st.timer(_tvtofloat(now))
-
-#----- Connections ----------------------------------------------------------
-
-cdef class Connect:
-  cdef conn c
-  cdef int _activep
-  cdef readonly object socket
-  def __new__(me, sk):
-    conn_fd(&me.c, &sel, sk.fileno(), _connfunc, <void *>me)
-    me._activep = 1
-    me.socket = sk
-  def __dealloc__(me):
-    if me._activep:
-      conn_kill(&me.c)
-  property activep:
-    def __get__(me):
-      return _tobool(me._activep)
-  def kill(me):
-    if not me._activep:
-      raise ValueError, 'already dead'
-    conn_kill(&me.c);
-    me._activep = 0
-    return me
-  def connected(me):
-    pass
-  def error(me, errno, strerror):
-    pass
-
-cdef void _connfunc(int fd, void *arg):
-  cdef Connect c
-  c = <Connect>arg
-  c._activep = 0
-  if fd == -1:
-    c.socket = None
-    c.error(errno, strerror(errno))
-  else:
-    c.connected()
-
-#----- Background name resolution -------------------------------------------
-
-cdef class Resolve:
-  cdef bres_client r
-  cdef int _activep
-  def __init__(me, *hunoz, **hukairz):
-    raise TypeError, 'abstract class'
-  property activep:
-    def __get__(me):
-      return _tobool(me._activep)
-  def kill(me):
-    if not me._activep:
-      raise ValueError, 'already dead'
-    bres_abort(&me.r)
-    return me
-  def resolved(me, h):
-    pass
-  def failed(me):
-    pass
-
-cdef class ResolveByName (Resolve):
-  def __new__(me, char *name):
-    bres_byname(&me.r, name, _resfunc, <void *>me)
-    me._activep = 1
-  def __init__(me, name):
-    pass
-
-cdef class ResolveByAddr (Resolve):
-  def __new__(me, char *addr):
-    cdef in_addr ia
-    if not inet_aton(addr, &ia):
-      raise TypeError, 'bad IP address'
-    bres_byaddr(&me.r, ia, _resfunc, <void *>me)
-    me._activep = 1
-  def __init__(me, addr):
-    pass
-
-cdef void _resfunc(hostent *h, void *arg):
-  cdef Resolve r
-  cdef int i
-  r = <Resolve>arg
-  r._activep = 0
-  if h is NULL:
-    r.failed(r)
-  else:
-    alias = []
-    addr = []
-    i = 0
-    while h.h_aliases[i]:
-      alias.append(h.h_aliases[i])
-      i = i + 1
-    i = 0
-    while h.h_addr_list[i]:
-      addr.append(inet_ntoa((<in_addr *>h.h_addr_list[i])[0]))
-      i = i + 1
-    r.resolved(h.h_name, alias, addr)
-
-#----- Signal handling ------------------------------------------------------
-
-cdef class Signal:
-  cdef sig s
-  cdef int _activep
-  cdef readonly int signal
-  def __new__(me, int sig):
-    if sig < 0 or sig >= signal.NSIG:
-      raise ValueError, 'signal number out of range'
-    me.signal = sig
-    me._activep = 0
-  def __dealloc__(me):
-    if me._activep:
-      sig_remove(&me.s)
-  def enable(me):
-    if me._activep:
-      raise ValueError, 'already enabled'
-    sig_add(&me.s, me.signal, _sigfunc, <void *>me)
-    me._activep = 1
-    return me
-  def disable(me):
-    if not me._activep:
-      raise ValueError, 'already disabled'
-    sig_remove(&me.s)
-    me._activep = 0
-    return me
-  def signalled(me):
-    pass
-
-cdef void _sigfunc(int sig, void *arg):
-  cdef Signal s
-  s = <Signal>arg
-  s.signalled()
-
-#----- Line buffers ---------------------------------------------------------
-
-CRLF = LBUF_CRLF
-STRICTCRLF = LBUF_STRICTCRLF
-
-cdef class LineBuffer:
-  cdef selbuf b
-  def __new__(me, fd):
-    selbuf_init(&me.b, &sel, _getfd(fd), _lbfunc, <void *>me)
-    selbuf_disable(&me.b)
-  def __dealloc__(me):
-    selbuf_destroy(&me.b)
-  property activep:
-    def __get__(me):
-      return _tobool(me.b.b.f & LFBUF_ENABLE)
-  property delim:
-    def __get__(me):
-      if me.b.b.delim == LBUF_CRLF or me.b.b.delim == LBUF_STRICTCRLF:
-        return me.b.b.delim
-      else:
-        return chr(me.b.b.delim)
-    def __set__(me, d):
-      if d == LBUF_CRLF or d == LBUF_STRICTCRLF:
-        me.b.b.delim = d
-      else:
-        me.b.b.delim = ord(d)
-  property size:
-    def __get__(me):
-      return me.b.b.sz
-    def __set__(me, sz):
-      selbuf_setsize(&me.b, sz)
-  def enable(me):
-    if me.b.b.f & LBUF_ENABLE:
-      raise ValueError, 'already enabled'
-    selbuf_enable(&me.b)
-    return me
-  def disable(me):
-    if not (me.b.b.f & LBUF_ENABLE):
-      raise ValueError, 'already disabled'
-    selbuf_disable(&me.b)
-    return me
-  def line(me, line):
-    pass
-  def eof(me):
-    pass
-
-cdef void _lbfunc(char *s, size_t n, void *arg):
-  cdef LineBuffer sb
-  sb = <LineBuffer>arg
-  if s is NULL:
-    sb.eof()
-  else:
-    sb.line(PyString_FromStringAndSize(s, n))
-
-#----- Packet buffers -------------------------------------------------------
-
-cdef class PacketBuffer:
-  cdef selpk p
-  def __new__(me, fd):
-    selpk_init(&me.p, &sel, _getfd(fd), _pkfunc, <void *>me)
-    selpk_disable(&me.p)
-  def __dealloc__(me):
-    selpk_destroy(&me.p)
-  property activep:
-    def __get__(me):
-      return _to_bool(me.p.pk.f & PKBUF_ENABLE)
-  property want:
-    def __get__(me):
-      return me.p.pk.want
-    def __set__(me, n):
-      selpk_want(&me.p, n)
-  def enable(me):
-    if me.p.pk.f & PKBUF_ENABLE:
-      raise ValueError, 'already enabled'
-    selpk_enable(&me.p)
-    return me
-  def disable(me):
-    if not (me.p.pk.f & PKBUF_ENABLE):
-      raise ValueError, 'already disabled'
-    selpk_disable(&me.p)
-    return me
-  def packet(me, pk):
-    return None
-  def eof(me):
-    pass
-
-cdef void _pkfunc(unsigned char *p, size_t n, pkbuf *pk,
-                  size_t *keep, void *arg):
-  cdef PacketBuffer pb
-  cdef void *rp
-  cdef int rn
-  pb = <PacketBuffer>arg
-  if p is NULL:
-    pb.eof()
-  else:
-    r = pb.packet(PyString_FromStringAndSize(<char *>p, n))
-    if r is not None:
-      PyObject_AsReadBuffer(r, &rp, &rn)
-      if rn > n:
-        raise ValueError, 'remaining buffer too large'
-      if rn:
-        memcpy(p + n - rn, rp, rn)
-        keep[0] = rn
-
-#----- Ident client ---------------------------------------------------------
-
-cdef _inaddr_frompy(sockaddr_in *sin, addr):
-  cdef int port
-  if len(addr) != 2:
-    raise TypeError, 'want address/port pair'
-  a = addr[0]
-  if not inet_aton(a, &sin.sin_addr):
-    raise TypeError, 'bad IP address'
-  port = addr[1]
-  if not (0 <= port < 65536):
-    raise TypeError, 'port number out of range'
-  sin.sin_port = htons(port)
-
-cdef _inaddr_topy(sockaddr_in *sin):
-  return inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)
-
-cdef class Identify:
-  cdef ident_request irq
-  cdef int _activep
-  cdef readonly localaddr
-  cdef readonly remoteaddr
-  def __new__(me, sk):
-    cdef sockaddr_in s_in, s_out
-    cdef size_t sz_in, sz_out
-    cdef int fd
-    if PyObject_TypeCheck(sk, socket.SocketType):
-      fd = sk.fileno()
-      sz_in = PSIZEOF(&s_in)
-      sz_out = PSIZEOF(&s_out)
-      if getsockname(fd, <sockaddr *>&s_in, &sz_in) or \
-         getpeername(fd, <sockaddr *>&s_out, &sz_out):
-        _oserror()
-      if s_in.sin_family != AF_INET or s_out.sin_family != AF_INET:
-        raise TypeError, 'must be internet socket'
-    elif len(sk) != 2:
-      raise TypeError, 'want pair of addresses'
-    else:
-      _inaddr_frompy(&s_in, sk[0])
-      _inaddr_frompy(&s_out, sk[1])
-    ident(&me.irq, &sel, &s_in, &s_out, _identfunc, <void *>me)
-    me.localaddr = _inaddr_topy(&s_in)
-    me.remoteaddr = _inaddr_topy(&s_out)
-    me._activep = 1
-  def __dealloc__(me):
-    if me._activep:
-      ident_abort(&me.irq)
-  property activep:
-    def __get__(me):
-      return _tobool(me._activep)
-  def kill(me):
-    if not me._activep:
-      raise ValueError, 'already disabled'
-    ident_abort(&me.irq)
-    me._activep = 0
-  def user(me, os, user):
-    pass
-  def bad(me):
-    pass
-  def error(me, error):
-    pass
-  def failed(me, errno, strerror):
-    pass
-
-cdef void _identfunc(ident_reply *i, void *arg):
-  cdef Identify id
-  id = <Identify>arg
-  id._activep = 0
-  if i.type == IDENT_BAD:
-    ii.bad()
-  elif i.type == IDENT_ERROR:
-    ii.error(i.u.error)
-  elif i.type == IDENT_USER:
-    ii.user(i.u.userid.os, i.u.userid.user)
-
-#----- That's all, folks ----------------------------------------------------