/* 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 #include #include #include "../shared/LL.h" #include "../shared/sockets.h" #include "../shared/debug.h" #include "clients.h" #include "client_functions.h" #include "parse.h" int parse_all_client_messages() { int i, j; int newtoken, inquote; client *c; char *str; // char *tok; int argc; char *argv[256]; char delimiters[] = " \0"; char leftquote[] = "\0\"'`([{\0"; char rightquote[] = "\0\"'`)]}\0"; char errmsg[256]; int invalid=0; //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... //len = strlen(str); argc=0; newtoken=1; inquote=0; for(i=0; str[i]; i++) { if(inquote) // Scan for the end of the quote { if(str[i] == rightquote[inquote]) { // Found the end of the quote inquote=0; str[i] = 0; newtoken=1; } } else // Normal operation; split at delimiters { for(j=1; leftquote[j]; j++) { // Found the beginning of a new quote... if(str[i] == leftquote[j]) { inquote = j; str[i] = 0; continue; } } for(j=0; delimiters[j]; j++) { // Break into a new string... if(str[i] == delimiters[j]) { str[i] = 0; newtoken = 1; continue; } } } if(newtoken && str[i]) { newtoken=0; argv[argc] = str + i; argc++; } else { } } if(inquote) { sprintf(errmsg, "huh? Unterminated string: missing %c\n", rightquote[inquote]); sock_send_string(c->sock, errmsg); continue; } /* for(tok = strtok(str, delimiters); tok; tok=strtok(NULL, delimiters)) { argv[argc] = tok; argc++; } */ argv[argc] = NULL; if(argc < 1) continue; // Now find and call the appropriate function... // debug("parse: Finding function...\n"); invalid = 1; for(i=0; commands[i].keyword; i++) { // debug("(checking %s)\n", commands[i].keyword); if(0 == strcmp(argv[0], commands[i].keyword)) { // debug("(FOUND %s)\n", commands[i].keyword); invalid = commands[i].function(c, argc, argv); // debug("parse: Returned %i...\n", err); } } if(invalid) { // FIXME: Check for buffer overflows here... sprintf(errmsg, "huh? Invalid command \"%s\"\n", argv[0]); sock_send_string(c->sock, errmsg); } free(str); // fixed memory leak? } // end for(str...) } // end if (c) } while (LL_Next(clients) == 0); return 0; }