Browse Source

correct how data from mgmt itf is received

pull/1/head
Heiko Hund 12 years ago
parent
commit
15287dc5ea
  1. 82
      manage.c
  2. 2
      options.h

82
manage.c

@ -190,8 +190,9 @@ void
OnManagement(SOCKET sk, LPARAM lParam) OnManagement(SOCKET sk, LPARAM lParam)
{ {
int res; int res;
char *pos = NULL; char *data;
char data[MAX_LOG_LENGTH]; ULONG data_size, offset;
connection_t *c = GetConnByManagement(sk); connection_t *c = GetConnByManagement(sk);
if (c == NULL) if (c == NULL)
return; return;
@ -199,7 +200,8 @@ OnManagement(SOCKET sk, LPARAM lParam)
switch (WSAGETSELECTEVENT(lParam)) switch (WSAGETSELECTEVENT(lParam))
{ {
case FD_CONNECT: case FD_CONNECT:
if (WSAGETSELECTERROR(lParam)) { if (WSAGETSELECTERROR(lParam))
{
if (time(NULL) < c->manage.timeout) if (time(NULL) < c->manage.timeout)
connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr));
else else
@ -208,34 +210,66 @@ OnManagement(SOCKET sk, LPARAM lParam)
break; break;
case FD_READ: case FD_READ:
/* Check if there's a complete line to read */ if (ioctlsocket(c->manage.sk, FIONREAD, &data_size) != 0
res = recv(c->manage.sk, data, sizeof(data), MSG_PEEK); || data_size == 0)
if (res < 1)
return; return;
pos = memchr(data, (*c->manage.password ? ':' : '\n'), res); data = malloc(c->manage.saved_size + data_size);
if (!pos) if (data == NULL)
return; return;
/* There is data available: read it */ res = recv(c->manage.sk, data + c->manage.saved_size, data_size, 0);
res = recv(c->manage.sk, data, pos - data + 1, 0); if (res != (int) data_size)
if (res != pos - data + 1) {
free(data);
return; return;
}
/* Copy previously saved management data */
if (c->manage.saved_size)
{
memcpy(data, c->manage.saved_data, c->manage.saved_size);
data_size += c->manage.saved_size;
free(c->manage.saved_data);
c->manage.saved_data = NULL;
c->manage.saved_size = 0;
}
offset = 0;
while (offset < data_size)
{
char *pos;
char *line = data + offset;
size_t line_size = data_size - offset;
pos = memchr(line, (*c->manage.password ? ':' : '\n'), line_size);
if (pos == NULL)
{
c->manage.saved_data = malloc(data_size);
if (c->manage.saved_data)
{
c->manage.saved_size = data_size;
memcpy(c->manage.saved_data, line, c->manage.saved_size);
}
break;
}
offset += (pos - line) + 1;
/* Reply to a management password request */ /* Reply to a management password request */
if (*c->manage.password) if (*c->manage.password)
{ {
ManagementCommand(c, c->manage.password, NULL, regular); ManagementCommand(c, c->manage.password, NULL, regular);
*c->manage.password = '\0'; *c->manage.password = '\0';
return; continue;
} }
/* Handle regular management interface output */ /* Handle regular management interface output */
data[pos - data - 1] = '\0'; line[pos - line - 1] = '\0';
if (data[0] == '>') if (line[0] == '>')
{ {
/* Real time notifications */ /* Real time notifications */
pos = data + 1; pos = line + 1;
if (strncmp(pos, "LOG:", 4) == 0) if (strncmp(pos, "LOG:", 4) == 0)
{ {
if (rtmsg_handler[log]) if (rtmsg_handler[log])
@ -273,27 +307,29 @@ OnManagement(SOCKET sk, LPARAM lParam)
{ {
/* Response to commands */ /* Response to commands */
mgmt_cmd_t *cmd = c->manage.cmd_queue; mgmt_cmd_t *cmd = c->manage.cmd_queue;
if (strncmp(data, "SUCCESS:", 8) == 0) if (strncmp(line, "SUCCESS:", 8) == 0)
{ {
if (cmd->handler) if (cmd->handler)
cmd->handler(c, data + 9); cmd->handler(c, line + 9);
UnqueueCommand(c); UnqueueCommand(c);
} }
else if (strncmp(data, "ERROR:", 6) == 0) else if (strncmp(line, "ERROR:", 6) == 0)
{ {
if (cmd->handler) if (cmd->handler)
cmd->handler(c, NULL); cmd->handler(c, NULL);
UnqueueCommand(c); UnqueueCommand(c);
} }
else if (strcmp(data, "END") == 0) else if (strcmp(line, "END") == 0)
{ {
UnqueueCommand(c); UnqueueCommand(c);
} }
else if (cmd->handler) else if (cmd->handler)
{ {
cmd->handler(c, data); cmd->handler(c, line);
}
} }
} }
free(data);
break; break;
case FD_WRITE: case FD_WRITE:
@ -301,6 +337,12 @@ OnManagement(SOCKET sk, LPARAM lParam)
break; break;
case FD_CLOSE: case FD_CLOSE:
if (c->manage.saved_size)
{
free(c->manage.saved_data);
c->manage.saved_data = NULL;
c->manage.saved_size = 0;
}
closesocket(c->manage.sk); closesocket(c->manage.sk);
c->manage.sk = INVALID_SOCKET; c->manage.sk = INVALID_SOCKET;
while (UnqueueCommand(c)) while (UnqueueCommand(c))

2
options.h

@ -88,6 +88,8 @@ struct connection {
SOCKADDR_IN skaddr; SOCKADDR_IN skaddr;
time_t timeout; time_t timeout;
char password[16]; char password[16];
char *saved_data;
size_t saved_size;
mgmt_cmd_t *cmd_queue; mgmt_cmd_t *cmd_queue;
} manage; } manage;

Loading…
Cancel
Save