// 'ls' and 'dir' handler static void shell_ls( int argc, char **argv ) { const DM_INSTANCE_DATA *pinst; unsigned dev, i; DM_DIR *d; struct dm_dirent *ent; u32 total; ( void )argc; ( void )argv; // Iterate through all devices, looking for the ones that can do "opendir" for( dev = 0; dev < dm_get_num_devices(); dev ++ ) { pinst = dm_get_instance_at( dev ); if( pinst->pdev->p_opendir_r == NULL || pinst->pdev->p_readdir_r == NULL || pinst->pdev->p_closedir_r == NULL ) continue; d = dm_opendir( pinst->name ); if( d ) { total = 0; printf( "\n%s", pinst->name ); while( ( ent = dm_readdir( d ) ) != NULL ) { printf( "\n%s", ent->fname ); for( i = strlen( ent->fname ); i <= DM_MAX_FNAME_LENGTH; i++ ) printf( " " ); printf( "%u bytes", ( unsigned )ent->fsize ); total = total + ent->fsize; } printf( "\n\nTotal on %s: %u bytes\n", pinst->name, ( unsigned )total ); dm_closedir( d ); } } printf( "\n" ); }
int _rename_r( struct _reent *r, const char *oldname, const char *newname ) { char *actname_old, *actname_new; int devid_old, devid_new; const DM_INSTANCE_DATA *pinst; // Look for device, return error if not found or if function not implemented if( ( devid_old = find_dm_entry( oldname, &actname_old ) ) == -1 ) { r->_errno = ENODEV; return -1; } if( ( devid_new = find_dm_entry( newname, &actname_new ) ) == -1 ) { r->_errno = ENODEV; return -1; } if( devid_old == devid_new ) { pinst = dm_get_instance_at( devid_old ); if( pinst->pdev->p_rename_r == NULL ) { r->_errno = EPERM; return -1; } // Device found, call its function return pinst->pdev->p_rename_r( r, actname_old, actname_new, pinst->pdata ); } // Cannot rename between different devices (EXDEV) r->_errno = EXDEV; return -1; }
const char *dm_getaddr( int fd ) { const DM_INSTANCE_DATA *pinst; // Find device, check write function pinst = dm_get_instance_at( DM_GET_DEVID( fd ) ); if( !pinst || pinst->pdev->p_getaddr_r == NULL ) { _REENT->_errno = ENOSYS; return NULL; } return pinst->pdev->p_getaddr_r( _REENT, DM_GET_FD( fd ), pinst->pdata ); }
// ***************************************************************************** // _close_r int _close_r( struct _reent *r, int file ) { const DM_INSTANCE_DATA *pinst; // Find device, check close function pinst = dm_get_instance_at( DM_GET_DEVID( file ) ); if( pinst->pdev->p_close_r == NULL ) { r->_errno = ENOSYS; return -1; } // And call the close function return pinst->pdev->p_close_r( r, DM_GET_FD( file ), pinst->pdata ); }
// ***************************************************************************** // _write_r _ssize_t _write_r( struct _reent *r, int file, const void *ptr, size_t len ) { const DM_INSTANCE_DATA *pinst; // Find device, check write function pinst = dm_get_instance_at( DM_GET_DEVID( file ) ); if( pinst->pdev->p_write_r == NULL ) { r->_errno = ENOSYS; return -1; } // And call the write function return pinst->pdev->p_write_r( r, DM_GET_FD( file ), ptr, len, pinst->pdata ); }
// Utility function: look in the device manager table and find the index // for the given name. Returns an index into the device structure, -1 if error. // Also returns a pointer to the actual file name (without the device part) static int find_dm_entry( const char* name, char **pactname ) { int i; const DM_INSTANCE_DATA* pinst; const char* preal; char tempname[ DM_MAX_DEV_NAME + 1 ]; // Sanity check for name if( name == NULL || *name == '\0' || *name != '/' ) return -1; // Find device name preal = strchr( name + 1, '/' ); if( preal == NULL ) { // This shortcut allows to register the "/" filesystem and use it like "/file.ext" strcpy( tempname, "/" ); preal = name; } else { if( ( preal - name > DM_MAX_DEV_NAME ) || ( preal - name == 1 ) ) // name too short/too long return -1; memcpy( tempname, name, preal - name ); tempname[ preal - name ] = '\0'; } // Find device for( i = 0; i < dm_get_num_devices(); i ++ ) { pinst = dm_get_instance_at( i ); if( !strcasecmp( tempname, pinst->name ) ) break; } if( i == dm_get_num_devices() ) return -1; // Find the actual first char of the name preal ++; if( *preal == '\0' ) return -1; *pactname = ( char * )preal; return i; }
// **************************************************************************** // _mkdir_r int _mkdir_r( struct _reent *r, const char *path, mkdir_mode_t mode ) { char *actname; int res, devid; const DM_INSTANCE_DATA *pinst; // Look for device, return error if not found or if function not implemented if( ( devid = find_dm_entry( path, &actname ) ) == -1 ) { r->_errno = ENODEV; return -1; } pinst = dm_get_instance_at( devid ); if( pinst->pdev->p_mkdir_r == NULL ) { r->_errno = EPERM; return -1; } // Device found, call its function return pinst->pdev->p_mkdir_r( r, actname - 1, mode, pinst->pdata ); }
int rmdir( const char *path ) { char* actname; int devid; const DM_INSTANCE_DATA *pinst; // Look for device, return error if not found or if function not implemented if( ( devid = find_dm_entry( path, &actname ) ) == -1 ) { _REENT->_errno = ENODEV; return -1; } pinst = dm_get_instance_at( devid ); if( pinst->pdev->p_rmdir_r == NULL ) { _REENT->_errno = ENOSYS; return -1; } // Device found, call its function return pinst->pdev->p_rmdir_r( _REENT, actname, pinst->pdata ); }
// **************************************************************************** // _unlink_r int _unlink_r( struct _reent *r, const char *fname ) { char* actname; int devid; const DM_INSTANCE_DATA *pinst; // Look for device, return error if not found or if function not implemented if( ( devid = find_dm_entry( fname, &actname ) ) == -1 ) { r->_errno = ENODEV; return -1; } pinst = dm_get_instance_at( devid ); if( pinst->pdev->p_unlink_r == NULL ) { r->_errno = ENOSYS; return -1; } // Device found, call its function return pinst->pdev->p_unlink_r( r, actname, pinst->pdata ); }
// ***************************************************************************** // _open_r int _open_r( struct _reent *r, const char *name, int flags, int mode ) { char *actname; int res, devid; const DM_INSTANCE_DATA *pinst; // Look for device, return error if not found or if function not implemented if( ( devid = find_dm_entry( name, &actname ) ) == -1 ) { r->_errno = ENODEV; return -1; } pinst = dm_get_instance_at( devid ); if( pinst->pdev->p_open_r == NULL ) { r->_errno = ENOSYS; return -1; } // Device found, call its function if( ( res = pinst->pdev->p_open_r( r, actname, flags, mode, pinst->pdata ) ) < 0 ) return res; return DM_MAKE_DESC( devid, res ); }