From d5e6ab1569aa12c522107bb721ced1af38a68f2b Mon Sep 17 00:00:00 2001
From: Mark Spencer <markster@digium.com>
Date: Mon, 27 Dec 1999 19:20:20 +0000
Subject: [PATCH] Version 0.1.2 from FTP

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@150 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 channels/iax.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
 cli.c          | 64 ++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 116 insertions(+), 12 deletions(-)
 create mode 100755 channels/iax.h

diff --git a/channels/iax.h b/channels/iax.h
new file mode 100755
index 0000000000..93335da8d4
--- /dev/null
+++ b/channels/iax.h
@@ -0,0 +1,64 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Implementation of Inter-Asterisk eXchange
+ * 
+ * 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
+ */
+ 
+#ifndef _ASTERISK_IAX_H
+#define _ASTERISK_IAX_H
+
+/* Max version of IAX protocol we support */
+#define AST_IAX_PROTO_VERSION 1
+
+#define AST_IAX_MAX_CALLS 32768
+
+#define AST_FLAG_FULL		0x8000
+
+#define AST_FLAG_SC_LOG		0x80
+
+#define AST_MAX_SHIFT		0x1F
+
+/* Subclass for AST_FRAME_IAX */
+#define AST_IAX_COMMAND_NEW		1
+#define AST_IAX_COMMAND_PING	2
+#define AST_IAX_COMMAND_PONG	3
+#define AST_IAX_COMMAND_ACK		4
+#define AST_IAX_COMMAND_HANGUP	5
+#define AST_IAX_COMMAND_REJECT	6
+#define AST_IAX_COMMAND_ACCEPT	7
+#define AST_IAX_COMMAND_AUTHREQ	8
+#define AST_IAX_COMMAND_AUTHREP	9
+#define AST_IAX_COMMAND_INVAL	10
+#define AST_IAX_COMMAND_LAGRQ	11
+#define AST_IAX_COMMAND_LAGRP	12
+
+#define AST_DEFAULT_IAX_PORTNO	5036
+
+/* Full frames are always delivered reliably */
+struct ast_iax_full_hdr {
+	short callno;			/* Source call number -- high bit must be 1 */
+	short dcallno;			/* Destination call number */
+	unsigned int ts;		/* 32-bit timestamp in milliseconds */
+	unsigned short seqno;	/* Packet number */
+	char type;				/* Frame type */
+	unsigned char csub;		/* Compressed subclass */
+	char data[0];
+};
+
+/* Mini header is used only for voice frames -- delivered unreliably */
+struct ast_iax_mini_hdr {
+	short callno;			/* Source call number -- high bit must be 0 */
+	unsigned short ts;		/* 16-bit Timestamp (high 32 bits from last ast_iax_full_hdr) */
+							/* Frametype implicitly VOICE_FRAME */
+							/* subclass implicit from last ast_iax_full_hdr */
+	char data[0];
+};
+
+#endif
diff --git a/cli.c b/cli.c
index 5d7f880fa3..fb8d0731e2 100755
--- a/cli.c
+++ b/cli.c
@@ -233,11 +233,11 @@ static int handle_help(int fd, int argc, char *argv[]);
 
 static struct ast_cli_entry builtins[] = {
 	/* Keep alphabetized */
-	{ { "show" , "channels", NULL }, handle_chanlist, "Display information on channels", chanlist_help },
 	{ { "help", NULL }, handle_help, "Display help list, or specific help on a command", help_help },
 	{ { "load", NULL }, handle_load, "Load a dynamic module by name", load_help, complete_fn },
-    { { "show", "modules", NULL }, handle_modlist, "List modules and info", modlist_help },
 	{ { "show", "channel", NULL }, handle_showchan, "Display information on a specific channel", showchan_help, complete_ch },
+	{ { "show", "channels", NULL }, handle_chanlist, "Display information on channels", chanlist_help },
+    { { "show", "modules", NULL }, handle_modlist, "List modules and info", modlist_help },
 	{ { "unload", NULL }, handle_unload, "Unload a dynamic module by name", unload_help, complete_fn },
 	{ { NULL }, NULL, NULL, NULL }
 };
@@ -271,7 +271,7 @@ static struct ast_cli_entry *find_cli(char *cmds[], int exact)
 	}
 	for (e=helpers;e;e=e->next) {
 		match = 1;
-		for (y=0;match && e->cmda[y]; y++) {
+		for (y=0;match && cmds[y]; y++) {
 			if (!e->cmda[y] && !exact)
 				break;
 			if (!e->cmda[y] || strcasecmp(e->cmda[y], cmds[y]))
@@ -297,6 +297,16 @@ static void join(char *s, int len, char *w[])
 	}
 }
 
+static void join2(char *s, int len, char *w[])
+{
+	int x;
+	/* Join words into a string */
+	strcpy(s, "");
+	for (x=0;w[x];x++) {
+		strncat(s, w[x], len - strlen(s));
+	}
+}
+
 static char *find_best(char *argv[])
 {
 	static char cmdline[80];
@@ -314,12 +324,35 @@ static char *find_best(char *argv[])
 	return cmdline;
 }
 
+int ast_cli_unregister(struct ast_cli_entry *e)
+{
+	struct ast_cli_entry *cur, *l=NULL;
+	pthread_mutex_lock(&clilock);
+	cur = helpers;
+	while(cur) {
+		if (e == cur) {
+			/* Rewrite */
+			if (l)
+				l->next = e->next;
+			else
+				helpers = e->next;
+			e->next = NULL;
+			break;
+		}
+		l = cur;
+		cur = cur->next;
+	}
+	pthread_mutex_unlock(&clilock);
+	return 0;
+}
+
 int ast_cli_register(struct ast_cli_entry *e)
 {
 	struct ast_cli_entry *cur, *l=NULL;
 	char fulle[80], fulltst[80];
+	static int len;
 	pthread_mutex_lock(&clilock);
-	join(fulle, sizeof(fulle), e->cmda);
+	join2(fulle, sizeof(fulle), e->cmda);
 	if (find_cli(e->cmda, -1)) {
 		ast_log(LOG_WARNING, "Command '%s' already registered (or something close enough)\n", fulle);
 		pthread_mutex_unlock(&clilock);
@@ -327,11 +360,18 @@ int ast_cli_register(struct ast_cli_entry *e)
 	}
 	cur = helpers;
 	while(cur) {
-		join(fulltst, sizeof(fulltst), cur->cmda);
-		if (strcmp(fulle, fulltst) > 0) {
-			/* Put it here */
-			e->next = cur->next;
-			cur->next = e;
+		join2(fulltst, sizeof(fulltst), cur->cmda);
+		len = strlen(fulltst);
+		if (strlen(fulle) < len)
+			len = strlen(fulle);
+		if (strncasecmp(fulle, fulltst, len) < 0) {
+			if (l) {
+				e->next = l->next;
+				l->next = e;
+			} else {
+				e->next = helpers;
+				helpers = e;
+			}
 			break;
 		}
 		l = cur;
@@ -364,7 +404,7 @@ static int help_workhorse(int fd, char *match[])
 			join(fullcmd2, sizeof(fullcmd2), e2->cmda);
 		if (e1->cmda[0])
 			join(fullcmd1, sizeof(fullcmd1), e1->cmda);
-		if (!e1->cmda || 
+		if (!e1->cmda[0] || 
 				(e2 && (strcmp(fullcmd2, fullcmd1) < 0))) {
 			/* Use e2 */
 			e = e2;
@@ -382,7 +422,7 @@ static int help_workhorse(int fd, char *match[])
 				continue;
 			}
 		}
-		ast_cli(fd, "%15s   %s\n", fullcmd, e->summary);
+		ast_cli(fd, "%20.20s   %s\n", fullcmd, e->summary);
 	}
 	return 0;
 }
@@ -560,7 +600,7 @@ int ast_cli_command(int fd, char *s)
 				default:
 				}
 			} else 
-				ast_cli(fd, "No such command '%s'\n", find_best(argv));
+				ast_cli(fd, "No such command '%s' (type 'help' for help)\n", find_best(argv));
 			pthread_mutex_unlock(&clilock);
 		}
 		free(dup);
-- 
GitLab