mirror of
https://github.com/zhaojh329/rtty.git
synced 2026-02-27 09:53:17 +08:00
feat: upload/download file support per tty
Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
This commit is contained in:
39
src/file.c
39
src/file.c
@@ -78,11 +78,13 @@ void file_context_reset(struct file_context *ctx)
|
||||
ctx->busy = false;
|
||||
}
|
||||
|
||||
static void notify_user_canceled(struct rtty *rtty)
|
||||
static void notify_user_canceled(struct tty *tty)
|
||||
{
|
||||
struct rtty *rtty = tty->rtty;
|
||||
|
||||
buffer_put_u8(&rtty->wb, MSG_TYPE_FILE);
|
||||
buffer_put_u16be(&rtty->wb, 33);
|
||||
buffer_put_data(&rtty->wb, rtty->file_context.sid, 32);
|
||||
buffer_put_data(&rtty->wb, tty->file.sid, 32);
|
||||
buffer_put_u8(&rtty->wb, RTTY_FILE_MSG_CANCELED);
|
||||
ev_io_start(rtty->loop, &rtty->iow);
|
||||
}
|
||||
@@ -97,7 +99,8 @@ static int notify_progress(struct file_context *ctx)
|
||||
|
||||
static void send_file_data(struct file_context *ctx)
|
||||
{
|
||||
struct rtty *rtty = container_of(ctx, struct rtty, file_context);
|
||||
struct tty *tty = container_of(ctx, struct tty, file);
|
||||
struct rtty *rtty = tty->rtty;
|
||||
uint8_t buf[4096 * 4];
|
||||
int ret;
|
||||
|
||||
@@ -130,13 +133,14 @@ static void send_file_data(struct file_context *ctx)
|
||||
return;
|
||||
|
||||
err:
|
||||
notify_user_canceled(rtty);
|
||||
notify_user_canceled(tty);
|
||||
file_context_reset(ctx);
|
||||
}
|
||||
|
||||
static int start_upload_file(struct file_context *ctx, const char *path)
|
||||
{
|
||||
struct rtty *rtty = container_of(ctx, struct rtty, file_context);
|
||||
struct tty *tty = container_of(ctx, struct tty, file);
|
||||
struct rtty *rtty = tty->rtty;
|
||||
const char *name = basename(path);
|
||||
struct stat st;
|
||||
int fd;
|
||||
@@ -167,7 +171,8 @@ static int start_upload_file(struct file_context *ctx, const char *path)
|
||||
|
||||
bool detect_file_operation(uint8_t *buf, int len, const char *sid, struct file_context *ctx)
|
||||
{
|
||||
struct rtty *rtty = container_of(ctx, struct rtty, file_context);
|
||||
struct tty *tty = container_of(ctx, struct tty, file);
|
||||
struct rtty *rtty = tty->rtty;
|
||||
char fifo_name[128];
|
||||
pid_t pid;
|
||||
int ctlfd;
|
||||
@@ -261,7 +266,7 @@ bool detect_file_operation(uint8_t *buf, int len, const char *sid, struct file_c
|
||||
|
||||
static void start_download_file(struct file_context *ctx, struct buffer *info, int len)
|
||||
{
|
||||
struct rtty *rtty = container_of(ctx, struct rtty, file_context);
|
||||
struct tty *tty = container_of(ctx, struct tty, file);
|
||||
char *name = savepath + strlen(savepath);
|
||||
struct mntent *ment;
|
||||
struct statvfs sfs;
|
||||
@@ -285,6 +290,12 @@ static void start_download_file(struct file_context *ctx, struct buffer *info, i
|
||||
|
||||
buffer_pull(info, name, len - 4);
|
||||
|
||||
if (!access(savepath, F_OK)) {
|
||||
send_file_control_msg(ctx->ctlfd, RTTY_FILE_MSG_ERR_EXIST, NULL, 0);
|
||||
log_err("the file '%s' already exists\n", name);
|
||||
goto open_fail;
|
||||
}
|
||||
|
||||
fd = open(savepath, O_WRONLY | O_TRUNC | O_CREAT, 0644);
|
||||
if (fd < 0) {
|
||||
send_file_control_msg(ctx->ctlfd, RTTY_FILE_MSG_ERR, NULL, 0);
|
||||
@@ -312,22 +323,24 @@ static void start_download_file(struct file_context *ctx, struct buffer *info, i
|
||||
check_space_fail:
|
||||
buffer_pull(info, name, len - 4);
|
||||
open_fail:
|
||||
notify_user_canceled(rtty);
|
||||
notify_user_canceled(tty);
|
||||
file_context_reset(ctx);
|
||||
}
|
||||
|
||||
static void send_file_data_ack(struct rtty *rtty)
|
||||
static void send_file_data_ack(struct tty *tty)
|
||||
{
|
||||
struct rtty *rtty = tty->rtty;
|
||||
|
||||
buffer_put_u8(&rtty->wb, MSG_TYPE_FILE);
|
||||
buffer_put_u16be(&rtty->wb, 33);
|
||||
buffer_put_data(&rtty->wb, rtty->file_context.sid, 32);
|
||||
buffer_put_data(&rtty->wb, tty->file.sid, 32);
|
||||
buffer_put_u8(&rtty->wb, RTTY_FILE_MSG_DATA_ACK);
|
||||
ev_io_start(rtty->loop, &rtty->iow);
|
||||
}
|
||||
|
||||
void parse_file_msg(struct file_context *ctx, struct buffer *data, int len)
|
||||
{
|
||||
struct rtty *rtty = container_of(ctx, struct rtty, file_context);
|
||||
struct tty *tty = container_of(ctx, struct tty, file);
|
||||
int type = buffer_pull_u8(data);
|
||||
|
||||
len--;
|
||||
@@ -344,13 +357,13 @@ void parse_file_msg(struct file_context *ctx, struct buffer *data, int len)
|
||||
ctx->remain_size -= len;
|
||||
|
||||
if (notify_progress(ctx) < 0) {
|
||||
notify_user_canceled(rtty);
|
||||
notify_user_canceled(tty);
|
||||
file_context_reset(ctx);
|
||||
} else {
|
||||
if (ctx->remain_size == 0)
|
||||
file_context_reset(ctx);
|
||||
else
|
||||
send_file_data_ack(rtty);
|
||||
send_file_data_ack(tty);
|
||||
}
|
||||
} else {
|
||||
buffer_pull(data, NULL, len);
|
||||
|
||||
@@ -39,6 +39,7 @@ enum {
|
||||
RTTY_FILE_MSG_PROGRESS,
|
||||
RTTY_FILE_MSG_REQUEST_ACCEPT,
|
||||
RTTY_FILE_MSG_NO_SPACE,
|
||||
RTTY_FILE_MSG_ERR_EXIST,
|
||||
RTTY_FILE_MSG_ERR
|
||||
};
|
||||
|
||||
|
||||
@@ -134,6 +134,10 @@ static void handle_file_control_msg(int fd, int sfd, const char *path)
|
||||
printf("\033[31mNo enough space\033[0m\n");
|
||||
goto done;
|
||||
|
||||
case RTTY_FILE_MSG_ERR_EXIST:
|
||||
printf("\033[31mThe file already exists\033[0m\n");
|
||||
goto done;
|
||||
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
15
src/rtty.c
15
src/rtty.c
@@ -57,7 +57,7 @@ static void del_tty(struct tty *tty)
|
||||
close(tty->pty);
|
||||
kill(tty->pid, SIGTERM);
|
||||
|
||||
file_context_reset(&rtty->file_context);
|
||||
file_context_reset(&tty->file);
|
||||
|
||||
log_info("delete tty: %s\n", tty->sid);
|
||||
|
||||
@@ -103,7 +103,7 @@ static void pty_on_read(struct ev_loop *loop, struct ev_io *w, int revents)
|
||||
return;
|
||||
}
|
||||
|
||||
if (detect_file_operation(buf, len, tty->sid, &rtty->file_context))
|
||||
if (detect_file_operation(buf, len, tty->sid, &tty->file))
|
||||
return;
|
||||
|
||||
buffer_put_u8(wb, MSG_TYPE_TERMDATA);
|
||||
@@ -197,6 +197,7 @@ static void tty_login(struct rtty *rtty, const char *sid)
|
||||
tty->pid = pid;
|
||||
tty->pty = pty;
|
||||
tty->rtty = rtty;
|
||||
tty->file.fd = -1;
|
||||
|
||||
strcpy(tty->sid, sid);
|
||||
|
||||
@@ -346,6 +347,9 @@ static void parse_tty_msg(struct rtty *rtty, int type, int len)
|
||||
case MSG_TYPE_WINSIZE:
|
||||
set_tty_winsize(tty);
|
||||
break;
|
||||
case MSG_TYPE_FILE:
|
||||
parse_file_msg(&tty->file, &rtty->rb, len);
|
||||
break;
|
||||
default:
|
||||
/* never to here */
|
||||
break;
|
||||
@@ -390,6 +394,7 @@ static int parse_msg(struct rtty *rtty)
|
||||
case MSG_TYPE_LOGOUT:
|
||||
case MSG_TYPE_TERMDATA:
|
||||
case MSG_TYPE_WINSIZE:
|
||||
case MSG_TYPE_FILE:
|
||||
parse_tty_msg(rtty, msgtype, msglen);
|
||||
break;
|
||||
|
||||
@@ -401,10 +406,6 @@ static int parse_msg(struct rtty *rtty)
|
||||
case MSG_TYPE_HEARTBEAT:
|
||||
break;
|
||||
|
||||
case MSG_TYPE_FILE:
|
||||
parse_file_msg(&rtty->file_context, rb, msglen);
|
||||
break;
|
||||
|
||||
case MSG_TYPE_WEB:
|
||||
web_request(rtty, msglen);
|
||||
break;
|
||||
@@ -658,8 +659,6 @@ int rtty_start(struct rtty *rtty)
|
||||
&& !rtty->reconnect)
|
||||
return -1;
|
||||
|
||||
rtty->file_context.fd = -1;
|
||||
|
||||
INIT_LIST_HEAD(&rtty->ttys);
|
||||
INIT_LIST_HEAD(&rtty->web_reqs);
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ struct tty {
|
||||
ev_tstamp active;
|
||||
struct ev_timer tmr;
|
||||
struct list_head node;
|
||||
struct file_context file;
|
||||
};
|
||||
|
||||
struct rtty {
|
||||
@@ -98,7 +99,6 @@ struct rtty {
|
||||
#endif
|
||||
int ntty; /* tty number */
|
||||
struct list_head ttys;
|
||||
struct file_context file_context;
|
||||
struct list_head web_reqs;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user