X-Git-Url: https://git.cworth.org/git?p=ttt;a=blobdiff_plain;f=src%2Fttt-client.c;h=8139ada1de03cb04a2e7c7c986ebd0aa1d136983;hp=9d44945e506664678854fab51c41fa3fd04e870d;hb=c6398c6a1b59f6eddefc9f9ce577017b15677251;hpb=907321c065fb1383e800f0794981df91d4327f57;ds=sidebyside diff --git a/src/ttt-client.c b/src/ttt-client.c index 9d44945..8139ada 100644 --- a/src/ttt-client.c +++ b/src/ttt-client.c @@ -21,9 +21,11 @@ #include "ttt-client.h" +#include "ttt-error.h" +#include "ttt-lex.h" #include "ttt-server.h" #include "ttt-socket.h" -#include "ttt-error.h" +#include "ttt-token.h" struct _ttt_client { pthread_mutex_t mutex; @@ -31,34 +33,35 @@ struct _ttt_client { ttt_server_t *server; int socket; + yyscan_t scanner; int id; - char buf[TTT_CLIENT_BUF_SIZE]; - char *buf_head; - char *buf_tail; - - char *request; - int request_size; - int request_len; + char **request_strings; + int num_request_strings; }; +static void +_free_request (ttt_client_t *client); + static void _ttt_client_init (ttt_client_t *client, ttt_server_t *server, int socket) { + FILE *file; + pthread_mutex_init (&client->mutex, NULL); client->server = server; client->socket = socket; - client->buf_head = client->buf; - client->buf_tail = client->buf; + file = xfdopen (socket, "r"); + yylex_init(&client->scanner); + yyset_in (file, client->scanner); - client->request = NULL; - client->request_size = 0; - client->request_len = 0; + client->request_strings = NULL; + client->num_request_strings = 0; /* XXX: Probably want to register only as the result of the HELO command. Not only will that match the protocol correctly, but @@ -73,97 +76,76 @@ _ttt_client_fini (ttt_client_t *client) ttt_server_unregister_client (client->server, client); + yylex_destroy (client->scanner); shutdown (client->socket, SHUT_RDWR); - free (client->request); + _free_request (client); pthread_mutex_unlock (&client->mutex); pthread_mutex_destroy (&client->mutex); } +/* XXX: The memory management for the request strings is pretty cheesy. */ static void _append_to_request (ttt_client_t *client, - const char *buf, - int size) + const char *string) { - int size_needed = client->request_len + size; - - if (size_needed > client->request_size) { - if (client->request_size == 0) { - client->request_size = size_needed; - } else { - while (size_needed > client->request_size) - client->request_size *= 2; - } + client->num_request_strings++; + client->request_strings = + xrealloc (client->request_strings, + client->num_request_strings * sizeof (char *)); - client->request = xrealloc (client->request, client->request_size); - } - - memcpy (client->request + client->request_len, - buf, size); - - client->request_len += size; + client->request_strings[client->num_request_strings - 1] = xstrdup (string); } -static ttt_status_t -_read_into_request_until (ttt_client_t *client, char delimeter) +static void +_free_request (ttt_client_t *client) { - ttt_bool_t found_delimeter = FALSE; - int bytes_read; - char *s; + int i; - client->request_len = 0; + for (i = 0; i < client->num_request_strings; i++) + free (client->request_strings[i]); - while (1) { + free (client->request_strings); - if (client->buf_tail >= client->buf_head) { - bytes_read = xread (client->socket, - client->buf, - TTT_CLIENT_BUF_SIZE); - if (bytes_read == 0) - return TTT_STATUS_EOF; - client->buf_head = client->buf; - client->buf_tail = client->buf_head + bytes_read; - } - - for (s = client->buf_head; s < client->buf_tail; s++) { - if (*s == delimeter) { - found_delimeter = TRUE; - s++; - break; - } - } - - _append_to_request (client, - client->buf_head, - s - client->buf_head); - client->buf_head = s; - - if (found_delimeter) - return TTT_STATUS_SUCCESS; - } + client->request_strings = NULL; + client->num_request_strings = 0; } static ttt_status_t _read_request (ttt_client_t *client) { - ttt_status_t status; - static const char null_terminator = '\0'; + ttt_token_t token; + + _free_request (client); - status = _read_into_request_until (client, '\n'); - if (status) - return status; + while (1) { + token = yylex (client->scanner); + /* Yes, EOF in two different enums is pretty ugly. */ + if (token == TTT_TOKEN_EOF) + return TTT_STATUS_EOF; + + if (token == TTT_TOKEN_NEWLINE) { + if (client->num_request_strings) + return TTT_STATUS_SUCCESS; + else + continue; + } - _append_to_request (client, &null_terminator, 1); + assert (token == TTT_TOKEN_STRING); - return TTT_STATUS_SUCCESS; + _append_to_request (client, yyget_text (client->scanner)); + } } static ttt_error_t _execute_request (ttt_client_t *client) { - ttt_server_broadcast (client->server, client->request); + int i; + + for (i=0; i < client->num_request_strings; i++) + ttt_server_broadcast (client->server, client->request_strings[i]); return TTT_ERROR_NONE; }