1999-12-09 23:15:14 +00:00
|
|
|
/*
|
|
|
|
|
parse.c
|
|
|
|
|
|
|
|
|
|
Handles input commands from clients, by splitting strings into tokens
|
|
|
|
|
and passing arguments to the appropriate handler.
|
|
|
|
|
|
|
|
|
|
It works much like a command line. Only the first token is used to
|
|
|
|
|
determine what function to call.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2001-05-25 03:14:27 +00:00
|
|
|
#include "shared/LL.h"
|
|
|
|
|
#include "shared/sockets.h"
|
|
|
|
|
#include "shared/debug.h"
|
1999-12-09 23:15:14 +00:00
|
|
|
#include "clients.h"
|
|
|
|
|
#include "client_functions.h"
|
|
|
|
|
#include "parse.h"
|
|
|
|
|
|
2001-09-21 21:08:10 +00:00
|
|
|
// This is a big function... TOO big. How to trim....
|
|
|
|
|
// TODO: Simplify... simplify...
|
2001-10-19 17:44:09 +00:00
|
|
|
|
|
|
|
|
#define MAX_ARGUMENTS 256
|
|
|
|
|
|
2000-03-30 20:20:41 +00:00
|
|
|
int
|
|
|
|
|
parse_all_client_messages ()
|
1999-12-09 23:15:14 +00:00
|
|
|
{
|
2001-10-05 22:04:35 +00:00
|
|
|
int i; // int j, len;
|
|
|
|
|
//int newtoken, inquote;
|
2000-04-03 22:13:57 +00:00
|
|
|
client *c;
|
2001-09-21 21:08:10 +00:00
|
|
|
char *str, *p, *q, *s;
|
1999-12-09 23:15:14 +00:00
|
|
|
// char *tok;
|
2000-04-03 22:13:57 +00:00
|
|
|
int argc;
|
2001-10-19 17:44:09 +00:00
|
|
|
char *argv[MAX_ARGUMENTS];
|
2001-10-05 22:04:35 +00:00
|
|
|
//char delimiters[] = " ";
|
2001-09-21 21:08:10 +00:00
|
|
|
char leftquote[] = "\"'`([{";
|
|
|
|
|
char rightquote[] = "\"'`)]}";
|
2000-04-03 22:13:57 +00:00
|
|
|
char errmsg[256];
|
|
|
|
|
int invalid = 0;
|
2001-09-21 21:08:10 +00:00
|
|
|
int quoteindex;
|
|
|
|
|
|
2001-10-19 17:44:09 +00:00
|
|
|
for (i = 0; i < MAX_ARGUMENTS; i++) {
|
2001-10-05 22:04:35 +00:00
|
|
|
argv[i] = NULL;
|
2001-09-21 21:08:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define SEPARATOR_CHAR ' '
|
|
|
|
|
#define LINE_TERM_CHAR '\0'
|
|
|
|
|
#define COMMENT_CHAR '#'
|
2000-03-30 20:20:41 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
//debug("parse: Rewinding list...\n");
|
|
|
|
|
LL_Rewind (clients);
|
|
|
|
|
do {
|
|
|
|
|
// Get the next client...
|
|
|
|
|
//debug("parse: Getting client...\n");
|
|
|
|
|
c = LL_Get (clients);
|
|
|
|
|
if (c) {
|
|
|
|
|
// And parse all its messages...
|
|
|
|
|
//debug("parse: Getting messages...\n");
|
|
|
|
|
for (str = client_get_message (c); str; str = client_get_message (c)) {
|
|
|
|
|
debug ("parse: ...%s\n", str);
|
|
|
|
|
// Now, split up the string...
|
|
|
|
|
argc = 0;
|
2001-09-21 21:08:10 +00:00
|
|
|
i = 0;
|
|
|
|
|
q = p = str;
|
|
|
|
|
|
|
|
|
|
if (*p == COMMENT_CHAR) {
|
|
|
|
|
continue; // found a comment line - skip it...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//fprintf(stderr, "starting string scan...\n");
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
|
// bypass initial white space...
|
|
|
|
|
while ((*p == SEPARATOR_CHAR) && (*p)) {
|
|
|
|
|
p++;
|
|
|
|
|
q++;
|
2000-04-03 22:13:57 +00:00
|
|
|
}
|
2001-09-21 21:08:10 +00:00
|
|
|
|
|
|
|
|
// If (*p) is null here, we reached the end of
|
|
|
|
|
// an empty parameter... so one of two things
|
|
|
|
|
// is true:
|
|
|
|
|
//
|
|
|
|
|
// 1. There is nothing but white space on this line (odd..)
|
|
|
|
|
// 2. This is trailing white space (odd... but allowable)
|
|
|
|
|
|
|
|
|
|
if (*p == LINE_TERM_CHAR) {
|
|
|
|
|
break;
|
|
|
|
|
// if there are no arguments, argc == 0 and will fail
|
|
|
|
|
// appropriately...
|
|
|
|
|
//
|
|
|
|
|
// if this is trailing white space, ignore the argc++ at the
|
|
|
|
|
// end and claim this as the end...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle quoted strings...
|
|
|
|
|
if ((s = strchr(leftquote, *p)) != NULL) {
|
|
|
|
|
quoteindex = s - leftquote;
|
|
|
|
|
//fprintf(stderr, "found <%c> at index [%d] = <%c>\n", *p, quoteindex, leftquote[quoteindex]);
|
|
|
|
|
q = ++p; // past open quote...
|
|
|
|
|
while ((rightquote[quoteindex] != *p) && (*p != LINE_TERM_CHAR)) {
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
if (*p == LINE_TERM_CHAR) {
|
|
|
|
|
// We just sucked up the rest of the command line: ERROR!!
|
|
|
|
|
snprintf (errmsg, sizeof(errmsg), "huh? unterminated string! missing ending %c\n",
|
|
|
|
|
rightquote[quoteindex]);
|
|
|
|
|
sock_send_string (c->sock, errmsg);
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
*p = LINE_TERM_CHAR; // terminate string
|
|
|
|
|
p++; // bypass to next character
|
|
|
|
|
// Note that next character could be a EndOfLine (null)
|
|
|
|
|
// if the string was last on the line, or it could be
|
|
|
|
|
// something else... is it a blank?
|
|
|
|
|
if (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR) {
|
|
|
|
|
sock_send_string (c->sock, "huh? improperly terminated string! (missing whitespace)\n");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Otherwise, normal string...
|
2000-04-03 22:13:57 +00:00
|
|
|
} else {
|
2001-09-21 21:08:10 +00:00
|
|
|
while (*p != SEPARATOR_CHAR && *p != LINE_TERM_CHAR)
|
|
|
|
|
p++;
|
2000-04-03 22:13:57 +00:00
|
|
|
}
|
2001-09-21 21:08:10 +00:00
|
|
|
|
|
|
|
|
// Not end of line?
|
|
|
|
|
if (*p) {
|
|
|
|
|
*p = LINE_TERM_CHAR;
|
|
|
|
|
//fprintf(stderr, "found new token: %s\n", q);
|
|
|
|
|
argv[i++] = q;
|
|
|
|
|
q = ++p;
|
|
|
|
|
} else {
|
|
|
|
|
//fprintf(stderr, "found new token: %s\n", q);
|
|
|
|
|
argv[i++] = q;
|
|
|
|
|
}
|
|
|
|
|
// At the end of this statement,
|
|
|
|
|
// *p will be '\0' if end of input reached;
|
|
|
|
|
// otherwise, it is the first character of the
|
|
|
|
|
// next part of the string.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
argc++;
|
|
|
|
|
} while (*p);
|
|
|
|
|
|
|
|
|
|
//fprintf(stderr, "exiting string scan...\n");
|
|
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
argv[argc] = NULL;
|
|
|
|
|
if (argc < 1)
|
|
|
|
|
continue;
|
2000-03-30 20:20:41 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
// Now find and call the appropriate function...
|
|
|
|
|
invalid = 1;
|
|
|
|
|
for (i = 0; commands[i].keyword; i++) {
|
|
|
|
|
if (0 == strcmp (argv[0], commands[i].keyword)) {
|
|
|
|
|
invalid = commands[i].function (c, argc, argv);
|
2001-09-21 21:08:10 +00:00
|
|
|
break; // found our function - don't continue on...
|
2000-04-03 22:13:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
2001-09-21 21:08:10 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
if (invalid) {
|
2001-09-21 21:08:10 +00:00
|
|
|
snprintf (errmsg, sizeof(errmsg), "huh? Invalid command \"%s\"\n", argv[0]);
|
2000-04-03 22:13:57 +00:00
|
|
|
sock_send_string (c->sock, errmsg);
|
|
|
|
|
}
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
free (str); // fixed memory leak?
|
|
|
|
|
} // end for(str...)
|
|
|
|
|
} // end if (c)
|
|
|
|
|
} while (LL_Next (clients) == 0);
|
1999-12-09 23:15:14 +00:00
|
|
|
|
2000-04-03 22:13:57 +00:00
|
|
|
return 0;
|
1999-12-09 23:15:14 +00:00
|
|
|
}
|