/***********************************************************
Copyright 1994 by Lance Ellinghouse,
Cathedral City, California Republic, United States of America.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the name of Lance Ellinghouse
not be used in advertising or publicity pertaining to distribution 
of the software without specific, written prior permission.

LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE BE LIABLE FOR ANY SPECIAL, 
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* This creates an encryption and decryption engine I am calling
   a rotor due to the original design was a harware rotor with
   contacts used in Germany during WWII.

Rotor Module:

-  rotor.newrotor('key') -> rotorobject  (default of 6 rotors)
-  rotor.newrotor('key', num_rotors) -> rotorobject

Rotor Objects:

-  ro.setkey('string') -> None (resets the key as defined in newrotor().
-  ro.encrypt('string') -> encrypted string
-  ro.decrypt('encrypted string') -> unencrypted string

-  ro.encryptmore('string') -> encrypted string
-  ro.decryptmore('encrypted string') -> unencrypted string

NOTE: the {en,de}cryptmore() methods use the setup that was
      established via the {en,de}crypt calls. They will NOT
      re-initalize the rotors unless: 1) They have not been
      initalized with {en,de}crypt since the last setkey() call;
      2) {en,de}crypt has not been called for this rotor yet.

NOTE: you MUST use the SAME key in rotor.newrotor()
      if you wish to decrypt an encrypted string.
      Also, the encrypted string is NOT 0-127 ASCII. 
      It is considered BINARY data.

*/

/* Rotor objects */

#include "Python.h"

#include "mymath.h"

#define TRUE	1
#define FALSE	0

typedef struct {
	PyObject_HEAD
	int seed[3];
    	short key[5];
	int  isinited;
	int  size;
	int  size_mask;
    	int  rotors;
	unsigned char *e_rotor; /* [num_rotors][size] */
	unsigned char *d_rotor; /* [num_rotors][size] */
	unsigned char *positions; /* [num_rotors] */
	unsigned char *advances; /* [num_rotors] */
} PyRotorObject;

staticforward PyTypeObject PyRotor_Type;

#define PyRotor_Check(v)		((v)->ob_type == &PyRotor_Type)

/*
	This defines the necessary routines to manage rotor objects
*/

static void set_seed( r )
PyRotorObject *r;
{
	r->seed[0] = r->key[0];
	r->seed[1] = r->key[1];
	r->seed[2] = r->key[2];
	r->isinited = FALSE;
}
	
/* Return the next random number in the range [0.0 .. 1.0) */
static float r_random( r )
PyRotorObject *r;
{
	int x, y, z;
	float val, term;

	x = r->seed[0];
	y = r->seed[1];
	z = r->seed[2];

	x = 171 * (x % 177) - 2 * (x/177);
	y = 172 * (y % 176) - 35 * (y/176);
	z = 170 * (z % 178) - 63 * (z/178);
	
	if (x < 0) x = x + 30269;
	if (y < 0) y = y + 30307;
	if (z < 0) z = z + 30323;
	
	r->seed[0] = x;
	r->seed[1] = y;
	r->seed[2] = z;

	term = (float)(
			(((float)x)/(float)30269.0) + 
			(((float)y)/(float)30307.0) + 
			(((float)z)/(float)30323.0)
			);
	val = term - (float)floor((double)term);

	if (val >= 1.0) val = 0.0;

	return val;
}

static short r_rand(r,s)
PyRotorObject *r;
short s;
{
	/*short tmp = (short)((int)(r_random(r) * (float)32768.0) % 32768);*/
	short tmp = (short)((short)(r_random(r) * (float)s) % s);
	return tmp;
}

static void set_key(r, key)
PyRotorObject *r;
char *key;
{
#ifdef BUGGY_CODE_BW_COMPAT
	/* See comments below */
	int k1=995, k2=576, k3=767, k4=671, k5=463;
#else
	unsigned long k1=995, k2=576, k3=767, k4=671, k5=463;
#endif
	int i;
	int len=strlen(key);
	for (i=0;i<len;i++) {
#ifdef BUGGY_CODE_BW_COMPAT
		/* This is the code as it was originally released.
		   It causes warnings on many systems and can generate
		   different results as well.  If you have files
		   encrypted using an older version you may want to
		   #define BUGGY_CODE_BW_COMPAT so as to be able to
		   decrypt them... */
		k1 = (((k1<<3 | k1<<-13) + key[i]) & 65535);
		k2 = (((k2<<3 | k2<<-13) ^ key[i]) & 65535);
		k3 = (((k3<<3 | k3<<-13) - key[i]) & 65535);
		k4 = ((key[i] - (k4<<3 | k4<<-13)) & 65535);
		k5 = (((k5<<3 | k5<<-13) ^ ~key[i]) & 65535);
#else
		/* This code should be more portable */
		k1 = (((k1<<3 | k1>>13) + key[i]) & 65535);
		k2 = (((k2<<3 | k2>>13) ^ key[i]) & 65535);
		k3 = (((k3<<3 | k3>>13) - key[i]) & 65535);
		k4 = ((key[i] - (k4<<3 | k4>>13)) & 65535);
		k5 = (((k5<<3 | k5>>13) ^ ~key[i]) & 65535);
#endif
	}
	r->key[0] = (short)k1;
	r->key[1] = (short)(k2|1);
	r->key[2] = (short)k3;
	r->key[3] = (short)k4;
	r->key[4] = (short)k5;

	set_seed(r);
}

/* These define the interface to a rotor object */
static PyRotorObject *
PyRotor_New(num_rotors, key)
	int num_rotors;
	char *key;
{
	PyRotorObject *xp;
	xp = PyObject_NEW(PyRotorObject, &PyRotor_Type);
	if (xp == NULL)
		return NULL;
	set_key(xp, key);

	xp->size = 256;
	xp->size_mask = xp->size - 1;
	xp->size_mask = 0;
	xp->rotors = num_rotors;
	xp->e_rotor = NULL;
	xp->d_rotor = NULL;
	xp->positions = NULL;
	xp->advances = NULL;

	xp->e_rotor =
	     (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
	if (xp->e_rotor == (unsigned char *)NULL)
		goto fail;
	xp->d_rotor =
	     (unsigned char *)malloc((num_rotors * (xp->size * sizeof(char))));
	if (xp->d_rotor == (unsigned char *)NULL)
		goto fail;
	xp->positions = (unsigned char *)malloc(num_rotors * sizeof(char));
	if (xp->positions == (unsigned char *)NULL)
		goto fail;
	xp->advances  = (unsigned char *)malloc(num_rotors * sizeof(char));
	if (xp->advances == (unsigned char *)NULL)
		goto fail;
	return xp;
fail:
	Py_DECREF(xp);
	return (PyRotorObject *)PyErr_NoMemory();
}

/* These routines impliment the rotor itself */

/*  Here is a fairly sofisticated {en,de}cryption system.  It is bassed
on the idea of a "rotor" machine.  A bunch of rotors, each with a
different permutation of the alphabet, rotate around a different
amount after encrypting one character.  The current state of the
rotors is used to encrypt one character.

  The code is smart enought to tell if your alphabet has a number of
characters equal to a power of two.  If it does, it uses logical
operations, if not it uses div and mod (both require a division).

  You will need to make two changes to the code 1) convert to c, and
customize for an alphabet of 255 chars 2) add a filter at the
begining, and end, which subtracts one on the way in, and adds one on
the way out.

  You might wish to do some timing studies.  Another viable
alternative is to "byte stuff" the encrypted data of a normal (perhaps
this one) encryption routine.

j'
*/

/*(defun RTR-make-id-rotor (rotor)
  "Set ROTOR to the identity permutation"
  (let ((j 0))
    (while (< j RTR-size)
      (aset rotor j j)
      (setq j (+ 1 j)))
    rotor))*/
static void RTR_make_id_rotor(r, rtr)
	PyRotorObject *r;
	unsigned char *rtr;
{
	register int j;
	register int size = r->size;
	for (j=0;j<size;j++) {
		rtr[j] = (unsigned char)j;
	}
}


/*(defvar RTR-e-rotors 
  (let ((rv (make-vector RTR-number-of-rotors 0))
	(i 0)
	tr)
    (while (< i RTR-number-of-rotors)
      (setq tr (make-vector RTR-size 0))
      (RTR-make-id-rotor tr)
      (aset rv i tr)
      (setq i (+ 1 i)))
    rv)
  "The current set of encryption rotors")*/
static void RTR_e_rotors(r)
	PyRotorObject *r;
{
	int i;
	for (i=0;i<r->rotors;i++) {
		RTR_make_id_rotor(r,&(r->e_rotor[(i*r->size)]));
	}
}

/*(defvar RTR-d-rotors 
  (let ((rv (make-vector RTR-number-of-rotors 0))
	(i 0)
	tr)
    (while (< i RTR-number-of-rotors)
      (setq tr (make-vector RTR-size 0))
      (setq j 0)
      (while (< j RTR-size)
	(aset tr j j)
	(setq j (+ 1 j)))
      (aset rv i tr)
      (setq i (+ 1 i)))
    rv)
  "The current set of decryption rotors")*/
static void RTR_d_rotors(r)
	PyRotorObject *r;
{
	register int i, j;
	for (i=0;i<r->rotors;i++) {
		for (j=0;j<r->size;j++) {
			r->d_rotor[((i*r->size)+j)] = (unsigned char)j;
		}
	}
}

/*(defvar RTR-positions (make-vector RTR-number-of-rotors 1)
  "The positions of the rotors at this time")*/
static void RTR_positions(r)
	PyRotorObject *r;
{
	int i;
	for (i=0;i<r->rotors;i++) {
		r->positions[i] = 1;
	}
}

/*(defvar RTR-advances (make-vector RTR-number-of-rotors 1)
  "The number of positions to advance the rotors at a time")*/
static void RTR_advances(r) 
	PyRotorObject *r;
{
	int i;
	for (i=0;i<r->rotors;i++) {
		r->advances[i] = 1;
	}
}

/*(defun RTR-permute-rotor (e d)
  "Permute the E rotor, and make the D rotor its inverse"
  ;; see Knuth for explaination of algorythm.
  (RTR-make-id-rotor e)
  (let ((i RTR-size)
	q j)
    (while (<= 2 i)
      (setq q (fair16 i))		; a little tricky, decrement here
      (setq i (- i 1))			; since we have origin 0 array's
      (setq j (aref e q))
      (aset e q (aref e i))
      (aset e i j)
      (aset d j i))
    (aset e 0 (aref e 0))		; don't forget e[0] and d[0]
    (aset d (aref e 0) 0)))*/
static void RTR_permute_rotor(r, e, d)
	PyRotorObject *r;
	unsigned char *e;
	unsigned char *d;
{
	short i = r->size;
	short q;
	unsigned char j;
	RTR_make_id_rotor(r,e);
	while (2 <= i) {
		q = r_rand(r,i);
		i--;
		j = e[q];
		e[q] = (unsigned char)e[i];
		e[i] = (unsigned char)j;
		d[j] = (unsigned char)i;
	}
	e[0] = (unsigned char)e[0];
	d[(e[0])] = (unsigned char)0;
}

/*(defun RTR-init (key)
  "Given KEY (a list of 5 16 bit numbers), initialize the rotor machine.
Set the advancement, position, and permutation of the rotors"
  (R16-set-state key)
  (let (i)
    (setq i 0)
    (while (< i RTR-number-of-rotors)
      (aset RTR-positions i (fair16 RTR-size))
      (aset RTR-advances i (+ 1 (* 2 (fair16 (/ RTR-size 2)))))
      (message "Initializing rotor %d..." i)
      (RTR-permute-rotor (aref RTR-e-rotors i) (aref RTR-d-rotors i))
      (setq i (+ 1 i)))))*/
static void RTR_init(r)
	PyRotorObject *r;
{
	int i;
	set_seed(r);
	RTR_positions(r);
	RTR_advances(r);
	RTR_e_rotors(r);
	RTR_d_rotors(r);
	for(i=0;i<r->rotors;i++) {
		r->positions[i] = r_rand(r,r->size);
		r->advances[i] = (1+(2*(r_rand(r,r->size/2))));
		RTR_permute_rotor(r,&(r->e_rotor[(i*r->size)]),&(r->d_rotor[(i*r->size)]));
	}
	r->isinited = TRUE;
}

/*(defun RTR-advance ()
  "Change the RTR-positions vector, using the RTR-advances vector"
  (let ((i 0)
	(temp 0))
    (if RTR-size-mask
	(while (< i RTR-number-of-rotors)
	  (setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
	  (aset RTR-positions i (logand temp RTR-size-mask))
	  (if (and (>= temp RTR-size)
		   (< i (- RTR-number-of-rotors 1))) 
	      (aset RTR-positions (+ i 1)
		    (+ 1 (aref RTR-positions (+ i 1)))))
	  (setq i (+ i 1)))
      (while (< i RTR-number-of-rotors)
	(setq temp (+ (aref RTR-positions i) (aref RTR-advances i)))
	(aset RTR-positions i (% temp RTR-size))
	(if (and (>= temp RTR-size)
		 (< i (- RTR-number-of-rotors 1))) 
	    (aset RTR-positions (+ i 1)
		  (+ 1 (aref RTR-positions (+ i 1)))))
	(setq i (+ i 1))))))*/
static void RTR_advance(r)
	PyRotorObject *r;
{
	register int i=0, temp=0;
	if (r->size_mask) {
		while (i<r->rotors) {
			temp = r->positions[i] + r->advances[i];
			r->positions[i] = temp & r->size_mask;
			if ((temp >= r->size) && (i < (r->rotors - 1))) {
				r->positions[(i+1)] = 1 + r->positions[(i+1)];
			}
			i++;
		}
	} else {
		while (i<r->rotors) {
			temp = r->positions[i] + r->advances[i];
			r->positions[i] = temp%r->size;
			if ((temp >= r->size) && (i < (r->rotors - 1))) {
				r->positions[(i+1)] = 1 + r->positions[(i+1)];
			}
			i++;
		}
	}
}

/*(defun RTR-e-char (p)
  "Encrypt the character P with the current rotor machine"
  (let ((i 0))
    (if RTR-size-mask
	(while (< i RTR-number-of-rotors)
	  (setq p (aref (aref RTR-e-rotors i)
			(logand (logxor (aref RTR-positions i)
					p)
				RTR-size-mask)))
	  (setq i (+ 1 i)))
      (while (< i RTR-number-of-rotors)
	  (setq p (aref (aref RTR-e-rotors i)
			(% (logxor (aref RTR-positions i)
				   p)
			   RTR-size)))
	(setq i (+ 1 i))))
    (RTR-advance)
    p))*/
static unsigned char RTR_e_char(r, p)
	PyRotorObject *r;
	unsigned char p;
{
	register int i=0;
	register unsigned char tp=p;
	if (r->size_mask) {
		while (i < r->rotors) {
			tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) & r->size_mask))];
			i++;
		}
	} else {
		while (i < r->rotors) {
			tp = r->e_rotor[(i*r->size)+(((r->positions[i] ^ tp) % (unsigned int) r->size))];
			i++;
		}
	}
	RTR_advance(r);
	return ((unsigned char)tp);
}

/*(defun RTR-d-char (c)
  "Decrypt the character C with the current rotor machine"
  (let ((i (- RTR-number-of-rotors 1)))
    (if RTR-size-mask
	(while (<= 0 i)
	  (setq c (logand (logxor (aref RTR-positions i)
				  (aref (aref RTR-d-rotors i)
					c))
			  RTR-size-mask))
	  (setq i (- i 1)))
	(while (<= 0 i)
	  (setq c (% (logxor (aref RTR-positions i)
			     (aref (aref RTR-d-rotors i)
				   c))
		     RTR-size))
	  (setq i (- i 1))))
    (RTR-advance)
    c))*/
static unsigned char RTR_d_char(r, c)
	PyRotorObject *r;
	unsigned char c;
{
	register int i=r->rotors - 1;
	register unsigned char tc=c;
	if (r->size_mask) {
		while (0 <= i) {
			tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) & r->size_mask;
			i--;
		}
	} else {
		while (0 <= i) {
			tc = (r->positions[i] ^ r->d_rotor[(i*r->size)+tc]) % (unsigned int) r->size;
			i--;
		}
	}
	RTR_advance(r);
	return(tc);
}

/*(defun RTR-e-region (beg end key)
  "Perform a rotor encryption of the region from BEG to END by KEY"
  (save-excursion
    (let ((tenth (/ (- end beg) 10)))
      (RTR-init key)
      (goto-char beg)
      ;; ### make it stop evry 10% or so to tell us
      (while (< (point) end)
	(let ((fc (following-char)))
	  (insert-char (RTR-e-char fc) 1)
	  (delete-char 1))))))*/
static void RTR_e_region(r, beg, len, doinit)
	PyRotorObject *r;
	unsigned char *beg;
	int len;
	int doinit;
{
	register int i;
	if (doinit || r->isinited == FALSE)
		RTR_init(r);
	for (i=0;i<len;i++) {
		beg[i]=RTR_e_char(r,beg[i]);
	}
}

/*(defun RTR-d-region (beg end key)
  "Perform a rotor decryption of the region from BEG to END by KEY"
  (save-excursion
    (progn
      (RTR-init key)
      (goto-char beg)
      (while (< (point) end)
	(let ((fc (following-char)))
	  (insert-char (RTR-d-char fc) 1)
	  (delete-char 1))))))*/
static void RTR_d_region(r, beg, len, doinit)
	PyRotorObject *r;
	unsigned char *beg;
	int len;
	int doinit;
{
	register int i;
	if (doinit || r->isinited == FALSE)
		RTR_init(r);
	for (i=0;i<len;i++) {
		beg[i]=RTR_d_char(r,beg[i]);
	}
}


/*(defun RTR-key-string-to-ints (key)
  "Convert a string into a list of 4 numbers"
  (let ((k1 995)
	(k2 576)
	(k3 767)
	(k4 671)
	(k5 463)
	(i 0))
    (while (< i (length key))
      (setq k1 (logand (+      (logior (lsh k1 3) (lsh k1 -13)) (aref key i)) 65535))
      (setq k2 (logand (logxor (logior (lsh k2 3) (lsh k2 -13)) (aref key i)) 65535))
      (setq k3 (logand (-      (logior (lsh k3 3) (lsh k3 -13)) (aref key i)) 65535))
      (setq k4 (logand (-      (aref key i) (logior (lsh k4 3) (lsh k4 -13))) 65535))
      (setq k5 (logand (logxor (logior (lsh k5 3) (lsh k5 -13)) (lognot (aref key i))) 65535))
      (setq i (+ i 1)))
    (list k1 (logior 1 k2) k3 k4 k5)))*/
/* This is done in set_key() above */

#if 0
/*(defun encrypt-region (beg end key)
  "Interactivly encrypt the region"
  (interactive "r\nsKey:")
  (RTR-e-region beg end (RTR-key-string-to-ints key)))*/
static void encrypt_region(r, region, len)
	PyRotorObject *r;
	unsigned char *region;
	int len;
{
	RTR_e_region(r,region,len,TRUE);
}

/*(defun decrypt-region (beg end key)
  "Interactivly decrypt the region"
  (interactive "r\nsKey:")
  (RTR-d-region beg end (RTR-key-string-to-ints key)))*/
static void decrypt_region(r, region, len)
	PyRotorObject *r;
	unsigned char *region;
	int len;
{
	RTR_d_region(r,region,len,TRUE);
}
#endif

/* Rotor methods */

static void
PyRotor_Dealloc(xp)
	PyRotorObject *xp;
{
	PyMem_XDEL(xp->e_rotor);
	PyMem_XDEL(xp->d_rotor);
	PyMem_XDEL(xp->positions);
	PyMem_XDEL(xp->advances);
	PyMem_DEL(xp);
}

static PyObject * 
PyRotor_Encrypt(self, args)
	PyRotorObject *self;
	PyObject * args;
{
	char *string = (char *)NULL;
	int len = 0;
	PyObject * rtn = (PyObject * )NULL;
	char *tmp;

	if (!PyArg_Parse(args,"s#",&string, &len))
		return NULL;
	if (!(tmp = (char *)malloc(len+5))) {
		PyErr_NoMemory();
		return NULL;
	}
	memset(tmp,'\0',len+1);
	memcpy(tmp,string,len);
	RTR_e_region(self,(unsigned char *)tmp,len, TRUE);
	rtn = PyString_FromStringAndSize(tmp,len);
	free(tmp);
	return(rtn);
}

static PyObject * 
PyRotor_EncryptMore(self, args)
	PyRotorObject *self;
	PyObject * args;
{
	char *string = (char *)NULL;
	int len = 0;
	PyObject * rtn = (PyObject * )NULL;
	char *tmp;

	if (!PyArg_Parse(args,"s#",&string, &len))
		return NULL;
	if (!(tmp = (char *)malloc(len+5))) {
		PyErr_NoMemory();
		return NULL;
	}
	memset(tmp,'\0',len+1);
	memcpy(tmp,string,len);
	RTR_e_region(self,(unsigned char *)tmp,len, FALSE);
	rtn = PyString_FromStringAndSize(tmp,len);
	free(tmp);
	return(rtn);
}

static PyObject * 
PyRotor_Decrypt(self, args)
	PyRotorObject *self;
	PyObject * args;
{
	char *string = (char *)NULL;
	int len = 0;
	PyObject * rtn = (PyObject * )NULL;
	char *tmp;

	if (!PyArg_Parse(args,"s#",&string, &len))
		return NULL;
	if (!(tmp = (char *)malloc(len+5))) {
		PyErr_NoMemory();
		return NULL;
	}
	memset(tmp,'\0',len+1);
	memcpy(tmp,string,len);
	RTR_d_region(self,(unsigned char *)tmp,len, TRUE);
	rtn = PyString_FromStringAndSize(tmp,len);
	free(tmp);
	return(rtn);
}

static PyObject * 
PyRotor_DecryptMore(self, args)
	PyRotorObject *self;
	PyObject * args;
{
	char *string = (char *)NULL;
	int len = 0;
	PyObject * rtn = (PyObject * )NULL;
	char *tmp;

	if (!PyArg_Parse(args,"s#",&string, &len))
		return NULL;
	if (!(tmp = (char *)malloc(len+5))) {
		PyErr_NoMemory();
		return NULL;
	}
	memset(tmp,'\0',len+1);
	memcpy(tmp,string,len);
	RTR_d_region(self,(unsigned char *)tmp,len, FALSE);
	rtn = PyString_FromStringAndSize(tmp,len);
	free(tmp);
	return(rtn);
}

static PyObject * 
PyRotor_SetKey(self, args)
	PyRotorObject *self;
	PyObject * args;
{
	char *string;

	if (PyArg_Parse(args,"s",&string))
		set_key(self,string);
	Py_INCREF(Py_None);
	return Py_None;
}

static struct PyMethodDef PyRotor_Methods[] = {
	{"encrypt",	(PyCFunction)PyRotor_Encrypt},
	{"encryptmore",	(PyCFunction)PyRotor_EncryptMore},
	{"decrypt",	(PyCFunction)PyRotor_Decrypt},
	{"decryptmore",	(PyCFunction)PyRotor_DecryptMore},
	{"setkey",	(PyCFunction)PyRotor_SetKey},
	{NULL,		NULL}		/* sentinel */
};


/* Return a rotor object's named attribute. */
static PyObject * 
PyRotor_GetAttr(s, name)
	PyRotorObject *s;
	char *name;
{
	return Py_FindMethod(PyRotor_Methods, (PyObject * ) s, name);
}

statichere PyTypeObject PyRotor_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,				/*ob_size*/
	"rotor",			/*tp_name*/
	sizeof(PyRotorObject),		/*tp_size*/
	0,				/*tp_itemsize*/
	/* methods */
	(destructor)PyRotor_Dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)PyRotor_GetAttr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
	0,                              /*tp_hash*/
};


static PyObject * 
PyRotor_Rotor(self, args)
	PyObject * self;
	PyObject * args;
{
	char *string;
	PyRotorObject *r;
	int len;
	int num_rotors;

	if (PyArg_Parse(args,"s#", &string, &len)) {
		num_rotors = 6;
	} else {
		PyErr_Clear();
		if (!PyArg_Parse(args,"(s#i)", &string, &len, &num_rotors))
			return NULL;
	}
	r = PyRotor_New(num_rotors, string);
	return (PyObject * )r;
}

static struct PyMethodDef PyRotor_Rotor_Methods[] = {
	{"newrotor",		(PyCFunction)PyRotor_Rotor},
	{NULL,			NULL}		 /* Sentinel */
};


/* Initialize this module.
   This is called when the first 'import rotor' is done,
   via a table in config.c, if config.c is compiled with USE_ROTOR
   defined. */

void
initrotor()
{
	PyObject * m;

	m = Py_InitModule("rotor", PyRotor_Rotor_Methods);
}
