Browse Source

ksession: ksession_split_pipes()

Serj Kalichev 2 years ago
parent
commit
cd8abbffdb
3 changed files with 118 additions and 5 deletions
  1. 1 0
      klish/ksession.h
  2. 72 0
      klish/ksession/ksession_parse.c
  3. 45 5
      klish/ktp/ktpd_session.c

+ 1 - 0
klish/ksession.h

@@ -25,6 +25,7 @@ kpath_t *ksession_path(const ksession_t *session);
 
 kpargv_t *ksession_parse_line(ksession_t *session, const char *line,
 	kpargv_purpose_e purpose);
+faux_list_t *ksession_split_pipes(const char *line);
 
 C_DECL_END
 

+ 72 - 0
klish/ksession/ksession_parse.c

@@ -285,3 +285,75 @@ kpargv_t *ksession_parse_line(ksession_t *session, const char *line,
 
 	return pargv;
 }
+
+
+// Delimeter of commands is '|' (pipe)
+faux_list_t *ksession_split_pipes(const char *line)
+{
+	faux_list_t *list = NULL;
+	faux_argv_t *argv = NULL;
+	faux_argv_node_t *argv_iter = NULL;
+	faux_argv_t *cur_argv = NULL; // Current argv
+	const char *delimeter = "|";
+	const char *arg = NULL;
+
+	assert(line);
+	if (!line)
+		return NULL;
+
+	// Split raw line to arguments
+	argv = faux_argv_new();
+	assert(argv);
+	if (!argv)
+		return NULL;
+	if (faux_argv_parse(argv, line) < 0) {
+		faux_argv_free(argv);
+		return NULL;
+	}
+
+	list = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
+		NULL, NULL, (void (*)(void *))faux_argv_free);
+	assert(list);
+	if (!list) {
+		faux_argv_free(argv);
+		return NULL;
+	}
+
+	argv_iter = faux_argv_iter(argv);
+	cur_argv = faux_argv_new();
+	assert(cur_argv);
+	while ((arg = faux_argv_each(&argv_iter))) {
+		if (strcmp(arg, delimeter) == 0) {
+			// End of current line (from "|" to "|")
+			// '|' in a first position is an error
+			if (faux_argv_len(cur_argv) == 0) {
+				faux_argv_free(argv);
+				faux_list_free(list);
+				return NULL;
+			}
+			// Add argv to argv's list
+			faux_list_add(list, cur_argv);
+			cur_argv = faux_argv_new();
+			assert(cur_argv);
+		} else {
+			faux_argv_add(cur_argv, arg);
+		}
+	}
+
+	// Continuable flag is usefull for last argv
+	faux_argv_set_continuable(cur_argv, faux_argv_is_continuable(argv));
+	// Empty cur_argv is not an error. It's usefull for completion and help.
+	// But empty cur_argv and continuable is abnormal.
+	if (faux_argv_len(cur_argv) == 0) {
+		if (faux_argv_is_continuable(cur_argv)) {
+			faux_argv_free(argv);
+			faux_list_free(list);
+			return NULL;
+		}
+	}
+	faux_list_add(list, cur_argv);
+
+	faux_argv_free(argv);
+
+	return list;
+}

+ 45 - 5
klish/ktp/ktpd_session.c

@@ -9,6 +9,7 @@
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <syslog.h>
 
 #include <faux/str.h>
 #include <faux/async.h>
@@ -65,6 +66,8 @@ static bool_t ktpd_session_process_cmd(ktpd_session_t *session, faux_msg_t *msg)
 	kpargv_t *pargv = NULL;
 	ktp_cmd_e cmd = KTP_CMD_ACK;
 
+	faux_list_t *split = NULL;
+
 	assert(session);
 	assert(msg);
 
@@ -75,6 +78,10 @@ static bool_t ktpd_session_process_cmd(ktpd_session_t *session, faux_msg_t *msg)
 		return BOOL_FALSE;
 	}
 
+	split = ksession_split_pipes(line);
+	printf("split %ld\n", split ? (ssize_t)faux_list_len(split) : -1);
+	faux_list_free(split);
+
 	// Parsing
 	pargv = ksession_parse_line(session->ksession, line, KPURPOSE_EXEC);
 	faux_str_free(line);
@@ -128,8 +135,40 @@ static bool_t ktpd_session_process_completion(ktpd_session_t *session, faux_msg_
 }
 
 
+static bool_t ktpd_session_process_help(ktpd_session_t *session, faux_msg_t *msg)
+{
+	char *line = NULL;
+	faux_msg_t *ack = NULL;
+	kpargv_t *pargv = NULL;
+	ktp_cmd_e cmd = KTP_HELP_ACK;
+
+	assert(session);
+	assert(msg);
+
+	// Get line from message
+	if (!(line = faux_msg_get_str_param_by_type(msg, KTP_PARAM_LINE))) {
+		ktpd_session_send_error(session, cmd, NULL);
+		return BOOL_FALSE;
+	}
+
+	// Parsing
+	pargv = ksession_parse_line(session->ksession, line, KPURPOSE_HELP);
+	faux_str_free(line);
+	kpargv_free(pargv);
+
+	// Send ACK message
+	ack = ktp_msg_preform(cmd, KTP_STATUS_NONE);
+	faux_msg_send_async(ack, session->async);
+	faux_msg_free(ack);
+
+	return BOOL_TRUE;
+}
+
+
 static bool_t ktpd_session_dispatch(ktpd_session_t *session, faux_msg_t *msg)
 {
+	uint16_t cmd = 0;
+
 	assert(session);
 	if (!session)
 		return BOOL_FALSE;
@@ -137,18 +176,19 @@ static bool_t ktpd_session_dispatch(ktpd_session_t *session, faux_msg_t *msg)
 	if (!msg)
 		return BOOL_FALSE;
 
-	printf("Dispatch cmd %c\n", (char)faux_msg_get_cmd(msg));
-	switch (faux_msg_get_cmd(msg)) {
+	cmd = faux_msg_get_cmd(msg);
+	switch (cmd) {
 	case KTP_CMD:
 		ktpd_session_process_cmd(session, msg);
 		break;
 	case KTP_COMPLETION:
 		ktpd_session_process_completion(session, msg);
 		break;
-/*	case KTP_HELP:
+	case KTP_HELP:
+		ktpd_session_process_help(session, msg);
 		break;
-*/	default:
-		printf("Unsupported command\n");
+	default:
+		syslog(LOG_WARNING, "Unsupported command: 0x%04u\n", cmd);
 		break;
 	}