|
|
@ -187,7 +187,7 @@ static const char *month_table[12] = { |
|
|
|
"Sep", |
|
|
|
"Oct", |
|
|
|
"Nov", |
|
|
|
"Dez" |
|
|
|
"Dec" |
|
|
|
}; |
|
|
|
|
|
|
|
/*
|
|
|
@ -343,6 +343,7 @@ struct ftpd_msgstate { |
|
|
|
vfs_t *vfs; |
|
|
|
struct ip4_addr dataip; |
|
|
|
u16_t dataport; |
|
|
|
struct tcp_pcb *datalistenpcb; |
|
|
|
struct tcp_pcb *datapcb; |
|
|
|
struct ftpd_datastate *datafs; |
|
|
|
int passive; |
|
|
@ -368,6 +369,14 @@ static void ftpd_dataclose(struct tcp_pcb *pcb, struct ftpd_datastate *fsd) |
|
|
|
tcp_arg(pcb, NULL); |
|
|
|
tcp_sent(pcb, NULL); |
|
|
|
tcp_recv(pcb, NULL); |
|
|
|
|
|
|
|
if (fsd->msgfs->datalistenpcb) { |
|
|
|
tcp_arg(fsd->msgfs->datalistenpcb, NULL); |
|
|
|
tcp_accept(fsd->msgfs->datalistenpcb, NULL); |
|
|
|
tcp_close(fsd->msgfs->datalistenpcb); |
|
|
|
fsd->msgfs->datalistenpcb = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
fsd->msgfs->datafs = NULL; |
|
|
|
sfifo_close(&fsd->fifo); |
|
|
|
free(fsd); |
|
|
@ -664,15 +673,29 @@ static int open_dataconnection(struct tcp_pcb *pcb, struct ftpd_msgstate *fsm) |
|
|
|
fsm->datafs = malloc(sizeof(struct ftpd_datastate)); |
|
|
|
|
|
|
|
if (fsm->datafs == NULL) { |
|
|
|
dbg_printf("open_dataconnection: Out of memory\n"); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
memset(fsm->datafs, 0, sizeof(struct ftpd_datastate)); |
|
|
|
fsm->datafs->msgfs = fsm; |
|
|
|
fsm->datafs->msgpcb = pcb; |
|
|
|
sfifo_init(&fsm->datafs->fifo, 2000); |
|
|
|
|
|
|
|
if (sfifo_init(&fsm->datafs->fifo, 2000) != 0) { |
|
|
|
free(fsm->datafs); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
fsm->datapcb = tcp_new(); |
|
|
|
|
|
|
|
if (fsm->datapcb == NULL) { |
|
|
|
sfifo_close(&fsm->datafs->fifo); |
|
|
|
free(fsm->datafs); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* Tell TCP that this is the structure we wish to be passed for our
|
|
|
|
callbacks. */ |
|
|
|
tcp_arg(fsm->datapcb, fsm->datafs); |
|
|
@ -865,19 +888,26 @@ static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate |
|
|
|
fsm->datafs = malloc(sizeof(struct ftpd_datastate)); |
|
|
|
|
|
|
|
if (fsm->datafs == NULL) { |
|
|
|
dbg_printf("cmd_pasv: Out of memory\n"); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return; |
|
|
|
} |
|
|
|
memset(fsm->datafs, 0, sizeof(struct ftpd_datastate)); |
|
|
|
|
|
|
|
fsm->datapcb = tcp_new(); |
|
|
|
if (!fsm->datapcb) { |
|
|
|
if (sfifo_init(&fsm->datafs->fifo, 2000) != 0) { |
|
|
|
free(fsm->datafs); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
sfifo_init(&fsm->datafs->fifo, 2000); |
|
|
|
fsm->datalistenpcb = tcp_new(); |
|
|
|
|
|
|
|
if (fsm->datalistenpcb == NULL) { |
|
|
|
free(fsm->datafs); |
|
|
|
sfifo_close(&fsm->datafs->fifo); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
start_port = port; |
|
|
|
|
|
|
@ -888,7 +918,7 @@ static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate |
|
|
|
port = 4096; |
|
|
|
|
|
|
|
fsm->dataport = port; |
|
|
|
err = tcp_bind(fsm->datapcb, (ip_addr_t*)&pcb->local_ip, fsm->dataport); |
|
|
|
err = tcp_bind(fsm->datalistenpcb, (ip_addr_t*)&pcb->local_ip, fsm->dataport); |
|
|
|
if (err == ERR_OK) |
|
|
|
break; |
|
|
|
if (start_port == port) |
|
|
@ -896,33 +926,32 @@ static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate |
|
|
|
if (err == ERR_USE) { |
|
|
|
continue; |
|
|
|
} else { |
|
|
|
ftpd_dataclose(fsm->datapcb, fsm->datafs); |
|
|
|
fsm->datapcb = NULL; |
|
|
|
ftpd_dataclose(fsm->datalistenpcb, fsm->datafs); |
|
|
|
fsm->datalistenpcb = NULL; |
|
|
|
fsm->datafs = NULL; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fsm->datafs->msgfs = fsm; |
|
|
|
|
|
|
|
temppcb = tcp_listen(fsm->datapcb); |
|
|
|
temppcb = tcp_listen(fsm->datalistenpcb); |
|
|
|
if (!temppcb) { |
|
|
|
ftpd_dataclose(fsm->datapcb, fsm->datafs); |
|
|
|
fsm->datapcb = NULL; |
|
|
|
dbg_printf("cmd_pasv: tcp_listen failed\n"); |
|
|
|
ftpd_dataclose(fsm->datalistenpcb, fsm->datafs); |
|
|
|
fsm->datalistenpcb = NULL; |
|
|
|
fsm->datafs = NULL; |
|
|
|
return; |
|
|
|
} |
|
|
|
fsm->datapcb = temppcb; |
|
|
|
fsm->datalistenpcb = temppcb; |
|
|
|
|
|
|
|
fsm->passive = 1; |
|
|
|
fsm->datafs->connected = 0; |
|
|
|
fsm->datafs->msgfs = fsm; |
|
|
|
fsm->datafs->msgpcb = pcb; |
|
|
|
|
|
|
|
/* Tell TCP that this is the structure we wish to be passed for our
|
|
|
|
callbacks. */ |
|
|
|
tcp_arg(fsm->datapcb, fsm->datafs); |
|
|
|
|
|
|
|
tcp_accept(fsm->datapcb, ftpd_dataaccept); |
|
|
|
tcp_arg(fsm->datalistenpcb, fsm->datafs); |
|
|
|
tcp_accept(fsm->datalistenpcb, ftpd_dataaccept); |
|
|
|
send_msg(pcb, fsm, msg227, ip4_addr1(ip_2_ip4(&pcb->local_ip)), ip4_addr2(ip_2_ip4(&pcb->local_ip)), ip4_addr3(ip_2_ip4(&pcb->local_ip)), ip4_addr4(ip_2_ip4(&pcb->local_ip)), (fsm->dataport >> 8) & 0xff, (fsm->dataport) & 0xff); |
|
|
|
} |
|
|
|
|
|
|
@ -932,7 +961,6 @@ static void cmd_abrt(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate |
|
|
|
tcp_arg(fsm->datapcb, NULL); |
|
|
|
tcp_sent(fsm->datapcb, NULL); |
|
|
|
tcp_recv(fsm->datapcb, NULL); |
|
|
|
tcp_arg(fsm->datapcb, NULL); |
|
|
|
tcp_abort(pcb); |
|
|
|
sfifo_close(&fsm->datafs->fifo); |
|
|
|
free(fsm->datafs); |
|
|
@ -973,6 +1001,7 @@ static void cmd_rnfr(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate |
|
|
|
free(fsm->renamefrom); |
|
|
|
fsm->renamefrom = malloc(strlen(arg) + 1); |
|
|
|
if (fsm->renamefrom == NULL) { |
|
|
|
dbg_printf("cmd_rnfr: Out of memory\n"); |
|
|
|
send_msg(pcb, fsm, msg451); |
|
|
|
return; |
|
|
|
} |
|
|
@ -1104,7 +1133,7 @@ static struct ftpd_command ftpd_commands[] = { |
|
|
|
{"RMD", cmd_rmd}, |
|
|
|
{"XRMD", cmd_rmd}, |
|
|
|
{"DELE", cmd_dele}, |
|
|
|
//{"PASV", cmd_pasv},
|
|
|
|
{"PASV", cmd_pasv}, |
|
|
|
{NULL, NULL} |
|
|
|
}; |
|
|
|
|
|
|
@ -1314,10 +1343,14 @@ static err_t ftpd_msgaccept(void *arg, struct tcp_pcb *pcb, err_t err) |
|
|
|
memset(fsm, 0, sizeof(struct ftpd_msgstate)); |
|
|
|
|
|
|
|
/* Initialize the structure. */ |
|
|
|
sfifo_init(&fsm->fifo, 2000); |
|
|
|
if (sfifo_init(&fsm->fifo, 2000) != 0) { |
|
|
|
free(fsm); |
|
|
|
return ERR_MEM; |
|
|
|
} |
|
|
|
fsm->state = FTPD_IDLE; |
|
|
|
fsm->vfs = vfs_openfs(); |
|
|
|
if (!fsm->vfs) { |
|
|
|
if (fsm->vfs == NULL) { |
|
|
|
sfifo_close(&fsm->fifo); |
|
|
|
free(fsm); |
|
|
|
return ERR_CLSD; |
|
|
|
} |
|
|
|