1998-10-19 05:03:00 +04:00
/*
Unix SMB / Netbios implementation .
Version 2.0
SMB wrapper functions - shared variables
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"
extern int DEBUGLEVEL ;
static int shared_fd ;
static char * variables ;
static int shared_size ;
/*****************************************************
setup the shared area
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void smbw_setup_shared ( void )
{
int fd ;
2001-04-16 06:42:10 +04:00
pstring name , s ;
1998-10-19 05:03:00 +04:00
2001-04-12 03:19:08 +04:00
slprintf ( name , sizeof ( name ) - 1 , " %s/smbw.XXXXXX " , tmpdir ( ) ) ;
1998-10-19 05:03:00 +04:00
2001-04-12 03:19:08 +04:00
fd = smb_mkstemp ( name ) ;
1998-10-19 05:03:00 +04:00
if ( fd = = - 1 ) goto failed ;
2001-04-12 03:19:08 +04:00
1998-10-19 06:49:48 +04:00
unlink ( name ) ;
1998-10-19 05:03:00 +04:00
shared_fd = set_maxfiles ( SMBW_MAX_OPEN ) ;
while ( shared_fd & & dup2 ( fd , shared_fd ) ! = shared_fd ) shared_fd - - ;
if ( shared_fd = = 0 ) goto failed ;
close ( fd ) ;
DEBUG ( 4 , ( " created shared_fd=%d \n " , shared_fd ) ) ;
slprintf ( s , sizeof ( s ) - 1 , " %d " , shared_fd ) ;
1998-10-20 10:45:18 +04:00
smbw_setenv ( " SMBW_HANDLE " , s ) ;
1998-10-19 05:03:00 +04:00
return ;
failed :
perror ( " Failed to setup shared variable area " ) ;
exit ( 1 ) ;
}
1998-10-23 05:26:46 +04:00
static int locked ;
1998-10-19 05:03:00 +04:00
/*****************************************************
lock the shared variable area
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void lockit ( void )
{
if ( shared_fd = = 0 ) {
char * p = getenv ( " SMBW_HANDLE " ) ;
if ( ! p ) {
DEBUG ( 0 , ( " ERROR: can't get smbw shared handle \n " ) ) ;
exit ( 1 ) ;
}
shared_fd = atoi ( p ) ;
}
1998-10-23 05:26:46 +04:00
if ( locked = = 0 & &
fcntl_lock ( shared_fd , SMB_F_SETLKW , 0 , 1 , F_WRLCK ) = = False ) {
1998-11-21 04:26:45 +03:00
DEBUG ( 0 , ( " ERROR: can't get smbw shared lock (%s) \n " , strerror ( errno ) ) ) ;
1998-10-19 05:03:00 +04:00
exit ( 1 ) ;
}
1998-10-23 05:26:46 +04:00
locked + + ;
1998-10-19 05:03:00 +04:00
}
/*****************************************************
unlock the shared variable area
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void unlockit ( void )
{
1998-10-23 05:26:46 +04:00
locked - - ;
if ( locked = = 0 ) {
fcntl_lock ( shared_fd , SMB_F_SETLK , 0 , 1 , F_UNLCK ) ;
}
1998-10-19 05:03:00 +04:00
}
/*****************************************************
get a variable from the shared area
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * smbw_getshared ( const char * name )
{
int i ;
struct stat st ;
lockit ( ) ;
/* maybe the area has changed */
if ( fstat ( shared_fd , & st ) ) goto failed ;
if ( st . st_size ! = shared_size ) {
variables = ( char * ) Realloc ( variables , st . st_size ) ;
if ( ! variables ) goto failed ;
shared_size = st . st_size ;
lseek ( shared_fd , 0 , SEEK_SET ) ;
if ( read ( shared_fd , variables , shared_size ) ! = shared_size ) {
goto failed ;
}
}
unlockit ( ) ;
i = 0 ;
while ( i < shared_size ) {
char * n , * v ;
1998-10-23 05:26:46 +04:00
int l1 , l2 ;
l1 = SVAL ( & variables [ i ] , 0 ) ;
l2 = SVAL ( & variables [ i ] , 2 ) ;
1998-10-19 05:03:00 +04:00
1998-10-23 05:26:46 +04:00
n = & variables [ i + 4 ] ;
v = & variables [ i + 4 + l1 ] ;
i + = 4 + l1 + l2 ;
1998-10-19 05:03:00 +04:00
if ( strcmp ( name , n ) ) {
continue ;
}
return v ;
}
return NULL ;
failed :
DEBUG ( 0 , ( " smbw: shared variables corrupt (%s) \n " , strerror ( errno ) ) ) ;
exit ( 1 ) ;
1998-10-20 10:51:21 +04:00
return NULL ;
1998-10-19 05:03:00 +04:00
}
/*****************************************************
set a variable in the shared area
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void smbw_setshared ( const char * name , const char * val )
{
1998-10-23 05:26:46 +04:00
int l1 , l2 ;
1998-10-19 05:03:00 +04:00
/* we don't allow variable overwrite */
if ( smbw_getshared ( name ) ) return ;
lockit ( ) ;
1998-10-23 05:26:46 +04:00
l1 = strlen ( name ) + 1 ;
l2 = strlen ( val ) + 1 ;
1998-10-19 05:03:00 +04:00
1998-10-23 05:26:46 +04:00
variables = ( char * ) Realloc ( variables , shared_size + l1 + l2 + 4 ) ;
1998-10-19 05:03:00 +04:00
if ( ! variables ) {
DEBUG ( 0 , ( " out of memory in smbw_setshared \n " ) ) ;
exit ( 1 ) ;
}
1998-10-23 05:26:46 +04:00
SSVAL ( & variables [ shared_size ] , 0 , l1 ) ;
SSVAL ( & variables [ shared_size ] , 2 , l2 ) ;
pstrcpy ( & variables [ shared_size ] + 4 , name ) ;
pstrcpy ( & variables [ shared_size ] + 4 + l1 , val ) ;
shared_size + = l1 + l2 + 4 ;
1998-10-19 05:03:00 +04:00
lseek ( shared_fd , 0 , SEEK_SET ) ;
if ( write ( shared_fd , variables , shared_size ) ! = shared_size ) {
DEBUG ( 0 , ( " smbw_setshared failed (%s) \n " , strerror ( errno ) ) ) ;
exit ( 1 ) ;
}
unlockit ( ) ;
}
1998-10-20 10:45:18 +04:00
/*****************************************************************
set an env variable - some systems don ' t have this
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_setenv ( const char * name , const char * value )
{
pstring s ;
1998-10-20 10:51:21 +04:00
char * p ;
1998-10-20 10:52:39 +04:00
int ret = - 1 ;
1998-10-20 10:45:18 +04:00
slprintf ( s , sizeof ( s ) - 1 , " %s=%s " , name , value ) ;
1998-10-20 10:51:21 +04:00
p = strdup ( s ) ;
1998-10-20 10:52:39 +04:00
if ( p ) ret = putenv ( p ) ;
1998-10-20 10:51:21 +04:00
1998-10-20 10:52:39 +04:00
return ret ;
1998-10-20 10:45:18 +04:00
}
1998-10-24 10:36:22 +04:00
/*****************************************************************
return true if the passed fd is the SMBW_HANDLE
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int smbw_shared_fd ( int fd )
{
return ( shared_fd & & shared_fd = = fd ) ;
}