[Pkg-privacy-commits] [irssi-plugin-otr] 129/267: Refactor the command subsystem

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 12:41:35 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch debian
in repository irssi-plugin-otr.

commit 5402ee97c9461efef52fdbcf496a5651e6a0d6ba
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Tue Nov 13 11:01:15 2012 -0500

    Refactor the command subsystem
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/cmd.c    | 147 +++++++++++++++++++++++++----------------------------------
 src/cmd.h    |   9 ++--
 src/module.c |  30 ++++++------
 src/otr.c    |   8 ++--
 src/otr.h    |  10 ++--
 src/utils.c  | 131 ++++++++++++++++++++++++++++++++++++++++------------
 src/utils.h  |   4 +-
 7 files changed, 195 insertions(+), 144 deletions(-)

diff --git a/src/cmd.c b/src/cmd.c
index ccb3a48..045c42b 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -18,6 +18,8 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
  */
 
+#include <assert.h>
+
 #include "cmd.h"
 #include "key.h"
 
@@ -25,8 +27,7 @@
  * /otr debug
  */
 static void _cmd_debug(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	debug = !debug;
 	if (debug) {
@@ -40,8 +41,7 @@ static void _cmd_debug(struct otr_user_state *ustate, SERVER_REC *irssi,
  * /otr version 
  */
 static void _cmd_version(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	IRSSI_INFO(NULL, NULL, "OTR module version: " VERSION);
 }
@@ -49,8 +49,8 @@ static void _cmd_version(struct otr_user_state *ustate, SERVER_REC *irssi,
 /*
  * /otr help 
  */
-static void _cmd_help(struct otr_user_state *ustate, SERVER_REC *irssi, int argc, char *argv[],
-		char *argv_eol[], char *target, const char *orig_args)
+static void _cmd_help(struct otr_user_state *ustate, SERVER_REC *irssi,
+		const char *target, const void *data)
 {
 	IRSSI_INFO(NULL, NULL, "%s", otr_help);
 }
@@ -59,8 +59,7 @@ static void _cmd_help(struct otr_user_state *ustate, SERVER_REC *irssi, int argc
  * /otr finish 
  */
 static void _cmd_finish(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	if (!irssi || !target) {
 		IRSSI_WARN(irssi, target,
@@ -79,8 +78,7 @@ end:
  * /otr trust
  */
 static void _cmd_trust(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	if (!irssi || !target) {
 		IRSSI_WARN(irssi, target,
@@ -99,8 +97,7 @@ end:
  * /otr authabort
  */
 static void _cmd_authabort(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	if (!irssi || !target) {
 		IRSSI_WARN(irssi, target,
@@ -119,9 +116,13 @@ end:
  * /otr genkey
  */
 static void _cmd_genkey(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
+	int argc;
+	char **argv;
+
+	utils_explode_args(data, &argv, &argc);
+
 	if (argc) {
 		if (strncmp(argv[0], "abort", strlen("abort")) == 0) {
 			key_generation_abort(ustate, FALSE);
@@ -135,73 +136,60 @@ static void _cmd_genkey(struct otr_user_state *ustate, SERVER_REC *irssi,
 		IRSSI_INFO(NULL, NULL, "I need an account name. "
 				"Try something like /otr genkey mynick at irc.server.net");
 	}
-}
-
-/*
- * Generic internal function for /otr auth command.
- */
-static void _auth(struct otr_user_state *ustate, SERVER_REC *irssi, int argc,
-		char *argv[], char *argv_eol[], char *target, int qanda,
-		const char *orig_args)
-{
-	int ret;
-	char *question = NULL, *secret = NULL;
-
-	/* have question? */
-	if (qanda) {
-		ret = utils_io_extract_smp(orig_args, &question, &secret);
-		if (ret < 0) {
-			IRSSI_NOTICE(irssi, target, "Usage: %9/otr authq [QUESTION] "
-					"SECRET%9");
-			goto end;
-		}
-	} else {
-		secret = argv_eol[0];
-	}
-
-	otr_auth(irssi, target, question, secret);
 
-	free(question);
-	if (qanda) {
-		free(secret);
-	}
-
-end:
-	return;
+	utils_free_args(&argv, argc);
 }
 
 /*
  * /otr authq (Authentication with a question)
  */
 static void _cmd_authq(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
+	int argc, ret;
+	char **argv, *question = NULL, *secret = NULL;
+
+	utils_explode_args(data, &argv, &argc);
+
 	if (argc == 0) {
 		IRSSI_NOTICE(irssi, target, "Huh... I need a question here Bob.");
 		goto end;
 	}
 
-	_auth(ustate, irssi, argc, argv, argv_eol, target, TRUE, orig_args);
+	ret = utils_io_extract_smp(data, &question, &secret);
+	if (ret < 0) {
+		IRSSI_NOTICE(irssi, target, "Usage: %9/otr authq [QUESTION] "
+				"SECRET%9");
+		goto end;
+	}
+
+	otr_auth(irssi, target, question, secret);
 
 end:
+	utils_free_args(&argv, argc);
 	return;
 }
 
 /*
  * /otr auth
  */
-static void _cmd_auth(struct otr_user_state *ustate, SERVER_REC *irssi, int argc,
-		char *argv[], char *argv_eol[], char *target, const char *orig_args)
+static void _cmd_auth(struct otr_user_state *ustate, SERVER_REC *irssi,
+		const char *target, const void *data)
 {
+	int argc;
+	char **argv;
+
+	utils_explode_args(data, &argv, &argc);
+
 	if (argc == 0) {
 		IRSSI_NOTICE(irssi, target, "Huh... I need a secret here James.");
 		goto end;
 	}
 
-	_auth(ustate, irssi, argc, argv, argv_eol, target, FALSE, orig_args);
+	otr_auth(irssi, target, NULL, argv[1]);
 
 end:
+	utils_free_args(&argv, argc);
 	return;
 }
 
@@ -209,8 +197,7 @@ end:
  * /otr contexts
  */
 static void _cmd_contexts(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	struct ctxlist_ *ctxlist = otr_contexts(ustate), *ctxnext = ctxlist;
 	struct fplist_ *fplist, *fpnext;
@@ -247,8 +234,7 @@ end:
 }
 
 static void _cmd_init(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
 	char *msg;
 	ConnContext *ctx;
@@ -278,16 +264,18 @@ end:
 }
 
 static void _cmd_forget(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
+	int argc;
+	char **argv;
 	char str_fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN], *fp = NULL;
 
+	utils_explode_args(data, &argv, &argc);
+
 	if (argc == 5) {
 		utils_hash_parts_to_readable_hash((const char **) argv, str_fp);
 		fp = str_fp;
-	} else if (!irssi || (irssi && argc != 0 &&
-				(argc == 1 && argv[0] != NULL))) {
+	} else if (!irssi || (irssi && argc != 0)) {
 		/* If no IRSSI or some arguments (not 5), bad command. */
 		IRSSI_NOTICE(irssi, target, "Usage %9/otr forget [FP]%9 "
 				"where FP is the five part of the fingerprint listed by "
@@ -300,20 +288,23 @@ static void _cmd_forget(struct otr_user_state *ustate, SERVER_REC *irssi,
 	otr_forget(irssi, target, fp, ustate);
 
 error:
+	utils_free_args(&argv, argc);
 	return;
 }
 
 static void _cmd_distrust(struct otr_user_state *ustate, SERVER_REC *irssi,
-		int argc, char *argv[], char *argv_eol[], char *target,
-		const char *orig_args)
+		const char *target, const void *data)
 {
+	int argc;
+	char **argv;
 	char str_fp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN], *fp = NULL;
 
+	utils_explode_args(data, &argv, &argc);
+
 	if (argc == 5) {
 		utils_hash_parts_to_readable_hash((const char **) argv, str_fp);
 		fp = str_fp;
-	} else if (!irssi || (irssi && argc != 0 &&
-				(argc == 1 && argv[0] != NULL))) {
+	} else if (!irssi || (irssi && argc != 0)) {
 		/* If no IRSSI or some arguments (not 5), bad command. */
 		IRSSI_NOTICE(irssi, target, "Usage %9/otr distrust [FP]%9 "
 				"where FP is the five part of the fingerprint listed by "
@@ -326,6 +317,7 @@ static void _cmd_distrust(struct otr_user_state *ustate, SERVER_REC *irssi,
 	otr_distrust(irssi, target, fp, ustate);
 
 error:
+	utils_free_args(&argv, argc);
 	return;
 }
 
@@ -352,33 +344,18 @@ static struct irssi_commands cmds[] = {
  *
  * Return TRUE if command exist and is executed else FALSE.
  */
-int cmd_generic(struct otr_user_state *ustate, SERVER_REC *irssi, int argc,
-		char *argv[], char *argv_eol[], char *target, const char *orig_args)
+void cmd_generic(struct otr_user_state *ustate, SERVER_REC *irssi,
+		const char *target, char *cmd, const void *data)
 {
-	char *cmd;
 	struct irssi_commands *commands = cmds;
 
-	if (!argc) {
-		IRSSI_INFO(NULL, NULL, "Alive");
-		goto done;
-	}
-
-	cmd = argv[0];
-
-	argv++;
-	argv_eol++;
-	argc--;
-
 	do {
 		if (strcmp(commands->name, cmd) == 0) {
-			commands->func(ustate, irssi, argc, argv, argv_eol, target,
-					orig_args);
-			goto done;
+			commands->func(ustate, irssi, target, data);
+			goto end;
 		}
 	} while ((++commands)->name);
 
-	return FALSE;
-
-done:
-	return TRUE;
+end:
+	return;
 }
diff --git a/src/cmd.h b/src/cmd.h
index d331693..3180017 100644
--- a/src/cmd.h
+++ b/src/cmd.h
@@ -25,12 +25,11 @@
 
 struct irssi_commands {
 	const char *name;
-	void (*func)(struct otr_user_state *ioustate, SERVER_REC *irssi, int argc,
-			char *argv[], char *argv_eol[], char *target,
-			const char *orig_args);
+	void (*func)(struct otr_user_state *ustate, SERVER_REC *irssi,
+			const char *target, const void *data);
 };
 
-int cmd_generic(struct otr_user_state *ioustate, SERVER_REC *irssi, int argc,
-		char *argv[], char *argv_eol[], char *target, const char *orig_args);
+void cmd_generic(struct otr_user_state *ustate, SERVER_REC *irssi,
+		const char *target, char *cmd, const void *data);
 
 #endif /* IRSSI_OTR_CMD_H */
diff --git a/src/module.c b/src/module.c
index 2e56521..161e719 100644
--- a/src/module.c
+++ b/src/module.c
@@ -19,6 +19,7 @@
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA
  */
 
+#include <assert.h>
 #include <glib.h>
 #include <glib/gprintf.h>
 #include <glib/gstdio.h>
@@ -133,31 +134,32 @@ static void sig_query_destroyed(QUERY_REC *query)
  */
 static void cmd_otr(const char *data, void *server, WI_ITEM_REC *item)
 {
-	int argc;
-	char **argv, **argv_eol;
-	QUERY_REC *query = QUERY(item);
+	char *cmd = NULL;
+	QUERY_REC *query;
+
+	query = QUERY(item);
 
 	if (*data == '\0') {
 		IRSSI_INFO(NULL, NULL, "Alive!");
 		goto end;
 	}
 
-	utils_io_explode_args(data, &argv, &argv_eol, &argc);
+	utils_extract_command(data, &cmd);
+	if (!cmd) {
+		/* ENOMEM and cmd is untouched. */
+		goto end;
+	}
 
 	if (query && query->server && query->server->connrec) {
-		cmd_generic(user_state_global, query->server, argc, argv, argv_eol,
-				query->name, data);
+		cmd_generic(user_state_global, query->server, query->name, cmd, data);
 	} else {
-		cmd_generic(user_state_global, NULL, argc, argv, argv_eol, NULL, data);
+		cmd_generic(user_state_global, NULL, NULL, cmd, data);
 	}
 
 	statusbar_items_redraw("otr");
 
-	g_free(argv_eol[0]);
-	g_free(argv_eol);
-	g_free(argv);
-
 end:
+	free(cmd);
 	return;
 }
 
@@ -293,11 +295,11 @@ void otr_deinit(void)
 	theme_unregister();
 }
 
-SERVER_REC *find_irssi_ctx_by_peername(const char *peername, char *nick)
+SERVER_REC *find_irssi_ctx_by_peername(const char *peername, const char *nick)
 {
 	GSList *tmp;
 	char pname[256];
-	char *address;
+	char *address, *_nick = strdup(nick);
 	SERVER_REC *server = NULL;
 
 	strncpy(pname, peername, sizeof(pname));
@@ -308,7 +310,7 @@ SERVER_REC *find_irssi_ctx_by_peername(const char *peername, char *nick)
 	}
 
 	*address = '\0';
-	strncpy(nick, pname, strlen(nick));
+	strncpy(_nick, pname, strlen(_nick));
 	*address++ = '@';
 
 	for (tmp = servers; tmp != NULL; tmp = tmp->next) {
diff --git a/src/otr.c b/src/otr.c
index 6e83f92..58ce603 100644
--- a/src/otr.c
+++ b/src/otr.c
@@ -335,7 +335,7 @@ struct ctxlist_ *otr_contexts(struct otr_user_state *ustate)
 /*
  * Finish the conversation.
  */
-void otr_finish(SERVER_REC *irssi, char *nick)
+void otr_finish(SERVER_REC *irssi, const char *nick)
 {
 	ConnContext *ctx;
 
@@ -389,7 +389,7 @@ void otr_finishall(struct otr_user_state *ustate)
 /*
  * Trust our peer.
  */
-void otr_trust(SERVER_REC *irssi, char *nick)
+void otr_trust(SERVER_REC *irssi, const char *nick)
 {
 	ConnContext *ctx;
 	char peerfp[OTRL_PRIVKEY_FPRINT_HUMAN_LEN];
@@ -424,7 +424,7 @@ end:
 /*
  * implements /otr authabort
  */
-void otr_auth_abort(SERVER_REC *irssi, char *nick)
+void otr_auth_abort(SERVER_REC *irssi, const char *nick)
 {
 	ConnContext *ctx;
 
@@ -453,7 +453,7 @@ end:
 /*
  * Initiate or respond to SMP authentication.
  */
-void otr_auth(SERVER_REC *irssi, char *nick, const char *question,
+void otr_auth(SERVER_REC *irssi, const char *nick, const char *question,
 		const char *secret)
 {
 	int ret;
diff --git a/src/otr.h b/src/otr.h
index 63fee6e..266848f 100644
--- a/src/otr.h
+++ b/src/otr.h
@@ -160,7 +160,7 @@ void irssi_send_message(SERVER_REC *irssi, const char *recipient,
 void otr_status_change(SERVER_REC *irssi, const char *nick,
 		enum otr_status_event event);
 
-SERVER_REC *find_irssi_ctx_by_peername(const char *peername, char *nick);
+SERVER_REC *find_irssi_ctx_by_peername(const char *peername, const char *nick);
 
 /* init stuff */
 
@@ -184,11 +184,11 @@ int otr_getstatus(SERVER_REC *irssi, const char *nick);
 
 /* user interaction */
 
-void otr_trust(SERVER_REC *irssi, char *nick);
-void otr_finish(SERVER_REC *irssi, char *nick);
-void otr_auth(SERVER_REC *irssi, char *nick, const char *question,
+void otr_trust(SERVER_REC *irssi, const char *nick);
+void otr_finish(SERVER_REC *irssi, const char *nick);
+void otr_auth(SERVER_REC *irssi, const char *nick, const char *question,
 		const char *secret);
-void otr_auth_abort(SERVER_REC *irssi, char *nick);
+void otr_auth_abort(SERVER_REC *irssi, const char *nick);
 struct ctxlist_ *otr_contexts(struct otr_user_state *ustate);
 void otr_finishall(struct otr_user_state *ustate);
 void otr_forget(SERVER_REC *irssi, const char *nick, char *str_fp,
diff --git a/src/utils.c b/src/utils.c
index cfbac5e..be3d299 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -29,6 +29,46 @@ static const char *lvlstring[] = {
 	"DEBUG"
 };
 
+/*
+ * Left trim a string.
+ */
+static char *ltrim(char *s)
+{
+	assert(s);
+
+	while (isspace(*s)) {
+		s++;
+	}
+	return s;
+}
+
+/*
+ * Right trim a string.
+ */
+static char *rtrim(char *s)
+{
+	char *back;
+
+	assert(s);
+
+	back = s + strlen(s);
+
+	while (isspace(*--back));
+	*(back + 1) = '\0';
+
+	return s;
+}
+
+/*
+ * Trim whitespaces in front and back of the string.
+ */
+char *utils_trim_string(char *s)
+{
+	assert(s);
+
+	return rtrim(ltrim(s));
+}
+
 int utils_io_extract_smp(const char *data, char **question, char **secret)
 {
 	unsigned int q_len, s_len;
@@ -106,31 +146,56 @@ error:
 
 void utils_explode_args(const char *_data, char ***_argv, int *_argc)
 {
-	int argc = 1, i = 0;
-	char **argv = NULL, *c, *data = NULL;
+	int argc = 0, i = 0, have_arg = 0;
+	char **argv = NULL, *c, *data = NULL, *cmd_offset;
 
-	assert(_data);
+	if (!_data) {
+		goto error;
+	}
 
 	data = strndup(_data, strlen(_data));
 	if (!data) {
 		goto error;
 	}
 
-	c = data;
+	c = utils_trim_string(data);
+
+	/* Ignore first command */
+	cmd_offset = strchr(c, ' ');
+	if (!cmd_offset) {
+		goto error;
+	}
+
+	cmd_offset = utils_trim_string(cmd_offset);
+
+	if (cmd_offset && strlen(cmd_offset) > 0) {
+		argc++;
+		have_arg = 1;
+	}
+
+	c = cmd_offset;
 	while ((c = strchr(c + 1, ' '))) {
 		/* Skip consecutive spaces. */
 		if (*(c + 1) == ' ') {
 			continue;
 		}
 		argc++;
+		have_arg = 1;
+	}
+
+	/* No args, only spaces encountered. */
+	if (!have_arg) {
+		argc = 0;
+		goto error;
 	}
 
-	argv = malloc(argc * sizeof(char *));
+	argv = zmalloc(argc * sizeof(char *));
 	if (!argv) {
 		goto error;
 	}
 
-	c = strtok(data, " ");
+	/* Ignore first command */
+	c = strtok(cmd_offset, " ");
 	while (c != NULL) {
 		argv[i] = strdup(c);
 		c = strtok(NULL, " ");
@@ -145,38 +210,46 @@ error:
 	return;
 }
 
-void utils_io_explode_args(const char *args, char ***argvp, char ***argv_eolp,
-		int *argcp)
+void utils_free_args(char ***argv, int argc)
 {
-	char **argv, **argv_eol;
-	char *s = (char *) args;
-	int argc = 1, i;
+	int i;
+	char **args;
 
-	while ((s = strchr(s + 1, ' '))) {
-		argc++;
+	assert(argv);
+
+	args = *argv;
+
+	for (i = 0; i < argc; i++) {
+		if (args[i]) {
+			free(args[i]);
+		}
 	}
 
-	argv = (char **) malloc(argc * sizeof(char *));
-	argv_eol = (char **) malloc(argc * sizeof(char *));
+	free(args);
+}
 
-	s = (char *) args;
-	argv_eol[0] = strdup(args);
-	i = 0;
+void utils_extract_command(const char *data, char **_cmd)
+{
+	char *s, *cmd = NULL;
 
-	while (++i < argc) {
-		argv_eol[i] = strchr(argv_eol[i - 1], ' ') + 1;
-	}
+	assert(data);
+	assert(_cmd);
 
-	argv[0] = strtok(strdup(args), " ");
-	i = 1;
-	while (i < argc) {
-		argv[i++] = strtok(NULL, " ");
-		otr_logst(MSGLEVEL_CRAP, "arg %d: %s", i, argv[i - 1]);
+	/* Search for the first whitespace. */
+	s = strchr(data, ' ');
+	if (s) {
+		cmd = strndup(data, s - data);
+		if (!cmd) {
+			goto error;
+		}
+	} else {
+		cmd = strdup(data);
 	}
 
-	*argvp = argv;
-	*argv_eolp = argv_eol;
-	*argcp = argc;
+	*_cmd = cmd;
+
+error:
+	return;
 }
 
 void otr_log(SERVER_REC *server, const char *nick, int lvl, const char *fmt, ...)
diff --git a/src/utils.h b/src/utils.h
index 5386dd3..82567f6 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -34,9 +34,9 @@
 
 void otr_log(SERVER_REC *server, const char *to, int lvl, const char *fmt, ...);
 
+void utils_free_args(char ***argv, int argc);
+void utils_extract_command(const char *data, char **_cmd);
 void utils_explode_args(const char *_data, char ***_argv, int *_argc);
-void utils_io_explode_args(const char *args, char ***argvp, char ***argv_eolp,
-		int *argcp);
 int utils_io_extract_smp(const char *data, char **question, char **secret);
 void utils_string_to_upper(char *string);
 void utils_hash_parts_to_readable_hash(const char **parts, char *dst);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/irssi-plugin-otr.git



More information about the Pkg-privacy-commits mailing list