2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
NTVFS base code
Copyright ( C ) Andrew Tridgell 2003
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
/*
this implements the core code for all NTVFS modules . Backends register themselves here .
*/
# include "includes.h"
/* the list of currently registered NTVFS backends, note that there
* can be more than one backend with the same name , as long as they
* have different typesx */
static struct {
struct ntvfs_ops * ops ;
} * backends = NULL ;
static int num_backends ;
/*
register a NTVFS backend .
The ' name ' can be later used by other backends to find the operations
structure for this backend .
The ' type ' is used to specify whether this is for a disk , printer or IPC $ share
*/
2003-11-25 03:15:26 +00:00
static NTSTATUS ntvfs_register ( void * _ops )
2003-08-13 01:53:07 +00:00
{
2003-11-25 03:15:26 +00:00
struct ntvfs_ops * ops = _ops ;
if ( ntvfs_backend_byname ( ops - > name , ops - > type ) ! = NULL ) {
2003-08-13 01:53:07 +00:00
/* its already registered! */
DEBUG ( 2 , ( " NTVFS backend '%s' for type %d already registered \n " ,
2003-11-25 03:15:26 +00:00
ops - > name , ( int ) ops - > type ) ) ;
return NT_STATUS_OBJECT_NAME_COLLISION ;
2003-08-13 01:53:07 +00:00
}
backends = Realloc ( backends , sizeof ( backends [ 0 ] ) * ( num_backends + 1 ) ) ;
if ( ! backends ) {
smb_panic ( " out of memory in ntvfs_register " ) ;
}
backends [ num_backends ] . ops = smb_xmemdup ( ops , sizeof ( * ops ) ) ;
2003-11-25 03:15:26 +00:00
backends [ num_backends ] . ops - > name = smb_xstrdup ( ops - > name ) ;
2003-08-13 01:53:07 +00:00
num_backends + + ;
2003-11-25 03:15:26 +00:00
return NT_STATUS_OK ;
2003-08-13 01:53:07 +00:00
}
/*
return the operations structure for a named backend of the specified type
*/
struct ntvfs_ops * ntvfs_backend_byname ( const char * name , enum ntvfs_type type )
{
int i ;
for ( i = 0 ; i < num_backends ; i + + ) {
2003-11-25 03:15:26 +00:00
if ( backends [ i ] . ops - > type = = type & &
strcmp ( backends [ i ] . ops - > name , name ) = = 0 ) {
2003-08-13 01:53:07 +00:00
return backends [ i ] . ops ;
}
}
return NULL ;
}
/*
return the NTVFS interface version , and the size of some critical types
This can be used by backends to either detect compilation errors , or provide
multiple implementations for different smbd compilation options in one module
*/
2003-12-02 09:16:53 +00:00
const struct ntvfs_critical_sizes * ntvfs_interface_version ( void )
2003-08-13 01:53:07 +00:00
{
2003-12-02 09:16:53 +00:00
static const struct ntvfs_critical_sizes critical_sizes = {
NTVFS_INTERFACE_VERSION ,
sizeof ( struct ntvfs_ops ) ,
sizeof ( SMB_OFF_T ) ,
sizeof ( struct tcon_context ) ,
sizeof ( struct request_context ) ,
} ;
return & critical_sizes ;
2003-08-13 01:53:07 +00:00
}
/*
initialise the NTVFS subsystem
*/
BOOL ntvfs_init ( void )
{
2003-11-25 03:15:26 +00:00
register_subsystem ( " ntvfs " , ntvfs_register ) ;
2003-08-13 01:53:07 +00:00
2003-11-25 03:15:26 +00:00
/* FIXME: Perhaps panic if a basic backend, such as IPC, fails to initialise? */
static_init_ntvfs ;
2003-08-13 01:53:07 +00:00
DEBUG ( 3 , ( " NTVFS version %d initialised \n " , NTVFS_INTERFACE_VERSION ) ) ;
return True ;
}
/*
initialise a connection structure to point at a NTVFS backend
*/
NTSTATUS ntvfs_init_connection ( struct request_context * req )
{
const char * handler = lp_ntvfs_handler ( req - > conn - > service ) ;
if ( strequal ( handler , " default " ) )
handler = " ipc " ;
req - > conn - > ntvfs_ops = ntvfs_backend_byname ( handler , req - > conn - > type ) ;
if ( ! req - > conn - > ntvfs_ops ) {
DEBUG ( 1 , ( " ntvfs_init_connection: failed to find backend=%s, type=%d \n " , handler , req - > conn - > type ) ) ;
return NT_STATUS_UNSUCCESSFUL ;
}
return NT_STATUS_OK ;
}