Annotation of embedaddon/mtr/packet/cmdparse.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 14: You should have received a copy of the GNU General Public License along
! 15: with this program; if not, write to the Free Software Foundation, Inc.,
! 16: 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1.1 misho 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:
1.1.1.2 ! misho 69: command_string will be modified in-place with NUL characters terminating
! 70: tokens, and the command_t will use pointers to the contents of
1.1 misho 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>