1
0
mirror of https://github.com/gryf/wicd.git synced 2025-12-19 20:38:00 +01:00

experimental:

- Add 3rd party python libraries used by ioctl backend to tree and to setup.py
- Port several bug fixes from the trunk (removing reliance on shell for running external commands, unicode fixes, gui crash fixes, authentication validation improvements, several others)
- Fix some crashes in ioctl backend.
- Change daemon/GUI launch scripts to use the -O flag.
This commit is contained in:
imdano
2008-10-09 18:45:01 +00:00
parent 0eba051360
commit 9ee8bc1875
40 changed files with 3412 additions and 129 deletions

View File

@@ -0,0 +1,428 @@
/*
* python-wpactrl
* --------------
* A Python extension for wpa_supplicant/hostapd control interface access
*
* Copyright (c) 2008 Kel Modderman <kel@otaku42.de>
* License: GPL v2
*
* This is based on (a fork of) pywpa:
* http://downloads.emperorlinux.com/contrib/pywpa/
* Copyright (c) 2006 Jeremy Moles <jeremy@emperorlinux.com>
* License: LGPL v2.1
*
*/
#include <Python.h>
#include <structmember.h>
#include <osdefs.h>
#include "wpa_ctrl.h"
#define WPACTRL_MAJ_VER 1
#define WPACTRL_MIN_VER 0
#define WPACTRL_MIC_VER 1
#define UNUSED __attribute__ (( __unused__ ))
/* ------------------------------------------------------------------------------------- WPACtrl */
typedef struct {
PyObject_HEAD
struct wpa_ctrl* ctrl_iface;
char* ctrl_iface_path;
int attached;
} WPACtrl;
/* -------------------------------------------------------------------------Function Definitions */
static PyObject* wpactrl_version(PyObject*, PyObject*);
static int WPACtrl_open(WPACtrl*, PyObject*, PyObject*);
static PyObject* WPACtrl_request(WPACtrl*, PyObject*, PyObject*);
static PyObject* WPACtrl_attach(WPACtrl*);
static PyObject* WPACtrl_detach(WPACtrl*);
static PyObject* WPACtrl_pending(WPACtrl*);
static PyObject* WPACtrl_recv(WPACtrl*);
static PyObject* WPACtrl_scanresults(WPACtrl*);
static void WPACtrl_close(WPACtrl*);
static PyObject* WPACtrl_error;
/* -------------------------------------------------------------------------- WPACTRL_DOC_STRING */
static char* WPACTRL_DOC_STRING =
"wpactrl defines a single class, WPACtrl, that must be instantiated\n"
"with the pathname of a UNIX domain socket control interface of a\n"
"wpa_supplicant/hostapd daemon.\n"
"\n"
"Once a WPACtrl object has been instantiated, it may call several\n"
"helper methods to interact with the wpa_supplicant/hostapd daemon.\n"
"If an error occurs, a wpactrl.error exception is raised.\n"
"\n"
"The destructor of a WPACtrl instance closes the connection to the\n"
"control interface socket.\n"
"\n"
"Recommendations for the use of wpa_supplicant/hostapd control\n"
"interface access in external programs are at:\n"
" <http://w1.fi/wpa_supplicant/devel/ctrl_iface_page.html>\n"
;
/* ----------------------------------------------------------------------------- wpactrl_version */
static PyObject* wpactrl_version(UNUSED PyObject* u1, UNUSED PyObject* u2)
{
return Py_BuildValue("(iii)", WPACTRL_MAJ_VER, WPACTRL_MIN_VER, WPACTRL_MIC_VER);
}
/* -------------------------------------------------------------------------------- WPACtrl_open */
static int WPACtrl_open(WPACtrl* self, PyObject* args, UNUSED PyObject* kargs)
{
char* path;
if (!PyArg_ParseTuple(args, "s", &path)) {
PyErr_SetString(WPACtrl_error, "failed to parse ctrl_iface_path string");
return -1;
}
if (strlen(path) >= MAXPATHLEN) {
PyErr_SetString(WPACtrl_error, "ctrl_iface_path string length too long");
return -1;
}
self->ctrl_iface_path = malloc(MAXPATHLEN);
if (!self->ctrl_iface_path) {
PyErr_SetString(WPACtrl_error, "failed to allocate memory for ctrl_iface_path");
return -1;
}
strcpy(self->ctrl_iface_path, path);
self->ctrl_iface = wpa_ctrl_open(self->ctrl_iface_path);
if (!self->ctrl_iface) {
PyErr_SetString(WPACtrl_error, "wpa_ctrl_open failed");
return -1;
}
self->attached = 0;
return 0;
}
/* ----------------------------------------------------------------------------- WPACtrl_request */
static PyObject* WPACtrl_request(WPACtrl* self, PyObject* args, UNUSED PyObject* kargs)
{
int ret;
char* cmd;
char buf[2048];
size_t buflen = sizeof(buf) - 1;
if (!PyArg_ParseTuple(args, "s", &cmd)) {
PyErr_SetString(WPACtrl_error, "failed to parse request command string");
return NULL;
}
ret = wpa_ctrl_request(self->ctrl_iface, cmd, strlen(cmd), buf, &buflen, NULL);
switch (ret) {
case 0:
buf[buflen] = '\0';
return Py_BuildValue("s", buf);
case -1:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_request failed");
break;
case -2:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_request timed out");
break;
default:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_request returned unknown error");
break;
}
return NULL;
}
/* ------------------------------------------------------------------------------ WPACtrl_attach */
static PyObject* WPACtrl_attach(WPACtrl* self)
{
int ret;
if (self->attached == 1)
Py_RETURN_NONE;
ret = wpa_ctrl_attach(self->ctrl_iface);
switch (ret) {
case 0:
self->attached = 1;
Py_RETURN_NONE;
case -1:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_attach failed");
break;
case -2:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_attach timed out");
break;
default:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_attach returned unknown error");
break;
}
return NULL;
}
/* ------------------------------------------------------------------------------ WPACtrl_detach */
static PyObject* WPACtrl_detach(WPACtrl* self)
{
int ret;
if (self->attached == 0)
Py_RETURN_NONE;
ret = wpa_ctrl_detach(self->ctrl_iface);
switch (ret) {
case 0:
self->attached = 0;
Py_RETURN_NONE;
case -1:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_detach failed");
break;
case -2:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_detach timed out");
break;
default:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_detach returned unknown error");
break;
}
return NULL;
}
/* ----------------------------------------------------------------------------- WPACtrl_pending */
static PyObject* WPACtrl_pending(WPACtrl* self)
{
int ret;
ret = wpa_ctrl_pending(self->ctrl_iface);
switch (ret) {
case 1:
Py_RETURN_TRUE;
case 0:
Py_RETURN_FALSE;
case -1:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_pending failed");
break;
default:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_pending returned unknown error");
break;
}
return NULL;
}
/* -------------------------------------------------------------------------------- WPACtrl_recv */
static PyObject* WPACtrl_recv(WPACtrl* self)
{
int ret;
char buf[256];
size_t buflen = sizeof(buf) - 1;
Py_BEGIN_ALLOW_THREADS
ret = wpa_ctrl_recv(self->ctrl_iface, buf, &buflen);
Py_END_ALLOW_THREADS
switch (ret) {
case 0:
buf[buflen] = '\0';
return Py_BuildValue("s", buf);
case -1:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_recv failed");
break;
default:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_recv returned unknown error");
break;
}
return NULL;
}
/* ------------------------------------------------------------------------- WPACtrl_scanresults */
static PyObject* WPACtrl_scanresults(WPACtrl* self)
{
int cell;
PyObject* results = PyList_New(0);
for (cell = 0; cell < 1000; cell++) {
int ret;
char bss[10];
char buf[2048];
size_t buflen = sizeof(buf) - 1;
snprintf(bss, sizeof(bss), "BSS %d", cell);
ret = wpa_ctrl_request(self->ctrl_iface, bss, sizeof(bss), buf, &buflen, NULL);
switch (ret) {
case 0:
buf[buflen] = '\0';
break;
case -1:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_request failed");
return NULL;
case -2:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_request timed out");
return NULL;
default:
PyErr_SetString(WPACtrl_error, "wpa_ctrl_request returned unknown error");
return NULL;
}
if (strstr(buf, "bssid="))
PyList_Append(results, Py_BuildValue("s", buf));
else
break;
}
return results;
}
/* ------------------------------------------------------------------------------- WPACtrl_close */
static void WPACtrl_close(WPACtrl* self)
{
if (self->ctrl_iface) {
if (self->attached == 1)
WPACtrl_detach(self);
wpa_ctrl_close(self->ctrl_iface);
self->ctrl_iface = NULL;
}
if (self->ctrl_iface_path) {
free(self->ctrl_iface_path);
self->ctrl_iface_path = NULL;
}
if (self->ob_type)
self->ob_type->tp_free((PyObject*)(self));
}
/* -------------------------------------------------------------------- Member/Method Structures */
static PyMethodDef module_methods[] = {
{
"version", wpactrl_version, METH_NOARGS,
"Returns a version tuple of wpactrl consisting of 3 integers; major version,\n"
"minor version and micro version."
},
{ NULL, NULL, 0, NULL }
};
static PyMethodDef WPACtrl_methods[] = {
{
"request", (PyCFunction)(WPACtrl_request), METH_VARARGS,
"Send a command to wpa_supplicant/hostapd. Returns the command response\n"
"in a string."
},
{
"attach", (PyCFunction)(WPACtrl_attach), METH_NOARGS,
"Register as an event monitor for the control interface."
},
{
"detach", (PyCFunction)(WPACtrl_detach), METH_NOARGS,
"Unregister event monitor from the control interface."
},
{
"pending", (PyCFunction)(WPACtrl_pending), METH_NOARGS,
"Check if any events/messages are pending. Returns True if messages are pending,\n"
"otherwise False."
},
{
"recv", (PyCFunction)(WPACtrl_recv), METH_NOARGS,
"Recieve a pending event/message from ctrl socket. Returns a message string."
},
{
"scanresults", (PyCFunction)(WPACtrl_scanresults), METH_NOARGS,
"Return list of scan results. Each element of the scan result list is a string\n"
"of properties for a single BSS. This method is specific to wpa_supplicant."
},
{ NULL, NULL, 0, NULL }
};
static PyMemberDef WPACtrl_members[] = {
{
"attached", T_INT, offsetof(WPACtrl, attached), READONLY,
"Set to value of 1 if instance has registered as an event monitor via\n"
"the attached() method, otherwise 0."
},
{
"ctrl_iface_path", T_STRING, offsetof(WPACtrl, ctrl_iface_path), READONLY,
"Pathname of WPACtrl control interface socket."
},
{ NULL }
};
/* ------------------------------------------------------------------------------ PyType_WPACtrl */
static PyTypeObject PyType_WPACtrl = {
PyObject_HEAD_INIT(NULL)
0, /* ob_size */
"wpactrl.WPACtrl", /* tp_name */
sizeof(WPACtrl), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)(WPACtrl_close), /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
WPACtrl_methods, /* tp_methods */
WPACtrl_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)(WPACtrl_open), /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
0, /* tp_mro */
0, /* tp_cache */
0, /* tp_subclasses */
0, /* tp_weaklist */
0 /* tp_del */
};
/* --------------------------------------------------------------------------------- initwpactrl */
PyMODINIT_FUNC initwpactrl(void)
{
PyObject* module;
PyType_Ready(&PyType_WPACtrl);
module = Py_InitModule3("wpactrl", module_methods, WPACTRL_DOC_STRING);
WPACtrl_error = PyErr_NewException("wpactrl.error", NULL, NULL);
Py_INCREF(&PyType_WPACtrl);
Py_INCREF(WPACtrl_error);
PyModule_AddObject(module, "WPACtrl", (PyObject*)(&PyType_WPACtrl));
PyModule_AddObject(module, "error", WPACtrl_error);
}