diff --git a/CHANGES b/CHANGES
index 1cc225f023beea706215b0606c71334e6f7653d7..0cc04030e0b197acd4289ebfb9fd8dbf49421891 100755
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,33 @@
+Asterisk 0.1.9
+ -- Implement IAX quelching
+ -- Allow Caller*ID to be overridden and suggested
+ -- Configure defaults to use IAXTEL
+ -- Allow remote dialplan polling via IAX
+ -- Eliminate ast_longest_extension
+ -- Implement dialplan request/reply
+ -- Let peers have allow/disallow for codecs
+ -- Change allow/deny to permit/deny in IAX
+ -- Allow dialplan entries to match Caller*ID as well
+ -- Added AGI (Asterisk Gateway Interface) scripting interface (app_agi)
+ -- Added chan_zap for zapata telephony kernel interface, removed chan_tor
+ -- Add convenience functions
+ -- Fix race condition in channel hangup
+ -- Fix memory leaks in both asterisk and iax frame allocations
+ -- Add "iax show stats" command and -DTRACE_FRAMES (for frame tracing)
+ -- Add DISA application (Thanks to Jim Dixon)
+ -- Add IAX transfer support
+ -- Add URL and HTML transmission
+ -- Add application for sending images
+ -- Add RedHat RPM spec file and build capability
+ -- Fix GSM WAV file format bug
+ -- Move ignorepat to main dialplan
+ -- Add ability to specificy TOS bits in IAX
+ -- Allow username:password in IAX strings
+ -- Updates to PhoneJack interface
+ -- Allow "servermail" in voicemail.conf to override e-mail in "from" line
+ -- Add 'skip' option to app_playback
+ -- Reject IAX calls on unknown extensions
+ -- Fix version stuff
 Asterisk 0.1.8
  -- Keep track of version information
  -- Add -f to cause Asterisk not to fork
diff --git a/channels/chan_tor.c b/channels/chan_tor.c
deleted file mode 100755
index 65a7791770cfaada86b4a0ea2657c43a64ab562f..0000000000000000000000000000000000000000
--- a/channels/chan_tor.c
+++ /dev/null
@@ -1,3509 +0,0 @@
-/*
- * Asterisk -- A telephony toolkit for Linux.
- *
- * Tormenta T1 Card (via Zapata library) support 
- * 
- * Copyright (C) 1999, Mark Spencer
- *
- * Mark Spencer <markster@linux-support.net>
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License
- */
-
-#include <stdio.h>
-#include <pthread.h>
-#include <string.h>
-#include <asterisk/channel.h>
-#include <asterisk/channel_pvt.h>
-#include <asterisk/config.h>
-#include <asterisk/logger.h>
-#include <asterisk/module.h>
-#include <asterisk/pbx.h>
-#include <asterisk/options.h>
-#include <asterisk/file.h>
-#include <asterisk/ulaw.h>
-#include <asterisk/callerid.h>
-#include <asterisk/cli.h>
-#include <sys/signal.h>
-#include <sys/select.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <linux/tor.h>
-#include <zap.h>
-#include <math.h>
-#include <tonezone.h>
-#ifdef TORMENTA_PRI
-#include <libpri.h>
-#endif
-
-/* 
-   XXX 
-   XXX   We definitely need to lock the private structure in tor_read and such 
-   XXX  
- */
-
-#ifdef TORMENTA_PRI
-static char *desc = "Tormenta (Zapata) Channelized T1/PRI Driver";
-static char *tdesc = "Tormenta T1//PRI Driver";
-#else
-static char *desc = "Tormenta (Zapata) Channelized T1 Driver";
-static char *tdesc = "Tormenta T1 Driver";
-#endif
-static char *type = "Tor";
-static char *config = "tormenta.conf";
-
-#define SIG_EM		0x1
-#define SIG_EMWINK 	0x11
-#define SIG_FEATD	0X21
-#define SIG_FXSLS	0x2
-#define SIG_FXSGS	0x3
-#define SIG_FXSKS	0x4
-#define SIG_FXOLS	0x5
-#define SIG_FXOGS	0x6
-#define SIG_FXOKS	0x7
-#define SIG_PRI		0x8
-
-#define NUM_SPANS 	2
-
-static char context[AST_MAX_EXTENSION] = "default";
-static char callerid[256] = "";
-
-/* Keep certain dial patterns from turning off dialtone */
-#define AST_MAX_DIAL_PAT 32
-
-static char keepdialpat[AST_MAX_DIAL_PAT][10];
-static int dialpats = 0;
-
-static char language[MAX_LANGUAGE] = "";
-
-static int use_callerid = 1;
-
-static int cur_signalling = -1;
-
-static int cur_group = 0;
-
-static int immediate = 0;
-
-static int stripmsd = 0;
-
-static int callwaiting = 0;
-
-static int callwaitingcallerid = 0;
-
-static int hidecallerid = 0;
-
-static int threewaycalling = 0;
-
-static int transfer = 0;
-
-static float rxgain = 0.0;
-
-static float txgain = 0.0;
-
-static int echocancel;
-
-/* Wait up to 16 seconds for first digit (FXO logic) */
-static int firstdigittimeout = 16000;
-
-/* How long to wait for following digits (FXO logic) */
-static int gendigittimeout = 8000;
-
-static int usecnt =0;
-static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
-
-/* Protect the interface list (of tor_pvt's) */
-static pthread_mutex_t iflock = PTHREAD_MUTEX_INITIALIZER;
-
-/* Protect the monitoring thread, so only one process can kill or start it, and not
-   when it's doing something critical. */
-static pthread_mutex_t monlock = PTHREAD_MUTEX_INITIALIZER;
-
-/* This is the thread for the monitor which checks for input on the channels
-   which are not currently in use.  */
-static pthread_t monitor_thread = 0;
-
-static int restart_monitor(void);
-
-static inline int tor_get_event(int fd)
-{
-	/* Avoid the silly tor_getevent which ignores a bunch of events */
-	int j;
-	if (ioctl(fd, TOR_GETEVENT, &j) == -1) return -1;
-	return j;
-}
-
-static inline int tor_wait_event(int fd)
-{
-	/* Avoid the silly tor_waitevent which ignores a bunch of events */
-	int i,j=0;
-	i = TOR_IOMUX_SIGEVENT;
-	if (ioctl(fd, TOR_IOMUX, &i) == -1) return -1;
-	if (ioctl(fd, TOR_GETEVENT, &j) == -1) return -1;
-	return j;
-}
-
-/* Chunk size to read -- we use the same size as the chunks that the zapata library uses.  */   
-#define READ_SIZE 204
-
-#define MASK_AVAIL		(1 << 0)		/* Channel available for PRI use */
-#define MASK_INUSE		(1 << 1)		/* Channel currently in use */
-
-#define CALLWAITING_SILENT_SAMPLES	( (300 * 8) / READ_SIZE) /* 300 ms */
-#define CALLWAITING_REPEAT_SAMPLES	( (10000 * 8) / READ_SIZE) /* 300 ms */
-
-struct tor_pvt;
-
-
-#ifdef TORMENTA_PRI
-struct tor_pri {
-	pthread_t master;			/* Thread of master */
-	pthread_mutex_t lock;		/* Mutex */
-	int nodetype;				/* Node type */
-	int switchtype;				/* Type of switch to emulate */
-	struct pri *pri;
-	int debug;
-	int fd;
-	int up;
-	int offset;
-	int span;
-	int chanmask[24];			/* Channel status */
-	struct tor_pvt *pvt[24];	/* Member channel pvt structs */
-	struct tor_channel *chan[24];	/* Channels on each line */
-};
-
-static struct tor_pri pris[NUM_SPANS];
-
-static int pritype = PRI_CPE;
-
-#if 0
-#define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE)
-#else
-#define DEFAULT_PRI_DEBUG 0
-/*
-#define DEFAULT_PRI_DEBUG (PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q921_DUMP | PRI_DEBUG_Q921_RAW)
-*/
-#endif
-
-static inline int pri_grab(struct tor_pri *pri)
-{
-	int res;
-	/* Grab the lock first */
-    res = ast_pthread_mutex_lock(&pri->lock);
-	if (res)
-		return res;
-	/* Then break the select */
-	pthread_kill(pri->master, SIGURG);
-	return 0;
-}
-
-static inline void pri_rel(struct tor_pri *pri)
-{
-	ast_pthread_mutex_unlock(&pri->lock);
-}
-
-static int switchtype = PRI_SWITCH_NI2;
-
-#endif
-
-static struct tor_pvt {
-	ZAP *z;
-	pthread_mutex_t lock;
-	struct ast_channel *owner;	/* Our owner (if applicable) */
-	struct ast_channel *owners[3];	
-		/* Up to three channels can be associated with this call */
-		
-	int callwaitindex;			/* Call waiting index into owners */	
-	int thirdcallindex;			/* Three-way calling index into owners */
-	int normalindex;			/* "Normal" call index into owners */
-	
-	int sig;					/* Signalling style */
-	float rxgain;
-	float txgain;
-	struct tor_pvt *next;			/* Next channel in list */
-	char context[AST_MAX_EXTENSION];
-	char exten[AST_MAX_EXTENSION];
-	char language[MAX_LANGUAGE];
-	char callerid[AST_MAX_EXTENSION];
-	char callwaitcid[AST_MAX_EXTENSION];
-	char dtmfq[AST_MAX_EXTENSION];
-	struct ast_frame f;
-	short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
-	int group;
-	int immediate;				/* Answer before getting digits? */
-	int channel;				/* Channel Number */
-	int span;					/* Span number */
-	int dialing;
-	int use_callerid;			/* Whether or not to use caller id on this channel */
-	int hidecallerid;
-	int permhidecallerid;		/* Whether to hide our outgoing caller ID or not */
-	int callwaitingrepeat;		/* How many samples to wait before repeating call waiting */
-	unsigned char *cidspill;
-	int cidpos;
-	int cidlen;
-	int stripmsd;
-	int needringing[3];
-	int needanswer[3];
-	int callwaiting;
-	int callwaitcas;
-	int callwaitrings;
-	int echocancel;
-	int permcallwaiting;
-	int callwaitingcallerid;
-	int threewaycalling;
-	int transfer;
-	int cref;					/* Call reference number */
-	DIAL_OPERATION dop;
-	struct tor_confinfo conf;	/* Saved state of conference */
-	struct tor_confinfo conf2;	/* Saved state of alternate conference */
-	int confno;					/* Conference number */
-	ZAP *pseudo;				/* Pseudo channel FD */
-	int pseudochan;				/* Pseudo channel */
-#ifdef TORMENTA_PRI
-	struct tor_pri *pri;
-	q931_call *call;
-#endif	
-} *iflist = NULL;
-
-#define FIRST_PSEUDO 49
-
-#define INTHREEWAY(p) ((p->normalindex > -1) && (p->thirdcallindex > -1) && \
-		(p->owner == p->owners[p->normalindex]))
-
-static int alloc_pseudo(struct tor_pvt *p)
-{
-	int x;
-	ZAP *z;
-	int res;
-	BUFFER_INFO bi;
-	char fn[256];
-	if (p->pseudo || p->pseudochan){
-		ast_log(LOG_WARNING, "Already have a pseudo fd: %d, chan: %d\n",
-			zap_fd(p->pseudo), p->pseudochan);
-		return -1;
-	}
-	for (x=FIRST_PSEUDO;;x++) {
-		snprintf(fn, sizeof(fn), "/dev/tor/%d", x);
-		z = zap_open(fn, 1);
-		if (!z) {
-			if (errno != EBUSY) {
-				ast_log(LOG_WARNING, "Unable to open %s: %s\n", fn, strerror(errno));
-				return -1;
-			}
-		} else {
-			res = ioctl(zap_fd(z), TOR_GET_BUFINFO, &bi);
-			if (!res) {
-				bi.txbufpolicy = POLICY_IMMEDIATE;
-				bi.rxbufpolicy = POLICY_IMMEDIATE;
-				bi.numbufs = 4;
-				res = ioctl(zap_fd(z), TOR_SET_BUFINFO, &bi);
-				if (res < 0) {
-					ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", x);
-				}
-			} else
-				ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", x);
-			p->pseudo = z;
-			p->pseudochan = x;
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Allocated pseudo channel %d on FD %d\n", p->pseudochan, zap_fd(p->pseudo));
-			return 0;
-		}
-	}
-	/* Never reached */
-	return 0;
-}
-
-static int unalloc_pseudo(struct tor_pvt *p)
-{
-	if (p->pseudo)
-		zap_close(p->pseudo);
-	if (option_debug)
-		ast_log(LOG_DEBUG, "Released pseudo channel %d\n", p->pseudochan);
-	p->pseudo = NULL;
-	p->pseudochan = 0;
-	return 0;
-}
-
-static int tor_digit(struct ast_channel *ast, char digit)
-{
-	DIAL_OPERATION zo;
-	struct tor_pvt *p;
-	int res;
-	zo.op = TOR_DIAL_OP_APPEND;
-	zo.dialstr[0] = 'T';
-	zo.dialstr[1] = digit;
-	zo.dialstr[2] = 0;
-	p = ast->pvt->pvt;
-	if ((res = ioctl(zap_fd(p->z), TOR_DIAL, &zo)))
-		ast_log(LOG_WARNING, "Couldn't dial digit %c\n", digit);
-	else
-		p->dialing = 1;
-	
-	return res;
-}
-
-static char *events[] = {
-        "No event",
-        "On hook",
-        "Ring/Answered",
-        "Wink/Flash",
-        "Alarm",
-        "No more alarm",
-		"HDLC Abort",
-		"HDLC Overrun",
-		"HDLC Bad FCS",
-		"Dial Complete",
-		"Ringer On",
-		"Ringer Off",
-		"Hook Transition Complete"
-};
- 
-static char *event2str(int event)
-{
-        static char buf[256];
-        if ((event < 13) && (event > -1))
-                return events[event];
-        sprintf(buf, "Event %d", event);
-        return buf;
-}
-
-static char *sig2str(int sig)
-{
-	static char buf[256];
-	switch(sig) {
-	case SIG_EM:
-		return "E & M Immediate";
-	case SIG_EMWINK:
-		return "E & M Wink";
-	case SIG_FEATD:
-		return "Feature Group D";
-	case SIG_FXSLS:
-		return "FXS Loopstart";
-	case SIG_FXSGS:
-		return "FXS Groundstart";
-	case SIG_FXSKS:
-		return "FXS Kewlstart";
-	case SIG_FXOLS:
-		return "FXO Loopstart";
-	case SIG_FXOGS:
-		return "FXO Groundstart";
-	case SIG_FXOKS:
-		return "FXO Kewlstart";
-	case SIG_PRI:
-		return "PRI Signalling";
-	default:
-		snprintf(buf, sizeof(buf), "Unknown signalling %d\n", sig);
-		return buf;
-	}
-}
-
-static int conf_set(struct tor_pvt *p, int req, int force)
-{
-	/* Set channel to given conference, -1 to allocate one */
-	TOR_CONFINFO ci;
-	TOR_CONFINFO cip;
-	int res;
-	if ((p->confno > -1) && (p->confno != req) && (!force)) {
-		ast_log(LOG_WARNING, "Channel %d already has conference %d allocated\n", p->channel, p->confno);
-		return -1;
-	}
-	ci.chan = 0;
-	ci.confno = 0;
-	/* Check current conference stuff */
-	res = ioctl(zap_fd(p->z), TOR_GETCONF, &ci);
-	if (res < 0) {
-		ast_log(LOG_WARNING, "Failed to get conference info on channel %d: %s\n",
-			p->channel, strerror(errno));
-		return -1;
-	}
-	if (!force && ci.confmode && (ci.confno != p->confno)) {
-		ast_log(LOG_WARNING, "Channel %d is already in a conference (%d, %d) we didn't create (req = %d)\n", p->channel, ci.confno, ci.confmode, req);
-		return -1;
-	}
-	ci.chan = 0;
-	ci.confno = req;
-	ci.confmode = TOR_CONF_REALANDPSEUDO | TOR_CONF_TALKER | TOR_CONF_LISTENER | TOR_CONF_PSEUDO_LISTENER | TOR_CONF_PSEUDO_TALKER;
-	res = ioctl(zap_fd(p->z), TOR_SETCONF, &ci);
-	if (res < 0) {
-		ast_log(LOG_WARNING, "Failed to set conference to %d on channel %d: %s\n",
-			req, p->channel, strerror(errno));
-		return -1;
-	}
-	if (INTHREEWAY(p)) {
-			/* We have a three way call active, be sure the third participant is included in
-			   our conference. */
-		cip.chan = 0;
-		cip.confno = ci.confno;
-		cip.confmode = TOR_CONF_CONF | TOR_CONF_TALKER | TOR_CONF_LISTENER;
-		
-		res = ioctl(zap_fd(p->pseudo), TOR_SETCONF, &cip);
-		if (res < 0) {
-			ast_log(LOG_WARNING, "Failed to set conference info on pseudo channel %d: %s\n",
-				p->pseudochan, strerror(errno));
-			return -1;
-		}
-		ast_log(LOG_DEBUG, "Conferenced in third way call\n");
-	} else {
-		if (p->pseudo || (p->pseudochan)) {
-			ast_log(LOG_DEBUG, "There's a pseudo something on %d (channel %d), but we're not conferencing it in at the moment?\n",
-				zap_fd(p->pseudo), p->pseudochan);
-			cip.chan = 0;
-			cip.confno = ci.confno;
-			cip.confmode = TOR_CONF_NORMAL;
-			res = ioctl(zap_fd(p->pseudo), TOR_SETCONF, &cip);
-			if (res < 0) {
-				ast_log(LOG_WARNING, "Failed to set conference info on pseudo channel %d: %s\n",
-					p->pseudochan, strerror(errno));
-				return -1;
-			}
-		}
-	}
-	p->confno = ci.confno;
-	return 0;
-}
-
-static int three_way(struct tor_pvt *p)
-{
-	ast_log(LOG_DEBUG, "Setting up three way call\n");
-	return conf_set(p, p->confno, 0);
-}
-
-static int conf_clear(struct tor_pvt *p)
-{
-	TOR_CONFINFO ci;
-	int res;
-	ci.confmode = TOR_CONF_NORMAL;
-	ci.chan = 0;
-	ci.confno = 0;
-	res = ioctl(zap_fd(p->z), TOR_SETCONF, &ci);
-	if (res < 0) {
-		ast_log(LOG_WARNING, "Failed to clear conference info on channel %d: %s\n",
-			p->channel, strerror(errno));
-		return -1;
-	}
-	p->confno = -1;
-	return 0;
-}
-
-static void tor_enable_ec(struct tor_pvt *p)
-{
-	int x;
-	int res;
-	if (p->echocancel) {
-		x = 1;
-		res = ioctl(zap_fd(p->z), TOR_ECHOCANCEL, &x);
-		if (res) 
-			ast_log(LOG_WARNING, "Unable to enable echo cancellation on channel %d\n", p->channel);
-		else
-			ast_log(LOG_DEBUG, "Enabled echo cancellation on channel %d\n", p->channel);
-	}
-}
-
-static void tor_disable_ec(struct tor_pvt *p)
-{
-	int x;
-	int res;
-	if (p->echocancel) {
-		x = 0;
-		res = ioctl(zap_fd(p->z), TOR_ECHOCANCEL, &x);
-		if (res) 
-			ast_log(LOG_WARNING, "Unable to disable echo cancellation on channel %d\n", p->channel);
-		else
-			ast_log(LOG_DEBUG, "disabled echo cancellation on channel %d\n", p->channel);
-	}
-}
-
-static int tor_get_index(struct ast_channel *ast, struct tor_pvt *p, int nullok)
-{
-	int res;
-	if (p->owners[0] == ast)
-		res = 0;
-	else if (p->owners[1] == ast)
-		res = 1;
-	else if (p->owners[2] == ast)
-		res = 2;
-	else {
-		res = -1;
-		if (!nullok)
-			ast_log(LOG_WARNING, "Unable to get index, and nullok is not asserted\n");
-	}
-	return res;
-}
-
-static int set_actual_gain(int fd, int chan, float rxgain, float txgain)
-{
-	struct	tor_gains g;
-	float ltxgain;
-	float lrxgain;
-	int j,k;
-	g.chan = chan;
-	  /* caluculate linear value of tx gain */
-	ltxgain = pow(10.0,txgain / 20.0);
-	  /* caluculate linear value of rx gain */
-	lrxgain = pow(10.0,rxgain / 20.0);
-	for (j=0;j<256;j++) {
-		k = (int)(((float)ast_mulaw[j]) * lrxgain);
-		if (k > 32767) k = 32767;
-		if (k < -32767) k = -32767;
-		g.rxgain[j] = ast_lin2mu[k + 32768];
-		k = (int)(((float)ast_mulaw[j]) * ltxgain);
-		if (k > 32767) k = 32767;
-		if (k < -32767) k = -32767;
-		g.txgain[j] = ast_lin2mu[k + 32768];
-	}
-		
-	  /* set 'em */
-	return(ioctl(fd,TOR_SETGAINS,&g));
-}
-
-static inline int tor_set_hook(int fd, int hs)
-{
-	int x, res;
-	x = hs;
-	res = ioctl(fd, TOR_HOOK, &x);
-	if (res < 0) 
-		ast_log(LOG_WARNING, "tor hook failed: %s\n", strerror(errno));
-	return res;
-}
-
-static int save_conference(struct tor_pvt *p)
-{
-	struct tor_confinfo c;
-	int res;
-	if (p->conf.confmode) {
-		ast_log(LOG_WARNING, "Can't save conference -- already in use\n");
-		return -1;
-	}
-	p->conf.chan = 0;
-	res = ioctl(zap_fd(p->z), TOR_GETCONF, &p->conf);
-	if (res) {
-		ast_log(LOG_WARNING, "Unable to get conference info: %s\n", strerror(errno));
-		p->conf.confmode = 0;
-		return -1;
-	}
-	c.chan = 0;
-	c.confno = 0;
-	c.confmode = TOR_CONF_NORMAL;
-	res = ioctl(zap_fd(p->z), TOR_SETCONF, &c);
-	if (res) {
-		ast_log(LOG_WARNING, "Unable to set conference info: %s\n", strerror(errno));
-		return -1;
-	}
-	switch(p->conf.confmode) {
-	case TOR_CONF_NORMAL:
-		p->conf2.confmode = 0;
-		break;
-	case TOR_CONF_MONITOR:
-		/* Get the other size */
-		p->conf2.chan = p->conf.confno;
-		res = ioctl(zap_fd(p->z), TOR_GETCONF, &p->conf2);
-		if (res) {
-			ast_log(LOG_WARNING, "Unable to get secondaryconference info: %s\n", strerror(errno));
-			p->conf2.confmode = 0;
-			return -1;
-		}
-		c.chan = p->conf.confno;
-		c.confno = 0;
-		c.confmode = TOR_CONF_NORMAL;
-		res = ioctl(zap_fd(p->z), TOR_SETCONF, &c);
-		if (res) {
-			ast_log(LOG_WARNING, "Unable to set secondaryconference info: %s\n", strerror(errno));
-			p->conf2.confmode = 0;
-			return -1;
-		}
-		break;
-	case TOR_CONF_CONF | TOR_CONF_LISTENER | TOR_CONF_TALKER:
-		p->conf2.confmode = 0;
-		break;
-	default:
-		ast_log(LOG_WARNING, "Don't know how to save conference state for conf mode %d\n", p->conf.confmode);
-		return -1;
-	}
-	if (option_debug)
-		ast_log(LOG_DEBUG, "Disabled conferencing\n");
-	return 0;
-}
-
-static int restore_conference(struct tor_pvt *p)
-{
-	int res;
-	if (p->conf.confmode) {
-		res = ioctl(zap_fd(p->z), TOR_SETCONF, &p->conf);
-		p->conf.confmode = 0;
-		if (res) {
-			ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
-			return -1;
-		}
-		if (p->conf2.confmode) {
-			res = ioctl(zap_fd(p->z), TOR_SETCONF, &p->conf2);
-			p->conf2.confmode = 0;
-			if (res) {
-				ast_log(LOG_WARNING, "Unable to restore conference info: %s\n", strerror(errno));
-				return -1;
-			}
-		}
-	}
-	if (option_debug)
-		ast_log(LOG_DEBUG, "Restored conferencing\n");
-	return 0;
-}
-
-static int send_callerid(struct tor_pvt *p);
-
-int send_cwcidspill(struct tor_pvt *p)
-{
-	p->callwaitcas = 0;
-	p->cidspill = malloc(MAX_CALLERID_SIZE);
-	if (p->cidspill) {
-		memset(p->cidspill, 0x7f, MAX_CALLERID_SIZE);
-		p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwaitcid);
-		/* Make sure we account for the end */
-		p->cidlen += READ_SIZE * 4;
-		p->cidpos = 0;
-		send_callerid(p);
-		if (option_verbose > 2)
-			ast_verbose(VERBOSE_PREFIX_3 "CPE supports Call Waiting Caller*ID.  Sending '%s'\n", p->callwaitcid);
-	} else return -1;
-	return 0;
-}
-
-static int send_callerid(struct tor_pvt *p)
-{
-	/* Assumes spill in p->cidspill, p->cidlen in length and we're p->cidpos into it */
-	int res;
-	while(p->cidpos < p->cidlen) {
-		res = write(zap_fd(p->z), p->cidspill + p->cidpos, p->cidlen - p->cidpos);
-		if (res < 0) {
-			if (errno == EAGAIN)
-				return 0;
-			else {
-				ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
-				return -1;
-			}
-		}
-		if (!res)
-			return 0;
-		p->cidpos += res;
-	}
-	free(p->cidspill);
-	p->cidspill = 0;
-	if (p->callwaitcas) {
-		zap_clrdtmfn(p->z);
-		/* Check for a the ack on the CAS */
-		res = zap_getdtmf(p->z, 1, NULL, 0, 250, 250, ZAP_HOOKEXIT | ZAP_TIMEOUTOK);
-		if (res > 0) {
-			char tmp[2];
-			strncpy(tmp, zap_dtmfbuf(p->z), sizeof(tmp));
-			zap_clrdtmfn(p->z);
-			if ((tmp[0] == 'A') || (tmp[0] == 'D')) {
-				send_cwcidspill(p);
-			}
-		} else {
-			if (option_verbose > 2)
-				ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
-			restore_conference(p);
-		}
-	} else
-		restore_conference(p);
-	return 0;
-}
-
-static int tor_callwait(struct ast_channel *ast)
-{
-	struct tor_pvt *p = ast->pvt->pvt;
-	p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
-	if (p->cidspill) {
-		ast_log(LOG_WARNING, "Spill already exists?!?\n");
-		free(p->cidspill);
-	}
-	p->cidspill = malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4);
-	if (p->cidspill) {
-		save_conference(p);
-		/* Silence */
-		memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
-		if (!p->callwaitrings && p->callwaitingcallerid) {
-			ast_callerid_gen_cas(p->cidspill, 2400 + 680);
-			p->callwaitcas = 1;
-			p->cidlen = 2400 + 680 + READ_SIZE * 4;
-		} else {
-			ast_callerid_gen_cas(p->cidspill, 2400);
-			p->callwaitcas = 0;
-			p->cidlen = 2400 + READ_SIZE * 4;
-		}
-		p->cidpos = 0;
-		send_callerid(p);
-	} else {
-		ast_log(LOG_WARNING, "Unable to create SAS/CAS spill\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int tor_call(struct ast_channel *ast, char *dest, int timeout)
-{
-	struct tor_pvt *p = ast->pvt->pvt;
-	int x, res, index;
-	char *c, *n, *l;
-	char callerid[256];
-	if ((ast->state != AST_STATE_DOWN) && (ast->state != AST_STATE_RESERVED)) {
-		ast_log(LOG_WARNING, "tor_call called on %s, neither down nor reserved\n", ast->name);
-		return -1;
-	}
-	switch(p->sig) {
-	case SIG_FXOLS:
-	case SIG_FXOGS:
-	case SIG_FXOKS:
-		if (p->owner == ast) {
-			/* Normal ring, on hook */
-			if (p->use_callerid) {
-				/* Generate the Caller-ID spill if desired */
-				if (p->cidspill) {
-					ast_log(LOG_WARNING, "cidspill already exists??\n");
-					free(p->cidspill);
-				}
-				p->cidspill = malloc(MAX_CALLERID_SIZE);
-				p->callwaitcas = 0;
-				if (p->cidspill) {
-					p->cidlen = ast_callerid_generate(p->cidspill, ast->callerid);
-					p->cidpos = 0;
-					send_callerid(p);
-				} else
-					ast_log(LOG_WARNING, "Unable to generate CallerID spill\n");
-			}
-			x = TOR_RING;
-			if (ioctl(zap_fd(p->z), TOR_HOOK, &x) && (errno != EINPROGRESS)) {
-				ast_log(LOG_WARNING, "Unable to ring phone: %s\n", strerror(errno));
-				return -1;
-			}
-			p->dialing = 1;
-		} else {
-			/* Call waiting call */
-			p->callwaitrings = 0;
-			if (ast->callerid)
-				strncpy(p->callwaitcid, ast->callerid, sizeof(p->callwaitcid));
-			else
-				strcpy(p->callwaitcid, "");
-			/* Call waiting tone instead */
-			if (tor_callwait(ast))
-				return -1;
-				
-		}
-		ast->state = AST_STATE_RINGING;
-		index = tor_get_index(ast, p, 0);
-		if (index > -1) {
-			p->needringing[index] = 1;
-		}
-		break;
-	case SIG_FXSLS:
-	case SIG_FXSGS:
-	case SIG_FXSKS:
-	case SIG_EMWINK:
-	case SIG_EM:
-	case SIG_FEATD:
-		c = strchr(dest, '/');
-		if (c)
-			c++;
-		else
-			c = dest;
-		if (strlen(c) < p->stripmsd) {
-			ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
-			return -1;
-		}
-		x = TOR_START;
-		/* Start the trunk */
-		res = ioctl(zap_fd(p->z), TOR_HOOK, &x);
-		if (res < 0) {
-			if (errno != EINPROGRESS) {
-				ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno));
-				return -1;
-			}
-		}
-		ast_log(LOG_DEBUG, "Dialing '%s'\n", c);
-		p->dop.op = TOR_DIAL_OP_REPLACE;
-		if (p->sig == SIG_FEATD) {
-			if (ast->callerid) {
-				strncpy(callerid, ast->callerid, sizeof(callerid));
-				ast_callerid_parse(callerid, &n, &l);
-				if (l) {
-					ast_shrink_phone_number(l);
-					if (!ast_isphonenumber(l))
-						l = NULL;
-				}
-			} else
-				l = NULL;
-			if (l) 
-				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T*%s*%s*", l, c + p->stripmsd);
-			else
-				snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T**%s*", c + p->stripmsd);
-		} else 
-			snprintf(p->dop.dialstr, sizeof(p->dop.dialstr), "T%s", c + p->stripmsd);
-		if (!res) {
-			if (ioctl(zap_fd(p->z), TOR_DIAL, &p->dop)) {
-				x = TOR_ONHOOK;
-				ioctl(zap_fd(p->z), TOR_HOOK, &x);
-				ast_log(LOG_WARNING, "Dialing failed on channel %d: %s\n", p->channel, strerror(errno));
-				return -1;
-			}
-		} else
-			ast_log(LOG_DEBUG, "Deferring dialing...\n");
-		p->dialing = 1;
-		ast->state = AST_STATE_DIALING;
-		break;
-#ifdef TORMENTA_PRI
-	case SIG_PRI:
-		c = strchr(dest, '/');
-		if (c)
-			c++;
-		else
-			c = dest;
-		if (ast->callerid) {
-			strncpy(callerid, ast->callerid, sizeof(callerid));
-			ast_callerid_parse(callerid, &n, &l);
-			if (l) {
-				ast_shrink_phone_number(l);
-				if (!ast_isphonenumber(l))
-					l = NULL;
-			}
-		} else
-			l = NULL;
-		if (strlen(c) < p->stripmsd) {
-			ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
-			return -1;
-		}
-		if (pri_call(p->pri->pri, p->call, PRI_TRANS_CAP_SPEECH, 
-			((p->channel - 1) % 24) + 1, p->pri->nodetype == PRI_NETWORK ? 0 : 1, 1, l, PRI_NATIONAL_ISDN, 
-			l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE,
-			c + p->stripmsd, PRI_NATIONAL_ISDN)) {
-			ast_log(LOG_WARNING, "Unable to setup call to %s\n", c + p->stripmsd);
-			return -1;
-		}
-		break;
-#endif				
-	default:
-		ast_log(LOG_DEBUG, "not yet implemented\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int tor_hangup(struct ast_channel *ast)
-{
-	int res;
-	int index;
-	struct tor_pvt *p = ast->pvt->pvt;
-	TOR_PARAMS par;
-	if (option_debug)
-		ast_log(LOG_DEBUG, "tor_hangup(%s)\n", ast->name);
-	if (!ast->pvt->pvt) {
-		ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
-		return 0;
-	}
-	index = tor_get_index(ast, p, 1);
-
-	zap_digitmode(p->z,0);
-	ast->state = AST_STATE_DOWN;
-	ast_log(LOG_DEBUG, "Hangup: index = %d, normal = %d, callwait = %d, thirdcall = %d\n",
-		index, p->normalindex, p->callwaitindex, p->thirdcallindex);
-	
-	if (index > -1) {
-		/* Real channel, do some fixup */
-		p->owners[index] = NULL;
-		p->needanswer[index] = 0;
-		p->needringing[index] = 0;
-		if (index == p->normalindex) {
-			p->normalindex = -1;
-			if ((p->callwaitindex > -1) && (p->thirdcallindex > -1)) 
-				ast_log(LOG_WARNING, "Normal call hung up with both three way call and a call waiting call in place?\n");
-			if (p->callwaitindex > -1) {
-				/* If we hung up the normal call, make the call wait call
-				   be the normal call if there was one */
-				p->normalindex = p->callwaitindex;
-				p->callwaitindex = -1;
-			} else if (p->thirdcallindex > -1) {
-				/* This was part of a three way call */
-				p->normalindex = p->thirdcallindex;
-				p->owners[p->normalindex]->fds[0] = zap_fd(p->z);
-				p->thirdcallindex = -1;
-				unalloc_pseudo(p);
-			}
-		} else if (index == p->callwaitindex) {
-			/* If this was a call waiting call, mark the call wait
-			   index as -1, so we know it's available again */
-			p->callwaitindex = -1;
-		} else if (index == p->thirdcallindex) {
-			/* If this was part of a three way call index, let us make
-			   another three way call */
-			p->thirdcallindex = -1;
-			unalloc_pseudo(p);
-		} else {
-			/* This wasn't any sort of call, but how are we an index? */
-			ast_log(LOG_WARNING, "Index found but not any type of call?\n");
-		}
-	}
-
-	if (!p->owners[0] && !p->owners[1] && !p->owners[2]) {
-		p->owner = NULL;
-		/* Perform low level hangup if no owner left */
-#ifdef TORMENTA_PRI
-		if (p->sig == SIG_PRI) {
-			if (p->call) {
-				if (!pri_grab(p->pri)) {
-					res = pri_disconnect(p->pri->pri, p->call, PRI_CAUSE_NORMAL_CLEARING);
-					p->call = NULL;
-					if (res < 0) 
-						ast_log(LOG_WARNING, "pri_disconnect failed\n");
-					pri_rel(p->pri);			
-				} else {
-					ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
-					res = -1;
-				}
-			} else
-				res = 0;
-		} else
-#endif
-			res = tor_set_hook(zap_fd(p->z), TOR_ONHOOK);
-		if (res < 0) {
-			ast_log(LOG_WARNING, "Unable to hangup line %s\n", ast->name);
-			return -1;
-		}
-		switch(p->sig) {
-		case SIG_FXOGS:
-		case SIG_FXOLS:
-		case SIG_FXOKS:
-			res = ioctl(zap_fd(p->z), TOR_GET_PARAMS, &par);
-			if (!res) {
-#if 0
-				ast_log(LOG_DEBUG, "Hanging up channel %d, offhook = %d\n", p->channel, par.rxisoffhook);
-#endif
-				/* If they're off hook, try playing congestion */
-				if (par.rxisoffhook)
-					tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-				else
-					tone_zone_play_tone(zap_fd(p->z), -1);
-			}
-			break;
-		default:
-		}
-		if (index > -1) {
-			p->needringing[index] = 0;
-			p->needanswer[index] = 0;
-		}
-		if (p->cidspill)
-			free(p->cidspill);
-		tor_disable_ec(p);
-		p->cidspill = NULL;
-		p->callwaitcas = 0;
-		p->callwaiting = p->permcallwaiting;
-		p->hidecallerid = p->permhidecallerid;
-		p->dialing = 0;
-		conf_clear(p);
-		unalloc_pseudo(p);
-		restart_monitor();
-	}
-	p->callwaitingrepeat = 0;
-	ast->pvt->pvt = NULL;
-	ast->state = AST_STATE_DOWN;
-	ast_pthread_mutex_lock(&usecnt_lock);
-	usecnt--;
-	if (usecnt < 0) 
-		ast_log(LOG_WARNING, "Usecnt < 0???\n");
-	ast_pthread_mutex_unlock(&usecnt_lock);
-	ast_update_use_count();
-	if (option_verbose > 2) 
-		ast_verbose( VERBOSE_PREFIX_3 "Hungup '%s'\n", ast->name);
-	return 0;
-}
-
-static int tor_answer(struct ast_channel *ast)
-{
-	struct tor_pvt *p = ast->pvt->pvt;
-	int res=0;
-	ast->state = AST_STATE_UP;
-	switch(p->sig) {
-	case SIG_FXSLS:
-	case SIG_FXSGS:
-	case SIG_FXSKS:
-	case SIG_EM:
-	case SIG_EMWINK:
-	case SIG_FEATD:
-	case SIG_FXOLS:
-	case SIG_FXOGS:
-	case SIG_FXOKS:
-		/* Pick up the line */
-		ast_log(LOG_DEBUG, "Took %s off hook\n", ast->name);
-		res =  tor_set_hook(zap_fd(p->z), TOR_OFFHOOK);
-		tone_zone_play_tone(zap_fd(p->z), -1);
-		if (INTHREEWAY(p))
-			tone_zone_play_tone(zap_fd(p->pseudo), -1);
-		p->dialing = 0;
-		break;
-#ifdef TORMENTA_PRI
-	case SIG_PRI:
-		/* Send a pri acknowledge */
-		if (!pri_grab(p->pri)) {
-			res = pri_answer(p->pri->pri, p->call, 0, 1);
-			pri_rel(p->pri);
-		} else {
-			ast_log(LOG_WARNING, "Unable to grab PRI on span %d\n", p->span);
-			res= -1;
-		}
-		break;
-#endif		
-	default:
-		ast_log(LOG_WARNING, "Don't know how to answer signalling %d (channel %d)\n", p->sig, p->channel);
-		return -1;
-	}
-	return res;
-}
-
-static inline int bridge_cleanup(struct tor_pvt *p0, struct tor_pvt *p1)
-{
-	int res;
-	res = conf_clear(p0);
-	res |= conf_clear(p1);
-	return res;
-}
-
-static int tor_setoption(struct ast_channel *chan, int option, void *data, int datalen)
-{
-char	*cp;
-
-	struct tor_pvt *p = chan->pvt->pvt;
-
-	ast_log(LOG_DEBUG, "Set option %d, data %p, len %d\n", option, data, datalen);
-	if (option != AST_OPTION_TONE_VERIFY) 
-	   {
-		errno = ENOSYS;
-		return -1;
-	   }
-	cp = (char *)data;
-	if ((!cp) || (datalen < 1))
-	   {
-		errno = EINVAL;
-		return -1;
-	   }
-	zap_digitmode(p->z,((*cp) ? ZAP_MUTECONF : 0));  /* set mute mode if desired */
-	errno = 0;
-	return 0;
-}
-
-static int tor_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
-{
-	/* Do a quickie conference between the two channels and wait for something to happen */
-	struct tor_pvt *p0 = c0->pvt->pvt;
-	struct tor_pvt *p1 = c1->pvt->pvt;
-	struct ast_channel *who, *cs[3];
-	struct ast_frame *f;
-	int to = -1;
-	
-	int confno = -1;
-	
-	/* Stop any playing tones */
-	tone_zone_play_tone(zap_fd(p0->z), 	-1);
-
-	tone_zone_play_tone(zap_fd(p1->z), 	-1);
-
-	cs[0] = c0;
-	cs[1] = c1;
-	for (;;) {
-		pthread_mutex_lock(&c0->lock);
-		pthread_mutex_lock(&c1->lock);
-		p0 = c0->pvt->pvt;
-		p1 = c1->pvt->pvt;
-
-		if (!p0 || !p1) {
-			pthread_mutex_unlock(&c0->lock);
-			pthread_mutex_unlock(&c1->lock);
-			return -1;
-		}
-
-		if (INTHREEWAY(p0) && (c0 == p0->owners[p0->thirdcallindex]))
-			tone_zone_play_tone(zap_fd(p0->pseudo), -1);
-		if (INTHREEWAY(p1) && (c1 == p1->owners[p1->thirdcallindex]))
-			tone_zone_play_tone(zap_fd(p1->pseudo), -1);
-		if (INTHREEWAY(p0) && (INTHREEWAY(p1))) {
-			ast_log(LOG_WARNING, "Too weird, can't bridge multiple three way calls\n");
-			pthread_mutex_unlock(&c0->lock);
-			pthread_mutex_unlock(&c1->lock);
-			return -1;
-		}
-		if ((p0->owner == c0) && (p1->owner == c1)) {
-			/* Okay, this call should actually be connected */
-			if ((p0->confno > -1) && (p1->confno > -1) && (p0->confno != p1->confno)) {
-				/* We have a conflict here.  Try to resolve it. */
-				if ((INTHREEWAY(p0) && (c0 == p0->owners[p0->normalindex]))) {
-					ast_log(LOG_DEBUG, "Channel %s is in a three way call with us, moving to our conference %d\n",
-						c1->name, p0->confno);
-					conf_set(p1, p0->confno, 1);
-				} else if (INTHREEWAY(p1) && (c1 == p1->owners[p1->normalindex])) {
-						ast_log(LOG_DEBUG, "Channel %s is in a three way call with us, moving to our conference %d\n",
-							c0->name, p1->confno);
-						conf_set(p0, p1->confno, 1);
-				} else {
-					ast_log(LOG_WARNING, "Can't bridge since %s is on conf %d and %s is on conf %d\n",
-						c0->name, p0->confno, c1->name, p1->confno);
-					pthread_mutex_unlock(&c0->lock);
-					pthread_mutex_unlock(&c1->lock);
-					return -1;
-				}
-			}
-			if (p0->confno > -1)
-				confno = p0->confno;
-			else
-				confno = p1->confno;
-			if (confno < 0) {
-				conf_set(p0, -1, 0);
-				confno = p0->confno;
-				ast_log(LOG_DEBUG, "Creating new conference %d for %s\n", confno, c0->name);
-			}
-			if (p0->confno != confno) {
-				ast_log(LOG_DEBUG, "Placing %s in conference %d\n", c0->name, confno);
-				conf_set(p0, confno, 0);
-			}
-			if (p1->confno != confno) {
-				ast_log(LOG_DEBUG, "Placing %s in conference %d\n", c1->name, confno);
-				conf_set(p1, confno, 0);
-			}
-		} else if (INTHREEWAY(p0) && (c0 == p0->owners[p0->thirdcallindex])) {
-			/* p0 is in a three way call and we're the third leg.  Join their
-			   conference, already in progress if there is one */
-			if ((p0->confno > -1) && (p1->confno != p0->confno)) {
-				confno = p0->confno;
-				ast_log(LOG_DEBUG, "Placing %s in conference %d\n", c1->name, confno);
-				conf_set(p1, confno, 0);
-			}
-		} else if (INTHREEWAY(p1) && (c1 == p1->owners[p1->thirdcallindex])) {
-			/* p0 is in a three way call and we're the third leg.  Join their
-			   conference, already in progress if there is one */
-			if ((p1->confno > -1) && (p1->confno != p0->confno)) {
-				confno = p0->confno;
-				ast_log(LOG_DEBUG, "Placing %s in conference %d\n", c0->name, confno);
-				conf_set(p0, confno, 0);
-			}
-		}
-		pthread_mutex_unlock(&c0->lock);
-		pthread_mutex_unlock(&c1->lock);
-		
-		who = ast_waitfor_n(cs, 2, &to);
-		if (!who) {
-			ast_log(LOG_WARNING, "Nobody there??\n");
-			continue;
-		}
-		f = ast_read(who);
-		if (!f) {
-			*fo = NULL;
-			*rc = who;
-			bridge_cleanup(p0, p1);
-			return 0;
-		}
-		if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
-			*fo = f;
-			*rc = who;
-			bridge_cleanup(p0, p1);
-			return 0;
-		}
-		if ((f->frametype == AST_FRAME_VOICE) ||
-			(f->frametype == AST_FRAME_TEXT) ||
-			(f->frametype == AST_FRAME_VIDEO) || 
-			(f->frametype == AST_FRAME_IMAGE) ||
-			(f->frametype == AST_FRAME_DTMF)) {
-			if ((f->frametype == AST_FRAME_DTMF) && (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
-				if ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) {
-					*rc = c0;
-					*fo = f;
-					bridge_cleanup(p0, p1);
-					return 0;
-				} else
-				if ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)) {
-					*rc = c1;
-					*fo = f;
-					bridge_cleanup(p0, p1);
-					return 0;
-				}
-			}
-			ast_frfree(f);
-		} else
-			ast_frfree(f);
-		/* Swap who gets priority */
-		cs[2] = cs[0];
-		cs[0] = cs[1];
-		cs[1] = cs[2];
-	}
-	return 0;
-}
-
-static int tor_indicate(struct ast_channel *chan, int condition);
-
-static int tor_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
-{
-	struct tor_pvt *p = newchan->pvt->pvt;
-	int x;
-	ast_log(LOG_DEBUG, "New owner for channel %d is %s\n", p->channel, newchan->name);
-	p->owner = newchan;
-	for (x=0;x<3;x++)
-		if (p->owners[x] == oldchan)
-			p->owners[x] = newchan;
-	if (newchan->state == AST_STATE_RINGING) 
-		tor_indicate(newchan, AST_CONTROL_RINGING);
-	return 0;
-}
-
-static int tor_ring_phone(struct tor_pvt *p)
-{
-	int x;
-	int res;
-	/* Make sure our transmit state is on hook */
-	x = 0;
-	x = TOR_ONHOOK;
-	res = ioctl(zap_fd(p->z), TOR_HOOK, &x);
-	do {
-		x = TOR_RING;
-		res = ioctl(zap_fd(p->z), TOR_HOOK, &x);
-#if 0
-		printf("Res: %d, error: %s\n", res, strerror(errno));
-#endif						
-		if (res) {
-			switch(errno) {
-			case EBUSY:
-			case EINTR:
-				/* Wait just in case */
-				usleep(10000);
-				continue;
-			case EINPROGRESS:
-				res = 0;
-				break;
-			default:
-				ast_log(LOG_WARNING, "Couldn't ring the phone: %s\n", strerror(errno));
-				res = 0;
-			}
-		}
-	} while (res);
-	return res;
-}
-
-static void *ss_thread(void *data);
-
-static struct ast_channel *tor_new(struct tor_pvt *, int, int, int, int);
-
-static int attempt_transfer(struct tor_pvt *p)
-{
-	/* In order to transfer, we need at least one of the channels to
-	   actually be in a call bridge.  We can't conference two applications
-	   together (but then, why would we want to?) */
-	if (p->owners[p->normalindex]->bridge) {
-		if (ast_channel_masquerade(p->owners[p->thirdcallindex], p->owners[p->normalindex]->bridge)) {
-			ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
-					p->owners[p->normalindex]->bridge->name, p->owners[p->thirdcallindex]->name);
-			return -1;
-		}
-		/* Orphan the channel */
-		p->owners[p->thirdcallindex] = NULL;
-		p->thirdcallindex = -1;
-	} else if (p->owners[p->thirdcallindex]->bridge) {
-		if (ast_channel_masquerade(p->owners[p->normalindex], p->owners[p->thirdcallindex]->bridge)) {
-			ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
-				p->owners[p->thirdcallindex]->bridge->name, p->owners[p->normalindex]->name);
-			return -1;
-		}
-		/* Orphan the normal channel */
-		p->owners[p->normalindex] = NULL;
-		p->normalindex = p->thirdcallindex;
-		p->thirdcallindex = -1;
-	} else {
-		ast_log(LOG_DEBUG, "Neither %s nor %s are in a bridge, nothing to transfer\n",
-					p->owners[p->normalindex]->name, p->owners[p->thirdcallindex]->name);
-		p->owners[p->thirdcallindex]->softhangup=1;
-	}
-	return 0;
-}
-
-struct ast_frame *tor_handle_event(struct ast_channel *ast)
-{
-	int res;
-	int index;
-	struct tor_pvt *p = ast->pvt->pvt;
-	pthread_t threadid;
-	pthread_attr_t attr;
-	struct ast_channel *chan;
-	pthread_attr_init(&attr);
-	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-	index = tor_get_index(ast, p, 0);
-	p->f.frametype = AST_FRAME_NULL;
-	p->f.datalen = 0;
-	p->f.timelen = 0;
-	p->f.mallocd = 0;
-	p->f.offset = 0;
-	p->f.src = "tor_handle_event";
-	p->f.data = NULL;
-	if (index < 0)
-		return &p->f;
-	res = tor_get_event(zap_fd(p->z));
-	ast_log(LOG_DEBUG, "Got event %s(%d) on channel %d (index %d)\n", event2str(res), res, p->channel, index);
-	switch(res) {
-		case TOR_EVENT_DIALCOMPLETE:
-			tor_enable_ec(p);
-			p->dialing = 0;
-			if (ast->state == AST_STATE_DIALING) {
-#if 0
-				ast->state = AST_STATE_RINGING;
-#else
-				ast->state = AST_STATE_UP;
-				p->f.frametype = AST_FRAME_CONTROL;
-				p->f.subclass = AST_CONTROL_ANSWER;
-#endif				
-			}
-			break;
-		case TOR_EVENT_ONHOOK:
-			switch(p->sig) {
-			case SIG_FXOLS:
-			case SIG_FXOGS:
-			case SIG_FXOKS:
-				/* Check for some special conditions regarding call waiting */
-				if (index == p->normalindex) {
-					/* The normal line was hung up */
-					if (p->callwaitindex > -1) {
-						/* There's a call waiting call, so ring the phone */
-						p->owner = p->owners[p->callwaitindex];
-						if (option_verbose > 2) 
-							ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has (callwait) call, ringing phone\n", p->owner);
-						p->needanswer[index] = 0;
-						p->needringing[index] = 0;
-						p->callwaitingrepeat = 0;
-						tor_ring_phone(p);
-					} else if (p->thirdcallindex > -1) {
-						if (p->transfer) {
-							if (attempt_transfer(p))
-								p->owners[p->thirdcallindex]->softhangup = 1;
-						} else
-							p->owners[p->thirdcallindex]->softhangup=1;
-					}
-				} else if (index == p->callwaitindex) {
-					/* Check to see if there is a normal call */
-					if (p->normalindex > -1) {
-						/* There's a call waiting call, so ring the phone */
-						p->owner = p->owners[p->normalindex];
-						if (option_verbose > 2) 
-							ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has (normal) call, ringing phone\n", p->owner);
-						p->needanswer[index] = 0;
-						p->needringing[index] = 0;
-						p->callwaitingrepeat = 0;
-						tor_ring_phone(p);
-					}
-				} else if (index == p->thirdcallindex) {
-					if ((ast->state != AST_STATE_UP) && (ast->state != AST_STATE_RINGING) &&
-							(ast->state != AST_STATE_RING)) {
-						/* According to the LSSGR, we should kill everything now, and we 
-						   do, instead of ringing the phone */
-						if (p->normalindex > -1) 
-							p->owners[p->normalindex]->softhangup=1;
-						if (p->callwaitindex > -1) {
-							ast_log(LOG_WARNING, "Somehow there was a call wait\n");
-							p->owners[p->callwaitindex]->softhangup = 1;
-						}
-						
-					} else {
-						if (p->transfer) {
-							if (attempt_transfer(p))
-								p->owners[p->normalindex]->softhangup = 1;
-							else {
-								/* Don't actually hangup.  We're going to get transferred */
-								tor_disable_ec(p);
-								break;
-							}
-						} else 
-							p->owners[p->normalindex]->softhangup = 1;
-					}
-				}
-				/* Fall through */
-			default:
-				tor_disable_ec(p);
-				return NULL;
-			}
-			break;
-		case TOR_EVENT_RINGOFFHOOK:
-			switch(p->sig) {
-			case SIG_FXOLS:
-			case SIG_FXOGS:
-			case SIG_FXOKS:
-				switch(ast->state) {
-				case AST_STATE_RINGING:
-					tor_enable_ec(p);
-					ast->state = AST_STATE_UP;
-					p->f.frametype = AST_FRAME_CONTROL;
-					p->f.subclass = AST_CONTROL_ANSWER;
-					/* Make sure it stops ringing */
-					tor_set_hook(zap_fd(p->z), TOR_OFFHOOK);
-					ast_log(LOG_DEBUG, "channel %d answered\n", p->channel);
-					if (p->cidspill) {
-						/* Cancel any running CallerID spill */
-						free(p->cidspill);
-						p->cidspill = NULL;
-					}
-					p->dialing = 0;
-					return &p->f;
-				case AST_STATE_DOWN:
-					ast->state = AST_STATE_RING;
-					ast->rings = 1;
-					p->f.frametype = AST_FRAME_CONTROL;
-					p->f.subclass = AST_CONTROL_OFFHOOK;
-					ast_log(LOG_DEBUG, "channel %d picked up\n", p->channel);
-					return &p->f;
-				case AST_STATE_UP:
-					/* Okay -- probably call waiting*/
-					break;
-				default:
-					ast_log(LOG_WARNING, "FXO phone off hook in weird state %d??\n", ast->state);
-				}
-				break;
-			case SIG_EM:
-			case SIG_EMWINK:
-			case SIG_FEATD:
-			case SIG_FXSLS:
-			case SIG_FXSGS:
-			case SIG_FXSKS:
-				if (ast->state == AST_STATE_DOWN) {
-					if (option_debug)
-						ast_log(LOG_DEBUG, "Ring detected\n");
-					p->f.frametype = AST_FRAME_CONTROL;
-					p->f.subclass = AST_CONTROL_RING;
-				} else if (ast->state == AST_STATE_RINGING) {
-					if (option_debug)
-						ast_log(LOG_DEBUG, "Line answered\n");
-					p->f.frametype = AST_FRAME_CONTROL;
-					p->f.subclass = AST_CONTROL_ANSWER;
-					ast->state = AST_STATE_UP;
-				} else 
-					ast_log(LOG_WARNING, "Ring/Off-hook in strange state %d on channel %d\n", ast->state, p->channel);
-				break;
-			default:
-				ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
-			}
-			break;
-		case TOR_EVENT_RINGEROFF:
-			ast->rings++;
-			if ((ast->rings > 1) && (p->cidspill)) {
-				ast_log(LOG_WARNING, "Didn't finish Caller-ID spill.  Cancelling.\n");
-				free(p->cidspill);
-				p->cidspill = NULL;
-				p->callwaitcas = 0;
-			}
-			p->f.frametype = AST_FRAME_CONTROL;
-			p->f.subclass = AST_CONTROL_RINGING;
-			break;
-		case TOR_EVENT_RINGERON:
-		case TOR_EVENT_NOALARM:
-			break;
-		case TOR_EVENT_WINKFLASH:
-			switch(p->sig) {
-			case SIG_FXOLS:
-			case SIG_FXOGS:
-			case SIG_FXOKS:
-				ast_log(LOG_DEBUG, "Winkflash, index: %d, normal: %d, callwait: %d, thirdcall: %d\n",
-					index, p->normalindex, p->callwaitindex, p->thirdcallindex);
-				if (index == p->normalindex) {
-					if (p->callwaitindex > -1) {
-						tone_zone_play_tone(zap_fd(p->z), -1);
-						p->owner = p->owners[p->callwaitindex];
-						if (p->owner->state == AST_STATE_RINGING) {
-							p->owner->state = AST_STATE_UP;
-							p->needanswer[p->callwaitindex] = 1;
-						}
-						p->callwaitingrepeat = 0;
-						conf_clear(p);
-					} else if (p->thirdcallindex == -1) {
-						if (p->threewaycalling) {
-							if ((ast->state == AST_STATE_RINGING) ||
-									(ast->state == AST_STATE_UP) ||
-									(ast->state == AST_STATE_RING)) {
-								if (!alloc_pseudo(p)) {
-									/* Start three way call */
-									res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_DIALRECALL);
-									if (res)
-										ast_log(LOG_WARNING, "Unable to start dial recall tone on channel %d\n", p->channel);
-									chan = tor_new(p, AST_STATE_RESERVED,0,0,1);
-									p->owner = chan;
-									if (pthread_create(&threadid, &attr, ss_thread, chan)) {
-										ast_log(LOG_WARNING, "Unable to start simple switch on channel %d\n", p->channel);
-										res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-										ast_hangup(chan);
-									} else {
-										if (option_verbose > 2)	
-											ast_verbose(VERBOSE_PREFIX_3 "Started three way call on channel %d (index %d)\n", p->channel, p->thirdcallindex);
-										conf_clear(p);
-									}		
-								} else
-									ast_log(LOG_WARNING, "Unable to allocate pseudo channel\n");
-							} else 
-								ast_log(LOG_DEBUG, "Flash when call not up or ringing\n");
-						}
-					} else {
-						if (option_debug)
-							ast_log(LOG_DEBUG, "Got flash with three way call up, dropping last call %d\n",
-								p->thirdcallindex);
-						/* Drop the last call and stop the conference */
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Dropping three-way call on %s\n", p->owners[p->thirdcallindex]->name);
-						p->owners[p->thirdcallindex]->softhangup=1;
-						conf_clear(p);
-					}
-				} else if (index == p->callwaitindex) {
-					if (p->normalindex > -1) {
-						p->owner = p->owners[p->normalindex];
-						p->callwaitingrepeat = 0;
-						conf_clear(p);
-					} else
-						ast_log(LOG_WARNING, "Wink/Flash on call wait, with no normal channel to flash to on channel %d?\n", p->channel);
-				} else if (index == p->thirdcallindex) {
-					if (p->normalindex > -1) {
-						if ((ast->state != AST_STATE_RINGING) && (ast->state != AST_STATE_UP) && (ast->state != AST_STATE_RING)) {
-							tone_zone_play_tone(zap_fd(p->z), -1);
-							p->owner = p->owners[p->normalindex];
-							ast_log(LOG_DEBUG, "Dumping incomplete three way call in state %d\n", ast->state);
-							return NULL;
-						}
-						p->owner = p->owners[p->normalindex];
-						p->owners[p->thirdcallindex]->fds[0] = zap_fd(p->pseudo);
-						p->callwaitingrepeat = 0;
-						if (p->owners[p->thirdcallindex]->state == AST_STATE_RINGING) {
-							/* If we were ringing, stop the ringing on the main line and start it on
-							   the pseudo */
-							tone_zone_play_tone(zap_fd(p->z), -1);
-							tone_zone_play_tone(zap_fd(p->pseudo), TOR_TONE_RINGTONE);
-						}
-						three_way(p);
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Established 3-way conference between %s and %s\n", 
-										p->owners[p->normalindex]->name, p->owners[p->thirdcallindex]->name);
-					} else {
-						ast_log(LOG_WARNING, "Wink/Flash on threeway call, with no normal channel to flash to on channel %d?\n", p->channel);
-						return NULL;
-					}
-				}
-				break;
-			case SIG_EM:
-			case SIG_EMWINK:
-			case SIG_FEATD:
-			case SIG_FXSLS:
-			case SIG_FXSGS:
-				if (p->dialing)
-					ast_log(LOG_DEBUG, "Ignoring wink on channel %d\n", p->channel);
-				else
-					ast_log(LOG_DEBUG, "Got wink in weird state %d on channel %d\n", ast->state, p->channel);
-				break;
-			default:
-				ast_log(LOG_WARNING, "Don't know how to handle ring/off hoook for signalling %d\n", p->sig);
-			}
-			break;
-		case TOR_EVENT_HOOKCOMPLETE:
-			res = ioctl(zap_fd(p->z), TOR_DIAL, &p->dop);
-			if (res < 0) {
-				ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
-				p->dop.dialstr[0] = '\0';
-				return NULL;
-			} else 
-				ast_log(LOG_DEBUG, "Sent deferred digit string: %s\n", p->dop.dialstr);
-			p->dop.dialstr[0] = '\0';
-			break;
-		default:
-			ast_log(LOG_DEBUG, "Dunno what to do with event %d on channel %d\n", res, p->channel);
-	}
-	return &p->f;
- }
-
-struct ast_frame *tor_exception(struct ast_channel *ast)
-{
-	struct tor_pvt *p = ast->pvt->pvt;
-	int res;
-	int usedindex=-1;
-	p->f.frametype = AST_FRAME_NULL;
-	p->f.datalen = 0;
-	p->f.timelen = 0;
-	p->f.mallocd = 0;
-	p->f.offset = 0;
-	p->f.subclass = 0;
-	p->f.src = "tor_exception";
-	p->f.data = NULL;
-	if ((p->owner != p->owners[0]) && 
-	    (p->owner != p->owners[1]) &&
-		(p->owner != p->owners[2])) {
-		/* If nobody owns us, absorb the event appropriately, otherwise
-		   we loop indefinitely.  This occurs when, during call waiting, the
-		   other end hangs up our channel so that it no longer exists, but we
-		   have neither FLASH'd nor ONHOOK'd to signify our desire to
-		   change to the other channel. */
-		res = tor_get_event(zap_fd(p->z));
-		if ((p->callwaitindex > -1) && (p->normalindex > -1)) 
-			ast_log(LOG_WARNING, "Absorbing exception on unowned channel, but there is both a normal and call waiting call still here?\n");
-		if (p->callwaitindex > -1) {
-			tone_zone_play_tone(zap_fd(p->z), -1);
-			p->owner = p->owners[p->callwaitindex];
-			usedindex = p->callwaitindex;
-		} else if (p->normalindex > -1) {
-			tone_zone_play_tone(zap_fd(p->z), -1);
-			p->owner = p->owners[p->normalindex];
-			usedindex = p->normalindex;
-		} else {
-			ast_log(LOG_WARNING, "No call wait call, no normal call, what do I do?\n");
-			return NULL;
-		}
-		switch(res) {
-		case TOR_EVENT_ONHOOK:
-			tor_disable_ec(p);
-			if (p->owner) {
-				if (option_verbose > 2) 
-					ast_verbose(VERBOSE_PREFIX_3 "Channel %s still has call, ringing phone\n", p->owner->name);
-				tor_ring_phone(p);
-				p->callwaitingrepeat = 0;
-			} else
-				ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
-			break;
-		case TOR_EVENT_WINKFLASH:
-			if (p->owner) {
-				if (option_verbose > 2) 
-					ast_verbose(VERBOSE_PREFIX_3 "Channel %d flashed to other channel %s\n", p->channel, p->owner->name);
-				if ((usedindex == p->callwaitindex) && (p->owner->state == AST_STATE_RINGING)) {
-					/* Answer the call wait if necessary */
-					p->needanswer[usedindex] = 1;
-					p->owner->state = AST_STATE_UP;
-				}
-				p->callwaitingrepeat = 0;
-			} else
-				ast_log(LOG_WARNING, "Absorbed on hook, but nobody is left!?!?\n");
-			break;
-		default:
-			ast_log(LOG_WARNING, "Don't know how to absorb event %s\n", event2str(res));
-		}
-		return &p->f;
-	}
-	/* If it's not us, return NULL immediately */
-	if (ast != p->owner)
-		return &p->f;
-		
-	return tor_handle_event(ast);
-}
-
-struct ast_frame  *tor_read(struct ast_channel *ast)
-{
-	struct tor_pvt *p = ast->pvt->pvt;
-	int res,x;
-	int index;
-	unsigned char ireadbuf[READ_SIZE];
-	unsigned char *readbuf;
-	ZAP *z = NULL;
-	
-	pthread_mutex_lock(&p->lock);
-	
-	p->f.frametype = AST_FRAME_NULL;
-	p->f.datalen = 0;
-	p->f.timelen = 0;
-	p->f.mallocd = 0;
-	p->f.offset = 0;
-	p->f.subclass = 0;
-	p->f.src = "tor_read";
-	p->f.data = NULL;
-	
-	index = tor_get_index(ast, p, 0);
-	
-	/* Hang up if we don't really exist */
-	if (index < 0)	{
-		ast_log(LOG_WARNING, "We dont exist?\n");
-		pthread_mutex_unlock(&p->lock);
-		return NULL;
-	}
-	
-	if (p->needringing[index]) {
-		/* Send ringing frame if requested */
-		p->needringing[index] = 0;
-		p->f.frametype = AST_FRAME_CONTROL;
-		p->f.subclass = AST_CONTROL_RINGING;
-		pthread_mutex_unlock(&p->lock);
-		return &p->f;
-	}	
-	
-	if (p->needanswer[index]) {
-		/* Send ringing frame if requested */
-		p->needanswer[index] = 0;
-		p->f.frametype = AST_FRAME_CONTROL;
-		p->f.subclass = AST_CONTROL_ANSWER;
-		pthread_mutex_unlock(&p->lock);
-		return &p->f;
-	}	
-	
-	if (ast != p->owner) {
-		/* If it's not us.  If this isn't a three way call, return immediately */
-		if (!INTHREEWAY(p)) {
-			pthread_mutex_unlock(&p->lock);
-			return &p->f;
-		}
-		/* If it's not the third call, return immediately */
-		if (ast != p->owners[p->thirdcallindex]) {
-			pthread_mutex_unlock(&p->lock);
-			return &p->f;
-		}
-		if (!p->pseudo) 
-			ast_log(LOG_ERROR, "No pseudo channel\n");
-		z = p->pseudo;		
-	} else
-		z = p->z;
-
-	if (!z) {
-		ast_log(LOG_WARNING, "No zap structure?!?\n");
-		pthread_mutex_unlock(&p->lock);
-		return NULL;
-	}
-	
-	/* Check first for any outstanding DTMF characters */
-	if (strlen(p->dtmfq)) {
-		p->f.subclass = p->dtmfq[0];
-		memmove(p->dtmfq, p->dtmfq + 1, sizeof(p->dtmfq) - 1);
-		p->f.frametype = AST_FRAME_DTMF;
-		pthread_mutex_unlock(&p->lock);
-		return &p->f;
-	}
-	
-	if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
-		/* Read into temporary buffer */
-		readbuf = ireadbuf;
-	} else if (ast->pvt->rawreadformat == AST_FORMAT_ULAW) {
-		/* Read ulaw directly into frame */
-		readbuf = ((unsigned char *)p->buffer) + AST_FRIENDLY_OFFSET;
-	} else {
-		ast_log(LOG_WARNING, "Don't know how to read frames in format %d\n", ast->pvt->rawreadformat);
-		pthread_mutex_unlock(&p->lock);
-		return NULL;
-	}
-	CHECK_BLOCKING(ast);
-	if ((z != p->z) && (z != p->pseudo)) {
-		pthread_mutex_unlock(&p->lock);
-		return NULL;
-	}
-	res = zap_recchunk(z, readbuf, READ_SIZE, ZAP_DTMFINT);
-	ast->blocking = 0;
-	/* Check for hangup */
-	if (res < 0) {
-		if (res == -1) 
-			ast_log(LOG_WARNING, "tor_rec: %s\n", strerror(errno));
-		pthread_mutex_unlock(&p->lock);
-		return NULL;
-	}
-	if (res != READ_SIZE) {
-		if (option_debug)
-			ast_log(LOG_DEBUG, "Short read, must be DTMF or something...\n");
-		/* XXX UGLY!!  Zapata's DTMF handling is a bit ugly XXX */
-		if (zap_dtmfwaiting(z) && !strlen(zap_dtmfbuf(z))) {
-			zap_getdtmf(z, 1, NULL, 0, 1, 1, 0);
-		}
-		if (strlen(zap_dtmfbuf(z))) {
-			ast_log(LOG_DEBUG, "Got some dtmf ('%s')... on channel %s\n", zap_dtmfbuf(z), ast->name);
-			/* DTMF tone detected.  Queue and erturn */
-			if (p->callwaitcas) {
-				if (!strcmp(zap_dtmfbuf(z), "A") || !strcmp(zap_dtmfbuf(z), "D")) {
-					ast_log(LOG_DEBUG, "Got some DTMF, but it's for the CAS\n");
-					if (p->cidspill)
-						free(p->cidspill);
-					send_cwcidspill(p);
-				}
-				/* Return NULL */
-				pthread_mutex_unlock(&p->lock);
-				return &p->f;
-			} else {
-				strncpy(p->dtmfq + strlen(p->dtmfq), zap_dtmfbuf(z), sizeof(p->dtmfq) - strlen(p->dtmfq));
-				zap_clrdtmfn(z);
-			}
-		} else {
-			pthread_mutex_unlock(&p->lock);
-			return tor_handle_event(ast);
-		}
-		if (strlen(p->dtmfq)) {
-			p->f.subclass = p->dtmfq[0];
-			memmove(p->dtmfq, p->dtmfq + 1, sizeof(p->dtmfq) - 1);
-			p->f.frametype = AST_FRAME_DTMF;
-		}
-		pthread_mutex_unlock(&p->lock);
-		return &p->f;
-	}
-	if (p->callwaitingrepeat)
-		p->callwaitingrepeat--;
-	/* Repeat callwaiting */
-	if (p->callwaitingrepeat == 1) {
-		p->callwaitrings++;
-		tor_callwait(ast);
-	}
-	if (ast->pvt->rawreadformat == AST_FORMAT_SLINEAR) {
-		for (x=0;x<READ_SIZE;x++) {
-			p->buffer[x + AST_FRIENDLY_OFFSET/2] = ast_mulaw[readbuf[x]];
-		}
-		p->f.datalen = READ_SIZE * 2;
-	} else 
-		p->f.datalen = READ_SIZE;
-
-	/* Handle CallerID Transmission */
-	if (p->cidspill &&((ast->state == AST_STATE_UP) || (ast->rings == 1)))
-		send_callerid(p);
-
-	p->f.frametype = AST_FRAME_VOICE;
-	p->f.subclass = ast->pvt->rawreadformat;
-	p->f.timelen = READ_SIZE/8;
-	p->f.mallocd = 0;
-	p->f.offset = AST_FRIENDLY_OFFSET;
-	p->f.data = p->buffer + AST_FRIENDLY_OFFSET/2;
-#if 0
-	ast_log(LOG_DEBUG, "Read %d of voice on %s\n", p->f.datalen, ast->name);
-#endif	
-	if (p->dialing) {
-		/* Whoops, we're still dialing, don't send anything */
-		p->f.frametype = AST_FRAME_NULL;
-		p->f.subclass = 0;
-		p->f.timelen = 0;
-		p->f.mallocd = 0;
-		p->f.offset = 0;
-		p->f.data = NULL;
-		p->f.datalen= 0;
-	}
-	pthread_mutex_unlock(&p->lock);
-	return &p->f;
-}
-
-static int my_tor_write(struct tor_pvt *p, unsigned char *buf, int len, int threeway)
-{
-	int sent=0;
-	int size;
-	int res;
-	int fd;
-	if (threeway) 
-		fd = zap_fd(p->pseudo);
-	else
-		fd = zap_fd(p->z);
-	while(len) {
-		size = len;
-		if (size > READ_SIZE)
-			size = READ_SIZE;
-		res = write(fd, buf, size);
-		if (res != size) {
-			ast_log(LOG_DEBUG, "Write returned %d (%s) on channel %d\n", res, strerror(errno), p->channel);
-			return sent;
-		}
-		len -= size;
-		buf += size;
-	}
-	return sent;
-}
-
-static int tor_write(struct ast_channel *ast, struct ast_frame *frame)
-{
-	struct tor_pvt *p = ast->pvt->pvt;
-	int x;
-	int res;
-	unsigned char outbuf[4096];
-	short *inbuf;
-	
-	if (ast != p->owner) {
-		/* If it's not us.  If this isn't a three way call, return immediately */
-		if (!INTHREEWAY(p)) {
-			return 0;
-		}
-		/* If it's not the third call, return immediately */
-		if (ast != p->owners[p->thirdcallindex]) {
-			return 0;
-		}
-	}
-	
-	/* Write a frame of (presumably voice) data */
-	if (frame->frametype != AST_FRAME_VOICE) {
-		ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
-		return -1;
-	}
-	if ((frame->subclass != AST_FORMAT_SLINEAR) && (frame->subclass != AST_FORMAT_ULAW)) {
-		ast_log(LOG_WARNING, "Cannot handle frames in %d format\n", frame->subclass);
-		return -1;
-	}
-	if (p->dialing) {
-#if 0
-		if (option_debug)
-#endif		
-			ast_log(LOG_DEBUG, "Dropping frame since I'm still dialing...\n");
-		return 0;
-	}
-	if (p->cidspill) {
-#if 0
-		if (option_debug)
-#endif		
-			ast_log(LOG_DEBUG, "Dropping frame since I've still got a callerid spill\n");
-		return 0;
-	}
-	/* Return if it's not valid data */
-	if (!frame->data || !frame->datalen)
-		return 0;
-	if (frame->datalen > sizeof(outbuf) * 2) {
-		ast_log(LOG_WARNING, "Frame too large\n");
-		return 0;
-	}
-	if (frame->subclass == AST_FORMAT_SLINEAR) {
-		inbuf = frame->data;
-		for (x=0;x<frame->datalen/2;x++)
-			outbuf[x] = ast_lin2mu[inbuf[x]+32768];
-		res = my_tor_write(p, outbuf, frame->datalen/2, (ast != p->owner));
-	} else {
-		/* uLaw already */
-		res = my_tor_write(p, (unsigned char *)frame->data, frame->datalen, (ast != p->owner));
-	}
-	if (res < 0) {
-		ast_log(LOG_WARNING, "write failed: %s\n", strerror(errno));
-		return -1;
-	} else if (res != frame->datalen/2) {
-		/* Some sort of an event */
-		return 0;
-	}
-	return 0;
-}
-
-static int tor_indicate(struct ast_channel *chan, int condition)
-{
-	struct tor_pvt *p = chan->pvt->pvt;
-	int res=-1;
-	switch(condition) {
-	case AST_CONTROL_BUSY:
-		res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_BUSY);
-		break;
-	case AST_CONTROL_RINGING:
-		res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_RINGTONE);
-		if (chan->state != AST_STATE_UP)
-			chan->state = AST_STATE_RINGING;
-		break;
-	case AST_CONTROL_CONGESTION:
-		res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-		break;
-	default:
-		ast_log(LOG_WARNING, "Don't know how to set condition %d on channel %s\n", condition, chan->name);
-	}
-	return res;
-}
-
-static struct ast_channel *tor_new(struct tor_pvt *i, int state, int startpbx, int callwaiting, int thirdcall)
-{
-	struct ast_channel *tmp;
-	int x;
-	for (x=0;x<3;x++)
-		if (!i->owners[x])
-			break;
-	if (x > 2) {
-		ast_log(LOG_WARNING, "No available owner slots\n");
-		return NULL;
-	}
-	tmp = ast_channel_alloc();
-	if (tmp) {
-		snprintf(tmp->name, sizeof(tmp->name), "Tor/%d-%d", i->channel, x + 1);
-		tmp->type = type;
-		tmp->fds[0] = zap_fd(i->z);
-		tmp->nativeformats = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
-		/* Start out assuming ulaw since it's smaller :) */
-		tmp->pvt->rawreadformat = AST_FORMAT_ULAW;
-		tmp->readformat = AST_FORMAT_ULAW;
-		tmp->pvt->rawwriteformat = AST_FORMAT_ULAW;
-		tmp->writeformat = AST_FORMAT_ULAW;
-		
-		tmp->state = state;
-		if (state == AST_STATE_RING)
-			tmp->rings = 1;
-		tmp->pvt->pvt = i;
-		tmp->pvt->send_digit = tor_digit;
-		tmp->pvt->call = tor_call;
-		tmp->pvt->hangup = tor_hangup;
-		tmp->pvt->answer = tor_answer;
-		tmp->pvt->read = tor_read;
-		tmp->pvt->write = tor_write;
-		tmp->pvt->bridge = tor_bridge;
-		tmp->pvt->exception = tor_exception;
-		tmp->pvt->indicate = tor_indicate;
-		tmp->pvt->fixup = tor_fixup;
-		tmp->pvt->setoption = tor_setoption;
-		if (strlen(i->language))
-			strncpy(tmp->language, i->language, sizeof(tmp->language));
-		/* Keep track of who owns it */
-		i->owners[x] = tmp;
-		if (!i->owner)
-			i->owner = tmp;
-		if (callwaiting) {
-			if (i->callwaitindex > -1)
-				ast_log(LOG_WARNING, "channel %d already has a call wait call\n", i->channel);
-			i->callwaitindex = x;
-		} else if (thirdcall) {
-			if (i->thirdcallindex > -1)
-				ast_log(LOG_WARNING, "channel %d already has a third call\n", i->channel);
-			i->thirdcallindex = x;
-		} else {
-			if (i->normalindex > -1) 
-				ast_log(LOG_WARNING, "channel %d already has a normal call\n", i->channel);
-			i->normalindex = x;
-		}
-		ast_pthread_mutex_lock(&usecnt_lock);
-		usecnt++;
-		ast_pthread_mutex_unlock(&usecnt_lock);
-		ast_update_use_count();
-		strncpy(tmp->context, i->context, sizeof(tmp->context));
-		if (strlen(i->exten))
-			strncpy(tmp->exten, i->exten, sizeof(tmp->exten));
-		if (startpbx) {
-			if (strlen(i->callerid))
-				tmp->callerid = strdup(i->callerid);
-			if (ast_pbx_start(tmp)) {
-				ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
-				ast_hangup(tmp);
-				tmp = NULL;
-			}
-		}
-	} else
-		ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
-	return tmp;
-}
-
-
-static int ignore_pat(char *s)
-{
-	int x;
-	for (x=0;x<dialpats;x++)
-		if (ast_extension_match(keepdialpat[x], s))
-			return 1;
-	return 0;
-}
-
-static int bump_gains(struct tor_pvt *p)
-{
-	int res;
-	/* Bump receive gain by 9.0db */
-	res = set_actual_gain(zap_fd(p->z), 0, p->rxgain + 5.0, p->txgain);
-	if (res) {
-		ast_log(LOG_WARNING, "Unable to bump gain\n");
-		return -1;
-	}
-	return 0;
-}
-
-static int restore_gains(struct tor_pvt *p)
-{
-	int res;
-	/* Bump receive gain by 9.0db */
-	res = set_actual_gain(zap_fd(p->z), 0, p->rxgain, p->txgain);
-	if (res) {
-		ast_log(LOG_WARNING, "Unable to restore gain\n");
-		return -1;
-	}
-	return 0;
-}
-
-static void *ss_thread(void *data)
-{
-	struct ast_channel *chan = data;
-	struct tor_pvt *p = chan->pvt->pvt;
-	char exten[AST_MAX_EXTENSION];
-	char exten2[AST_MAX_EXTENSION];
-	unsigned char buf[256];
-	char cid[256];
-	struct callerid_state *cs;
-	char *name, *number;
-	int flags;
-	int i;
-	int timeout;
-	char *s1, *s2;
-	int len = 0;
-	int res;
-	if (option_verbose > 2) 
-		ast_verbose( VERBOSE_PREFIX_3 "Starting simple switch on '%s'\n", chan->name);
-	zap_clrdtmf(p->z);
-	switch(p->sig) {
-	case SIG_FEATD:
-	case SIG_EMWINK:
-		zap_wink(p->z);
-		/* Fall through */
-	case SIG_EM:
-		res = tone_zone_play_tone(zap_fd(p->z), -1);
-		zap_clrdtmf(p->z);
-		/* Wait for the first digit (up to 1 second). */
-		res = zap_getdtmf(p->z, 1, NULL, 0, 1000, 1000, ZAP_TIMEOUTOK | ZAP_HOOKEXIT);
-
-		if (res == 1) {
-			/* If we got it, get the rest */
-			res = zap_getdtmf(p->z, 50, NULL, 0, 250, 15000, ZAP_TIMEOUTOK | ZAP_HOOKEXIT);
-		}
-		if (res == -1) {
-			ast_log(LOG_WARNING, "getdtmf on channel %d: %s\n", p->channel, strerror(errno));
-			ast_hangup(chan);
-			return NULL;
-		} else if (res < 0) {
-			ast_log(LOG_DEBUG, "Got hung up before digits finished\n");
-			ast_hangup(chan);
-			return NULL;
-		}
-		strncpy(exten, zap_dtmfbuf(p->z), sizeof(exten));
-		if (!strlen(exten))
-			strncpy(exten, "s", sizeof(exten));
-		if (p->sig == SIG_FEATD) {
-			if (exten[0] == '*') {
-				strncpy(exten2, exten, sizeof(exten2));
-				/* Parse out extension and callerid */
-				s1 = strtok(exten2 + 1, "*");
-				s2 = strtok(NULL, "*");
-				if (s2) {
-					if (strlen(p->callerid))
-						chan->callerid = strdup(p->callerid);
-					else
-						chan->callerid = strdup(s1);
-					strncpy(exten, s2, sizeof(exten));
-				} else
-					strncpy(exten, s1, sizeof(exten));
-			} else
-				ast_log(LOG_WARNING, "Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead\n", p->channel);
-		}
-		tor_enable_ec(p);
-		if (ast_exists_extension(chan, chan->context, exten, 1)) {
-			strncpy(chan->exten, exten, sizeof(chan->exten));
-			zap_clrdtmf(p->z);
-			res = ast_pbx_run(chan);
-			if (res) {
-				ast_log(LOG_WARNING, "PBX exited non-zero\n");
-				res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-			}
-			return NULL;
-		} else {
-			if (option_verbose > 2)
-				ast_verbose(VERBOSE_PREFIX_2 "Unknown extension '%s' in context '%s' requested\n", exten, chan->context);
-			sleep(2);
-			res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_INFO);
-			if (res < 0)
-				ast_log(LOG_WARNING, "Unable to start special tone on %d\n", p->channel);
-			else
-				sleep(1);
-			res = ast_streamfile(chan, "ss-noservice", chan->language);
-			if (res >= 0)
-				ast_waitstream(chan, "");
-			res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-			ast_hangup(chan);
-			return NULL;
-		}
-		break;
-	case SIG_FXOLS:
-	case SIG_FXOGS:
-	case SIG_FXOKS:
-		/* Read the first digit */
-		timeout = firstdigittimeout;
-		while(len < AST_MAX_EXTENSION-1) {
-			res = ast_waitfordigit(chan, timeout);
-			if (res < 0) {
-				ast_log(LOG_DEBUG, "waitfordigit returned < 0...\n");
-				res = tone_zone_play_tone(zap_fd(p->z), -1);
-				ast_hangup(chan);
-				return NULL;
-			} else if (res == 0) {
-				ast_log(LOG_DEBUG, "not enough digits...\n");
-				res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-				tor_wait_event(zap_fd(p->z));
-				ast_hangup(chan);
-				return NULL;
-			} else {
-				exten[len++]=res;
-            exten[len] = '\0';
-			}
-			if (!ignore_pat(exten))
-				tone_zone_play_tone(zap_fd(p->z), -1);
-			if (ast_exists_extension(chan, chan->context, exten, 1)) {
-				res = tone_zone_play_tone(zap_fd(p->z), -1);
-				strncpy(chan->exten, exten, sizeof(chan->exten));
-				if (strlen(p->callerid) && !p->hidecallerid)
-					chan->callerid = strdup(p->callerid);
-				chan->state = AST_STATE_RING;
-				tor_enable_ec(p);
-				res = ast_pbx_run(chan);
-				if (res) {
-					ast_log(LOG_WARNING, "PBX exited non-zero\n");
-					res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-				}						
-				return NULL;
-			} else if (p->callwaiting && !strcmp(exten, "*70")) {
-				if (option_verbose > 2) 
-					ast_verbose(VERBOSE_PREFIX_3 "Disabling call waiting on %s\n", chan->name);
-				/* Disable call waiting if enabled */
-				p->callwaiting = 0;
-				res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_DIALRECALL);
-				if (res) {
-					ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
-						chan->name, strerror(errno));
-				}
-				len = 0;
-				memset(exten, 0, sizeof(exten));
-				timeout = firstdigittimeout;
-					
-			} else if (!p->hidecallerid && !strcmp(exten, "*67")) {
-				if (option_verbose > 2) 
-					ast_verbose(VERBOSE_PREFIX_3 "Disabling Caller*ID on %s\n", chan->name);
-				/* Disable Caller*ID if enabled */
-				p->hidecallerid = 1;
-				if (chan->callerid)
-					free(chan->callerid);
-				chan->callerid = NULL;
-				res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_DIALRECALL);
-				if (res) {
-					ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
-						chan->name, strerror(errno));
-				}
-				len = 0;
-				memset(exten, 0, sizeof(exten));
-				timeout = firstdigittimeout;
-					
-			} else if (p->hidecallerid && !strcmp(exten, "*82")) {
-				if (option_verbose > 2) 
-					ast_verbose(VERBOSE_PREFIX_3 "Enabling Caller*ID on %s\n", chan->name);
-				/* Enable Caller*ID if enabled */
-				p->hidecallerid = 0;
-				if (chan->callerid)
-					free(chan->callerid);
-				chan->callerid = NULL;
-				res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_DIALRECALL);
-				if (res) {
-					ast_log(LOG_WARNING, "Unable to do dial recall on channel %s: %s\n", 
-						chan->name, strerror(errno));
-				}
-				len = 0;
-				memset(exten, 0, sizeof(exten));
-				timeout = firstdigittimeout;
-					
-			} else if (!ast_canmatch_extension(chan, chan->context, exten, 1) &&
-							((exten[0] != '*') || (strlen(exten) > 2))) {
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Can't match %s from '%s' in context %s\n", exten, chan->callerid ? chan->callerid : "<Unknown Caller>", chan->context);
-				break;
-			}
-			timeout = gendigittimeout;
-			if (len && !ignore_pat(exten))
-				tone_zone_play_tone(zap_fd(p->z), -1);
-		}
-		break;
-	case SIG_FXSLS:
-	case SIG_FXSGS:
-	case SIG_FXSKS:
-		if (p->use_callerid) {
-			cs = callerid_new();
-			if (cs) {
-#if 1
-				bump_gains(p);
-#endif				
-				len = 0;
-				for(;;) {	
-					i = TOR_IOMUX_READ | TOR_IOMUX_SIGEVENT;
-					if ((res = ioctl(zap_fd(p->z), TOR_IOMUX, &i)))	{
-						ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
-						callerid_free(cs);
-						ast_hangup(chan);
-						return NULL;
-					}
-					if (i & TOR_IOMUX_SIGEVENT) {
-						res = tor_get_event(zap_fd(p->z));
-						ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
-						res = 0;
-						break;
-					} else if (i & TOR_IOMUX_READ) {
-						res = read(zap_fd(p->z), buf + len, sizeof(buf) - len);
-						if (res < 0) {
-							if (errno != ELAST) {
-								ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
-								callerid_free(cs);
-								ast_hangup(chan);
-								return NULL;
-							}
-							break;
-						}
-						res = callerid_feed(cs, buf, res);
-						if (res < 0) {
-							ast_log(LOG_WARNING, "CallerID feed failed: %s\n", strerror(errno));
-							break;
-						} else if (res)
-							break;
-					}
-				}
-				if (res == 1) {
-					callerid_get(cs, &number, &name, &flags);
-					if (option_debug)
-						ast_log(LOG_DEBUG, "CallerID number: %s, name: %s, flags=%d\n", number, name, flags);
-				}
-#if 1
-				restore_gains(p);
-#endif				
-				if (res < 0) {
-					ast_log(LOG_WARNING, "CallerID returned with error on channel '%s'\n", chan->name);
-				}
-			} else
-				ast_log(LOG_WARNING, "Unable to get caller ID space\n");
-		}
-		if (name && number) {
-			snprintf(cid, sizeof(cid), "\"%s\" <%s>", name, number);
-		} else if (name) {
-			snprintf(cid, sizeof(cid), "\"%s\"", name);
-		} else if (number) {
-			snprintf(cid, sizeof(cid), "%s", number);
-		} else {
-			strcpy(cid, "");
-		}
-		if (strlen(cid))
-			chan->callerid = strdup(cid);
-		chan->state = AST_STATE_RING;
-		chan->rings = 1;
-		tor_enable_ec(p);
-		res = ast_pbx_run(chan);
-		if (res) {
-			ast_hangup(chan);
-			ast_log(LOG_WARNING, "PBX exited non-zero\n");
-		}
-		return NULL;
-	default:
-		ast_log(LOG_WARNING, "Don't know how to handle simple switch with signalling %s on channel %d\n", sig2str(p->sig), p->channel);
-		res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-		if (res < 0)
-				ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
-	}
-	res = tone_zone_play_tone(zap_fd(p->z), TOR_TONE_CONGESTION);
-	if (res < 0)
-			ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", p->channel);
-	ast_hangup(chan);
-	return NULL;
-}
-
-static int handle_init_event(struct tor_pvt *i, int event)
-{
-	int res;
-	pthread_t threadid;
-	pthread_attr_t attr;
-	struct ast_channel *chan;
-	pthread_attr_init(&attr);
-	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-	/* Handle an event on a given channel for the monitor thread. */
-	switch(event) {
-	case TOR_EVENT_RINGOFFHOOK:
-		/* Got a ring/answer.  What kind of channel are we? */
-		switch(i->sig) {
-		case SIG_FXOLS:
-		case SIG_FXOGS:
-		case SIG_FXOKS:
-			if (i->immediate) {
-				tor_enable_ec(i);
-				/* The channel is immediately up.  Start right away */
-				res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_RINGTONE);
-				chan = tor_new(i, AST_STATE_RING, 1, 0, 0);
-				if (!chan)  {
-					ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
-					res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
-					if (res < 0)
-						ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
-				}
-			} else {
-				res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_DIALTONE);
-				if (res < 0) 
-					ast_log(LOG_WARNING, "Unable to play dialtone on channel %d\n", i->channel);
-				/* Check for callerid, digits, etc */
-				chan = tor_new(i, AST_STATE_DOWN, 0, 0, 0);
-				if (pthread_create(&threadid, &attr, ss_thread, chan)) {
-					ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
-					res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
-					if (res < 0)
-						ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
-					ast_hangup(chan);
-				}
-#if 0
-				printf("Created thread %ld detached in switch\n", threadid);
-#endif
-			}
-			break;
-		case SIG_EMWINK:
-		case SIG_FEATD:
-		case SIG_EM:
-		case SIG_FXSLS:
-		case SIG_FXSGS:
-		case SIG_FXSKS:
-				/* Check for callerid, digits, etc */
-				chan = tor_new(i, AST_STATE_RING, 0, 0, 0);
-				if (pthread_create(&threadid, &attr, ss_thread, chan)) {
-					ast_log(LOG_WARNING, "Unable to start simple switch thread on channel %d\n", i->channel);
-					res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
-					if (res < 0)
-						ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
-					ast_hangup(chan);
-				}
-#if 0
-				printf("Created thread %ld detached in switch(2)\n", threadid);
-#endif
-				break;
-		default:
-			ast_log(LOG_WARNING, "Don't know how to handle ring/answer with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
-			res = tone_zone_play_tone(zap_fd(i->z), TOR_TONE_CONGESTION);
-			if (res < 0)
-					ast_log(LOG_WARNING, "Unable to play congestion tone on channel %d\n", i->channel);
-			return -1;
-		}
-		break;
-	case TOR_EVENT_WINKFLASH:
-	case TOR_EVENT_ONHOOK:
-		/* Back on hook.  Hang up. */
-		switch(i->sig) {
-		case SIG_FXOLS:
-		case SIG_FXOGS:
-		case SIG_FXOKS:
-		case SIG_FEATD:
-		case SIG_EM:
-		case SIG_EMWINK:
-		case SIG_FXSLS:
-		case SIG_FXSGS:
-		case SIG_FXSKS:
-			tor_disable_ec(i);
-			res = tone_zone_play_tone(zap_fd(i->z), -1);
-			tor_set_hook(zap_fd(i->z), TOR_ONHOOK);
-			break;
-		default:
-			ast_log(LOG_WARNING, "Don't know hwo to handle on hook with signalling %s on channel %d\n", sig2str(i->sig), i->channel);
-			res = tone_zone_play_tone(zap_fd(i->z), -1);
-			return -1;
-		}
-		break;
-	}
-	return 0;
-}
-
-static void *do_monitor(void *data)
-{
-	fd_set efds;
-	int n, res;
-	struct tor_pvt *i;
-	/* This thread monitors all the frame relay interfaces which are not yet in use
-	   (and thus do not have a separate thread) indefinitely */
-	/* From here on out, we die whenever asked */
-#if 0
-	if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
-		ast_log(LOG_WARNING, "Unable to set cancel type to asynchronous\n");
-		return NULL;
-	}
-	ast_log(LOG_DEBUG, "Monitor starting...\n");
-#endif
-	for(;;) {
-		/* Lock the interface list */
-		if (ast_pthread_mutex_lock(&iflock)) {
-			ast_log(LOG_ERROR, "Unable to grab interface lock\n");
-			return NULL;
-		}
-		/* Build the stuff we're going to select on, that is the socket of every
-		   tor_pvt that does not have an associated owner channel */
-		n = -1;
-		FD_ZERO(&efds);
-		i = iflist;
-		while(i) {
-			if (FD_ISSET(zap_fd(i->z), &efds)) 
-				ast_log(LOG_WARNING, "Descriptor %d appears twice?\n", zap_fd(i->z));
-			if (!i->owner) {
-				/* This needs to be watched, as it lacks an owner */
-				FD_SET(zap_fd(i->z), &efds);
-				if (zap_fd(i->z) > n)
-					n = zap_fd(i->z);
-			}
-			i = i->next;
-		}
-		/* Okay, now that we know what to do, release the interface lock */
-		ast_pthread_mutex_unlock(&iflock);
-		
-		pthread_testcancel();
-		/* Wait indefinitely for something to happen */
-		res = select(n + 1, NULL, NULL, &efds, NULL);
-		pthread_testcancel();
-		/* Okay, select has finished.  Let's see what happened.  */
-		if (res < 0) {
-			if ((errno != EAGAIN) && (errno != EINTR))
-				ast_log(LOG_WARNING, "select return %d: %s\n", res, strerror(errno));
-			continue;
-		}
-		/* Alright, lock the interface list again, and let's look and see what has
-		   happened */
-		if (ast_pthread_mutex_lock(&iflock)) {
-			ast_log(LOG_WARNING, "Unable to lock the interface list\n");
-			continue;
-		}
-		i = iflist;
-		while(i) {
-			if (FD_ISSET(zap_fd(i->z), &efds)) {
-				if (i->owner) {
-					ast_log(LOG_WARNING, "Whoa....  I'm owned but found (%d)...\n", zap_fd(i->z));
-					i = i->next;
-					continue;
-				}
-				res = tor_get_event(zap_fd(i->z));
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Monitor doohicky got event %s on channel %d\n", event2str(res), i->channel);
-				handle_init_event(i, res);
-			}
-			i=i->next;
-		}
-		ast_pthread_mutex_unlock(&iflock);
-	}
-	/* Never reached */
-	return NULL;
-	
-}
-
-static int restart_monitor(void)
-{
-	pthread_attr_t attr;
-	pthread_attr_init(&attr);
-	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-	/* If we're supposed to be stopped -- stay stopped */
-	if (monitor_thread == -2)
-		return 0;
-	if (ast_pthread_mutex_lock(&monlock)) {
-		ast_log(LOG_WARNING, "Unable to lock monitor\n");
-		return -1;
-	}
-	if (monitor_thread == pthread_self()) {
-		ast_pthread_mutex_unlock(&monlock);
-		ast_log(LOG_WARNING, "Cannot kill myself\n");
-		return -1;
-	}
-	if (monitor_thread) {
-		pthread_cancel(monitor_thread);
-		pthread_kill(monitor_thread, SIGURG);
-		pthread_join(monitor_thread, NULL);
-	}
-	/* Start a new monitor */
-	if (pthread_create(&monitor_thread, &attr, do_monitor, NULL) < 0) {
-		ast_pthread_mutex_unlock(&monlock);
-		ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
-		return -1;
-	}
-#if 0
-	printf("Created thread %ld detached in restart monitor\n", monitor_thread);
-#endif
-	ast_pthread_mutex_unlock(&monlock);
-	return 0;
-}
-
-static struct tor_pvt *mkif(int channel, int signalling)
-{
-	/* Make a tor_pvt structure for this interface */
-	struct tor_pvt *tmp;
-	char fn[80];
-#if 1
-	struct tor_bufferinfo bi;
-#endif	
-	int res;
-	int span;
-	TOR_PARAMS p;
-
-	tmp = malloc(sizeof(struct tor_pvt));
-	if (tmp) {
-		memset(tmp, 0, sizeof(struct tor_pvt));
-		snprintf(fn, sizeof(fn), "/dev/tor/%d", channel);
-		/* Open non-blocking */
-		tmp->z = zap_open(fn, 1);
-		/* Allocate a zapata structure */
-		if (!tmp->z) {
-			ast_log(LOG_ERROR, "Unable to open channel %d: %s\n", channel, strerror(errno));
-			free(tmp);
-			return NULL;
-		}
-		res = ioctl(zap_fd(tmp->z), TOR_GET_PARAMS, &p);
-		if (res < 0) {
-			ast_log(LOG_ERROR, "Unable to get parameters\n");
-			free(tmp);
-			return NULL;
-		}
-		if (p.sigtype != (signalling & 0xf)) {
-			ast_log(LOG_ERROR, "Signalling requested is %s but line is in %s signalling\n", sig2str(signalling), sig2str(p.sigtype));
-			free(tmp);
-			return NULL;
-		}
-		span = (channel - 1)/24;
-		tmp->span = span + 1;
-#ifdef TORMENTA_PRI
-		if (signalling == SIG_PRI) {
-			int offset;
-			offset = 1;
-			if (ioctl(zap_fd(tmp->z), TOR_AUDIOMODE, &offset)) {
-				ast_log(LOG_ERROR, "Unable to set audio mode on clear channel %d of span %d: %s\n", channel, span, strerror(errno));
-				return NULL;
-			}
-			if (span >= NUM_SPANS) {
-				ast_log(LOG_ERROR, "Channel %d does not lie on a span I know of (%d)\n", channel, span);
-				free(tmp);
-				return NULL;
-			} else {
-				offset = (channel -1) % 24 + 1;
-				if (offset < 24) {
-					if (pris[span].nodetype && (pris[span].nodetype != pritype)) {
-						ast_log(LOG_ERROR, "Span %d is already a %s node\n", span + 1, pri_node2str(pris[span].nodetype));
-						free(tmp);
-						return NULL;
-					}
-					if (pris[span].switchtype && (pris[span].switchtype != switchtype)) {
-						ast_log(LOG_ERROR, "Span %d is already a %s switch\n", span + 1, pri_switch2str(pris[span].switchtype));
-						free(tmp);
-						return NULL;
-					}
-					pris[span].nodetype = pritype;
-					pris[span].switchtype = switchtype;
-					pris[span].chanmask[offset] |= MASK_AVAIL;
-					pris[span].pvt[offset] = tmp;
-					tmp->pri = &pris[span];
-					tmp->call = NULL;
-				} else {
-					ast_log(LOG_ERROR, "Channel 24 is reserved for D-channel.\n");
-					free(tmp);
-					return NULL;
-				}
-			}
-		}
-#endif		
-		/* Adjust starttime on loopstart and kewlstart trunks to reasonable values */
-		if ((signalling == SIG_FXSKS) || (signalling == SIG_FXSLS)) {
-			p.starttime = 250;
-			res = ioctl(zap_fd(tmp->z), TOR_SET_PARAMS, &p);
-			if (res < 0) {
-				ast_log(LOG_ERROR, "Unable to set parameters\n");
-				free(tmp);
-				return NULL;
-			}
-		}
-#if 0
-		res = fcntl(zap_fd(tmp->z), F_GETFL);
-		if (res >= 0) {
-			res |= O_NONBLOCK;
-			if (fcntl(zap_fd(tmp->z), F_SETFL, res))
-				ast_log(LOG_WARNING, "Unable to set non-blocking mode on channel %d\n", channel);
-		} else
-			ast_log(LOG_WARNING, "Unable to read flags on channel %d\n", channel);
-#endif			
-#if 1
-		res = ioctl(zap_fd(tmp->z), TOR_GET_BUFINFO, &bi);
-		if (!res) {
-			bi.txbufpolicy = POLICY_IMMEDIATE;
-			bi.rxbufpolicy = POLICY_IMMEDIATE;
-			bi.numbufs = 4;
-			res = ioctl(zap_fd(tmp->z), TOR_SET_BUFINFO, &bi);
-			if (res < 0) {
-				ast_log(LOG_WARNING, "Unable to set buffer policy on channel %d\n", channel);
-			}
-		} else
-			ast_log(LOG_WARNING, "Unable to check buffer policy on channel %d\n", channel);
-#endif
-		tmp->immediate = immediate;
-		tmp->sig = signalling;
-		if ((signalling == SIG_FXOKS) || (signalling == SIG_FXOLS) || (signalling == SIG_FXOGS))
-			tmp->permcallwaiting = callwaiting;
-		else
-			tmp->permcallwaiting = 0;
-		tmp->callwaitingcallerid = callwaitingcallerid;
-		tmp->threewaycalling = threewaycalling;
-		tmp->permhidecallerid = hidecallerid;
-		tmp->echocancel = echocancel;
-		tmp->callwaiting = tmp->permcallwaiting;
-		tmp->hidecallerid = tmp->permhidecallerid;
-		tmp->channel = channel;
-		tmp->stripmsd = stripmsd;
-		tmp->use_callerid = use_callerid;
-		tmp->callwaitindex = -1;
-		tmp->normalindex = -1;
-		tmp->thirdcallindex = -1;
-		tmp->normalindex = -1;
-		tmp->confno = -1;
-		tmp->pseudo = NULL;
-		tmp->pseudochan = 0;
-		tmp->transfer = transfer;
-		pthread_mutex_init(&tmp->lock, NULL);
-		strncpy(tmp->language, language, sizeof(tmp->language));
-		strncpy(tmp->context, context, sizeof(tmp->context));
-		strncpy(tmp->callerid, callerid, sizeof(tmp->callerid));
-		tmp->group = cur_group;
-		tmp->next = NULL;
-		tmp->rxgain = rxgain;
-		tmp->txgain = txgain;
-		set_actual_gain(zap_fd(tmp->z), 0, tmp->rxgain, tmp->txgain);
-		zap_digitmode(tmp->z, ZAP_DTMF /* | ZAP_MUTECONF */);
-		conf_clear(tmp);
-		if (signalling != SIG_PRI) 
-			/* Hang it up to be sure it's good */
-			tor_set_hook(zap_fd(tmp->z), TOR_ONHOOK);
-	}
-	return tmp;
-}
-
-static inline int available(struct tor_pvt *p, int channelmatch, int groupmatch)
-{
-	/* First, check group matching */
-	if ((p->group & groupmatch) != groupmatch)
-		return 0;
-	/* Check to see if we have a channel match */
-	if ((channelmatch > 0) && (p->channel != channelmatch))
-		return 0;
-		
-	/* If no owner definitely available */
-	if (!p->owner)
-		return 1;
-
-	if (!p->callwaiting) {
-		/* If they don't have call waiting enabled, then for sure they're unavailable at this point */
-		return 0;
-	}
-
-	if (p->callwaitindex > -1) {
-		/* If there is already a call waiting call, then we can't take a second one */
-		return 0;
-	}
-	
-	if ((p->owner->state != AST_STATE_UP) &&
-		(p->owner->state != AST_STATE_RINGING)) {
-		/* If the current call is not up, then don't allow the call */
-		return 0;
-	}
-	if ((p->thirdcallindex > -1) && (p->owner == p->owners[p->thirdcallindex])) {
-		/* Can't take a call wait when the three way calling hasn't been merged yet. */
-		return 0;
-	}
-	/* We're cool */
-	return 1;
-}
-
-static struct ast_channel *tor_request(char *type, int format, void *data)
-{
-	int oldformat;
-	int groupmatch = 0;
-	int channelmatch = -1;
-	struct tor_pvt *p;
-	struct ast_channel *tmp = NULL;
-	char *dest=NULL;
-	int x;
-	char *s;
-	int callwait;
-	
-	/* We do signed linear */
-	oldformat = format;
-	format &= (AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%d'\n", oldformat);
-		return NULL;
-	}
-	if (data) {
-		dest = strdup((char *)data);
-	} else {
-		ast_log(LOG_WARNING, "Channel requested with no data\n");
-		return NULL;
-	}
-	if (dest[0] == 'g') {
-		/* Retrieve the group number */
-		s = strtok(dest  + 1, "/");
-		if (sscanf(s, "%d", &x) != 1) {
-			ast_log(LOG_WARNING, "Unable to determine group for data %s\n", (char *)data);
-			free(dest);
-			return NULL;
-		}
-		groupmatch = 1 << x;
-	} else {
-		s = strtok(dest, "/");
-		if (sscanf(s, "%d", &x) != 1) {
-			ast_log(LOG_WARNING, "Unable to determine channel for data %s\n", (char *)data);
-			free(dest);
-			return NULL;
-		}
-		channelmatch = x;
-	}
-	/* Search for an unowned channel */
-	if (ast_pthread_mutex_lock(&iflock)) {
-		ast_log(LOG_ERROR, "Unable to lock interface list???\n");
-		return NULL;
-	}
-	p = iflist;
-	while(p && !tmp) {
-		if (available(p, channelmatch, groupmatch)) {
-			if (option_debug)
-				ast_log(LOG_DEBUG, "Using channel %d\n", p->channel);
-#ifdef TORMENTA_PRI
-       	if (p->pri) 
-				if (!(p->call = pri_new_call(p->pri->pri))) {
-					ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
-					break;
-				}
-#endif
-			callwait = (p->owner != NULL);
-			tmp = tor_new(p, AST_STATE_RESERVED, 0, p->owner ? 1 : 0, 0);
-			/* Note if the call is a call waiting call */
-			if (callwait)
-				tmp->cdrflags |= AST_CDR_CALLWAIT;
-			break;
-		}
-		p = p->next;
-	}
-	ast_pthread_mutex_unlock(&iflock);
-	restart_monitor();
-	return tmp;
-}
-
-
-static int get_group(char *s)
-{
-	char *copy;
-	char *piece;
-	int start, finish,x;
-	int group = 0;
-	copy = strdup(s);
-	if (!copy) {
-		ast_log(LOG_ERROR, "Out of memory\n");
-		return 0;
-	}
-	piece = strtok(copy, ",");
-	while(piece) {
-		if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
-			/* Range */
-		} else if (sscanf(piece, "%d", &start)) {
-			/* Just one */
-			finish = start;
-		} else {
-			ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'.  Using '0'\n", s,piece);
-			return 0;
-		}
-		piece = strtok(NULL, ",");
-		for (x=start;x<=finish;x++) {
-			if ((x > 31) || (x < 0)) {
-				ast_log(LOG_WARNING, "Ignoring invalid group %d\n", x);
-			} else
-				group |= (1 << x);
-		}
-	}
-	free(copy);
-	return group;
-}
-
-#ifdef TORMENTA_PRI
-
-static int pri_find_empty_chan(struct tor_pri *pri)
-{
-	int x;
-	for (x=23;x>0;x--) {
-		if (pri->pvt[x] && !pri->pvt[x]->owner)
-			return x;
-	}
-	return 0;
-}
-
-static int pri_fixup(struct tor_pri *pri, int channel, q931_call *c)
-{
-	int x;
-	for (x=1;x<24;x++) {
-		if (!pri->pvt[x]) continue;
-		if (pri->pvt[x]->call == c) {
-			/* Found our call */
-			if (channel != x) {
-				if (option_verbose > 2)
-					ast_verbose(VERBOSE_PREFIX_3 "Moving call from channel %d to channel %d\n",
-						x, channel);
-				if (pri->pvt[channel]->owner) {
-					ast_log(LOG_WARNING, "Can't fix up channel from %d to %d because %d is already in use\n",
-						x, channel, channel);
-					return 0;
-				}
-				/* Fix it all up now */
-				pri->pvt[channel]->owner = pri->pvt[x]->owner;
-				pri->pvt[channel]->owner->pvt->pvt = pri->pvt[channel];
-				pri->pvt[channel]->owner->fds[0] = zap_fd(pri->pvt[channel]->z);
-				pri->pvt[channel]->call = pri->pvt[x]->call;
-				
-				/* Free up the old channel, now not in use */
-				pri->pvt[x]->owner = NULL;
-				pri->pvt[x]->call = NULL;
-			}
-			return channel;
-		}
-	}
-	return 0;
-}
-
-static void *pri_dchannel(void *vpri)
-{
-	struct tor_pri *pri = vpri;
-	pri_event *e;
-	fd_set efds;
-	fd_set rfds;
-	int res;
-	int chan;
-	int x;
-	struct ast_channel *c;
-	for(;;) {
-		FD_ZERO(&rfds);
-		FD_ZERO(&efds);
-		FD_SET(pri->fd, &rfds);
-		FD_SET(pri->fd, &efds);
-		res = select(pri->fd + 1, &rfds, NULL, &efds, pri_schedule_next(pri->pri));
-		pthread_mutex_lock(&pri->lock);
-		if (!res) {
-			/* Just a timeout, run the scheduler */
-			pri_schedule_run(pri->pri);
-		} else if (res > -1) {
-			e = pri_check_event(pri->pri);
-			if (e) {
-				if (pri->debug)
-					pri_dump_event(pri->pri, e);
-				switch(e->e) {
-				case PRI_EVENT_DCHAN_UP:
-					if (option_verbose > 1) 
-						ast_verbose(VERBOSE_PREFIX_2 "D-Channel on span %d up\n", pri->span);
-					pri->up = 1;
-					break;
-				case PRI_EVENT_DCHAN_DOWN:
-					if (option_verbose > 1) 
-						ast_verbose(VERBOSE_PREFIX_2 "D-Channel on span %d down\n", pri->span);
-					pri->up = 0;
-					break;
-				case PRI_EVENT_RESTART:
-					chan = e->restart.channel;
-					if (chan > -1) {
-						if ((chan < 1) || (chan > 23) )
-							ast_log(LOG_WARNING, "Restart requested on odd channel number %d on span %d\n", chan, pri->span);
-						else if (!pri->pvt[chan])
-							ast_log(LOG_WARNING, "Restart requested on unconfigured channel %d on span %d\n", chan, pri->span);
-						else {
-							if (option_verbose > 2)
-								ast_verbose(VERBOSE_PREFIX_3 "B-channel %d restarted on span %d\n", 
-									chan, pri->span);
-							/* Force soft hangup if appropriate */
-							if (pri->pvt[chan]->owner)
-								pri->pvt[chan]->owner->softhangup = 1;
-						}
-					} else {
-						if (option_verbose > 2)
-							ast_verbose("Restart on requested on entire span %d\n", pri->span);
-						for (x=1;x<24;x++)
-							if (pri->pvt[chan]->owner)
-								pri->pvt[chan]->owner->softhangup = 1;
-					}
-					break;
-				case PRI_EVENT_RING:
-					chan = e->ring.channel;
-					if ((chan < 1) || (chan > 23)) {
-						ast_log(LOG_WARNING, "Ring requested on odd channel number %d span %d\n", chan, pri->span);
-						chan = 0;
-					} else if (!pri->pvt[chan]) {
-						ast_log(LOG_WARNING, "Ring requested on unconfigured channel %d span %d\n", chan, pri->span);
-						chan = 0;
-					} else if (pri->pvt[chan]->owner) {
-						ast_log(LOG_WARNING, "Ring requested on channel %d already in use on span %d\n", chan, pri->span);
-						chan = 0;
-					}
-					if (!chan && (e->ring.flexible))
-						chan = pri_find_empty_chan(pri);
-					if (chan) {
-						/* Get caller ID */
-						if (pri->pvt[chan]->use_callerid) 
-							strncpy(pri->pvt[chan]->callerid, e->ring.callingnum, sizeof(pri->pvt[chan]->callerid));
-						else
-							strcpy(pri->pvt[chan]->callerid, "");
-						/* Get called number */
-						if (strlen(e->ring.callednum)) {
-							strncpy(pri->pvt[chan]->exten, e->ring.callednum, sizeof(pri->pvt[chan]->exten));
-						} else
-							strcpy(pri->pvt[chan]->exten, "s");
-						/* Make sure extension exists */
-						if (ast_exists_extension(NULL, pri->pvt[chan]->context, pri->pvt[chan]->exten, 1)) {
-							/* Start PBX */
-							pri->pvt[chan]->call = e->ring.call;
-							c = tor_new(pri->pvt[chan], AST_STATE_RING, 1, 0, 0);
-							if (c) {
-								if (option_verbose > 2)
-									ast_verbose(VERBOSE_PREFIX_3 "Accepting call from '%s' to '%s' on channel %d, span %d\n",
-										e->ring.callingnum, pri->pvt[chan]->exten, chan, pri->span);
-								pri_acknowledge(pri->pri, e->ring.call, chan, 0);
-							} else {
-								ast_log(LOG_WARNING, "Unable to start PBX on channel %d, span %d\n", chan, pri->span);
-								pri_release(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
-								pri->pvt[chan]->call = NULL;
-							}
-						} else {
-							if (option_verbose > 2) 
-								ast_verbose(VERBOSE_PREFIX_3 "Extension '%s' in context '%s' does not exist.  Rejecting call on channel %d, span %d\n", 
-									pri->pvt[chan]->exten, pri->pvt[chan]->context, chan, pri->span);
-							pri_release(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
-						}
-					} else 
-						pri_release(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
-					break;
-				case PRI_EVENT_RINGING:
-					chan = e->ringing.channel;
-					if ((chan < 1) || (chan > 23)) {
-						ast_log(LOG_WARNING, "Ringing requested on odd channel number %d span %d\n", chan, pri->span);
-						chan = 0;
-					} else if (!pri->pvt[chan]) {
-						ast_log(LOG_WARNING, "Ringing requested on unconfigured channel %d span %d\n", chan, pri->span);
-						chan = 0;
-					}
-					if (chan) {
-						chan = pri_fixup(pri, chan, e->ringing.call);
-						if (!chan) {
-							ast_log(LOG_WARNING, "Ringing requested on channel %d not in use on span %d\n", e->ringing.channel, pri->span);
-							chan = 0;
-						} else
-							pri->pvt[chan]->needringing[0] =1;
-					}
-					break;				
-				case PRI_EVENT_ANSWER:
-					chan = e->answer.channel;
-					if ((chan < 1) || (chan > 23)) {
-						ast_log(LOG_WARNING, "Answer on odd channel number %d span %d\n", chan, pri->span);
-						chan = 0;
-					} else if (!pri->pvt[chan]) {
-						ast_log(LOG_WARNING, "Answer on unconfigured channel %d span %d\n", chan, pri->span);
-						chan = 0;
-					}
-					if (chan) {
-						chan = pri_fixup(pri, chan, e->ringing.call);
-						if (!chan) {
-							ast_log(LOG_WARNING, "Ring requested on channel %d not in use on span %d\n", chan, pri->span);
-							chan = 0;
-						} else
-							pri->pvt[chan]->needanswer[0] =1;
-					}
-					break;				
-				case PRI_EVENT_HANGUP:
-					chan = e->hangup.channel;
-					if ((chan < 1) || (chan > 23)) {
-						ast_log(LOG_WARNING, "Hangup requested on odd channel number %d span %d\n", chan, pri->span);
-						chan = 0;
-					} else if (!pri->pvt[chan]) {
-						ast_log(LOG_WARNING, "Hanngup requested on unconfigured channel %d span %d\n", chan, pri->span);
-						chan = 0;
-					}
-					if (chan) {
-						chan = pri_fixup(pri, chan, e->hangup.call);
-						if (chan) {
-							if (pri->pvt[chan]->owner) {
-								if (option_verbose > 3) 
-									ast_verbose(VERBOSE_PREFIX_3, "Channel %d, span %d got hangup\n", chan, pri->span);
-								pri->pvt[chan]->owner->softhangup = 1;
-								pri->pvt[chan]->call = NULL;
-							}
-						}
-					}
-					break;
-				case PRI_EVENT_CONFIG_ERR:
-					ast_log(LOG_WARNING, "PRI Error: %s\n", e->err.err);
-					break;
-				default:
-					ast_log(LOG_DEBUG, "Event: %d\n", e->e);
-				}
-			} else {
-				/* Check for an event */
-				x = 0;
-				res = ioctl(pri->fd, TOR_GETEVENT, &x);
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Got event %s (%d) on D-channel for span %d\n", event2str(x), x, pri->span);
-			}
-		} else {
-			if (errno != EINTR) 
-				ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
-		}
-		pthread_mutex_unlock(&pri->lock);
-	}
-	/* Never reached */
-	return NULL;
-}
-
-static int start_pri(struct tor_pri *pri)
-{
-	char filename[80];
-	int res;
-	TOR_PARAMS p;
-	BUFFER_INFO bi;
-	snprintf(filename, sizeof(filename), "/dev/tor/%d", pri->offset + 24);
-	pri->fd = open(filename, O_RDWR, 0600);
-	if (pri->fd < 0) {
-		ast_log(LOG_ERROR, "Unable to open D-channel %s (%s)\n", filename, strerror(errno));
-		return -1;
-	}
-	res = ioctl(pri->fd, TOR_GET_PARAMS, &p);
-	if (res) {
-		close(pri->fd);
-		pri->fd = -1;
-		ast_log(LOG_ERROR, "Unable to get parameters for D-channel %s (%s)\n", filename, strerror(errno));
-		return -1;
-	}
-	if (p.sigtype != TOR_HDLCFCS) {
-		close(pri->fd);
-		pri->fd = -1;
-		ast_log(LOG_ERROR, "D-channel %s is not in HDLC/FCS mode.  See /etc/tormenta.conf\n", filename);
-		return -1;
-	}
-	bi.txbufpolicy = POLICY_IMMEDIATE;
-	bi.rxbufpolicy = POLICY_IMMEDIATE;
-	bi.numbufs = 4;
-	bi.bufsize = 1024;
-	if (ioctl(pri->fd, TOR_SET_BUFINFO, &bi)) {
-		ast_log(LOG_ERROR, "Unable to set appropriate buffering on %s\n", filename);
-		close(pri->fd);
-		pri->fd = -1;
-		return -1;
-	}
-	pri->pri = pri_new(pri->fd, pri->nodetype, pri->switchtype);
-	if (!pri->pri) {
-		close(pri->fd);
-		pri->fd = -1;
-		ast_log(LOG_ERROR, "Unable to create PRI structure\n");
-		return -1;
-	}
-	pri_set_debug(pri->pri, DEFAULT_PRI_DEBUG);
-	if (pthread_create(&pri->master, NULL, pri_dchannel, pri)) {
-		close(pri->fd);
-		pri->fd = -1;
-		ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
-		return -1;
-	}
-	return 0;
-}
-
-static char *complete_span(char *line, char *word, int pos, int state)
-{
-	int span=1;
-	char tmp[50];
-	while(span <= NUM_SPANS) {
-		if (span > state)
-			break;
-		span++;
-	}
-	if (span <= NUM_SPANS) {
-		snprintf(tmp, sizeof(tmp), "%d", span);
-		return strdup(tmp);
-	} else
-		return NULL;
-}
-
-static int handle_pri_debug(int fd, int argc, char *argv[])
-{
-	int span;
-	span = atoi(argv[3]);
-	if ((span < 1) || (span > NUM_SPANS)) {
-		ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[3], 1, NUM_SPANS);
-		return RESULT_SUCCESS;
-	}
-	if (!pris[span-1].pri) {
-		ast_cli(fd, "No PRI running on span %d\n", span);
-		return RESULT_SUCCESS;
-	}
-	pri_set_debug(pris[span-1].pri, PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE);
-	ast_cli(fd, "Enabled debugging on span %d\n", span);
-	return RESULT_SUCCESS;
-}
-
-static int handle_pri_no_debug(int fd, int argc, char *argv[])
-{
-	int span;
-	span = atoi(argv[4]);
-	if ((span < 1) || (span > NUM_SPANS)) {
-		ast_cli(fd, "Invalid span %s.  Should be a number %d to %d\n", argv[4], 1, NUM_SPANS);
-		return RESULT_SUCCESS;
-	}
-	if (!pris[span-1].pri) {
-		ast_cli(fd, "No PRI running on span %d\n", span);
-		return RESULT_SUCCESS;
-	}
-	pri_set_debug(pris[span-1].pri, 0);
-	ast_cli(fd, "Disabled debugging on span %d\n", span);
-	return RESULT_SUCCESS;
-}
-
-
-static char pri_debug_help[] = 
-	"Usage: pri debug span <span>\n"
-	"       Enables debugging on a given PRI span\n";
-	
-static char pri_no_debug_help[] = 
-	"Usage: pri no debug span <span>\n"
-	"       Disables debugging on a given PRI span\n";
-
-static struct ast_cli_entry pri_debug = {
-	{ "pri", "debug", "span", NULL }, handle_pri_debug, "Enables PRI debugging on a span", pri_debug_help, complete_span 
-};
-
-static struct ast_cli_entry pri_no_debug = {
-	{ "pri", "no", "debug", "span", NULL }, handle_pri_no_debug, "Enables PRI debugging on a span", pri_no_debug_help, complete_span };
-
-#endif
-
-int load_module()
-{
-	struct ast_config *cfg;
-	struct ast_variable *v;
-	struct tor_pvt *tmp;
-	char *chan;
-	int start, finish,x;
-#ifdef TORMENTA_PRI
-	int y;
-#endif
-
-	
-#ifdef TORMENTA_PRI
-	memset(pris, 0, sizeof(pris));
-	for (y=0;y<NUM_SPANS;y++)
-		pris[y].fd = -1;
-#endif
-	
-	cfg = ast_load(config);
-
-	/* We *must* have a config file otherwise stop immediately */
-	if (!cfg) {
-		ast_log(LOG_ERROR, "Unable to load config %s\n", config);
-		return -1;
-	}
-	
-
-	if (ast_pthread_mutex_lock(&iflock)) {
-		/* It's a little silly to lock it, but we mind as well just to be sure */
-		ast_log(LOG_ERROR, "Unable to lock interface list???\n");
-		return -1;
-	}
-	v = ast_variable_browse(cfg, "channels");
-	while(v) {
-		/* Create the interface list */
-		if (!strcasecmp(v->name, "channel")) {
-			if (cur_signalling < 0) {
-				ast_log(LOG_ERROR, "Signalling must be specified before any channels are.\n");
-				ast_destroy(cfg);
-				ast_pthread_mutex_unlock(&iflock);
-				unload_module();
-				return -1;
-			}
-			chan = strtok(v->value, ",");
-			while(chan) {
-				if (sscanf(chan, "%d-%d", &start, &finish) == 2) {
-					/* Range */
-				} else if (sscanf(chan, "%d", &start)) {
-					/* Just one */
-					finish = start;
-				} else {
-					ast_log(LOG_ERROR, "Syntax error parsing '%s' at '%s'\n", v->value, chan);
-					ast_destroy(cfg);
-					ast_pthread_mutex_unlock(&iflock);
-					unload_module();
-					return -1;
-				}
-				if (finish < start) {
-					ast_log(LOG_WARNING, "Sillyness: %d < %d\n", start, finish);
-					x = finish;
-					finish = start;
-					start = x;
-				}
-				for (x=start;x<=finish;x++) {
-					tmp = mkif(x, cur_signalling);
-					if (tmp) {
-						tmp->next = iflist;
-						iflist = tmp;
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Registered channel %d, %s signalling\n", x, sig2str(tmp->sig));
-					} else {
-						ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);
-						ast_destroy(cfg);
-						ast_pthread_mutex_unlock(&iflock);
-						unload_module();
-						return -1;
-					}
-				}
-				chan = strtok(NULL, ",");
-			}
-		} else if (!strcasecmp(v->name, "usecallerid")) {
-			use_callerid = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "threewaycalling")) {
-			threewaycalling = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "transfer")) {
-			transfer = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "echocancel")) {
-			echocancel = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "hidecallerid")) {
-			hidecallerid = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "callwaiting")) {
-			callwaiting = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "callwaitingcallerid")) {
-			callwaitingcallerid = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "context")) {
-			strncpy(context, v->value, sizeof(context));
-		} else if (!strcasecmp(v->name, "language")) {
-			strncpy(language, v->value, sizeof(language));
-		} else if (!strcasecmp(v->name, "stripmsd")) {
-			stripmsd = atoi(v->value);
-		} else if (!strcasecmp(v->name, "group")) {
-			cur_group = get_group(v->value);
-		} else if (!strcasecmp(v->name, "immediate")) {
-			immediate = ast_true(v->value);
-		} else if (!strcasecmp(v->name, "rxgain")) {
-			if (sscanf(v->value, "%f", &rxgain) != 1) {
-				ast_log(LOG_WARNING, "Invalid rxgain: %s\n", v->value);
-			}
-		} else if (!strcasecmp(v->name, "txgain")) {
-			if (sscanf(v->value, "%f", &txgain) != 1) {
-				ast_log(LOG_WARNING, "Invalid txgain: %s\n", v->value);
-			}
-		} else if (!strcasecmp(v->name, "callerid")) {
-			if (!strcasecmp(v->value, "asreceived"))
-				strcpy(callerid,"");
-			else
-				strncpy(callerid, v->value, sizeof(callerid));
-		} else if (!strcasecmp(v->name, "ignorepat")) {
-			if (dialpats < AST_MAX_DIAL_PAT - 1) {
-				strncpy(keepdialpat[dialpats], v->value, sizeof(keepdialpat[dialpats]));
-				dialpats++;
-			} else
-				ast_log(LOG_WARNING, "Too many dial patterns, ignoring '%s'\n", v->value);
-		} else if (!strcasecmp(v->name, "signalling")) {
-			if (!strcasecmp(v->value, "em")) {
-				cur_signalling = SIG_EM;
-			} else if (!strcasecmp(v->value, "em_w")) {
-				cur_signalling = SIG_EMWINK;
-			} else if (!strcasecmp(v->value, "fxs_ls")) {
-				cur_signalling = SIG_FXSLS;
-			} else if (!strcasecmp(v->value, "fxs_gs")) {
-				cur_signalling = SIG_FXSGS;
-			} else if (!strcasecmp(v->value, "fxs_ks")) {
-				cur_signalling = SIG_FXSKS;
-			} else if (!strcasecmp(v->value, "fxo_ls")) {
-				cur_signalling = SIG_FXOLS;
-			} else if (!strcasecmp(v->value, "fxo_gs")) {
-				cur_signalling = SIG_FXOGS;
-			} else if (!strcasecmp(v->value, "fxo_ks")) {
-				cur_signalling = SIG_FXOKS;
-			} else if (!strcasecmp(v->value, "featd")) {
-				cur_signalling = SIG_FEATD;
-#ifdef TORMENTA_PRI
-			} else if (!strcasecmp(v->value, "pri_net")) {
-				cur_signalling = SIG_PRI;
-				pritype = PRI_NETWORK;
-			} else if (!strcasecmp(v->value, "pri_cpe")) {
-				cur_signalling = SIG_PRI;
-				pritype = PRI_CPE;
-#endif
-			} else {
-				ast_log(LOG_ERROR, "Unknown signalling method '%s'\n", v->value);
-			}
-#ifdef TORMENTA_PRI
-		} else if (!strcasecmp(v->name, "switchtype")) {
-			if (!strcasecmp(v->value, "national")) 
-				switchtype = PRI_SWITCH_NI2;
-			else if (!strcasecmp(v->value, "dms100"))
-				switchtype = PRI_SWITCH_DMS100;
-			else if (!strcasecmp(v->value, "4ess"))
-				switchtype = PRI_SWITCH_ATT4ESS;
-			else if (!strcasecmp(v->value, "5ess"))
-				switchtype = PRI_SWITCH_LUCENT5E;
-			else {
-				ast_log(LOG_ERROR, "Unknown switchtype '%s'\n", v->value);
-				ast_destroy(cfg);
-				ast_pthread_mutex_unlock(&iflock);
-				unload_module();
-				return -1;
-			}
-#endif		
-		} else
-			ast_log(LOG_DEBUG, "Ignoring %s\n", v->name);
-		v = v->next;
-	}
-	ast_pthread_mutex_unlock(&iflock);
-	/* Make sure we can register our Tor channel type */
-	if (ast_channel_register(type, tdesc, AST_FORMAT_SLINEAR |  AST_FORMAT_ULAW, tor_request)) {
-		ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
-		ast_destroy(cfg);
-		unload_module();
-		return -1;
-	}
-	ast_destroy(cfg);
-#ifdef TORMENTA_PRI
-	for (x=0;x<NUM_SPANS;x++) {
-		for (y=1;y<23;y++) {
-			if (pris[x].chanmask[y]) {
-				pris[x].offset = x * 24;
-				pris[x].span = x + 1;
-				if (start_pri(pris + x)) {
-					ast_log(LOG_ERROR, "Unable to start D-channel on span %d\n", x + 1);
-					return -1;
-				} else if (option_verbose > 1) 
-					ast_verbose(VERBOSE_PREFIX_2 "Starting D-Channel on span %d\n", x + 1);
-				break;
-			}
-		}
-	}
-	ast_cli_register(&pri_debug);
-	ast_cli_register(&pri_no_debug);
-#endif	
-	/* And start the monitor for the first time */
-	restart_monitor();
-	return 0;
-}
-
-int unload_module()
-{
-	struct tor_pvt *p, *pl;
-	/* First, take us out of the channel loop */
-	ast_channel_unregister(type);
-	if (!ast_pthread_mutex_lock(&iflock)) {
-		/* Hangup all interfaces if they have an owner */
-		p = iflist;
-		while(p) {
-			if (p->owner)
-				ast_softhangup(p->owner);
-			p = p->next;
-		}
-		iflist = NULL;
-		ast_pthread_mutex_unlock(&iflock);
-	} else {
-		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
-		return -1;
-	}
-	if (!ast_pthread_mutex_lock(&monlock)) {
-		if (monitor_thread) {
-			pthread_cancel(monitor_thread);
-			pthread_kill(monitor_thread, SIGURG);
-			pthread_join(monitor_thread, NULL);
-		}
-		monitor_thread = -2;
-		ast_pthread_mutex_unlock(&monlock);
-	} else {
-		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
-		return -1;
-	}
-
-	if (!ast_pthread_mutex_lock(&iflock)) {
-		/* Destroy all the interfaces and free their memory */
-		p = iflist;
-		while(p) {
-			/* Free any callerid */
-			if (p->cidspill)
-				free(p->cidspill);
-			/* Close the zapata thingy */
-			if (p->z)
-				zap_close(p->z);
-			pl = p;
-			p = p->next;
-			/* Free associated memory */
-			free(pl);
-		}
-		iflist = NULL;
-		ast_pthread_mutex_unlock(&iflock);
-	} else {
-		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
-		return -1;
-	}
-		
-	return 0;
-}
-int usecount()
-{
-	int res;
-	ast_pthread_mutex_lock(&usecnt_lock);
-	res = usecnt;
-	ast_pthread_mutex_unlock(&usecnt_lock);
-	return res;
-}
-
-char *description()
-{
-	return desc;
-}
-
-char *key()
-{
-	return ASTERISK_GPL_KEY;
-}