Annotation of embedaddon/mtr/packet/cmdparse.c, revision 1.1
1.1 ! misho 1: /*
! 2: mtr -- a network diagnostic tool
! 3: Copyright (C) 2016 Matt Kimball
! 4:
! 5: This program is free software; you can redistribute it and/or modify
! 6: it under the terms of the GNU General Public License version 2 as
! 7: published by the Free Software Foundation.
! 8:
! 9: This program is distributed in the hope that it will be useful,
! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 12: GNU General Public License for more details.
! 13:
! 14: You should have received a copy of the GNU General Public License
! 15: along with this program; if not, write to the Free Software
! 16: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
! 17: */
! 18:
! 19: #include "cmdparse.h"
! 20:
! 21: #include <ctype.h>
! 22: #include <errno.h>
! 23: #include <stdlib.h>
! 24: #include <string.h>
! 25:
! 26: /*
! 27: NUL terminate the whitespace separated tokens in the command string.
! 28: This modifies command_string in-place with NUL characters.
! 29: Fill the tokens array with pointers to the tokens, and return the
! 30: number of tokens found.
! 31: */
! 32: static
! 33: int tokenize_command(
! 34: char **tokens,
! 35: int max_tokens,
! 36: char *command_string)
! 37: {
! 38: int token_count = 0;
! 39: int on_space = 1;
! 40: int i;
! 41:
! 42: for (i = 0; command_string[i]; i++) {
! 43: if (on_space) {
! 44: if (!isspace((unsigned char) command_string[i])) {
! 45: /* Take care not to exceed the token array length */
! 46: if (token_count >= max_tokens) {
! 47: return -1;
! 48: }
! 49:
! 50: tokens[token_count++] = &command_string[i];
! 51: on_space = 0;
! 52: }
! 53: } else {
! 54: if (isspace((unsigned char) command_string[i])) {
! 55: command_string[i] = 0;
! 56: on_space = 1;
! 57: }
! 58: }
! 59: }
! 60:
! 61: return token_count;
! 62: }
! 63:
! 64: /*
! 65: Parse a command string (or command reply string) into a command_t
! 66: structure for later semantic interpretation. Returns EINVAL if the
! 67: command string is unparseable or zero for success.
! 68:
! 69: comamnd_string will be modified in-place with NUL characters terminating
! 70: tokens, and the command_t will use pointers to the conents of
! 71: command_string without copying, so any interpretation of the
! 72: command_t structure requires that the command_string memory has not yet
! 73: been freed or otherwise reused.
! 74: */
! 75: int parse_command(
! 76: struct command_t *command,
! 77: char *command_string)
! 78: {
! 79: char *tokens[MAX_COMMAND_TOKENS];
! 80: int token_count;
! 81: int i;
! 82:
! 83: memset(command, 0, sizeof(struct command_t));
! 84:
! 85: /* Tokenize the string using whitespace */
! 86: token_count =
! 87: tokenize_command(tokens, MAX_COMMAND_TOKENS, command_string);
! 88: if (token_count < 2) {
! 89: errno = EINVAL;
! 90: return -1;
! 91: }
! 92:
! 93: /* Expect the command token to be a numerical value */
! 94: errno = 0;
! 95: command->token = strtol(tokens[0], NULL, 10);
! 96: if (errno) {
! 97: errno = EINVAL;
! 98: return -1;
! 99: }
! 100: command->command_name = tokens[1];
! 101:
! 102: /*
! 103: The tokens beyond the command name are expected to be in
! 104: name, value pairs.
! 105: */
! 106: i = 2;
! 107: command->argument_count = 0;
! 108: while (i < token_count) {
! 109: /* It's an error if we get a name without a key */
! 110: if (i + 1 >= token_count) {
! 111: errno = EINVAL;
! 112: return -1;
! 113: }
! 114:
! 115: /* It's an error if we get more arguments than we have space for */
! 116: if (command->argument_count >= MAX_COMMAND_ARGUMENTS) {
! 117: errno = EINVAL;
! 118: return -1;
! 119: }
! 120:
! 121: command->argument_name[command->argument_count] = tokens[i];
! 122: command->argument_value[command->argument_count] = tokens[i + 1];
! 123: command->argument_count++;
! 124:
! 125: i += 2;
! 126: }
! 127:
! 128: return 0;
! 129: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>