Example #1
0
static int run_cmds(clockid_t clkid, int cmdc, char *cmdv[])
{
	int i = 0, result = 0;
	cmd_func_t action = NULL;

	while (i < cmdc) {
		char *arg = cmdv[i];

		/* increment now to remove the command argument */
		i++;

		action = get_command_function(arg);
		if (action)
			result = action(clkid, cmdc - i, &cmdv[i]);
		else
			pr_err("unknown command %s.", arg);

		/* result is how many arguments were used up by the command,
		 * not including the ";". We will increment the loop counter
		 * to avoid processing the arguments as commands.
		 */
		if (result < 0)
			return result;
		else
			i += result;
	}

	return 0;
}
Example #2
0
File: server.c Project: cotsog/ihlt
void LineLocator(struct ConnectionNode *conn) {
	/* look for the end of the line */
	char *str1, *saveptr1, *ntoken, *token;
	bool endswell = false;
	switch (conn->buf[conn->nbytes - 1]) {
	case '\r':
	case '\n':
		endswell = true;
		break;
	};

	for (str1 = conn->buf;; str1 = NULL ) {
		ntoken = strtok_r(str1, "\r\n", &saveptr1);
		/* Reverse this so we know the next result. */
		if (str1 == NULL ) {
			if (ntoken != NULL || endswell) {
				char *str2, *saveptr2, *subtoken;
				char **argv = NULL;
				while (argv == NULL )
					argv = malloc(0);
				int argc = 0;

				for (str2 = token;; str2 = NULL ) {
					subtoken = strtok_r(str2, " \t", &saveptr2);
					if (subtoken == NULL )
						break;
					void *i = NULL;
					while (i == NULL )
						i = realloc(argv, sizeof(void*) * (argc + 1));
					argv = i;
					argv[argc++] = subtoken;
				}
				CommandFunc f;
				f = get_command_function(argv[0]);
				if (!f) {
					write(conn->fd,
							"502 Bad command or it is not implemented here.\r\n",
							48);
				} else
					f(conn, argc, argv);
				if (ntoken == NULL ) {
					free(conn->buf);
					conn->buf = NULL;
					conn->nbytes = 0;
					break;
				}
			} else {
				conn->nbytes = strlen(token);
				str1 = strdup(token);
				free(conn->buf);
				conn->buf = str1;
				break;
			}
		}
		token = ntoken;
	}
}
Example #3
0
static int parse_message(const char *str, Client *c)
{
	typedef enum { ST_INITIAL, ST_WHITESPACE, ST_ARGUMENT, ST_FINAL } State;
	State state = ST_INITIAL;

	int error = 0;
	char quote = '\0';	/* The quote used to open a quote string */
	int pos = 0;
	char *arg_space;
	int argc = 0;
	char *argv[MAX_ARGUMENTS];
	int argpos = 0;
	CommandFunc function = NULL;

	debug(RPT_DEBUG, "%s(str=\"%.120s\", client=[%d])", __FUNCTION__, str, c->sock);

	/* We will create a list of strings that is shorter or equally long as
	 * the original string str.
	 */
	arg_space = malloc(strlen(str)+1);
	if (arg_space == NULL) {
		report(RPT_ERR, "%s: Could not allocate memory", __FUNCTION__);
		sock_send_error(c->sock, "error allocating memory!\n");
	}

	argv[0] = arg_space;

	while ((state != ST_FINAL) && !error) {
		char ch = str[pos++];

		switch (state) {
		  case ST_INITIAL:
		  case ST_WHITESPACE:
			if (is_whitespace(ch))
				break;
			if (is_final(ch)) {
				state = ST_FINAL;
				break;
			}	  
			/* otherwise fall through */
			state = ST_ARGUMENT;
		  case ST_ARGUMENT:
			if (is_final(ch)) {
				if (quote)
					error = 2;
				if (argc >= MAX_ARGUMENTS-1) {
					error = 1;
				}
				else {
					argv[argc][argpos] = '\0';
					argv[argc+1] = argv[argc] + argpos + 1;
					argc++;
					argpos = 0;
				}
				state = ST_FINAL;
			}
			else if (ch == '\\') {
			 	if (str[pos]) {
			 		/* We solve quoted chars here right away */
					const char escape_chars[] = "nrt";
					const char escape_trans[] = "\n\r\t";
			 		char *p = strchr(escape_chars, str[pos]);

					/* Is it wise to have the characters \n, \r & \t expanded ?
					 * Can the displays deal with them ?
					 */
					if (p != NULL) {
						/* Insert a replacement for the code */
						argv[argc][argpos++] = escape_trans[p - escape_chars];
					}
					else {
						 /* Copy char literally */
						argv[argc][argpos++] = str[pos];
					}
					pos++;
			 	}
			 	else {
			 		error = 2;
					/* alternative: argv[argc][argpos++] = ch; */
					if (argc >= MAX_ARGUMENTS-1) {
						error = 1;
					}
					else {
						argv[argc][argpos] = '\0';
						argv[argc+1] = argv[argc] + argpos + 1;
						argc++;
						argpos = 0;
					}
			 		state = ST_FINAL;
			 	}
			}
			else if (is_opening_quote(ch, quote)) {
				quote = ch;
			}	
			else if (is_closing_quote(ch, quote)) {
				quote = '\0';
				if (argc >= MAX_ARGUMENTS-1) {
					error = 1;
				}
				else {
					argv[argc][argpos] = '\0';
					argv[argc+1] = argv[argc] + argpos + 1;
					argc++;
					argpos = 0;
				}
				state = ST_WHITESPACE;
			}
			else if (is_whitespace(ch) && (quote == '\0')) {
				if (argc >= MAX_ARGUMENTS-1) {
					error = 1;
				}
				else {
					argv[argc][argpos] = '\0';
					argv[argc+1] = argv[argc] + argpos + 1;
					argc++;
					argpos = 0;
				}
				state = ST_WHITESPACE;
			}	
			else {
				argv[argc][argpos++] = ch;
			}	
			break;
		  case ST_FINAL:
		  	/* This will never be reached */
			break;
		}
	}
	if (argc < MAX_ARGUMENTS)
		argv[argc] = NULL;
	else
		error = 1;

	if (error) {
		sock_send_error(c->sock, "Could not parse command\n");
		free(arg_space);
		return 0;
	}

#if 0 /* show what we have parsed */
	int i;
	for (i = 0; i < argc; i++) {
		printf("%s%c", argv[i], (i == argc-1) ? '\n' : ' ');
	}	
#endif

	/* Now find and call the appropriate function...*/
	function = get_command_function(argv[0]);

	if (function != NULL) {
		error = function(c, argc, argv);
		if (error) {
			sock_printf_error(c->sock, "Function returned error \"%.40s\"\n", argv[0]);
			report(RPT_WARNING, "Command function returned an error after command from client on socket %d: %.40s", c->sock, str);
		}	
	}
	else {
		sock_printf_error(c->sock, "Invalid command \"%.40s\"\n", argv[0]);
		report(RPT_WARNING, "Invalid command from client on socket %d: %.40s", c->sock, str);
	}

	free(arg_space);
	return 0;
}
Example #4
0
static inline int name_is_a_command(const char *name)
{
	return get_command_function(name) != NULL;
}