diff -u --recursive --new-file asterisk-0.5.0/channels/chan_iax2.c.unload asterisk-0.5.0/channels/chan_iax2.c
--- asterisk-0.5.0/channels/chan_iax2.c.unload	Thu Oct 30 00:52:42 2003
+++ asterisk-0.5.0/channels/chan_iax2.c	Thu Oct 30 00:52:42 2003
@@ -5753,6 +5753,10 @@
 	ast_cli_unregister(&cli_set_jitter);
 	ast_cli_unregister(&cli_show_stats);
 	ast_cli_unregister(&cli_show_cache);
+	ast_cli_unregister(&cli_show_registry);
+	ast_cli_unregister(&cli_debug);
+	ast_cli_unregister(&cli_trunk_debug);
+	ast_cli_unregister(&cli_no_debug);
 	ast_unregister_switch(&iax2_switch);
 	delete_users();
 	return 0;
diff -u --recursive --new-file asterisk-0.5.0/channels/chan_zap.c.unload asterisk-0.5.0/channels/chan_zap.c
--- asterisk-0.5.0/channels/chan_zap.c.unload	Thu Oct 30 01:05:05 2003
+++ asterisk-0.5.0/channels/chan_zap.c	Thu Oct 30 01:07:04 2003
@@ -6946,6 +6946,15 @@
 	/* First, take us out of the channel loop */
 	ast_channel_unregister(type);
 	ast_channel_unregister(typecompat);
+#ifdef ZAPATA_PRI
+	ast_cli_unregister(&pri_debug);
+	ast_cli_unregister(&pri_no_debug);
+	ast_cli_unregister(&pri_really_debug);
+#endif	
+#ifdef ZAPATA_R2
+	ast_cli_unregister(&r2_debug);
+	ast_cli_unregister(&r2_no_debug);
+#endif	
 	ast_cli_unregister(&cli_show_channels);
 	ast_cli_unregister(&cli_show_channel);
 	ast_cli_unregister(&cli_destroy_channel);
diff -u --recursive --new-file asterisk-0.5.0/channels/chan_zap_old.c.unload asterisk-0.5.0/channels/chan_zap_old.c
--- asterisk-0.5.0/channels/chan_zap_old.c.unload	Thu Oct 30 01:07:12 2003
+++ asterisk-0.5.0/channels/chan_zap_old.c	Thu Oct 30 01:07:51 2003
@@ -6820,6 +6820,15 @@
 	/* First, take us out of the channel loop */
 	ast_channel_unregister(type);
 	ast_channel_unregister(typecompat);
+#ifdef ZAPATA_PRI
+	ast_cli_unregister(&pri_debug);
+	ast_cli_unregister(&pri_no_debug);
+	ast_cli_unregister(&pri_really_debug);
+#endif	
+#ifdef ZAPATA_R2
+	ast_cli_unregister(&r2_debug);
+	ast_cli_unregister(&r2_no_debug);
+#endif	
 	ast_cli_unregister(&cli_show_channels);
 	ast_cli_unregister(&cli_show_channel);
 	ast_cli_unregister(&cli_destroy_channel);
diff -u --recursive --new-file asterisk-0.5.0/channels/chan_sip.c.unload asterisk-0.5.0/channels/chan_sip.c
--- asterisk-0.5.0/channels/chan_sip.c.unload	Thu Oct 30 01:09:14 2003
+++ asterisk-0.5.0/channels/chan_sip.c	Thu Oct 30 01:10:16 2003
@@ -6114,6 +6114,14 @@
 	
 	/* First, take us out of the channel loop */
 	ast_channel_unregister(type);
+	ast_cli_unregister(&cli_show_users);
+	ast_cli_unregister(&cli_show_channels);
+	ast_cli_unregister(&cli_show_channel);
+	ast_cli_unregister(&cli_show_peers);
+	ast_cli_unregister(&cli_show_registry);
+	ast_cli_unregister(&cli_debug);
+	ast_cli_unregister(&cli_no_debug);
+	ast_cli_unregister(&cli_inuse_show);
 	if (!ast_mutex_lock(&iflock)) {
 		/* Hangup all interfaces if they have an owner */
 		p = iflist;
diff -u --recursive --new-file asterisk-0.5.0/channels/chan_mgcp.c.unload asterisk-0.5.0/channels/chan_mgcp.c
diff -u --recursive --new-file asterisk-0.5.0/channels/chan_iax.c.unload asterisk-0.5.0/channels/chan_iax.c
--- asterisk-0.5.0/channels/chan_iax.c.unload	Thu Oct 30 01:12:04 2003
+++ asterisk-0.5.0/channels/chan_iax.c	Thu Oct 30 01:12:37 2003
@@ -5184,6 +5184,9 @@
 	ast_cli_unregister(&cli_set_jitter);
 	ast_cli_unregister(&cli_show_stats);
 	ast_cli_unregister(&cli_show_cache);
+	ast_cli_unregister(&cli_show_registry);
+	ast_cli_unregister(&cli_debug);
+	ast_cli_unregister(&cli_no_debug);
 	ast_unregister_switch(&iax_switch);
 	delete_users();
 	return 0;
diff -u --recursive --new-file asterisk-0.5.0/channels/chan_h323.c.unload asterisk-0.5.0/channels/chan_h323.c
--- asterisk-0.5.0/channels/chan_h323.c.unload	Thu Oct 30 01:39:32 2003
+++ asterisk-0.5.0/channels/chan_h323.c	Thu Oct 30 01:43:41 2003
@@ -1823,6 +1823,19 @@
 		ast_log(LOG_WARNING, "Unable to lock the interface list\n");
 		return -1;
 	}
+
+	if (!ast_mutex_lock(&monlock)) {
+		if (monitor_thread) {
+			pthread_cancel(monitor_thread);
+			pthread_kill(monitor_thread, SIGURG);
+			pthread_join(monitor_thread, NULL);
+		}
+		monitor_thread = (pthread_t) -2;
+		ast_mutex_unlock(&monlock);
+	} else {
+		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
+		return -1;
+	}
 		
 	if (!ast_mutex_lock(&iflock)) {
 		/* destroy all the interfaces and free their memory */
diff -u --recursive --new-file asterisk-0.5.0/loader.c.unload asterisk-0.5.0/loader.c
--- asterisk-0.5.0/loader.c.unload	Wed Oct 29 23:47:00 2003
+++ asterisk-0.5.0/loader.c	Thu Oct 30 01:15:37 2003
@@ -98,6 +98,8 @@
 
 static struct module *module_list=NULL;
 
+static int atexit_registered = 0;
+
 int ast_unload_resource(char *resource_name, int force)
 {
 	struct module *m, *ml = NULL;
@@ -140,6 +142,65 @@
 	return res;
 }
 
+static void ast_unload_modules(void)
+{
+	struct module *m, *ml = NULL;
+	int res = -1;
+	int force = 0;
+	char tmp[80];
+	if (ast_mutex_lock(&modlock))
+		ast_log(LOG_WARNING, "Failed to lock\n");
+	m = module_list;
+	while(m) {
+		if ((res = m->usecount()) > 0)  {
+			if (force) 
+				ast_log(LOG_WARNING, "Warning:  Forcing removal of module %s with use count %d\n", m->resource, res);
+			else {
+//				ast_log(LOG_WARNING, "Soft unload failed, '%s' has use count %d\n", m->resource, res);
+				m = m->next;
+				continue;
+//				ast_mutex_unlock(&modlock);
+//				return -1;
+			}
+		}
+		if(m->unload_module)
+		{
+			if (option_verbose > 2) 
+				ast_verbose(VERBOSE_PREFIX_3 "=> Unloading module '%s' (%s)\n", m->resource, term_color(tmp, m->description(), COLOR_BROWN, COLOR_BLACK, sizeof(tmp)));
+			res = m->unload_module();
+		}
+		else
+			res = 1;
+		if (res) {
+			ast_log(LOG_WARNING, "Firm unload failed for %s\n", m->resource);
+			if (force <= AST_FORCE_FIRM) {
+				m = m->next;
+				continue;
+//				ast_mutex_unlock(&modlock);
+//				return -1;
+			} else
+				ast_log(LOG_WARNING, "** Dangerous **: Unloading resource %s anyway, at user request\n", m->resource);
+		}
+		if (ml)
+			ml->next = m->next;
+		else
+			module_list = m->next;
+		dlclose(m->lib);
+		free(m);
+
+		if(ml)
+			m = ml->next;
+		else
+			m = module_list;
+
+//		ml = m;
+//		m = m->next;
+	}
+	ast_mutex_unlock(&modlock);
+	ast_update_use_count();
+//	return res;
+}
+
 void ast_module_reload(void)
 {
 	struct module *m;
@@ -302,6 +363,11 @@
 		ast_unload_resource(resource_name, 0);
 		return -1;
 	}
+	if(!atexit_registered)
+	{
+		ast_register_atexit(ast_unload_modules);
+		atexit_registered = 1;
+	}
 	ast_update_use_count();
 	return 0;
 }	
