-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathparse_args.c
More file actions
116 lines (105 loc) · 3.19 KB
/
parse_args.c
File metadata and controls
116 lines (105 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ARGS_COUNT 127
#define MAX_ARG_LENGTH 4095
char **parse_args(const char *command) {
#define STATUS_FIND_BEGIN 1
#define STATUS_FIND_END 2
char **args = malloc((MAX_ARGS_COUNT + 1) * sizeof(char *));
int args_index = 0;
char arg[MAX_ARG_LENGTH + 1] = {'\0'};
int arg_index = 0;
int command_length = strlen(command);
char arg_quote = 0;
int status = STATUS_FIND_BEGIN;
int i = 0;
for (i = 0; i <= command_length; i ++) {
char c = command[i];
if (status == STATUS_FIND_BEGIN) {
if (c != ' ') {
arg_index = 0;
if (c == '"' || c == '\'') {
arg_quote = c;
} else {
arg_quote = 0;
arg[arg_index++] = c;
}
status = STATUS_FIND_END;
}
} else if (status == STATUS_FIND_END) {
if (c == '\\') {
if (i < command_length-1) {
switch(command[i+1]) {
case '"':
case '\'':
case '\\':
case ' ':
if (arg_index < MAX_ARG_LENGTH) {
arg[arg_index++] = command[i+1];
}
i ++;
continue;
default:
goto COPYC;
}
} else {
goto COPYC;
}
} else if (c == '\0'
|| (arg_quote != 0 && c == arg_quote)
|| (arg_quote == 0 && c == ' ')) {
arg[arg_index] = '\0';
args[args_index++] = strdup(arg);
status = STATUS_FIND_BEGIN;
if (args_index >= MAX_ARGS_COUNT) {
goto END;
}
} else {
COPYC:
if (arg_index < MAX_ARG_LENGTH) {
arg[arg_index++] = c;
}
}
}
}
END:
args[args_index] = NULL;
return args;
}
void free_args(char **args) {
if (args == NULL) return;
char **a = args;
while(*a) {
free(*a++);
}
free(args);
}
#ifdef ARG_PARSER_TEST
void dump_command(const char *command) {
printf("--------------\n");
printf("%s\n", command);
char **args = parse_args(command);
char **a = args;
while (*a) {
printf("\"%s\"\n", *a++);
}
free_args(args);
}
int main(int argc, char **argv) {
dump_command("ls -lh");
dump_command("mysql -uroot -pfasdfasd");
dump_command("mysql -u\"root\" -p\"fasdfasd\"");
dump_command("mysql \"fasdfasd\"");
dump_command("mysql \"fas\"dfasd\"");
dump_command("mysql \"fas\\\"dfasd\"");
dump_command("mysql \"fas dfasd\"");
dump_command("mysql \"fas\\ dfasd\" ");
dump_command("\"mysql\" \"fas\\ dfasd\" -a");
dump_command("\"mysql\" fas\\ dfasd -a");
dump_command("msyql -u'root'");
dump_command("mysql '-uroot' -p'\"padfs'");
dump_command("mysql '-uroot''''''");
return 0;
}
#endif