📄 ftpd.c
字号:
{
ptr = strtok(NULL, " \r\n");
strcpy(tmp, ptr);
ftp->file = ffopen(ptr, 'r'); //Open file for reading.
if (ftp->file)
{
if (ftp->type == ASCII) // Tell transmission type (ASCII/Binary)
{
TCPsend_P(socket, sizeof(FTP_ACONN), FTP_ACONN);
}
else
{
TCPsend_P(socket, sizeof(FTP_BCONN), FTP_BCONN);
}
ftp->dataSocket = TCPaopen(ftp->dataPort, ftp->dataIP0, ftp->dataIP1, 20);
if (!ftp->dataSocket) // Could not open data connection.
{
TCPsend_P(socket, sizeof(FTP_ERR_DATA), FTP_ERR_DATA);
ffclose(ftp->file);
}
else
{
ftp->state = DATA;
ftp->datastate = RETR;
x = ffread(ftp->file, outBuffer, FTP_BUFFERSIZE); //read first 'FTP_BUFFERSIZE ' bytes data from file and send.
if (x)
{
TCPsend(ftp->dataSocket, x, outBuffer);
}
}
}
else
{
TCPsend_P(socket, sizeof(FTP_ERR_FILE), FTP_ERR_FILE);
}
}
else if(!strcmp(ptr, "STOR")) //User wants to send file
{
ptr = strtok(NULL, " \r\n");
strcpy(tmp, ptr);
ftp->file = ffopen(ptr, 'w'); //Open file for writing.
if (ftp->file)
{
if (ftp->type == ASCII)
{
TCPsend_P(socket, sizeof(FTP_ACONN), FTP_ACONN);
}
else
{
TCPsend_P(socket, sizeof(FTP_BCONN), FTP_BCONN);
}
ftp->dataSocket = TCPaopen(ftp->dataPort, ftp->dataIP0, ftp->dataIP1, 20);
if (!ftp->dataSocket)
{
TCPsend_P(socket, sizeof(FTP_ERR_DATA), FTP_ERR_DATA);
ffclose(ftp->file);
}
else
{
ftp->state = DATA;
ftp->datastate = STOR;
}
}
else
{
TCPsend_P(socket, sizeof(FTP_ERR_FILE), FTP_ERR_FILE);
}
}
else if (!strcmp(ptr, "DELE")) //User wants to delete file.
{
ptr = strtok(NULL, " ");
if (ffdelete(ptr)) //Delete file.
{
TCPsend_P(socket, sizeof(FTP_DELE), FTP_DELE); //Send acknowledge.
}
else
{
TCPsend_P(socket, sizeof(FTP_ERR_FILE), FTP_ERR_FILE); //Could not delete file.
}
}
else
{
TCPsend_P(socket, sizeof(FTP_ERROR), FTP_ERROR);
}
break;
}//end switch
}
}
else if (ftp->state == DATA) //Data connection open
{
if (ftp->dataSocket) //Check if data connection is still open.
{
if ( (ftp->dataSocket->hisIP1 == ftp->dataIP1) && (ftp->dataSocket->hisIP0 == ftp->dataIP0) &&
(ftp->dataSocket->hisPort == ftp->dataPort) )
{
switch(ftp->datastate)
{
case(WDIRECTORY): //Long directory listing.
case(DIRECTORY): //Short directory listing.
if (ftp->dir)
{
ftp->lastAction = ticker;
if (ftp->dataSocket->state == OPEN)
{
if(ftp->datastate == DIRECTORY)
{
ptr = readdir(ftp->dir);
}
else
{
ptr = readwdir(ftp->dir);
}
if (!ptr)
{
closedir(ftp->dir);
TCPclose(ftp->dataSocket);
ftp->dir = NULL;
}
else
{
TCPsend(ftp->dataSocket, strlen(ptr), ptr);
}
}
}
else
{
ftp->dataSocket = NULL;
TCPsend_P(socket, sizeof(FTP_COMPLETE), FTP_COMPLETE);
ftp->datastate = UNUSED;
ftp->state = IDLE;
}
break;
case(RETR):
if (ftp->file) //If file is still open
{
ftp->lastAction = ticker;
if ( ftp->dataSocket->state == OPEN) //If connection is still open
{
if (!ffeof(ftp->file))
{
z = TCPbufferSpace(ftp->dataSocket); //Check how much data tcp can receive.
if (z>FTP_BUFFERSIZE)
{
z=FTP_BUFFERSIZE;
}
x=ffread(ftp->file, outBuffer, z); //Read data from file.
TCPsend(ftp->dataSocket, x, outBuffer); //Send data.
}
else
{
ffclose(ftp->file); //If EOF, close file and data connection
ftp->file = NULL;
TCPclose(ftp->dataSocket);
}
}
}
else
{
ftp->dataSocket = NULL; // If data connection is closed, send transmission complete.
TCPsend_P(socket, sizeof(FTP_COMPLETE), FTP_COMPLETE);
ftp->state = IDLE;
ftp->datastate = UNUSED;
ftp->state = IDLE;
ftp->dataSocket = NULL;
}
break;
case(STOR):
if (ftp->file) //Is file still open?
{
ftp->lastAction = ticker;
if (ftp->dataSocket)
{
z = TCPget(ftp->dataSocket, FTP_BUFFERSIZE, inBuffer);// Get data from tcp
if (z)
{
x = ffwrite(ftp->file, inBuffer, z); //write data to file.
if (x!=z) //If written data != data size
{
TCPsend_P(socket, sizeof(FTP_ERR_FILE), FTP_ERR_FILE);
TCPclose(ftp->dataSocket);
ftp->dataSocket = NULL;
ftp->state = IDLE;
ftp->datastate = UNUSED;
ffclose(ftp->file);
TCPclose(ftp->dataSocket);
break;
}
}
if ( (ftp->dataSocket->state == HALF_CLOSED) && !TCPsize(ftp->dataSocket) )
{
ffclose(ftp->file); //If data connection is closing.
TCPclose(ftp->dataSocket); //close file and close data connection.
ftp->dataSocket = NULL;
ftp->state = IDLE;
ftp->datastate = UNUSED;
TCPsend_P(socket, sizeof(FTP_COMPLETE), FTP_COMPLETE); // Send acknowledge
}
}
else
{
TCPclose(ftp->dataSocket);
ftp->dataSocket = NULL;
ftp->state = IDLE;
ftp->datastate = UNUSED;
}
}
else
{
TCPsend_P(socket, sizeof(FTP_ERR_FILE), FTP_ERR_FILE);
TCPclose(ftp->dataSocket);
ftp->dataSocket = NULL;
ftp->state = IDLE;
ftp->datastate = UNUSED;
}
break;
default: // Error. Delete datasocket.
ftp->dataSocket = NULL;
ftp->dataPort = 0;
ftp->dataIP0 = 0;
ftp->dataIP1 = 0;
ftp->state = IDLE;
ftp->datastate = UNUSED;
break;
}
}
else
{
ftp->datastate = UNUSED;
ftp->state = IDLE;
}
}
}
socket = socket->next; // Check next socket.
}
}
void closeFTP(FTPCONNECTION *ftp) //Close connection and cleanup.
{
ftp->dataPort = 0;
ftp->state = ULOCKED;
ftp->datastate = UNUSED;
ftp->type =ASCII;
ftp->hisPort = 0;
ftp->hisIP0 = 0;
ftp->hisIP1 = 0;
ftp->dataPort = 0;
ftp->dataIP0 = 0;
ftp->dataIP1 = 0;
ftp->file = NULL;
ftp->dir = NULL;
ftp->lastAction = ticker;
ftp->username[0] = '\0';
ftp->password[0] = '\0';
}
void refresh(void) // Find aborted connections and cleanup.
{
if ( ftpconnection.state != ULOCKED )
{
if ( !((ftpconnection.hisIP0 == ftpconnection.controlSocket->hisIP0) &&
(ftpconnection.hisIP1 == ftpconnection.controlSocket->hisIP1) &&
(ftpconnection.hisPort == ftpconnection.controlSocket->hisPort)) )
{
ftpconnection.state = ULOCKED;
ftpconnection.datastate = UNUSED;
ftpconnection.type =ASCII;
ftpconnection.hisPort = 0;
ftpconnection.hisIP0 = 0;
ftpconnection.hisIP1 = 0;
ftpconnection.dataPort = 0;
ftpconnection.dataIP0 = 0;
ftpconnection.dataIP1 = 0;
ftpconnection.file = NULL;
ftpconnection.dir = NULL;
ftpconnection.username[0] = '\0';
ftpconnection.password[0] = '\0';
}
else if ( ftpconnection.state == DATA )
{
if ( !((ftpconnection.dataIP0 == ftpconnection.dataSocket->hisIP0) &&
(ftpconnection.dataIP1 == ftpconnection.dataSocket->hisIP1) &&
(ftpconnection.dataPort == ftpconnection.dataSocket->hisPort)) )
{
ftpconnection.dataSocket = NULL;
ftpconnection.state = IDLE;
ftpconnection.datastate = UNUSED;
ftpconnection.dataPort = 0;
ftpconnection.dataIP0 = 0;
ftpconnection.dataIP1 = 0;
}
}
if (ftpconnection.controlSocket->state == HALF_CLOSED)
{
TCPclose(ftpconnection.controlSocket);
}
else if ((ftpconnection.lastAction + FTP_TIMEOUT) == ticker)
{
TCPabort(ftpconnection.controlSocket);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -