diff --git a/asterisk.c b/asterisk.c
index 56dcc0d09a06e9b1def9326b3e45aa6ce49d97f4..449c1ddcdeeff6d80a2d3ab3ea8722ca4ef0c018 100755
--- a/asterisk.c
+++ b/asterisk.c
@@ -48,6 +48,10 @@
 #include "asterisk.h"
 #include <asterisk/config.h>
 
+#if  defined(__FreeBSD__)
+#include <netdb.h>
+#endif
+
 #define AST_MAX_CONNECTS 128
 #define NUM_MSGS 64
 
@@ -1675,13 +1679,133 @@ int main(int argc, char *argv[])
 	return 0;
 }
 
+
+#if  defined(__FreeBSD__)
+
+/* duh? ERANGE value copied from web... */
+#define ERANGE 34
+#undef gethostbyname
+
+int gethostbyname_r (const char *name,
+		     struct hostent *ret,
+		     char *buf,
+		     size_t buflen,
+		     struct hostent **result,
+		     int *h_errnop);
+
+int gethostbyname_r (const char *name,
+		     struct hostent *ret,
+		     char *buf,
+		     size_t buflen,
+		     struct hostent **result,
+		     int *h_errnop) {
+
+  int hsave;
+  struct hostent *ph;
+  static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER;
+  pthread_mutex_lock(&__mutex); /* begin critical area */
+  hsave = h_errno;
+
+  ph = gethostbyname(name);
+  *h_errnop = h_errno; /* copy h_errno to *h_herrnop */
+  if (ph == NULL) {
+    *result = NULL;
+  } else {
+    char **p, **q;
+    char *pbuf;
+    int nbytes=0;
+    int naddr=0, naliases=0;
+    /* determine if we have enough space in buf */
+
+    /* count how many addresses */
+    for (p = ph->h_addr_list; *p != 0; p++) {
+      nbytes += ph->h_length; /* addresses */
+      nbytes += sizeof(*p); /* pointers */
+      naddr++;
+    }
+    nbytes += sizeof(*p); /* one more for the terminating NULL */
+
+    /* count how many aliases, and total length of strings */
+
+    for (p = ph->h_aliases; *p != 0; p++) {
+      nbytes += (strlen(*p)+1); /* aliases */
+      nbytes += sizeof(*p);  /* pointers */
+      naliases++;
+    }
+    nbytes += sizeof(*p); /* one more for the terminating NULL */
+
+    /* here nbytes is the number of bytes required in buffer */
+    /* as a terminator must be there, the minimum value is ph->h_length */
+    if(nbytes > buflen) {
+      *result = NULL;
+      pthread_mutex_unlock(&__mutex); /* end critical area */
+      return ERANGE; /* not enough space in buf!! */
+    }
+
+    /* There is enough space. Now we need to do a deep copy! */
+    /* Allocation in buffer:
+       from [0] to [(naddr-1) * sizeof(*p)]:
+       pointers to addresses
+       at [naddr * sizeof(*p)]:
+       NULL
+       from [(naddr+1) * sizeof(*p)] to [(naddr+naliases) * sizeof(*p)] :
+       pointers to aliases
+       at [(naddr+naliases+1) * sizeof(*p)]:
+       NULL
+       then naddr addresses (fixed length), and naliases aliases (asciiz).
+    */
+
+    *ret = *ph;   /* copy whole structure (not its address!) */
+
+    /* copy addresses */
+    q = (char **)buf; /* pointer to pointers area (type: char **) */
+    ret->h_addr_list = q; /* update pointer to address list */
+    pbuf = buf + ((naddr+naliases+2)*sizeof(*p)); /* skip that area */
+    for (p = ph->h_addr_list; *p != 0; p++) {
+      memcpy(pbuf, *p, ph->h_length); /* copy address bytes */
+      *q++ = pbuf; /* the pointer is the one inside buf... */
+      pbuf += ph->h_length; /* advance pbuf */
+    }
+    *q++ = NULL; /* address list terminator */
+
+    /* copy aliases */
+
+    ret->h_aliases = q; /* update pointer to aliases list */
+    for (p = ph->h_aliases; *p != 0; p++) {
+      strcpy(pbuf, *p); /* copy alias strings */
+      *q++ = pbuf; /* the pointer is the one inside buf... */
+      pbuf += strlen(*p); /* advance pbuf */
+      *pbuf++ = 0; /* string terminator */
+    }
+    *q++ = NULL; /* terminator */
+
+    strcpy(pbuf, ph->h_name); /* copy alias strings */
+    ret->h_name = pbuf;
+    pbuf += strlen(ph->h_name); /* advance pbuf */
+    *pbuf++ = 0; /* string terminator */
+
+    *result = ret;  /* and let *result point to structure */
+
+  }
+  h_errno = hsave;  /* restore h_errno */
+
+  pthread_mutex_unlock(&__mutex); /* end critical area */
+
+  return (*result == NULL);
+
+}
+
+
+#endif
+
 struct hostent *ast_gethostbyname(const char *host, struct ast_hostent *hp)
 {
 	int res;
 	int herrno;
 	struct hostent *result = NULL;
-	/* XXX Does BSD do this differently? XXX */
+
 	res = gethostbyname_r(host, &hp->hp, hp->buf, sizeof(hp->buf), &result, &herrno);
+
 	if (res)
 		return NULL;
 	return &hp->hp;
diff --git a/channels/chan_zap.c b/channels/chan_zap.c
index 0752649b163f9581572017e13a465e88c9a110f2..d68847f5605ba0e60b1f385ba2d4740485da4ad9 100755
--- a/channels/chan_zap.c
+++ b/channels/chan_zap.c
@@ -4087,11 +4087,6 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
 			ast_log(LOG_WARNING, "Channel %d already has a %s call\n", i->channel,subnames[index]);
 		}
 		i->subs[index].owner = tmp;
-		ast_setstate(tmp, state);
-		ast_mutex_lock(&usecnt_lock);
-		usecnt++;
-		ast_mutex_unlock(&usecnt_lock);
-		ast_update_use_count();
 		strncpy(tmp->context, i->context, sizeof(tmp->context)-1);
 		/* Copy call forward info */
 		strncpy(tmp->call_forward, i->call_forward, sizeof(tmp->call_forward));
@@ -4124,6 +4119,11 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int
 		i->fake_event = 0;
 		/* Assure there is no confmute on this channel */
 		zt_confmute(i, 0);
+		ast_setstate(tmp, state);
+		ast_mutex_lock(&usecnt_lock);
+		usecnt++;
+		ast_mutex_unlock(&usecnt_lock);
+		ast_update_use_count();
 		if (startpbx) {
 			if (ast_pbx_start(tmp)) {
 				ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);