socket_wrapper/py_socket_wrapper.c - include Python 2.4 compatiblity code
[samba.git] / lib / socket_wrapper / py_socket_wrapper.c
1 /*
2  * Copyright (C) Amitay Isaacs 2011
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the author nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  */
34
35 /*
36    Python interface to socket wrapper library.
37
38    Passes all socket communication over unix domain sockets if the environment
39    variable SOCKET_WRAPPER_DIR is set.
40 */
41
42 #include <Python.h>
43 #include <pytalloc.h>
44 #include "replace/replace.h"
45 #include "system/network.h"
46 #include "socket_wrapper.h"
47
48 /* There's no Py_ssize_t in 2.4, apparently */
49 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
50 typedef int Py_ssize_t;
51 typedef inquiry lenfunc;
52 typedef intargfunc ssizeargfunc;
53 #endif
54
55 #ifndef Py_RETURN_NONE
56 #define Py_RETURN_NONE  return Py_INCREF(Py_None), Py_None
57 #endif
58
59 #ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */
60 #define Py_TYPE(ob)             (((PyObject*)(ob))->ob_type)
61 #endif
62
63 #ifndef PY_CHECK_TYPE
64 #define PY_CHECK_TYPE(type, var, fail) \
65         if (!PyObject_TypeCheck(var, type)) {\
66                 PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \
67                 fail; \
68         }
69 #endif
70
71 staticforward PyTypeObject PySocket;
72
73 static PyObject *py_socket_error;
74
75 void initsocket_wrapper(void);
76
77 static PyObject *py_socket_addr_to_tuple(struct sockaddr *addr, socklen_t len)
78 {
79         char host[256];
80         char service[8];
81         int status;
82         PyObject *pyaddr;
83
84         status = getnameinfo(addr, len, host, 255, service, 7, NI_NUMERICHOST|NI_NUMERICSERV);
85         if (status < 0) {
86                 PyErr_SetString(py_socket_error, gai_strerror(status));
87                 return NULL;
88         }
89
90         pyaddr = PyTuple_New(2);
91         if (pyaddr == NULL) {
92                 return PyErr_NoMemory();
93         }
94
95         PyTuple_SetItem(pyaddr, 0, PyString_FromString(host));
96         PyTuple_SetItem(pyaddr, 1, PyInt_FromLong(atoi(service)));
97
98         return pyaddr;
99 }
100
101 static bool py_socket_tuple_to_addr(PyObject *pyaddr, struct sockaddr *addr, socklen_t *len)
102 {
103         const char *host;
104         char *service;
105         in_port_t port;
106         struct addrinfo *ainfo;
107         int status;
108
109         if (!PyTuple_Check(pyaddr)) {
110                 PyErr_SetString(PyExc_TypeError, "Expected a tuple");
111                 return false;
112         }
113
114         if (!PyArg_ParseTuple(pyaddr, "sH", &host, &port)) {
115                 return false;
116         }
117
118         service = talloc_asprintf(NULL, "%d", port);
119         if (service == NULL) {
120                 PyErr_NoMemory();
121                 return false;
122         }
123
124         status = getaddrinfo(host, service, NULL, &ainfo);
125         if (status < 0) {
126                 talloc_free(service);
127                 PyErr_SetString(py_socket_error, gai_strerror(status));
128                 return false;
129         }
130
131         talloc_free(service);
132
133         memcpy(addr, ainfo->ai_addr, sizeof(struct sockaddr));
134         *len = ainfo->ai_addrlen;
135
136         freeaddrinfo(ainfo);
137         return true;
138 }
139
140
141 static PyObject *py_socket_accept(pytalloc_Object *self, PyObject *args)
142 {
143         int *sock, *new_sock;
144         struct sockaddr addr;
145         socklen_t addrlen;
146         PyObject *pysocket;
147         PyObject *pyaddr;
148         PyObject *pyret;
149
150         sock = pytalloc_get_ptr(self);
151
152         new_sock = talloc_zero(NULL, int);
153         if (new_sock == NULL) {
154                 return PyErr_NoMemory();
155         }
156
157         *new_sock = swrap_accept(*sock, &addr, &addrlen);
158         if (*new_sock < 0) {
159                 return PyErr_SetFromErrno(py_socket_error);
160         }
161
162         if ((pysocket = pytalloc_steal(&PySocket, new_sock)) == NULL) {
163                 return PyErr_NoMemory();
164         }
165
166         pyret = PyTuple_New(2);
167         if (pyret == NULL) {
168                 Py_DECREF(pysocket);
169                 return PyErr_NoMemory();
170         }
171
172         pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
173         if (pyaddr == NULL) {
174                 Py_DECREF(pysocket);
175                 Py_DECREF(pysocket);
176                 return NULL;
177         }
178
179         PyTuple_SetItem(pyret, 0, pysocket);
180         PyTuple_SetItem(pyret, 1, pyaddr);
181         return pyret;
182 }
183
184 static PyObject *py_socket_bind(pytalloc_Object *self, PyObject *args)
185 {
186         PyObject *pyaddr;
187         int *sock;
188         int status;
189         struct sockaddr addr;
190         socklen_t addrlen;
191
192         if (!PyArg_ParseTuple(args, "O:bind", &pyaddr)) {
193                 return NULL;
194         }
195
196         if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
197                 return NULL;
198         }
199
200         sock = pytalloc_get_ptr(self);
201
202         status = swrap_bind(*sock, &addr, addrlen);
203         if (status < 0) {
204                 PyErr_SetString(py_socket_error, "Unable to bind");
205                 return NULL;
206         }
207
208         Py_RETURN_NONE;
209 }
210
211 static PyObject *py_socket_close(pytalloc_Object *self, PyObject *args)
212 {
213         int *sock;
214         int status;
215
216         sock = pytalloc_get_ptr(self);
217
218         status = swrap_close(*sock);
219         if (status < 0) {
220                 return PyErr_SetFromErrno(py_socket_error);
221         }
222
223         Py_RETURN_NONE;
224 }
225
226 static PyObject *py_socket_connect(pytalloc_Object *self, PyObject *args)
227 {
228         int *sock;
229         PyObject *pyaddr;
230         struct sockaddr addr;
231         socklen_t addrlen;
232         int status;
233
234         if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) {
235                 return NULL;
236         }
237
238         if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
239                 return NULL;
240         }
241
242         sock = pytalloc_get_ptr(self);
243
244         status = swrap_connect(*sock, &addr, addrlen);
245         if (status < 0) {
246                 PyErr_SetFromErrno(py_socket_error);
247                 return NULL;
248         }
249
250         Py_RETURN_NONE;
251 }
252
253 static PyObject *py_socket_connect_ex(pytalloc_Object *self, PyObject *args)
254 {
255         int *sock;
256         PyObject *pyaddr;
257         struct sockaddr addr;
258         socklen_t addrlen;
259         int status;
260
261         if (!PyArg_ParseTuple(args, "O:connect", &pyaddr)) {
262                 return NULL;
263         }
264
265         if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
266                 return NULL;
267         }
268
269         sock = pytalloc_get_ptr(self);
270
271         status = swrap_connect(*sock, &addr, addrlen);
272         if (status < 0) {
273                 return Py_BuildValue("%d", errno);
274         }
275
276         return Py_BuildValue("%d", 0);
277 }
278
279 static PyObject *py_socket_dup(pytalloc_Object *self, PyObject *args)
280 {
281         int *sock, *new_sock;
282         PyObject *pysocket;
283
284         sock = pytalloc_get_ptr(self);
285
286         new_sock = talloc_zero(NULL, int);
287         if (new_sock == NULL) {
288                 return PyErr_NoMemory();
289         }
290
291         *new_sock = swrap_dup(*sock);
292         if (*new_sock < 0) {
293                 return PyErr_SetFromErrno(py_socket_error);
294         }
295
296         pysocket = pytalloc_steal(&PySocket, new_sock);
297         if (pysocket == NULL) {
298                 return PyErr_NoMemory();
299         }
300
301         return pysocket;
302 }
303
304 static PyObject *py_socket_dup2(pytalloc_Object *self, PyObject *args)
305 {
306         int *sock, *new_sock;
307         PyObject *pysocket;
308         int status;
309
310         if (!PyArg_ParseTuple(args, "O", &pysocket)) {
311                 return NULL;
312         }
313
314         PY_CHECK_TYPE(&PySocket, pysocket, return NULL);
315
316         sock = pytalloc_get_ptr(self);
317         new_sock = pytalloc_get_ptr(pysocket);
318
319         status = swrap_dup2(*sock, *new_sock);
320         if (status < 0) {
321                 return PyErr_SetFromErrno(py_socket_error);
322         }
323
324         Py_RETURN_NONE;
325 }
326
327 static PyObject *py_socket_fileno(pytalloc_Object *self, PyObject *args)
328 {
329         PyErr_SetString(py_socket_error, "Not Supported");
330         return NULL;
331 }
332
333 static PyObject *py_socket_getpeername(pytalloc_Object *self, PyObject *args)
334 {
335         int *sock;
336         struct sockaddr addr;
337         socklen_t addrlen;
338         int status;
339         PyObject *pyaddr;
340
341         sock = pytalloc_get_ptr(self);
342
343         status = swrap_getpeername(*sock, &addr, &addrlen);
344         if (status < 0) {
345                 return PyErr_SetFromErrno(py_socket_error);
346         }
347
348         pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
349
350         return pyaddr;
351 }
352
353 static PyObject *py_socket_getsockname(pytalloc_Object *self, PyObject *args)
354 {
355         int *sock;
356         struct sockaddr addr;
357         socklen_t addrlen;
358         int status;
359         PyObject *pyaddr;
360
361         sock = pytalloc_get_ptr(self);
362
363         status = swrap_getsockname(*sock, &addr, &addrlen);
364         if (status < 0) {
365                 return PyErr_SetFromErrno(py_socket_error);
366         }
367
368         pyaddr = py_socket_addr_to_tuple(&addr, addrlen);
369
370         return pyaddr;
371 }
372
373 static PyObject *py_socket_getsockopt(pytalloc_Object *self, PyObject *args)
374 {
375         int level, optname;
376         int *sock;
377         socklen_t optlen = -1, newlen;
378         int optval;
379         bool is_integer = false;
380         char *buffer;
381         PyObject *pyret;
382         int status;
383
384         if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &optlen)) {
385                 return NULL;
386         }
387
388         if (optlen < 0) {
389                 optlen = sizeof(int);
390                 is_integer = true;
391         }
392
393         buffer = talloc_zero_array(NULL, char, optlen);
394         if (buffer == NULL) {
395                 return PyErr_NoMemory();
396         }
397
398         sock = pytalloc_get_ptr(self);
399
400         status = swrap_getsockopt(*sock, level, optname, (void *)buffer, &newlen);
401         if (status < 0) {
402                 talloc_free(buffer);
403                 return PyErr_SetFromErrno(py_socket_error);
404         }
405
406         if (is_integer) {
407                 optval = *(int *)buffer;
408                 pyret = PyInt_FromLong(optval);
409         } else {
410                 pyret = PyString_FromStringAndSize(buffer, optlen);
411         }
412
413         talloc_free(buffer);
414
415         return pyret;
416 }
417
418 static PyObject *py_socket_gettimeout(pytalloc_Object *self, PyObject *args)
419 {
420         PyErr_SetString(py_socket_error, "Not Supported");
421         return NULL;
422 }
423
424 static PyObject *py_socket_listen(pytalloc_Object *self, PyObject *args)
425 {
426         int backlog;
427         int *sock;
428         int status;
429
430         if (!PyArg_ParseTuple(args, "i:listen", &backlog)) {
431                 return NULL;
432         }
433
434         sock = pytalloc_get_ptr(self);
435
436         status = swrap_listen(*sock, backlog);
437         if (status < 0) {
438                 return PyErr_SetFromErrno(py_socket_error);
439         }
440
441         Py_RETURN_NONE;
442 }
443
444 static PyObject *py_socket_makefile(pytalloc_Object *self, PyObject *args)
445 {
446         PyErr_SetString(py_socket_error, "Not Supported");
447         return NULL;
448 }
449
450 static PyObject *py_socket_read(pytalloc_Object *self, PyObject *args)
451 {
452         int bufsize, len;
453         int *sock;
454         char *buffer;
455         PyObject *pyret;
456
457         if (!PyArg_ParseTuple(args, "i:read", &bufsize)) {
458                 return NULL;
459         }
460
461         buffer = talloc_zero_array(NULL, char, bufsize);
462         if (buffer == NULL) {
463                 return PyErr_NoMemory();
464         }
465
466         sock = pytalloc_get_ptr(self);
467
468         len = swrap_read(*sock, buffer, bufsize);
469         if (len < 0) {
470                 return PyErr_SetFromErrno(py_socket_error);
471         }
472
473         pyret = PyString_FromStringAndSize(buffer, len);
474
475         talloc_free(buffer);
476
477         return pyret;
478 }
479
480 static PyObject *py_socket_recv(pytalloc_Object *self, PyObject *args)
481 {
482         int bufsize, flags, len;
483         int *sock;
484         char *buffer;
485         PyObject *pyret;
486
487         if (!PyArg_ParseTuple(args, "ii:recv", &bufsize, &flags)) {
488                 return NULL;
489         }
490
491         buffer = talloc_zero_array(NULL, char, bufsize);
492         if (buffer == NULL) {
493                 return PyErr_NoMemory();
494         }
495
496         sock = pytalloc_get_ptr(self);
497
498         len = swrap_recv(*sock, buffer, bufsize, flags);
499         if (len < 0) {
500                 return PyErr_SetFromErrno(py_socket_error);
501         }
502
503         pyret = PyString_FromStringAndSize(buffer, len);
504
505         talloc_free(buffer);
506
507         return pyret;
508 }
509
510 static PyObject *py_socket_recvfrom(pytalloc_Object *self, PyObject *args)
511 {
512         int bufsize, flags, len;
513         int *sock;
514         char *buffer;
515         struct sockaddr from;
516         socklen_t fromlen;
517         PyObject *pybuf, *pyaddr, *pyret;
518
519         if (!PyArg_ParseTuple(args, "ii:recvfrom", &bufsize, &flags)) {
520                 return NULL;
521         }
522
523         buffer = talloc_zero_array(NULL, char, bufsize);
524         if (buffer == NULL) {
525                 return PyErr_NoMemory();
526         }
527
528         sock = pytalloc_get_ptr(self);
529
530         fromlen = sizeof(struct sockaddr);
531
532         len = swrap_recvfrom(*sock, buffer, bufsize, flags, &from, &fromlen);
533         if (len < 0) {
534                 talloc_free(buffer);
535                 return PyErr_SetFromErrno(py_socket_error);
536         }
537
538         pybuf = PyString_FromStringAndSize(buffer, len);
539         if (pybuf == NULL) {
540                 talloc_free(buffer);
541                 return PyErr_NoMemory();
542         }
543
544         talloc_free(buffer);
545
546         pyaddr = py_socket_addr_to_tuple(&from, fromlen);
547         if (pyaddr == NULL) {
548                 Py_DECREF(pybuf);
549                 return NULL;
550         }
551
552         pyret = PyTuple_New(2);
553         if (pyret == NULL) {
554                 Py_DECREF(pybuf);
555                 Py_DECREF(pyaddr);
556                 return PyErr_NoMemory();
557         }
558
559         PyTuple_SetItem(pyret, 0, pybuf);
560         PyTuple_SetItem(pyret, 1, pyaddr);
561
562         return pyret;
563 }
564
565 static PyObject *py_socket_send(pytalloc_Object *self, PyObject *args)
566 {
567         char *buffer;
568         int len, flags;
569         int *sock;
570         int status;
571
572         if (!PyArg_ParseTuple(args, "s#i:sendto", &buffer, &len, &flags)) {
573                 return NULL;
574         }
575
576         sock = pytalloc_get_ptr(self);
577
578         status = swrap_send(*sock, buffer, len, flags);
579         if (status < 0) {
580                 PyErr_SetFromErrno(py_socket_error);
581                 return NULL;
582         }
583
584         Py_RETURN_NONE;
585 }
586
587 static PyObject *py_socket_sendall(pytalloc_Object *self, PyObject *args)
588 {
589         char *buffer;
590         int len, flags;
591         int *sock;
592         int status;
593
594         if (!PyArg_ParseTuple(args, "s#i:sendall", &buffer, &len, &flags)) {
595                 return NULL;
596         }
597
598         sock = pytalloc_get_ptr(self);
599
600         status = swrap_send(*sock, buffer, len, flags);
601         if (status < 0) {
602                 PyErr_SetFromErrno(py_socket_error);
603                 return NULL;
604         }
605
606         Py_RETURN_NONE;
607 }
608
609 static PyObject *py_socket_sendto(pytalloc_Object *self, PyObject *args)
610 {
611         PyObject *pyaddr;
612         char *buffer;
613         int len, flags;
614         int *sock;
615         struct sockaddr addr;
616         socklen_t addrlen;
617         int status;
618
619         if (!PyArg_ParseTuple(args, "s#iO:sendto", &buffer, &len, &flags, &pyaddr)) {
620                 return NULL;
621         }
622
623         if (!py_socket_tuple_to_addr(pyaddr, &addr, &addrlen)) {
624                 return NULL;
625         }
626
627         sock = pytalloc_get_ptr(self);
628
629         status = swrap_sendto(*sock, buffer, len, flags, &addr, addrlen);
630         if (status < 0) {
631                 PyErr_SetFromErrno(py_socket_error);
632                 return NULL;
633         }
634
635         Py_RETURN_NONE;
636 }
637
638 static PyObject *py_socket_setblocking(pytalloc_Object *self, PyObject *args)
639 {
640         PyErr_SetString(py_socket_error, "Not Supported");
641         return NULL;
642 }
643
644 static PyObject *py_socket_setsockopt(pytalloc_Object *self, PyObject *args)
645 {
646         int level, optname;
647         int *sock;
648         PyObject *pyval;
649         int optval;
650         Py_ssize_t optlen;
651         char *buffer;
652         int status;
653
654         if (!PyArg_ParseTuple(args, "iiO:getsockopt", &level, &optname, &pyval)) {
655                 return NULL;
656         }
657
658         if (PyInt_Check(pyval)) {
659                 optval = PyInt_AsLong(pyval);
660                 buffer = (char *)&optval;
661                 optlen = sizeof(int);
662         } else {
663                 PyString_AsStringAndSize(pyval, &buffer, &optlen);
664         }
665
666         sock = pytalloc_get_ptr(self);
667
668         status = swrap_setsockopt(*sock, level, optname, (void *)buffer, optlen);
669         if (status < 0) {
670                 return PyErr_SetFromErrno(py_socket_error);
671         }
672
673         Py_RETURN_NONE;
674 }
675
676 static PyObject *py_socket_settimeout(pytalloc_Object *self, PyObject *args)
677 {
678         PyErr_SetString(py_socket_error, "Not Supported");
679         return NULL;
680 }
681
682 static PyObject *py_socket_shutdown(pytalloc_Object *self, PyObject *args)
683 {
684         PyErr_SetString(py_socket_error, "Not Supported");
685         return NULL;
686 }
687
688 static PyObject *py_socket_write(pytalloc_Object *self, PyObject *args)
689 {
690         char *buffer;
691         int len;
692         int *sock;
693         int status;
694
695         if (!PyArg_ParseTuple(args, "s#:write", &buffer, &len)) {
696                 return NULL;
697         }
698
699         sock = pytalloc_get_ptr(self);
700
701         status = swrap_send(*sock, buffer, len, 0);
702         if (status < 0) {
703                 PyErr_SetFromErrno(py_socket_error);
704                 return NULL;
705         }
706
707         Py_RETURN_NONE;
708 }
709
710
711 static PyMethodDef py_socket_methods[] = {
712         { "accept", (PyCFunction)py_socket_accept, METH_NOARGS,
713                 "accept() -> (socket object, address info)\n\n \
714                 Wait for an incoming connection." },
715         { "bind", (PyCFunction)py_socket_bind, METH_VARARGS,
716                 "bind(address)\n\n \
717                 Bind the socket to a local address." },
718         { "close", (PyCFunction)py_socket_close, METH_NOARGS,
719                 "close()\n\n \
720                 Close the socket." },
721         { "connect", (PyCFunction)py_socket_connect, METH_VARARGS,
722                 "connect(address)\n\n \
723                 Connect the socket to a remote address." },
724         { "connect_ex", (PyCFunction)py_socket_connect_ex, METH_VARARGS,
725                 "connect_ex(address)\n\n \
726                 Connect the socket to a remote address." },
727         { "dup", (PyCFunction)py_socket_dup, METH_VARARGS,
728                 "dup() -> socket object\n\n \
729                 Return a new socket object connected to the same system resource." },
730         { "dup2", (PyCFunction)py_socket_dup2, METH_VARARGS,
731                 "dup2(socket object) -> socket object\n\n \
732                 Return a new socket object connected to teh same system resource." },
733         { "fileno", (PyCFunction)py_socket_fileno, METH_NOARGS,
734                 "fileno() -> file descriptor\n\n \
735                 Return socket's file descriptor." },
736         { "getpeername", (PyCFunction)py_socket_getpeername, METH_NOARGS,
737                 "getpeername() -> address info\n\n \
738                 Return the address of the remote endpoint." },
739         { "getsockname", (PyCFunction)py_socket_getsockname, METH_NOARGS,
740                 "getsockname() -> address info\n\n \
741                 Return the address of the local endpoing." },
742         { "getsockopt", (PyCFunction)py_socket_getsockopt, METH_VARARGS,
743                 "getsockopt(level, option[, buffersize]) -> value\n\n \
744                 Get a socket option." },
745         { "gettimeout", (PyCFunction)py_socket_gettimeout, METH_NOARGS,
746                 "gettimeout() -> value\n\n \
747                 Return the timeout in seconds associated with socket operations." },
748         { "listen", (PyCFunction)py_socket_listen, METH_VARARGS,
749                 "listen(backlog)\n\n \
750                 Enable a server to accept connections." },
751         { "makefile", (PyCFunction)py_socket_makefile, METH_NOARGS,
752                 "makefile() -> file object\n\n \
753                 Return a file object associated with the socket." },
754         { "read", (PyCFunction)py_socket_read, METH_VARARGS,
755                 "read(buflen) -> data\n\n \
756                 Receive data." },
757         { "recv", (PyCFunction)py_socket_recv, METH_VARARGS,
758                 "recv(buflen, flags) -> data\n\n \
759                 Receive data." },
760         { "recvfrom", (PyCFunction)py_socket_recvfrom, METH_VARARGS,
761                 "recvfrom(buflen, flags) -> (data, sender address)\n\n \
762                 Receive data and sender's address." },
763         { "send", (PyCFunction)py_socket_send, METH_VARARGS,
764                 "send(data, flags)\n\n \
765                 Send data." },
766         { "sendall", (PyCFunction)py_socket_sendall, METH_VARARGS,
767                 "sendall(data, flags)\n\n \
768                 Send data." },
769         { "sendto", (PyCFunction)py_socket_sendto, METH_VARARGS,
770                 "sendto(data, flags, addr)\n\n \
771                 Send data to a given address." },
772         { "setblocking", (PyCFunction)py_socket_setblocking, METH_VARARGS,
773                 "setblocking(flag)\n\n \
774                 Set blocking or non-blocking mode of the socket." },
775         { "setsockopt", (PyCFunction)py_socket_setsockopt, METH_VARARGS,
776                 "setsockopt(level, option, value)\n\n \
777                 Set a socket option." },
778         { "settimeout", (PyCFunction)py_socket_settimeout, METH_VARARGS,
779                 "settimeout(value)\n\n \
780                 Set a timeout on socket blocking operations." },
781         { "shutdown", (PyCFunction)py_socket_shutdown, METH_VARARGS,
782                 "shutdown(how)\n\n \
783                 Shut down one or both halves of the connection." },
784         { "write", (PyCFunction)py_socket_write, METH_VARARGS,
785                 "write(data)\n\n \
786                 Send data." },
787         { NULL },
788 };
789
790
791 static PyObject *py_socket_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
792 {
793         int family, sock_type, protocol;
794         int *sock;
795         PyObject *pysocket;
796
797         if (!PyArg_ParseTuple(args, "iii:socket", &family, &sock_type, &protocol)) {
798                 return NULL;
799         }
800
801         sock = talloc_zero(NULL, int);
802         if (sock == NULL) {
803                 return PyErr_NoMemory();
804         }
805
806         *sock = swrap_socket(family, sock_type, protocol);
807         if (*sock < 0) {
808                 return PyErr_SetFromErrno(py_socket_error);
809         }
810
811         if ((pysocket = pytalloc_steal(type, sock)) == NULL) {
812                 return PyErr_NoMemory();
813         }
814
815         return pysocket;
816 }
817
818
819 static PyTypeObject PySocket = {
820         .tp_name = "socket_wrapper.socket",
821         .tp_basicsize = sizeof(pytalloc_Object),
822         .tp_flags = Py_TPFLAGS_DEFAULT,
823         .tp_methods = py_socket_methods,
824         .tp_new = py_socket_new,
825         .tp_doc = "socket(family, type, proto) -> socket object\n\n Open a socket of the give type.",
826 };
827
828 static PyObject *py_socket_wrapper_dir(PyObject *self)
829 {
830         const char *dir;
831
832         dir = socket_wrapper_dir();
833
834         return PyString_FromString(dir);
835 }
836
837 static PyObject *py_socket_wrapper_default_interface(PyObject *self)
838 {
839         unsigned int id;
840
841         id = socket_wrapper_default_iface();
842
843         return PyInt_FromLong(id);
844 }
845
846
847 static PyMethodDef py_socket_wrapper_methods[] = {
848         { "dir", (PyCFunction)py_socket_wrapper_dir, METH_NOARGS,
849                 "dir() -> path\n\n \
850                 Return socket_wrapper directory." },
851         { "default_iface", (PyCFunction)py_socket_wrapper_default_interface, METH_NOARGS,
852                 "default_iface() -> id\n\n \
853                 Return default interface id." },
854         { NULL },
855 };
856
857 void initsocket_wrapper(void)
858 {
859         PyObject *m;
860         char exception_name[] = "socket_wrapper.error";
861
862         PyTypeObject *talloc_type = pytalloc_GetObjectType();
863         if (talloc_type == NULL) {
864                 return;
865         }
866
867         PySocket.tp_base = talloc_type;
868         if (PyType_Ready(&PySocket) < 0) {
869                 return;
870         }
871
872         m = Py_InitModule3("socket_wrapper", py_socket_wrapper_methods, "Socket wrapper");
873         if (m == NULL) {
874                 return;
875         }
876
877         py_socket_error = PyErr_NewException(exception_name, NULL, NULL);
878         Py_INCREF(py_socket_error);
879         PyModule_AddObject(m, "error", py_socket_error);
880
881         Py_INCREF(&PySocket);
882         PyModule_AddObject(m, "socket", (PyObject *)&PySocket);
883 }