void telnet_sddump( file_handle_t handle, char** argv, unsigned int argc ) { unsigned long sector = 0; char tmp[8]; char* parseend; if( argc != 2) { file_puts("sddump [sector]\r\n", telnet_handle); return; } sector = strtoul( argv[1], &parseend, 0); unsigned char* data = malloc( SECTOR_SIZE ); unsigned char result = DFS_ReadSector(0, data, sector, 1); if( result == 0 ) { memdump( handle, data, data + SECTOR_SIZE); } else { file_puts("Error reading sector. Response code:", handle ); sprintf(tmp,"%02hhx", result ); file_puts(tmp, handle); file_puts(CRLF, handle); } free(data); return; }
void exec_line( char* line, char* end ) { int token_count = tokenise_line( line, end, NULL, 0 ); if( token_count > 0 ) { char** argv = malloc( sizeof(char*) * token_count ); tokenise_line( line, end, argv, token_count ); //match command against cmd list unsigned short i = 0; for( ; i < CMDS_SIZE; i++ ) { if( strcmp( commands[i].command, argv[0] ) == 0) { commands[i].exec( telnet_handle, argv, token_count); break; } } if( i == CMDS_SIZE ) //fell out of loop without a match { file_puts("Unknown command: ", telnet_handle); file_puts(argv[0], telnet_handle ); file_puts(CRLF, telnet_handle ); } free( argv ); } }
void memdump( file_handle_t handle, char* start, char* end ) { int i = 1; char* line = malloc(64); char *tmp; while( start < end ) { tmp = line; tmp += sprintf(tmp,"%p\t", start); for( i = 0 ; i < 8; i++ ) { unsigned char b = start[i]; tmp+=sprintf(tmp, "%02hhx ", b); } *tmp = '\t'; for( i = 0 ; i < 8; i++ ) { if( *start >= ' ' && *start <= '~' ) *tmp++ = *start; else *tmp++ = '.'; start++; } *tmp = '\0'; file_puts( line , telnet_handle); file_puts( CRLF , telnet_handle); } free(line); }
static int modfile_fputs( INSTANCE * my, int * params ) { char * str = ( char * ) string_get( params[1] ); int r = file_puts(( file * )params[0], str ) ; if ( str[strlen( str )-1] != '\n' ) file_puts(( file * )params[0], "\r\n" ) ; /* int r = file_puts ((file *)params[0], string_get(params[1])) ; */ string_discard( params[1] ) ; return r ; }
void telnet_help( file_handle_t handle, char** argv, unsigned int argc ) { file_puts( "Configured commands:\r\n" , handle); int i = 0; for( ; i < CMDS_SIZE ; i++ ) { file_puts( commands[i].command , handle); file_puts( CRLF , handle ); } }
void telnet_cat( file_handle_t handle, char** argv, unsigned int argc ) { if( argc != 2 ) { file_puts("cat [filename]\r\n", telnet_handle); return; } u8_t* scratch = malloc(SECTOR_SIZE); VOLINFO* volinfo = malloc( sizeof(VOLINFO) ); FILEINFO* file = malloc( sizeof(FILEINFO) ); u8_t* read_buf = malloc( SEND_BUF_SIZE ); //get partition start sector uint32_t startsector = DFS_GetPtnStart( 0, scratch, 0 , NULL, NULL, NULL ); if( startsector == DFS_ERRMISC ) { file_puts("Error finding partition start\r\n", handle); goto exit; } //get volume info if( DFS_GetVolInfo(0,scratch,startsector,volinfo) ) { file_puts("Error getting volume info\r\n", handle); goto exit; } //open file if( DFS_OpenFile( volinfo, (u8_t*)argv[1], DFS_READ, scratch, file ) ) { file_puts("Error opening file ", handle); file_puts( argv[1], handle ); file_puts( CRLF, handle ); goto exit; } //read it to the output handle uint32_t read = 0; //TODO - would like the use the send buffer as THE buffer while( read < file->filelen ) { uint32_t did_read; DFS_ReadFile( file, scratch, read_buf, &did_read, SEND_BUF_SIZE ); if( did_read == 0 ) { file_puts("Error reading file ", handle); file_puts( argv[1], handle ); file_puts( CRLF, handle ); goto exit; } u16_t i = 0; for( ; i < did_read; i++ ) { file_putchar( read_buf[i], handle ); } read += did_read; } exit: free( read_buf ); free( file ); free( volinfo ); free( scratch ); }
void telnet_echo( file_handle_t handle, char** argv, unsigned int argc ) { int i; for( i=1; i < argc; ) { file_puts(argv[i], handle); if( ++i < argc ) file_putchar(' ',handle); } file_puts(CRLF, handle); return; }
void telnet_time( file_handle_t handle, char** argv, unsigned int argc ) { file_puts( "RTCC Date/Time: ", handle ); struct tm time; rtcc_get_tm( &time ); char* timestr = malloc( 32 ); sprintf(timestr,"%u-%02u-%02u %02u:%02u:%02u", time.tm_year+1900, time.tm_mon+1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec ); file_puts(timestr, handle); free( timestr ); file_puts(CRLF, handle); }
static int file_puts_retry(const char *pathname, const char *value, int retry) { while (retry-- && file_puts(pathname, value) < 0) { sleep(2); } return retry; }
void telnet_memdump( file_handle_t handle, char** argv, unsigned int argc ) { char* memstart = NULL; char* parseend; unsigned int len = 0; if( argc != 3) { file_puts("memdump [address] [count]\r\n", telnet_handle); return; } memstart = (char*)(unsigned short) strtoul( argv[1], &parseend, 0); len = (unsigned int) strtoul( argv[2], &parseend, 0); memdump( handle, memstart, memstart + len); return; }
//A pointer to this function is passed into the socket_listen call //It will be called whenever an incoming connection is setup on the listening port file_handle_t telnet_connect_accept(u16_t local_port, u16_t *remote_address, u16_t remote_port) { #ifdef __DEBUG unsigned char* raddr = (unsigned char*) remote_address; printf("\nTelnet: Connect from %hhd.%hhd.%hhd.%hhd port %d", raddr[1],raddr[0],raddr[3],raddr[2], remote_port ); #endif if( telnet_handle != FILE_INVALID_HANDLE ) return FILE_INVALID_HANDLE; buffer_init( &telnet_send_buffer, send_buf, SEND_BUF_SIZE ); buffer_init( &telnet_receive_buffer, receive_buf, REC_BUF_SIZE ); telnet_handle = file_handle_create( &telnet_receive_buffer, &telnet_send_buffer ); optneg_mode = 0; //we will do the echoing from this end. //It's just easier than to try and do full option negotiation telnet_mode = 0 | MODE_ECHO; file_putchar(TELNET_IAC, telnet_handle); file_putchar(TELNET_WILL, telnet_handle); file_putchar(TELNET_ECHO, telnet_handle); file_putchar(TELNET_IAC, telnet_handle); file_putchar(TELNET_WILL, telnet_handle); file_putchar(TELNET_SUPPRESS_GO_AHEAD, telnet_handle); file_puts("\r\nWeb platform telnet. Enter help for commands.\r\n>", telnet_handle); return telnet_handle; }
void telnet_rm( file_handle_t handle, char** argv, unsigned int argc ) { if( argc != 2 ) { file_puts("rm [filename]\r\n", telnet_handle); return; } u8_t* scratch = malloc(SECTOR_SIZE); VOLINFO* volinfo = malloc( sizeof(VOLINFO) ); //get partition start sector uint32_t startsector = DFS_GetPtnStart( 0, scratch, 0 , NULL, NULL, NULL ); if( startsector == DFS_ERRMISC ) { file_puts("Error finding partition start\r\n", handle); goto exit; } //get volume info if( DFS_GetVolInfo(0,scratch,startsector,volinfo) ) { file_puts("Error getting volume info\r\n", handle); goto exit; } //unlink file uint32_t result = DFS_UnlinkFile( volinfo, (u8_t*)argv[1], scratch ); if( result != DFS_OK ) { file_puts("Error unlinking file ", handle); file_puts( argv[1], handle ); file_puts(". RC=", handle ); file_putchar( (char)result + '0', handle); file_puts( CRLF, handle ); } exit: free( volinfo ); free( scratch ); }
//! This function adds files in play list //! //! @param sz_filterext add file only corresponding to the extension filter //! @param u8_mode PL_ADD_FILE, PL_ADD_DIR, PL_ADD_SUBDIR //! //! @return false in case of error, see global value "fs_g_status" for more detail //! @return true otherwise //! //! @verbatim //! It is possible to select a file or all files in a directory //! @endverbatim //! bool pl_add( const FS_STRING sz_filterext , uint8_t u8_mode ) { uint8_t nav_id_save; uint8_t u8_folder_level; if( !pl_main_modify() ) return false; nav_id_save = nav_get(); // Check last character of file nav_select( FS_NAV_ID_PLAYLIST ); if( 0!=nav_file_lgt() ) { #if( PL_UNICODE == true) file_string_unicode(); file_seek( 2, FS_SEEK_END); if( '\n' != file_getc()) { file_seek( 2, FS_SEEK_END); file_putc('\n'); } file_string_ascii(); #else file_seek( 1, FS_SEEK_END); if( '\n' != file_getc()) { file_seek( 1, FS_SEEK_END); file_putc('\n'); } #endif } nav_select( nav_id_save ); // Get path of play list file and check with current to create a relative path if( PL_ADD_FILE == u8_mode ) goto pl_add_file; // Add all files valid in current dir u8_folder_level = 0; nav_filelist_reset(); while(1) { while(1) { if( nav_filelist_set( 0 , FS_FIND_NEXT ) ) break; // a next file and directory is found // No other dir or file in current dir then go to parent dir if( 0 == u8_folder_level ) goto pl_add_end; // end of ADD // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list u8_folder_level--; if( !nav_dir_gotoparent() ) return false; } if( nav_file_isdir()) { if( PL_ADD_SUBDIR == u8_mode ) { // Enter in sub dir if( !nav_dir_cd()) return false; u8_folder_level++; } } else { pl_add_file: if( nav_file_checkext( sz_filterext ) ) { // It is a valid file // Get name of current file #if( (FS_ASCII == true) && (FS_UNICODE == true) && (PL_UNICODE == false) ) nav_string_ascii(); #endif nav_getcwd( (FS_STRING)pl_cache_path, PL_CACHE_PATH_MAX_SIZE, true ); #if( (FS_ASCII == true) && (FS_UNICODE == true) && (PL_UNICODE == false) ) nav_string_unicode(); #endif // Write path in file list nav_select( FS_NAV_ID_PLAYLIST ); #if( PL_UNICODE == true) file_string_unicode(); #endif if( file_puts(pl_cache_path)) file_putc('\n'); #if( PL_UNICODE == true) file_string_ascii(); #endif nav_select( nav_id_save ); pl_g_u16_list_size++; } if( PL_ADD_FILE == u8_mode ) goto pl_add_end; } // if dir OR file } // end of first while(1) pl_add_end: // Go to beginning of file AND no file selected nav_select( FS_NAV_ID_PLAYLIST ); file_seek( 0 , FS_SEEK_SET ); pl_g_u16_list_sel = 0; nav_select( nav_id_save ); return true; }
//The main telnet task void telnet_task_main(void) { /* commands[0].command="help"; commands[0].exec = &telnet_help; commands[1].command="echo"; commands[1].exec = &telnet_echo; commands[2].command="time"; commands[2].exec = &telnet_time; commands[3].command="quit"; commands[3].exec = &telnet_quit; commands[4].command="memdump"; commands[4].exec = &telnet_memdump; */ connection_event.event_mask = ReadableOrException; telnet_handle = FILE_INVALID_HANDLE; socket_listen(HTONS(23), &telnet_connect_accept ); unsigned short pos = 0; while(1) { restart: while( ! file_get_next_event( &telnet_handle, 1, &connection_event) ) { task_yield(); } if( connection_event.event & Exception ) { //#ifdef __DEBUG puts("\r\nTelnet: Closing connection"); //#endif file_close( telnet_handle ); telnet_handle = FILE_INVALID_HANDLE; pos = 0; optneg_mode = 0; goto restart; } unsigned short avail = buffer_available(&telnet_receive_buffer); char* rd_buf = buffer_read_ptr(&telnet_receive_buffer); while( pos < avail)//if avail == 1, rd_buf[0] is the last char we can read { unsigned char c = rd_buf[pos]; if( pos == REC_BUF_SIZE-1 ) { //buffer is full, but no CR/LF seen yet... what to do? //either discard line, or pretend the last char was \r ?? c = '\r'; } switch(c) { case TELNET_IAC: if( avail - pos > 2 ) { //buf[pos+1] = will/wont/do/dont //buf[pos+2] = option switch( (unsigned char) rd_buf[pos+2] ) { case TELNET_ECHO: switch( (unsigned char) rd_buf[pos+1] ) { case TELNET_DO: //other end wants us to echo telnet_mode |= MODE_ECHO; break; case TELNET_DONT: //other end demands we don't echo telnet_mode &= ~MODE_ECHO; break; } break; } //remove 3 chars from buffer buffer_unwrite(&telnet_receive_buffer, &rd_buf[pos], 3 ); avail -= 3; } else { task_yield(); } break; case '\r': // could be \r\n , \r\0 or just \r on its own pos++; if( telnet_mode & MODE_ECHO) { file_puts(CRLF, telnet_handle); } //if there's a following character, and it's \n or \0, chomp it too. if( pos < avail && (rd_buf[pos+1] == '\n' || rd_buf[pos+1] == '\0')) pos++; exec_line( rd_buf, rd_buf+pos ); //if read rd_buf[0], pos == 1 -> end = (rd_ptr + 1) buffer_seek( &telnet_receive_buffer, pos ); //free buffer rd_buf = buffer_read_ptr(&telnet_receive_buffer); pos = 0; avail = buffer_available(&telnet_receive_buffer); file_putchar('>', telnet_handle); break; case '\b': case 0x7f: puts("\r\ntel:backspace"); if( pos > 0 ) //not the first character { if( telnet_mode & MODE_ECHO) { file_putchar('\b', telnet_handle); file_putchar(' ', telnet_handle); file_putchar('\b', telnet_handle); } buffer_unwrite(&telnet_receive_buffer, &rd_buf[pos-1], 2 ); avail-=2; pos--; } else { buffer_unwrite(&telnet_receive_buffer, &rd_buf[pos], 1 ); avail--; } break; default: if( c >= ' ' && c <='~' ) { if( telnet_mode & MODE_ECHO) { file_putchar(c, telnet_handle); pos++; } } else { buffer_unwrite(&telnet_receive_buffer, &rd_buf[pos], 1 ); avail--; } }//end switch }//end while loop task_yield(); }//end outer while }
void telnet_ls( file_handle_t handle, char** argv, unsigned int argc ) { if( argc != 2 ) { file_puts("ls [path]\r\n", telnet_handle); return; } u8_t* scratch = malloc(SECTOR_SIZE); VOLINFO* volinfo = malloc( sizeof(VOLINFO) ); DIRINFO* dir = malloc( sizeof(DIRINFO) ); DIRENT* dirent = malloc( sizeof(DIRENT) ); //get partition start sector uint32_t startsector = DFS_GetPtnStart( 0, scratch, 0 , NULL, NULL, NULL ); if( startsector == DFS_ERRMISC ) { file_puts("Error finding partition start\r\n", handle); goto exit; } //get volume info if( DFS_GetVolInfo(0,scratch,startsector,volinfo) ) { file_puts("Error getting volume info\r\n", handle); goto exit; } //open dir dir->scratch = scratch; if( DFS_OpenDir( volinfo, (u8_t*)argv[1], dir ) ) { file_puts("Error opening dir ", handle); file_puts( argv[1], handle ); file_puts( CRLF, handle ); goto exit; } file_puts("Directory of ", handle ); file_puts( argv[1] , handle ); file_puts( CRLF, handle ); char* tmp = malloc(64); while( DFS_GetNext(volinfo, dir, dirent) == DFS_OK ) { if( dirent->name[0] != '\0' ) { char* t= tmp; uint32_t file_size =dirent->filesize_3; file_size <<= 8; file_size+=dirent->filesize_2; file_size <<= 8; file_size+=dirent->filesize_1; file_size <<= 8; file_size+=dirent->filesize_0; register uint16_t date = (dirent->wrtdate_h <<8) + dirent->wrtdate_l; register uint16_t time = (dirent->wrttime_h <<8) + dirent->wrttime_l; register uint8_t attr = dirent->attr; t+=sprintf(t,"%04hu-%02hu-%02hu %02hu:%02hu:%02hu ", (date >> 9) + 1980, (date & 0x01e0) >> 5, (date & 0x1f), (time >> 11), (time & 0x07e0) >>5, (time & 0x1f) << 1); t+=sprintf(t,"%c%c%c%c%c %10lu ", (attr & ATTR_READ_ONLY ? 'r':'-'), (attr & ATTR_HIDDEN ? 'h':'-'), (attr & ATTR_SYSTEM ? 's':'-'), (attr & ATTR_DIRECTORY ? 'd':'-'), (attr & ATTR_ARCHIVE ? 'a':'-'), file_size); sprintf(t,"%s",dirent->name); t[12] = '\0'; t[11] = t[10]; t[10] = t[9]; t[9] = t[8]; t[8] = (attr & ATTR_DIRECTORY ? ' ':'.'); file_puts( tmp, handle ); file_puts( CRLF, handle ); } }
void telnet_touch( file_handle_t handle, char** argv, unsigned int argc ) { if( argc < 2 ) { file_puts("touch [filename] [data to write] [...]\r\n", telnet_handle); return; } u8_t* scratch = malloc(SECTOR_SIZE); VOLINFO* volinfo = malloc( sizeof(VOLINFO) ); FILEINFO* file = malloc( sizeof(FILEINFO) ); //get partition start sector uint32_t startsector = DFS_GetPtnStart( 0, scratch, 0 , NULL, NULL, NULL ); if( startsector == DFS_ERRMISC ) { file_puts("Error finding partition start\r\n", handle); goto exit; } //get volume info if( DFS_GetVolInfo(0,scratch,startsector,volinfo) ) { file_puts("Error getting volume info\r\n", handle); goto exit; } //open file uint32_t result = DFS_OpenFile( volinfo, (u8_t*)argv[1], DFS_WRITE, scratch, file ); if(!( result == DFS_OK || result == DFS_EOF)) { file_puts("Error opening file ", handle); file_puts( argv[1], handle ); file_puts(". RC=", handle ); file_putchar( (char)result + '0', handle); file_puts( CRLF, handle ); goto exit; } uint16_t i; for( i = 2; i < argc; i++ ) { uint32_t did_write; uint16_t len = strlen(argv[i]); DFS_WriteFile( file, scratch, argv[i], &did_write, len ); if( did_write != len ) { file_puts("Error writing to file ", handle); file_puts( argv[1], handle ); file_puts( CRLF, handle ); break; } if( i < (argc-1) ) { DFS_WriteFile( file, scratch, " ", &did_write, 1 ); if( did_write != 1 ) { file_puts("Error writing to file ", handle); file_puts( argv[1], handle ); file_puts( CRLF, handle ); break; } } } exit: free( file ); free( volinfo ); free( scratch ); }