2004-09-18 08:16:14 +00:00
/*
Unix SMB / CIFS implementation .
POSIX NTVFS backend -
Copyright ( C ) Andrew Tridgell 2004
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-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2004-09-18 08:16:14 +00: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 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-09-18 08:16:14 +00:00
*/
2004-11-05 07:29:02 +00:00
# include "includes.h"
2004-09-18 08:16:14 +00:00
# include "vfs_posix.h"
2004-09-20 07:28:43 +00:00
/****************************************************************************
Change a unix mode to a dos mode .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static uint32_t dos_mode_from_stat ( struct pvfs_state * pvfs , struct stat * st )
2004-09-18 08:16:14 +00:00
{
2004-09-20 07:28:43 +00:00
int result = 0 ;
if ( ( st - > st_mode & S_IWUSR ) = = 0 )
result | = FILE_ATTRIBUTE_READONLY ;
2004-11-05 11:31:35 +00:00
if ( ( pvfs - > flags & PVFS_FLAG_MAP_ARCHIVE ) & & ( ( st - > st_mode & S_IXUSR ) ! = 0 ) )
result | = FILE_ATTRIBUTE_ARCHIVE ;
if ( ( pvfs - > flags & PVFS_FLAG_MAP_SYSTEM ) & & ( ( st - > st_mode & S_IXGRP ) ! = 0 ) )
result | = FILE_ATTRIBUTE_SYSTEM ;
if ( ( pvfs - > flags & PVFS_FLAG_MAP_HIDDEN ) & & ( ( st - > st_mode & S_IXOTH ) ! = 0 ) )
result | = FILE_ATTRIBUTE_HIDDEN ;
2004-09-20 07:28:43 +00:00
if ( S_ISDIR ( st - > st_mode ) )
result = FILE_ATTRIBUTE_DIRECTORY | ( result & FILE_ATTRIBUTE_READONLY ) ;
return result ;
}
2004-09-18 08:16:14 +00:00
2004-09-20 07:28:43 +00:00
/*
fill in the dos file attributes for a file
*/
2004-11-05 07:29:02 +00:00
NTSTATUS pvfs_fill_dos_info ( struct pvfs_state * pvfs , struct pvfs_filename * name , int fd )
2004-09-20 07:28:43 +00:00
{
2006-02-28 03:47:02 +00:00
/* make directories appear as size 0 with 1 link */
2004-10-25 07:03:15 +00:00
if ( S_ISDIR ( name - > st . st_mode ) ) {
name - > st . st_size = 0 ;
2006-02-28 03:47:02 +00:00
name - > st . st_nlink = 1 ;
2004-10-25 07:03:15 +00:00
}
2004-09-20 07:28:43 +00:00
/* for now just use the simple samba mapping */
unix_to_nt_time ( & name - > dos . create_time , name - > st . st_ctime ) ;
unix_to_nt_time ( & name - > dos . access_time , name - > st . st_atime ) ;
2004-10-26 07:11:49 +00:00
unix_to_nt_time ( & name - > dos . write_time , name - > st . st_mtime ) ;
unix_to_nt_time ( & name - > dos . change_time , name - > st . st_ctime ) ;
2004-09-24 00:44:42 +00:00
# ifdef HAVE_STAT_TV_NSEC
name - > dos . create_time + = name - > st . st_ctim . tv_nsec / 100 ;
name - > dos . access_time + = name - > st . st_atim . tv_nsec / 100 ;
name - > dos . write_time + = name - > st . st_mtim . tv_nsec / 100 ;
2004-10-26 07:11:49 +00:00
name - > dos . change_time + = name - > st . st_ctim . tv_nsec / 100 ;
2004-09-24 00:44:42 +00:00
# endif
2004-09-20 07:28:43 +00:00
name - > dos . attrib = dos_mode_from_stat ( pvfs , & name - > st ) ;
2004-11-17 07:17:55 +00:00
name - > dos . alloc_size = pvfs_round_alloc_size ( pvfs , name - > st . st_size ) ;
2004-09-20 07:28:43 +00:00
name - > dos . nlink = name - > st . st_nlink ;
2004-12-16 12:29:47 +00:00
name - > dos . ea_size = 4 ;
2004-09-20 07:28:43 +00:00
name - > dos . file_id = ( ( ( uint64_t ) name - > st . st_dev ) < < 32 ) | name - > st . st_ino ;
2004-11-24 06:09:14 +00:00
name - > dos . flags = 0 ;
2004-09-18 08:16:14 +00:00
2004-11-05 11:31:35 +00:00
return pvfs_dosattrib_load ( pvfs , name , fd ) ;
2004-09-18 08:16:14 +00:00
}
2004-10-25 05:27:49 +00:00
/*
return a set of unix file permissions for a new file or directory
*/
2005-01-31 16:06:21 +00:00
mode_t pvfs_fileperms ( struct pvfs_state * pvfs , uint32_t attrib )
2004-10-25 05:27:49 +00:00
{
2007-07-04 04:16:16 +00:00
mode_t mode = ( S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH ) ;
2004-10-25 05:27:49 +00:00
2007-07-04 04:16:16 +00:00
if ( ! ( pvfs - > flags & PVFS_FLAG_XATTR_ENABLE ) & &
( attrib & FILE_ATTRIBUTE_READONLY ) ) {
mode & = ~ ( S_IWUSR | S_IWGRP | S_IWOTH ) ;
2004-10-25 05:27:49 +00:00
}
2004-11-05 07:29:02 +00:00
if ( ! ( pvfs - > flags & PVFS_FLAG_XATTR_ENABLE ) ) {
if ( ( attrib & FILE_ATTRIBUTE_ARCHIVE ) & &
( pvfs - > flags & PVFS_FLAG_MAP_ARCHIVE ) ) {
mode | = S_IXUSR ;
}
if ( ( attrib & FILE_ATTRIBUTE_SYSTEM ) & &
( pvfs - > flags & PVFS_FLAG_MAP_SYSTEM ) ) {
mode | = S_IXGRP ;
}
if ( ( attrib & FILE_ATTRIBUTE_HIDDEN ) & &
( pvfs - > flags & PVFS_FLAG_MAP_HIDDEN ) ) {
mode | = S_IXOTH ;
}
2004-10-25 05:27:49 +00:00
}
2007-07-04 04:16:16 +00:00
if ( attrib & FILE_ATTRIBUTE_DIRECTORY ) {
mode | = ( S_IFDIR | S_IWUSR ) ;
mode | = ( S_IXUSR | S_IXGRP | S_IXOTH ) ;
mode & = pvfs - > options . dir_mask ;
mode | = pvfs - > options . force_dir_mode ;
} else {
mode & = pvfs - > options . create_mask ;
mode | = pvfs - > options . force_create_mode ;
}
2004-10-25 05:27:49 +00:00
return mode ;
}
2004-11-17 05:58:04 +00:00
2007-07-04 04:16:16 +00:00