void getCurrentDate(DateTime *date) { //Retrieve current time time_t time = getCurrentUnixTime(); //Convert Unix timestamp to date convertUnixTimeToDate(time, date); }
void ftpServerSendData(FtpServerContext *context, FtpClientConnection *connection) { error_t error; size_t n; //Any data waiting for transmission? if(connection->bufferLength > 0) { //Send more data error = socketSend(connection->dataSocket, connection->buffer + connection->bufferPos, connection->bufferLength, &n, 0); //Failed to send data? if(error != NO_ERROR && error != ERROR_TIMEOUT) { //Close the data connection ftpServerCloseDataConnection(connection); //Release previously allocated resources if(connection->file != NULL) { fsCloseFile(connection->file); connection->file = NULL; } if(connection->dir != NULL) { fsCloseDir(connection->dir); connection->dir = NULL; } //Back to idle state connection->controlState = FTP_CONTROL_STATE_IDLE; //Transfer status strcpy(connection->response, "451 Transfer aborted\r\n"); //Debug message TRACE_DEBUG("FTP server: %s", connection->response); //Number of bytes in the response buffer connection->responseLength = strlen(connection->response); connection->responsePos = 0; //Exit immediately return; } //Advance data pointer connection->bufferPos += n; //Number of bytes still available in the buffer connection->bufferLength -= n; } //Empty transmission buffer? if(connection->bufferLength == 0) { //File transfer in progress? if(connection->controlState == FTP_CONTROL_STATE_RETR) { //Read more data error = fsReadFile(connection->file, connection->buffer, FTP_SERVER_BUFFER_SIZE, &n); //End of stream? if(error) { //Close file fsCloseFile(connection->file); connection->file = NULL; //Wait for all the data to be transmitted and acknowledged connection->dataState = FTP_DATA_STATE_WAIT_ACK; //Exit immediately return; } } //Directory listing in progress? else if(connection->controlState == FTP_CONTROL_STATE_LIST) { uint_t perm; time_t currentTime; time_t modified; char_t *path; FsDirEntry dirEntry; //Read a new entry in the directory error = fsReadDir(connection->dir, &dirEntry); //End of stream? if(error) { //Close directory fsCloseDir(connection->dir); connection->dir = NULL; //Wait for all the data to be transmitted and acknowledged connection->dataState = FTP_DATA_STATE_WAIT_ACK; //Exit immediately return; } //Point to the scratch buffer path = connection->buffer; //Get the pathname of the directory being listed strcpy(path, connection->path); //Retrieve the full pathname pathCombine(path, dirEntry.name, FTP_SERVER_MAX_PATH_LEN); pathCanonicalize(path); //Get permissions for the specified file perm = ftpServerGetFilePermissions(context, connection, path); //Enforce access rights if(perm & FTP_FILE_PERM_LIST) { //Format links, owner, group and size fields n = sprintf(connection->buffer, "---------- 1 owner group %10" PRIu32, dirEntry.size); //Check whether the current entry is a directory if(dirEntry.attributes & FS_FILE_ATTR_DIRECTORY) connection->buffer[0] = 'd'; //Read access? if(perm & FTP_FILE_PERM_READ) { connection->buffer[1] = 'r'; connection->buffer[4] = 'r'; connection->buffer[7] = 'r'; } //Write access if(perm & FTP_FILE_PERM_WRITE) { connection->buffer[2] = 'w'; connection->buffer[5] = 'w'; connection->buffer[8] = 'w'; } //Get current time currentTime = getCurrentUnixTime(); //Get modification time modified = convertDateToUnixTime(&dirEntry.modified); //Check whether the modification time is within the previous 180 days if(currentTime > modified && currentTime < (modified + FTP_SERVER_180_DAYS)) { //The format of the date/time field is Mmm dd hh:mm n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %02" PRIu8 ":%02" PRIu8, months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day, dirEntry.modified.hours, dirEntry.modified.minutes); } else { //The format of the date/time field is Mmm dd yyyy n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %04" PRIu16, months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day, dirEntry.modified.year); } //Append filename n += sprintf(connection->buffer + n, " %s\r\n", dirEntry.name); //Debug message TRACE_DEBUG("FTP server: %s", connection->buffer); } else { //Insufficient access rights n = 0; } } //Invalid state? else { //The FTP server has encountered a critical error ftpServerCloseConnection(context, connection); //Exit immediately return; } //Number of bytes in the buffer connection->bufferPos = 0; connection->bufferLength = n; } }