1 | /* |
---|
2 | parse.c |
---|
3 | |
---|
4 | Handles input commands from clients, by splitting strings into tokens |
---|
5 | and passing arguments to the appropriate handler. |
---|
6 | |
---|
7 | It works much like a command line. Only the first token is used to |
---|
8 | determine what function to call. |
---|
9 | |
---|
10 | */ |
---|
11 | |
---|
12 | |
---|
13 | #include <stdlib.h> |
---|
14 | #include <stdio.h> |
---|
15 | #include <string.h> |
---|
16 | |
---|
17 | #include "../shared/LL.h" |
---|
18 | #include "../shared/sockets.h" |
---|
19 | #include "../shared/debug.h" |
---|
20 | #include "clients.h" |
---|
21 | #include "client_functions.h" |
---|
22 | #include "parse.h" |
---|
23 | |
---|
24 | |
---|
25 | |
---|
26 | int parse_all_client_messages() |
---|
27 | { |
---|
28 | int i, j; |
---|
29 | int newtoken, inquote; |
---|
30 | client *c; |
---|
31 | char *str; |
---|
32 | // char *tok; |
---|
33 | int argc; |
---|
34 | char *argv[256]; |
---|
35 | char delimiters[] = " \0"; |
---|
36 | char leftquote[] = "\0\"'`([{\0"; |
---|
37 | char rightquote[] = "\0\"'`)]}\0"; |
---|
38 | char errmsg[256]; |
---|
39 | int invalid=0; |
---|
40 | |
---|
41 | //debug("parse: Rewinding list...\n"); |
---|
42 | LL_Rewind(clients); |
---|
43 | do { |
---|
44 | // Get the next client... |
---|
45 | //debug("parse: Getting client...\n"); |
---|
46 | c = LL_Get(clients); |
---|
47 | if(c) |
---|
48 | { |
---|
49 | // And parse all its messages... |
---|
50 | //debug("parse: Getting messages...\n"); |
---|
51 | for(str = client_get_message(c); str; str = client_get_message(c)) |
---|
52 | { |
---|
53 | debug("parse: ...%s\n", str); |
---|
54 | // Now, split up the string... |
---|
55 | //len = strlen(str); |
---|
56 | argc=0; |
---|
57 | newtoken=1; |
---|
58 | inquote=0; |
---|
59 | for(i=0; str[i]; i++) |
---|
60 | { |
---|
61 | if(inquote) // Scan for the end of the quote |
---|
62 | { |
---|
63 | if(str[i] == rightquote[inquote]) |
---|
64 | { // Found the end of the quote |
---|
65 | inquote=0; |
---|
66 | str[i] = 0; |
---|
67 | newtoken=1; |
---|
68 | } |
---|
69 | } |
---|
70 | else // Normal operation; split at delimiters |
---|
71 | { |
---|
72 | for(j=1; leftquote[j]; j++) |
---|
73 | { |
---|
74 | // Found the beginning of a new quote... |
---|
75 | if(str[i] == leftquote[j]) |
---|
76 | { |
---|
77 | inquote = j; |
---|
78 | str[i] = 0; |
---|
79 | continue; |
---|
80 | } |
---|
81 | } |
---|
82 | for(j=0; delimiters[j]; j++) |
---|
83 | { |
---|
84 | // Break into a new string... |
---|
85 | if(str[i] == delimiters[j]) |
---|
86 | { |
---|
87 | str[i] = 0; |
---|
88 | newtoken = 1; |
---|
89 | continue; |
---|
90 | } |
---|
91 | } |
---|
92 | } |
---|
93 | if(newtoken && str[i]) |
---|
94 | { |
---|
95 | newtoken=0; |
---|
96 | argv[argc] = str + i; |
---|
97 | argc++; |
---|
98 | } |
---|
99 | else |
---|
100 | { |
---|
101 | } |
---|
102 | } |
---|
103 | if(inquote) |
---|
104 | { |
---|
105 | sprintf(errmsg, "huh? Unterminated string: missing %c\n", |
---|
106 | rightquote[inquote]); |
---|
107 | sock_send_string(c->sock, errmsg); |
---|
108 | continue; |
---|
109 | } |
---|
110 | /* |
---|
111 | for(tok = strtok(str, delimiters); |
---|
112 | tok; |
---|
113 | tok=strtok(NULL, delimiters)) |
---|
114 | { |
---|
115 | argv[argc] = tok; |
---|
116 | argc++; |
---|
117 | } |
---|
118 | */ |
---|
119 | argv[argc] = NULL; |
---|
120 | if(argc < 1) continue; |
---|
121 | |
---|
122 | // Now find and call the appropriate function... |
---|
123 | // debug("parse: Finding function...\n"); |
---|
124 | invalid = 1; |
---|
125 | for(i=0; commands[i].keyword; i++) |
---|
126 | { |
---|
127 | // debug("(checking %s)\n", commands[i].keyword); |
---|
128 | if(0 == strcmp(argv[0], commands[i].keyword)) |
---|
129 | { |
---|
130 | // debug("(FOUND %s)\n", commands[i].keyword); |
---|
131 | invalid = commands[i].function(c, argc, argv); |
---|
132 | // debug("parse: Returned %i...\n", err); |
---|
133 | } |
---|
134 | } |
---|
135 | if(invalid) |
---|
136 | { |
---|
137 | // FIXME: Check for buffer overflows here... |
---|
138 | sprintf(errmsg, "huh? Invalid command \"%s\"\n", argv[0]); |
---|
139 | sock_send_string(c->sock, errmsg); |
---|
140 | } |
---|
141 | |
---|
142 | free(str); // fixed memory leak? |
---|
143 | } // end for(str...) |
---|
144 | } // end if (c) |
---|
145 | } while (LL_Next(clients) == 0); |
---|
146 | |
---|
147 | return 0; |
---|
148 | } |
---|