int doCommand( char *command, size_t comm_len, char *arg_str ) { if( strncmp( command, "help", 4 ) == 0 || strncmp( command, "?", 1 ) == 0 ) { printf("read <path> - Read the contents of a file\n"); printf("ld [path] - List the contents of a directory\n"); printf("cd [path] - Change current directory\n"); printf("wd - Display the current working directory\n"); printf("exec <path> - Explicitly execute a file\n"); printf("echo <msg> - Prints a message\n"); printf("time - Displays the current time\n"); printf("help OR ? - Prints this message\n"); } else if( strncmp( command, "read", 4 ) == 0 ) { int result; int len; void *file_buffer = NULL; char *path = getFullPathName( arg_str ); FILE *stream = fopen(path, "r"); if( !stream ) { printf("Unable to open stream\n"); return -1; } fseek(stream, 0, SEEK_END); len = ftell(stream); if( len < 0 ) return 0; else if( len == 0 ) { printf("Empty\n"); return 0; } file_buffer = malloc( len ); fseek(stream, 0, SEEK_SET); result = fread(file_buffer, 1, len, stream); if( !file_buffer || result < 0 ) return -1; else if( len > 0 ) printf("%.*s\n", result, file_buffer ); free(file_buffer); fclose(stream); } else if( strncmp( command, "wd", 2 ) == 0 ) printf("%.*s\n", PATH_LEN, currDir); else if( strncmp( command, "cd", 2 ) == 0 ) { char *path; size_t pathLen; if( arg_str == NULL || strlen(arg_str) == 0 ) path = "/"; else if( arg_str[0] == '/' ) path = arg_str; else path = getFullPathName( arg_str ); if( getFileAttributes( path, attrib_list ) >= 0 ) strncpy( currDir, path, PATH_LEN ); else return -1; } else if( strncmp( command, "time", 4 ) == 0 ) { time_t t = time(NULL); printf("The time/date is: %s", asctime(gmtime(&t))); } else if( strncmp( command, "ld", 2 ) == 0 ) { int n; char *path, *buffer; size_t pathLen; if( arg_str == NULL || strlen(arg_str) == 0 ) path = currDir; else path = getFullPathName(arg_str); n = listDir(path, sizeof attrib_list / sizeof(struct FileAttributes), attrib_list); if( n < 0 ) { printf("Failure\n"); return -1; } printf("Listing %d entries of %.*s:\n", n, strlen(path), path); if( n == 0 ) printf("No entries\n"); else { for(unsigned i=0; i < (unsigned)n; i++) printf("%.*s%c\n", attrib_list[i].name_len, attrib_list[i].name, ((attrib_list[i].flags & FS_DIR) ? '/' : '\0')); } } else if( strncmp( command, "echo", 4 ) == 0 ) { if( arg_str ) printf("%.*s\n", comm_len, arg_str); } else if( strncmp( command, "exec", 4 ) == 0 ) { char *fName = strtok(arg_str, " "), *args=""; printf("Executing '%s'\n", fName); return exec(fName, args); } else { printf("Unknown command!\n"); return -1; } return 0; }
bool FileSystemManager::isValidFileName(QString filePath) { // If the file attributes don't return anything, this file is invalid return getFileAttributes(filePath) != 0; }
/* Once a file has been opened, it can be read using the SSH_FXP_READ message, which has the following format: uint32 id string handle uint64 offset uint32 len where `id' is the request identifier, `handle' is an open file handle returned by SSH_FXP_OPEN, `offset' is the offset (in bytes) relative to the beginning of the file from where to start reading, and `len' is the maximum number of bytes to read. In response to this request, the server will read as many bytes as it can from the file (up to `len'), and return them in a SSH_FXP_DATA message. If an error occurs or EOF is encountered before reading any data, the server will respond with SSH_FXP_STATUS. For normal disk files, it is guaranteed that this will read the specified number of bytes, or up to end of file. For e.g. device files this may return fewer bytes than requested. */ int32 SftpFileHandle::read(uint8 *pBuf, uint32 bufLen, uint64 offset, uint32 &bytesRead) { int32 result = PTSSH_SUCCESS; pthread_mutex_t *pWaitMutex = NULL; pthread_cond_t *pWaitCond = NULL; bool bErrorOccured = false; uint32 requestID, bytesToRead = 0, sftpDataLen = 1 + //byte SSH_FXP_OPEN 4 + //uint32 request-id 4 + m_handleStrLen + //string handle 8 + //uint64 offset 4; //uint32 len bytesRead = 0; /* If we haven't already gotten the file stats, get them now. We will base our * transfer technique on the file size */ if ( ! bFileStatsSet) { result = getFileAttributes(); if ( result != PTSSH_SUCCESS) return result; } while ( bytesRead < m_attrs.fileSize() && bytesRead < bufLen && ! bErrorOccured ) { //Alert our SftpRequestMgr that we are going to be waiting on data for a new request result = m_pRequestMgr->createRequest( requestID, &pWaitCond, &pWaitMutex); if ( result != PTSSH_SUCCESS) return result; //Create the request SftpBinaryPacket *pSBP = new SftpBinaryPacket(m_cNum); if ( pSBP && pSBP->init(sftpDataLen, SSH_FXP_READ, requestID, m_remoteChannelNum) == PTSSH_SUCCESS) { /**** Write the packet guts ******/ pSBP->writeString( (const char *)m_pHandleStr, m_handleStrLen); pSBP->writeUint64( offset + bytesRead); pSBP->writeUint32( bufLen); //Send the packet off result = m_pChannelMgr->queueOutboundData( pSBP); if ( result == PTSSH_SUCCESS) { uint32 bytesInRequest = 0; /* The response to this request will be a SSH_FXP_STATUS message. One should note that on some server platforms even a close can fail. This can happen e.g. if the server operating system caches writes, and an error occurs while flushing cached writes during the close. */ //Wait for the SftpRequestMgr to get a response to our request pthread_mutex_lock( pWaitMutex); pthread_cond_wait(pWaitCond, pWaitMutex); pthread_mutex_unlock( pWaitMutex); //We should now be able to get all the data for the request or detect if an error occured result = readRequestDataIntoBuffer( requestID, pBuf + bytesRead, pBuf + bufLen, bytesInRequest); if ( result == PTSSH_SUCCESS) { bytesRead += bytesInRequest; } else { bErrorOccured = true; result = PTSFTP_E_CouldNotGetResponse; } } else { bErrorOccured = true; delete pSBP; result = PTSSH_ERR_CouldNotQueuePacketForSending; } } //Alert the request manager that we are done with this request m_pRequestMgr->deleteRequest(requestID); } return result; }