コード例 #1
0
ファイル: ftpd.c プロジェクト: zeldin/dc-ftpd
static void send_file(struct ftpd_datastate *fsd, struct tcp_pcb *pcb)
{
	if (!fsd->connected)
		return;

	if (fsd->vfs_file) {
		char buffer[2048];
		int len;

		len = sfifo_space(&fsd->fifo);
		if (len == 0) {
			send_data(pcb, fsd);
			return;
		}
		if (len > 2048)
			len = 2048;
		len = vfs_read(buffer, 1, len, fsd->vfs_file);
		if (len == 0) {
			if (vfs_eof(fsd->vfs_file) == 0)
				return;
			vfs_close(fsd->vfs_file);
			fsd->vfs_file = NULL;
			return;
		}
		sfifo_write(&fsd->fifo, buffer, len);
		send_data(pcb, fsd);
	} else {
		struct ftpd_msgstate *fsm;
		struct tcp_pcb *msgpcb;

		if (sfifo_used(&fsd->fifo) > 0) {
			send_data(pcb, fsd);
			return;
		}
		fsm = fsd->msgfs;
		msgpcb = fsd->msgpcb;

		vfs_close(fsd->vfs_file);
		fsd->vfs_file = NULL;
		ftpd_dataclose(pcb, fsd);
		fsm->datapcb = NULL;
		fsm->datafs = NULL;
		fsm->state = FTPD_IDLE;
		send_msg(msgpcb, fsm, msg226);
		return;
	}
}
コード例 #2
0
ファイル: ftpd.c プロジェクト: skyformat99/lwip-ftpd
static void ftpd_msgclose(struct tcp_pcb *pcb, struct ftpd_msgstate *fsm)
{
	tcp_arg(pcb, NULL);
	tcp_sent(pcb, NULL);
	tcp_recv(pcb, NULL);
	if (fsm->datafs)
		ftpd_dataclose(fsm->datapcb, fsm->datafs);
	sfifo_close(&fsm->fifo);
	vfs_close(fsm->vfs);
	fsm->vfs = NULL;
	if (fsm->renamefrom)
		free(fsm->renamefrom);
	fsm->renamefrom = NULL;
	free(fsm);
	tcp_arg(pcb, NULL);
	tcp_close(pcb);
}
コード例 #3
0
ファイル: ftpd.c プロジェクト: skyformat99/lwip-ftpd
static void ftpd_msgerr(void *arg, err_t err)
{
	struct ftpd_msgstate *fsm = arg;

	dbg_printf("ftpd_msgerr: %s (%i)\n", lwip_strerr(err), err);
	if (fsm == NULL)
		return;
	if (fsm->datafs)
		ftpd_dataclose(fsm->datapcb, fsm->datafs);
	sfifo_close(&fsm->fifo);
	vfs_close(fsm->vfs);
	fsm->vfs = NULL;
	if (fsm->renamefrom)
		free(fsm->renamefrom);
	fsm->renamefrom = NULL;
	free(fsm);
}
コード例 #4
0
ファイル: ftpd.c プロジェクト: skyformat99/lwip-ftpd
static err_t ftpd_datarecv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
	struct ftpd_datastate *fsd = arg;

	if (err == ERR_OK && p != NULL) {
		struct pbuf *q;
		u16_t tot_len = 0;

		for (q = p; q != NULL; q = q->next) {
			int len;

			len = vfs_write(q->payload, 1, q->len, fsd->vfs_file);
			tot_len += len;
			if (len != q->len)
				break;
		}

		/* Inform TCP that we have taken the data. */
		tcp_recved(pcb, tot_len);

		pbuf_free(p);
	}
	if (err == ERR_OK && p == NULL) {
		struct ftpd_msgstate *fsm;
		struct tcp_pcb *msgpcb;

		fsm = fsd->msgfs;
		msgpcb = fsd->msgpcb;

		vfs_close(fsd->vfs_file);
		fsd->vfs_file = NULL;
		ftpd_dataclose(pcb, fsd);
		fsm->datapcb = NULL;
		fsm->datafs = NULL;
		fsm->state = FTPD_IDLE;
		send_msg(msgpcb, fsm, msg226);
	}

	return ERR_OK;
}
コード例 #5
0
ファイル: ftpd.c プロジェクト: skyformat99/lwip-ftpd
static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate *fsm)
{
	static u16_t port = 4096;
	static u16_t start_port = 4096;
	struct tcp_pcb *temppcb;

	/* Allocate memory for the structure that holds the state of the
	   connection. */
	fsm->datafs = malloc(sizeof(struct ftpd_datastate));

	if (fsm->datafs == NULL) {
		send_msg(pcb, fsm, msg451);
		return;
	}
	memset(fsm->datafs, 0, sizeof(struct ftpd_datastate));

	fsm->datapcb = tcp_new();
	if (!fsm->datapcb) {
		free(fsm->datafs);
		send_msg(pcb, fsm, msg451);
		return;
	}

	sfifo_init(&fsm->datafs->fifo, 2000);

	start_port = port;

	while (1) {
		err_t err;

		if(++port > 0x7fff)
			port = 4096;

		fsm->dataport = port;
		err = tcp_bind(fsm->datapcb, (ip_addr_t*)&pcb->local_ip, fsm->dataport);
		if (err == ERR_OK)
			break;
		if (start_port == port)
			err = ERR_CLSD;
		if (err == ERR_USE) {
			continue;
		} else {
			ftpd_dataclose(fsm->datapcb, fsm->datafs);
			fsm->datapcb = NULL;
			fsm->datafs = NULL;
			return;
		}
	}

	fsm->datafs->msgfs = fsm;

	temppcb = tcp_listen(fsm->datapcb);
	if (!temppcb) {
		ftpd_dataclose(fsm->datapcb, fsm->datafs);
		fsm->datapcb = NULL;
		fsm->datafs = NULL;
		return;
	}
	fsm->datapcb = temppcb;

	fsm->passive = 1;
	fsm->datafs->connected = 0;
	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);
	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);
}
コード例 #6
0
ファイル: ftpd.c プロジェクト: skyformat99/lwip-ftpd
static void send_next_directory(struct ftpd_datastate *fsd, struct tcp_pcb *pcb, int shortlist)
{
	char buffer[1024];
	int len;

	while (1) {
	if (fsd->vfs_dirent == NULL)
		fsd->vfs_dirent = vfs_readdir(fsd->vfs_dir);

	if (fsd->vfs_dirent) {
		if (shortlist) {
			len = sprintf(buffer, "%s\r\n", fsd->vfs_dirent->name);
			if (sfifo_space(&fsd->fifo) < len) {
				send_data(pcb, fsd);
				return;
			}
			sfifo_write(&fsd->fifo, buffer, len);
			fsd->vfs_dirent = NULL;
		} else {
			vfs_stat_t st;
			time_t current_time;
			int current_year;
			struct tm *s_time;

			time(&current_time);
			s_time = gmtime(&current_time);
			current_year = s_time->tm_year;

			vfs_stat(fsd->msgfs->vfs, fsd->vfs_dirent->name, &st);
			s_time = gmtime(&st.st_mtime);
			if (s_time->tm_year == current_year)
				len = sprintf(buffer, "-rw-rw-rw-   1 user     ftp  %11ld %s %02i %02i:%02i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_hour, s_time->tm_min, fsd->vfs_dirent->name);
			else
				len = sprintf(buffer, "-rw-rw-rw-   1 user     ftp  %11ld %s %02i %5i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_year + 1900, fsd->vfs_dirent->name);
			if (VFS_ISDIR(st.st_mode))
				buffer[0] = 'd';
			if (sfifo_space(&fsd->fifo) < len) {
				send_data(pcb, fsd);
				return;
			}
			sfifo_write(&fsd->fifo, buffer, len);
			fsd->vfs_dirent = NULL;
		}
	} else {
		struct ftpd_msgstate *fsm;
		struct tcp_pcb *msgpcb;

		if (sfifo_used(&fsd->fifo) > 0) {
			send_data(pcb, fsd);
			return;
		}
		fsm = fsd->msgfs;
		msgpcb = fsd->msgpcb;

		vfs_closedir(fsd->vfs_dir);
		fsd->vfs_dir = NULL;
		ftpd_dataclose(pcb, fsd);
		fsm->datapcb = NULL;
		fsm->datafs = NULL;
		fsm->state = FTPD_IDLE;
		send_msg(msgpcb, fsm, msg226);
		return;
	}
	}
}