1999-12-21 06:05:38 +03:00
# define NBDEBUG 0
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1999-12-21 06:05:38 +03:00
SMB torture tester
Copyright ( C ) Andrew Tridgell 1997 - 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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1999-12-21 06:05:38 +03:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1999-12-21 06:05:38 +03:00
*/
# include "includes.h"
# define MAX_FILES 1000
static char buf [ 70000 ] ;
extern int line_count ;
2002-02-05 04:31:47 +03:00
extern int nbio_id ;
static int nprocs ;
1999-12-21 06:05:38 +03:00
static struct {
int fd ;
int handle ;
} ftable [ MAX_FILES ] ;
2006-08-01 16:45:12 +04:00
static struct children {
2002-02-05 04:31:47 +03:00
double bytes_in , bytes_out ;
int line ;
2002-02-05 06:55:20 +03:00
int done ;
2002-02-05 04:31:47 +03:00
} * children ;
double nbio_total ( void )
{
int i ;
double total = 0 ;
for ( i = 0 ; i < nprocs ; i + + ) {
total + = children [ i ] . bytes_out + children [ i ] . bytes_in ;
}
return total ;
}
2003-12-02 14:36:02 +03:00
void nb_alarm ( int ignore )
2002-02-05 04:31:47 +03:00
{
int i ;
2002-02-05 06:55:20 +03:00
int lines = 0 , num_clients = 0 ;
2002-02-05 04:31:47 +03:00
if ( nbio_id ! = - 1 ) return ;
for ( i = 0 ; i < nprocs ; i + + ) {
lines + = children [ i ] . line ;
2002-02-05 06:55:20 +03:00
if ( ! children [ i ] . done ) num_clients + + ;
2002-02-05 04:31:47 +03:00
}
2002-02-05 06:55:20 +03:00
printf ( " %4d %8d %.2f MB/sec \r " , num_clients , lines / nprocs , 1.0e-6 * nbio_total ( ) / end_timer ( ) ) ;
2002-02-05 04:31:47 +03:00
signal ( SIGALRM , nb_alarm ) ;
alarm ( 1 ) ;
}
void nbio_shmem ( int n )
{
nprocs = n ;
2006-08-01 16:45:12 +04:00
children = ( struct children * ) shm_setup ( sizeof ( * children ) * nprocs ) ;
2002-02-05 04:31:47 +03:00
if ( ! children ) {
printf ( " Failed to setup shared memory! \n " ) ;
exit ( 1 ) ;
}
}
2003-12-02 14:36:02 +03:00
#if 0
2002-07-15 14:35:28 +04:00
static int ne_find_handle ( int handle )
{
int i ;
children [ nbio_id ] . line = line_count ;
for ( i = 0 ; i < MAX_FILES ; i + + ) {
if ( ftable [ i ] . handle = = handle ) return i ;
}
return - 1 ;
}
2003-12-02 14:36:02 +03:00
# endif
2002-07-15 14:35:28 +04:00
2002-02-05 04:31:47 +03:00
static int find_handle ( int handle )
{
int i ;
children [ nbio_id ] . line = line_count ;
for ( i = 0 ; i < MAX_FILES ; i + + ) {
if ( ftable [ i ] . handle = = handle ) return i ;
}
2002-03-05 22:51:05 +03:00
printf ( " (%d) ERROR: handle %d was not found \n " ,
2002-02-05 04:31:47 +03:00
line_count , handle ) ;
exit ( 1 ) ;
2002-04-05 02:56:39 +04:00
return - 1 ; /* Not reached */
2002-02-05 04:31:47 +03:00
}
1999-12-21 06:05:38 +03:00
static struct cli_state * c ;
static void sigsegv ( int sig )
{
char line [ 200 ] ;
printf ( " segv at line %d \n " , line_count ) ;
slprintf ( line , sizeof ( line ) , " /usr/X11R6/bin/xterm -e gdb /proc/%d/exe %d " ,
2000-01-14 11:33:20 +03:00
( int ) getpid ( ) , ( int ) getpid ( ) ) ;
1999-12-21 06:05:38 +03:00
system ( line ) ;
exit ( 1 ) ;
}
void nb_setup ( struct cli_state * cli )
{
signal ( SIGSEGV , sigsegv ) ;
c = cli ;
2002-02-05 04:31:47 +03:00
start_timer ( ) ;
2002-02-05 06:55:20 +03:00
children [ nbio_id ] . done = 0 ;
1999-12-21 06:05:38 +03:00
}
2003-04-23 12:12:34 +04:00
void nb_unlink ( const char * fname )
1999-12-21 06:05:38 +03:00
{
if ( ! cli_unlink ( c , fname ) ) {
# if NBDEBUG
printf ( " (%d) unlink %s failed (%s) \n " ,
line_count , fname , cli_errstr ( c ) ) ;
# endif
}
}
2002-02-05 04:31:47 +03:00
2003-04-23 12:12:34 +04:00
void nb_createx ( const char * fname ,
2002-02-05 04:31:47 +03:00
unsigned create_options , unsigned create_disposition , int handle )
1999-12-21 06:05:38 +03:00
{
int fd , i ;
2002-03-05 22:51:05 +03:00
uint32 desired_access ;
if ( create_options & FILE_DIRECTORY_FILE ) {
desired_access = FILE_READ_DATA ;
} else {
desired_access = FILE_READ_DATA | FILE_WRITE_DATA ;
}
1999-12-21 06:05:38 +03:00
2003-04-15 23:51:17 +04:00
fd = cli_nt_create_full ( c , fname , 0 ,
2002-03-05 22:51:05 +03:00
desired_access ,
0x0 ,
2002-02-05 04:31:47 +03:00
FILE_SHARE_READ | FILE_SHARE_WRITE ,
create_disposition ,
2003-04-15 23:51:17 +04:00
create_options , 0 ) ;
2002-02-05 04:31:47 +03:00
if ( fd = = - 1 & & handle ! = - 1 ) {
printf ( " ERROR: cli_nt_create_full failed for %s - %s \n " ,
fname , cli_errstr ( c ) ) ;
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 04:31:47 +03:00
if ( fd ! = - 1 & & handle = = - 1 ) {
printf ( " ERROR: cli_nt_create_full succeeded for %s \n " , fname ) ;
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 04:31:47 +03:00
if ( fd = = - 1 ) return ;
1999-12-21 06:05:38 +03:00
for ( i = 0 ; i < MAX_FILES ; i + + ) {
if ( ftable [ i ] . handle = = 0 ) break ;
}
if ( i = = MAX_FILES ) {
2002-02-05 04:31:47 +03:00
printf ( " (%d) file table full for %s \n " , line_count ,
fname ) ;
1999-12-21 06:05:38 +03:00
exit ( 1 ) ;
}
ftable [ i ] . handle = handle ;
ftable [ i ] . fd = fd ;
}
2002-02-05 04:31:47 +03:00
void nb_writex ( int handle , int offset , int size , int ret_size )
1999-12-21 06:05:38 +03:00
{
int i ;
if ( buf [ 0 ] = = 0 ) memset ( buf , 1 , sizeof ( buf ) ) ;
2002-02-05 04:31:47 +03:00
i = find_handle ( handle ) ;
if ( cli_write ( c , ftable [ i ] . fd , 0 , buf , offset , size ) ! = ret_size ) {
printf ( " (%d) ERROR: write failed on handle %d, fd %d \
2001-03-27 04:28:01 +04:00
errno % d ( % s ) \ n " , line_count, handle, ftable[i].fd, errno, strerror(errno));
2002-02-05 04:31:47 +03:00
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 04:31:47 +03:00
children [ nbio_id ] . bytes_out + = ret_size ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 04:31:47 +03:00
void nb_readx ( int handle , int offset , int size , int ret_size )
1999-12-21 06:05:38 +03:00
{
int i , ret ;
2002-02-05 04:31:47 +03:00
i = find_handle ( handle ) ;
if ( ( ret = cli_read ( c , ftable [ i ] . fd , buf , offset , size ) ) ! = ret_size ) {
printf ( " (%d) ERROR: read failed on handle %d ofs=%d size=%d res=%d fd %d errno %d (%s) \n " ,
2001-03-27 04:28:01 +04:00
line_count , handle , offset , size , ret , ftable [ i ] . fd , errno , strerror ( errno ) ) ;
2002-02-05 04:31:47 +03:00
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 04:31:47 +03:00
children [ nbio_id ] . bytes_in + = ret_size ;
1999-12-21 06:05:38 +03:00
}
void nb_close ( int handle )
{
int i ;
2002-02-05 04:31:47 +03:00
i = find_handle ( handle ) ;
if ( ! cli_close ( c , ftable [ i ] . fd ) ) {
printf ( " (%d) close failed on handle %d \n " , line_count , handle ) ;
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
ftable [ i ] . handle = 0 ;
}
2003-04-23 12:12:34 +04:00
void nb_rmdir ( const char * fname )
1999-12-21 06:05:38 +03:00
{
if ( ! cli_rmdir ( c , fname ) ) {
2002-02-05 04:31:47 +03:00
printf ( " ERROR: rmdir %s failed (%s) \n " ,
1999-12-21 06:05:38 +03:00
fname , cli_errstr ( c ) ) ;
2002-02-05 04:31:47 +03:00
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
}
2005-06-25 00:25:18 +04:00
void nb_rename ( const char * oldname , const char * newname )
1999-12-21 06:05:38 +03:00
{
2005-06-25 00:25:18 +04:00
if ( ! cli_rename ( c , oldname , newname ) ) {
2002-02-05 04:31:47 +03:00
printf ( " ERROR: rename %s %s failed (%s) \n " ,
2005-06-25 13:07:42 +04:00
oldname , newname , cli_errstr ( c ) ) ;
2002-02-05 04:31:47 +03:00
exit ( 1 ) ;
1999-12-21 06:05:38 +03:00
}
}
2003-04-23 12:12:34 +04:00
void nb_qpathinfo ( const char * fname )
2002-02-05 04:31:47 +03:00
{
cli_qpathinfo ( c , fname , NULL , NULL , NULL , NULL , NULL ) ;
}
void nb_qfileinfo ( int fnum )
{
int i ;
i = find_handle ( fnum ) ;
cli_qfileinfo ( c , ftable [ i ] . fd , NULL , NULL , NULL , NULL , NULL , NULL , NULL ) ;
}
void nb_qfsinfo ( int level )
1999-12-21 06:05:38 +03:00
{
2002-02-05 04:31:47 +03:00
int bsize , total , avail ;
/* this is not the right call - we need cli_qfsinfo() */
cli_dskattr ( c , & bsize , & total , & avail ) ;
}
1999-12-21 06:05:38 +03:00
2005-03-11 19:13:46 +03:00
static void find_fn ( const char * mnt , file_info * finfo , const char * name , void * state )
2002-02-05 04:31:47 +03:00
{
/* noop */
}
1999-12-21 06:05:38 +03:00
2003-04-23 12:12:34 +04:00
void nb_findfirst ( const char * mask )
2002-02-05 04:31:47 +03:00
{
cli_list ( c , mask , 0 , find_fn , NULL ) ;
}
void nb_flush ( int fnum )
{
int i ;
i = find_handle ( fnum ) ;
/* hmmm, we don't have cli_flush() yet */
}
static int total_deleted ;
2005-03-11 19:13:46 +03:00
static void delete_fn ( const char * mnt , file_info * finfo , const char * name , void * state )
2002-02-05 04:31:47 +03:00
{
char * s , * n ;
if ( finfo - > name [ 0 ] = = ' . ' ) return ;
2005-05-07 10:59:00 +04:00
n = SMB_STRDUP ( name ) ;
2002-02-05 04:31:47 +03:00
n [ strlen ( n ) - 1 ] = 0 ;
asprintf ( & s , " %s%s " , n , finfo - > name ) ;
if ( finfo - > mode & aDIR ) {
2002-02-05 06:55:20 +03:00
char * s2 ;
asprintf ( & s2 , " %s \\ * " , s ) ;
cli_list ( c , s2 , aDIR , delete_fn , NULL ) ;
nb_rmdir ( s ) ;
2002-02-05 04:31:47 +03:00
} else {
total_deleted + + ;
nb_unlink ( s ) ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 04:31:47 +03:00
free ( s ) ;
free ( n ) ;
1999-12-21 06:05:38 +03:00
}
2003-04-23 12:12:34 +04:00
void nb_deltree ( const char * dname )
1999-12-21 06:05:38 +03:00
{
2002-02-05 04:31:47 +03:00
char * mask ;
asprintf ( & mask , " %s \\ * " , dname ) ;
total_deleted = 0 ;
cli_list ( c , mask , aDIR , delete_fn , NULL ) ;
free ( mask ) ;
2002-02-05 06:02:14 +03:00
cli_rmdir ( c , dname ) ;
2002-02-05 04:31:47 +03:00
if ( total_deleted ) printf ( " WARNING: Cleaned up %d files \n " , total_deleted ) ;
1999-12-21 06:05:38 +03:00
}
2002-02-05 06:55:20 +03:00
void nb_cleanup ( void )
{
cli_rmdir ( c , " clients " ) ;
children [ nbio_id ] . done = 1 ;
}