2005-03-18 16:13:38 +03:00
/*
* Catia VFS module
*
* Implement a fixed mapping of forbidden NT characters in filenames that are
* used a lot by the CAD package Catia .
*
* Yes , this a BAD BAD UGLY INCOMPLETE hack , but it helps quite some people
* out there . Catia V4 on AIX uses characters like " <*$ a *lot*, all forbidden
* under Windows . . .
*
* Copyright ( C ) Volker Lendecke , 2005
*
* 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
2007-07-09 23:25:36 +04:00
* the Free Software Foundation ; either version 3 of the License , or
2005-03-18 16:13:38 +03:00
* ( 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
2007-07-10 09:23:25 +04:00
* along with this program ; if not , see < http : //www.gnu.org/licenses/>.
2005-03-18 16:13:38 +03:00
*/
# include "includes.h"
static void catia_string_replace ( char * s , unsigned char oldc , unsigned
char newc )
{
static smb_ucs2_t tmpbuf [ sizeof ( pstring ) ] ;
smb_ucs2_t * ptr = tmpbuf ;
smb_ucs2_t old = oldc ;
push_ucs2 ( NULL , tmpbuf , s , sizeof ( tmpbuf ) , STR_TERMINATE ) ;
for ( ; * ptr ; ptr + + )
if ( * ptr = = old ) * ptr = newc ;
2007-09-19 13:40:40 +04:00
pull_ucs2 ( NULL , s , tmpbuf , sizeof ( pstring ) , sizeof ( tmpbuf ) , STR_TERMINATE ) ;
2005-03-18 16:13:38 +03:00
}
static void from_unix ( char * s )
{
catia_string_replace ( s , ' \x22 ' , ' \xa8 ' ) ;
catia_string_replace ( s , ' \x2a ' , ' \xa4 ' ) ;
catia_string_replace ( s , ' \x2f ' , ' \xf8 ' ) ;
catia_string_replace ( s , ' \x3a ' , ' \xf7 ' ) ;
catia_string_replace ( s , ' \x3c ' , ' \xab ' ) ;
catia_string_replace ( s , ' \x3e ' , ' \xbb ' ) ;
catia_string_replace ( s , ' \x3f ' , ' \xbf ' ) ;
catia_string_replace ( s , ' \x5c ' , ' \xff ' ) ;
catia_string_replace ( s , ' \x7c ' , ' \xa6 ' ) ;
catia_string_replace ( s , ' ' , ' \xb1 ' ) ;
}
static void to_unix ( char * s )
{
catia_string_replace ( s , ' \xa8 ' , ' \x22 ' ) ;
catia_string_replace ( s , ' \xa4 ' , ' \x2a ' ) ;
catia_string_replace ( s , ' \xf8 ' , ' \x2f ' ) ;
catia_string_replace ( s , ' \xf7 ' , ' \x3a ' ) ;
catia_string_replace ( s , ' \xab ' , ' \x3c ' ) ;
catia_string_replace ( s , ' \xbb ' , ' \x3e ' ) ;
catia_string_replace ( s , ' \xbf ' , ' \x3f ' ) ;
catia_string_replace ( s , ' \xff ' , ' \x5c ' ) ;
catia_string_replace ( s , ' \xa6 ' , ' \x7c ' ) ;
catia_string_replace ( s , ' \xb1 ' , ' ' ) ;
}
2006-07-11 22:01:26 +04:00
static SMB_STRUCT_DIR * catia_opendir ( vfs_handle_struct * handle ,
const char * fname , const char * mask , uint32 attr )
2005-03-18 16:13:38 +03:00
{
pstring name ;
pstrcpy ( name , fname ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_OPENDIR ( handle , name , mask , attr ) ;
2005-03-18 16:13:38 +03:00
}
static SMB_STRUCT_DIRENT * catia_readdir ( vfs_handle_struct * handle ,
2006-07-11 22:01:26 +04:00
SMB_STRUCT_DIR * dirp )
2005-03-18 16:13:38 +03:00
{
2006-07-11 22:01:26 +04:00
SMB_STRUCT_DIRENT * result = SMB_VFS_NEXT_READDIR ( handle , dirp ) ;
2005-03-18 16:13:38 +03:00
if ( result = = NULL )
return result ;
from_unix ( result - > d_name ) ;
return result ;
}
2006-07-11 22:01:26 +04:00
static int catia_open ( vfs_handle_struct * handle ,
const char * fname , files_struct * fsp , int flags , mode_t mode )
2005-03-18 16:13:38 +03:00
{
pstring name ;
pstrcpy ( name , fname ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_OPEN ( handle , name , fsp , flags , mode ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_rename ( vfs_handle_struct * handle ,
2005-06-25 13:07:42 +04:00
const char * oldname , const char * newname )
2005-03-18 16:13:38 +03:00
{
pstring oname , nname ;
2005-06-25 13:07:42 +04:00
pstrcpy ( oname , oldname ) ;
2005-03-18 16:13:38 +03:00
to_unix ( oname ) ;
2005-06-25 13:07:42 +04:00
pstrcpy ( nname , newname ) ;
2005-03-18 16:13:38 +03:00
to_unix ( nname ) ;
DEBUG ( 10 , ( " converted old name: %s \n " , oname ) ) ;
DEBUG ( 10 , ( " converted new name: %s \n " , nname ) ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_RENAME ( handle , oname , nname ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_stat ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * fname , SMB_STRUCT_STAT * sbuf )
{
pstring name ;
pstrcpy ( name , fname ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_STAT ( handle , name , sbuf ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_lstat ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path , SMB_STRUCT_STAT * sbuf )
{
pstring name ;
pstrcpy ( name , path ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_LSTAT ( handle , name , sbuf ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_unlink ( vfs_handle_struct * handle , const char * path )
2005-03-18 16:13:38 +03:00
{
pstring name ;
pstrcpy ( name , path ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_UNLINK ( handle , name ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_chmod ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path , mode_t mode )
{
pstring name ;
pstrcpy ( name , path ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_CHMOD ( handle , name , mode ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_chown ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path , uid_t uid , gid_t gid )
{
pstring name ;
pstrcpy ( name , path ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_CHOWN ( handle , name , uid , gid ) ;
2005-03-18 16:13:38 +03:00
}
2007-05-24 03:55:12 +04:00
static int catia_lchown ( vfs_handle_struct * handle ,
const char * path , uid_t uid , gid_t gid )
{
pstring name ;
pstrcpy ( name , path ) ;
to_unix ( name ) ;
return SMB_VFS_NEXT_LCHOWN ( handle , name , uid , gid ) ;
}
2006-07-11 22:01:26 +04:00
static int catia_chdir ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path )
{
pstring name ;
pstrcpy ( name , path ) ;
to_unix ( name ) ;
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_CHDIR ( handle , name ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static char * catia_getwd ( vfs_handle_struct * handle , char * buf )
2005-03-18 16:13:38 +03:00
{
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_GETWD ( handle , buf ) ;
2005-03-18 16:13:38 +03:00
}
2007-03-06 02:40:03 +03:00
static int catia_ntimes ( vfs_handle_struct * handle ,
const char * path , const struct timespec ts [ 2 ] )
2005-03-18 16:13:38 +03:00
{
2007-03-06 02:40:03 +03:00
return SMB_VFS_NEXT_NTIMES ( handle , path , ts ) ;
2005-03-18 16:13:38 +03:00
}
2007-10-19 04:40:25 +04:00
static bool catia_symlink ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * oldpath , const char * newpath )
{
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_SYMLINK ( handle , oldpath , newpath ) ;
2005-03-18 16:13:38 +03:00
}
2007-10-19 04:40:25 +04:00
static bool catia_readlink ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path , char * buf , size_t bufsiz )
{
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_READLINK ( handle , path , buf , bufsiz ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_link ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * oldpath , const char * newpath )
{
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_LINK ( handle , oldpath , newpath ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static int catia_mknod ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path , mode_t mode , SMB_DEV_T dev )
{
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_MKNOD ( handle , path , mode , dev ) ;
2005-03-18 16:13:38 +03:00
}
2006-07-11 22:01:26 +04:00
static char * catia_realpath ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * path , char * resolved_path )
{
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_REALPATH ( handle , path , resolved_path ) ;
2005-03-18 16:13:38 +03:00
}
2007-10-13 23:06:49 +04:00
static NTSTATUS catia_get_nt_acl ( vfs_handle_struct * handle , files_struct * fsp ,
2005-03-18 16:13:38 +03:00
const char * name , uint32 security_info ,
2007-07-05 14:32:51 +04:00
struct security_descriptor * * ppdesc )
2005-03-18 16:13:38 +03:00
{
return SMB_VFS_NEXT_GET_NT_ACL ( handle , fsp , name , security_info ,
ppdesc ) ;
}
2007-06-27 02:49:10 +04:00
static NTSTATUS catia_set_nt_acl ( vfs_handle_struct * handle , files_struct * fsp ,
2005-03-18 16:13:38 +03:00
const char * name , uint32 security_info_sent ,
2007-07-05 14:32:51 +04:00
struct security_descriptor * psd )
2005-03-18 16:13:38 +03:00
{
return SMB_VFS_NEXT_SET_NT_ACL ( handle , fsp , name , security_info_sent ,
psd ) ;
}
2006-07-11 22:01:26 +04:00
static int catia_chmod_acl ( vfs_handle_struct * handle ,
2005-03-18 16:13:38 +03:00
const char * name , mode_t mode )
{
/* If the underlying VFS doesn't have ACL support... */
if ( ! handle - > vfs_next . ops . chmod_acl ) {
errno = ENOSYS ;
return - 1 ;
}
2006-07-11 22:01:26 +04:00
return SMB_VFS_NEXT_CHMOD_ACL ( handle , name , mode ) ;
2005-03-18 16:13:38 +03:00
}
/* VFS operations structure */
static vfs_op_tuple catia_op_tuples [ ] = {
/* Directory operations */
{ SMB_VFS_OP ( catia_opendir ) , SMB_VFS_OP_OPENDIR ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_readdir ) , SMB_VFS_OP_READDIR ,
SMB_VFS_LAYER_TRANSPARENT } ,
/* File operations */
{ SMB_VFS_OP ( catia_open ) , SMB_VFS_OP_OPEN ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_rename ) , SMB_VFS_OP_RENAME ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_stat ) , SMB_VFS_OP_STAT ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_lstat ) , SMB_VFS_OP_LSTAT ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_unlink ) , SMB_VFS_OP_UNLINK ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_chmod ) , SMB_VFS_OP_CHMOD ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_chown ) , SMB_VFS_OP_CHOWN ,
2007-05-24 03:55:12 +04:00
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_lchown ) , SMB_VFS_OP_LCHOWN ,
2005-03-18 16:13:38 +03:00
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_chdir ) , SMB_VFS_OP_CHDIR ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_getwd ) , SMB_VFS_OP_GETWD ,
SMB_VFS_LAYER_TRANSPARENT } ,
2007-03-06 02:40:03 +03:00
{ SMB_VFS_OP ( catia_ntimes ) , SMB_VFS_OP_NTIMES ,
2005-03-18 16:13:38 +03:00
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_symlink ) , SMB_VFS_OP_SYMLINK ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_readlink ) , SMB_VFS_OP_READLINK ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_link ) , SMB_VFS_OP_LINK ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_mknod ) , SMB_VFS_OP_MKNOD ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_realpath ) , SMB_VFS_OP_REALPATH ,
SMB_VFS_LAYER_TRANSPARENT } ,
/* NT File ACL operations */
{ SMB_VFS_OP ( catia_get_nt_acl ) , SMB_VFS_OP_GET_NT_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ SMB_VFS_OP ( catia_set_nt_acl ) , SMB_VFS_OP_SET_NT_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
/* POSIX ACL operations */
{ SMB_VFS_OP ( catia_chmod_acl ) , SMB_VFS_OP_CHMOD_ACL ,
SMB_VFS_LAYER_TRANSPARENT } ,
{ NULL , SMB_VFS_OP_NOOP ,
SMB_VFS_LAYER_NOOP }
} ;
2006-12-19 23:16:52 +03:00
NTSTATUS vfs_catia_init ( void ) ;
2006-07-11 22:01:26 +04:00
NTSTATUS vfs_catia_init ( void )
2005-03-18 16:13:38 +03:00
{
return smb_register_vfs ( SMB_VFS_INTERFACE_VERSION , " catia " ,
catia_op_tuples ) ;
}