/** Directory listing callback. * Responds to a SBP_MSG_FILEIO_READ_DIR_REQUEST message. * * The offset parameter can be used to skip the first n elements of the file * list. * * Returns a SBP_MSG_FILEIO_READ_DIR_RESPONSE message containing the directory * listings as a NULL delimited list. The listing is chunked over multiple SBP * packets and the end of the list is identified by an entry containing just * the character 0xFF. */ static void read_dir_cb(u16 sender_id, u8 len, u8 msg[], void* context) { (void)context; if (sender_id != SBP_SENDER_ID) { log_error("Invalid sender!\n"); return; } if ((len < 5) || (msg[len-1] != '\0')) { log_error("Invalid fileio read dir message!\n"); return; } u32 offset = ((u32)msg[3] << 24) | ((u32)msg[2] << 16) | (msg[1] << 8) | msg[0]; struct cfs_dir dir; struct cfs_dirent dirent; u8 buf[256]; memcpy(buf, msg, len); cfs_opendir(&dir, (char*)&msg[4]); while (offset && (cfs_readdir(&dir, &dirent) == 0)) offset--; while ((cfs_readdir(&dir, &dirent) == 0) && (len < SBP_FRAMING_MAX_PAYLOAD_SIZE)) { strncpy((char*)buf + len, dirent.name, SBP_FRAMING_MAX_PAYLOAD_SIZE - len); len += strlen(dirent.name) + 1; } if (len < SBP_FRAMING_MAX_PAYLOAD_SIZE) buf[len++] = 0xff; cfs_closedir(&dir); sbp_send_msg(SBP_MSG_FILEIO_READ_DIR_RESPONSE, len, buf); }
/*-----------------------------------------------------------------------------------*/ static void read_dirent(void) { static struct cfs_dirent dirent; static char message[40]; if(loading == LOADING_DIR) { if(cfs_readdir(&dir, &dirent)) { cfs_closedir(&dir); loading = LOADING_DSC; filenameptr = 0; } else if(strcasecmp(&dirent.name[strlen(dirent.name) - 4], ".dsc") == 0) { strncpy(filenames[numfiles], dirent.name, FILENAMELEN); ++numfiles; if(numfiles == MAX_NUMFILES) { cfs_closedir(&dir); loading = LOADING_DSC; filenameptr = 0; return; } strcpy(message, "Found \""); strcpy(message + 7, dirent.name); strcpy(message + 7 + strlen(dirent.name), "\"..."); show_statustext(message); } } }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_ls_process, ev, data) { static struct cfs_dir dir; static cfs_offset_t totsize; struct cfs_dirent dirent; char buf[32]; PROCESS_BEGIN(); if(data != NULL) { if(cfs_opendir(&dir, data) != 0) { shell_output_str(&ls_command, "Cannot open directory", ""); } else { totsize = 0; while(cfs_readdir(&dir, &dirent) == 0) { totsize += dirent.size; sprintf(buf, "%lu ", (unsigned long)dirent.size); /* printf("'%s'\n", dirent.name);*/ shell_output_str(&ls_command, buf, dirent.name); } cfs_closedir(&dir); sprintf(buf, "%lu", (unsigned long)totsize); shell_output_str(&ls_command, "Total size: ", buf); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ char ctk_filedialog_eventhandler(struct ctk_filedialog_state *s, process_event_t ev, process_data_t data) { static struct cfs_dirent dirent; if(state == STATE_OPEN) { if(ev == ctk_signal_widget_activate && data == (process_data_t)&button) { ctk_dialog_close(); state = STATE_CLOSED; process_post(PROCESS_CURRENT(), s->ev, &filename); return 1; } else if(ev == PROCESS_EVENT_CONTINUE && (process_data_t)s == data) { if(cfs_readdir(&dir, &dirent) == 0 && dirfileptr < MAX_NUMFILES) { strncpy(&files[dirfileptr * FILES_WIDTH], dirent.name, FILES_WIDTH); CTK_WIDGET_REDRAW(&fileslabel); ++dirfileptr; process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, s); } else { fileptr = 0; cfs_closedir(&dir); } return 1; } else if(ev == ctk_signal_keypress) { if((char)(size_t)data == CH_CURS_UP) { clearptr(); if(fileptr > 0) { --fileptr; } showptr(); return 1; } else if((char)(size_t)data == CH_CURS_DOWN) { clearptr(); if(fileptr < FILES_HEIGHT - 1) { ++fileptr; } showptr(); return 1; } } } return 0; }
static int dir_test(void) { struct cfs_dir dir; struct cfs_dirent dirent; /* Coffee provides a root directory only. */ if(cfs_opendir(&dir, "/") != 0) { printf("failed to open the root directory\n"); return 0; } /* List all files and their file sizes. */ printf("Available files\n"); while(cfs_readdir(&dir, &dirent) == 0) { printf("%s (%lu bytes)\n", dirent.name, (unsigned long)dirent.size); } cfs_closedir(&dir); return 1; }
/*-----------------------------------------------------------------------------------*/ void shell_eventhandler(ek_event_t ev, ek_data_t data) { static struct cfs_dirent dirent; static char size[10]; if(ev == EK_EVENT_CONTINUE) { if(showingdir != 0) { if(cfs_readdir(&dir, &dirent) != 0) { cfs_closedir(&dir); showingdir = 0; inttostr(size, totsize); shell_output("Total number of blocks: ", size); shell_prompt("contiki-c64> "); } else { totsize += dirent.size; inttostr(size, dirent.size); shell_output(size, dirent.name); ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); } } } }
//TODO: help verify void handle_list_file(char* prefix) { log_info("handle_list_file(%s)\n", prefix); char buf[200] = ""; uint8_t buf_size = 0; struct cfs_dir dir; int ret = cfs_opendir(&dir, ""); if (ret == -1) { log_info("cfs_opendir() failed: %d\n", ret); return; } while (ret != -1) { struct cfs_dirent dirent; ret = cfs_readdir(&dir, &dirent); if (ret != -1) { log_info("file:%s, %d\n", dirent.name, dirent.size); char* short_name = filter_filename_by_prefix(prefix, dirent.name); uint8_t len = strlen(short_name) + 1; if (buf_size + len >= sizeof(buf) - 1) break; strcat(buf, short_name); strcat(buf, ";"); buf_size += len; } } cfs_closedir(&dir); send_file_list(buf); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(console_server, ev, data) { static uint8_t buf[257]; static uint8_t processingFile = 0; static uint32_t received = 0; static struct cfs_dirent dirent; static struct cfs_dir dir; static uint32_t fdFile; static char *filename; PROCESS_BEGIN(); elfloader_init(); printf("Console server started !\n"); while(1) { PROCESS_YIELD(); if (ev == serial_line_event_message) { if (!strcmp(data, "ls")) { if(cfs_opendir(&dir, ".") == 0) { while(cfs_readdir(&dir, &dirent) != -1) { printf("File: %s (%ld bytes)\n", dirent.name, (long)dirent.size); } cfs_closedir(&dir); } } else if (!strcmp(data, "format")) { /* format the flash */ printf("Formatting\n"); printf("It takes around 3 minutes\n"); printf("...\n"); fdFile = cfs_coffee_format(); printf("Formatted with result %ld\n", fdFile); } else if (strstr(data, "cat") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ); if (fdFile < 0) printf("error opening the file %s\n", tmp); while ((n = cfs_read(fdFile, buf, 60)) > 0) { for (jj = 0 ; jj < n ; jj++) printf("%c", (char)buf[jj]); } printf("\n"); cfs_close(fdFile); if (n!=0) printf("Some error reading the file\n"); } else if (strstr(data, "loadelf") == data) { filename = strstr(data, " "); filename++; // Cleanup previous loads if (elfloader_autostart_processes != NULL) autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; // Load elf file fdFile = cfs_open(filename, CFS_READ | CFS_WRITE); received = elfloader_load(fdFile); cfs_close(fdFile); printf("Result of loading %lu\n", received); // As the file has been modified and can't be reloaded, remove it printf("Remove dirty firmware '%s'\n", filename); cfs_remove(filename); // execute the program if (ELFLOADER_OK == received) { if (elfloader_autostart_processes) { PRINT_PROCESSES(elfloader_autostart_processes); autostart_start(elfloader_autostart_processes); } } else if (ELFLOADER_SYMBOL_NOT_FOUND == received) { printf("Symbol not found: '%s'\n", elfloader_unknown); } } else if (strstr(data, "rm") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; cfs_remove(tmp); } else if (strstr(data, "upload") == data) { char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ | CFS_WRITE); printf("Uploading file %s\n", tmp); processingFile = 1; } else if (!strcmp(data, "endupload")) { cfs_close(fdFile); printf("File uploaded (%ld bytes)\n", received); received = 0; processingFile = 0; } else if (processingFile) { int n = strlen(data); int r = decode(data, n, buf); received += r; cfs_write(fdFile, buf, r); } else { printf("%s (%lu bytes received)\n", (char*)data, received); } } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(ftp_process, ev, data) { uip_ipaddr_t ipaddr; uip_ipaddr_t *ipaddrptr; PROCESS_BEGIN(); ftpc_init(); memset(statustext, 0, sizeof(statustext)); memset(remotefiles, 0, sizeof(remotefiles)); memset(localfiles, 0, sizeof(localfiles)); memset(leftptr, 0, sizeof(leftptr)); memset(midptr, 0, sizeof(midptr)); memset(rightptr, 0, sizeof(rightptr)); ptrstate = PTRSTATE_REMOTEFILES; localptr = remoteptr = 0; connection = NULL; ctk_window_new(&window, 3 + FILES_WIDTH * 2, 3 + FILES_HEIGHT, "FTP Client"); CTK_WIDGET_ADD(&window, &localtextlabel); CTK_WIDGET_ADD(&window, &remotetextlabel); CTK_WIDGET_ADD(&window, &leftptrlabel); CTK_WIDGET_ADD(&window, &localfileslabel); CTK_WIDGET_ADD(&window, &midptrlabel); CTK_WIDGET_ADD(&window, &remotefileslabel); CTK_WIDGET_ADD(&window, &rightptrlabel); CTK_WIDGET_ADD(&window, &reloadbutton); #if CTK_CONF_WINDOWS CTK_WIDGET_ADD(&window, &connectionbutton); #else /* CTK_CONF_WINDOWS */ CTK_WIDGET_ADD(&window, &usagetextlabel); #endif /* CTK_CONF_WINDOWS */ CTK_WIDGET_ADD(&window, &quitbutton); CTK_WIDGET_ADD(&window, &statuslabel); #if CTK_CONF_WINDOWS CTK_WIDGET_FOCUS(&window, &connectionbutton); #endif /* CTK_CONF_WINDOWS */ #if CTK_CONF_WINDOWS ctk_window_open(&window); showptr(); start_loaddir(); ptractive = 1; #else /* CTK_CONF_WINDOWS */ make_connectionwindow(); ctk_window_open(&connectionwindow); #endif /* CTK_CONF_WINDOWS */ while(1) { PROCESS_WAIT_EVENT(); if(ev == PROCESS_EVENT_CONTINUE) { if(cfs_readdir(&dir, &dirent) == 0 && localfileptr < FILES_HEIGHT) { strncpy(&localfiles[localfileptr * FILES_WIDTH], dirent.name, FILES_WIDTH); CTK_WIDGET_REDRAW(&localfileslabel); ++localfileptr; process_post(&ftp_process, PROCESS_EVENT_CONTINUE, NULL); } else{ cfs_closedir(&dir); } } else if(ev == PROCESS_EVENT_EXIT) { quit(); } else if(ev == tcpip_event) { ftpc_appcall(data); #if UIP_UDP } else if(ev == resolv_event_found) { /* Either found a hostname, or not. */ if((char *)data != NULL && resolv_lookup((char *)data, &ipaddrptr) == RESOLV_STATUS_CACHED) { connection = ftpc_connect(ipaddrptr, UIP_HTONS(21)); show_statustext("Connecting to ", hostname); } else { show_statustext("Host not found: ", hostname); } #endif /* UIP_UDP */ } else if( #if CTK_CONF_WINDOWCLOSE ev == ctk_signal_window_close && #endif /* CTK_CONF_WINDOWCLOSE */ data == (process_data_t)&window) { quit(); } else if(ev == ctk_signal_widget_activate) { if((struct ctk_button *)data == &quitbutton) { quit(); } else if((struct ctk_button *)data == &cancelbutton) { #if CTK_CONF_WINDOWS ctk_dialog_close(); #else /* CTK_CONF_WINDOWS */ ctk_window_close(&dialog); ctk_window_open(&window); #endif /* CTK_CONF_WINDOWS */ ptractive = 1; } else if((struct ctk_button *)data == &downloadbutton) { #if CTK_CONF_WINDOWS ctk_dialog_close(); #else /* CTK_CONF_WINDOWS */ ctk_window_close(&dialog); ctk_window_open(&window); #endif /* CTK_CONF_WINDOWS */ ptractive = 1; close_file(); fd = cfs_open(localfilename, CFS_WRITE); if(fd != -1) { show_statustext("Downloading ", remotefilename); ftpc_get(connection, remotefilename); } else { show_statustext("Could not create ", localfilename); } } else if((struct ctk_button *)data == &reloadbutton) { start_loaddir(); #if CTK_CONF_WINDOWS } else if((struct ctk_button *)data == &connectionbutton) { ptractive = 0; make_connectionwindow(); ctk_dialog_open(&connectionwindow); } else if((struct ctk_button *)data == &closebutton) { ctk_dialog_close(); ptractive = 1; #endif /* CTK_CONF_WINDOWS */ } else if((struct ctk_button *)data == &anonymousbutton) { strcpy(username, "anonymous"); strcpy(password, "contiki@ftp"); CTK_WIDGET_REDRAW(&userentry); CTK_WIDGET_REDRAW(&passwordentry); #if CTK_CONF_WINDOWS } else if((struct ctk_button *)data == &closeconnectionbutton) { ctk_dialog_close(); ptractive = 1; ftpc_close(connection); #endif /* CTK_CONF_WINDOWS */ } else if((struct ctk_button *)data == &connectbutton) { #if CTK_CONF_WINDOWS ctk_dialog_close(); #else /* CTK_CONF_WINDOWS */ ctk_window_close(&connectionwindow); ctk_window_open(&window); showptr(); start_loaddir(); #endif /* CTK_CONF_WINDOWS */ ptractive = 1; #if UIP_UDP if(uiplib_ipaddrconv(hostname, &ipaddr) == 0) { if(resolv_lookup(hostname, &ipaddrptr) != RESOLV_STATUS_CACHED) { resolv_query(hostname); show_statustext("Resolving host ", hostname); break; } connection = ftpc_connect(ipaddrptr, UIP_HTONS(21)); show_statustext("Connecting to ", hostname); } else { connection = ftpc_connect(&ipaddr, UIP_HTONS(21)); show_statustext("Connecting to ", hostname); } #else /* UIP_UDP */ uiplib_ipaddrconv(hostname, &ipaddr); connection = ftpc_connect(&ipaddr, UIP_HTONS(21)); show_statustext("Connecting to ", hostname); #endif /* UIP_UDP */ } /* if((struct ctk_button *)data == &closebutton) { ftpc_close(connection); }*/ } else if(ptractive && ev == ctk_signal_keypress) { if((ctk_arch_key_t)(size_t)data == ' ') { if(ptrstate == PTRSTATE_LOCALFILES) { ptrstate = PTRSTATE_REMOTEFILES; } else { ptrstate = PTRSTATE_LOCALFILES; } } else if((ctk_arch_key_t)(size_t)data == CH_CURS_UP) { clearptr(); if(ptrstate == PTRSTATE_LOCALFILES) { if(localptr > 0) { --localptr; } } else { if(remoteptr > 0) { --remoteptr; } } } else if((ctk_arch_key_t)(size_t)data == CH_CURS_DOWN) { clearptr(); if(ptrstate == PTRSTATE_LOCALFILES) { if(localptr < FILES_HEIGHT - 1) { ++localptr; } } else { if(remoteptr < FILES_HEIGHT - 1) { ++remoteptr; } } } else if((ctk_arch_key_t)(size_t)data == CH_ENTER) { if(ptrstate == PTRSTATE_LOCALFILES) { strncpy(localfilename, &localfiles[localptr * FILES_WIDTH], FILES_WIDTH); strncpy(remotefilename, &localfiles[localptr * FILES_WIDTH], FILES_WIDTH); ptractive = 0; make_uploaddialog(); #if CTK_CONF_WINDOWS ctk_dialog_open(&dialog); #else /* CTK_CONF_WINDOWS */ ctk_window_close(&window); ctk_window_open(&dialog); #endif /* CTK_CONF_WINDOWS */ } else { strncpy(localfilename, &remotefiles[remoteptr * FILES_WIDTH], FILES_WIDTH); strncpy(remotefilename, &remotefiles[remoteptr * FILES_WIDTH], FILES_WIDTH); ftpc_cwd(connection, remotefilename); /* make_downloaddialog(); ctk_dialog_open(&dialog);*/ } } else if((ctk_arch_key_t)(size_t)data == 'u') { ftpc_cdup(connection); } if(ptractive) { showptr(); } } } PROCESS_END(); }