#include <Python.h>
#include <zephyr/zephyr.h>
#include <com_err.h>
/* write various functions to wrap it by hand... */
/* consider swig... */
/* get python2.2-ext from somewhere */
static PyObject *zephyr_getsender(PyObject *self, PyObject *args) {
return Py_BuildValue("s", ZGetSender());
}
/*
char *ZGetVariable ZP((char *));
Code_t ZSetVariable ZP((char *var, char *value));
Code_t ZUnsetVariable ZP((char *var));
int ZGetWGPort ZP((void));
Code_t ZSetDestAddr ZP((struct sockaddr_in *));
Code_t ZFormatNoticeList ZP((ZNotice_t*, char**, int,
char **, int*, Z_AuthProc));
Code_t ZParseNotice ZP((char*, int, ZNotice_t *));
Code_t ZReadAscii ZP((char*, int, unsigned char*, int));
Code_t ZReadAscii32 ZP((char *, int, unsigned long *));
Code_t ZReadAscii16 ZP((char *, int, unsigned short *));
Code_t ZSendPacket ZP((char*, int, int));
Code_t ZSendList ZP((ZNotice_t*, char *[], int, Z_AuthProc));
Code_t ZSrvSendList ZP((ZNotice_t*, char*[], int, Z_AuthProc, Code_t (*)()));
Code_t ZSendNotice ZP((ZNotice_t *, Z_AuthProc));
Code_t ZSrvSendNotice ZP((ZNotice_t*, Z_AuthProc, Code_t (*)()));
Code_t ZFormatNotice ZP((ZNotice_t*, char**, int*, Z_AuthProc));
Code_t ZFormatSmallNotice ZP((ZNotice_t*, ZPacket_t, int*, Z_AuthProc));
Code_t ZFormatRawNoticeList ZP((ZNotice_t *notice, char *list[], int nitems,
char **buffer, int *ret_len));
Code_t ZLocateUser ZP((char *, int *, Z_AuthProc));
Code_t ZRequestLocations ZP((char *, ZAsyncLocateData_t *,
ZNotice_Kind_t, Z_AuthProc));
Code_t ZhmStat ZP((struct in_addr *, ZNotice_t *));
*/
/*
Code_t ZInitialize ZP((void));
*/
static PyObject *ZephyrComErr;
static PyObject *zephyr_initialize(PyObject *self, PyObject *args) {
int retval = ZInitialize();
if (retval != ZERR_NONE) {
PyErr_SetString(ZephyrComErr, error_message(retval));
return NULL;
}
Py_INCREF(Py_None);
return Py_None;
}
/*
Code_t ZSetServerState ZP((int));
Code_t ZSetFD ZP((int));
Code_t ZFormatSmallRawNotice ZP((ZNotice_t*, ZPacket_t, int*));
int ZCompareUID ZP((ZUnique_Id_t*, ZUnique_Id_t*));
Code_t ZSrvSendRawList ZP((ZNotice_t*, char*[], int,
Code_t (*)(ZNotice_t *, char *, int, int)));
Code_t ZMakeAscii ZP((char*, int, unsigned char*, int));
Code_t ZMakeAscii32 ZP((char *, int, unsigned long));
Code_t ZMakeAscii16 ZP((char *, int, unsigned int));
Code_t ZReceivePacket ZP((ZPacket_t, int*, struct sockaddr_in*));
Code_t ZCheckAuthentication ZP((ZNotice_t*, struct sockaddr_in*));
Code_t ZInitLocationInfo ZP((char *hostname, char *tty));
Code_t ZSetLocation ZP((char *exposure));
Code_t ZUnsetLocation ZP((void));
Code_t ZFlushMyLocations ZP((void));
char *ZParseExposureLevel ZP((char *text));
Code_t ZFormatRawNotice ZP((ZNotice_t *, char**, int *));
Code_t ZRetrieveSubscriptions ZP((unsigned short, int*));
Code_t ZOpenPort ZP((unsigned short *port));
Code_t ZClosePort ZP((void));
Code_t ZFlushLocations ZP((void));
Code_t ZFlushSubscriptions ZP((void));
Code_t ZFreeNotice ZP((ZNotice_t *notice));
Code_t ZParseLocations ZP((register ZNotice_t *notice,
register ZAsyncLocateData_t *zald, int *nlocs,
char **user));
int ZCompareALDPred ZP((ZNotice_t *notice, void *zald));
void ZFreeALD ZP((register ZAsyncLocateData_t *zald));
Code_t ZCheckIfNotice ZP((ZNotice_t *notice, struct sockaddr_in *from,
register int (*predicate) ZP((ZNotice_t *,void *)),
void *args));
Code_t ZPeekPacket ZP((char **buffer, int *ret_len,
struct sockaddr_in *from));
Code_t ZPeekNotice ZP((ZNotice_t *notice, struct sockaddr_in *from));
Code_t ZIfNotice ZP((ZNotice_t *notice, struct sockaddr_in *from,
int (*predicate) ZP((ZNotice_t *, void *)), void *args));
Code_t ZSubscribeTo ZP((ZSubscription_t *sublist, int nitems,
unsigned int port));
Code_t ZSubscribeToSansDefaults ZP((ZSubscription_t *sublist, int nitems,
unsigned int port));
Code_t ZUnsubscribeTo ZP((ZSubscription_t *sublist, int nitems,
unsigned int port));
Code_t ZCancelSubscriptions ZP((unsigned int port));
int ZPending ZP((void));
Code_t ZReceiveNotice ZP((ZNotice_t *notice, struct sockaddr_in *from));
*/
/* need to construct a notice subclass with a keyworded constructor */
staticforward PyTypeObject Notice_Type;
typedef struct {
PyObject_HEAD
PyObject *attr; /* Attributes dictionary */
ZNotice_t znotice;
} NoticeObject;
static void Notice_dealloc(PyObject* self) {
/* clean up znotice here if we need to */
PyObject_Del(self);
}
static PyMethodDef NoticeMethods[] = {
{ "send", Notice_send, METH_VARARGS, "Send zgram." },
{ NULL, NULL, 0, NULL }, /* end of list */
}
static PyObject* Notice_alloc(PyObject* self, PyObject* args, PyObject* kwds) {
NoticeObject* nobj;
char *kwlist[] = {
"kind", /* int */
"auth", /* ? str */
"class", /* str */
"instance", /* str */
"opcode", /* str */
"sender", /* str */
"recipient", /* str */
"default_format", /* str */
/* "message", /* list of str */
NULL
};
int kkind;
char *kauth = NULL, *kclass = NULL, *kinstance = NULL;
char *kopcode = NULL, *ksender = NULL, *krecip = NULL, *kdefform = NULL;
char *kmessage = NULL; /* wrong */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "izzzzzzz:Notice_alloc", kwlist,
&kkind, &kauth, &kclass, &kinstance, &kopcode,
&ksender, &krecip, &kdefform))
return NULL;
nobj = PyObject_New(NoticeObject, &Notice_Type);
nobj->znotice.z_kind = kkind;
nobj->znotice.z_class = kclass;
nobj->znotice.z_class_inst = kinstance;
nobj->znotice.z_opcode = kopcode;
nobj->znotice.z_sender = ksender;
nobj->znotice.z_recipient = krecip;
nobj->znotice.z_default_format = kdefform;
/* add methods here... */
/* in particular, hook in Notice_send */
/* do we have to give ourselves a dictionary? */
/* looks like it - make a dict, stuff in Notice_send,
maybe stuff in the other fields, or accessors for them... */
/* see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/54352 */
nobj->attr = PyDict_New();
{
/* loop later */
PyMethodDef* pymeth = NoticeMethods;
PyObject* pyfunct = PyCFunction_New(pymeth, NULL);
PyDict_SetItemString(d, "send", pyfunct);
Py_DECREF(pyfunct);
}
return (PyObject*)nobj;
}
static PyObject* Notice_getattr(PyObject* self, PyObject* args, PyObject* kwds) {
return self;
}
static PyObject* Notice_setattr(PyObject* self, PyObject* args, PyObject* kwds) {
return self;
}
/*
char *z_packet;
char *z_version;
ZNotice_Kind_t z_kind;
ZUnique_Id_t z_uid;
#define z_sender_addr z_uid.zuid_addr
struct timeval z_time;
unsigned short z_port;
int z_auth;
int z_checked_auth;
int z_authent_len;
char *z_ascii_authent;
char *z_class;
char *z_class_inst;
char *z_opcode;
char *z_sender;
char *z_recipient;
char *z_default_format;
char *z_multinotice;
ZUnique_Id_t z_multiuid;
ZChecksum_t z_checksum;
int z_num_other_fields;
char *z_other_fields[Z_MAXOTHERFIELDS];
caddr_t z_message;
int z_message_len;
*/
/* Code_t ZSendNotice(notice, cert_routine)
with this we don't really need the other pieces... */
static PyObject *Notice_send(PyObject *self, PyObject *args) {
NoticeObject* nobj;
Code_t st;
int authflag = 0;
if (!PyArg_ParseTuple(args, "i:Notice_send", &authflag)) {
return NULL;
}
nobj = (NoticeObject*)self;
st = ZSendNotice(&nobj->znotice, authflag?ZAUTH:ZNOAUTH);
if (st) {
/* do something clever */
return NULL; /* like raise an exception */
} else {
return NULL; /* "normal" return */
}
}
statichere PyTypeObject Notice_Type = {
/* The ob_type field must be initialized in the module init function
* to be portable to Windows without using C++. */
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"zephyr.Notice", /*tp_name*/
sizeof(NoticeObject), /*tp_basicsize*/
0, /*tp_itemsize*/
/* methods */
(destructor)Notice_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)Notice_getattr, /*tp_getattr*/
(setattrfunc)Notice_setattr, /*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*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
0, /*tp_doc*/
0, /*tp_traverse*/
0, /*tp_clear*/
0, /*tp_richcompare*/
0, /*tp_weaklistoffset*/
0, /*tp_iter*/
0, /*tp_iternext*/
0, /*tp_methods*/
0, /*tp_members*/
0, /*tp_getset*/
0, /*tp_base*/
0, /*tp_dict*/
0, /*tp_descr_get*/
0, /*tp_descr_set*/
0, /*tp_dictoffset*/
0, /*tp_init*/
0, /*tp_alloc*/
0, /*tp_new*/
0, /*tp_free*/
0, /*tp_is_gc*/
};
static PyMethodDef ZephyrMethods[] = {
{ "initialize", zephyr_initialize, METH_NOARGS, "Initialize Zephyr Library." },
{ "getsender", zephyr_getsender, METH_NOARGS, "Get Zephyr Sender." },
{ "Notice", Notice_alloc, METH_KEYWORDS|METH_VARARGS, "Notice subtype." },
{ NULL, NULL, 0, NULL }, /* end of list */
};
#define def_to_string(n) \
PyDict_SetItemString(d, #n, PyString_FromString(n))
#define def_to_int(n) \
PyDict_SetItemString(d, #n, PyInt_FromLong((long)n))
void initzephyr(void) {
PyObject *m, *d;
m = Py_InitModule("zephyr", ZephyrMethods);
d = PyModule_GetDict(m);
/* should these even bother to be exposed? */
def_to_string(HM_SVCNAME);
def_to_string(HM_SRV_SVCNAME);
def_to_string(SERVER_SVCNAME);
def_to_string(SERVER_INSTANCE);
def_to_string(SERVER_SERVICE);
/* these make more sense */
def_to_int(ZAUTH_FAILED);
def_to_int(ZAUTH_YES);
def_to_int(ZAUTH_NO);
def_to_int(UNSAFE);
def_to_int(UNACKED);
def_to_int(ACKED);
def_to_int(HMACK);
def_to_int(HMCTL);
def_to_int(SERVACK);
def_to_int(SERVNAK);
def_to_int(CLIENTACK);
def_to_int(STAT);
/* mirror ZNoticeKinds too? */
/* com_err stuff. we *shouldn't* need the constants, but... */
def_to_int(ZERR_PKTLEN);
def_to_int(ZERR_HEADERLEN);
def_to_int(ZERR_ILLVAL);
def_to_int(ZERR_HMPORT);
def_to_int(ZERR_PORTINUSE);
def_to_int(ZERR_BADPKT);
def_to_int(ZERR_VERS);
def_to_int(ZERR_NOPORT);
def_to_int(ZERR_NONOTICE);
def_to_int(ZERR_QLEN);
def_to_int(ZERR_HMDEAD);
def_to_int(ZERR_INTERNAL);
def_to_int(ZERR_NOLOCATIONS);
def_to_int(ZERR_NOMORELOCS);
def_to_int(ZERR_FIELDLEN);
def_to_int(ZERR_BADFIELD);
def_to_int(ZERR_SERVNAK);
def_to_int(ZERR_AUTHFAIL);
def_to_int(ZERR_LOGINFAIL);
def_to_int(ZERR_NOSUBSCRIPTIONS);
def_to_int(ZERR_NOMORESUBSCRIPTIONS);
def_to_int(ZERR_TOOMANYSUBS);
def_to_int(ZERR_EOF);
def_to_int(ERROR_TABLE_BASE_zeph);
ZephyrComErr = PyErr_NewException("zephyr.comerr", NULL, NULL);
PyDict_SetItemString(d, "comerr", ZephyrComErr);
}