|
|
@ -29,6 +29,29 @@ void usage(int exitcode) { |
|
|
|
exit(exitcode); |
|
|
|
exit(exitcode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
|
|
|
handle_recv() { |
|
|
|
|
|
|
|
char buf[WBUF_SIZE] = ""; /* our "read" is server "write" */ |
|
|
|
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (csock < 0) |
|
|
|
|
|
|
|
return 0; /* not connected */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret = recv(csock, &buf, sizeof(buf), MSG_DONTWAIT); |
|
|
|
|
|
|
|
if (ret > 0) { |
|
|
|
|
|
|
|
write(fileno(stdout), buf, ret); |
|
|
|
|
|
|
|
} else if (ret == 0) { |
|
|
|
|
|
|
|
puts("connection closed"); |
|
|
|
|
|
|
|
exit(EXIT_SUCCESS); /* received EOF */ |
|
|
|
|
|
|
|
} else if (ret < 0 && errno == EAGAIN) { |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} else /* ret < 0 */ { |
|
|
|
|
|
|
|
perror("recv()"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
int |
|
|
|
handle_cmd(const char *line) { |
|
|
|
handle_cmd(const char *line) { |
|
|
|
const char *p = NULL; |
|
|
|
const char *p = NULL; |
|
|
@ -42,7 +65,6 @@ handle_cmd(const char *line) { |
|
|
|
while (p && *p != '\0') { |
|
|
|
while (p && *p != '\0') { |
|
|
|
len = strlen(p); |
|
|
|
len = strlen(p); |
|
|
|
ret = send(csock, p, strlen(p), 0); |
|
|
|
ret = send(csock, p, strlen(p), 0); |
|
|
|
/* blocks only for a second, see timeouts */ |
|
|
|
|
|
|
|
if (ret < 0 && errno == EAGAIN) { |
|
|
|
if (ret < 0 && errno == EAGAIN) { |
|
|
|
continue; /* try again */ |
|
|
|
continue; /* try again */ |
|
|
|
} else if (ret < 0) { |
|
|
|
} else if (ret < 0) { |
|
|
@ -55,23 +77,6 @@ handle_cmd(const char *line) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
while (1) { |
|
|
|
|
|
|
|
ret = recv(csock, &buf, sizeof(buf), 0); |
|
|
|
|
|
|
|
/* blocks only for a second, see timeouts */ |
|
|
|
|
|
|
|
if (ret > 0) { |
|
|
|
|
|
|
|
write(fileno(stdout), buf, ret); |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} else if (ret == 0) { |
|
|
|
|
|
|
|
puts("connection closed"); |
|
|
|
|
|
|
|
exit(EXIT_SUCCESS); /* received EOF */ |
|
|
|
|
|
|
|
} else if (ret < 0 && errno == EAGAIN) { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} else /* ret < 0 */ { |
|
|
|
|
|
|
|
perror("recv()"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -101,25 +106,12 @@ setup_sigaction(int signum) { |
|
|
|
void |
|
|
|
void |
|
|
|
setup_socket() { |
|
|
|
setup_socket() { |
|
|
|
struct sockaddr_un saddr; |
|
|
|
struct sockaddr_un saddr; |
|
|
|
struct timeval tv; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((csock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { |
|
|
|
if ((csock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { |
|
|
|
perror("socket()"); |
|
|
|
perror("socket()"); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
tv.tv_sec = 1, tv.tv_usec = 0; |
|
|
|
|
|
|
|
if (setsockopt(csock, SOL_SOCKET, SO_RCVTIMEO, (void *) &tv, sizeof(struct timeval)) < 0) { |
|
|
|
|
|
|
|
perror("setsockopt() - recv"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tv.tv_sec = 1, tv.tv_usec = 0; |
|
|
|
|
|
|
|
if (setsockopt(csock, SOL_SOCKET, SO_SNDTIMEO, (void *) &tv, sizeof(struct timeval)) < 0) { |
|
|
|
|
|
|
|
perror("setsockopt() - send"); |
|
|
|
|
|
|
|
exit(EXIT_FAILURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
memset(&saddr, 0x0, sizeof(saddr)); |
|
|
|
memset(&saddr, 0x0, sizeof(saddr)); |
|
|
|
saddr.sun_family = AF_UNIX; |
|
|
|
saddr.sun_family = AF_UNIX; |
|
|
|
strlcpy(saddr.sun_path, opts.spath, sizeof(saddr.sun_path) - 1); |
|
|
|
strlcpy(saddr.sun_path, opts.spath, sizeof(saddr.sun_path) - 1); |
|
|
@ -132,22 +124,21 @@ setup_socket() { |
|
|
|
#ifdef WITH_READLINE |
|
|
|
#ifdef WITH_READLINE |
|
|
|
#include <readline/readline.h> |
|
|
|
#include <readline/readline.h> |
|
|
|
#include <readline/history.h> |
|
|
|
#include <readline/history.h> |
|
|
|
|
|
|
|
rl_event_hook = &handle_recv; |
|
|
|
#else |
|
|
|
#else |
|
|
|
char * |
|
|
|
char * |
|
|
|
readline(const char *prompt) { |
|
|
|
readline(const char *prompt) { |
|
|
|
char line[INPUT_LINE_MAX]; |
|
|
|
char line[RBUF_SIZE+1]; |
|
|
|
char *p; |
|
|
|
char *p; |
|
|
|
|
|
|
|
|
|
|
|
while (1) { |
|
|
|
while (1) { |
|
|
|
line[0] = '\0'; |
|
|
|
line[0] = '\0'; |
|
|
|
p = &line[0]; |
|
|
|
p = &line[0]; |
|
|
|
|
|
|
|
handle_recv(); |
|
|
|
fputs(prompt, stdout); |
|
|
|
fputs(prompt, stdout); |
|
|
|
if (!fgets(line, sizeof(line) - 1, stdin)) { |
|
|
|
if (!fgets(line, sizeof(line) - 1, stdin)) { |
|
|
|
if (feof(stdin)) { |
|
|
|
if (!feof(stdin)) |
|
|
|
fputc('\n', stdout); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
fputs("read error\n", stdout); |
|
|
|
fputs("read error\n", stdout); |
|
|
|
} |
|
|
|
|
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
while (isspace(*p)) p++; |
|
|
|
while (isspace(*p)) p++; |
|
|
|