Blame libiscsi/pylibiscsi.c

Packit Service 2a7015
/*
Packit Service 2a7015
 * iSCSI Administration library
Packit Service 2a7015
 *
Packit Service 2a7015
 * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
Packit Service 2a7015
 * Copyright (C) 2008-2009 Hans de Goede <hdegoede@redhat.com>
Packit Service 2a7015
 * maintained by open-iscsi@googlegroups.com
Packit Service 2a7015
 *
Packit Service 2a7015
 * This program is free software; you can redistribute it and/or modify
Packit Service 2a7015
 * it under the terms of the GNU General Public License as published
Packit Service 2a7015
 * by the Free Software Foundation; either version 2 of the License, or
Packit Service 2a7015
 * (at your option) any later version.
Packit Service 2a7015
 *
Packit Service 2a7015
 * This program is distributed in the hope that it will be useful, but
Packit Service 2a7015
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 2a7015
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Packit Service 2a7015
 * General Public License for more details.
Packit Service 2a7015
 *
Packit Service 2a7015
 * See the file COPYING included with this distribution for more details.
Packit Service 2a7015
 */
Packit Service 2a7015
Packit Service 2a7015
#include <Python.h>
Packit Service 2a7015
#include "libiscsi.h"
Packit Service 2a7015
Packit Service 2a7015
#if PY_MAJOR_VERSION >= 3
Packit Service 2a7015
#define IS_PY3K
Packit Service 2a7015
#define MODINITERROR return NULL
Packit Service 2a7015
#define PYNUM_FROMLONG PyLong_FromLong
Packit Service 2a7015
#define PYSTR_FROMSTRING PyUnicode_FromString
Packit Service 2a7015
#else
Packit Service 2a7015
#define MODINITERROR return
Packit Service 2a7015
#define PYNUM_FROMLONG PyInt_FromLong
Packit Service 2a7015
#define PYSTR_FROMSTRING PyString_FromString
Packit Service 2a7015
#endif
Packit Service 2a7015
Packit Service 2a7015
#define RET_TRUE_ELSE_FALSE { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; }
Packit Service 2a7015
#define CMP_TO_RICHCMP(cmpfunc) \
Packit Service 2a7015
	int comp_res = cmpfunc(self, other); \
Packit Service 2a7015
	switch (op) { \
Packit Service 2a7015
	    case Py_LT: \
Packit Service 2a7015
		if (comp_res < 0) RET_TRUE_ELSE_FALSE \
Packit Service 2a7015
	    case Py_LE: \
Packit Service 2a7015
		if (comp_res <= 0) RET_TRUE_ELSE_FALSE \
Packit Service 2a7015
	    case Py_EQ: \
Packit Service 2a7015
		if (comp_res == 0) RET_TRUE_ELSE_FALSE \
Packit Service 2a7015
	    case Py_NE: \
Packit Service 2a7015
		if (comp_res != 0) RET_TRUE_ELSE_FALSE \
Packit Service 2a7015
	    case Py_GT: \
Packit Service 2a7015
		if (comp_res > 0) RET_TRUE_ELSE_FALSE \
Packit Service 2a7015
	    default: \
Packit Service 2a7015
		if (comp_res >= 0) RET_TRUE_ELSE_FALSE \
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
static struct libiscsi_context *context = NULL;
Packit Service 2a7015
Packit Service 2a7015
/****************************** helpers ***********************************/
Packit Service 2a7015
static int check_string(const char *string)
Packit Service 2a7015
{
Packit Service 2a7015
	if (strlen(string) >= LIBISCSI_VALUE_MAXLEN) {
Packit Service 2a7015
		PyErr_SetString(PyExc_ValueError, "string too long");
Packit Service 2a7015
		return -1;
Packit Service 2a7015
	}
Packit Service 2a7015
	return 0;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
/********************** PyIscsiChapAuthInfo ***************************/
Packit Service 2a7015
Packit Service 2a7015
typedef struct {
Packit Service 2a7015
	PyObject_HEAD
Packit Service 2a7015
Packit Service 2a7015
	struct libiscsi_auth_info info;
Packit Service 2a7015
} PyIscsiChapAuthInfo;
Packit Service 2a7015
Packit Service 2a7015
static int PyIscsiChapAuthInfo_init(PyObject *self, PyObject *args,
Packit Service 2a7015
				    PyObject *kwds)
Packit Service 2a7015
{
Packit Service 2a7015
	int i;
Packit Service 2a7015
	PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
Packit Service 2a7015
	char *kwlist[] = {"username", "password", "reverse_username",
Packit Service 2a7015
				"reverse_password", NULL};
Packit Service 2a7015
	const char *string[4] = { NULL, NULL, NULL, NULL };
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_ParseTupleAndKeywords(args, kwds,
Packit Service 2a7015
					"zz|zz:chapAuthInfo.__init__",
Packit Service 2a7015
					kwlist, &string[0], &string[1],
Packit Service 2a7015
					&string[2], &string[3]))
Packit Service 2a7015
		return -1;
Packit Service 2a7015
Packit Service 2a7015
	for (i = 0; i < 4; i++)
Packit Service 2a7015
		if (string[i] && check_string(string[i]))
Packit Service 2a7015
			return -1;
Packit Service 2a7015
Packit Service 2a7015
	memset (&chap->info, 0, sizeof(chap->info));
Packit Service 2a7015
	chap->info.method = libiscsi_auth_chap;
Packit Service 2a7015
	if (string[0])
Packit Service 2a7015
		strcpy(chap->info.chap.username, string[0]);
Packit Service 2a7015
	if (string[1])
Packit Service 2a7015
		strcpy(chap->info.chap.password, string[1]);
Packit Service 2a7015
	if (string[2])
Packit Service 2a7015
		strcpy(chap->info.chap.reverse_username, string[2]);
Packit Service 2a7015
	if (string[3])
Packit Service 2a7015
		strcpy(chap->info.chap.reverse_password, string[3]);
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_verify_auth_info(context, &chap->info)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_ValueError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return -1;
Packit Service 2a7015
	}
Packit Service 2a7015
	return 0;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiChapAuthInfo_get(PyObject *self, void *data)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
Packit Service 2a7015
	const char *attr = (const char *)data;
Packit Service 2a7015
Packit Service 2a7015
	if (!strcmp(attr, "username")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(chap->info.chap.username);
Packit Service 2a7015
	} else if (!strcmp(attr, "password")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(chap->info.chap.password);
Packit Service 2a7015
	} else if (!strcmp(attr, "reverse_username")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(chap->info.chap.reverse_username);
Packit Service 2a7015
	} else if (!strcmp(attr, "reverse_password")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(chap->info.chap.reverse_password);
Packit Service 2a7015
	}
Packit Service 2a7015
	return NULL;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static int PyIscsiChapAuthInfo_set(PyObject *self, PyObject *value, void *data)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
Packit Service 2a7015
	const char *attr = (const char *)data;
Packit Service 2a7015
	const char *str;
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_Parse(value, "s", &str) || check_string(str))
Packit Service 2a7015
		return -1;
Packit Service 2a7015
Packit Service 2a7015
	if (!strcmp(attr, "username")) {
Packit Service 2a7015
		strcpy(chap->info.chap.username, str);
Packit Service 2a7015
	} else if (!strcmp(attr, "password")) {
Packit Service 2a7015
		strcpy(chap->info.chap.password, str);
Packit Service 2a7015
	} else if (!strcmp(attr, "reverse_username")) {
Packit Service 2a7015
		strcpy(chap->info.chap.reverse_username, str);
Packit Service 2a7015
	} else if (!strcmp(attr, "reverse_password")) {
Packit Service 2a7015
		strcpy(chap->info.chap.reverse_password, str);
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	return 0;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static int PyIscsiChapAuthInfo_compare(PyIscsiChapAuthInfo *self,
Packit Service 2a7015
				       PyIscsiChapAuthInfo *other)
Packit Service 2a7015
{
Packit Service 2a7015
	int r;
Packit Service 2a7015
Packit Service 2a7015
	r = strcmp(self->info.chap.username, other->info.chap.username);
Packit Service 2a7015
	if (r)
Packit Service 2a7015
		return r;
Packit Service 2a7015
Packit Service 2a7015
	r = strcmp(self->info.chap.password, other->info.chap.password);
Packit Service 2a7015
	if (r)
Packit Service 2a7015
		return r;
Packit Service 2a7015
Packit Service 2a7015
	r = strcmp(self->info.chap.reverse_username,
Packit Service 2a7015
		   other->info.chap.reverse_username);
Packit Service 2a7015
	if (r)
Packit Service 2a7015
		return r;
Packit Service 2a7015
Packit Service 2a7015
	r = strcmp(self->info.chap.reverse_password,
Packit Service 2a7015
		   other->info.chap.reverse_password);
Packit Service 2a7015
	return r;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
PyObject *PyIscsiChapAuthInfo_richcompare(PyIscsiChapAuthInfo *self,
Packit Service 2a7015
	                                  PyIscsiChapAuthInfo *other,
Packit Service 2a7015
					  int op)
Packit Service 2a7015
{
Packit Service 2a7015
	CMP_TO_RICHCMP(PyIscsiChapAuthInfo_compare)
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiChapAuthInfo_str(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiChapAuthInfo *chap = (PyIscsiChapAuthInfo *)self;
Packit Service 2a7015
	char s[1024], reverse[512] = "";
Packit Service 2a7015
Packit Service 2a7015
	if (chap->info.chap.reverse_username[0])
Packit Service 2a7015
		snprintf(reverse, sizeof(reverse), ", %s:%s",
Packit Service 2a7015
			 chap->info.chap.reverse_username,
Packit Service 2a7015
			 chap->info.chap.reverse_password);
Packit Service 2a7015
Packit Service 2a7015
	snprintf(s, sizeof(s), "%s:%s%s", chap->info.chap.username,
Packit Service 2a7015
		 chap->info.chap.password, reverse);
Packit Service 2a7015
Packit Service 2a7015
	return PYSTR_FROMSTRING(s);
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static struct PyGetSetDef PyIscsiChapAuthInfo_getseters[] = {
Packit Service 2a7015
	{"username", (getter)PyIscsiChapAuthInfo_get,
Packit Service 2a7015
		(setter)PyIscsiChapAuthInfo_set,
Packit Service 2a7015
		"username", "username"},
Packit Service 2a7015
	{"password", (getter)PyIscsiChapAuthInfo_get,
Packit Service 2a7015
		(setter)PyIscsiChapAuthInfo_set,
Packit Service 2a7015
		"password", "password"},
Packit Service 2a7015
	{"reverse_username", (getter)PyIscsiChapAuthInfo_get,
Packit Service 2a7015
		(setter)PyIscsiChapAuthInfo_set,
Packit Service 2a7015
		"reverse_username", "reverse_username"},
Packit Service 2a7015
	{"reverse_password", (getter)PyIscsiChapAuthInfo_get,
Packit Service 2a7015
		(setter)PyIscsiChapAuthInfo_set,
Packit Service 2a7015
		"reverse_password", "reverse_password"},
Packit Service 2a7015
	{NULL}
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
PyTypeObject PyIscsiChapAuthInfo_Type = {
Packit Service 2a7015
	PyVarObject_HEAD_INIT(NULL, 0)
Packit Service 2a7015
	.tp_name = "libiscsi.chapAuthInfo",
Packit Service 2a7015
	.tp_basicsize = sizeof (PyIscsiChapAuthInfo),
Packit Service 2a7015
	.tp_getset = PyIscsiChapAuthInfo_getseters,
Packit Service 2a7015
	.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Packit Service 2a7015
#ifndef IS_PY3K
Packit Service 2a7015
	// Py_TPFLAGS_CHECKTYPES is only needed on Python 2
Packit Service 2a7015
	|  Py_TPFLAGS_CHECKTYPES
Packit Service 2a7015
#endif
Packit Service 2a7015
	,
Packit Service 2a7015
	.tp_richcompare = (richcmpfunc)PyIscsiChapAuthInfo_compare,
Packit Service 2a7015
	.tp_init = PyIscsiChapAuthInfo_init,
Packit Service 2a7015
	.tp_str = PyIscsiChapAuthInfo_str,
Packit Service 2a7015
	.tp_new = PyType_GenericNew,
Packit Service 2a7015
	.tp_doc = "iscsi chap authentication information.",
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
/***************************** PyIscsiNode  ********************************/
Packit Service 2a7015
Packit Service 2a7015
typedef struct {
Packit Service 2a7015
	PyObject_HEAD
Packit Service 2a7015
Packit Service 2a7015
	struct libiscsi_node node;
Packit Service 2a7015
} PyIscsiNode;
Packit Service 2a7015
Packit Service 2a7015
static int PyIscsiNode_init(PyObject *self, PyObject *args, PyObject *kwds)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	char *kwlist[] = {"name", "tpgt", "address", "port", "iface", NULL};
Packit Service 2a7015
	const char *name = NULL, *address = NULL, *iface = NULL;
Packit Service 2a7015
	int tpgt = -1, port = 3260;
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|isis:node.__init__",
Packit Service 2a7015
					 kwlist, &name, &tpgt, &address,
Packit Service 2a7015
					 &port, &iface))
Packit Service 2a7015
		return -1;
Packit Service 2a7015
	if (address == NULL) {
Packit Service 2a7015
		PyErr_SetString(PyExc_ValueError, "address not set");
Packit Service 2a7015
		return -1;
Packit Service 2a7015
	}
Packit Service 2a7015
	if (check_string(name) || check_string(address) || check_string(iface))
Packit Service 2a7015
		return -1;
Packit Service 2a7015
Packit Service 2a7015
	strcpy(node->node.name, name);
Packit Service 2a7015
	node->node.tpgt = tpgt;
Packit Service 2a7015
	strcpy(node->node.address, address);
Packit Service 2a7015
	node->node.port = port;
Packit Service 2a7015
	strcpy(node->node.iface, iface);
Packit Service 2a7015
Packit Service 2a7015
	return 0;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_get(PyObject *self, void *data)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	const char *attr = (const char *)data;
Packit Service 2a7015
Packit Service 2a7015
	if (!strcmp(attr, "name")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(node->node.name);
Packit Service 2a7015
	} else if (!strcmp(attr, "tpgt")) {
Packit Service 2a7015
		return PYNUM_FROMLONG(node->node.tpgt);
Packit Service 2a7015
	} else if (!strcmp(attr, "address")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(node->node.address);
Packit Service 2a7015
	} else if (!strcmp(attr, "port")) {
Packit Service 2a7015
		return PYNUM_FROMLONG(node->node.port);
Packit Service 2a7015
	} else if (!strcmp(attr, "iface")) {
Packit Service 2a7015
		return PYSTR_FROMSTRING(node->node.iface);
Packit Service 2a7015
	}
Packit Service 2a7015
	return NULL;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static int PyIscsiNode_set(PyObject *self, PyObject *value, void *data)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	const char *attr = (const char *)data;
Packit Service 2a7015
	const char *str;
Packit Service 2a7015
	int i;
Packit Service 2a7015
Packit Service 2a7015
	if (!strcmp(attr, "name")) {
Packit Service 2a7015
		if (!PyArg_Parse(value, "s", &str) || check_string(str))
Packit Service 2a7015
			return -1;
Packit Service 2a7015
		strcpy(node->node.name, str);
Packit Service 2a7015
	} else if (!strcmp(attr, "tpgt")) {
Packit Service 2a7015
		if (!PyArg_Parse(value, "i", &i))
Packit Service 2a7015
			return -1;
Packit Service 2a7015
		node->node.tpgt = i;
Packit Service 2a7015
	} else if (!strcmp(attr, "address")) {
Packit Service 2a7015
		if (!PyArg_Parse(value, "s", &str) || check_string(str))
Packit Service 2a7015
			return -1;
Packit Service 2a7015
		strcpy(node->node.address, str);
Packit Service 2a7015
	} else if (!strcmp(attr, "port")) {
Packit Service 2a7015
		if (!PyArg_Parse(value, "i", &i))
Packit Service 2a7015
			return -1;
Packit Service 2a7015
		node->node.port = i;
Packit Service 2a7015
	} else if (!strcmp(attr, "iface")) {
Packit Service 2a7015
		if (!PyArg_Parse(value, "s", &str) || check_string(str))
Packit Service 2a7015
			return -1;
Packit Service 2a7015
		strcpy(node->node.iface, str);
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	return 0;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static int PyIscsiNode_compare(PyIscsiNode *self, PyIscsiNode *other)
Packit Service 2a7015
{
Packit Service 2a7015
	int res;
Packit Service 2a7015
Packit Service 2a7015
	res = strcmp(self->node.name, other->node.name);
Packit Service 2a7015
	if (res)
Packit Service 2a7015
		return res;
Packit Service 2a7015
Packit Service 2a7015
	if (self->node.tpgt < other->node.tpgt)
Packit Service 2a7015
		return -1;
Packit Service 2a7015
	if (self->node.tpgt > other->node.tpgt)
Packit Service 2a7015
		return -1;
Packit Service 2a7015
Packit Service 2a7015
	res = strcmp(self->node.address, other->node.address);
Packit Service 2a7015
	if (res)
Packit Service 2a7015
		return res;
Packit Service 2a7015
Packit Service 2a7015
	if (self->node.port < other->node.port)
Packit Service 2a7015
		return -1;
Packit Service 2a7015
	if (self->node.port > other->node.port)
Packit Service 2a7015
		return -1;
Packit Service 2a7015
Packit Service 2a7015
	res = strcmp(self->node.iface, other->node.iface);
Packit Service 2a7015
	if (res)
Packit Service 2a7015
		return res;
Packit Service 2a7015
Packit Service 2a7015
	return 0;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
PyObject *PyIscsiNode_richcompare(PyIscsiNode *self, PyIscsiNode *other, int op)
Packit Service 2a7015
{
Packit Service 2a7015
    CMP_TO_RICHCMP(PyIscsiNode_compare)
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_str(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	char s[1024], tpgt[16] = "";
Packit Service 2a7015
Packit Service 2a7015
	if (node->node.tpgt != -1)
Packit Service 2a7015
		sprintf(tpgt, ",%d", node->node.tpgt);
Packit Service 2a7015
Packit Service 2a7015
	snprintf(s, sizeof(s), "%s:%d%s %s", node->node.address,
Packit Service 2a7015
		 node->node.port, tpgt, node->node.name);
Packit Service 2a7015
Packit Service 2a7015
	return PYSTR_FROMSTRING(s);
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_login(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service e47d02
	int ret;
Packit Service 2a7015
Packit Service e47d02
	Py_BEGIN_ALLOW_THREADS
Packit Service e47d02
	ret = libiscsi_node_login(context, &node->node);
Packit Service e47d02
	Py_END_ALLOW_THREADS
Packit Service e47d02
Packit Service e47d02
	if (ret) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
	Py_RETURN_NONE;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_logout(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_node_logout(context, &node->node)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
	Py_RETURN_NONE;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_setAuth(PyObject *self, PyObject *args,
Packit Service 2a7015
				     PyObject *kwds)
Packit Service 2a7015
{
Packit Service 2a7015
	char *kwlist[] = {"authinfo", NULL};
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	PyObject *arg;
Packit Service 2a7015
	const struct libiscsi_auth_info *authinfo = NULL;
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "O", kwlist, &arg))
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
Packit Service 2a7015
	if (arg == Py_None) {
Packit Service 2a7015
		authinfo = NULL;
Packit Service 2a7015
	} else if (PyObject_IsInstance(arg, (PyObject *)
Packit Service 2a7015
				       &PyIscsiChapAuthInfo_Type)) {
Packit Service 2a7015
		PyIscsiChapAuthInfo *pyauthinfo = (PyIscsiChapAuthInfo *)arg;
Packit Service 2a7015
		authinfo = &pyauthinfo->info;
Packit Service 2a7015
	} else {
Packit Service 2a7015
		PyErr_SetString(PyExc_ValueError, "invalid authinfo type");
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_node_set_auth(context, &node->node, authinfo)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
	Py_RETURN_NONE;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_getAuth(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	PyIscsiChapAuthInfo *pyauthinfo;
Packit Service 2a7015
	struct libiscsi_auth_info authinfo;
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_node_get_auth(context, &node->node, &authinfo)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	switch (authinfo.method) {
Packit Service 2a7015
	case libiscsi_auth_chap:
Packit Service 2a7015
		pyauthinfo = PyObject_New(PyIscsiChapAuthInfo,
Packit Service 2a7015
					  &PyIscsiChapAuthInfo_Type);
Packit Service 2a7015
		if (!pyauthinfo)
Packit Service 2a7015
			return NULL;
Packit Service 2a7015
Packit Service 2a7015
		pyauthinfo->info = authinfo;
Packit Service 2a7015
Packit Service 2a7015
		return (PyObject *)pyauthinfo;
Packit Service 2a7015
Packit Service 2a7015
	case libiscsi_auth_none:
Packit Service 2a7015
	default:
Packit Service 2a7015
		Py_RETURN_NONE;
Packit Service 2a7015
	}
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_setParameter(PyObject *self, PyObject *args,
Packit Service 2a7015
					  PyObject *kwds)
Packit Service 2a7015
{
Packit Service 2a7015
	char *kwlist[] = {"parameter", "value", NULL};
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	const char *parameter, *value;
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", kwlist,
Packit Service 2a7015
					 &parameter, &value))
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	if (check_string(parameter) || check_string(value))
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_node_set_parameter(context, &node->node, parameter,
Packit Service 2a7015
				        value)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
	Py_RETURN_NONE;
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *PyIscsiNode_getParameter(PyObject *self, PyObject *args,
Packit Service 2a7015
					  PyObject *kwds)
Packit Service 2a7015
{
Packit Service 2a7015
	char *kwlist[] = {"parameter", NULL};
Packit Service 2a7015
	PyIscsiNode *node = (PyIscsiNode *)self;
Packit Service 2a7015
	const char *parameter;
Packit Service 2a7015
	char value[LIBISCSI_VALUE_MAXLEN];
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &parameter))
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	if (check_string(parameter))
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_node_get_parameter(context, &node->node, parameter,
Packit Service 2a7015
					value)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
	return Py_BuildValue("s", value);
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static struct PyGetSetDef PyIscsiNode_getseters[] = {
Packit Service 2a7015
	{"name", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
Packit Service 2a7015
		"name", "name"},
Packit Service 2a7015
	{"tpgt", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
Packit Service 2a7015
		"tpgt", "tpgt"},
Packit Service 2a7015
	{"address", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
Packit Service 2a7015
		"address", "address"},
Packit Service 2a7015
	{"port", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
Packit Service 2a7015
		"port", "port"},
Packit Service 2a7015
	{"iface", (getter)PyIscsiNode_get, (setter)PyIscsiNode_set,
Packit Service 2a7015
		"iface", "iface"},
Packit Service 2a7015
	{NULL}
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
static struct PyMethodDef  PyIscsiNode_methods[] = {
Packit Service 2a7015
	{"login", (PyCFunction) PyIscsiNode_login, METH_NOARGS,
Packit Service 2a7015
		"Log in to the node"},
Packit Service 2a7015
	{"logout", (PyCFunction) PyIscsiNode_logout, METH_NOARGS,
Packit Service 2a7015
		"Log out of the node"},
Packit Service 2a7015
	{"setAuth", (PyCFunction) PyIscsiNode_setAuth,
Packit Service 2a7015
		METH_VARARGS|METH_KEYWORDS,
Packit Service 2a7015
		"Set authentication information"},
Packit Service 2a7015
	{"getAuth", (PyCFunction) PyIscsiNode_getAuth, METH_NOARGS,
Packit Service 2a7015
		"Get authentication information"},
Packit Service 2a7015
	{"setParameter", (PyCFunction) PyIscsiNode_setParameter,
Packit Service 2a7015
		METH_VARARGS|METH_KEYWORDS,
Packit Service 2a7015
		"Set an iscsi node parameter"},
Packit Service 2a7015
	{"getParameter", (PyCFunction) PyIscsiNode_getParameter,
Packit Service 2a7015
		METH_VARARGS|METH_KEYWORDS,
Packit Service 2a7015
		"Get an iscsi node parameter"},
Packit Service 2a7015
	{NULL}
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
PyTypeObject PyIscsiNode_Type = {
Packit Service 2a7015
	PyVarObject_HEAD_INIT(NULL, 0)
Packit Service 2a7015
	.tp_name = "libiscsi.node",
Packit Service 2a7015
	.tp_basicsize = sizeof (PyIscsiNode),
Packit Service 2a7015
	.tp_getset = PyIscsiNode_getseters,
Packit Service 2a7015
	.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
Packit Service 2a7015
#ifndef IS_PY3K
Packit Service 2a7015
	| Py_TPFLAGS_CHECKTYPES
Packit Service 2a7015
#endif
Packit Service 2a7015
	,
Packit Service 2a7015
	.tp_methods = PyIscsiNode_methods,
Packit Service 2a7015
	.tp_richcompare = (richcmpfunc)PyIscsiNode_richcompare,
Packit Service 2a7015
	.tp_init = PyIscsiNode_init,
Packit Service 2a7015
	.tp_str = PyIscsiNode_str,
Packit Service 2a7015
	.tp_new = PyType_GenericNew,
Packit Service 2a7015
	.tp_doc = "The iscsi node contains iscsi node information.",
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
/***************************************************************************/
Packit Service 2a7015
Packit Service 2a7015
static PyObject *pylibiscsi_discover_sendtargets(PyObject *self,
Packit Service 2a7015
						PyObject *args, PyObject *kwds)
Packit Service 2a7015
{
Packit Service 2a7015
	char *kwlist[] = {"address", "port", "authinfo", NULL};
Packit Service 2a7015
	const char *address = NULL;
Packit Service 2a7015
	int i, nr_found, port = 3260;
Packit Service 2a7015
	PyObject *authinfo_arg = NULL;
Packit Service 2a7015
	const struct libiscsi_auth_info *authinfo = NULL;
Packit Service 2a7015
	struct libiscsi_node *found_nodes;
Packit Service 2a7015
	PyObject* found_node_list;
Packit Service e47d02
	int ret;
Packit Service 2a7015
Packit Service 2a7015
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|iO",
Packit Service 2a7015
					kwlist, &address, &port,
Packit Service 2a7015
					&authinfo_arg))
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
Packit Service 2a7015
	if (authinfo_arg) {
Packit Service 2a7015
		if (PyObject_IsInstance(authinfo_arg, (PyObject *)
Packit Service 2a7015
					       &PyIscsiChapAuthInfo_Type)) {
Packit Service 2a7015
			PyIscsiChapAuthInfo *pyauthinfo =
Packit Service 2a7015
				(PyIscsiChapAuthInfo *)authinfo_arg;
Packit Service 2a7015
			authinfo = &pyauthinfo->info;
Packit Service 2a7015
		} else if (authinfo_arg != Py_None) {
Packit Service 2a7015
			PyErr_SetString(PyExc_ValueError,
Packit Service 2a7015
				"invalid authinfo type");
Packit Service 2a7015
			return NULL;
Packit Service 2a7015
		}
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service e47d02
	Py_BEGIN_ALLOW_THREADS
Packit Service e47d02
	ret = libiscsi_discover_sendtargets(context, address, port, authinfo,
Packit Service e47d02
					    &nr_found, &found_nodes);
Packit Service e47d02
	Py_END_ALLOW_THREADS
Packit Service e47d02
Packit Service e47d02
	if (ret) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	if (nr_found == 0)
Packit Service 2a7015
		Py_RETURN_NONE;
Packit Service 2a7015
Packit Service 2a7015
	found_node_list = PyList_New(nr_found);
Packit Service 2a7015
	if (!found_node_list)
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
Packit Service 2a7015
	for(i = 0; i < nr_found; i++) {
Packit Service 2a7015
		PyIscsiNode *pynode;
Packit Service 2a7015
		
Packit Service 2a7015
		pynode = PyObject_New(PyIscsiNode, &PyIscsiNode_Type);
Packit Service 2a7015
		if (!pynode) {
Packit Service 2a7015
			/* This will deref already added nodes for us */
Packit Service 2a7015
			Py_DECREF(found_node_list);
Packit Service 2a7015
			return NULL;
Packit Service 2a7015
		}
Packit Service 2a7015
		pynode->node = found_nodes[i];
Packit Service 2a7015
		PyList_SET_ITEM(found_node_list, i, (PyObject *)pynode);
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	return found_node_list;	
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *pylibiscsi_discover_firmware(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	int i, nr_found;
Packit Service 2a7015
	struct libiscsi_node *found_nodes;
Packit Service 2a7015
	PyObject* found_node_list;
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_discover_firmware(context, &nr_found, &found_nodes)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	if (nr_found == 0)
Packit Service 2a7015
		Py_RETURN_NONE;
Packit Service 2a7015
Packit Service 2a7015
	found_node_list = PyList_New(nr_found);
Packit Service 2a7015
	if (!found_node_list)
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
Packit Service 2a7015
	for(i = 0; i < nr_found; i++) {
Packit Service 2a7015
		PyIscsiNode *pynode;
Packit Service 2a7015
		
Packit Service 2a7015
		pynode = PyObject_New(PyIscsiNode, &PyIscsiNode_Type);
Packit Service 2a7015
		if (!pynode) {
Packit Service 2a7015
			/* This will deref already added nodes for us */
Packit Service 2a7015
			Py_DECREF(found_node_list);
Packit Service 2a7015
			return NULL;
Packit Service 2a7015
		}
Packit Service 2a7015
		pynode->node = found_nodes[i];
Packit Service 2a7015
		PyList_SET_ITEM(found_node_list, i, (PyObject *)pynode);
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	return found_node_list;	
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyObject *pylibiscsi_get_firmware_initiator_name(PyObject *self)
Packit Service 2a7015
{
Packit Service 2a7015
	char initiatorname[LIBISCSI_VALUE_MAXLEN];
Packit Service 2a7015
Packit Service 2a7015
	if (libiscsi_get_firmware_initiator_name(initiatorname)) {
Packit Service 2a7015
		PyErr_SetString(PyExc_IOError,
Packit Service 2a7015
				libiscsi_get_error_string(context));
Packit Service 2a7015
		return NULL;
Packit Service 2a7015
	}
Packit Service 2a7015
Packit Service 2a7015
	return PYSTR_FROMSTRING(initiatorname);
Packit Service 2a7015
}
Packit Service 2a7015
Packit Service 2a7015
static PyMethodDef pylibiscsi_functions[] = {
Packit Service 2a7015
	{	"discover_sendtargets",
Packit Service 2a7015
		(PyCFunction)pylibiscsi_discover_sendtargets,
Packit Service 2a7015
		METH_VARARGS|METH_KEYWORDS,
Packit Service 2a7015
		"Do sendtargets discovery and return a list of found nodes)"},
Packit Service 2a7015
	{	"discover_firmware",
Packit Service 2a7015
		(PyCFunction)pylibiscsi_discover_firmware, METH_NOARGS,
Packit Service 2a7015
		"Do firmware discovery and return a list of found nodes)"},
Packit Service 2a7015
	{	"get_firmware_initiator_name",
Packit Service 2a7015
		(PyCFunction)pylibiscsi_get_firmware_initiator_name,
Packit Service 2a7015
		METH_NOARGS,
Packit Service 2a7015
		"Get initator name (iqn) from firmware"},
Packit Service 2a7015
	{NULL, NULL}
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
#ifdef IS_PY3K
Packit Service 2a7015
static struct PyModuleDef libiscsi_def = {
Packit Service 2a7015
	PyModuleDef_HEAD_INIT,
Packit Service 2a7015
	"libiscsi",
Packit Service 2a7015
	NULL,
Packit Service 2a7015
	-1,
Packit Service 2a7015
	pylibiscsi_functions,
Packit Service 2a7015
	NULL,
Packit Service 2a7015
	NULL,
Packit Service 2a7015
	NULL,
Packit Service 2a7015
	NULL
Packit Service 2a7015
};
Packit Service 2a7015
Packit Service 2a7015
PyMODINIT_FUNC PyInit_libiscsi(void)
Packit Service 2a7015
#else
Packit Service 2a7015
PyMODINIT_FUNC initlibiscsi(void)
Packit Service 2a7015
#endif
Packit Service 2a7015
{
Packit Service 2a7015
	PyObject *m;
Packit Service 2a7015
Packit Service 2a7015
	if (!context) /* We may be called more then once */
Packit Service 2a7015
		context = libiscsi_init();
Packit Service 2a7015
	if (!context)
Packit Service 2a7015
		MODINITERROR;
Packit Service 2a7015
Packit Service 2a7015
	if (PyType_Ready(&PyIscsiChapAuthInfo_Type) < 0)
Packit Service 2a7015
		MODINITERROR;
Packit Service 2a7015
Packit Service 2a7015
	if (PyType_Ready(&PyIscsiNode_Type) < 0)
Packit Service 2a7015
		MODINITERROR;
Packit Service 2a7015
Packit Service 2a7015
#ifdef IS_PY3K
Packit Service 2a7015
	m = PyModule_Create(&libiscsi_def);
Packit Service 2a7015
#else
Packit Service 2a7015
	m = Py_InitModule("libiscsi", pylibiscsi_functions);
Packit Service 2a7015
#endif
Packit Service 2a7015
	Py_INCREF(&PyIscsiChapAuthInfo_Type);
Packit Service 2a7015
	PyModule_AddObject(m, "chapAuthInfo", (PyObject *) &PyIscsiChapAuthInfo_Type);
Packit Service 2a7015
	Py_INCREF(&PyIscsiNode_Type);
Packit Service 2a7015
	PyModule_AddObject(m, "node", (PyObject *) &PyIscsiNode_Type);
Packit Service 2a7015
#ifdef IS_PY3K
Packit Service 2a7015
	return m;
Packit Service 2a7015
#endif
Packit Service 2a7015
}