2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
simple NTVFS filesystem backend
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
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 01:53:07 +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/>.
2003-08-13 01:53:07 +00:00
*/
/*
utility functions for simple backend
*/
# include "includes.h"
2005-02-10 05:09:35 +00:00
# include "system/filesys.h"
2003-08-13 01:53:07 +00:00
# include "svfs.h"
2004-11-02 00:24:21 +00:00
# include "system/time.h"
# include "system/dir.h"
2005-12-27 22:51:30 +00:00
# include "ntvfs/ntvfs.h"
2003-08-13 01:53:07 +00:00
/*
convert a windows path to a unix path - don ' t do any manging or case sensitive handling
*/
2004-09-29 13:17:09 +00:00
char * svfs_unix_path ( struct ntvfs_module_context * ntvfs ,
2006-03-10 14:31:17 +00:00
struct ntvfs_request * req , const char * name )
2003-08-13 01:53:07 +00:00
{
2004-09-29 13:17:09 +00:00
struct svfs_private * private = ntvfs - > private_data ;
2003-08-13 01:53:07 +00:00
char * ret ;
if ( * name ! = ' \\ ' ) {
2004-09-08 05:39:06 +00:00
ret = talloc_asprintf ( req , " %s/%s " , private - > connectpath , name ) ;
2003-08-13 01:53:07 +00:00
} else {
2004-09-08 05:39:06 +00:00
ret = talloc_asprintf ( req , " %s%s " , private - > connectpath , name ) ;
2003-08-13 01:53:07 +00:00
}
all_string_sub ( ret , " \\ " , " / " , 0 ) ;
2004-08-24 23:58:00 +00:00
strlower ( ret + strlen ( private - > connectpath ) ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
read a directory and find all matching file names and stat info
returned names are separate unix and DOS names . The returned names
are relative to the directory
*/
2006-03-10 14:31:17 +00:00
struct svfs_dir * svfs_list_unix ( TALLOC_CTX * mem_ctx , struct ntvfs_request * req , const char * unix_path )
2003-08-13 01:53:07 +00:00
{
char * p , * mask ;
struct svfs_dir * dir ;
DIR * odir ;
struct dirent * dent ;
uint_t allocated = 0 ;
char * low_mask ;
2005-01-27 07:08:20 +00:00
dir = talloc ( mem_ctx , struct svfs_dir ) ;
2003-08-13 01:53:07 +00:00
if ( ! dir ) { return NULL ; }
dir - > count = 0 ;
dir - > files = 0 ;
/* find the base directory */
p = strrchr ( unix_path , ' / ' ) ;
if ( ! p ) { return NULL ; }
dir - > unix_dir = talloc_strndup ( mem_ctx , unix_path , PTR_DIFF ( p , unix_path ) ) ;
if ( ! dir - > unix_dir ) { return NULL ; }
/* the wildcard pattern is the last part */
mask = p + 1 ;
low_mask = talloc_strdup ( mem_ctx , mask ) ;
if ( ! low_mask ) { return NULL ; }
strlower ( low_mask ) ;
odir = opendir ( dir - > unix_dir ) ;
if ( ! odir ) { return NULL ; }
while ( ( dent = readdir ( odir ) ) ) {
uint_t i = dir - > count ;
char * full_name ;
char * low_name ;
2004-04-06 08:02:55 +00:00
if ( strchr ( dent - > d_name , ' : ' ) & & ! strchr ( unix_path , ' : ' ) ) {
/* don't show streams in dir listing */
continue ;
}
2003-08-13 01:53:07 +00:00
low_name = talloc_strdup ( mem_ctx , dent - > d_name ) ;
if ( ! low_name ) { continue ; }
strlower ( low_name ) ;
/* check it matches the wildcard pattern */
if ( ms_fnmatch ( low_mask , low_name , PROTOCOL_NT1 ) ! = 0 ) {
continue ;
}
if ( dir - > count > = allocated ) {
allocated = ( allocated + 100 ) * 1.2 ;
2005-01-27 07:08:20 +00:00
dir - > files = talloc_realloc ( dir , dir - > files , struct svfs_dirfile , allocated ) ;
2003-08-13 01:53:07 +00:00
if ( ! dir - > files ) {
closedir ( odir ) ;
return NULL ;
}
}
dir - > files [ i ] . name = low_name ;
if ( ! dir - > files [ i ] . name ) { continue ; }
asprintf ( & full_name , " %s/%s " , dir - > unix_dir , dir - > files [ i ] . name ) ;
if ( ! full_name ) { continue ; }
if ( stat ( full_name , & dir - > files [ i ] . st ) = = 0 ) {
dir - > count + + ;
}
free ( full_name ) ;
}
closedir ( odir ) ;
return dir ;
}
2004-04-06 08:02:55 +00:00
/*
read a directory and find all matching file names and stat info
returned names are separate unix and DOS names . The returned names
are relative to the directory
*/
2006-03-10 14:31:17 +00:00
struct svfs_dir * svfs_list ( struct ntvfs_module_context * ntvfs , struct ntvfs_request * req , const char * pattern )
2004-04-06 08:02:55 +00:00
{
2004-09-29 13:17:09 +00:00
struct svfs_private * private = ntvfs - > private_data ;
2004-04-06 08:02:55 +00:00
char * unix_path ;
2004-09-29 13:17:09 +00:00
unix_path = svfs_unix_path ( ntvfs , req , pattern ) ;
2004-04-06 08:02:55 +00:00
if ( ! unix_path ) { return NULL ; }
2004-09-29 13:17:09 +00:00
return svfs_list_unix ( private , req , unix_path ) ;
2004-04-06 08:02:55 +00:00
}
2003-08-13 01:53:07 +00:00
/*******************************************************************
set the time on a file via file descriptor
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int svfs_file_utime ( int fd , struct utimbuf * times )
{
char * fd_path = NULL ;
int ret ;
asprintf ( & fd_path , " /proc/self/%d " , fd ) ;
if ( ! fd_path ) {
errno = ENOMEM ;
return - 1 ;
}
ret = utime ( fd_path , times ) ;
free ( fd_path ) ;
return ret ;
}
/*
map a unix file attrib to a DOS attribute
*/
2004-05-25 17:24:24 +00:00
uint16_t svfs_unix_to_dos_attrib ( mode_t mode )
2003-08-13 01:53:07 +00:00
{
2004-05-25 17:24:24 +00:00
uint16_t ret = 0 ;
2003-08-13 01:53:07 +00:00
if ( S_ISDIR ( mode ) ) ret | = FILE_ATTRIBUTE_DIRECTORY ;
if ( ! ( mode & S_IWUSR ) ) ret | = FILE_ATTRIBUTE_READONLY ;
return ret ;
}
2003-09-02 04:37:33 +00:00