1998-10-02 16:37:31 +04:00
/*
Unix SMB / Netbios implementation .
Version 2.0
SMB wrapper functions
Copyright ( C ) Andrew Tridgell 1998
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 .
*/
# include "includes.h"
1998-10-07 11:55:14 +04:00
# include "realcalls.h"
1998-10-02 16:37:31 +04:00
1998-10-06 14:24:22 +04:00
pstring smbw_cwd ;
1998-10-02 16:37:31 +04:00
static struct smbw_file * smbw_files ;
static struct smbw_server * smbw_srvs ;
1998-10-04 07:28:43 +04:00
struct bitmap * smbw_file_bmap ;
extern pstring global_myname ;
1998-10-02 16:37:31 +04:00
extern int DEBUGLEVEL ;
1998-10-06 14:24:22 +04:00
fstring smbw_prefix = SMBW_PREFIX ;
1998-10-04 07:28:43 +04:00
int smbw_busy = 0 ;
1998-10-03 12:34:35 +04:00
1998-10-07 13:57:22 +04:00
/* needs to be here because of dumb include files on some systems */
int creat_bits = O_WRONLY | O_CREAT | O_TRUNC ;
1998-10-02 16:37:31 +04:00
/*****************************************************
initialise structures
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void smbw_init ( void )
{
extern BOOL in_client ;
static int initialised ;
static pstring servicesf = CONFIGFILE ;
extern FILE * dbf ;
char * p ;
if ( initialised ) return ;
initialised = 1 ;
1998-10-03 12:34:35 +04:00
smbw_busy + + ;
1998-10-02 16:37:31 +04:00
DEBUGLEVEL = 0 ;
setup_logging ( " smbw " , True ) ;
dbf = stderr ;
1998-10-03 12:34:35 +04:00
if ( ( p = getenv ( " SMBW_LOGFILE " ) ) ) {
dbf = fopen ( p , " a " ) ;
}
1998-10-04 07:28:43 +04:00
smbw_file_bmap = bitmap_allocate ( SMBW_MAX_OPEN ) ;
if ( ! smbw_file_bmap ) {
1998-10-02 16:37:31 +04:00
exit ( 1 ) ;
}
charset_initialise ( ) ;
in_client = True ;
1998-10-04 05:10:18 +04:00
load_interfaces ( ) ;
1998-10-05 06:55:53 +04:00
lp_load ( servicesf , True , False , False ) ;
1998-10-02 16:37:31 +04:00
1998-10-04 07:28:43 +04:00
get_myname ( global_myname , NULL ) ;
1998-10-02 16:37:31 +04:00
if ( ( p = getenv ( " SMBW_DEBUG " ) ) ) {
DEBUGLEVEL = atoi ( p ) ;
}
1998-10-06 14:24:22 +04:00
if ( ( p = getenv ( " SMBW_PREFIX " ) ) ) {
slprintf ( smbw_prefix , sizeof ( fstring ) - 1 , " /%s/ " , p ) ;
string_sub ( smbw_prefix , " // " , " / " ) ;
DEBUG ( 2 , ( " SMBW_PREFIX is %s \n " , smbw_prefix ) ) ;
}
1998-10-03 12:34:35 +04:00
if ( ( p = getenv ( SMBW_PWD_ENV ) ) ) {
1998-10-06 14:24:22 +04:00
pstrcpy ( smbw_cwd , p ) ;
DEBUG ( 4 , ( " Initial cwd from smbw_cwd is %s \n " , smbw_cwd ) ) ;
1998-10-02 16:37:31 +04:00
} else {
1998-10-06 14:24:22 +04:00
sys_getwd ( smbw_cwd ) ;
DEBUG ( 4 , ( " Initial cwd from getwd is %s \n " , smbw_cwd ) ) ;
1998-10-02 16:37:31 +04:00
}
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-05 05:57:03 +04:00
set_maxfiles ( ) ;
1998-10-02 16:37:31 +04:00
}
/*****************************************************
determine if a file descriptor is a smb one
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-04 05:36:40 +04:00
int smbw_fd ( int fd )
1998-10-02 16:37:31 +04:00
{
1998-10-04 05:36:40 +04:00
if ( smbw_busy ) return 0 ;
1998-10-04 08:48:17 +04:00
return smbw_file_bmap & & bitmap_query ( smbw_file_bmap , fd ) ;
1998-10-02 16:37:31 +04:00
}
1998-10-03 17:12:08 +04:00
/*****************************************************
a crude inode number generator
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ino_t smbw_inode ( const char * name )
{
return ( ino_t ) str_checksum ( name ) ;
}
1998-10-02 16:37:31 +04:00
/*****************************************************
remove redundent stuff from a filename
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void clean_fname ( char * name )
{
char * p , * p2 ;
int l ;
int modified = 1 ;
if ( ! name ) return ;
while ( modified ) {
modified = 0 ;
1998-10-03 12:34:35 +04:00
DEBUG ( 5 , ( " cleaning %s \n " , name ) ) ;
1998-10-02 16:37:31 +04:00
if ( ( p = strstr ( name , " /./ " ) ) ) {
modified = 1 ;
while ( * p ) {
p [ 0 ] = p [ 2 ] ;
p + + ;
}
}
if ( ( p = strstr ( name , " // " ) ) ) {
modified = 1 ;
while ( * p ) {
p [ 0 ] = p [ 1 ] ;
p + + ;
}
}
if ( strcmp ( name , " /../ " ) = = 0 ) {
modified = 1 ;
name [ 1 ] = 0 ;
}
if ( ( p = strstr ( name , " /../ " ) ) ) {
modified = 1 ;
for ( p2 = ( p > name ? p - 1 : p ) ; p2 > name ; p2 - - ) {
if ( p2 [ 0 ] = = ' / ' ) break ;
}
while ( * p2 ) {
p2 [ 0 ] = p2 [ 3 ] ;
p2 + + ;
}
}
if ( strcmp ( name , " /.. " ) = = 0 ) {
modified = 1 ;
name [ 1 ] = 0 ;
}
l = strlen ( name ) ;
p = l > = 3 ? ( name + l - 3 ) : name ;
if ( strcmp ( p , " /.. " ) = = 0 ) {
modified = 1 ;
for ( p2 = p - 1 ; p2 > name ; p2 - - ) {
if ( p2 [ 0 ] = = ' / ' ) break ;
}
if ( p2 = = name ) {
p [ 0 ] = ' / ' ;
p [ 1 ] = 0 ;
} else {
p2 [ 0 ] = 0 ;
}
}
l = strlen ( name ) ;
p = l > = 2 ? ( name + l - 2 ) : name ;
if ( strcmp ( p , " /. " ) = = 0 ) {
if ( p = = name ) {
p [ 1 ] = 0 ;
} else {
p [ 0 ] = 0 ;
}
}
if ( strncmp ( p = name , " ./ " , 2 ) = = 0 ) {
modified = 1 ;
do {
p [ 0 ] = p [ 2 ] ;
} while ( * p + + ) ;
}
l = strlen ( p = name ) ;
if ( l > 1 & & p [ l - 1 ] = = ' / ' ) {
modified = 1 ;
p [ l - 1 ] = 0 ;
}
}
}
/*****************************************************
parse a smb path into its components .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-03 13:39:11 +04:00
char * smbw_parse_path ( const char * fname , char * server , char * share , char * path )
1998-10-02 16:37:31 +04:00
{
1998-10-03 13:39:11 +04:00
static pstring s ;
1998-10-02 16:37:31 +04:00
char * p , * p2 ;
1998-10-06 14:24:22 +04:00
int len = strlen ( smbw_prefix ) - 1 ;
1998-10-02 16:37:31 +04:00
1998-10-03 14:24:49 +04:00
* server = * share = * path = 0 ;
1998-10-02 16:37:31 +04:00
if ( fname [ 0 ] = = ' / ' ) {
pstrcpy ( s , fname ) ;
} else {
1998-10-06 14:24:22 +04:00
slprintf ( s , sizeof ( s ) - 1 , " %s/%s " , smbw_cwd , fname ) ;
1998-10-02 16:37:31 +04:00
}
clean_fname ( s ) ;
1998-10-03 12:34:35 +04:00
DEBUG ( 5 , ( " cleaned %s (fname=%s cwd=%s) \n " ,
1998-10-06 14:24:22 +04:00
s , fname , smbw_cwd ) ) ;
1998-10-02 16:37:31 +04:00
1998-10-06 14:24:22 +04:00
if ( strncmp ( s , smbw_prefix , len ) | |
1998-10-04 15:25:06 +04:00
( s [ len ] ! = ' / ' & & s [ len ] ! = 0 ) ) return s ;
p = s + len ;
if ( * p = = ' / ' ) p + + ;
1998-10-02 16:37:31 +04:00
p2 = strchr ( p , ' / ' ) ;
if ( p2 ) {
len = ( int ) ( p2 - p ) ;
} else {
len = strlen ( p ) ;
}
1998-10-03 13:39:11 +04:00
len = MIN ( len , sizeof ( fstring ) - 1 ) ;
strncpy ( server , p , len ) ;
server [ len ] = 0 ;
1998-10-02 16:37:31 +04:00
p = p2 ;
if ( ! p ) {
1998-10-04 15:25:06 +04:00
if ( len = = 0 ) {
char * workgroup = getenv ( " SMBW_WORKGROUP " ) ;
if ( ! workgroup ) workgroup = lp_workgroup ( ) ;
slprintf ( server , sizeof ( fstring ) - 1 , " %s#1D " , workgroup ) ;
}
1998-10-03 13:39:11 +04:00
fstrcpy ( share , " IPC$ " ) ;
pstrcpy ( path , " " ) ;
1998-10-02 16:37:31 +04:00
goto ok ;
}
p + + ;
p2 = strchr ( p , ' / ' ) ;
if ( p2 ) {
len = ( int ) ( p2 - p ) ;
} else {
len = strlen ( p ) ;
}
1998-10-03 13:39:11 +04:00
len = MIN ( len , sizeof ( fstring ) - 1 ) ;
1998-10-02 16:37:31 +04:00
1998-10-03 13:39:11 +04:00
strncpy ( share , p , len ) ;
share [ len ] = 0 ;
1998-10-02 16:37:31 +04:00
p = p2 ;
if ( ! p ) {
1998-10-03 13:39:11 +04:00
pstrcpy ( path , " \\ " ) ;
1998-10-02 16:37:31 +04:00
goto ok ;
}
1998-10-03 13:39:11 +04:00
pstrcpy ( path , p ) ;
1998-10-02 16:37:31 +04:00
1998-10-03 13:39:11 +04:00
string_sub ( path , " / " , " \\ " ) ;
1998-10-02 16:37:31 +04:00
ok :
1998-10-03 12:34:35 +04:00
DEBUG ( 5 , ( " parsed path name=%s cwd=%s [%s] [%s] [%s] \n " ,
1998-10-06 14:24:22 +04:00
fname , smbw_cwd ,
1998-10-03 13:39:11 +04:00
server , share , path ) ) ;
1998-10-02 16:37:31 +04:00
return s ;
}
/*****************************************************
determine if a path name ( possibly relative ) is in the
smb name space
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-04 05:36:40 +04:00
int smbw_path ( const char * path )
1998-10-02 16:37:31 +04:00
{
1998-10-03 13:39:11 +04:00
fstring server , share ;
pstring s ;
1998-10-02 16:37:31 +04:00
char * cwd ;
1998-10-06 14:24:22 +04:00
int len ;
smbw_init ( ) ;
len = strlen ( smbw_prefix ) - 1 ;
1998-10-03 14:24:49 +04:00
1998-10-06 14:24:22 +04:00
if ( path [ 0 ] = = ' / ' & & strncmp ( path , smbw_prefix , len ) ) {
1998-10-04 05:36:40 +04:00
return 0 ;
1998-10-03 14:24:49 +04:00
}
1998-10-03 12:34:35 +04:00
1998-10-04 05:36:40 +04:00
if ( smbw_busy ) return 0 ;
1998-10-03 12:34:35 +04:00
DEBUG ( 3 , ( " smbw_path(%s) \n " , path ) ) ;
1998-10-03 13:39:11 +04:00
cwd = smbw_parse_path ( path , server , share , s ) ;
1998-10-03 12:34:35 +04:00
1998-10-06 14:24:22 +04:00
if ( strncmp ( cwd , smbw_prefix , len ) = = 0 & &
( cwd [ len ] = = ' / ' | | cwd [ len ] = = 0 ) ) {
1998-10-04 05:36:40 +04:00
return 1 ;
1998-10-03 12:34:35 +04:00
}
1998-10-04 05:36:40 +04:00
return 0 ;
1998-10-02 16:37:31 +04:00
}
/*****************************************************
return a unix errno from a SMB error pair
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-03 12:34:35 +04:00
int smbw_errno ( struct cli_state * c )
1998-10-02 16:37:31 +04:00
{
1998-10-03 13:39:11 +04:00
uint8 eclass ;
uint32 ecode ;
int ret ;
ret = cli_error ( c , & eclass , & ecode ) ;
if ( ret ) {
1998-10-04 10:44:20 +04:00
DEBUG ( 3 , ( " smbw_error %d %d (0x%x) -> %d \n " ,
( int ) eclass , ( int ) ecode , ( int ) ecode , ret ) ) ;
1998-10-03 13:39:11 +04:00
}
return ret ;
1998-10-02 16:37:31 +04:00
}
/*****************************************************
return a connection to a server ( existing or new )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct smbw_server * smbw_server ( char * server , char * share )
{
struct smbw_server * srv = NULL ;
1998-10-04 07:28:43 +04:00
struct cli_state c ;
1998-10-02 16:37:31 +04:00
char * username ;
char * password ;
char * workgroup ;
struct nmb_name called , calling ;
1998-10-04 15:25:06 +04:00
char * p , * server_n = server ;
fstring group ;
1998-10-02 16:37:31 +04:00
1998-10-04 07:28:43 +04:00
ZERO_STRUCT ( c ) ;
1998-10-02 16:37:31 +04:00
username = getenv ( " SMBW_USER " ) ;
if ( ! username ) username = getenv ( " USER " ) ;
if ( ! username ) username = " guest " ;
workgroup = getenv ( " SMBW_WORKGROUP " ) ;
if ( ! workgroup ) workgroup = lp_workgroup ( ) ;
password = getenv ( " SMBW_PASSWORD " ) ;
if ( ! password ) password = " " ;
/* try to use an existing connection */
for ( srv = smbw_srvs ; srv ; srv = srv - > next ) {
if ( strcmp ( server , srv - > server_name ) = = 0 & &
strcmp ( share , srv - > share_name ) = = 0 ) return srv ;
}
1998-10-03 12:34:35 +04:00
if ( server [ 0 ] = = 0 ) {
errno = EPERM ;
return NULL ;
}
1998-10-04 14:46:52 +04:00
make_nmb_name ( & calling , global_myname , 0x0 , " " ) ;
make_nmb_name ( & called , server , 0x20 , " " ) ;
1998-10-04 16:00:40 +04:00
DEBUG ( 5 , ( " server_n=[%s] server=[%s] \n " , server_n , server ) ) ;
if ( ( p = strchr ( server_n , ' # ' ) ) & & strcmp ( p + 1 , " 1D " ) = = 0 ) {
1998-10-04 15:25:06 +04:00
struct in_addr ip ;
fstrcpy ( group , server_n ) ;
p = strchr ( group , ' # ' ) ;
* p = 0 ;
if ( ! find_master ( group , & ip ) ) {
errno = ENOENT ;
return NULL ;
}
fstrcpy ( group , inet_ntoa ( ip ) ) ;
server_n = group ;
}
1998-10-04 16:00:40 +04:00
DEBUG ( 5 , ( " -> server_n=[%s] server=[%s] \n " , server_n , server ) ) ;
again :
1998-10-02 16:37:31 +04:00
/* have to open a new connection */
1998-10-04 15:25:06 +04:00
if ( ! cli_initialise ( & c ) | | ! cli_connect ( & c , server_n , NULL ) ) {
1998-10-02 16:37:31 +04:00
errno = ENOENT ;
return NULL ;
}
if ( ! cli_session_request ( & c , & calling , & called ) ) {
cli_shutdown ( & c ) ;
1998-10-04 14:46:52 +04:00
if ( strcmp ( called . name , " *SMBSERVER " ) ) {
make_nmb_name ( & called , " *SMBSERVER " , 0x20 , " " ) ;
goto again ;
}
1998-10-02 16:37:31 +04:00
errno = ENOENT ;
return NULL ;
}
1998-10-04 14:46:52 +04:00
1998-10-02 16:37:31 +04:00
if ( ! cli_negprot ( & c ) ) {
cli_shutdown ( & c ) ;
errno = ENOENT ;
return NULL ;
}
if ( ! cli_session_setup ( & c , username ,
password , strlen ( password ) ,
password , strlen ( password ) ,
1998-10-07 04:40:18 +04:00
workgroup ) & &
/* try an anonymous login if it failed */
! cli_session_setup ( & c , " " , " " , 1 , " " , 0 , workgroup ) ) {
1998-10-02 16:37:31 +04:00
cli_shutdown ( & c ) ;
errno = EPERM ;
return NULL ;
}
1998-10-04 13:42:51 +04:00
if ( ! cli_send_tconX ( & c , share , " ????? " ,
1998-10-02 16:37:31 +04:00
password , strlen ( password ) + 1 ) ) {
1998-10-03 12:34:35 +04:00
errno = smbw_errno ( & c ) ;
1998-10-02 16:37:31 +04:00
cli_shutdown ( & c ) ;
return NULL ;
}
srv = ( struct smbw_server * ) malloc ( sizeof ( * srv ) ) ;
if ( ! srv ) {
errno = ENOMEM ;
goto failed ;
}
ZERO_STRUCTP ( srv ) ;
srv - > cli = c ;
1998-10-03 17:12:08 +04:00
srv - > dev = ( dev_t ) ( str_checksum ( server ) ^ str_checksum ( share ) ) ;
1998-10-02 16:37:31 +04:00
srv - > server_name = strdup ( server ) ;
if ( ! srv - > server_name ) {
errno = ENOMEM ;
goto failed ;
}
srv - > share_name = strdup ( share ) ;
if ( ! srv - > share_name ) {
errno = ENOMEM ;
goto failed ;
}
1998-10-03 14:24:49 +04:00
/* some programs play with file descriptors fairly intimately. We
try to get out of the way by duping to a high fd number */
1998-10-03 15:54:20 +04:00
if ( fcntl ( SMBW_CLI_FD + srv - > cli . fd , F_GETFD ) & & errno = = EBADF ) {
if ( dup2 ( srv - > cli . fd , SMBW_CLI_FD + srv - > cli . fd ) = =
srv - > cli . fd + SMBW_CLI_FD ) {
1998-10-03 14:24:49 +04:00
close ( srv - > cli . fd ) ;
1998-10-03 15:54:20 +04:00
srv - > cli . fd + = SMBW_CLI_FD ;
1998-10-03 14:24:49 +04:00
}
}
1998-10-02 16:37:31 +04:00
DLIST_ADD ( smbw_srvs , srv ) ;
return srv ;
failed :
cli_shutdown ( & c ) ;
if ( ! srv ) return NULL ;
if ( srv - > server_name ) free ( srv - > server_name ) ;
if ( srv - > share_name ) free ( srv - > share_name ) ;
free ( srv ) ;
return NULL ;
}
/*****************************************************
map a fd to a smbw_file structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct smbw_file * smbw_file ( int fd )
{
struct smbw_file * file ;
for ( file = smbw_files ; file ; file = file - > next ) {
if ( file - > fd = = fd ) return file ;
}
return NULL ;
}
/*****************************************************
a wrapper for open ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-03 13:39:11 +04:00
int smbw_open ( const char * fname , int flags , mode_t mode )
1998-10-02 16:37:31 +04:00
{
1998-10-03 13:39:11 +04:00
fstring server , share ;
pstring path ;
1998-10-02 16:37:31 +04:00
struct smbw_server * srv = NULL ;
1998-10-05 16:17:01 +04:00
int eno = 0 , fd = - 1 ;
1998-10-02 16:37:31 +04:00
struct smbw_file * file = NULL ;
1998-10-03 12:34:35 +04:00
smbw_init ( ) ;
1998-10-02 16:37:31 +04:00
if ( ! fname ) {
errno = EINVAL ;
return - 1 ;
}
1998-10-03 12:34:35 +04:00
smbw_busy + + ;
1998-10-02 16:37:31 +04:00
/* work out what server they are after */
1998-10-03 13:39:11 +04:00
smbw_parse_path ( fname , server , share , path ) ;
1998-10-02 16:37:31 +04:00
/* get a connection to the server */
srv = smbw_server ( server , share ) ;
if ( ! srv ) {
/* smbw_server sets errno */
goto failed ;
}
1998-10-03 12:34:35 +04:00
if ( path [ strlen ( path ) - 1 ] = = ' \\ ' ) {
fd = - 1 ;
} else {
fd = cli_open ( & srv - > cli , path , flags , DENY_NONE ) ;
}
1998-10-02 16:37:31 +04:00
if ( fd = = - 1 ) {
/* it might be a directory. Maybe we should use chkpath? */
1998-10-06 07:12:40 +04:00
eno = smbw_errno ( & srv - > cli ) ;
1998-10-03 20:34:57 +04:00
fd = smbw_dir_open ( fname ) ;
1998-10-05 17:51:19 +04:00
if ( fd = = - 1 ) errno = eno ;
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
return fd ;
1998-10-02 16:37:31 +04:00
}
file = ( struct smbw_file * ) malloc ( sizeof ( * file ) ) ;
if ( ! file ) {
errno = ENOMEM ;
goto failed ;
}
ZERO_STRUCTP ( file ) ;
1998-10-04 11:52:00 +04:00
file - > f = ( struct smbw_filedes * ) malloc ( sizeof ( * ( file - > f ) ) ) ;
if ( ! file - > f ) {
errno = ENOMEM ;
goto failed ;
}
ZERO_STRUCTP ( file - > f ) ;
file - > f - > cli_fd = fd ;
file - > f - > fname = strdup ( path ) ;
if ( ! file - > f - > fname ) {
1998-10-02 16:37:31 +04:00
errno = ENOMEM ;
goto failed ;
}
file - > srv = srv ;
1998-10-04 10:22:08 +04:00
file - > fd = open ( SMBW_DUMMY , O_WRONLY ) ;
1998-10-02 16:37:31 +04:00
if ( file - > fd = = - 1 ) {
errno = EMFILE ;
goto failed ;
}
1998-10-04 08:48:17 +04:00
if ( bitmap_query ( smbw_file_bmap , file - > fd ) ) {
DEBUG ( 0 , ( " ERROR: fd used in smbw_open \n " ) ) ;
errno = EIO ;
goto failed ;
}
1998-10-02 16:37:31 +04:00
1998-10-04 11:52:00 +04:00
file - > f - > ref_count = 1 ;
1998-10-04 08:48:17 +04:00
bitmap_set ( smbw_file_bmap , file - > fd ) ;
1998-10-02 16:37:31 +04:00
DLIST_ADD ( smbw_files , file ) ;
1998-10-03 13:39:11 +04:00
DEBUG ( 4 , ( " opened %s \n " , fname ) ) ;
1998-10-02 16:37:31 +04:00
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return file - > fd ;
failed :
if ( fd ! = - 1 ) {
cli_close ( & srv - > cli , fd ) ;
}
if ( file ) {
1998-10-04 11:52:00 +04:00
if ( file - > f ) {
if ( file - > f - > fname ) {
free ( file - > f - > fname ) ;
}
free ( file - > f ) ;
1998-10-02 16:37:31 +04:00
}
free ( file ) ;
}
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return - 1 ;
}
1998-10-05 06:31:39 +04:00
/*****************************************************
a wrapper for pread ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ssize_t smbw_pread ( int fd , void * buf , size_t count , off_t ofs )
{
struct smbw_file * file ;
int ret ;
smbw_busy + + ;
file = smbw_file ( fd ) ;
if ( ! file ) {
errno = EBADF ;
smbw_busy - - ;
return - 1 ;
}
ret = cli_read ( & file - > srv - > cli , file - > f - > cli_fd , buf , ofs , count ) ;
if ( ret = = - 1 ) {
errno = smbw_errno ( & file - > srv - > cli ) ;
smbw_busy - - ;
return - 1 ;
}
smbw_busy - - ;
return ret ;
}
1998-10-02 16:37:31 +04:00
/*****************************************************
a wrapper for read ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ssize_t smbw_read ( int fd , void * buf , size_t count )
{
struct smbw_file * file ;
int ret ;
1998-10-06 17:10:06 +04:00
DEBUG ( 4 , ( " smbw_read(%d, %d) \n " , fd , ( int ) count ) ) ;
1998-10-03 12:34:35 +04:00
smbw_busy + + ;
1998-10-02 16:37:31 +04:00
file = smbw_file ( fd ) ;
if ( ! file ) {
errno = EBADF ;
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return - 1 ;
}
1998-10-05 06:31:39 +04:00
ret = cli_read ( & file - > srv - > cli , file - > f - > cli_fd , buf ,
file - > f - > offset , count ) ;
1998-10-02 16:37:31 +04:00
if ( ret = = - 1 ) {
1998-10-03 12:34:35 +04:00
errno = smbw_errno ( & file - > srv - > cli ) ;
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return - 1 ;
}
1998-10-04 11:52:00 +04:00
file - > f - > offset + = ret ;
1998-10-06 17:10:06 +04:00
DEBUG ( 4 , ( " -> %d \n " , ret ) ) ;
1998-10-02 16:37:31 +04:00
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return ret ;
}
1998-10-05 06:31:39 +04:00
1998-10-02 16:37:31 +04:00
/*****************************************************
a wrapper for write ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ssize_t smbw_write ( int fd , void * buf , size_t count )
{
struct smbw_file * file ;
int ret ;
1998-10-03 12:34:35 +04:00
smbw_busy + + ;
1998-10-02 16:37:31 +04:00
file = smbw_file ( fd ) ;
if ( ! file ) {
DEBUG ( 3 , ( " bad fd in read \n " ) ) ;
errno = EBADF ;
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return - 1 ;
}
1998-10-04 11:52:00 +04:00
ret = cli_write ( & file - > srv - > cli , file - > f - > cli_fd , buf , file - > f - > offset , count ) ;
1998-10-02 16:37:31 +04:00
if ( ret = = - 1 ) {
1998-10-03 12:34:35 +04:00
errno = smbw_errno ( & file - > srv - > cli ) ;
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return - 1 ;
}
1998-10-04 11:52:00 +04:00
file - > f - > offset + = ret ;
1998-10-02 16:37:31 +04:00
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return ret ;
}
1998-10-05 06:31:39 +04:00
/*****************************************************
a wrapper for pwrite ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ssize_t smbw_pwrite ( int fd , void * buf , size_t count , off_t ofs )
{
struct smbw_file * file ;
int ret ;
smbw_busy + + ;
file = smbw_file ( fd ) ;
if ( ! file ) {
DEBUG ( 3 , ( " bad fd in read \n " ) ) ;
errno = EBADF ;
smbw_busy - - ;
return - 1 ;
}
ret = cli_write ( & file - > srv - > cli , file - > f - > cli_fd , buf , ofs , count ) ;
if ( ret = = - 1 ) {
errno = smbw_errno ( & file - > srv - > cli ) ;
smbw_busy - - ;
return - 1 ;
}
smbw_busy - - ;
return ret ;
}
1998-10-02 16:37:31 +04:00
/*****************************************************
a wrapper for close ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_close ( int fd )
{
struct smbw_file * file ;
1998-10-03 12:34:35 +04:00
smbw_busy + + ;
1998-10-02 16:37:31 +04:00
file = smbw_file ( fd ) ;
if ( ! file ) {
1998-10-03 12:34:35 +04:00
int ret = smbw_dir_close ( fd ) ;
smbw_busy - - ;
return ret ;
1998-10-02 16:37:31 +04:00
}
1998-10-04 11:52:00 +04:00
if ( file - > f - > ref_count = = 1 & &
! cli_close ( & file - > srv - > cli , file - > f - > cli_fd ) ) {
1998-10-03 12:34:35 +04:00
errno = smbw_errno ( & file - > srv - > cli ) ;
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return - 1 ;
}
1998-10-04 08:48:17 +04:00
bitmap_clear ( smbw_file_bmap , file - > fd ) ;
close ( file - > fd ) ;
1998-10-02 16:37:31 +04:00
DLIST_REMOVE ( smbw_files , file ) ;
1998-10-04 11:52:00 +04:00
file - > f - > ref_count - - ;
if ( file - > f - > ref_count = = 0 ) {
free ( file - > f - > fname ) ;
free ( file - > f ) ;
}
1998-10-02 16:37:31 +04:00
ZERO_STRUCTP ( file ) ;
free ( file ) ;
1998-10-03 12:34:35 +04:00
smbw_busy - - ;
1998-10-02 16:37:31 +04:00
return 0 ;
}
/*****************************************************
a wrapper for fcntl ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_fcntl ( int fd , int cmd , long arg )
{
return 0 ;
}
/*****************************************************
a wrapper for access ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-03 13:39:11 +04:00
int smbw_access ( const char * name , int mode )
1998-10-02 16:37:31 +04:00
{
struct stat st ;
1998-10-06 17:10:06 +04:00
DEBUG ( 4 , ( " smbw_access(%s, 0x%x) \n " , name , mode ) ) ;
if ( smbw_stat ( name , & st ) ) return - 1 ;
if ( ( ( mode & R_OK ) & & ! ( st . st_mode & S_IRUSR ) ) | |
( ( mode & W_OK ) & & ! ( st . st_mode & S_IWUSR ) ) | |
( ( mode & X_OK ) & & ! ( st . st_mode & S_IXUSR ) ) ) {
errno = EACCES ;
return - 1 ;
}
return 0 ;
1998-10-02 16:37:31 +04:00
}
1998-10-03 12:34:35 +04:00
/*****************************************************
a wrapper for realink ( ) - needed for correct errno setting
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-03 13:39:11 +04:00
int smbw_readlink ( const char * path , char * buf , size_t bufsize )
1998-10-03 12:34:35 +04:00
{
struct stat st ;
int ret ;
ret = smbw_stat ( path , & st ) ;
if ( ret ! = 0 ) {
DEBUG ( 4 , ( " readlink(%s) failed \n " , path ) ) ;
return - 1 ;
}
/* it exists - say it isn't a link */
DEBUG ( 4 , ( " readlink(%s) not a link \n " , path ) ) ;
errno = EINVAL ;
return - 1 ;
}
1998-10-02 16:37:31 +04:00
1998-10-03 13:39:11 +04:00
/*****************************************************
a wrapper for unlink ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_unlink ( const char * fname )
{
struct smbw_server * srv ;
fstring server , share ;
pstring path ;
if ( ! fname ) {
errno = EINVAL ;
return - 1 ;
}
smbw_init ( ) ;
smbw_busy + + ;
/* work out what server they are after */
smbw_parse_path ( fname , server , share , path ) ;
/* get a connection to the server */
srv = smbw_server ( server , share ) ;
if ( ! srv ) {
/* smbw_server sets errno */
goto failed ;
}
1998-10-04 14:14:21 +04:00
if ( strncmp ( srv - > cli . dev , " LPT " , 3 ) = = 0 ) {
int job = smbw_stat_printjob ( srv , path , NULL , NULL ) ;
if ( job = = - 1 ) {
goto failed ;
}
if ( cli_printjob_del ( & srv - > cli , job ) ! = 0 ) {
goto failed ;
}
} else if ( ! cli_unlink ( & srv - > cli , path ) ) {
1998-10-03 13:39:11 +04:00
errno = smbw_errno ( & srv - > cli ) ;
goto failed ;
}
smbw_busy - - ;
return 0 ;
failed :
smbw_busy - - ;
return - 1 ;
}
/*****************************************************
a wrapper for rename ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_rename ( const char * oldname , const char * newname )
{
struct smbw_server * srv ;
fstring server1 , share1 ;
pstring path1 ;
fstring server2 , share2 ;
pstring path2 ;
if ( ! oldname | | ! newname ) {
errno = EINVAL ;
return - 1 ;
}
smbw_init ( ) ;
1998-10-06 17:10:06 +04:00
DEBUG ( 4 , ( " smbw_rename(%s,%s) \n " , oldname , newname ) ) ;
1998-10-03 13:39:11 +04:00
smbw_busy + + ;
/* work out what server they are after */
smbw_parse_path ( oldname , server1 , share1 , path1 ) ;
smbw_parse_path ( newname , server2 , share2 , path2 ) ;
if ( strcmp ( server1 , server2 ) | | strcmp ( share1 , share2 ) ) {
/* can't cross filesystems */
errno = EXDEV ;
return - 1 ;
}
/* get a connection to the server */
srv = smbw_server ( server1 , share1 ) ;
if ( ! srv ) {
/* smbw_server sets errno */
goto failed ;
}
if ( ! cli_rename ( & srv - > cli , path1 , path2 ) ) {
1998-10-06 17:10:06 +04:00
int eno = smbw_errno ( & srv - > cli ) ;
if ( eno ! = EEXIST | |
! cli_unlink ( & srv - > cli , path2 ) | |
! cli_rename ( & srv - > cli , path1 , path2 ) ) {
errno = eno ;
goto failed ;
}
1998-10-03 13:39:11 +04:00
}
smbw_busy - - ;
return 0 ;
failed :
smbw_busy - - ;
return - 1 ;
}
1998-10-03 14:24:49 +04:00
/*****************************************************
1998-10-05 12:44:46 +04:00
a wrapper for utime and utimes
1998-10-03 14:24:49 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-05 12:44:46 +04:00
static int smbw_settime ( const char * fname , time_t t )
1998-10-03 14:24:49 +04:00
{
struct smbw_server * srv ;
fstring server , share ;
pstring path ;
uint32 mode ;
if ( ! fname ) {
errno = EINVAL ;
return - 1 ;
}
smbw_init ( ) ;
smbw_busy + + ;
/* work out what server they are after */
smbw_parse_path ( fname , server , share , path ) ;
/* get a connection to the server */
srv = smbw_server ( server , share ) ;
if ( ! srv ) {
/* smbw_server sets errno */
goto failed ;
}
if ( ! cli_getatr ( & srv - > cli , path , & mode , NULL , NULL ) ) {
errno = smbw_errno ( & srv - > cli ) ;
goto failed ;
}
1998-10-05 12:44:46 +04:00
if ( ! cli_setatr ( & srv - > cli , path , mode , t ) ) {
1998-10-06 15:56:44 +04:00
/* some servers always refuse directory changes */
if ( ! ( mode & aDIR ) ) {
errno = smbw_errno ( & srv - > cli ) ;
goto failed ;
}
1998-10-03 14:24:49 +04:00
}
smbw_busy - - ;
return 0 ;
failed :
smbw_busy - - ;
return - 1 ;
}
1998-10-05 12:44:46 +04:00
/*****************************************************
a wrapper for utime
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_utime ( const char * fname , void * buf )
{
struct utimbuf * tbuf = ( struct utimbuf * ) buf ;
return smbw_settime ( fname , tbuf ? tbuf - > modtime : time ( NULL ) ) ;
}
/*****************************************************
a wrapper for utime
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_utimes ( const char * fname , void * buf )
{
struct timeval * tbuf = ( struct timeval * ) buf ;
return smbw_settime ( fname , tbuf ? tbuf - > tv_sec : time ( NULL ) ) ;
}
1998-10-03 14:24:49 +04:00
/*****************************************************
a wrapper for chown ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_chown ( const char * fname , uid_t owner , gid_t group )
{
struct smbw_server * srv ;
fstring server , share ;
pstring path ;
uint32 mode ;
if ( ! fname ) {
errno = EINVAL ;
return - 1 ;
}
smbw_init ( ) ;
smbw_busy + + ;
/* work out what server they are after */
smbw_parse_path ( fname , server , share , path ) ;
/* get a connection to the server */
srv = smbw_server ( server , share ) ;
if ( ! srv ) {
/* smbw_server sets errno */
goto failed ;
}
if ( ! cli_getatr ( & srv - > cli , path , & mode , NULL , NULL ) ) {
errno = smbw_errno ( & srv - > cli ) ;
goto failed ;
}
/* assume success */
smbw_busy - - ;
return 0 ;
failed :
smbw_busy - - ;
return - 1 ;
}
/*****************************************************
a wrapper for chmod ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_chmod ( const char * fname , mode_t newmode )
{
struct smbw_server * srv ;
fstring server , share ;
pstring path ;
uint32 mode ;
if ( ! fname ) {
errno = EINVAL ;
return - 1 ;
}
smbw_init ( ) ;
smbw_busy + + ;
/* work out what server they are after */
smbw_parse_path ( fname , server , share , path ) ;
/* get a connection to the server */
srv = smbw_server ( server , share ) ;
if ( ! srv ) {
/* smbw_server sets errno */
goto failed ;
}
1998-10-06 15:14:52 +04:00
mode = 0 ;
if ( ! ( newmode & ( S_IWUSR | S_IWGRP | S_IWOTH ) ) ) mode | = aRONLY ;
if ( ( newmode & S_IXUSR ) & & lp_map_archive ( - 1 ) ) mode | = aARCH ;
if ( ( newmode & S_IXGRP ) & & lp_map_system ( - 1 ) ) mode | = aSYSTEM ;
if ( ( newmode & S_IXOTH ) & & lp_map_hidden ( - 1 ) ) mode | = aHIDDEN ;
if ( ! cli_setatr ( & srv - > cli , path , mode , 0 ) ) {
1998-10-03 14:24:49 +04:00
errno = smbw_errno ( & srv - > cli ) ;
goto failed ;
}
smbw_busy - - ;
return 0 ;
failed :
smbw_busy - - ;
return - 1 ;
}
1998-10-03 15:54:20 +04:00
/*****************************************************
a wrapper for lseek ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-10-03 16:33:34 +04:00
off_t smbw_lseek ( int fd , off_t offset , int whence )
1998-10-03 15:54:20 +04:00
{
struct smbw_file * file ;
1998-10-05 16:17:01 +04:00
size_t size ;
1998-10-03 15:54:20 +04:00
smbw_busy + + ;
file = smbw_file ( fd ) ;
if ( ! file ) {
1998-10-03 16:33:34 +04:00
off_t ret = smbw_dir_lseek ( fd , offset , whence ) ;
1998-10-03 15:54:20 +04:00
smbw_busy - - ;
1998-10-03 16:33:34 +04:00
return ret ;
1998-10-03 15:54:20 +04:00
}
switch ( whence ) {
case SEEK_SET :
1998-10-04 11:52:00 +04:00
file - > f - > offset = offset ;
1998-10-03 15:54:20 +04:00
break ;
case SEEK_CUR :
1998-10-04 11:52:00 +04:00
file - > f - > offset + = offset ;
1998-10-03 15:54:20 +04:00
break ;
case SEEK_END :
1998-10-04 11:52:00 +04:00
if ( ! cli_qfileinfo ( & file - > srv - > cli , file - > f - > cli_fd ,
1998-10-03 15:54:20 +04:00
NULL , & size , NULL , NULL , NULL ) & &
1998-10-04 11:52:00 +04:00
! cli_getattrE ( & file - > srv - > cli , file - > f - > cli_fd ,
1998-10-03 15:54:20 +04:00
NULL , & size , NULL , NULL , NULL ) ) {
errno = EINVAL ;
smbw_busy - - ;
return - 1 ;
}
1998-10-04 11:52:00 +04:00
file - > f - > offset = size + offset ;
1998-10-03 15:54:20 +04:00
break ;
}
smbw_busy - - ;
1998-10-04 11:52:00 +04:00
return file - > f - > offset ;
}
/*****************************************************
a wrapper for dup ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_dup ( int fd )
{
int fd2 ;
struct smbw_file * file , * file2 ;
smbw_busy + + ;
file = smbw_file ( fd ) ;
if ( ! file ) {
errno = EBADF ;
goto failed ;
}
fd2 = dup ( file - > fd ) ;
if ( fd2 = = - 1 ) {
goto failed ;
}
if ( bitmap_query ( smbw_file_bmap , fd2 ) ) {
DEBUG ( 0 , ( " ERROR: fd already open in dup! \n " ) ) ;
errno = EIO ;
goto failed ;
}
file2 = ( struct smbw_file * ) malloc ( sizeof ( * file2 ) ) ;
if ( ! file2 ) {
close ( fd2 ) ;
errno = ENOMEM ;
goto failed ;
}
ZERO_STRUCTP ( file2 ) ;
* file2 = * file ;
file2 - > fd = fd2 ;
file - > f - > ref_count + + ;
bitmap_set ( smbw_file_bmap , fd2 ) ;
DLIST_ADD ( smbw_files , file2 ) ;
smbw_busy - - ;
return fd2 ;
failed :
smbw_busy - - ;
return - 1 ;
}
/*****************************************************
a wrapper for dup2 ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_dup2 ( int fd , int fd2 )
{
struct smbw_file * file , * file2 ;
smbw_busy + + ;
file = smbw_file ( fd ) ;
if ( ! file ) {
errno = EBADF ;
goto failed ;
}
if ( bitmap_query ( smbw_file_bmap , fd2 ) ) {
DEBUG ( 0 , ( " ERROR: fd already open in dup2! \n " ) ) ;
errno = EIO ;
goto failed ;
}
if ( dup2 ( file - > fd , fd2 ) ! = fd2 ) {
goto failed ;
}
file2 = ( struct smbw_file * ) malloc ( sizeof ( * file2 ) ) ;
if ( ! file2 ) {
close ( fd2 ) ;
errno = ENOMEM ;
goto failed ;
}
ZERO_STRUCTP ( file2 ) ;
* file2 = * file ;
file2 - > fd = fd2 ;
file - > f - > ref_count + + ;
bitmap_set ( smbw_file_bmap , fd2 ) ;
DLIST_ADD ( smbw_files , file2 ) ;
smbw_busy - - ;
return fd2 ;
failed :
smbw_busy - - ;
return - 1 ;
1998-10-03 15:54:20 +04:00
}
1998-10-03 17:27:56 +04:00
1998-10-06 16:23:37 +04:00
/*****************************************************
close a connection to a server
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void smbw_srv_close ( struct smbw_server * srv )
{
smbw_busy + + ;
cli_shutdown ( & srv - > cli ) ;
free ( srv - > server_name ) ;
free ( srv - > share_name ) ;
DLIST_REMOVE ( smbw_srvs , srv ) ;
ZERO_STRUCTP ( srv ) ;
free ( srv ) ;
smbw_busy - - ;
}
/*****************************************************
when we fork we have to close all connections and files
in the child
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_fork ( void )
{
pid_t child ;
int p [ 2 ] ;
char c = 0 ;
struct smbw_file * file , * next_file ;
struct smbw_server * srv , * next_srv ;
if ( pipe ( p ) ) return real_fork ( ) ;
child = real_fork ( ) ;
if ( child ) {
/* block the parent for a moment until the sockets are
closed */
close ( p [ 1 ] ) ;
read ( p [ 0 ] , & c , 1 ) ;
close ( p [ 0 ] ) ;
return child ;
}
close ( p [ 0 ] ) ;
/* close all files */
for ( file = smbw_files ; file ; file = next_file ) {
next_file = file - > next ;
close ( file - > fd ) ;
}
/* close all server connections */
for ( srv = smbw_srvs ; srv ; srv = next_srv ) {
next_srv = srv - > next ;
smbw_srv_close ( srv ) ;
}
/* unblock the parent */
write ( p [ 1 ] , & c , 1 ) ;
close ( p [ 1 ] ) ;
/* and continue in the child */
return 0 ;
}
1998-10-07 13:57:22 +04:00
# ifdef HAVE_ACL
/*****************************************************
say no to acls
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_acl ( const char * pathp , int cmd , int nentries , aclent_t * aclbufp )
{
if ( cmd = = GETACL | | cmd = = GETACLCNT ) return 0 ;
errno = ENOSYS ;
return - 1 ;
}
# endif
# ifdef HAVE_FACL
/*****************************************************
say no to acls
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_facl ( int fd , int cmd , int nentries , aclent_t * aclbufp )
{
if ( cmd = = GETACL | | cmd = = GETACLCNT ) return 0 ;
errno = ENOSYS ;
return - 1 ;
}
# endif
# ifdef HAVE_STAT64
/* this can't be in wrapped.c because of include conflicts */
void stat64_convert ( struct stat * st , struct stat64 * st64 )
{
st64 - > st_size = st - > st_size ;
st64 - > st_mode = st - > st_mode ;
st64 - > st_ino = st - > st_ino ;
st64 - > st_dev = st - > st_dev ;
st64 - > st_rdev = st - > st_rdev ;
st64 - > st_nlink = st - > st_nlink ;
st64 - > st_uid = st - > st_uid ;
st64 - > st_gid = st - > st_gid ;
st64 - > st_atime = st - > st_atime ;
st64 - > st_mtime = st - > st_mtime ;
st64 - > st_ctime = st - > st_ctime ;
st64 - > st_blksize = st - > st_blksize ;
st64 - > st_blocks = st - > st_blocks ;
}
# endif
# ifdef HAVE_READDIR64
void dirent64_convert ( struct dirent * d , struct dirent64 * d64 )
{
d64 - > d_ino = d - > d_ino ;
d64 - > d_off = d - > d_off ;
d64 - > d_reclen = d - > d_reclen ;
pstrcpy ( d64 - > d_name , d - > d_name ) ;
}
# endif
# ifdef HAVE___XSTAT
/* Definition of `struct stat' used in the linux kernel.. */
struct kernel_stat {
unsigned short int st_dev ;
unsigned short int __pad1 ;
unsigned long int st_ino ;
unsigned short int st_mode ;
unsigned short int st_nlink ;
unsigned short int st_uid ;
unsigned short int st_gid ;
unsigned short int st_rdev ;
unsigned short int __pad2 ;
unsigned long int st_size ;
unsigned long int st_blksize ;
unsigned long int st_blocks ;
unsigned long int st_atime ;
unsigned long int __unused1 ;
unsigned long int st_mtime ;
unsigned long int __unused2 ;
unsigned long int st_ctime ;
unsigned long int __unused3 ;
unsigned long int __unused4 ;
unsigned long int __unused5 ;
} ;
void xstat_convert ( int vers , struct stat * st , struct kernel_stat * kbuf )
{
if ( vers = = _STAT_VER_LINUX_OLD ) {
memcpy ( st , kbuf , sizeof ( * st ) ) ;
return ;
}
ZERO_STRUCTP ( st ) ;
st - > st_dev = kbuf - > st_dev ;
st - > st_ino = kbuf - > st_ino ;
st - > st_mode = kbuf - > st_mode ;
st - > st_nlink = kbuf - > st_nlink ;
st - > st_uid = kbuf - > st_uid ;
st - > st_gid = kbuf - > st_gid ;
st - > st_rdev = kbuf - > st_rdev ;
st - > st_size = kbuf - > st_size ;
st - > st_blksize = kbuf - > st_blksize ;
st - > st_blocks = kbuf - > st_blocks ;
st - > st_atime = kbuf - > st_atime ;
st - > st_mtime = kbuf - > st_mtime ;
st - > st_ctime = kbuf - > st_ctime ;
}
# endif