version 1.16, 2019/01/21 12:53:35 |
version 1.17, 2019/01/23 02:01:10 |
|
|
#include <sys/queue.h> |
#include <sys/queue.h> |
#include <sys/time.h> |
#include <sys/time.h> |
|
|
|
#include <errno.h> |
|
#include <poll.h> |
#include <stdarg.h> |
#include <stdarg.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <errno.h> |
|
|
|
#include "xmalloc.h" |
#include "xmalloc.h" |
#include "sshbuf.h" |
#include "sshbuf.h" |
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
fd_set *rset, *wset; |
|
int r, ch, in, out, max, log_stderr = 0; |
int r, ch, in, out, max, log_stderr = 0; |
ssize_t len, olen, set_size; |
ssize_t len; |
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; |
SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; |
LogLevel log_level = SYSLOG_LEVEL_ERROR; |
LogLevel log_level = SYSLOG_LEVEL_ERROR; |
char buf[4*4096]; |
char buf[4*4096]; |
extern char *__progname; |
extern char *__progname; |
|
struct pollfd pfd[2]; |
|
|
ssh_malloc_init(); /* must be called before any mallocs */ |
ssh_malloc_init(); /* must be called before any mallocs */ |
TAILQ_INIT(&pkcs11_keylist); |
TAILQ_INIT(&pkcs11_keylist); |
|
|
if ((oqueue = sshbuf_new()) == NULL) |
if ((oqueue = sshbuf_new()) == NULL) |
fatal("%s: sshbuf_new failed", __func__); |
fatal("%s: sshbuf_new failed", __func__); |
|
|
set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask); |
while (1) { |
rset = xmalloc(set_size); |
memset(pfd, 0, sizeof(pfd)); |
wset = xmalloc(set_size); |
pfd[0].fd = in; |
|
pfd[1].fd = out; |
|
|
for (;;) { |
|
memset(rset, 0, set_size); |
|
memset(wset, 0, set_size); |
|
|
|
/* |
/* |
* Ensure that we can read a full buffer and handle |
* Ensure that we can read a full buffer and handle |
* the worst-case length packet it can generate, |
* the worst-case length packet it can generate, |
|
|
*/ |
*/ |
if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && |
if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 && |
(r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0) |
(r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0) |
FD_SET(in, rset); |
pfd[0].events = POLLIN; |
else if (r != SSH_ERR_NO_BUFFER_SPACE) |
else if (r != SSH_ERR_NO_BUFFER_SPACE) |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
|
|
olen = sshbuf_len(oqueue); |
if (sshbuf_len(oqueue) > 0) |
if (olen > 0) |
pfd[1].events = POLLOUT; |
FD_SET(out, wset); |
|
|
|
if (select(max+1, rset, wset, NULL, NULL) < 0) { |
if ((r = poll(pfd, 2, -1 /* INFTIM */)) <= 0) { |
if (errno == EINTR) |
if (r == 0 || errno == EINTR) |
continue; |
continue; |
error("select: %s", strerror(errno)); |
fatal("poll: %s", strerror(errno)); |
cleanup_exit(2); |
|
} |
} |
|
|
/* copy stdin to iqueue */ |
/* copy stdin to iqueue */ |
if (FD_ISSET(in, rset)) { |
if ((pfd[0].revents & (POLLIN|POLLERR)) != 0) { |
len = read(in, buf, sizeof buf); |
len = read(in, buf, sizeof buf); |
if (len == 0) { |
if (len == 0) { |
debug("read eof"); |
debug("read eof"); |
|
|
} |
} |
} |
} |
/* send oqueue to stdout */ |
/* send oqueue to stdout */ |
if (FD_ISSET(out, wset)) { |
if ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) { |
len = write(out, sshbuf_ptr(oqueue), olen); |
len = write(out, sshbuf_ptr(oqueue), |
|
sshbuf_len(oqueue)); |
if (len < 0) { |
if (len < 0) { |
error("write: %s", strerror(errno)); |
error("write: %s", strerror(errno)); |
cleanup_exit(1); |
cleanup_exit(1); |