void sd_close() { fat16_close_dir(sd_dd); fat16_close(sd_fs); partition_close(sd_partition); sd_dd = 0; sd_fs = 0; sd_partition = 0; }
/** * \ingroup tcpftp * \b CDUP-Befehl * * ein Verzeichnis in der Hierarchie nach oben wechseln */ int16_t cmd_CDUP(char *outbuffer) { #if !USE_MMC return cmd_502(outbuffer); #else #if !FTP_ANONYMOUS if (outbuffer && !tcpsrv_status.loginOK) return cmd_530(outbuffer); #endif // ein Verzeichnis nach oben int8_t i = strlen(cwdirectory) - 1; char *pdir = (char *)cwdirectory; for (;i>=0;--i) { if (*(pdir+i) == '/') { *(pdir+i) = '\0'; break; } } if (i <= 0) { strcpy_P((char *)cwdirectory,PSTR("/")); // oben angekommen } // Zeiger aktualisieren struct fat16_dir_entry_struct directory; if (fat16_get_dir_entry_of_path(sd_get_fs(), cwdirectory, &directory)) { struct fat16_dir_struct* dir_new = fat16_open_dir(sd_get_fs(), &directory); if(dir_new) { if(cwdir_ptr != sd_get_root_dir()) fat16_close_dir(cwdir_ptr); cwdir_ptr = dir_new; } } if (outbuffer) { sprintf_P(outbuffer,PSTR("250 Directory changed to %s\r\n"),cwdirectory); return strlen(outbuffer); } else { return 0; } #endif }
void AF_Wave::close_dir(void) { // close it fat16_close_dir(dd); }
/** * \ingroup tcpftp * \b CWD bzw. \b CD-Befehl * * neuen Pfad in cwdirectory abspeichern und auf Existenz überprüfen * \remarks * cwdirectory enthält den aktuellen Pfad ohne trailing "/" * nur das Rootverzeichnis enthält "/" */ int16_t cmd_CWD(char *outbuffer) { #if !USE_MMC return cmd_502(outbuffer); #else #if !FTP_ANONYMOUS if (outbuffer && !tcpsrv_status.loginOK) return cmd_530(outbuffer); #endif char tmpdir[MAX_PATH+1]; if (*argv != '/') { // bei aktuellem directory beginnen strcpy(tmpdir,cwdirectory); if ((strlen(argv) == 2) && *argv == '.' && *(argv+1) == '.') { strcat_P(argv,PSTR("/")); } while ((strlen(argv) > 2) && *argv == '.' && *(argv+1) == '.' && *(argv+2) == '/') { // ein Verzeichnis nach oben int8_t i = strlen(tmpdir) - 1; for (;i>=0;--i) { if (tmpdir[i] == '/') { tmpdir[i] = '\0'; break; } } if (i <= 0) { tmpdir[0] = '/'; // oben angekommen tmpdir[1] = '\0'; } argv += 3; } if (*argv == '.' && *(argv+1) == '/') argv += 2; // zeigt auf aktuelles Verzeichnis register uint8_t len = strlen(tmpdir); register uint8_t lennew = strlen(argv); if ( (len > 1) && lennew ) // falls nicht root und neues Unterverzeichnis übergeben wurde strcat_P(tmpdir,PSTR("/")); // also nicht ".." eingegeben if ((len + lennew) < MAX_PATH) { // falls der Pfad auch in den Speicherplatz passt register char *ptr = argv; // letzen '/' bei Unterverzeichnis entfernen while (*ptr++); ptr -= 2; if (*ptr == '/') *ptr = '\0'; strcat(tmpdir,argv); } } else { register uint8_t lennew = strlen(argv) - 1; // letzten '/' entfernen falls vorhanden if ( lennew > 0 && *(argv + lennew) == '/' ) *(argv + lennew) = '\0'; strcpy(tmpdir,argv); } // Verzeichnis überprüfen und Zeiger neu setzen struct fat16_dir_entry_struct directory; if (fat16_get_dir_entry_of_path(sd_get_fs(), tmpdir, &directory)) { // neues Verzeichnis gefunden strcpy((char *)cwdirectory,tmpdir); struct fat16_dir_struct* dir_new = fat16_open_dir(sd_get_fs(), &directory); if(dir_new) { if(cwdir_ptr != sd_get_root_dir()) fat16_close_dir(cwdir_ptr); cwdir_ptr = dir_new; } } if (outbuffer) { sprintf_P(outbuffer,PSTR("250 Directory changed to %s\r\n"),cwdirectory); return strlen(outbuffer); } else { return 0; } #endif }
int main() { /* setup uart */ uart_init(); /* setup stdio */ uart_connect_stdio(); /* setup sd card slot */ if(!sd_raw_init()) { #if DEBUG printf_P(PSTR("MMC/SD initialization failed\n")); #endif return 1; } /* open first partition */ struct partition_struct* partition = partition_open(sd_raw_read, sd_raw_read_interval, sd_raw_write, 0); if(!partition) { /* If the partition did not open, assume the storage device * is a "superfloppy", i.e. has no MBR. */ partition = partition_open(sd_raw_read, sd_raw_read_interval, sd_raw_write, -1 ); if(!partition) { #if DEBUG printf_P(PSTR("opening partition failed\n")); #endif return 1; } } /* open file system */ struct fat16_fs_struct* fs = fat16_open(partition); if(!fs) { #if DEBUG printf_P(PSTR("opening filesystem failed\n")); #endif return 1; } /* open root directory */ struct fat16_dir_entry_struct directory; fat16_get_dir_entry_of_path(fs, "/", &directory); struct fat16_dir_struct* dd = fat16_open_dir(fs, &directory); if(!dd) { #if DEBUG printf_P(PSTR("opening root directory failed\n")); #endif return 1; } /* provide a simple shell */ char buffer[24]; while(1) { /* print prompt */ uart_putc('>'); uart_putc(' '); /* read command */ char* command = buffer; if(read_line(command, sizeof(buffer)) < 1) continue; /* execute command */ if(strncmp_P(command, PSTR("cd "), 3) == 0) { command += 3; if(command[0] == '\0') continue; /* change directory */ struct fat16_dir_entry_struct subdir_entry; if(find_file_in_dir(fs, dd, command, &subdir_entry)) { struct fat16_dir_struct* dd_new = fat16_open_dir(fs, &subdir_entry); if(dd_new) { fat16_close_dir(dd); dd = dd_new; continue; } } printf_P(PSTR("directory not found: %s\n"), command); } else if(strcmp_P(command, PSTR("ls")) == 0) { /* print directory listing */ struct fat16_dir_entry_struct dir_entry; while(fat16_read_dir(dd, &dir_entry)) { printf_P(PSTR("%10lu %s%c\n"), dir_entry.file_size, dir_entry.long_name, (dir_entry.attributes & FAT16_ATTRIB_DIR) ? '/' : ' ' ); } } else if(strncmp_P(command, PSTR("cat "), 4) == 0) { command += 4; if(command[0] == '\0') continue; /* search file in current directory and open it */ struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command); if(!fd) { printf_P(PSTR("error opening %s\n"), command); continue; } /* print file contents */ uint8_t buffer[8]; uint32_t offset = 0; while(fat16_read_file(fd, buffer, sizeof(buffer)) > 0) { printf_P(PSTR("%08lx: %02x %02x %02x %02x %02x %02x %02x %02x\n"), offset, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7] ); offset += 8; } fat16_close_file(fd); } #if FAT16_WRITE_SUPPORT else if(strncmp_P(command, PSTR("rm "), 3) == 0) { command += 3; if(command[0] == '\0') continue; struct fat16_dir_entry_struct file_entry; if(find_file_in_dir(fs, dd, command, &file_entry)) { if(fat16_delete_file(fs, &file_entry)) continue; } printf_P(PSTR("error deleting file: %s\n"), command); } else if(strncmp_P(command, PSTR("touch "), 6) == 0) { command += 6; if(command[0] == '\0') continue; struct fat16_dir_entry_struct file_entry; if(!fat16_create_file(dd, command, &file_entry)) printf_P(PSTR("error creating file: %s\n"), command); } else if(strncmp_P(command, PSTR("write "), 6) == 0) { command += 6; if(command[0] == '\0') continue; char* offset_value = command; while(*offset_value != ' ' && *offset_value != '\0') ++offset_value; if(*offset_value == ' ') *offset_value++ = '\0'; else continue; /* search file in current directory and open it */ struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command); if(!fd) { printf_P(PSTR("error opening %s\n"), command); continue; } int32_t offset = strtol(offset_value, 0, 0); if(!fat16_seek_file(fd, &offset, FAT16_SEEK_SET)) { printf_P(PSTR("error seeking on %s\n"), command); fat16_close_file(fd); continue; } /* read text from the shell and write it to the file */ uint8_t data_len; while(1) { /* give a different prompt */ uart_putc('<'); uart_putc(' '); /* read one line of text */ data_len = read_line(buffer, sizeof(buffer)); if(!data_len) break; /* write text to file */ if(fat16_write_file(fd, (uint8_t*) buffer, data_len) != data_len) { printf_P(PSTR("error writing to file\n")); break; } } fat16_close_file(fd); } #endif #if SD_RAW_WRITE_BUFFERING else if(strcmp_P(command, PSTR("sync")) == 0) { if(!sd_raw_sync()) printf_P(PSTR("error syncing disk\n")); } #endif else { printf_P(PSTR("unknown command: %s\n"), command); } } /* close file system */ fat16_close(fs); /* close partition */ partition_close(partition); return 0; }