|
|
@ -11,6 +11,18 @@ |
|
|
|
#include "common.h" |
|
|
|
#include "common.h" |
|
|
|
#include "client.h" |
|
|
|
#include "client.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_READLINE |
|
|
|
|
|
|
|
#include <readline/readline.h> |
|
|
|
|
|
|
|
#include <readline/history.h> |
|
|
|
|
|
|
|
#else |
|
|
|
|
|
|
|
/* stubs */ |
|
|
|
|
|
|
|
#define add_history(x) (void)(x) |
|
|
|
|
|
|
|
#define using_history() |
|
|
|
|
|
|
|
#define rl_clear_visible_line() |
|
|
|
|
|
|
|
#define rl_on_new_line() |
|
|
|
|
|
|
|
#define rl_redisplay() |
|
|
|
|
|
|
|
#endif /* WITH_READLINE */ |
|
|
|
|
|
|
|
|
|
|
|
struct { |
|
|
|
struct { |
|
|
|
enum { interactive = 0, oneshot } mode; |
|
|
|
enum { interactive = 0, oneshot } mode; |
|
|
|
char spath[PATH_MAX]; |
|
|
|
char spath[PATH_MAX]; |
|
|
@ -29,6 +41,16 @@ void usage(int exitcode) { |
|
|
|
exit(exitcode); |
|
|
|
exit(exitcode); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
|
|
|
handle_print(const char *buf, size_t len, bool last) { |
|
|
|
|
|
|
|
rl_clear_visible_line(); |
|
|
|
|
|
|
|
if (len == 0) len = strlen(buf); |
|
|
|
|
|
|
|
fwrite(buf, len, 1, stdout); |
|
|
|
|
|
|
|
if (last) return; |
|
|
|
|
|
|
|
rl_on_new_line(); |
|
|
|
|
|
|
|
rl_redisplay(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
int |
|
|
|
handle_recv() { |
|
|
|
handle_recv() { |
|
|
|
char buf[WBUF_SIZE] = ""; /* our "read" is server "write" */ |
|
|
|
char buf[WBUF_SIZE] = ""; /* our "read" is server "write" */ |
|
|
@ -39,14 +61,14 @@ handle_recv() { |
|
|
|
|
|
|
|
|
|
|
|
ret = recv(csock, &buf, sizeof(buf), MSG_DONTWAIT); |
|
|
|
ret = recv(csock, &buf, sizeof(buf), MSG_DONTWAIT); |
|
|
|
if (ret > 0) { |
|
|
|
if (ret > 0) { |
|
|
|
write(fileno(stdout), buf, ret); |
|
|
|
handle_print(buf, ret, false); |
|
|
|
} else if (ret == 0) { |
|
|
|
} else if (ret == 0) { |
|
|
|
puts("connection closed"); |
|
|
|
handle_print("connection closed\n", 0, true); |
|
|
|
exit(EXIT_SUCCESS); /* received EOF */ |
|
|
|
exit(EXIT_SUCCESS); /* received EOF */ |
|
|
|
} else if (ret < 0 && errno == EAGAIN) { |
|
|
|
} else if (ret < 0 && errno == EAGAIN) { |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} else /* ret < 0 */ { |
|
|
|
} else /* ret < 0 */ { |
|
|
|
perror("recv()"); |
|
|
|
handle_print(strerror(errno), 0, true); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
exit(EXIT_FAILURE); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
@ -122,12 +144,10 @@ setup_socket() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_READLINE |
|
|
|
#ifdef WITH_READLINE |
|
|
|
#include <readline/readline.h> |
|
|
|
|
|
|
|
#include <readline/history.h> |
|
|
|
|
|
|
|
rl_hook_func_t *rl_event_hook = &handle_recv; |
|
|
|
rl_hook_func_t *rl_event_hook = &handle_recv; |
|
|
|
#else |
|
|
|
#else |
|
|
|
char * |
|
|
|
char * |
|
|
|
readline(const char *prompt) { |
|
|
|
readline(const char *prompt) { |
|
|
|
char line[RBUF_SIZE+1]; |
|
|
|
char line[RBUF_SIZE+1]; |
|
|
|
char *p; |
|
|
|
char *p; |
|
|
|
|
|
|
|
|
|
|
@ -146,12 +166,8 @@ readline(const char *prompt) { |
|
|
|
return strdup(p); |
|
|
|
return strdup(p); |
|
|
|
} |
|
|
|
} |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif /* WITH_READLINE */ |
|
|
|
/* stubs */ |
|
|
|
|
|
|
|
#define add_history(x) (void)(x); |
|
|
|
|
|
|
|
#define using_history() |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
int main(int argc, char *argv[]) { |
|
|
|
char *line = NULL; |
|
|
|
char *line = NULL; |
|
|
|