summaryrefslogtreecommitdiff
path: root/accel-pppd/cli
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd/cli')
-rw-r--r--accel-pppd/cli/std_cmd.c2
-rw-r--r--accel-pppd/cli/tcp.c49
-rw-r--r--accel-pppd/cli/telnet.c55
3 files changed, 68 insertions, 38 deletions
diff --git a/accel-pppd/cli/std_cmd.c b/accel-pppd/cli/std_cmd.c
index 62327f92..500102b0 100644
--- a/accel-pppd/cli/std_cmd.c
+++ b/accel-pppd/cli/std_cmd.c
@@ -20,7 +20,7 @@ void core_restart(int);
static int show_stat_exec(const char *cmd, char * const *fields, int fields_cnt, void *client)
{
struct timespec ts;
- time_t dt;
+ unsigned long dt;
int day,hour;
char statm_fname[128];
FILE *f;
diff --git a/accel-pppd/cli/tcp.c b/accel-pppd/cli/tcp.c
index 2a6bfdee..051ff84c 100644
--- a/accel-pppd/cli/tcp.c
+++ b/accel-pppd/cli/tcp.c
@@ -95,7 +95,7 @@ static int cli_client_send(struct cli_client_t *tcln, const void *_buf, int size
if (cln->disconnect)
return -1;
- if (!list_empty(&cln->xmit_queue)) {
+ if (cln->xmit_buf) {
b = _malloc(sizeof(*b) + size);
b->size = size;
memcpy(b->buf, buf, size);
@@ -109,7 +109,7 @@ static int cli_client_send(struct cli_client_t *tcln, const void *_buf, int size
if (errno == EAGAIN) {
b = _malloc(sizeof(*b) + size - n);
b->size = size - n;
- memcpy(b->buf, buf, size - n);
+ memcpy(b->buf, buf + n, size - n);
queue_buffer(cln, b);
triton_md_enable_handler(&cln->hnd, MD_MODE_WRITE);
@@ -147,7 +147,7 @@ static int cln_read(struct triton_md_handler_t *h)
while (1) {
n = read(h->fd, cln->cmdline + cln->recv_pos, RECV_BUF_SIZE - 1 - cln->recv_pos);
if (n == 0)
- break;
+ goto disconn_soft;
if (n < 0) {
if (errno != EAGAIN)
log_error("cli: read: %s\n", strerror(errno));
@@ -162,7 +162,7 @@ static int cln_read(struct triton_md_handler_t *h)
if (!d) {
if (cln->recv_pos == RECV_BUF_SIZE - 1) {
log_warn("cli: tcp: recv buffer overflow\n");
- goto drop;
+ goto disconn_hard;
}
break;
}
@@ -171,7 +171,7 @@ static int cln_read(struct triton_md_handler_t *h)
if (!cln->auth) {
if (strcmp((char *)cln->cmdline, conf_cli_passwd))
- goto drop;
+ goto disconn_hard;
cln->auth = 1;
} else {
if (conf_verbose == 2)
@@ -181,15 +181,25 @@ static int cln_read(struct triton_md_handler_t *h)
}
if (cln->disconnect)
- goto drop;
+ goto disconn_soft;
cln->recv_pos -= (uint8_t *)d + 1 - cln->cmdline;
memmove(cln->cmdline, d + 1, cln->recv_pos);
}
}
-drop:
+disconn_soft:
+ /* Wait for pending data to be transmitted before disconnecting */
+ if (cln->xmit_buf) {
+ triton_md_disable_handler(&cln->hnd, MD_MODE_READ);
+ cln->disconnect = 1;
+
+ return 0;
+ }
+
+disconn_hard:
disconnect(cln);
+
return -1;
}
@@ -198,10 +208,7 @@ static int cln_write(struct triton_md_handler_t *h)
struct tcp_client_t *cln = container_of(h, typeof(*cln), hnd);
int k;
- if (!cln->xmit_buf)
- return 0;
-
- while (1) {
+ while (cln->xmit_buf) {
for (; cln->xmit_pos < cln->xmit_buf->size; cln->xmit_pos += k) {
k = write(cln->hnd.fd, cln->xmit_buf->buf + cln->xmit_pos, cln->xmit_buf->size - cln->xmit_pos);
if (k < 0) {
@@ -209,8 +216,7 @@ static int cln_write(struct triton_md_handler_t *h)
return 0;
if (errno != EPIPE)
log_error("cli: tcp: write: %s\n", strerror(errno));
- disconnect(cln);
- return -1;
+ goto disconn;
}
}
@@ -219,16 +225,25 @@ static int cln_write(struct triton_md_handler_t *h)
if (list_empty(&cln->xmit_queue)) {
cln->xmit_buf = NULL;
- break;
+ } else {
+ cln->xmit_buf = list_first_entry(&cln->xmit_queue,
+ typeof(*cln->xmit_buf),
+ entry);
+ list_del(&cln->xmit_buf->entry);
}
-
- cln->xmit_buf = list_entry(cln->xmit_queue.next, typeof(*cln->xmit_buf), entry);
- list_del(&cln->xmit_buf->entry);
}
+ if (cln->disconnect)
+ goto disconn;
+
triton_md_disable_handler(&cln->hnd, MD_MODE_WRITE);
return 0;
+
+disconn:
+ disconnect(cln);
+
+ return -1;
}
static int serv_read(struct triton_md_handler_t *h)
diff --git a/accel-pppd/cli/telnet.c b/accel-pppd/cli/telnet.c
index de2f39ff..9ef2ea84 100644
--- a/accel-pppd/cli/telnet.c
+++ b/accel-pppd/cli/telnet.c
@@ -143,7 +143,7 @@ static int telnet_send(struct telnet_client_t *cln, const void *_buf, int size)
if (cln->disconnect)
return -1;
- if (!list_empty(&cln->xmit_queue)) {
+ if (cln->xmit_buf) {
b = _malloc(sizeof(*b) + size);
b->size = size;
memcpy(b->buf, buf, size);
@@ -157,7 +157,7 @@ static int telnet_send(struct telnet_client_t *cln, const void *_buf, int size)
if (errno == EAGAIN) {
b = _malloc(sizeof(*b) + size - n);
b->size = size - n;
- memcpy(b->buf, buf, size - n);
+ memcpy(b->buf, buf + n, size - n);
queue_buffer(cln, b);
triton_md_enable_handler(&cln->hnd, MD_MODE_WRITE);
@@ -477,10 +477,8 @@ static int cln_read(struct triton_md_handler_t *h)
while (1) {
n = read(h->fd, recv_buf, RECV_BUF_SIZE);
- if (n == 0) {
- disconnect(cln);
- return -1;
- }
+ if (n == 0)
+ goto disconn_soft;
if (n < 0) {
if (errno != EAGAIN)
log_error("cli: telnet: read: %s\n", strerror(errno));
@@ -492,13 +490,25 @@ static int cln_read(struct triton_md_handler_t *h)
if (telnet_input_char(cln, recv_buf[i]))
break;
}
- if (cln->disconnect) {
- disconnect(cln);
- return -1;
- }
+
+ if (cln->disconnect)
+ goto disconn_soft;
}
return 0;
+
+disconn_soft:
+ /* Wait for pending data to be transmitted before disconnecting */
+ if (cln->xmit_buf) {
+ triton_md_disable_handler(&cln->hnd, MD_MODE_READ);
+ cln->disconnect = 1;
+
+ return 0;
+ }
+
+ disconnect(cln);
+
+ return -1;
}
static int cln_write(struct triton_md_handler_t *h)
@@ -506,10 +516,7 @@ static int cln_write(struct triton_md_handler_t *h)
struct telnet_client_t *cln = container_of(h, typeof(*cln), hnd);
int k;
- if (!cln->xmit_buf)
- return 0;
-
- while (1) {
+ while (cln->xmit_buf) {
for (; cln->xmit_pos < cln->xmit_buf->size; cln->xmit_pos += k) {
k = write(cln->hnd.fd, cln->xmit_buf->buf + cln->xmit_pos, cln->xmit_buf->size - cln->xmit_pos);
if (k < 0) {
@@ -517,8 +524,7 @@ static int cln_write(struct triton_md_handler_t *h)
return 0;
if (errno != EPIPE)
log_error("cli: telnet: write: %s\n", strerror(errno));
- disconnect(cln);
- return -1;
+ goto disconn;
}
}
@@ -527,16 +533,25 @@ static int cln_write(struct triton_md_handler_t *h)
if (list_empty(&cln->xmit_queue)) {
cln->xmit_buf = NULL;
- break;
+ } else {
+ cln->xmit_buf = list_first_entry(&cln->xmit_queue,
+ typeof(*cln->xmit_buf),
+ entry);
+ list_del(&cln->xmit_buf->entry);
}
-
- cln->xmit_buf = list_entry(cln->xmit_queue.next, typeof(*cln->xmit_buf), entry);
- list_del(&cln->xmit_buf->entry);
}
+ if (cln->disconnect)
+ goto disconn;
+
triton_md_disable_handler(&cln->hnd, MD_MODE_WRITE);
return 0;
+
+disconn:
+ disconnect(cln);
+
+ return -1;
}
static int serv_read(struct triton_md_handler_t *h)