2000-12-26 05:57:10 +00:00
/*
Unix SMB / Netbios implementation .
Version 2.0
SMB client library implementation
Copyright ( C ) Andrew Tridgell 1998
Copyright ( C ) Richard Sharpe 2000
Copyright ( C ) John Terpstra 2000
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"
# include "libsmbclient.h"
/* Structure for servers ... Held here so we don't need an include ...
* May be better to put in an include file
*/
struct smbc_server {
2001-11-21 03:55:59 +00:00
struct smbc_server * next , * prev ;
struct cli_state cli ;
dev_t dev ;
char * server_name ;
char * share_name ;
char * workgroup ;
char * username ;
BOOL no_pathinfo2 ;
2000-12-26 05:57:10 +00:00
} ;
2001-01-05 13:43:19 +00:00
/* Keep directory entries in a list */
struct smbc_dir_list {
2001-11-21 03:55:59 +00:00
struct smbc_dir_list * next ;
struct smbc_dirent * dirent ;
2001-01-05 13:43:19 +00:00
} ;
2000-12-26 05:57:10 +00:00
struct smbc_file {
2001-11-21 03:55:59 +00:00
int cli_fd ;
int smbc_fd ;
char * fname ;
off_t offset ;
struct smbc_server * srv ;
BOOL file ;
struct smbc_dir_list * dir_list , * dir_end , * dir_next ;
int dir_type , dir_error ;
2000-12-26 05:57:10 +00:00
} ;
2001-02-26 11:53:22 +00:00
int smbc_fstatdir ( int fd , struct stat * st ) ; /* Forward decl */
BOOL smbc_getatr ( struct smbc_server * srv , char * path ,
uint16 * mode , size_t * size ,
time_t * c_time , time_t * a_time , time_t * m_time ,
SMB_INO_T * ino ) ;
2001-01-05 13:43:19 +00:00
extern BOOL in_client ;
2001-11-21 03:55:59 +00:00
extern pstring global_myname ;
2000-12-26 05:57:10 +00:00
static int smbc_initialized = 0 ;
static smbc_get_auth_data_fn smbc_auth_fn = NULL ;
2001-03-09 05:47:48 +00:00
/*static int smbc_debug;*/
2000-12-26 05:57:10 +00:00
static int smbc_start_fd ;
static struct smbc_file * * smbc_file_table ;
2001-01-05 13:43:19 +00:00
static struct smbc_server * smbc_srvs ;
static pstring my_netbios_name ;
2001-01-12 05:10:45 +00:00
static pstring smbc_user ;
2000-12-26 05:57:10 +00:00
/*
* Function to parse a path and turn it into components
*
2001-01-05 13:43:19 +00:00
* We accept smb : //[[[domain;]user[:password@]]server[/share[/path[/file]]]]
*
* smb : // means show all the workgroups
* smb : //name/ means, if name<1D> exists, list servers in workgroup,
* else , if name < 20 > exists , list all shares for server . . .
2000-12-26 05:57:10 +00:00
*/
static const char * smbc_prefix = " smb: " ;
static int
2001-01-12 05:10:45 +00:00
smbc_parse_path ( const char * fname , char * server , char * share , char * path ,
char * user , char * password ) /* FIXME, lengths of strings */
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
static pstring s ;
pstring userinfo ;
char * p ;
char * q , * r ;
int len ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
server [ 0 ] = share [ 0 ] = path [ 0 ] = user [ 0 ] = password [ 0 ] = ( char ) 0 ;
pstrcpy ( s , fname ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* clean_fname(s); causing problems ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* see if it has the right prefix */
len = strlen ( smbc_prefix ) ;
if ( strncmp ( s , smbc_prefix , len ) | |
( s [ len ] ! = ' / ' & & s [ len ] ! = 0 ) ) return - 1 ; /* What about no smb: ? */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
p = s + len ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Watch the test below, we are testing to see if we should exit */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( strncmp ( p , " // " , 2 ) & & strncmp ( p , " \\ \\ " , 2 ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
p + = 2 ; /* Skip the // or \\ */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( * p = = ( char ) 0 )
return 0 ;
2001-01-06 12:15:46 +00:00
2001-11-21 03:55:59 +00:00
if ( * p = = ' / ' ) {
2001-01-06 12:15:46 +00:00
2001-11-21 03:55:59 +00:00
strncpy ( server , ( char * ) lp_workgroup ( ) , 16 ) ; /* FIXME: Danger here */
return 0 ;
}
2001-01-06 12:15:46 +00:00
2001-11-21 03:55:59 +00:00
/*
* ok , its for us . Now parse out the server , share etc .
*
* However , we want to parse out [ [ domain ; ] user [ : password ] @ ] if it
* exists . . .
*/
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
/* check that '@' occurs before '/', if '/' exists at all */
q = strchr_m ( p , ' @ ' ) ;
r = strchr_m ( p , ' / ' ) ;
if ( q & & ( ! r | | q < r ) ) {
pstring username , passwd , domain ;
char * u = userinfo ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
next_token ( & p , userinfo , " @ " , sizeof ( fstring ) ) ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
username [ 0 ] = passwd [ 0 ] = domain [ 0 ] = 0 ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( strchr_m ( u , ' ; ' ) ) {
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
next_token ( & u , domain , " ; " , sizeof ( fstring ) ) ;
}
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( strchr_m ( u , ' : ' ) ) {
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
next_token ( & u , username , " : " , sizeof ( fstring ) ) ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( passwd , u ) ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( username , u ) ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( username [ 0 ] )
strncpy ( user , username , sizeof ( fstring ) ) ; /* FIXME, size and domain */
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( passwd [ 0 ] )
strncpy ( password , passwd , sizeof ( fstring ) ) ; /* FIXME, size */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! next_token ( & p , server , " / " , sizeof ( fstring ) ) ) {
return - 1 ;
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( * p = = ( char ) 0 ) return 0 ; /* That's it ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! next_token ( & p , share , " / " , sizeof ( fstring ) ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( path , p ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
all_string_sub ( path , " / " , " \\ " , 0 ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Convert an SMB error into a UNIX error . . .
*/
int smbc_errno ( struct cli_state * c )
{
int ret ;
2001-08-10 06:00:33 +00:00
if ( cli_is_dos_error ( c ) ) {
uint8 eclass ;
uint32 ecode ;
cli_dos_error ( c , & eclass , & ecode ) ;
ret = cli_errno_from_dos ( eclass , ecode ) ;
DEBUG ( 3 , ( " smbc_error %d %d (0x%x) -> %d \n " ,
( int ) eclass , ( int ) ecode , ( int ) ecode , ret ) ) ;
} else {
2001-08-27 19:46:22 +00:00
NTSTATUS status ;
2001-08-10 06:00:33 +00:00
2001-08-10 06:16:05 +00:00
status = cli_nt_error ( c ) ;
2001-08-10 06:00:33 +00:00
ret = cli_errno_from_nt ( status ) ;
2001-09-04 10:57:29 +00:00
DEBUG ( 3 , ( " smbc errno %s -> %d \n " ,
get_nt_error_msg ( status ) , ret ) ) ;
2001-08-10 06:00:33 +00:00
}
2000-12-26 05:57:10 +00:00
return ret ;
}
/*
* Connect to a server , possibly on an existing connection
2001-01-12 05:10:45 +00:00
*
* Here , what we want to do is : If the server and username
* match an existing connection , reuse that , otherwise , establish a
* new connection .
*
* If we have to create a new connection , call the auth_fn to get the
* info we need , unless the username and password were passed in .
2000-12-26 05:57:10 +00:00
*/
2001-01-12 05:10:45 +00:00
struct smbc_server * smbc_server ( char * server , char * share ,
char * workgroup , char * username ,
char * password )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
struct smbc_server * srv = NULL ;
struct cli_state c ;
struct nmb_name called , calling ;
char * p , * server_n = server ;
fstring group ;
pstring ipenv ;
struct in_addr ip ;
2000-12-26 05:57:10 +00:00
2001-11-26 03:11:44 +00:00
zero_ip ( & ip ) ;
2001-11-21 03:55:59 +00:00
ZERO_STRUCT ( c ) ;
/* try to use an existing connection */
for ( srv = smbc_srvs ; srv ; srv = srv - > next ) {
if ( strcmp ( server , srv - > server_name ) = = 0 & &
strcmp ( share , srv - > share_name ) = = 0 & &
strcmp ( workgroup , srv - > workgroup ) = = 0 & &
strcmp ( username , srv - > username ) = = 0 )
return srv ;
}
if ( server [ 0 ] = = 0 ) {
errno = EPERM ;
return NULL ;
}
/*
* Pick up the auth info here , once we know we need to connect
* But only if we do not have a username and password . . .
*/
if ( ! username [ 0 ] | | ! password [ 0 ] )
smbc_auth_fn ( server , share , workgroup , sizeof ( fstring ) ,
username , sizeof ( fstring ) , password , sizeof ( fstring ) ) ;
/*
* However , smbc_auth_fn may have picked up info relating to an
* existing connection , so try for an existing connection again . . .
*/
for ( srv = smbc_srvs ; srv ; srv = srv - > next ) {
if ( strcmp ( server , srv - > server_name ) = = 0 & &
strcmp ( share , srv - > share_name ) = = 0 & &
strcmp ( workgroup , srv - > workgroup ) = = 0 & &
strcmp ( username , srv - > username ) = = 0 )
return srv ;
}
make_nmb_name ( & calling , my_netbios_name , 0x0 ) ;
make_nmb_name ( & called , server , 0x20 ) ;
DEBUG ( 4 , ( " smbc_server: server_n=[%s] server=[%s] \n " , server_n , server ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ( p = strchr_m ( server_n , ' # ' ) ) & &
( strcmp ( p + 1 , " 1D " ) = = 0 | | strcmp ( p + 1 , " 01 " ) = = 0 ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fstrcpy ( group , server_n ) ;
p = strchr_m ( group , ' # ' ) ;
* p = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " -> server_n=[%s] server=[%s] \n " , server_n , server ) ) ;
2000-12-26 05:57:10 +00:00
again :
2001-11-21 03:55:59 +00:00
slprintf ( ipenv , sizeof ( ipenv ) - 1 , " HOST_%s " , server_n ) ;
2001-11-26 03:11:44 +00:00
zero_ip ( & ip ) ;
2001-11-21 03:55:59 +00:00
/* have to open a new connection */
if ( ! cli_initialise ( & c ) | | ! cli_connect ( & c , server_n , & ip ) ) {
2001-11-27 10:42:39 +00:00
if ( c . initialised ) cli_shutdown ( & c ) ;
2001-11-21 03:55:59 +00:00
errno = ENOENT ;
return NULL ;
}
if ( ! cli_session_request ( & c , & calling , & called ) ) {
cli_shutdown ( & c ) ;
if ( strcmp ( called . name , " *SMBSERVER " ) ) {
make_nmb_name ( & called , " *SMBSERVER " , 0x20 ) ;
goto again ;
}
errno = ENOENT ;
return NULL ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " session request ok \n " ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_negprot ( & c ) ) {
cli_shutdown ( & c ) ;
errno = ENOENT ;
return NULL ;
}
if ( ! cli_session_setup ( & c , username ,
password , strlen ( password ) ,
password , strlen ( password ) ,
workgroup ) & &
/* try an anonymous login if it failed */
! cli_session_setup ( & c , " " , " " , 1 , " " , 0 , workgroup ) ) {
cli_shutdown ( & c ) ;
errno = EPERM ;
return NULL ;
}
DEBUG ( 4 , ( " session setup ok \n " ) ) ;
if ( ! cli_send_tconX ( & c , share , " ????? " ,
password , strlen ( password ) + 1 ) ) {
errno = smbc_errno ( & c ) ;
cli_shutdown ( & c ) ;
return NULL ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " tconx ok \n " ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv = ( struct smbc_server * ) malloc ( sizeof ( * srv ) ) ;
if ( ! srv ) {
errno = ENOMEM ;
goto failed ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
ZERO_STRUCTP ( srv ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv - > cli = c ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv - > dev = ( dev_t ) ( str_checksum ( server ) ^ str_checksum ( share ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv - > server_name = strdup ( server ) ;
if ( ! srv - > server_name ) {
errno = ENOMEM ;
goto failed ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv - > share_name = strdup ( share ) ;
if ( ! srv - > share_name ) {
errno = ENOMEM ;
goto failed ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv - > workgroup = strdup ( workgroup ) ;
if ( ! srv - > workgroup ) {
errno = ENOMEM ;
goto failed ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
srv - > username = strdup ( username ) ;
if ( ! srv - > username ) {
errno = ENOMEM ;
goto failed ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DLIST_ADD ( smbc_srvs , srv ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return srv ;
2000-12-26 05:57:10 +00:00
failed :
2001-11-21 03:55:59 +00:00
cli_shutdown ( & c ) ;
if ( ! srv ) return NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( srv - > server_name ) ;
SAFE_FREE ( srv - > share_name ) ;
SAFE_FREE ( srv - > workgroup ) ;
SAFE_FREE ( srv - > username ) ;
SAFE_FREE ( srv ) ;
return NULL ;
}
/*
* Remove a server from the list smbc_srvs if it ' s unused - - Tom ( tom @ ninja . nl )
*
* We accept a * srv
*/
BOOL smbc_remove_unused_server ( struct smbc_server * s )
{
int p ;
/* are we being fooled ? */
if ( ! s ) return False ;
/* close all open files/directories on this server */
for ( p = 0 ; p < SMBC_MAX_FD ; p + + ) {
if ( smbc_file_table [ p ] & &
smbc_file_table [ p ] - > srv = = s ) {
/* Still used .. DARN */
DEBUG ( 3 , ( " smbc_remove_usused_server: %x still used by %s (%d). \n " , ( int ) s ,
smbc_file_table [ p ] - > fname , smbc_file_table [ p ] - > smbc_fd ) ) ;
return False ;
}
}
cli_shutdown ( & s - > cli ) ;
SAFE_FREE ( s - > username ) ;
SAFE_FREE ( s - > workgroup ) ;
SAFE_FREE ( s - > server_name ) ;
SAFE_FREE ( s - > share_name ) ;
DLIST_REMOVE ( smbc_srvs , s ) ;
DEBUG ( 3 , ( " smbc_remove_usused_server: %x removed. \n " , ( int ) s ) ) ;
SAFE_FREE ( s ) ;
return True ;
2000-12-26 05:57:10 +00:00
}
/*
* Initialise the library etc
2001-01-29 09:34:24 +00:00
*
2001-11-21 03:55:59 +00:00
* We accept valid values for debug from 0 to 100 ,
2001-01-29 09:34:24 +00:00
* and insist that fn must be non - null .
2000-12-26 05:57:10 +00:00
*/
2001-02-12 12:17:54 +00:00
int smbc_init ( smbc_get_auth_data_fn fn , int debug )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
pstring conf ;
int p , pid ;
char * user = NULL , * home = NULL , * pname = " libsmbclient " ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fn | | debug < 0 | | debug > 100 ) {
2001-06-07 22:17:01 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-06-07 22:17:01 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-08 02:47:30 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_initialized ) { /* Don't go through this if we have already done it */
2001-01-08 02:47:30 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
smbc_initialized = 1 ;
smbc_auth_fn = fn ;
/* smbc_debug = debug; */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
DEBUGLEVEL = - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
setup_logging ( pname , False ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Here we would open the smb.conf file if needed ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
home = getenv ( " HOME " ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
slprintf ( conf , sizeof ( conf ) , " %s/.smb/smb.conf " , home ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
load_interfaces ( ) ; /* Load the list of interfaces ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
in_client = True ; /* FIXME, make a param */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! lp_load ( conf , True , False , False ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Hmmm , what the hell do we do here . . . we could not parse the
* config file . . . We must return an error . . . and keep info around
* about why we failed
*/
errno = ENOENT ; /* FIXME: Figure out the correct error response */
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
reopen_logs ( ) ; /* Get logging working ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* FIXME : Is this the best way to get the user info ?
*/
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
user = getenv ( " USER " ) ;
/* walk around as "guest" if no username can be found */
if ( ! user ) user = strdup ( " guest " ) ;
pstrcpy ( smbc_user , user ) ; /* Save for use elsewhere */
/*
* We try to get our netbios name from the config . If that fails we fall
* back on constructing our netbios name from our hostname etc
*/
if ( global_myname ) {
pstrcpy ( my_netbios_name , global_myname ) ;
}
else {
/*
* Hmmm , I want to get hostname as well , but I am too lazy for the moment
*/
pid = getpid ( ) ;
slprintf ( my_netbios_name , 16 , " smbc%s%d " , user , pid ) ;
}
DEBUG ( 0 , ( " Using netbios name %s. \n " , my_netbios_name ) ) ;
2001-01-08 02:47:30 +00:00
2001-11-21 03:55:59 +00:00
name_register_wins ( my_netbios_name , 0 ) ;
2001-02-18 10:36:03 +00:00
2001-11-21 03:55:59 +00:00
/*
* Now initialize the file descriptor array and figure out what the
* max open files is , so we can return FD ' s that are above the max
* open file , and separated by a guard band
*/
2000-12-26 05:57:10 +00:00
# if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2001-11-21 03:55:59 +00:00
do {
struct rlimit rlp ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( getrlimit ( RLIMIT_NOFILE , & rlp ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 0 , ( " smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s \n " , strerror ( errno ) ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_start_fd = 1000000 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_start_fd = rlp . rlim_max + 10000 ; /* Leave a guard space of 10,000 */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
} while ( 0 ) ;
2000-12-26 05:57:10 +00:00
# else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2001-11-21 03:55:59 +00:00
smbc_start_fd = 1000000 ;
2000-12-26 05:57:10 +00:00
# endif
2001-11-21 03:55:59 +00:00
smbc_file_table = malloc ( SMBC_MAX_FD * sizeof ( struct smbc_file * ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
for ( p = 0 ; p < SMBC_MAX_FD ; p + + )
smbc_file_table [ p ] = NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_file_table )
return ENOMEM ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ; /* Success */
2000-12-26 05:57:10 +00:00
}
/*
* Routine to open ( ) a file . . .
*/
int smbc_open ( const char * fname , int flags , mode_t mode )
{
2001-11-21 03:55:59 +00:00
fstring server , share , user , password , workgroup ;
pstring path ;
struct smbc_server * srv = NULL ;
int fd ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /* FIXME, check errors */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( errno = = EPERM ) errno = EACCES ;
return - 1 ; /* smbc_server sets errno */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Hmmm, the test for a directory is suspect here ... FIXME */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( strlen ( path ) > 0 & & path [ strlen ( path ) - 1 ] = = ' \\ ' ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fd = - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
int slot = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Find a free slot first */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
while ( smbc_file_table [ slot ] )
slot + + ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( slot > SMBC_MAX_FD ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOMEM ; /* FIXME, is this best? */
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] = malloc ( sizeof ( struct smbc_file ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_file_table [ slot ] ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ( fd = cli_open ( & srv - > cli , path , flags , DENY_NONE ) ) < 0 ) {
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
/* Handle the error ... */
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( smbc_file_table [ slot ] ) ;
errno = smbc_errno ( & srv - > cli ) ;
return - 1 ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Fill in file struct */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > cli_fd = fd ;
smbc_file_table [ slot ] - > smbc_fd = slot + smbc_start_fd ;
smbc_file_table [ slot ] - > fname = strdup ( fname ) ;
smbc_file_table [ slot ] - > srv = srv ;
smbc_file_table [ slot ] - > offset = 0 ;
smbc_file_table [ slot ] - > file = True ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return smbc_file_table [ slot ] - > smbc_fd ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check if opendir needed ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( fd = = - 1 ) {
int eno = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
eno = smbc_errno ( & srv - > cli ) ;
fd = smbc_opendir ( fname ) ;
if ( fd < 0 ) errno = eno ;
return fd ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 1 ; /* Success, with fd ... */
2000-12-26 05:57:10 +00:00
}
/*
* Routine to create a file
*/
static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC ; /* FIXME: Do we need this */
int smbc_creat ( const char * path , mode_t mode )
{
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
return smbc_open ( path , creat_bits , mode ) ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to read ( ) a file . . .
*/
ssize_t smbc_read ( int fd , void * buf , size_t count )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
int ret ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_read(%d, %d) \n " , fd , ( int ) count ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check that the buffer exists ... */
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( buf = = NULL ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe | | ! fe - > file ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
ret = cli_read ( & fe - > srv - > cli , fe - > cli_fd , buf , fe - > offset , count ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ret < 0 ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & fe - > srv - > cli ) ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fe - > offset + = ret ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " --> %d \n " , ret ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return ret ; /* Success, ret bytes of data ... */
2000-12-26 05:57:10 +00:00
}
/*
* Routine to write ( ) a file . . .
*/
ssize_t smbc_write ( int fd , void * buf , size_t count )
{
2001-11-21 03:55:59 +00:00
int ret ;
struct smbc_file * fe ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check that the buffer exists ... */
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
if ( buf = = NULL ) {
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe | | ! fe - > file ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
ret = cli_write ( & fe - > srv - > cli , fe - > cli_fd , 0 , buf , fe - > offset , count ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ret < = 0 ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & fe - > srv - > cli ) ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fe - > offset + = ret ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return ret ; /* Success, 0 bytes of data ... */
2000-12-26 05:57:10 +00:00
}
2001-01-05 13:43:19 +00:00
2000-12-26 05:57:10 +00:00
/*
* Routine to close ( ) a file . . .
*/
int smbc_close ( int fd )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
struct smbc_server * srv ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe - > file ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return smbc_closedir ( fd ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
if ( ! cli_close ( & fe - > srv - > cli , fe - > cli_fd ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 3 , ( " cli_close failed on %s (%d). purging server. \n " ,
fe - > fname , fe - > smbc_fd ) ) ;
/* Deallocate slot and remove the server
* from the server cache if unused */
errno = smbc_errno ( & fe - > srv - > cli ) ;
srv = fe - > srv ;
SAFE_FREE ( fe - > fname ) ;
SAFE_FREE ( fe ) ;
smbc_file_table [ fd - smbc_start_fd ] = NULL ;
smbc_remove_unused_server ( srv ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( fe - > fname ) ;
SAFE_FREE ( fe ) ;
smbc_file_table [ fd - smbc_start_fd ] = NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to unlink ( ) a file
*/
int smbc_unlink ( const char * fname )
{
2001-11-21 03:55:59 +00:00
fstring server , share , user , password , workgroup ;
pstring path ;
struct smbc_server * srv = NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /* FIXME, check errors */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ; /* smbc_server sets errno */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* if (strncmp(srv->cli.dev, "LPT", 3) == 0) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
int job = smbc_stat_printjob ( srv , path , NULL , NULL ) ;
if ( job = = - 1 ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
if ( ( err = cli_printjob_del ( & srv - > cli , job ) ) ! = 0 ) {
2000-12-26 05:57:10 +00:00
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
} else */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_unlink ( & srv - > cli , path ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & srv - > cli ) ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
if ( errno = = EACCES ) { /* Check if the file is a directory */
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
int saverr = errno ;
size_t size = 0 ;
uint16 mode = 0 ;
time_t m_time = 0 , a_time = 0 , c_time = 0 ;
SMB_INO_T ino = 0 ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_getatr ( srv , path , & mode , & size ,
& c_time , & a_time , & m_time , & ino ) ) {
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
/* Hmmm, bad error ... What? */
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & srv - > cli ) ;
return - 1 ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
if ( IS_DOS_DIR ( mode ) )
errno = EISDIR ;
else
errno = saverr ; /* Restore this */
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
}
}
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ; /* Success ... */
2000-12-26 05:57:10 +00:00
}
/*
* Routine to rename ( ) a file
*/
int smbc_rename ( const char * oname , const char * nname )
{
2001-11-21 03:55:59 +00:00
fstring server1 , share1 , server2 , share2 , user1 , user2 , password1 , password2 , workgroup ;
pstring path1 , path2 ;
struct smbc_server * srv = NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! oname | | ! nname ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_rename(%s,%s) \n " , oname , nname ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( oname , server1 , share1 , path1 , user1 , password1 ) ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( user1 [ 0 ] = = ( char ) 0 ) pstrcpy ( user1 , smbc_user ) ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( nname , server2 , share2 , path2 , user2 , password2 ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( user2 [ 0 ] = = ( char ) 0 ) pstrcpy ( user2 , smbc_user ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( strcmp ( server1 , server2 ) | | strcmp ( share1 , share2 ) | |
strcmp ( user1 , user2 ) ) {
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
/* Can't rename across file systems, or users?? */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EXDEV ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server1 , share1 , workgroup , user1 , password1 ) ;
if ( ! srv ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_rename ( & srv - > cli , path1 , path2 ) ) {
int eno = smbc_errno ( & srv - > cli ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( eno ! = EEXIST | |
! cli_unlink ( & srv - > cli , path2 ) | |
! cli_rename ( & srv - > cli , path1 , path2 ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = eno ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ; /* Success */
2000-12-26 05:57:10 +00:00
}
/*
* A routine to lseek ( ) a file
*/
off_t smbc_lseek ( int fd , off_t offset , int whence )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
size_t size ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe - > file ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ; /* Can't lseek a dir ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
switch ( whence ) {
case SEEK_SET :
fe - > offset = offset ;
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
case SEEK_CUR :
fe - > offset + = offset ;
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
case SEEK_END :
if ( ! cli_qfileinfo ( & fe - > srv - > cli , fe - > cli_fd , NULL , & size , NULL , NULL ,
NULL , NULL , NULL ) & &
! cli_getattrE ( & fe - > srv - > cli , fe - > cli_fd , NULL , & size , NULL , NULL ,
NULL ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
}
fe - > offset = size + offset ;
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
default :
errno = EINVAL ;
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return fe - > offset ;
2000-12-26 05:57:10 +00:00
}
/*
* Generate an inode number from file name for those things that need it
*/
static
ino_t smbc_inode ( const char * name )
{
2001-11-21 03:55:59 +00:00
if ( ! * name ) return 2 ; /* FIXME, why 2 ??? */
return ( ino_t ) str_checksum ( name ) ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to put basic stat info into a stat structure . . . Used by stat and
* fstat below .
*/
static
int smbc_setup_stat ( struct stat * st , char * fname , size_t size , int mode )
{
2001-11-21 03:55:59 +00:00
st - > st_mode = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( IS_DOS_DIR ( mode ) ) {
st - > st_mode = SMBC_DIR_MODE ;
} else {
st - > st_mode = SMBC_FILE_MODE ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( IS_DOS_ARCHIVE ( mode ) ) st - > st_mode | = S_IXUSR ;
if ( IS_DOS_SYSTEM ( mode ) ) st - > st_mode | = S_IXGRP ;
if ( IS_DOS_HIDDEN ( mode ) ) st - > st_mode | = S_IXOTH ;
if ( ! IS_DOS_READONLY ( mode ) ) st - > st_mode | = S_IWUSR ;
st - > st_size = size ;
st - > st_blksize = 512 ;
st - > st_blocks = ( size + 511 ) / 512 ;
st - > st_uid = getuid ( ) ;
st - > st_gid = getgid ( ) ;
if ( IS_DOS_DIR ( mode ) ) {
st - > st_nlink = 2 ;
} else {
st - > st_nlink = 1 ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( st - > st_ino = = 0 ) {
st - > st_ino = smbc_inode ( fname ) ;
}
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
return True ; /* FIXME: Is this needed ? */
2001-02-26 11:53:22 +00:00
2000-12-26 05:57:10 +00:00
}
/*
* Get info from an SMB server on a file . Use a qpathinfo call first
* and if that fails , use getatr , as Win95 sometimes refuses qpathinfo
*/
BOOL smbc_getatr ( struct smbc_server * srv , char * path ,
uint16 * mode , size_t * size ,
time_t * c_time , time_t * a_time , time_t * m_time ,
SMB_INO_T * ino )
{
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_getatr: sending qpathinfo \n " ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv - > no_pathinfo2 & &
cli_qpathinfo2 ( & srv - > cli , path , c_time , a_time , m_time , NULL ,
size , mode , ino ) ) return True ;
/* if this is NT then don't bother with the getatr */
if ( srv - > cli . capabilities & CAP_NT_SMBS ) return False ;
if ( cli_getatr ( & srv - > cli , path , mode , size , m_time ) ) {
a_time = c_time = m_time ;
srv - > no_pathinfo2 = True ;
return True ;
}
return False ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to stat a file given a name
*/
int smbc_stat ( const char * fname , struct stat * st )
{
2001-11-21 03:55:59 +00:00
struct smbc_server * srv ;
fstring server , share , user , password , workgroup ;
pstring path ;
time_t m_time = 0 , a_time = 0 , c_time = 0 ;
size_t size = 0 ;
uint16 mode = 0 ;
SMB_INO_T ino = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_stat(%s) \n " , fname ) ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /*FIXME, errors*/
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
mode = aDIR | aRONLY ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
else if ( strncmp ( srv - > cli . dev , " LPT " , 3 ) = = 0 ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( strcmp ( path , " \\ " ) = = 0 ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
mode = aDIR | aRONLY ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
mode = aRONLY ;
smbc_stat_printjob ( srv , path , & size , & m_time ) ;
c_time = a_time = m_time ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
else { */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_getatr ( srv , path , & mode , & size ,
& c_time , & a_time , & m_time , & ino ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & srv - > cli ) ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* } */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
st - > st_ino = ino ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_setup_stat ( st , path , size , mode ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
st - > st_atime = a_time ;
st - > st_ctime = c_time ;
st - > st_mtime = m_time ;
st - > st_dev = srv - > dev ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to stat a file given an fd
*/
int smbc_fstat ( int fd , struct stat * st )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
time_t c_time , a_time , m_time ;
size_t size ;
uint16 mode ;
SMB_INO_T ino = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe - > file ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return smbc_fstatdir ( fd , st ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_qfileinfo ( & fe - > srv - > cli , fe - > cli_fd ,
& mode , & size , & c_time , & a_time , & m_time , NULL , & ino ) & &
! cli_getattrE ( & fe - > srv - > cli , fe - > cli_fd ,
& mode , & size , & c_time , & a_time , & m_time ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
st - > st_ino = ino ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
smbc_setup_stat ( st , fe - > fname , size , mode ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
st - > st_atime = a_time ;
st - > st_ctime = c_time ;
st - > st_mtime = m_time ;
st - > st_dev = fe - > srv - > dev ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to open a directory
2001-01-05 13:43:19 +00:00
*
* We want to allow :
*
* smb : which should list all the workgroups available
* smb : workgroup
* smb : workgroup //server
* smb : //server
* smb : //server/share
2001-11-21 03:55:59 +00:00
* smb : //<IP-addr> which should list shares on server
* smb : //<IP-addr>/share which should list files on share
2000-12-26 05:57:10 +00:00
*/
2001-01-05 13:43:19 +00:00
static void smbc_remove_dir ( struct smbc_file * dir )
{
2001-11-21 03:55:59 +00:00
struct smbc_dir_list * d , * f ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
d = dir - > dir_list ;
while ( d ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
f = d ; d = d - > next ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( f - > dirent ) ;
SAFE_FREE ( f ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_list = dir - > dir_end = dir - > dir_next = NULL ;
2001-01-05 13:43:19 +00:00
}
static int add_dirent ( struct smbc_file * dir , const char * name , const char * comment , uint32 type )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
struct smbc_dirent * dirent ;
int size ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Allocate space for the dirent , which must be increased by the
* size of the name and the comment and 1 for the null on the comment .
* The null on the name is already accounted for .
*/
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
size = sizeof ( struct smbc_dirent ) + ( name ? strlen ( name ) : 0 ) +
( comment ? strlen ( comment ) : 0 ) + 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dirent = malloc ( size ) ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! dirent ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_error = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( dir - > dir_list = = NULL ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_list = malloc ( sizeof ( struct smbc_dir_list ) ) ;
if ( ! dir - > dir_list ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( dirent ) ;
dir - > dir_error = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end = dir - > dir_next = dir - > dir_list ;
2001-01-07 13:07:26 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end - > next = malloc ( sizeof ( struct smbc_dir_list ) ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! dir - > dir_end ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( dirent ) ;
dir - > dir_error = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end = dir - > dir_end - > next ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end - > next = NULL ;
dir - > dir_end - > dirent = dirent ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dirent - > smbc_type = type ;
dirent - > namelen = ( name ? strlen ( name ) : 0 ) ;
dirent - > commentlen = ( comment ? strlen ( comment ) : 0 ) ;
dirent - > dirlen = size ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
strncpy ( dirent - > name , ( name ? name : " " ) , dirent - > namelen + 1 ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dirent - > comment = ( char * ) ( & dirent - > name + dirent - > namelen + 1 ) ;
strncpy ( dirent - > comment , ( comment ? comment : " " ) , dirent - > commentlen + 1 ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
2001-01-05 13:43:19 +00:00
static void
list_fn ( const char * name , uint32 type , const char * comment , void * state )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * dir = ( struct smbc_file * ) state ;
int dirent_type ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
/* We need to process the type a little ... */
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( dir - > dir_type = = SMBC_FILE_SHARE ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
switch ( type ) {
case 0 : /* Directory tree */
dirent_type = SMBC_FILE_SHARE ;
break ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
case 1 :
dirent_type = SMBC_PRINTER_SHARE ;
break ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
case 2 :
dirent_type = SMBC_COMMS_SHARE ;
break ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
case 3 :
dirent_type = SMBC_IPC_SHARE ;
break ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
default :
dirent_type = SMBC_FILE_SHARE ; /* FIXME, error? */
break ;
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
else dirent_type = dir - > dir_type ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( add_dirent ( dir , name , comment , dirent_type ) < 0 ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* An error occurred, what do we do? */
/* FIXME: Add some code here */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
}
2001-01-06 14:48:55 +00:00
static void
dir_list_fn ( file_info * finfo , const char * mask , void * state )
{
2001-11-21 03:55:59 +00:00
if ( add_dirent ( ( struct smbc_file * ) state , finfo - > name , " " ,
( finfo - > mode & aDIR ? SMBC_DIR : SMBC_FILE ) ) < 0 ) {
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
/* Handle an error ... */
/* FIXME: Add some code ... */
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-06 14:48:55 +00:00
}
2001-01-05 13:43:19 +00:00
int smbc_opendir ( const char * fname )
{
2001-11-21 03:55:59 +00:00
fstring server , share , user , password , workgroup ;
pstring path ;
struct smbc_server * srv = NULL ;
struct in_addr rem_ip ;
int slot = 0 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_parse_path ( fname , server , share , path , user , password ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
/* Get a file entry ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
slot = 0 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
while ( smbc_file_table [ slot ] )
slot + + ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( slot > SMBC_MAX_FD ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOMEM ;
return - 1 ; /* FIXME, ... move into a func */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] = malloc ( sizeof ( struct smbc_file ) ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_file_table [ slot ] ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > cli_fd = 0 ;
smbc_file_table [ slot ] - > smbc_fd = slot + smbc_start_fd ;
smbc_file_table [ slot ] - > fname = strdup ( fname ) ;
smbc_file_table [ slot ] - > srv = NULL ;
smbc_file_table [ slot ] - > offset = 0 ;
smbc_file_table [ slot ] - > file = False ;
smbc_file_table [ slot ] - > dir_list =
smbc_file_table [ slot ] - > dir_next =
smbc_file_table [ slot ] - > dir_end = NULL ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( server [ 0 ] = = ( char ) 0 ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( share [ 0 ] ! = ( char ) 0 | | path [ 0 ] ! = ( char ) 0 ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* We have server and share and path empty ... so list the workgroups */
2001-02-19 05:50:09 +00:00
2001-11-21 03:55:59 +00:00
if ( ! resolve_name ( lp_workgroup ( ) , & rem_ip , 0x1d ) ) {
2001-02-19 05:50:09 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Something wrong with smb.conf? */
return - 1 ;
2001-02-19 05:50:09 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > dir_type = SMBC_WORKGROUP ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* find the name of the server ... */
2001-02-19 05:50:09 +00:00
2001-11-21 23:00:59 +00:00
if ( ! name_status_find ( " * " , 0 , 0 , rem_ip , server ) ) {
2001-02-26 11:53:22 +00:00
2001-11-21 05:19:13 +00:00
DEBUG ( 0 , ( " Could not get the name of local master browser for server %s \n " , server ) ) ;
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-19 05:50:09 +00:00
2001-11-21 03:55:59 +00:00
/*
* Get a connection to IPC $ on the server if we do not already have one
*/
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , " IPC$ " , workgroup , user , password ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > srv = srv ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the stuff ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_NetServerEnum ( & srv - > cli , workgroup , 0x80000000 , list_fn ,
( void * ) smbc_file_table [ slot ] ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
errno = cli_errno ( & srv - > cli ) ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
}
else { /* Server not an empty string ... Check the rest and see what gives */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( share [ 0 ] = = ( char ) 0 ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( path [ 0 ] ! = ( char ) 0 ) { /* Should not have empty share with path */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Check to see if <server><1D> translates, or <server><20> translates */
/* However, we check to see if <server> is an IP address first */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! is_ipaddress ( server ) & & /* Not an IP addr so check next */
resolve_name ( server , & rem_ip , 0x1d ) ) { /* Found LMB */
pstring buserver ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > dir_type = SMBC_SERVER ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Get the backup list . . .
*/
2001-01-05 13:43:19 +00:00
2001-02-19 05:50:09 +00:00
2001-11-21 23:00:59 +00:00
if ( ! name_status_find ( " * " , 0 , 0 , rem_ip , buserver ) ) {
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 0 , ( " Could not get name of local master browser %s \n " , server ) ) ;
errno = EPERM ; /* FIXME, is this correct */
return - 1 ;
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Get a connection to IPC $ on the server if we do not already have one
*/
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( buserver , " IPC$ " , workgroup , user , password ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > srv = srv ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the servers ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_NetServerEnum ( & srv - > cli , server , 0x0000FFFE , list_fn ,
( void * ) smbc_file_table [ slot ] ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
errno = cli_errno ( & srv - > cli ) ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( resolve_name ( server , & rem_ip , 0x20 ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the shares ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > dir_type = SMBC_FILE_SHARE ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , " IPC$ " , workgroup , user , password ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > srv = srv ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the servers ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( cli_RNetShareEnum ( & srv - > cli , list_fn ,
( void * ) smbc_file_table [ slot ] ) < 0 ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = cli_errno ( & srv - > cli ) ;
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENODEV ; /* Neither the workgroup nor server exists */
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
else { /* The server and share are specified ... work from there ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Well, we connect to the server and list the directory */
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > dir_type = SMBC_FILE_SHARE ;
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
return - 1 ;
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ slot ] - > srv = srv ;
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the files ... */
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
pstrcat ( path , " \\ * " ) ;
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( cli_list ( & srv - > cli , path , aDIR | aSYSTEM | aHIDDEN , dir_list_fn ,
( void * ) smbc_file_table [ slot ] ) < 0 ) {
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_file_table [ slot ] ) {
SAFE_FREE ( smbc_file_table [ slot ] - > fname ) ;
SAFE_FREE ( smbc_file_table [ slot ] ) ;
}
errno = smbc_errno ( & srv - > cli ) ;
return - 1 ;
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
return smbc_file_table [ slot ] - > smbc_fd ;
2001-01-05 13:43:19 +00:00
}
2000-12-26 05:57:10 +00:00
/*
* Routine to close a directory
*/
int smbc_closedir ( int fd )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
smbc_remove_dir ( fe ) ; /* Clean it up */
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fe ) {
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( fe - > fname ) ;
SAFE_FREE ( fe ) ; /* Free the space too */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
smbc_file_table [ fd - smbc_start_fd ] = NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to get a directory entry
*/
2001-01-12 05:10:45 +00:00
static char smbc_local_dirent [ 512 ] ; /* Make big enough */
struct smbc_dirent * smbc_readdir ( unsigned int fd )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
struct smbc_dirent * dirp , * dirent ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
/* Check that all is ok first ... */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return NULL ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return NULL ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return NULL ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( fe - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
return NULL ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe - > dir_next )
return NULL ;
else {
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
dirent = fe - > dir_next - > dirent ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
if ( ! dirent ) {
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOENT ;
return NULL ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
/* Hmmm, do I even need to copy it? */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
bcopy ( dirent , smbc_local_dirent , dirent - > dirlen ) ; /* Copy the dirent */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
dirp = ( struct smbc_dirent * ) smbc_local_dirent ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
dirp - > comment = ( char * ) ( & dirp - > name + dirent - > namelen + 1 ) ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
fe - > dir_next = fe - > dir_next - > next ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
return ( struct smbc_dirent * ) smbc_local_dirent ;
}
2001-01-12 05:10:45 +00:00
}
/*
* Routine to get directory entries
*/
2001-01-05 13:43:19 +00:00
int smbc_getdents ( unsigned int fd , struct smbc_dirent * dirp , int count )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
struct smbc_dir_list * dir ;
int rem = count , reqd ;
char * ndir = ( char * ) dirp ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check that all is ok first ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( fe - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Now , retrieve the number of entries that will fit in what was passed
* We have to figure out if the info is in the list , or we need to
* send a request to the server to get the info .
*/
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
while ( ( dir = fe - > dir_next ) ) {
struct smbc_dirent * dirent ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! dir - > dirent ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOENT ; /* Bad error */
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( rem < ( reqd = ( sizeof ( struct smbc_dirent ) + dir - > dirent - > namelen +
dir - > dirent - > commentlen + 1 ) ) ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( rem < count ) { /* We managed to copy something */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = 0 ;
return count - rem ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
else { /* Nothing copied ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Not enough space ... */
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dirent = dir - > dirent ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
bcopy ( dirent , ndir , reqd ) ; /* Copy the data in ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
( ( struct smbc_dirent * ) ndir ) - > comment =
( char * ) ( & ( ( struct smbc_dirent * ) ndir ) - > name + dirent - > namelen + 1 ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
ndir + = reqd ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
rem - = reqd ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
fe - > dir_next = dir = dir - > next ;
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( rem = = count )
return 0 ;
else
return count - rem ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to create a directory . . .
*/
int smbc_mkdir ( const char * fname , mode_t mode )
{
2001-11-21 03:55:59 +00:00
struct smbc_server * srv ;
fstring server , share , user , password , workgroup ;
pstring path ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_mkdir(%s) \n " , fname ) ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /*FIXME, errors*/
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
/* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
mode = aDIR | aRONLY ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
else if ( strncmp ( srv - > cli . dev , " LPT " , 3 ) = = 0 ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( strcmp ( path , " \\ " ) = = 0 ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
mode = aDIR | aRONLY ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
mode = aRONLY ;
smbc_stat_printjob ( srv , path , & size , & m_time ) ;
c_time = a_time = m_time ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
else { */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_mkdir ( & srv - > cli , path ) ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & srv - > cli ) ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2001-01-12 12:48:55 +00:00
}
2001-03-27 12:13:59 +00:00
/*
* Our list function simply checks to see if a directory is not empty
*/
static int smbc_rmdir_dirempty = True ;
static void rmdir_list_fn ( file_info * finfo , const char * mask , void * state )
{
2001-11-21 03:55:59 +00:00
if ( strncmp ( finfo - > name , " . " , 1 ) ! = 0 & & strncmp ( finfo - > name , " .. " , 2 ) ! = 0 )
smbc_rmdir_dirempty = False ;
2001-03-27 12:13:59 +00:00
}
2001-01-12 12:48:55 +00:00
/*
* Routine to remove a directory
*/
int smbc_rmdir ( const char * fname )
{
2001-11-21 03:55:59 +00:00
struct smbc_server * srv ;
fstring server , share , user , password , workgroup ;
pstring path ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_rmdir(%s) \n " , fname ) ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /*FIXME, errors*/
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
/* if (strncmp(srv->cli.dev, "IPC", 3) == 0) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
mode = aDIR | aRONLY ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
else if ( strncmp ( srv - > cli . dev , " LPT " , 3 ) = = 0 ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( strcmp ( path , " \\ " ) = = 0 ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
mode = aDIR | aRONLY ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
mode = aRONLY ;
smbc_stat_printjob ( srv , path , & size , & m_time ) ;
c_time = a_time = m_time ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
else { */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! cli_rmdir ( & srv - > cli , path ) ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & srv - > cli ) ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( errno = = EACCES ) { /* Check if the dir empty or not */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
pstring lpath ; /* Local storage to avoid buffer overflows */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
smbc_rmdir_dirempty = True ; /* Make this so ... */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( lpath , path ) ;
pstrcat ( lpath , " \\ * " ) ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( cli_list ( & srv - > cli , lpath , aDIR | aSYSTEM | aHIDDEN , rmdir_list_fn ,
NULL ) < 0 ) {
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
/* Fix errno to ignore latest error ... */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 5 , ( " smbc_rmdir: cli_list returned an error: %d \n " ,
smbc_errno ( & srv - > cli ) ) ) ;
errno = EACCES ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_rmdir_dirempty )
errno = EACCES ;
else
errno = ENOTEMPTY ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2001-01-07 07:10:50 +00:00
2000-12-26 05:57:10 +00:00
}
2001-01-12 12:48:55 +00:00
/*
* Routine to return the current directory position
*/
off_t smbc_telldir ( int fd )
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( fe - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
return ( off_t ) fe - > dir_next ;
2001-01-12 12:48:55 +00:00
}
2001-03-06 14:00:48 +00:00
/*
* A routine to run down the list and see if the entry is OK
*/
struct smbc_dir_list * smbc_check_dir_ent ( struct smbc_dir_list * list ,
struct smbc_dirent * dirent )
{
2001-11-21 03:55:59 +00:00
/* Run down the list looking for what we want */
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
if ( dirent ) {
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
struct smbc_dir_list * tmp = list ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
while ( tmp ) {
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
if ( tmp - > dirent = = dirent )
return tmp ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
tmp = tmp - > next ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
return NULL ; /* Not found, or an error */
2001-03-06 14:00:48 +00:00
}
2000-12-26 05:57:10 +00:00
/*
* Routine to seek on a directory
*/
2001-03-07 04:39:31 +00:00
int smbc_lseekdir ( int fd , off_t offset )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
struct smbc_file * fe ;
struct smbc_dirent * dirent = ( struct smbc_dirent * ) offset ;
struct smbc_dir_list * list_ent = NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( fd < smbc_start_fd | | fd > = ( smbc_start_fd + SMBC_MAX_FD ) ) {
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
fe = smbc_file_table [ fd - smbc_start_fd ] ;
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fe ) {
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
return - 1 ;
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
if ( fe - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
return - 1 ;
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
/* Now, check what we were passed and see if it is OK ... */
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
if ( dirent = = NULL ) { /* Seek to the begining of the list */
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
fe - > dir_next = fe - > dir_list ;
return 0 ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
/* Now, run down the list and make sure that the entry is OK */
/* This may need to be changed if we change the format of the list */
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
if ( ( list_ent = smbc_check_dir_ent ( fe - > dir_list , dirent ) ) = = NULL ) {
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Bad entry */
return - 1 ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
fe - > dir_next = list_ent ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to fstat a dir
*/
int smbc_fstatdir ( int fd , struct stat * st )
{
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
/* No code yet ... */
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
2001-02-05 13:02:20 +00:00
}
/*
* Routine to print a file on a remote server . . .
*
* We open the file , which we assume to be on a remote server , and then
* copy it to a print file on the share specified by printq .
*/
int smbc_print_file ( const char * fname , const char * printq )
{
2001-11-21 03:55:59 +00:00
int fid1 , fid2 , bytes , saverr , tot_bytes = 0 ;
char buf [ 4096 ] ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname & & ! printq ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
/* Try to open the file for reading ... */
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ( fid1 = smbc_open ( fname , O_RDONLY , 0666 ) ) < 0 ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 3 , ( " Error, fname=%s, errno=%i \n " , fname , errno ) ) ;
return - 1 ; /* smbc_open sets errno */
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
/* Now, try to open the printer file for writing */
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ( fid2 = smbc_open_print_job ( printq ) ) < 0 ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
saverr = errno ; /* Save errno */
smbc_close ( fid1 ) ;
errno = saverr ;
return - 1 ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
while ( ( bytes = smbc_read ( fid1 , buf , sizeof ( buf ) ) ) > 0 ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
tot_bytes + = bytes ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ( smbc_write ( fid2 , buf , bytes ) ) < 0 ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
saverr = errno ;
smbc_close ( fid1 ) ;
smbc_close ( fid2 ) ;
errno = saverr ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
saverr = errno ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
smbc_close ( fid1 ) ; /* We have to close these anyway */
smbc_close ( fid2 ) ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( bytes < 0 ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
errno = saverr ;
return - 1 ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
return tot_bytes ;
2001-02-06 19:25:12 +00:00
}
/*
* Open a print file to be written to by other calls
*/
int smbc_open_print_job ( const char * fname )
{
2001-11-21 03:55:59 +00:00
fstring server , share , user , password ;
pstring path ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_open_print_job(%s) \n " , fname ) ) ;
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /*FIXME, errors*/
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
/* What if the path is empty, or the file exists? */
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
return smbc_open ( fname , O_WRONLY , 666 ) ;
2001-02-05 13:02:20 +00:00
2000-12-26 05:57:10 +00:00
}
2001-02-04 19:48:26 +00:00
/*
* Routine to list print jobs on a printer share . . .
*/
int smbc_list_print_jobs ( const char * fname , void ( * fn ) ( struct print_job_info * ) )
{
2001-11-21 03:55:59 +00:00
struct smbc_server * srv ;
fstring server , share , user , password , workgroup ;
pstring path ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_list_print_jobs(%s) \n " , fname ) ) ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /*FIXME, errors*/
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
if ( cli_print_queue ( & srv - > cli , fn ) < 0 ) {
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
errno = smbc_errno ( & srv - > cli ) ;
return - 1 ;
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-04 19:48:26 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2001-02-04 19:48:26 +00:00
}
2001-02-05 13:02:20 +00:00
/*
* Delete a print job from a remote printer share
*/
int smbc_unlink_print_job ( const char * fname , int id )
{
2001-11-21 03:55:59 +00:00
struct smbc_server * srv ;
fstring server , share , user , password , workgroup ;
pstring path ;
int err ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( ! smbc_initialized ) {
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_unlink_print_job(%s) \n " , fname ) ) ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
smbc_parse_path ( fname , server , share , path , user , password ) ; /*FIXME, errors*/
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( user [ 0 ] = = ( char ) 0 ) pstrcpy ( user , smbc_user ) ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
2001-11-17 07:30:19 +00:00
2001-11-21 03:55:59 +00:00
srv = smbc_server ( server , share , workgroup , user , password ) ;
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( ( err = cli_printjob_del ( & srv - > cli , id ) ) ! = 0 ) {
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
if ( err < 0 )
errno = smbc_errno ( & srv - > cli ) ;
else if ( err = = ERRnosuchprintjob )
errno = EINVAL ;
return - 1 ;
2001-02-05 13:02:20 +00:00
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-05 13:02:20 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2001-02-05 13:02:20 +00:00
}