Pulled some duplicated code out of control.c into

read_lines_until_blankline.
This commit is contained in:
mbloch
2012-05-23 14:03:30 +01:00
parent 9c26f7f36f
commit d5d6e0f55d
3 changed files with 76 additions and 60 deletions

117
control.c
View File

@@ -49,8 +49,9 @@ void* mirror_runner(void* serve_params_uncast)
return NULL; return NULL;
} }
#define write_socket(msg) write(client->socket, (msg "\n"), strlen((msg))+1)
void control_mirror(struct control_params* client) int control_mirror(struct control_params* client, int linesc, char** lines)
{ {
off64_t size, remote_size; off64_t size, remote_size;
int fd, map_fd; int fd, map_fd;
@@ -58,25 +59,24 @@ void control_mirror(struct control_params* client)
union mysockaddr connect_to; union mysockaddr connect_to;
char s_ip_address[64], s_port[8]; char s_ip_address[64], s_port[8];
CLIENT_ERROR_ON_FAILURE( if (linesc != 2) {
read_until_newline(client->socket, s_ip_address, 64), write_socket("1: mirror only takes two parameters");
"Failed to read destination IP" return -1;
); }
CLIENT_ERROR_ON_FAILURE(
read_until_newline(client->socket, s_port, 8), if (parse_ip_to_sockaddr(&connect_to.generic, s_ip_address) == 0) {
"Failed to read destination port" write_socket("1: bad IP address");
); return -1;
}
if (parse_ip_to_sockaddr(&connect_to.generic, s_ip_address) == 0)
CLIENT_ERROR("Couldn't parse connection address '%s'",
s_ip_address);
connect_to.v4.sin_port = atoi(s_port); connect_to.v4.sin_port = atoi(s_port);
if (connect_to.v4.sin_port < 0 || connect_to.v4.sin_port > 65535) if (connect_to.v4.sin_port < 0 || connect_to.v4.sin_port > 65535) {
CLIENT_ERROR("Port number must be >= 0 and <= 65535"); write_socket("1: bad IP port number");
return -1;
}
connect_to.v4.sin_port = htobe16(connect_to.v4.sin_port); connect_to.v4.sin_port = htobe16(connect_to.v4.sin_port);
fd = socket_connect(&connect_to.generic); /* FIXME uses wrong error handler */ fd = socket_connect(&connect_to.generic);
remote_size = socket_nbd_read_hello(fd); remote_size = socket_nbd_read_hello(fd);
remote_size = remote_size; // shush compiler remote_size = remote_size; // shush compiler
@@ -110,32 +110,19 @@ void control_mirror(struct control_params* client)
), ),
"Failed to create mirror thread" "Failed to create mirror thread"
); );
return 0;
} }
void control_acl(struct control_params* client) int control_acl(struct control_params* client, int linesc, char** lines)
{ {
int acl_entries = 0, parsed; int acl_entries = 0, parsed;
char** s_acl_entry = NULL; char** s_acl_entry = NULL;
struct ip_and_mask (*acl)[], (*old_acl)[]; struct ip_and_mask (*acl)[], (*old_acl)[];
while (1) { parsed = parse_acl(&acl, linesc, lines);
char entry[64]; if (parsed != linesc) {
int result = read_until_newline(client->socket, entry, 64); write(client->socket, "3: bad spec ", 12);
if (result == -1)
goto done;
if (result == 1) /* blank line terminates */
break;
s_acl_entry = xrealloc(
s_acl_entry,
++acl_entries * sizeof(struct s_acl_entry*)
);
s_acl_entry[acl_entries-1] = strdup(entry);
debug("acl_entry = '%s'", s_acl_entry[acl_entries-1]);
}
parsed = parse_acl(&acl, acl_entries, s_acl_entry);
if (parsed != acl_entries) {
write(client->socket, "error: ", 7);
write(client->socket, s_acl_entry[parsed], write(client->socket, s_acl_entry[parsed],
strlen(s_acl_entry[parsed])); strlen(s_acl_entry[parsed]));
write(client->socket, "\n", 1); write(client->socket, "\n", 1);
@@ -146,43 +133,53 @@ void control_acl(struct control_params* client)
client->serve->acl = acl; client->serve->acl = acl;
client->serve->acl_entries = acl_entries; client->serve->acl_entries = acl_entries;
free(old_acl); free(old_acl);
write(client->socket, "ok\n", 3); write_socket("0: updated");
} }
done: if (acl_entries > 0) { return 0;
int i;
for (i=0; i<acl_entries; i++)
free(s_acl_entry[i]);
free(s_acl_entry);
}
return;
} }
void control_status(struct control_params* client) int control_status(struct control_params* client, int linesc, char** lines)
{ {
return 0;
} }
void* control_serve(void* client_uncast) void* control_serve(void* client_uncast)
{ {
const int max = 256;
char command[max];
struct control_params* client = (struct control_params*) client_uncast; struct control_params* client = (struct control_params*) client_uncast;
char **lines = NULL;
int finished=0;
while (1) { while (!finished) {
CLIENT_ERROR_ON_FAILURE( int i, linesc;
read_until_newline(client->socket, command, max), linesc = read_lines_until_blankline(client->socket, 256, &lines);
"Error reading command"
);
if (strcmp(command, "acl") == 0) if (linesc < 1)
control_acl(client); {
else if (strcmp(command, "mirror") == 0) write(client->socket, "9: missing command\n", 19);
control_mirror(client); finished = 1;
else if (strcmp(command, "status") == 0) /* ignore failure */
control_status(client);
else {
write(client->socket, "error: unknown command\n", 23);
break;
} }
else if (strcmp(lines[0], "acl") == 0) {
if (control_acl(client, linesc-1, lines+1) < 0)
finished = 1;
}
else if (strcmp(lines[0], "mirror") == 0) {
if (control_mirror(client, linesc-1, lines+1) < 0)
finished = 1;
}
else if (strcmp(lines[0], "status") == 0) {
if (control_status(client, linesc-1, lines+1) < 0)
finished = 1;
}
else {
write(client->socket, "10: unknown command\n", 23);
finished = 1;
}
for (i=0; i<linesc; i++)
free(lines[i]);
free(lines);
} }
close(client->socket); close(client->socket);

View File

@@ -184,3 +184,21 @@ int read_until_newline(int fd, char* buf, int bufsize)
return cur; return cur;
} }
int read_lines_until_blankline(int fd, int max_line_length, char ***lines)
{
int lines_count = 0;
char line[max_line_length+1];
*lines = NULL;
while (1) {
if (read_until_newline(fd, line, max_line_length) < 0)
return lines_count;
*lines = xrealloc(*lines, (lines_count+1) * sizeof(char*));
(*lines)[lines_count] = strdup(line);
if ((*lines)[lines_count][0] == 0)
return lines_count;
lines_count++;
}
}

View File

@@ -10,6 +10,7 @@ int readloop(int filedes, void *buffer, size_t size);
int sendfileloop(int out_fd, int in_fd, off64_t *offset, size_t count); int sendfileloop(int out_fd, int in_fd, off64_t *offset, size_t count);
int splice_via_pipe_loop(int fd_in, int fd_out, size_t len); int splice_via_pipe_loop(int fd_in, int fd_out, size_t len);
int read_until_newline(int fd, char* buf, int bufsize); int read_until_newline(int fd, char* buf, int bufsize);
int read_lines_until_blankline(int fd, int max_line_length, char ***lines);
int open_and_mmap(char* filename, int* out_fd, off64_t *out_size, void **out_map); int open_and_mmap(char* filename, int* out_fd, off64_t *out_size, void **out_map);
#endif #endif