diff options
author | Amitay Isaacs <amitay@gmail.com> | 2011-10-14 17:24:16 +1100 |
---|---|---|
committer | Kai Blin <kai@samba.org> | 2011-11-17 08:42:45 +0100 |
commit | bd8aafc530ba473acefd53665b73a47d1ebbb3a5 (patch) | |
tree | 3472039c38fcf4fc54dba0e3ab1612d0dace923e /lib/socket_wrapper | |
parent | f7c8af759909e472a5f9dcaa7f738c7151a57afc (diff) | |
download | samba-bd8aafc530ba473acefd53665b73a47d1ebbb3a5.tar.gz samba-bd8aafc530ba473acefd53665b73a47d1ebbb3a5.tar.bz2 samba-bd8aafc530ba473acefd53665b73a47d1ebbb3a5.zip |
socket_wrapper: Added python interface to socket_wrapper
The socket_wrapper does not support setting blocking flag or
timeouts on the sockets.
To use socket module in python, use
from samba import socket
Signed-off-by: Kai Blin <kai@samba.org>
Diffstat (limited to 'lib/socket_wrapper')
-rw-r--r-- | lib/socket_wrapper/py_socket_wrapper.c | 876 | ||||
-rw-r--r-- | lib/socket_wrapper/socket.py | 52 | ||||
-rw-r--r-- | lib/socket_wrapper/wscript_build | 10 |
3 files changed, 938 insertions, 0 deletions
diff --git a/lib/socket_wrapper/py_socket_wrapper.c b/lib/socket_wrapper/py_socket_wrapper.c new file mode 100644 index 0000000000..405a43a81d --- /dev/null +++ b/lib/socket_wrapper/py_socket_wrapper.c @@ -0,0 +1,876 @@ +/* + * Copyright (C) Amitay Isaacs 2011 + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + Python interface to socket wrapper library. + + Passes all socket communication over unix domain sockets if the environment + variable SOCKET_WRAPPER_DIR is set. +*/ + +#include <Python.h> +#include <pytalloc.h> +#include "replace/replace.h" +#include "system/network.h" +#include "socket_wrapper.h" + +#ifndef Py_RETURN_NONE +#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None +#endif + +#ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */ +#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) +#endif + +#ifndef PY_CHECK_TYPE +#define PY_CHECK_TYPE(type, var, fail) \ + if (!PyObject_TypeCheck(var, type)) {\ + PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \ + fail; \ + } +#endif + +staticforward PyTypeObject PySocket; + +static PyObject *py_socket_error; + +void initsocket_wrapper(void); + +static PyObject *py_socket_addr_to_tuple(struct sockaddr *addr, socklen_t len) +{ + char host[256]; + char service[8]; + int status; + PyObject *pyaddr; + + status = getnameinfo(addr, len, host, 255, service, 7, NI_NUMERICHOST|NI_NUMERICSERV); + if (status < 0) { + PyErr_SetString(py_socket_error, gai_strerror(status)); + return NULL; + } + + pyaddr = PyTuple_New(2); + if (pyaddr == NULL) { + return PyErr_NoMemory(); + } + + PyTuple_SetItem(pyaddr, 0, PyString_FromString(host)); + PyTuple_SetItem(pyaddr, 1, PyInt_FromLong(atoi(service))); + + return pyaddr; +} + +static bool py_socket_tuple_to_addr(PyObject *pyaddr, struct sockaddr *addr, socklen_t *len) +{ + const char *host; + char *service; + in_port_t port; + struct addrinfo *ainfo; + int status; + + if (!PyTuple_Check(pyaddr)) { + PyErr_SetString(PyExc_TypeError, "Expected a tuple"); + return false; + } + + if (!PyArg_ParseTuple(pyaddr, "sH", &host, &port)) { + return false; + } + + service = talloc_asprintf(NULL, "%d", port); + if (service == NULL) { + PyErr_NoMemory(); + return false; + } + + status = getaddrinfo(host, service, NULL, &ainfo); + if (status < 0) { + talloc_free(service); + PyErr_SetString(py_socket_error, gai_strerror(status)); + return false; + } + + talloc_free(service); + + memcpy(addr, ainfo->ai_addr, sizeof(struct sockaddr)); + *len = ainfo->ai_addrlen; + + freeaddrinfo(ainfo); + return true; +} + + +static PyObject *py_socket_accept(pytalloc_Object *self, PyObject *args) +{ + int *sock, *new_sock; + struct sockaddr addr; + socklen_t addrlen; + PyObject *pysocket; + PyObject *pyaddr; + PyObject *pyret; + + sock = pytalloc_get_ptr(self); + + new_sock = talloc_zero(NULL, int); + if (new_sock == NULL) { + return PyErr_NoMemory(); + } + + *new_sock = swrap_accept(*sock, &addr, &addrlen); + if (*new_sock < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + if ((pysocket = pytalloc_steal(&PySocket, new_sock)) == NULL) { + return PyErr_NoMemory(); + } + + pyret = PyTuple_New(2); + if (pyret == NULL) { + Py_DECREF(pysocket); + return PyErr_NoMemory(); + } + + pyaddr = py_socket_addr_to_tuple(&addr, addrlen); + if (pyaddr == NULL) { + Py_DECREF(pysocket); + Py_DECREF(pysocket); + return NULL; + } + + PyTuple_SetItem(pyret, 0, pysocket); + PyTuple_SetItem(pyret, 1, pyaddr); + return pyret; +} + +static PyObject *py_socket_bind(pytalloc_Object *self, PyObject *args) +{ + PyObject *pyaddr; + int *sock; + int status; + struct sockaddr addr; + socklen_t addrlen; + + if (!PyArg_ParseTuple(args, "O:bind", &pyaddr)) { + return NULL; + } + + if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_bind(*sock, &addr, addrlen); + if (status < 0) { + PyErr_SetString(py_socket_error, "Unable to bind"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_close(pytalloc_Object *self, PyObject *args) +{ + int *sock; + int status; + + sock = pytalloc_get_ptr(self); + + status = swrap_close(*sock); + if (status < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_connect(pytalloc_Object *self, PyObject *args) +{ + int *sock; + PyObject *pyaddr; + struct sockaddr addr; + socklen_t addrlen; + int status; + + if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) { + return NULL; + } + + if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_connect(*sock, &addr, addrlen); + if (status < 0) { + PyErr_SetFromErrno(py_socket_error); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_connect_ex(pytalloc_Object *self, PyObject *args) +{ + int *sock; + PyObject *pyaddr; + struct sockaddr addr; + socklen_t addrlen; + int status; + + if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) { + return NULL; + } + + if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_connect(*sock, &addr, addrlen); + if (status < 0) { + return Py_BuildValue("%d", errno); + } + + return Py_BuildValue("%d", 0); +} + +static PyObject *py_socket_dup(pytalloc_Object *self, PyObject *args) +{ + int *sock, *new_sock; + PyObject *pysocket; + + sock = pytalloc_get_ptr(self); + + new_sock = talloc_zero(NULL, int); + if (new_sock == NULL) { + return PyErr_NoMemory(); + } + + *new_sock = swrap_dup(*sock); + if (*new_sock < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + pysocket = pytalloc_steal(&PySocket, new_sock); + if (pysocket == NULL) { + return PyErr_NoMemory(); + } + + return pysocket; +} + +static PyObject *py_socket_dup2(pytalloc_Object *self, PyObject *args) +{ + int *sock, *new_sock; + PyObject *pysocket; + int status; + + if (!PyArg_ParseTuple(args, "O", &pysocket)) { + return NULL; + } + + PY_CHECK_TYPE(&PySocket, pysocket, return NULL); + + sock = pytalloc_get_ptr(self); + new_sock = pytalloc_get_ptr(pysocket); + + status = swrap_dup2(*sock, *new_sock); + if (status < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_fileno(pytalloc_Object *self, PyObject *args) +{ + PyErr_SetString(py_socket_error, "Not Supported"); + return NULL; +} + +static PyObject *py_socket_getpeername(pytalloc_Object *self, PyObject *args) +{ + int *sock; + struct sockaddr addr; + socklen_t addrlen; + int status; + PyObject *pyaddr; + + sock = pytalloc_get_ptr(self); + + status = swrap_getpeername(*sock, &addr, &addrlen); + if (status < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + pyaddr = py_socket_addr_to_tuple(&addr, addrlen); + + return pyaddr; +} + +static PyObject *py_socket_getsockname(pytalloc_Object *self, PyObject *args) +{ + int *sock; + struct sockaddr addr; + socklen_t addrlen; + int status; + PyObject *pyaddr; + + sock = pytalloc_get_ptr(self); + + status = swrap_getsockname(*sock, &addr, &addrlen); + if (status < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + pyaddr = py_socket_addr_to_tuple(&addr, addrlen); + + return pyaddr; +} + +static PyObject *py_socket_getsockopt(pytalloc_Object *self, PyObject *args) +{ + int level, optname; + int *sock; + socklen_t optlen = -1, newlen; + int optval; + bool is_integer = false; + char *buffer; + PyObject *pyret; + int status; + + if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &optlen)) { + return NULL; + } + + if (optlen < 0) { + optlen = sizeof(int); + is_integer = true; + } + + buffer = talloc_zero_array(NULL, char, optlen); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + + sock = pytalloc_get_ptr(self); + + status = swrap_getsockopt(*sock, level, optname, (void *)buffer, &newlen); + if (status < 0) { + talloc_free(buffer); + return PyErr_SetFromErrno(py_socket_error); + } + + if (is_integer) { + optval = *(int *)buffer; + pyret = PyInt_FromLong(optval); + } else { + pyret = PyString_FromStringAndSize(buffer, optlen); + } + + talloc_free(buffer); + + return pyret; +} + +static PyObject *py_socket_gettimeout(pytalloc_Object *self, PyObject *args) +{ + PyErr_SetString(py_socket_error, "Not Supported"); + return NULL; +} + +static PyObject *py_socket_listen(pytalloc_Object *self, PyObject *args) +{ + int backlog; + int *sock; + int status; + + if (!PyArg_ParseTuple(args, "i:listen", &backlog)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_listen(*sock, backlog); + if (status < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_makefile(pytalloc_Object *self, PyObject *args) +{ + PyErr_SetString(py_socket_error, "Not Supported"); + return NULL; +} + +static PyObject *py_socket_read(pytalloc_Object *self, PyObject *args) +{ + int bufsize, len; + int *sock; + char *buffer; + PyObject *pyret; + + if (!PyArg_ParseTuple(args, "i:read", &bufsize)) { + return NULL; + } + + buffer = talloc_zero_array(NULL, char, bufsize); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + + sock = pytalloc_get_ptr(self); + + len = swrap_read(*sock, buffer, bufsize); + if (len < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + pyret = PyString_FromStringAndSize(buffer, len); + + talloc_free(buffer); + + return pyret; +} + +static PyObject *py_socket_recv(pytalloc_Object *self, PyObject *args) +{ + int bufsize, flags, len; + int *sock; + char *buffer; + PyObject *pyret; + + if (!PyArg_ParseTuple(args, "ii:recv", &bufsize, &flags)) { + return NULL; + } + + buffer = talloc_zero_array(NULL, char, bufsize); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + + sock = pytalloc_get_ptr(self); + + len = swrap_recv(*sock, buffer, bufsize, flags); + if (len < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + pyret = PyString_FromStringAndSize(buffer, len); + + talloc_free(buffer); + + return pyret; +} + +static PyObject *py_socket_recvfrom(pytalloc_Object *self, PyObject *args) +{ + int bufsize, flags, len; + int *sock; + char *buffer; + struct sockaddr from; + socklen_t fromlen; + PyObject *pybuf, *pyaddr, *pyret; + + if (!PyArg_ParseTuple(args, "ii:recvfrom", &bufsize, &flags)) { + return NULL; + } + + buffer = talloc_zero_array(NULL, char, bufsize); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + + sock = pytalloc_get_ptr(self); + + fromlen = sizeof(struct sockaddr); + + len = swrap_recvfrom(*sock, buffer, bufsize, flags, &from, &fromlen); + if (len < 0) { + talloc_free(buffer); + return PyErr_SetFromErrno(py_socket_error); + } + + pybuf = PyString_FromStringAndSize(buffer, len); + if (pybuf == NULL) { + talloc_free(buffer); + return PyErr_NoMemory(); + } + + talloc_free(buffer); + + pyaddr = py_socket_addr_to_tuple(&from, fromlen); + if (pyaddr == NULL) { + Py_DECREF(pybuf); + return NULL; + } + + pyret = PyTuple_New(2); + if (pyret == NULL) { + Py_DECREF(pybuf); + Py_DECREF(pyaddr); + return PyErr_NoMemory(); + } + + PyTuple_SetItem(pyret, 0, pybuf); + PyTuple_SetItem(pyret, 1, pyaddr); + + return pyret; +} + +static PyObject *py_socket_send(pytalloc_Object *self, PyObject *args) +{ + char *buffer; + int len, flags; + int *sock; + int status; + + if (!PyArg_ParseTuple(args, "s#i:sendto", &buffer, &len, &flags)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_send(*sock, buffer, len, flags); + if (status < 0) { + PyErr_SetFromErrno(py_socket_error); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_sendall(pytalloc_Object *self, PyObject *args) +{ + char *buffer; + int len, flags; + int *sock; + int status; + + if (!PyArg_ParseTuple(args, "s#i:sendall", &buffer, &len, &flags)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_send(*sock, buffer, len, flags); + if (status < 0) { + PyErr_SetFromErrno(py_socket_error); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_sendto(pytalloc_Object *self, PyObject *args) +{ + PyObject *pyaddr; + char *buffer; + int len, flags; + int *sock; + struct sockaddr addr; + socklen_t addrlen; + int status; + + if (!PyArg_ParseTuple(args, "s#iO:sendto", &buffer, &len, &flags, &pyaddr)) { + return NULL; + } + + if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_sendto(*sock, buffer, len, flags, &addr, addrlen); + if (status < 0) { + PyErr_SetFromErrno(py_socket_error); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_setblocking(pytalloc_Object *self, PyObject *args) +{ + PyErr_SetString(py_socket_error, "Not Supported"); + return NULL; +} + +static PyObject *py_socket_setsockopt(pytalloc_Object *self, PyObject *args) +{ + int level, optname; + int *sock; + PyObject *pyval; + int optval; + Py_ssize_t optlen; + char *buffer; + int status; + + if (!PyArg_ParseTuple(args, "iiO:getsockopt", &level, &optname, &pyval)) { + return NULL; + } + + if (PyInt_Check(pyval)) { + optval = PyInt_AsLong(pyval); + buffer = (char *)&optval; + optlen = sizeof(int); + } else { + PyString_AsStringAndSize(pyval, &buffer, &optlen); + } + + sock = pytalloc_get_ptr(self); + + status = swrap_setsockopt(*sock, level, optname, (void *)buffer, optlen); + if (status < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + Py_RETURN_NONE; +} + +static PyObject *py_socket_settimeout(pytalloc_Object *self, PyObject *args) +{ + PyErr_SetString(py_socket_error, "Not Supported"); + return NULL; +} + +static PyObject *py_socket_shutdown(pytalloc_Object *self, PyObject *args) +{ + PyErr_SetString(py_socket_error, "Not Supported"); + return NULL; +} + +static PyObject *py_socket_write(pytalloc_Object *self, PyObject *args) +{ + char *buffer; + int len; + int *sock; + int status; + + if (!PyArg_ParseTuple(args, "s#:write", &buffer, &len)) { + return NULL; + } + + sock = pytalloc_get_ptr(self); + + status = swrap_send(*sock, buffer, len, 0); + if (status < 0) { + PyErr_SetFromErrno(py_socket_error); + return NULL; + } + + Py_RETURN_NONE; +} + + +static PyMethodDef py_socket_methods[] = { + { "accept", (PyCFunction)py_socket_accept, METH_NOARGS, + "accept() -> (socket object, address info)\n\n \ + Wait for an incoming connection." }, + { "bind", (PyCFunction)py_socket_bind, METH_VARARGS, + "bind(address)\n\n \ + Bind the socket to a local address." }, + { "close", (PyCFunction)py_socket_close, METH_NOARGS, + "close()\n\n \ + Close the socket." }, + { "connect", (PyCFunction)py_socket_connect, METH_VARARGS, + "connect(address)\n\n \ + Connect the socket to a remote address." }, + { "connect_ex", (PyCFunction)py_socket_connect_ex, METH_VARARGS, + "connect_ex(address)\n\n \ + Connect the socket to a remote address." }, + { "dup", (PyCFunction)py_socket_dup, METH_VARARGS, + "dup() -> socket object\n\n \ + Return a new socket object connected to the same system resource." }, + { "dup2", (PyCFunction)py_socket_dup2, METH_VARARGS, + "dup2(socket object) -> socket object\n\n \ + Return a new socket object connected to teh same system resource." }, + { "fileno", (PyCFunction)py_socket_fileno, METH_NOARGS, + "fileno() -> file descriptor\n\n \ + Return socket's file descriptor." }, + { "getpeername", (PyCFunction)py_socket_getpeername, METH_NOARGS, + "getpeername() -> address info\n\n \ + Return the address of the remote endpoint." }, + { "getsockname", (PyCFunction)py_socket_getsockname, METH_NOARGS, + "getsockname() -> address info\n\n \ + Return the address of the local endpoing." }, + { "getsockopt", (PyCFunction)py_socket_getsockopt, METH_VARARGS, + "getsockopt(level, option[, buffersize]) -> value\n\n \ + Get a socket option." }, + { "gettimeout", (PyCFunction)py_socket_gettimeout, METH_NOARGS, + "gettimeout() -> value\n\n \ + Return the timeout in seconds associated with socket operations." }, + { "listen", (PyCFunction)py_socket_listen, METH_VARARGS, + "listen(backlog)\n\n \ + Enable a server to accept connections." }, + { "makefile", (PyCFunction)py_socket_makefile, METH_NOARGS, + "makefile() -> file object\n\n \ + Return a file object associated with the socket." }, + { "read", (PyCFunction)py_socket_read, METH_VARARGS, + "read(buflen) -> data\n\n \ + Receive data." }, + { "recv", (PyCFunction)py_socket_recv, METH_VARARGS, + "recv(buflen, flags) -> data\n\n \ + Receive data." }, + { "recvfrom", (PyCFunction)py_socket_recvfrom, METH_VARARGS, + "recvfrom(buflen, flags) -> (data, sender address)\n\n \ + Receive data and sender's address." }, + { "send", (PyCFunction)py_socket_send, METH_VARARGS, + "send(data, flags)\n\n \ + Send data." }, + { "sendall", (PyCFunction)py_socket_sendall, METH_VARARGS, + "sendall(data, flags)\n\n \ + Send data." }, + { "sendto", (PyCFunction)py_socket_sendto, METH_VARARGS, + "sendto(data, flags, addr)\n\n \ + Send data to a given address." }, + { "setblocking", (PyCFunction)py_socket_setblocking, METH_VARARGS, + "setblocking(flag)\n\n \ + Set blocking or non-blocking mode of the socket." }, + { "setsockopt", (PyCFunction)py_socket_setsockopt, METH_VARARGS, + "setsockopt(level, option, value)\n\n \ + Set a socket option." }, + { "settimeout", (PyCFunction)py_socket_settimeout, METH_VARARGS, + "settimeout(value)\n\n \ + Set a timeout on socket blocking operations." }, + { "shutdown", (PyCFunction)py_socket_shutdown, METH_VARARGS, + "shutdown(how)\n\n \ + Shut down one or both halves of the connection." }, + { "write", (PyCFunction)py_socket_write, METH_VARARGS, + "write(data)\n\n \ + Send data." }, + { NULL }, +}; + + +static PyObject *py_socket_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + int family, sock_type, protocol; + int *sock; + PyObject *pysocket; + + if (!PyArg_ParseTuple(args, "iii:socket", &family, &sock_type, &protocol)) { + return NULL; + } + + sock = talloc_zero(NULL, int); + if (sock == NULL) { + return PyErr_NoMemory(); + } + + *sock = swrap_socket(family, sock_type, protocol); + if (*sock < 0) { + return PyErr_SetFromErrno(py_socket_error); + } + + if ((pysocket = pytalloc_steal(type, sock)) == NULL) { + return PyErr_NoMemory(); + } + + return pysocket; +} + + +static PyTypeObject PySocket = { + .tp_name = "socket_wrapper.socket", + .tp_basicsize = sizeof(pytalloc_Object), + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = py_socket_methods, + .tp_new = py_socket_new, + .tp_doc = "socket(family, type, proto) -> socket object\n\n Open a socket of the give type.", +}; + +static PyObject *py_socket_wrapper_dir(PyObject *self) +{ + const char *dir; + + dir = socket_wrapper_dir(); + + return PyString_FromString(dir); +} + +static PyObject *py_socket_wrapper_default_interface(PyObject *self) +{ + unsigned int id; + + id = socket_wrapper_default_iface(); + + return PyInt_FromLong(id); +} + + +static PyMethodDef py_socket_wrapper_methods[] = { + { "dir", (PyCFunction)py_socket_wrapper_dir, METH_NOARGS, + "dir() -> path\n\n \ + Return socket_wrapper directory." }, + { "default_iface", (PyCFunction)py_socket_wrapper_default_interface, METH_NOARGS, + "default_iface() -> id\n\n \ + Return default interface id." }, + { NULL }, +}; + +void initsocket_wrapper(void) +{ + PyObject *m; + char exception_name[] = "socket_wrapper.error"; + + PyTypeObject *talloc_type = pytalloc_GetObjectType(); + if (talloc_type == NULL) { + return; + } + + PySocket.tp_base = talloc_type; + if (PyType_Ready(&PySocket) < 0) { + return; + } + + m = Py_InitModule3("socket_wrapper", py_socket_wrapper_methods, "Socket wrapper"); + if (m == NULL) { + return; + } + + py_socket_error = PyErr_NewException(exception_name, NULL, NULL); + Py_INCREF(py_socket_error); + PyModule_AddObject(m, "error", py_socket_error); + + Py_INCREF(&PySocket); + PyModule_AddObject(m, "socket", (PyObject *)&PySocket); +} diff --git a/lib/socket_wrapper/socket.py b/lib/socket_wrapper/socket.py new file mode 100644 index 0000000000..bba96653af --- /dev/null +++ b/lib/socket_wrapper/socket.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# Wrapper for socket wrapper (based on python socket wrapper) +# Copyright (C) Amitay Isaacs 2011 +# +# 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 3 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 +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# + +import _socket +from _socket import * + +from samba.socket_wrapper import socket + + +def getfqdn(name=''): + """Get fully qualified domain name from name. + + An empty argument is interpreted as meaning the local host. + + First the hostname returned by gethostbyaddr() is checked, then + possibly existing aliases. In case no FQDN is available, hostname + from gethostname() is returned. + """ + name = name.strip() + if not name or name == '0.0.0.0': + name = gethostname() + try: + hostname, aliases, ipaddrs = gethostbyaddr(name) + except error: + pass + else: + aliases.insert(0, hostname) + for name in aliases: + if '.' in name: + break + else: + name = hostname + return name + + +_GLOBAL_DEFAULT_TIMEOUT = object() diff --git a/lib/socket_wrapper/wscript_build b/lib/socket_wrapper/wscript_build index a81c7aa61a..c4b94147d6 100644 --- a/lib/socket_wrapper/wscript_build +++ b/lib/socket_wrapper/wscript_build @@ -7,3 +7,13 @@ bld.SAMBA_LIBRARY('socket_wrapper', enabled=bld.CONFIG_SET('SOCKET_WRAPPER'), deps='replace') +bld.SAMBA_PYTHON('py_socket_wrapper', + source='py_socket_wrapper.c', + deps='socket_wrapper', + public_deps='talloc pytalloc-util', + realname='samba/socket_wrapper.so') + +bld.SAMBA_SCRIPT('python_socket', + pattern='socket.py', + installdir='python', + installname='samba/socket.py') |