1996-05-04 11:50:46 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
SMB client
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
1996-05-04 11:50:46 +04:00
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 .
*/
# ifdef SYSLOG
# undef SYSLOG
# endif
# include "includes.h"
# ifndef REGISTER
# define REGISTER 0
# endif
pstring cur_dir = " \\ " ;
pstring cd_path = " " ;
1997-10-22 18:28:19 +04:00
extern pstring service ;
extern pstring desthost ;
1998-04-25 05:12:08 +04:00
extern pstring global_myname ;
1997-09-06 01:32:32 +04:00
extern pstring myhostname ;
1997-10-22 18:28:19 +04:00
extern pstring password ;
extern pstring username ;
extern pstring workgroup ;
1996-05-31 19:13:29 +04:00
char * cmdstr = " " ;
1997-10-22 18:28:19 +04:00
extern BOOL got_pass ;
1998-02-26 23:41:05 +03:00
extern BOOL no_pass ;
1997-10-22 18:28:19 +04:00
extern BOOL connect_as_printer ;
extern BOOL connect_as_ipc ;
1996-06-06 15:43:09 +04:00
extern struct in_addr ipzero ;
1996-05-04 11:50:46 +04:00
1997-10-22 18:28:19 +04:00
extern BOOL doencrypt ;
1996-05-04 11:50:46 +04:00
extern pstring user_socket_options ;
/* 30 second timeout on most commands */
# define CLIENT_TIMEOUT (30*1000)
# define SHORT_TIMEOUT (5*1000)
/* value for unused fid field in trans2 secondary request */
# define FID_UNUSED (0xFFFF)
1997-10-22 18:28:19 +04:00
extern int name_type ;
1996-05-04 11:50:46 +04:00
1997-10-22 18:28:19 +04:00
extern int max_protocol ;
1996-05-04 11:50:46 +04:00
time_t newer_than = 0 ;
int archive_level = 0 ;
extern pstring debugf ;
extern int DEBUGLEVEL ;
BOOL translation = False ;
1997-10-22 18:28:19 +04:00
extern int cnum ;
extern int mid ;
extern int pid ;
extern int tid ;
extern int gid ;
extern int uid ;
extern BOOL have_ip ;
extern int max_xmit ;
1996-06-04 10:42:03 +04:00
static int interpret_long_filename ( int level , char * p , file_info * finfo ) ;
1998-04-13 23:24:06 +04:00
static void dir_action ( char * inbuf , char * outbuf , int attribute , file_info * finfo , BOOL recurse_dir , void ( * fn ) ( file_info * ) , BOOL longdir , BOOL dirstoo ) ;
1996-06-04 10:42:03 +04:00
static int interpret_short_filename ( char * p , file_info * finfo ) ;
1997-07-28 22:59:57 +04:00
static BOOL do_this_one ( file_info * finfo ) ;
1996-06-04 10:42:03 +04:00
1996-05-04 11:50:46 +04:00
/* clitar bits insert */
extern int blocksize ;
extern BOOL tar_inc ;
extern BOOL tar_reset ;
/* clitar bits end */
int myumask = 0755 ;
extern pstring scope ;
BOOL prompt = True ;
int printmode = 1 ;
BOOL recurse = False ;
BOOL lowercase = False ;
struct in_addr dest_ip ;
# define SEPARATORS " \t\n\r"
BOOL abort_mget = True ;
extern int Protocol ;
1997-10-22 18:28:19 +04:00
extern BOOL readbraw_supported ;
extern BOOL writebraw_supported ;
1996-05-04 11:50:46 +04:00
pstring fileselection = " " ;
extern file_info def_finfo ;
/* timing globals */
int get_total_size = 0 ;
int get_total_time_ms = 0 ;
int put_total_size = 0 ;
int put_total_time_ms = 0 ;
1997-07-28 22:59:57 +04:00
/* totals globals */
int dir_total = 0 ;
1996-05-04 11:50:46 +04:00
extern int Client ;
# define USENMB
1998-03-03 23:19:14 +03:00
# define CNV_LANG(s) dos_to_unix(s,False)
# define CNV_INPUT(s) unix_to_dos(s,True)
1996-05-04 11:50:46 +04:00
1997-10-23 17:38:46 +04:00
/****************************************************************************
send an SMBclose on an SMB file handle
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1997-10-24 17:15:34 +04:00
void cli_smb_close ( char * inbuf , char * outbuf , int clnt_fd , int c_num , int f_num )
1997-10-23 17:38:46 +04:00
{
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 3 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBclose ;
SSVAL ( outbuf , smb_tid , c_num ) ;
cli_setup_pkt ( outbuf ) ;
SSVAL ( outbuf , smb_vwv0 , f_num ) ;
SIVALS ( outbuf , smb_vwv1 , - 1 ) ;
send_smb ( clnt_fd , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( clnt_fd , inbuf , CLIENT_TIMEOUT ) ;
1997-10-23 17:38:46 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
write to a local file with CR / LF - > LF translation if appropriate . return the
number taken from the buffer . This may not equal the number written .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int writefile ( int f , char * b , int n )
{
int i ;
if ( ! translation )
return ( write ( f , b , n ) ) ;
i = 0 ;
while ( i < n )
{
if ( * b = = ' \r ' & & ( i < ( n - 1 ) ) & & * ( b + 1 ) = = ' \n ' )
{
b + + ; i + + ;
}
if ( write ( f , b , 1 ) ! = 1 )
{
break ;
}
b + + ;
i + + ;
}
return ( i ) ;
}
/****************************************************************************
read from a file with LF - > CR / LF translation if appropriate . return the
number read . read approx n bytes .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int readfile ( char * b , int size , int n , FILE * f )
{
int i ;
int c ;
if ( ! translation | | ( size ! = 1 ) )
return ( fread ( b , size , n , f ) ) ;
i = 0 ;
while ( i < n )
{
if ( ( c = getc ( f ) ) = = EOF )
{
break ;
}
if ( c = = ' \n ' ) /* change all LFs to CR/LF */
{
b [ i + + ] = ' \r ' ;
n + + ;
}
1997-08-26 02:18:31 +04:00
if ( i < n )
b [ i + + ] = c ;
1996-05-04 11:50:46 +04:00
}
return ( i ) ;
}
/****************************************************************************
read from a file with print translation . return the number read . read approx n
bytes .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int printread ( FILE * f , char * b , int n )
{
int i ;
i = readfile ( b , 1 , n - 1 , f ) ;
# if FORMFEED
if ( feof ( f ) & & i > 0 )
b [ i + + ] = ' \014 ' ;
# endif
return ( i ) ;
}
/****************************************************************************
check for existance of a dir
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL chkpath ( char * path , BOOL report )
{
fstring path2 ;
pstring inbuf , outbuf ;
char * p ;
1998-05-12 04:55:32 +04:00
fstrcpy ( path2 , path ) ;
1996-05-04 11:50:46 +04:00
trim_string ( path2 , NULL , " \\ " ) ;
if ( ! * path2 ) * path2 = ' \\ ' ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 0 , 4 + strlen ( path2 ) , True ) ;
SCVAL ( outbuf , smb_com , SMBchkpth ) ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
fstrcpy ( p , path2 ) ;
1996-05-04 11:50:46 +04:00
1997-10-04 09:21:14 +04:00
#if 0
{
/* this little bit of code can be used to extract NT error codes.
Just feed a bunch of " cd foo " commands to smbclient then watch
in netmon ( tridge ) */
static int code = 0 ;
SIVAL ( outbuf , smb_rcls , code | 0xC0000000 ) ;
SSVAL ( outbuf , smb_flg2 , SVAL ( outbuf , smb_flg2 ) | ( 1 < < 14 ) ) ;
code + + ;
}
# endif
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( report & & CVAL ( inbuf , smb_rcls ) ! = 0 )
DEBUG ( 2 , ( " chkpath: %s \n " , smb_errstr ( inbuf ) ) ) ;
return ( CVAL ( inbuf , smb_rcls ) = = 0 ) ;
}
/****************************************************************************
send a message
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void send_message ( char * inbuf , char * outbuf )
{
int total_len = 0 ;
char * p ;
int grp_id ;
/* send a SMBsendstrt command */
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 0 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBsendstrt ;
SSVAL ( outbuf , smb_tid , cnum ) ;
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , username ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , desthost ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
set_message ( outbuf , 0 , PTR_DIFF ( p , smb_buf ( outbuf ) ) , False ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( Client , inbuf , SHORT_TIMEOUT ) | | CVAL ( inbuf , smb_rcls ) ! = 0 )
1996-05-04 11:50:46 +04:00
{
printf ( " SMBsendstrt failed. (%s) \n " , smb_errstr ( inbuf ) ) ;
return ;
}
grp_id = SVAL ( inbuf , smb_vwv0 ) ;
printf ( " Connected. Type your message, ending it with a Control-D \n " ) ;
while ( ! feof ( stdin ) & & total_len < 1600 )
{
int maxlen = MIN ( 1600 - total_len , 127 ) ;
pstring msg ;
int l = 0 ;
int c ;
bzero ( msg , smb_size ) ;
for ( l = 0 ; l < maxlen & & ( c = fgetc ( stdin ) ) ! = EOF ; l + + )
{
if ( c = = ' \n ' )
msg [ l + + ] = ' \r ' ;
msg [ l ] = c ;
}
CVAL ( outbuf , smb_com ) = SMBsendtxt ;
set_message ( outbuf , 1 , l + 3 , True ) ;
SSVAL ( outbuf , smb_vwv0 , grp_id ) ;
p = smb_buf ( outbuf ) ;
* p = 1 ;
SSVAL ( p , 1 , l ) ;
memcpy ( p + 3 , msg , l ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( Client , inbuf , SHORT_TIMEOUT ) | | CVAL ( inbuf , smb_rcls ) ! = 0 )
1996-05-04 11:50:46 +04:00
{
printf ( " SMBsendtxt failed (%s) \n " , smb_errstr ( inbuf ) ) ;
return ;
}
total_len + = l ;
}
if ( total_len > = 1600 )
printf ( " the message was truncated to 1600 bytes " ) ;
else
printf ( " sent %d bytes " , total_len ) ;
printf ( " (status was %d-%d) \n " , CVAL ( inbuf , smb_rcls ) , SVAL ( inbuf , smb_err ) ) ;
CVAL ( outbuf , smb_com ) = SMBsendend ;
set_message ( outbuf , 1 , 0 , False ) ;
SSVAL ( outbuf , smb_vwv0 , grp_id ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( Client , inbuf , SHORT_TIMEOUT ) | | CVAL ( inbuf , smb_rcls ) ! = 0 )
1996-05-04 11:50:46 +04:00
{
printf ( " SMBsendend failed (%s) \n " , smb_errstr ( inbuf ) ) ;
return ;
}
}
/****************************************************************************
check the space on a device
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_dskattr ( void )
{
pstring inbuf , outbuf ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 0 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBdskattr ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
DEBUG ( 0 , ( " Error in dskattr: %s \n " , smb_errstr ( inbuf ) ) ) ;
DEBUG ( 0 , ( " \n \t \t %d blocks of size %d. %d blocks available \n " ,
SVAL ( inbuf , smb_vwv0 ) ,
SVAL ( inbuf , smb_vwv1 ) * SVAL ( inbuf , smb_vwv2 ) ,
SVAL ( inbuf , smb_vwv3 ) ) ) ;
}
/****************************************************************************
show cd / pwd
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_pwd ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
DEBUG ( 0 , ( " Current directory is %s " , CNV_LANG ( service ) ) ) ;
DEBUG ( 0 , ( " %s \n " , CNV_LANG ( cur_dir ) ) ) ;
}
/****************************************************************************
change directory - inner section
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_cd ( char * newdir )
{
char * p = newdir ;
pstring saved_dir ;
pstring dname ;
/* Save the current directory in case the
new directory is invalid */
1998-05-12 04:55:32 +04:00
pstrcpy ( saved_dir , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( * p = = ' \\ ' )
1998-05-12 04:55:32 +04:00
pstrcpy ( cur_dir , p ) ;
1996-05-04 11:50:46 +04:00
else
1998-05-12 04:55:32 +04:00
pstrcat ( cur_dir , p ) ;
1996-05-04 11:50:46 +04:00
if ( * ( cur_dir + strlen ( cur_dir ) - 1 ) ! = ' \\ ' ) {
1998-05-12 04:55:32 +04:00
pstrcat ( cur_dir , " \\ " ) ;
1996-05-04 11:50:46 +04:00
}
dos_clean_name ( cur_dir ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( dname , cur_dir ) ;
pstrcat ( cur_dir , " \\ " ) ;
1996-05-04 11:50:46 +04:00
dos_clean_name ( cur_dir ) ;
if ( ! strequal ( cur_dir , " \\ " ) )
if ( ! chkpath ( dname , True ) )
1998-05-12 04:55:32 +04:00
pstrcpy ( cur_dir , saved_dir ) ;
1996-05-04 11:50:46 +04:00
1998-05-12 04:55:32 +04:00
pstrcpy ( cd_path , cur_dir ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
change directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_cd ( char * inbuf , char * outbuf )
{
fstring buf ;
if ( next_token ( NULL , buf , NULL ) )
do_cd ( buf ) ;
else
DEBUG ( 0 , ( " Current directory is %s \n " , CNV_LANG ( cur_dir ) ) ) ;
}
/****************************************************************************
display info about a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void display_finfo ( file_info * finfo )
{
1997-07-28 22:59:57 +04:00
if ( do_this_one ( finfo ) ) {
time_t t = finfo - > mtime ; /* the time is assumed to be passed as GMT */
DEBUG ( 0 , ( " %-30s%7.7s%10d %s " ,
CNV_LANG ( finfo - > name ) ,
1996-05-04 11:50:46 +04:00
attrib_string ( finfo - > mode ) ,
finfo - > size ,
1996-05-31 19:13:29 +04:00
asctime ( LocalTime ( & t ) ) ) ) ;
1997-07-28 22:59:57 +04:00
dir_total + = finfo - > size ;
}
1996-05-04 11:50:46 +04:00
}
1996-06-04 10:42:03 +04:00
/****************************************************************************
do a directory listing , calling fn on each file found . Use the TRANSACT2
call for long filenames
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static int do_long_dir ( char * inbuf , char * outbuf , char * Mask , int attribute , void ( * fn ) ( file_info * ) , BOOL recurse_dir , BOOL dirstoo )
1996-06-04 10:42:03 +04:00
{
int max_matches = 512 ;
int info_level = Protocol < PROTOCOL_NT1 ? 1 : 260 ; /* NT uses 260, OS/2 uses 2. Both accept 1. */
char * p ;
pstring mask ;
file_info finfo ;
int i ;
char * dirlist = NULL ;
int dirlist_len = 0 ;
int total_received = 0 ;
BOOL First = True ;
char * resp_data = NULL ;
char * resp_param = NULL ;
int resp_data_len = 0 ;
int resp_param_len = 0 ;
int ff_resume_key = 0 ;
int ff_searchcount = 0 ;
int ff_eos = 0 ;
int ff_lastname = 0 ;
int ff_dir_handle = 0 ;
int loop_count = 0 ;
uint16 setup ;
pstring param ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , Mask ) ;
1996-06-04 10:42:03 +04:00
while ( ff_eos = = 0 )
{
loop_count + + ;
if ( loop_count > 200 )
{
1997-07-30 14:13:14 +04:00
DEBUG ( 0 , ( " Error: Looping in FIND_NEXT?? \n " ) ) ;
1996-06-04 10:42:03 +04:00
break ;
}
if ( First )
{
setup = TRANSACT2_FINDFIRST ;
SSVAL ( param , 0 , attribute ) ; /* attribute */
SSVAL ( param , 2 , max_matches ) ; /* max count */
SSVAL ( param , 4 , 8 + 4 + 2 ) ; /* resume required + close on end + continue */
SSVAL ( param , 6 , info_level ) ;
SIVAL ( param , 8 , 0 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( param + 12 , mask ) ;
1996-06-04 10:42:03 +04:00
}
else
{
setup = TRANSACT2_FINDNEXT ;
SSVAL ( param , 0 , ff_dir_handle ) ;
SSVAL ( param , 2 , max_matches ) ; /* max count */
SSVAL ( param , 4 , info_level ) ;
SIVAL ( param , 6 , ff_resume_key ) ; /* ff_resume_key */
SSVAL ( param , 10 , 8 + 4 + 2 ) ; /* resume required + close on end + continue */
1998-05-12 04:55:32 +04:00
pstrcpy ( param + 12 , mask ) ;
1996-06-04 10:42:03 +04:00
DEBUG ( 5 , ( " hand=0x%X resume=%d ff_lastname=%d mask=%s \n " ,
ff_dir_handle , ff_resume_key , ff_lastname , mask ) ) ;
}
/* ??? original code added 1 pad byte after param */
1997-11-01 22:20:29 +03:00
cli_send_trans_request ( outbuf , SMBtrans2 , NULL , 0 , FID_UNUSED , 0 ,
1996-06-04 10:42:03 +04:00
NULL , param , & setup ,
0 , 12 + strlen ( mask ) + 1 , 1 ,
BUFFER_SIZE , 10 , 0 ) ;
1997-10-22 18:28:19 +04:00
if ( ! cli_receive_trans_response ( inbuf , SMBtrans2 ,
1996-06-04 10:42:03 +04:00
& resp_data_len , & resp_param_len ,
& resp_data , & resp_param ) )
{
DEBUG ( 3 , ( " FIND%s gave %s \n " , First ? " FIRST " : " NEXT " , smb_errstr ( inbuf ) ) ) ;
break ;
}
/* parse out some important return info */
p = resp_param ;
if ( First )
{
ff_dir_handle = SVAL ( p , 0 ) ;
ff_searchcount = SVAL ( p , 2 ) ;
ff_eos = SVAL ( p , 4 ) ;
ff_lastname = SVAL ( p , 8 ) ;
}
else
{
ff_searchcount = SVAL ( p , 0 ) ;
ff_eos = SVAL ( p , 2 ) ;
ff_lastname = SVAL ( p , 6 ) ;
}
if ( ff_searchcount = = 0 )
break ;
/* point to the data bytes */
p = resp_data ;
/* we might need the lastname for continuations */
if ( ff_lastname > 0 )
{
switch ( info_level )
{
case 260 :
ff_resume_key = 0 ;
StrnCpy ( mask , p + ff_lastname , resp_data_len - ff_lastname ) ;
1998-05-12 04:55:32 +04:00
/* pstrcpy(mask,p+ff_lastname+94); */
1996-06-04 10:42:03 +04:00
break ;
case 1 :
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , p + ff_lastname + 1 ) ;
1996-06-04 10:42:03 +04:00
ff_resume_key = 0 ;
break ;
}
}
else
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , " " ) ;
1996-06-04 10:42:03 +04:00
/* and add them to the dirlist pool */
dirlist = Realloc ( dirlist , dirlist_len + resp_data_len ) ;
if ( ! dirlist )
{
DEBUG ( 0 , ( " Failed to expand dirlist \n " ) ) ;
break ;
}
/* put in a length for the last entry, to ensure we can chain entries
into the next packet */
{
char * p2 ;
for ( p2 = p , i = 0 ; i < ( ff_searchcount - 1 ) ; i + + )
p2 + = interpret_long_filename ( info_level , p2 , NULL ) ;
SSVAL ( p2 , 0 , resp_data_len - PTR_DIFF ( p2 , p ) ) ;
}
/* grab the data for later use */
memcpy ( dirlist + dirlist_len , p , resp_data_len ) ;
dirlist_len + = resp_data_len ;
total_received + = ff_searchcount ;
if ( resp_data ) free ( resp_data ) ; resp_data = NULL ;
if ( resp_param ) free ( resp_param ) ; resp_param = NULL ;
DEBUG ( 3 , ( " received %d entries (eos=%d resume=%d) \n " ,
ff_searchcount , ff_eos , ff_resume_key ) ) ;
First = False ;
}
if ( ! fn )
for ( p = dirlist , i = 0 ; i < total_received ; i + + )
{
p + = interpret_long_filename ( info_level , p , & finfo ) ;
display_finfo ( & finfo ) ;
}
for ( p = dirlist , i = 0 ; i < total_received ; i + + )
{
p + = interpret_long_filename ( info_level , p , & finfo ) ;
1998-04-11 11:52:13 +04:00
dir_action ( inbuf , outbuf , attribute , & finfo , recurse_dir , fn , True , dirstoo ) ;
1996-06-04 10:42:03 +04:00
}
/* free up the dirlist buffer */
if ( dirlist ) free ( dirlist ) ;
return ( total_received ) ;
}
/****************************************************************************
do a directory listing , calling fn on each file found
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static int do_short_dir ( char * inbuf , char * outbuf , char * Mask , int attribute , void ( * fn ) ( file_info * ) , BOOL recurse_dir , BOOL dirstoo )
1996-06-04 10:42:03 +04:00
{
char * p ;
int received = 0 ;
BOOL first = True ;
char status [ 21 ] ;
int num_asked = ( max_xmit - 100 ) / DIR_STRUCT_SIZE ;
int num_received = 0 ;
int i ;
char * dirlist = NULL ;
pstring mask ;
file_info finfo ;
finfo = def_finfo ;
bzero ( status , 21 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , Mask ) ;
1996-06-04 10:42:03 +04:00
while ( 1 )
{
bzero ( outbuf , smb_size ) ;
if ( first )
set_message ( outbuf , 2 , 5 + strlen ( mask ) , True ) ;
else
set_message ( outbuf , 2 , 5 + 21 , True ) ;
# if FFIRST
if ( Protocol > = PROTOCOL_LANMAN1 )
CVAL ( outbuf , smb_com ) = SMBffirst ;
else
# endif
CVAL ( outbuf , smb_com ) = SMBsearch ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-06-04 10:42:03 +04:00
SSVAL ( outbuf , smb_vwv0 , num_asked ) ;
SSVAL ( outbuf , smb_vwv1 , attribute ) ;
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
if ( first )
1998-05-12 04:55:32 +04:00
pstrcpy ( p , mask ) ;
1996-06-04 10:42:03 +04:00
else
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " " ) ;
1996-06-04 10:42:03 +04:00
p + = strlen ( p ) + 1 ;
* p + + = 5 ;
if ( first )
SSVAL ( p , 0 , 0 ) ;
else
{
SSVAL ( p , 0 , 21 ) ;
p + = 2 ;
memcpy ( p , status , 21 ) ;
}
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-06-04 10:42:03 +04:00
received = SVAL ( inbuf , smb_vwv0 ) ;
DEBUG ( 5 , ( " dir received %d \n " , received ) ) ;
DEBUG ( 6 , ( " errstr=%s \n " , smb_errstr ( inbuf ) ) ) ;
if ( received < = 0 ) break ;
first = False ;
dirlist = Realloc ( dirlist , ( num_received + received ) * DIR_STRUCT_SIZE ) ;
if ( ! dirlist )
return 0 ;
p = smb_buf ( inbuf ) + 3 ;
memcpy ( dirlist + num_received * DIR_STRUCT_SIZE ,
p , received * DIR_STRUCT_SIZE ) ;
memcpy ( status , p + ( ( received - 1 ) * DIR_STRUCT_SIZE ) , 21 ) ;
num_received + = received ;
if ( CVAL ( inbuf , smb_rcls ) ! = 0 ) break ;
}
# if FFIRST
if ( ! first & & Protocol > = PROTOCOL_LANMAN1 )
{
bzero ( outbuf , smb_size ) ;
CVAL ( outbuf , smb_com ) = SMBfclose ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-06-04 10:42:03 +04:00
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " " ) ;
1996-06-04 10:42:03 +04:00
p + = strlen ( p ) + 1 ;
* p + + = 5 ;
SSVAL ( p , 0 , 21 ) ;
p + = 2 ;
memcpy ( p , status , 21 ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-06-04 10:42:03 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
DEBUG ( 0 , ( " Error closing search: %s \n " , smb_errstr ( inbuf ) ) ) ;
}
# endif
if ( ! fn )
for ( p = dirlist , i = 0 ; i < num_received ; i + + )
{
p + = interpret_short_filename ( p , & finfo ) ;
display_finfo ( & finfo ) ;
}
for ( p = dirlist , i = 0 ; i < num_received ; i + + )
{
p + = interpret_short_filename ( p , & finfo ) ;
1998-04-11 11:52:13 +04:00
dir_action ( inbuf , outbuf , attribute , & finfo , recurse_dir , fn , False , dirstoo ) ;
1996-06-04 10:42:03 +04:00
}
if ( dirlist ) free ( dirlist ) ;
return ( num_received ) ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
do a directory listing , calling fn on each file found
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
void do_dir ( char * inbuf , char * outbuf , char * Mask , int attribute , void ( * fn ) ( file_info * ) , BOOL recurse_dir , BOOL dirstoo )
1996-05-04 11:50:46 +04:00
{
DEBUG ( 5 , ( " do_dir(%s,%x,%s) \n " , Mask , attribute , BOOLSTR ( recurse_dir ) ) ) ;
if ( Protocol > = PROTOCOL_LANMAN2 )
{
1998-04-11 11:52:13 +04:00
if ( do_long_dir ( inbuf , outbuf , Mask , attribute , fn , recurse_dir , dirstoo ) > 0 )
1996-05-04 11:50:46 +04:00
return ;
}
expand_mask ( Mask , False ) ;
1998-04-11 11:52:13 +04:00
do_short_dir ( inbuf , outbuf , Mask , attribute , fn , recurse_dir , dirstoo ) ;
1996-05-04 11:50:46 +04:00
return ;
}
/*******************************************************************
decide if a file should be operated on
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL do_this_one ( file_info * finfo )
{
if ( finfo - > mode & aDIR ) return ( True ) ;
if ( newer_than & & finfo - > mtime < newer_than )
return ( False ) ;
if ( ( archive_level = = 1 | | archive_level = = 2 ) & & ! ( finfo - > mode & aARCH ) )
return ( False ) ;
return ( True ) ;
}
1996-08-13 12:57:55 +04:00
/*****************************************************************************
1997-10-22 18:28:19 +04:00
Convert a character pointer in a cli_call_api ( ) response to a form we can use .
1996-08-13 12:57:55 +04:00
This function contains code to prevent core dumps if the server returns
invalid data .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * fix_char_ptr ( unsigned int datap , unsigned int converter , char * rdata , int rdrcnt )
{
if ( datap = = 0 ) /* turn NULL pointers */
{ /* into zero length strings */
return " " ;
}
else
{
unsigned int offset = datap - converter ;
1997-05-31 00:40:48 +04:00
if ( offset > = rdrcnt )
1996-08-13 12:57:55 +04:00
{
1997-07-24 21:25:11 +04:00
DEBUG ( 1 , ( " bad char ptr: datap=%u, converter=%u, rdata=%lu, rdrcnt=%d> " , datap , converter , ( unsigned long ) rdata , rdrcnt ) ) ;
1996-08-13 12:57:55 +04:00
return " <ERROR> " ;
}
else
{
return & rdata [ offset ] ;
}
}
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
interpret a short filename structure
The length of the structure is returned
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int interpret_short_filename ( char * p , file_info * finfo )
{
finfo - > mode = CVAL ( p , 21 ) ;
/* this date is converted to GMT by make_unix_date */
finfo - > ctime = make_unix_date ( p + 22 ) ;
finfo - > mtime = finfo - > atime = finfo - > ctime ;
finfo - > size = IVAL ( p , 26 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( finfo - > name , p + 30 ) ;
1996-05-04 11:50:46 +04:00
return ( DIR_STRUCT_SIZE ) ;
}
/****************************************************************************
interpret a long filename structure - this is mostly guesses at the moment
The length of the structure is returned
The structure of a long filename depends on the info level . 260 is used
by NT and 2 is used by OS / 2
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int interpret_long_filename ( int level , char * p , file_info * finfo )
{
if ( finfo )
memcpy ( finfo , & def_finfo , sizeof ( * finfo ) ) ;
switch ( level )
{
case 1 : /* OS/2 understands this */
if ( finfo )
{
/* these dates are converted to GMT by make_unix_date */
finfo - > ctime = make_unix_date2 ( p + 4 ) ;
finfo - > atime = make_unix_date2 ( p + 8 ) ;
finfo - > mtime = make_unix_date2 ( p + 12 ) ;
finfo - > size = IVAL ( p , 16 ) ;
finfo - > mode = CVAL ( p , 24 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( finfo - > name , p + 27 ) ;
1996-05-04 11:50:46 +04:00
}
return ( 28 + CVAL ( p , 26 ) ) ;
case 2 : /* this is what OS/2 uses mostly */
if ( finfo )
{
/* these dates are converted to GMT by make_unix_date */
finfo - > ctime = make_unix_date2 ( p + 4 ) ;
finfo - > atime = make_unix_date2 ( p + 8 ) ;
finfo - > mtime = make_unix_date2 ( p + 12 ) ;
finfo - > size = IVAL ( p , 16 ) ;
finfo - > mode = CVAL ( p , 24 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( finfo - > name , p + 31 ) ;
1996-05-04 11:50:46 +04:00
}
return ( 32 + CVAL ( p , 30 ) ) ;
/* levels 3 and 4 are untested */
case 3 :
if ( finfo )
{
/* these dates are probably like the other ones */
finfo - > ctime = make_unix_date2 ( p + 8 ) ;
finfo - > atime = make_unix_date2 ( p + 12 ) ;
finfo - > mtime = make_unix_date2 ( p + 16 ) ;
finfo - > size = IVAL ( p , 20 ) ;
finfo - > mode = CVAL ( p , 28 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( finfo - > name , p + 33 ) ;
1996-05-04 11:50:46 +04:00
}
return ( SVAL ( p , 4 ) + 4 ) ;
case 4 :
if ( finfo )
{
/* these dates are probably like the other ones */
finfo - > ctime = make_unix_date2 ( p + 8 ) ;
finfo - > atime = make_unix_date2 ( p + 12 ) ;
finfo - > mtime = make_unix_date2 ( p + 16 ) ;
finfo - > size = IVAL ( p , 20 ) ;
finfo - > mode = CVAL ( p , 28 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( finfo - > name , p + 37 ) ;
1996-05-04 11:50:46 +04:00
}
return ( SVAL ( p , 4 ) + 4 ) ;
case 260 : /* NT uses this, but also accepts 2 */
if ( finfo )
{
int ret = SVAL ( p , 0 ) ;
int namelen ;
p + = 4 ; /* next entry offset */
p + = 4 ; /* fileindex */
/* these dates appear to arrive in a weird way. It seems to
be localtime plus the serverzone given in the initial
connect . This is GMT when DST is not in effect and one
hour from GMT otherwise . Can this really be right ? ?
I suppose this could be called kludge - GMT . Is is the GMT
you get by using the current DST setting on a different
localtime . It will be cheap to calculate , I suppose , as
no DST tables will be needed */
finfo - > ctime = interpret_long_date ( p ) ; p + = 8 ;
finfo - > atime = interpret_long_date ( p ) ; p + = 8 ;
finfo - > mtime = interpret_long_date ( p ) ; p + = 8 ; p + = 8 ;
finfo - > size = IVAL ( p , 0 ) ; p + = 8 ;
p + = 8 ; /* alloc size */
finfo - > mode = CVAL ( p , 0 ) ; p + = 4 ;
namelen = IVAL ( p , 0 ) ; p + = 4 ;
p + = 4 ; /* EA size */
p + = 2 ; /* short name len? */
p + = 24 ; /* short name? */
StrnCpy ( finfo - > name , p , namelen ) ;
1996-06-04 10:42:03 +04:00
return ( ret ) ;
}
return ( SVAL ( p , 0 ) ) ;
}
1996-05-04 11:50:46 +04:00
1996-06-04 10:42:03 +04:00
DEBUG ( 1 , ( " Unknown long filename format %d \n " , level ) ) ;
return ( SVAL ( p , 0 ) ) ;
}
1996-05-04 11:50:46 +04:00
1996-06-04 10:42:03 +04:00
/****************************************************************************
act on the files in a dir listing
1998-04-11 11:52:13 +04:00
RJS , 4 - Apr - 1998 , dirstoo added to allow caller to indicate that directories
should be processed as well .
1996-06-04 10:42:03 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void dir_action ( char * inbuf , char * outbuf , int attribute , file_info * finfo , BOOL recurse_dir , void ( * fn ) ( file_info * ) , BOOL longdir , BOOL dirstoo )
1996-06-04 10:42:03 +04:00
{
1996-05-04 11:50:46 +04:00
1996-06-04 10:42:03 +04:00
if ( ! ( ( finfo - > mode & aDIR ) = = 0 & & * fileselection & &
! mask_match ( finfo - > name , fileselection , False , False ) ) & &
! ( recurse_dir & & ( strequal ( finfo - > name , " . " ) | |
strequal ( finfo - > name , " .. " ) ) ) )
1996-05-04 11:50:46 +04:00
{
1996-06-04 10:42:03 +04:00
if ( recurse_dir & & ( finfo - > mode & aDIR ) )
{
pstring mask2 ;
pstring sav_dir ;
1998-04-11 11:52:13 +04:00
if ( fn & & dirstoo & & do_this_one ( finfo ) ) { /* Do dirs, RJS */
fn ( finfo ) ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( sav_dir , cur_dir ) ;
pstrcat ( cur_dir , finfo - > name ) ;
pstrcat ( cur_dir , " \\ " ) ;
pstrcpy ( mask2 , cur_dir ) ;
1996-05-04 11:50:46 +04:00
1996-06-04 10:42:03 +04:00
if ( ! fn )
DEBUG ( 0 , ( " \n %s \n " , CNV_LANG ( cur_dir ) ) ) ;
1996-05-04 11:50:46 +04:00
1998-05-12 04:55:32 +04:00
pstrcat ( mask2 , " * " ) ;
1996-05-04 11:50:46 +04:00
1996-06-04 10:42:03 +04:00
if ( longdir )
1998-04-11 11:52:13 +04:00
do_long_dir ( inbuf , outbuf , mask2 , attribute , fn , True , dirstoo ) ;
1996-06-04 10:42:03 +04:00
else
1998-04-11 11:52:13 +04:00
do_dir ( inbuf , outbuf , mask2 , attribute , fn , True , dirstoo ) ;
1996-05-04 11:50:46 +04:00
1998-05-12 04:55:32 +04:00
pstrcpy ( cur_dir , sav_dir ) ;
1996-06-04 10:42:03 +04:00
}
else
{
if ( fn & & do_this_one ( finfo ) )
fn ( finfo ) ;
}
1996-05-04 11:50:46 +04:00
}
}
1996-06-04 10:42:03 +04:00
1996-05-04 11:50:46 +04:00
/****************************************************************************
get a directory listing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_dir ( char * inbuf , char * outbuf )
{
int attribute = aDIR | aSYSTEM | aHIDDEN ;
pstring mask ;
fstring buf ;
char * p = buf ;
1997-07-28 22:59:57 +04:00
dir_total = 0 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( mask [ strlen ( mask ) - 1 ] ! = ' \\ ' )
1998-05-12 04:55:32 +04:00
pstrcat ( mask , " \\ " ) ;
1996-05-04 11:50:46 +04:00
if ( next_token ( NULL , buf , NULL ) )
{
if ( * p = = ' \\ ' )
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , p ) ;
1996-05-04 11:50:46 +04:00
else
1998-05-12 04:55:32 +04:00
pstrcat ( mask , p ) ;
1996-05-04 11:50:46 +04:00
}
else {
1998-05-12 04:55:32 +04:00
pstrcat ( mask , " * " ) ;
1996-05-04 11:50:46 +04:00
}
1998-04-11 11:52:13 +04:00
do_dir ( inbuf , outbuf , mask , attribute , NULL , recurse , False ) ;
1996-05-04 11:50:46 +04:00
do_dskattr ( ) ;
1997-07-28 22:59:57 +04:00
DEBUG ( 3 , ( " Total bytes listed: %d \n " , dir_total ) ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
get a file from rname to lname
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_get ( char * rname , char * lname , file_info * finfo1 )
{
int handle = 0 , fnum ;
uint32 nread = 0 ;
char * p ;
BOOL newhandle = False ;
char * inbuf , * outbuf ;
file_info finfo ;
BOOL close_done = False ;
BOOL ignore_close_error = False ;
char * dataptr = NULL ;
int datalen = 0 ;
struct timeval tp_start ;
GetTimeOfDay ( & tp_start ) ;
if ( finfo1 )
finfo = * finfo1 ;
else
finfo = def_finfo ;
if ( lowercase )
strlower ( lname ) ;
inbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
outbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
if ( ! inbuf | | ! outbuf )
{
DEBUG ( 0 , ( " out of memory \n " ) ) ;
return ;
}
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 15 , 1 + strlen ( rname ) , True ) ;
CVAL ( outbuf , smb_com ) = SMBopenX ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , 0xFF ) ;
1997-11-01 16:22:16 +03:00
SSVAL ( outbuf , smb_vwv2 , 1 ) ; /* return additional info */
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv3 , ( DENY_NONE < < 4 ) ) ;
SSVAL ( outbuf , smb_vwv4 , aSYSTEM | aHIDDEN ) ;
SSVAL ( outbuf , smb_vwv5 , aSYSTEM | aHIDDEN ) ;
SSVAL ( outbuf , smb_vwv8 , 1 ) ;
1997-10-23 17:38:46 +04:00
SSVAL ( outbuf , smb_vwv11 , 0xffff ) ;
SSVAL ( outbuf , smb_vwv12 , 0xffff ) ;
1996-05-04 11:50:46 +04:00
p = smb_buf ( outbuf ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , rname ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
/* do a chained openX with a readX? */
# if 1
if ( finfo . size > 0 )
{
DEBUG ( 3 , ( " Chaining readX wth openX \n " ) ) ;
SSVAL ( outbuf , smb_vwv0 , SMBreadX ) ;
SSVAL ( outbuf , smb_vwv1 , smb_offset ( p , outbuf ) ) ;
bzero ( p , 200 ) ;
p - = smb_wct ;
SSVAL ( p , smb_wct , 10 ) ;
SSVAL ( p , smb_vwv0 , 0xFF ) ;
SSVAL ( p , smb_vwv5 , MIN ( max_xmit - 500 , finfo . size ) ) ;
SSVAL ( p , smb_vwv9 , MIN ( BUFFER_SIZE , finfo . size ) ) ;
smb_setlen ( outbuf , smb_len ( outbuf ) + 11 * 2 + 1 ) ;
}
# endif
if ( ! strcmp ( lname , " - " ) )
handle = fileno ( stdout ) ;
else
{
handle = creat ( lname , 0644 ) ;
newhandle = True ;
}
if ( handle < 0 )
{
DEBUG ( 0 , ( " Error opening local file %s \n " , lname ) ) ;
free ( inbuf ) ; free ( outbuf ) ;
return ;
}
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
if ( CVAL ( inbuf , smb_rcls ) = = ERRSRV & &
SVAL ( inbuf , smb_err ) = = ERRnoresource & &
1997-10-22 18:28:19 +04:00
cli_reopen_connection ( inbuf , outbuf ) )
1996-05-04 11:50:46 +04:00
{
do_get ( rname , lname , finfo1 ) ;
return ;
}
DEBUG ( 0 , ( " %s opening remote file %s \n " , smb_errstr ( inbuf ) , CNV_LANG ( rname ) ) ) ;
if ( newhandle )
close ( handle ) ;
free ( inbuf ) ; free ( outbuf ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( finfo . name , rname ) ;
1996-05-04 11:50:46 +04:00
if ( ! finfo1 )
{
finfo . mode = SVAL ( inbuf , smb_vwv3 ) ;
/* these times arrive as LOCAL time, using the DST offset
corresponding to that time , we convert them to GMT */
finfo . mtime = make_unix_date3 ( inbuf + smb_vwv4 ) ;
finfo . atime = finfo . ctime = finfo . mtime ;
finfo . size = IVAL ( inbuf , smb_vwv6 ) ;
}
DEBUG ( 3 , ( " file %s attrib 0x%X \n " , CNV_LANG ( finfo . name ) , finfo . mode ) ) ;
fnum = SVAL ( inbuf , smb_vwv2 ) ;
/* we might have got some data from a chained readX */
if ( SVAL ( inbuf , smb_vwv0 ) = = SMBreadX )
{
p = ( smb_base ( inbuf ) + SVAL ( inbuf , smb_vwv1 ) ) - smb_wct ;
datalen = SVAL ( p , smb_vwv5 ) ;
dataptr = smb_base ( inbuf ) + SVAL ( p , smb_vwv6 ) ;
}
else
{
dataptr = NULL ;
datalen = 0 ;
}
DEBUG ( 2 , ( " getting file %s of size %d bytes as %s " ,
CNV_LANG ( finfo . name ) ,
finfo . size ,
lname ) ) ;
while ( nread < finfo . size & & ! close_done )
{
int method = - 1 ;
static BOOL can_chain_close = True ;
p = NULL ;
DEBUG ( 3 , ( " nread=%d max_xmit=%d fsize=%d \n " , nread , max_xmit , finfo . size ) ) ;
/* 3 possible read types. readbraw if a large block is required.
readX + close if not much left and read if neither is supported */
/* we might have already read some data from a chained readX */
if ( dataptr & & datalen > 0 )
method = 3 ;
/* if we can finish now then readX+close */
if ( method < 0 & & can_chain_close & & ( Protocol > = PROTOCOL_LANMAN1 ) & &
( ( finfo . size - nread ) <
( max_xmit - ( 2 * smb_size + 13 * SIZEOFWORD + 300 ) ) ) )
method = 0 ;
/* if we support readraw then use that */
if ( method < 0 & & readbraw_supported )
method = 1 ;
/* if we can then use readX */
if ( method < 0 & & ( Protocol > = PROTOCOL_LANMAN1 ) )
method = 2 ;
switch ( method )
{
/* use readX */
case 0 :
case 2 :
if ( method = = 0 )
close_done = True ;
/* use readX + close */
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 10 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBreadX ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
if ( close_done )
{
CVAL ( outbuf , smb_vwv0 ) = SMBclose ;
SSVAL ( outbuf , smb_vwv1 , smb_offset ( smb_buf ( outbuf ) , outbuf ) ) ;
}
else
CVAL ( outbuf , smb_vwv0 ) = 0xFF ;
SSVAL ( outbuf , smb_vwv2 , fnum ) ;
SIVAL ( outbuf , smb_vwv3 , nread ) ;
SSVAL ( outbuf , smb_vwv5 , MIN ( max_xmit - 200 , finfo . size - nread ) ) ;
SSVAL ( outbuf , smb_vwv6 , 0 ) ;
SIVAL ( outbuf , smb_vwv7 , 0 ) ;
SSVAL ( outbuf , smb_vwv9 , MIN ( BUFFER_SIZE , finfo . size - nread ) ) ;
if ( close_done )
{
p = smb_buf ( outbuf ) ;
bzero ( p , 9 ) ;
CVAL ( p , 0 ) = 3 ;
SSVAL ( p , 1 , fnum ) ;
SIVALS ( p , 3 , - 1 ) ;
/* now set the total packet length */
smb_setlen ( outbuf , smb_len ( outbuf ) + 9 ) ;
}
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " Error %s reading remote file \n " , smb_errstr ( inbuf ) ) ) ;
break ;
}
if ( close_done & &
SVAL ( inbuf , smb_vwv0 ) ! = SMBclose )
{
/* NOTE: WfWg sometimes just ignores the chained
command ! This seems to break the spec ? */
DEBUG ( 3 , ( " Rejected chained close? \n " ) ) ;
close_done = False ;
can_chain_close = False ;
ignore_close_error = True ;
}
datalen = SVAL ( inbuf , smb_vwv5 ) ;
dataptr = smb_base ( inbuf ) + SVAL ( inbuf , smb_vwv6 ) ;
break ;
/* use readbraw */
case 1 :
{
static int readbraw_size = BUFFER_SIZE ;
extern int Client ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 8 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBreadbraw ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
SIVAL ( outbuf , smb_vwv1 , nread ) ;
SSVAL ( outbuf , smb_vwv3 , MIN ( finfo . size - nread , readbraw_size ) ) ;
SSVAL ( outbuf , smb_vwv4 , 0 ) ;
SIVALS ( outbuf , smb_vwv5 , - 1 ) ;
send_smb ( Client , outbuf ) ;
/* Now read the raw data into the buffer and write it */
if ( read_smb_length ( Client , inbuf , 0 ) = = - 1 ) {
DEBUG ( 0 , ( " Failed to read length in readbraw \n " ) ) ;
exit ( 1 ) ;
}
/* Even though this is not an smb message, smb_len
returns the generic length of an smb message */
datalen = smb_len ( inbuf ) ;
if ( datalen = = 0 )
{
/* we got a readbraw error */
DEBUG ( 4 , ( " readbraw error - reducing size \n " ) ) ;
readbraw_size = ( readbraw_size * 9 ) / 10 ;
if ( readbraw_size < max_xmit )
{
DEBUG ( 0 , ( " disabling readbraw \n " ) ) ;
readbraw_supported = False ;
}
dataptr = NULL ;
continue ;
}
if ( read_data ( Client , inbuf , datalen ) ! = datalen ) {
DEBUG ( 0 , ( " Failed to read data in readbraw \n " ) ) ;
exit ( 1 ) ;
}
dataptr = inbuf ;
}
break ;
case 3 :
/* we've already read some data with a chained readX */
break ;
default :
/* use plain read */
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 5 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBread ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
SSVAL ( outbuf , smb_vwv1 , MIN ( max_xmit - 200 , finfo . size - nread ) ) ;
SIVAL ( outbuf , smb_vwv2 , nread ) ;
SSVAL ( outbuf , smb_vwv4 , finfo . size - nread ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " Error %s reading remote file \n " , smb_errstr ( inbuf ) ) ) ;
break ;
}
datalen = SVAL ( inbuf , smb_vwv0 ) ;
dataptr = smb_buf ( inbuf ) + 3 ;
break ;
}
if ( writefile ( handle , dataptr , datalen ) ! = datalen )
{
DEBUG ( 0 , ( " Error writing local file \n " ) ) ;
break ;
}
nread + = datalen ;
if ( datalen = = 0 )
{
DEBUG ( 0 , ( " Error reading file %s. Got %d bytes \n " , CNV_LANG ( rname ) , nread ) ) ;
break ;
}
dataptr = NULL ;
datalen = 0 ;
}
if ( ! close_done )
{
1997-10-23 17:38:46 +04:00
cli_smb_close ( inbuf , outbuf , Client , cnum , fnum ) ;
1996-05-04 11:50:46 +04:00
if ( ! ignore_close_error & & CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " Error %s closing remote file \n " , smb_errstr ( inbuf ) ) ) ;
if ( newhandle )
close ( handle ) ;
free ( inbuf ) ; free ( outbuf ) ;
return ;
}
}
if ( newhandle )
close ( handle ) ;
if ( archive_level > = 2 & & ( finfo . mode & aARCH ) ) {
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 8 , strlen ( rname ) + 4 , True ) ;
CVAL ( outbuf , smb_com ) = SMBsetatr ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , finfo . mode & ~ ( aARCH ) ) ;
SIVALS ( outbuf , smb_vwv1 , 0 ) ;
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , rname ) ;
1996-05-04 11:50:46 +04:00
p + = strlen ( p ) + 1 ;
* p + + = 4 ;
* p = 0 ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
}
{
struct timeval tp_end ;
int this_time ;
GetTimeOfDay ( & tp_end ) ;
this_time =
( tp_end . tv_sec - tp_start . tv_sec ) * 1000 +
( tp_end . tv_usec - tp_start . tv_usec ) / 1000 ;
get_total_time_ms + = this_time ;
get_total_size + = finfo . size ;
1996-10-04 13:31:07 +04:00
DEBUG ( 1 , ( " (%g kb/s) (average %g kb/s) \n " ,
1996-05-04 11:50:46 +04:00
finfo . size / ( 1.024 * this_time + 1.0e-4 ) ,
get_total_size / ( 1.024 * get_total_time_ms ) ) ) ;
}
free ( inbuf ) ; free ( outbuf ) ;
}
/****************************************************************************
get a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_get ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
pstring lname ;
pstring rname ;
char * p ;
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , " \\ " ) ;
1996-05-04 11:50:46 +04:00
p = rname + strlen ( rname ) ;
if ( ! next_token ( NULL , p , NULL ) ) {
DEBUG ( 0 , ( " get <filename> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( lname , p ) ;
1996-05-04 11:50:46 +04:00
dos_clean_name ( rname ) ;
next_token ( NULL , lname , NULL ) ;
do_get ( rname , lname , NULL ) ;
}
/****************************************************************************
do a mget operation on one file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_mget ( file_info * finfo )
{
pstring rname ;
pstring quest ;
if ( strequal ( finfo - > name , " . " ) | | strequal ( finfo - > name , " .. " ) )
return ;
if ( abort_mget )
{
DEBUG ( 0 , ( " mget aborted \n " ) ) ;
return ;
}
if ( finfo - > mode & aDIR )
1998-05-11 10:38:36 +04:00
slprintf ( quest , sizeof ( pstring ) - 1 ,
" Get directory %s? " , CNV_LANG ( finfo - > name ) ) ;
1996-05-04 11:50:46 +04:00
else
1998-05-11 10:38:36 +04:00
slprintf ( quest , sizeof ( pstring ) - 1 ,
" Get file %s? " , CNV_LANG ( finfo - > name ) ) ;
1996-05-04 11:50:46 +04:00
if ( prompt & & ! yesno ( quest ) ) return ;
if ( finfo - > mode & aDIR )
{
pstring saved_curdir ;
pstring mget_mask ;
char * inbuf , * outbuf ;
inbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
outbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
if ( ! inbuf | | ! outbuf )
{
DEBUG ( 0 , ( " out of memory \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( saved_curdir , cur_dir ) ;
1996-05-04 11:50:46 +04:00
1998-05-12 04:55:32 +04:00
pstrcat ( cur_dir , finfo - > name ) ;
pstrcat ( cur_dir , " \\ " ) ;
1996-05-04 11:50:46 +04:00
unix_format ( finfo - > name ) ;
{
if ( lowercase )
strlower ( finfo - > name ) ;
if ( ! directory_exist ( finfo - > name , NULL ) & &
sys_mkdir ( finfo - > name , 0777 ) ! = 0 )
{
DEBUG ( 0 , ( " failed to create directory %s \n " , CNV_LANG ( finfo - > name ) ) ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( cur_dir , saved_curdir ) ;
1996-05-04 11:50:46 +04:00
free ( inbuf ) ; free ( outbuf ) ;
return ;
}
if ( sys_chdir ( finfo - > name ) ! = 0 )
{
DEBUG ( 0 , ( " failed to chdir to directory %s \n " , CNV_LANG ( finfo - > name ) ) ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( cur_dir , saved_curdir ) ;
1996-05-04 11:50:46 +04:00
free ( inbuf ) ; free ( outbuf ) ;
return ;
}
}
1998-05-12 04:55:32 +04:00
pstrcpy ( mget_mask , cur_dir ) ;
pstrcat ( mget_mask , " * " ) ;
1996-05-04 11:50:46 +04:00
do_dir ( ( char * ) inbuf , ( char * ) outbuf ,
1998-04-11 11:52:13 +04:00
mget_mask , aSYSTEM | aHIDDEN | aDIR , do_mget , False , False ) ;
1996-05-04 11:50:46 +04:00
chdir ( " .. " ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( cur_dir , saved_curdir ) ;
1996-05-04 11:50:46 +04:00
free ( inbuf ) ; free ( outbuf ) ;
}
else
{
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , finfo - > name ) ;
1996-05-04 11:50:46 +04:00
do_get ( rname , finfo - > name , finfo ) ;
}
}
/****************************************************************************
view the file using the pager
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_more ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
fstring rname , lname , tmpname , pager_cmd ;
char * pager ;
1998-05-12 04:55:32 +04:00
fstrcpy ( rname , cur_dir ) ;
fstrcat ( rname , " \\ " ) ;
1998-05-11 10:38:36 +04:00
slprintf ( tmpname ,
sizeof ( fstring ) - 1 ,
" %s/smbmore.%d " , tmpdir ( ) , ( int ) getpid ( ) ) ;
1998-05-12 04:55:32 +04:00
fstrcpy ( lname , tmpname ) ;
1996-05-04 11:50:46 +04:00
if ( ! next_token ( NULL , rname + strlen ( rname ) , NULL ) ) {
DEBUG ( 0 , ( " more <filename> \n " ) ) ;
return ;
}
dos_clean_name ( rname ) ;
do_get ( rname , lname , NULL ) ;
pager = getenv ( " PAGER " ) ;
1998-05-11 10:38:36 +04:00
slprintf ( pager_cmd , sizeof ( pager_cmd ) - 1 ,
" %s %s " , ( pager ? pager : PAGER ) , tmpname ) ;
1996-05-04 11:50:46 +04:00
system ( pager_cmd ) ;
unlink ( tmpname ) ;
}
/****************************************************************************
do a mget command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_mget ( char * inbuf , char * outbuf )
{
int attribute = aSYSTEM | aHIDDEN ;
pstring mget_mask ;
fstring buf ;
char * p = buf ;
* mget_mask = 0 ;
if ( recurse )
attribute | = aDIR ;
abort_mget = False ;
while ( next_token ( NULL , p , NULL ) )
{
1998-05-12 04:55:32 +04:00
pstrcpy ( mget_mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( mget_mask [ strlen ( mget_mask ) - 1 ] ! = ' \\ ' )
1998-05-12 04:55:32 +04:00
pstrcat ( mget_mask , " \\ " ) ;
1996-05-04 11:50:46 +04:00
if ( * p = = ' \\ ' )
1998-05-12 04:55:32 +04:00
pstrcpy ( mget_mask , p ) ;
1996-05-04 11:50:46 +04:00
else
1998-05-12 04:55:32 +04:00
pstrcat ( mget_mask , p ) ;
1998-04-11 11:52:13 +04:00
do_dir ( ( char * ) inbuf , ( char * ) outbuf , mget_mask , attribute , do_mget , False , False ) ;
1996-05-04 11:50:46 +04:00
}
if ( ! * mget_mask )
{
1998-05-12 04:55:32 +04:00
pstrcpy ( mget_mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( mget_mask [ strlen ( mget_mask ) - 1 ] ! = ' \\ ' )
1998-05-12 04:55:32 +04:00
pstrcat ( mget_mask , " \\ " ) ;
pstrcat ( mget_mask , " * " ) ;
1998-04-11 11:52:13 +04:00
do_dir ( ( char * ) inbuf , ( char * ) outbuf , mget_mask , attribute , do_mget , False , False ) ;
1996-05-04 11:50:46 +04:00
}
}
/****************************************************************************
make a directory of name " name "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL do_mkdir ( char * name )
{
char * p ;
char * inbuf , * outbuf ;
inbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
outbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
if ( ! inbuf | | ! outbuf )
{
DEBUG ( 0 , ( " out of memory \n " ) ) ;
return False ;
}
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 0 , 2 + strlen ( name ) , True ) ;
CVAL ( outbuf , smb_com ) = SMBmkdir ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , name ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s making remote directory %s \n " ,
smb_errstr ( inbuf ) , CNV_LANG ( name ) ) ) ;
free ( inbuf ) ; free ( outbuf ) ;
return ( False ) ;
}
free ( inbuf ) ; free ( outbuf ) ;
return ( True ) ;
}
/****************************************************************************
make a directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_mkdir ( char * inbuf , char * outbuf )
{
pstring mask ;
fstring buf ;
char * p = buf ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( ! next_token ( NULL , p , NULL ) )
{
if ( ! recurse )
DEBUG ( 0 , ( " mkdir <dirname> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcat ( mask , p ) ;
1996-05-04 11:50:46 +04:00
if ( recurse )
{
pstring ddir ;
pstring ddir2 ;
* ddir2 = 0 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( ddir , mask ) ;
1996-05-04 11:50:46 +04:00
trim_string ( ddir , " . " , NULL ) ;
p = strtok ( ddir , " / \\ " ) ;
while ( p )
{
1998-05-12 04:55:32 +04:00
pstrcat ( ddir2 , p ) ;
1996-05-04 11:50:46 +04:00
if ( ! chkpath ( ddir2 , False ) )
{
do_mkdir ( ddir2 ) ;
}
1998-05-12 04:55:32 +04:00
pstrcat ( ddir2 , " \\ " ) ;
1996-05-04 11:50:46 +04:00
p = strtok ( NULL , " / \\ " ) ;
}
}
else
do_mkdir ( mask ) ;
}
/*******************************************************************
write to a file using writebraw
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int smb_writeraw ( char * outbuf , int fnum , int pos , char * buf , int n )
{
extern int Client ;
pstring inbuf ;
bzero ( outbuf , smb_size ) ;
bzero ( inbuf , smb_size ) ;
set_message ( outbuf , Protocol > PROTOCOL_COREPLUS ? 12 : 10 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBwritebraw ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
SSVAL ( outbuf , smb_vwv1 , n ) ;
SIVAL ( outbuf , smb_vwv3 , pos ) ;
SSVAL ( outbuf , smb_vwv7 , 1 ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) | | CVAL ( inbuf , smb_rcls ) ! = 0 )
1996-05-04 11:50:46 +04:00
return ( 0 ) ;
_smb_setlen ( buf - 4 , n ) ; /* HACK! XXXX */
if ( write_socket ( Client , buf - 4 , n + 4 ) ! = n + 4 )
return ( 0 ) ;
1997-12-20 17:36:11 +03:00
if ( ! client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) | | CVAL ( inbuf , smb_rcls ) ! = 0 ) {
1996-05-04 11:50:46 +04:00
DEBUG ( 0 , ( " Error writing remote file (2) \n " ) ) ;
return ( 0 ) ;
}
return ( SVAL ( inbuf , smb_vwv0 ) ) ;
}
/*******************************************************************
write to a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int smb_writefile ( char * outbuf , int fnum , int pos , char * buf , int n )
{
pstring inbuf ;
if ( writebraw_supported & & n > ( max_xmit - 200 ) )
return ( smb_writeraw ( outbuf , fnum , pos , buf , n ) ) ;
bzero ( outbuf , smb_size ) ;
bzero ( inbuf , smb_size ) ;
set_message ( outbuf , 5 , n + 3 , True ) ;
CVAL ( outbuf , smb_com ) = SMBwrite ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
SSVAL ( outbuf , smb_vwv1 , n ) ;
SIVAL ( outbuf , smb_vwv2 , pos ) ;
SSVAL ( outbuf , smb_vwv4 , 0 ) ;
CVAL ( smb_buf ( outbuf ) , 0 ) = 1 ;
SSVAL ( smb_buf ( outbuf ) , 1 , n ) ;
memcpy ( smb_buf ( outbuf ) + 3 , buf , n ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 ) {
DEBUG ( 0 , ( " %s writing remote file \n " , smb_errstr ( inbuf ) ) ) ;
return ( 0 ) ;
}
return ( SVAL ( inbuf , smb_vwv0 ) ) ;
}
/****************************************************************************
put a single file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_put ( char * rname , char * lname , file_info * finfo )
{
int fnum ;
FILE * f ;
int nread = 0 ;
char * p ;
char * inbuf , * outbuf ;
time_t close_time = finfo - > mtime ;
char * buf = NULL ;
static int maxwrite = 0 ;
struct timeval tp_start ;
GetTimeOfDay ( & tp_start ) ;
inbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
outbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
if ( ! inbuf | | ! outbuf )
{
DEBUG ( 0 , ( " out of memory \n " ) ) ;
return ;
}
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 3 , 2 + strlen ( rname ) , True ) ;
if ( finfo - > mtime = = 0 | | finfo - > mtime = = - 1 )
finfo - > mtime = finfo - > atime = finfo - > ctime = time ( NULL ) ;
CVAL ( outbuf , smb_com ) = SMBcreate ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , finfo - > mode ) ;
put_dos_date3 ( outbuf , smb_vwv1 , finfo - > mtime ) ;
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , rname ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s opening remote file %s \n " , smb_errstr ( inbuf ) , CNV_LANG ( rname ) ) ) ;
free ( inbuf ) ; free ( outbuf ) ; if ( buf ) free ( buf ) ;
return ;
}
f = fopen ( lname , " r " ) ;
if ( ! f )
{
DEBUG ( 0 , ( " Error opening local file %s \n " , lname ) ) ;
free ( inbuf ) ; free ( outbuf ) ;
return ;
}
fnum = SVAL ( inbuf , smb_vwv0 ) ;
if ( finfo - > size < 0 )
finfo - > size = file_size ( lname ) ;
DEBUG ( 1 , ( " putting file %s of size %d bytes as %s " , lname , finfo - > size , CNV_LANG ( rname ) ) ) ;
if ( ! maxwrite )
maxwrite = writebraw_supported ? MAX ( max_xmit , BUFFER_SIZE ) : ( max_xmit - 200 ) ;
while ( nread < finfo - > size )
{
int n = maxwrite ;
int ret ;
n = MIN ( n , finfo - > size - nread ) ;
buf = ( char * ) Realloc ( buf , n + 4 ) ;
fseek ( f , nread , SEEK_SET ) ;
if ( ( n = readfile ( buf + 4 , 1 , n , f ) ) < 1 )
{
DEBUG ( 0 , ( " Error reading local file \n " ) ) ;
break ;
}
ret = smb_writefile ( outbuf , fnum , nread , buf + 4 , n ) ;
if ( n ! = ret ) {
if ( ! maxwrite ) {
DEBUG ( 0 , ( " Error writing file \n " ) ) ;
break ;
} else {
maxwrite / = 2 ;
continue ;
}
}
nread + = n ;
}
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 3 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBclose ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
put_dos_date3 ( outbuf , smb_vwv1 , close_time ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s closing remote file %s \n " , smb_errstr ( inbuf ) , CNV_LANG ( rname ) ) ) ;
fclose ( f ) ;
free ( inbuf ) ; free ( outbuf ) ;
if ( buf ) free ( buf ) ;
return ;
}
fclose ( f ) ;
free ( inbuf ) ; free ( outbuf ) ;
if ( buf ) free ( buf ) ;
{
struct timeval tp_end ;
int this_time ;
GetTimeOfDay ( & tp_end ) ;
this_time =
( tp_end . tv_sec - tp_start . tv_sec ) * 1000 +
( tp_end . tv_usec - tp_start . tv_usec ) / 1000 ;
put_total_time_ms + = this_time ;
put_total_size + = finfo - > size ;
1996-10-04 13:31:07 +04:00
DEBUG ( 1 , ( " (%g kb/s) (average %g kb/s) \n " ,
1996-05-04 11:50:46 +04:00
finfo - > size / ( 1.024 * this_time + 1.0e-4 ) ,
put_total_size / ( 1.024 * put_total_time_ms ) ) ) ;
}
}
/****************************************************************************
put a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_put ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
pstring lname ;
pstring rname ;
fstring buf ;
char * p = buf ;
file_info finfo ;
finfo = def_finfo ;
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , " \\ " ) ;
1996-05-04 11:50:46 +04:00
if ( ! next_token ( NULL , p , NULL ) )
{
DEBUG ( 0 , ( " put <filename> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( lname , p ) ;
1996-05-04 11:50:46 +04:00
if ( next_token ( NULL , p , NULL ) )
1998-05-12 04:55:32 +04:00
pstrcat ( rname , p ) ;
1996-05-04 11:50:46 +04:00
else
1998-05-12 04:55:32 +04:00
pstrcat ( rname , lname ) ;
1996-05-04 11:50:46 +04:00
dos_clean_name ( rname ) ;
{
struct stat st ;
if ( ! file_exist ( lname , & st ) ) {
DEBUG ( 0 , ( " %s does not exist \n " , lname ) ) ;
return ;
}
finfo . mtime = st . st_mtime ;
}
do_put ( rname , lname , & finfo ) ;
}
/****************************************************************************
seek in a directory / file list until you get something that doesn ' t start with
the specified name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL seek_list ( FILE * f , char * name )
{
pstring s ;
while ( ! feof ( f ) )
{
if ( fscanf ( f , " %s " , s ) ! = 1 ) return ( False ) ;
trim_string ( s , " ./ " , NULL ) ;
if ( strncmp ( s , name , strlen ( name ) ) ! = 0 )
{
1998-05-12 04:55:32 +04:00
pstrcpy ( name , s ) ;
1996-05-04 11:50:46 +04:00
return ( True ) ;
}
}
return ( False ) ;
}
/****************************************************************************
set the file selection mask
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_select ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
1998-05-12 04:55:32 +04:00
pstrcpy ( fileselection , " " ) ;
1996-05-04 11:50:46 +04:00
next_token ( NULL , fileselection , NULL ) ;
}
/****************************************************************************
mput some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_mput ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
pstring lname ;
pstring rname ;
file_info finfo ;
fstring buf ;
char * p = buf ;
finfo = def_finfo ;
while ( next_token ( NULL , p , NULL ) )
{
struct stat st ;
pstring cmd ;
pstring tmpname ;
FILE * f ;
1998-05-11 10:38:36 +04:00
slprintf ( tmpname , sizeof ( pstring ) - 1 ,
" %s/ls.smb.%d " , tmpdir ( ) , ( int ) getpid ( ) ) ;
1996-05-04 11:50:46 +04:00
if ( recurse )
1998-05-11 10:38:36 +04:00
slprintf ( cmd , sizeof ( pstring ) - 1 ,
" find . -name \" %s \" -print > %s " , p , tmpname ) ;
1996-05-04 11:50:46 +04:00
else
1998-05-11 10:38:36 +04:00
slprintf ( cmd , sizeof ( pstring ) - 1 ,
" /bin/ls %s > %s " , p , tmpname ) ;
1996-05-04 11:50:46 +04:00
system ( cmd ) ;
f = fopen ( tmpname , " r " ) ;
if ( ! f ) continue ;
while ( ! feof ( f ) )
{
pstring quest ;
if ( fscanf ( f , " %s " , lname ) ! = 1 ) break ;
trim_string ( lname , " ./ " , NULL ) ;
again1 :
/* check if it's a directory */
if ( directory_exist ( lname , & st ) )
{
if ( ! recurse ) continue ;
1998-05-11 10:38:36 +04:00
slprintf ( quest , sizeof ( pstring ) - 1 ,
" Put directory %s? " , lname ) ;
1996-05-04 11:50:46 +04:00
if ( prompt & & ! yesno ( quest ) )
{
1998-05-12 04:55:32 +04:00
pstrcat ( lname , " / " ) ;
1996-05-04 11:50:46 +04:00
if ( ! seek_list ( f , lname ) )
break ;
goto again1 ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , lname ) ;
1996-05-05 15:12:54 +04:00
if ( ! chkpath ( rname , False ) & & ! do_mkdir ( rname ) ) {
1998-05-12 04:55:32 +04:00
pstrcat ( lname , " / " ) ;
1996-05-05 15:12:54 +04:00
if ( ! seek_list ( f , lname ) )
break ;
goto again1 ;
}
1996-05-04 11:50:46 +04:00
continue ;
}
else
{
1998-05-11 10:38:36 +04:00
slprintf ( quest , sizeof ( quest ) - 1 ,
" Put file %s? " , lname ) ;
1996-05-04 11:50:46 +04:00
if ( prompt & & ! yesno ( quest ) ) continue ;
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , lname ) ;
1996-05-04 11:50:46 +04:00
}
dos_format ( rname ) ;
/* null size so do_put knows to ignore it */
finfo . size = - 1 ;
/* set the date on the file */
finfo . mtime = st . st_mtime ;
do_put ( rname , lname , & finfo ) ;
}
fclose ( f ) ;
unlink ( tmpname ) ;
}
}
/****************************************************************************
cancel a print job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_cancel ( int job )
{
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
bzero ( param , sizeof ( param ) ) ;
p = param ;
1996-08-13 12:57:55 +04:00
SSVAL ( p , 0 , 81 ) ; /* DosPrintJobDel() */
1996-05-04 11:50:46 +04:00
p + = 2 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " W " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , job ) ;
p + = 2 ;
1997-11-01 22:20:29 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p , param ) , 0 , 0 ,
1997-10-23 21:54:21 +04:00
6 , 1000 ,
1996-05-04 11:50:46 +04:00
& rprcnt , & rdrcnt ,
1997-10-23 17:38:46 +04:00
param , NULL , NULL ,
1996-05-04 11:50:46 +04:00
& rparam , & rdata ) )
{
int res = SVAL ( rparam , 0 ) ;
if ( ! res )
printf ( " Job %d cancelled \n " , job ) ;
else
printf ( " Error %d calcelling job %d \n " , res , job ) ;
return ;
}
else
printf ( " Server refused cancel request \n " ) ;
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return ;
}
/****************************************************************************
cancel a print job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_cancel ( char * inbuf , char * outbuf )
{
fstring buf ;
int job ;
if ( ! connect_as_printer )
{
DEBUG ( 0 , ( " WARNING: You didn't use the -P option to smbclient. \n " ) ) ;
DEBUG ( 0 , ( " Trying to cancel print jobs without -P may fail \n " ) ) ;
}
if ( ! next_token ( NULL , buf , NULL ) ) {
printf ( " cancel <jobid> ... \n " ) ;
return ;
}
do {
job = atoi ( buf ) ;
do_cancel ( job ) ;
} while ( next_token ( NULL , buf , NULL ) ) ;
}
/****************************************************************************
print a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_print ( char * inbuf , char * outbuf )
{
int fnum ;
FILE * f = NULL ;
uint32 nread = 0 ;
pstring lname ;
pstring rname ;
char * p ;
if ( ! connect_as_printer )
{
DEBUG ( 0 , ( " WARNING: You didn't use the -P option to smbclient. \n " ) ) ;
DEBUG ( 0 , ( " Trying to print without -P may fail \n " ) ) ;
}
if ( ! next_token ( NULL , lname , NULL ) )
{
DEBUG ( 0 , ( " print <filename> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , lname ) ;
1996-05-04 11:50:46 +04:00
p = strrchr ( rname , ' / ' ) ;
if ( p )
{
pstring tname ;
1998-05-12 04:55:32 +04:00
pstrcpy ( tname , p + 1 ) ;
pstrcpy ( rname , tname ) ;
1996-05-04 11:50:46 +04:00
}
if ( ( int ) strlen ( rname ) > 14 )
rname [ 14 ] = 0 ;
if ( strequal ( lname , " - " ) )
{
f = stdin ;
1998-05-12 04:55:32 +04:00
pstrcpy ( rname , " stdin " ) ;
1996-05-04 11:50:46 +04:00
}
dos_clean_name ( rname ) ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 2 , 2 + strlen ( rname ) , True ) ;
CVAL ( outbuf , smb_com ) = SMBsplopen ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , 0 ) ;
SSVAL ( outbuf , smb_vwv1 , printmode ) ;
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , rname ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s opening printer for %s \n " , smb_errstr ( inbuf ) , CNV_LANG ( rname ) ) ) ;
return ;
}
if ( ! f )
f = fopen ( lname , " r " ) ;
if ( ! f )
{
DEBUG ( 0 , ( " Error opening local file %s \n " , lname ) ) ;
return ;
}
fnum = SVAL ( inbuf , smb_vwv0 ) ;
DEBUG ( 1 , ( " printing file %s as %s \n " , lname , CNV_LANG ( rname ) ) ) ;
while ( ! feof ( f ) )
{
int n ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 1 , 3 , True ) ;
/* for some strange reason the OS/2 print server can't handle large
packets when printing . weird */
n = MIN ( 1024 , max_xmit - ( smb_len ( outbuf ) + 4 ) ) ;
if ( translation )
n = printread ( f , smb_buf ( outbuf ) + 3 , ( int ) ( 0.95 * n ) ) ;
else
n = readfile ( smb_buf ( outbuf ) + 3 , 1 , n , f ) ;
if ( n < = 0 )
{
DEBUG ( 0 , ( " read gave %d \n " , n ) ) ;
break ;
}
smb_setlen ( outbuf , smb_len ( outbuf ) + n ) ;
CVAL ( outbuf , smb_com ) = SMBsplwr ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
SSVAL ( outbuf , smb_vwv1 , n + 3 ) ;
CVAL ( smb_buf ( outbuf ) , 0 ) = 1 ;
SSVAL ( smb_buf ( outbuf ) , 1 , n ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s printing remote file \n " , smb_errstr ( inbuf ) ) ) ;
break ;
}
nread + = n ;
}
DEBUG ( 2 , ( " %d bytes printed \n " , nread ) ) ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 1 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBsplclose ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , fnum ) ;
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s closing print file \n " , smb_errstr ( inbuf ) ) ) ;
if ( f ! = stdin )
fclose ( f ) ;
return ;
}
if ( f ! = stdin )
fclose ( f ) ;
}
/****************************************************************************
1997-07-01 05:19:13 +04:00
show a print queue - this is deprecated as it uses the old smb that
has limited support - the correct call is the cmd_p_queue_4 ( ) after this .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_queue ( char * inbuf , char * outbuf )
{
int count ;
char * p ;
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 2 , 0 , True ) ;
CVAL ( outbuf , smb_com ) = SMBsplretq ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , 32 ) ; /* a max of 20 entries is to be shown */
SSVAL ( outbuf , smb_vwv1 , 0 ) ; /* the index into the queue */
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s obtaining print queue \n " , smb_errstr ( inbuf ) ) ) ;
return ;
}
count = SVAL ( inbuf , smb_vwv0 ) ;
p = smb_buf ( inbuf ) + 3 ;
if ( count < = 0 )
{
DEBUG ( 0 , ( " No entries in the print queue \n " ) ) ;
return ;
}
{
char status [ 20 ] ;
DEBUG ( 0 , ( " Job Name Size Status \n " ) ) ;
while ( count - - )
{
switch ( CVAL ( p , 4 ) )
{
1998-05-12 04:55:32 +04:00
case 0x01 : safe_strcpy ( status , " held or stopped " , sizeof ( status ) - 1 ) ; break ;
case 0x02 : safe_strcpy ( status , " printing " , sizeof ( status ) - 1 ) ; break ;
case 0x03 : safe_strcpy ( status , " awaiting print " , sizeof ( status ) - 1 ) ; break ;
case 0x04 : safe_strcpy ( status , " in intercept " , sizeof ( status ) - 1 ) ; break ;
case 0x05 : safe_strcpy ( status , " file had error " , sizeof ( status ) - 1 ) ; break ;
case 0x06 : safe_strcpy ( status , " printer error " , sizeof ( status ) - 1 ) ; break ;
default : safe_strcpy ( status , " unknown " , sizeof ( status ) - 1 ) ; break ;
1996-05-04 11:50:46 +04:00
}
DEBUG ( 0 , ( " %-6d %-16.16s %-9d %s \n " ,
SVAL ( p , 5 ) , p + 12 , IVAL ( p , 7 ) , status ) ) ;
p + = 28 ;
}
}
}
1997-07-01 05:19:13 +04:00
/****************************************************************************
show information about a print queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_p_queue_4 ( char * inbuf , char * outbuf )
{
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
int result_code = 0 ;
if ( ! connect_as_printer )
{
DEBUG ( 0 , ( " WARNING: You didn't use the -P option to smbclient. \n " ) ) ;
DEBUG ( 0 , ( " Trying to print without -P may fail \n " ) ) ;
}
bzero ( param , sizeof ( param ) ) ;
p = param ;
SSVAL ( p , 0 , 76 ) ; /* API function number 76 (DosPrintJobEnum) */
p + = 2 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " zWrLeh " ) ; /* parameter description? */
1997-07-01 05:19:13 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " WWzWWDDzz " ) ; /* returned data format */
1997-07-01 05:19:13 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , strrchr ( service , ' \\ ' ) + 1 ) ; /* name of queue */
1997-07-01 05:19:13 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 2 ) ; /* API function level 2, PRJINFO_2 data structure */
SSVAL ( p , 2 , 1000 ) ; /* size of bytes of returned data buffer */
p + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " " ) ; /* subformat */
1997-07-01 05:19:13 +04:00
p = skip_string ( p , 1 ) ;
DEBUG ( 1 , ( " Calling DosPrintJobEnum()... \n " ) ) ;
1998-02-12 14:59:55 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p , param ) , 0 , 0 ,
10 , 4096 ,
1997-07-01 05:19:13 +04:00
& rprcnt , & rdrcnt ,
1997-10-23 17:38:46 +04:00
param , NULL , NULL ,
1997-07-01 05:19:13 +04:00
& rparam , & rdata ) )
{
int converter ;
result_code = SVAL ( rparam , 0 ) ;
converter = SVAL ( rparam , 2 ) ; /* conversion factor */
DEBUG ( 2 , ( " returned %d bytes of parameters, %d bytes of data, %d records \n " , rprcnt , rdrcnt , SVAL ( rparam , 4 ) ) ) ;
if ( result_code = = 0 ) /* if no error, */
{
int i ;
uint16 JobId ;
uint16 Priority ;
uint32 Size ;
char * UserName ;
char * JobName ;
char * JobTimeStr ;
time_t JobTime ;
1998-05-12 04:55:32 +04:00
fstring PrinterName ;
1997-07-01 05:19:13 +04:00
1998-05-12 04:55:32 +04:00
fstrcpy ( PrinterName , strrchr ( service , ' \\ ' ) + 1 ) ; /* name of queue */
1997-07-01 05:19:13 +04:00
strlower ( PrinterName ) ; /* in lower case */
p = rdata ; /* received data */
for ( i = 0 ; i < SVAL ( rparam , 4 ) ; + + i )
{
JobId = SVAL ( p , 0 ) ;
Priority = SVAL ( p , 2 ) ;
UserName = fix_char_ptr ( SVAL ( p , 4 ) , converter , rdata , rdrcnt ) ;
strlower ( UserName ) ;
Priority = SVAL ( p , 2 ) ;
JobTime = make_unix_date3 ( p + 12 ) ;
JobTimeStr = asctime ( LocalTime ( & JobTime ) ) ;
Size = IVAL ( p , 16 ) ;
JobName = fix_char_ptr ( SVAL ( p , 24 ) , converter , rdata , rdrcnt ) ;
printf ( " %s-%u %s priority %u %s %s %u bytes \n " ,
PrinterName , JobId , UserName ,
Priority , JobTimeStr , JobName , Size ) ;
#if 0 /* DEBUG code */
printf ( " Job Id: \" %u \" \n " , SVAL ( p , 0 ) ) ;
printf ( " Priority: \" %u \" \n " , SVAL ( p , 2 ) ) ;
printf ( " User Name: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 4 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Position: \" %u \" \n " , SVAL ( p , 8 ) ) ;
printf ( " Status: \" %u \" \n " , SVAL ( p , 10 ) ) ;
JobTime = make_unix_date3 ( p + 12 ) ;
printf ( " Submitted: \" %s \" \n " , asctime ( LocalTime ( & JobTime ) ) ) ;
printf ( " date: \" %u \" \n " , SVAL ( p , 12 ) ) ;
printf ( " Size: \" %u \" \n " , SVAL ( p , 16 ) ) ;
printf ( " Comment: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 20 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Document: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 24 ) , converter , rdata , rdrcnt ) ) ;
# endif /* DEBUG CODE */
p + = 28 ;
}
}
}
1997-10-22 18:28:19 +04:00
else /* cli_call_api() failed */
1997-07-01 05:19:13 +04:00
{
printf ( " Failed, error = %d \n " , result_code ) ;
}
/* If any parameters or data were returned, free the storage. */
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return ;
}
1996-08-13 12:57:55 +04:00
/****************************************************************************
show information about a print queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_qinfo ( char * inbuf , char * outbuf )
{
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
1996-08-17 18:27:12 +04:00
int result_code = 0 ;
1996-08-13 12:57:55 +04:00
bzero ( param , sizeof ( param ) ) ;
p = param ;
SSVAL ( p , 0 , 70 ) ; /* API function number 70 (DosPrintQGetInfo) */
p + = 2 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " zWrLh " ) ; /* parameter description? */
1996-08-13 12:57:55 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " zWWWWzzzzWWzzl " ) ; /* returned data format */
1996-08-13 12:57:55 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , strrchr ( service , ' \\ ' ) + 1 ) ; /* name of queue */
1996-08-13 12:57:55 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 3 ) ; /* API function level 3, just queue info, no job info */
SSVAL ( p , 2 , 1000 ) ; /* size of bytes of returned data buffer */
p + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " " ) ; /* subformat */
1996-08-13 12:57:55 +04:00
p = skip_string ( p , 1 ) ;
DEBUG ( 1 , ( " Calling DosPrintQueueGetInfo()... \n " ) ) ;
1997-11-01 22:20:29 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p , param ) , 0 , 0 ,
1997-10-23 21:54:21 +04:00
10 , 4096 ,
1996-08-13 12:57:55 +04:00
& rprcnt , & rdrcnt ,
1997-10-23 17:38:46 +04:00
param , NULL , NULL ,
1996-08-13 12:57:55 +04:00
& rparam , & rdata ) )
{
int converter ;
result_code = SVAL ( rparam , 0 ) ;
converter = SVAL ( rparam , 2 ) ; /* conversion factor */
DEBUG ( 2 , ( " returned %d bytes of parameters, %d bytes of data, %d records \n " , rprcnt , rdrcnt , SVAL ( rparam , 4 ) ) ) ;
if ( result_code = = 0 ) /* if no error, */
{
p = rdata ; /* received data */
printf ( " Name: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 0 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Priority: %u \n " , SVAL ( p , 4 ) ) ;
printf ( " Start time: %u \n " , SVAL ( p , 6 ) ) ;
printf ( " Until time: %u \n " , SVAL ( p , 8 ) ) ;
printf ( " Seperator file: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 12 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Print processor: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 16 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Parameters: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 20 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Comment: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 24 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Status: %u \n " , SVAL ( p , 28 ) ) ;
printf ( " Jobs: %u \n " , SVAL ( p , 30 ) ) ;
printf ( " Printers: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 32 ) , converter , rdata , rdrcnt ) ) ;
printf ( " Drivername: \" %s \" \n " , fix_char_ptr ( SVAL ( p , 36 ) , converter , rdata , rdrcnt ) ) ;
/* Dump the driver data */
{
int count , x , y , c ;
char * ddptr ;
ddptr = rdata + SVAL ( p , 40 ) - converter ;
if ( SVAL ( p , 40 ) = = 0 ) { count = 0 ; } else { count = IVAL ( ddptr , 0 ) ; }
printf ( " Driverdata: size=%d, version=%u \n " , count , IVAL ( ddptr , 4 ) ) ;
for ( x = 8 ; x < count ; x + = 16 )
{
for ( y = 0 ; y < 16 ; y + + )
{
if ( ( x + y ) < count )
printf ( " %2.2X " , CVAL ( ddptr , ( x + y ) ) ) ;
else
fputs ( " " , stdout ) ;
}
for ( y = 0 ; y < 16 & & ( x + y ) < count ; y + + )
{
c = CVAL ( ddptr , ( x + y ) ) ;
if ( isprint ( c ) )
fputc ( c , stdout ) ;
else
fputc ( ' . ' , stdout ) ;
}
fputc ( ' \n ' , stdout ) ;
}
}
}
}
1997-10-22 18:28:19 +04:00
else /* cli_call_api() failed */
1996-08-13 12:57:55 +04:00
{
printf ( " Failed, error = %d \n " , result_code ) ;
}
/* If any parameters or data were returned, free the storage. */
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
delete some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_del ( file_info * finfo )
{
char * p ;
char * inbuf , * outbuf ;
pstring mask ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , cur_dir ) ;
pstrcat ( mask , finfo - > name ) ;
1996-05-04 11:50:46 +04:00
if ( finfo - > mode & aDIR )
return ;
inbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
outbuf = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
if ( ! inbuf | | ! outbuf )
{
DEBUG ( 0 , ( " out of memory \n " ) ) ;
return ;
}
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 1 , 2 + strlen ( mask ) , True ) ;
CVAL ( outbuf , smb_com ) = SMBunlink ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
SSVAL ( outbuf , smb_vwv0 , 0 ) ;
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , mask ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
DEBUG ( 0 , ( " %s deleting remote file %s \n " , smb_errstr ( inbuf ) , CNV_LANG ( mask ) ) ) ;
free ( inbuf ) ; free ( outbuf ) ;
}
/****************************************************************************
delete some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_del ( char * inbuf , char * outbuf )
{
pstring mask ;
fstring buf ;
int attribute = aSYSTEM | aHIDDEN ;
if ( recurse )
attribute | = aDIR ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( ! next_token ( NULL , buf , NULL ) )
{
DEBUG ( 0 , ( " del <filename> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcat ( mask , buf ) ;
1996-05-04 11:50:46 +04:00
1998-04-11 11:52:13 +04:00
do_dir ( ( char * ) inbuf , ( char * ) outbuf , mask , attribute , do_del , False , False ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
remove a directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_rmdir ( char * inbuf , char * outbuf )
{
pstring mask ;
fstring buf ;
char * p ;
1998-05-12 04:55:32 +04:00
pstrcpy ( mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( ! next_token ( NULL , buf , NULL ) )
{
DEBUG ( 0 , ( " rmdir <dirname> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcat ( mask , buf ) ;
1996-05-04 11:50:46 +04:00
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 0 , 2 + strlen ( mask ) , True ) ;
CVAL ( outbuf , smb_com ) = SMBrmdir ;
SSVAL ( outbuf , smb_tid , cnum ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , mask ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s removing remote directory file %s \n " , smb_errstr ( inbuf ) , CNV_LANG ( mask ) ) ) ;
return ;
}
}
/****************************************************************************
rename some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void cmd_rename ( char * inbuf , char * outbuf )
{
pstring src , dest ;
fstring buf , buf2 ;
char * p ;
1998-05-12 04:55:32 +04:00
pstrcpy ( src , cur_dir ) ;
pstrcpy ( dest , cur_dir ) ;
1996-05-04 11:50:46 +04:00
if ( ! next_token ( NULL , buf , NULL ) | | ! next_token ( NULL , buf2 , NULL ) )
{
DEBUG ( 0 , ( " rename <src> <dest> \n " ) ) ;
return ;
}
1998-05-12 04:55:32 +04:00
pstrcat ( src , buf ) ;
pstrcat ( dest , buf2 ) ;
1996-05-04 11:50:46 +04:00
bzero ( outbuf , smb_size ) ;
set_message ( outbuf , 1 , 4 + strlen ( src ) + strlen ( dest ) , True ) ;
CVAL ( outbuf , smb_com ) = SMBmv ;
SSVAL ( outbuf , smb_tid , cnum ) ;
SSVAL ( outbuf , smb_vwv0 , aHIDDEN | aDIR | aSYSTEM ) ;
1997-10-22 18:28:19 +04:00
cli_setup_pkt ( outbuf ) ;
1996-05-04 11:50:46 +04:00
p = smb_buf ( outbuf ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , src ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
* p + + = 4 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , dest ) ;
1996-05-04 11:50:46 +04:00
send_smb ( Client , outbuf ) ;
1997-12-20 17:36:11 +03:00
client_receive_smb ( Client , inbuf , CLIENT_TIMEOUT ) ;
1996-05-04 11:50:46 +04:00
if ( CVAL ( inbuf , smb_rcls ) ! = 0 )
{
DEBUG ( 0 , ( " %s renaming files \n " , smb_errstr ( inbuf ) ) ) ;
return ;
}
}
/****************************************************************************
toggle the prompt flag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_prompt ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
prompt = ! prompt ;
DEBUG ( 2 , ( " prompting is now %s \n " , prompt ? " on " : " off " ) ) ;
}
/****************************************************************************
set the newer than time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_newer ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
fstring buf ;
BOOL ok ;
struct stat sbuf ;
ok = next_token ( NULL , buf , NULL ) ;
if ( ok & & ( sys_stat ( buf , & sbuf ) = = 0 ) )
{
newer_than = sbuf . st_mtime ;
DEBUG ( 1 , ( " Getting files newer than %s " ,
1996-05-31 19:13:29 +04:00
asctime ( LocalTime ( & newer_than ) ) ) ) ;
1996-05-04 11:50:46 +04:00
}
else
newer_than = 0 ;
if ( ok & & newer_than = = 0 )
DEBUG ( 0 , ( " Error setting newer-than time \n " ) ) ;
}
/****************************************************************************
set the archive level
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_archive ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
fstring buf ;
if ( next_token ( NULL , buf , NULL ) ) {
archive_level = atoi ( buf ) ;
} else
DEBUG ( 0 , ( " Archive level is %d \n " , archive_level ) ) ;
}
/****************************************************************************
toggle the lowercaseflag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_lowercase ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
lowercase = ! lowercase ;
DEBUG ( 2 , ( " filename lowercasing is now %s \n " , lowercase ? " on " : " off " ) ) ;
}
/****************************************************************************
toggle the recurse flag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_recurse ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
recurse = ! recurse ;
DEBUG ( 2 , ( " directory recursion is now %s \n " , recurse ? " on " : " off " ) ) ;
}
/****************************************************************************
toggle the translate flag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_translate ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
translation = ! translation ;
DEBUG ( 2 , ( " CR/LF<->LF and print text translation now %s \n " ,
translation ? " on " : " off " ) ) ;
}
/****************************************************************************
do a printmode command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_printmode ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
fstring buf ;
fstring mode ;
if ( next_token ( NULL , buf , NULL ) )
{
if ( strequal ( buf , " text " ) )
printmode = 0 ;
else
{
if ( strequal ( buf , " graphics " ) )
printmode = 1 ;
else
printmode = atoi ( buf ) ;
}
}
switch ( printmode )
{
case 0 :
1998-05-12 04:55:32 +04:00
fstrcpy ( mode , " text " ) ;
1996-05-04 11:50:46 +04:00
break ;
case 1 :
1998-05-12 04:55:32 +04:00
fstrcpy ( mode , " graphics " ) ;
1996-05-04 11:50:46 +04:00
break ;
default :
1998-05-12 04:55:32 +04:00
slprintf ( mode , sizeof ( mode ) - 1 , " %d " , printmode ) ;
1996-05-04 11:50:46 +04:00
break ;
}
DEBUG ( 2 , ( " the printmode is now %s \n " , mode ) ) ;
}
/****************************************************************************
do the lcd command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void cmd_lcd ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
fstring buf ;
pstring d ;
if ( next_token ( NULL , buf , NULL ) )
sys_chdir ( buf ) ;
DEBUG ( 2 , ( " the local directory is now %s \n " , GetWd ( d ) ) ) ;
}
/****************************************************************************
try and browse available connections on a host
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL browse_host ( BOOL sort )
{
# ifdef NOSTRCASECMP
1997-07-24 21:25:11 +04:00
/* If strcasecmp is already defined, remove it. */
# ifdef strcasecmp
# undef strcasecmp
# endif /* strcasecmp */
1996-05-04 11:50:46 +04:00
# define strcasecmp StrCaseCmp
1997-07-24 21:25:11 +04:00
# endif /* NOSTRCASECMP */
1996-05-04 11:50:46 +04:00
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
int count = - 1 ;
/* now send a SMBtrans command with api RNetShareEnum */
p = param ;
SSVAL ( p , 0 , 0 ) ; /* api number */
p + = 2 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " WrLeh " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " B13BWz " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 1 ) ;
SSVAL ( p , 2 , BUFFER_SIZE ) ;
p + = 4 ;
1997-11-01 22:20:29 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p , param ) , 0 , 0 ,
1997-10-23 21:54:21 +04:00
1024 , BUFFER_SIZE ,
1998-06-04 22:49:13 +04:00
& rprcnt , & rdrcnt ,
param , NULL , NULL ,
& rparam , & rdata ) )
{
int res = SVAL ( rparam , 0 ) ;
int converter = SVAL ( rparam , 2 ) ;
int i ;
BOOL long_share_name = False ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
if ( res = = 0 | | res = = ERRmoredata )
{
count = SVAL ( rparam , 4 ) ;
p = rdata ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
if ( count > 0 )
{
printf ( " \n \t Sharename Type Comment \n " ) ;
printf ( " \t --------- ---- ------- \n " ) ;
}
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
if ( sort )
qsort ( p , count , 20 , QSORT_CAST StrCaseCmp ) ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
for ( i = 0 ; i < count ; i + + )
{
char * sname = p ;
int type = SVAL ( p , 14 ) ;
int comment_offset = IVAL ( p , 16 ) & 0xFFFF ;
fstring typestr ;
* typestr = 0 ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
switch ( type )
{
case STYPE_DISKTREE :
fstrcpy ( typestr , " Disk " ) ; break ;
case STYPE_PRINTQ :
fstrcpy ( typestr , " Printer " ) ; break ;
case STYPE_DEVICE :
fstrcpy ( typestr , " Device " ) ; break ;
case STYPE_IPC :
fstrcpy ( typestr , " IPC " ) ; break ;
}
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
printf ( " \t %-15.15s%-10.10s%s \n " ,
sname , typestr ,
comment_offset ? rdata + comment_offset - converter : " " ) ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
if ( strlen ( sname ) > 8 ) long_share_name = True ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
p + = 20 ;
}
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
if ( long_share_name ) {
printf ( " \n NOTE: There were share names longer than 8 chars. \n \
On older clients these may not be accessible or may give browsing errors \ n " );
}
if ( res = = ERRmoredata )
printf ( " \n NOTE: More data was available, the list was truncated. \n " ) ;
1996-05-04 11:50:46 +04:00
}
1998-06-04 22:49:13 +04:00
}
1996-05-04 11:50:46 +04:00
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return ( count > 0 ) ;
}
/****************************************************************************
get some server info
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
static void server_info ( void )
1996-05-04 11:50:46 +04:00
{
char * rparam = NULL ;
char * rdata = NULL ;
char * p ;
int rdrcnt , rprcnt ;
pstring param ;
bzero ( param , sizeof ( param ) ) ;
p = param ;
1996-08-13 12:57:55 +04:00
SSVAL ( p , 0 , 63 ) ; /* NetServerGetInfo()? */
1996-05-04 11:50:46 +04:00
p + = 2 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " WrLh " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " zzzBBzz " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , 10 ) ; /* level 10 */
SSVAL ( p , 2 , 1000 ) ;
p + = 6 ;
1997-11-01 22:20:29 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p , param ) , 0 , 0 ,
1997-10-23 21:54:21 +04:00
6 , 1000 ,
1996-05-04 11:50:46 +04:00
& rprcnt , & rdrcnt ,
1997-10-23 17:38:46 +04:00
param , NULL , NULL ,
1996-05-04 11:50:46 +04:00
& rparam , & rdata ) )
{
int res = SVAL ( rparam , 0 ) ;
int converter = SVAL ( rparam , 2 ) ;
if ( res = = 0 )
{
p = rdata ;
printf ( " \n Server=[%s] User=[%s] Workgroup=[%s] Domain=[%s] \n " ,
rdata + SVAL ( p , 0 ) - converter ,
rdata + SVAL ( p , 4 ) - converter ,
rdata + SVAL ( p , 8 ) - converter ,
rdata + SVAL ( p , 14 ) - converter ) ;
}
}
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
return ;
}
/****************************************************************************
try and browse available connections on a host
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-07-17 22:33:36 +04:00
static BOOL list_servers ( char * wk_grp )
1996-05-04 11:50:46 +04:00
{
char * rparam = NULL ;
char * rdata = NULL ;
int rdrcnt , rprcnt ;
1996-07-22 16:00:39 +04:00
char * p , * svtype_p ;
1996-05-04 11:50:46 +04:00
pstring param ;
int uLevel = 1 ;
int count = 0 ;
1996-06-04 19:14:47 +04:00
BOOL ok = False ;
1996-07-22 16:00:39 +04:00
BOOL generic_request = False ;
if ( strequal ( wk_grp , " WORKGROUP " ) ) {
/* we won't specify a workgroup */
generic_request = True ;
}
1996-05-04 11:50:46 +04:00
/* now send a SMBtrans command with api ServerEnum? */
p = param ;
SSVAL ( p , 0 , 0x68 ) ; /* api number */
p + = 2 ;
1996-07-22 16:00:39 +04:00
1998-05-12 04:55:32 +04:00
pstrcpy ( p , generic_request ? " WrLehDO " : " WrLehDz " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
1998-05-12 04:55:32 +04:00
pstrcpy ( p , " B16BBDz " ) ;
1996-05-04 11:50:46 +04:00
p = skip_string ( p , 1 ) ;
SSVAL ( p , 0 , uLevel ) ;
1997-08-26 02:18:31 +04:00
SSVAL ( p , 2 , BUFFER_SIZE - SAFETY_MARGIN ) ; /* buf length */
1996-05-04 11:50:46 +04:00
p + = 4 ;
1996-07-22 16:00:39 +04:00
svtype_p = p ;
1996-07-17 22:33:36 +04:00
p + = 4 ;
1996-07-22 16:00:39 +04:00
if ( ! generic_request ) {
1998-05-12 04:55:32 +04:00
pstrcpy ( p , wk_grp ) ;
1996-07-22 16:00:39 +04:00
p = skip_string ( p , 1 ) ;
}
/* first ask for a list of servers in this workgroup */
SIVAL ( svtype_p , 0 , SV_TYPE_ALL ) ;
1996-07-17 22:33:36 +04:00
1997-11-01 22:20:29 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p + 4 , param ) , 0 , 0 ,
1997-10-23 21:54:21 +04:00
8 , BUFFER_SIZE - SAFETY_MARGIN ,
1998-06-04 22:49:13 +04:00
& rprcnt , & rdrcnt ,
param , NULL , NULL ,
& rparam , & rdata ) )
{
int res = SVAL ( rparam , 0 ) ;
int converter = SVAL ( rparam , 2 ) ;
int i ;
if ( res = = 0 | | res = = ERRmoredata ) {
char * p2 = rdata ;
count = SVAL ( rparam , 4 ) ;
if ( count > 0 ) {
printf ( " \n \n This machine has a browse list: \n " ) ;
printf ( " \n \t Server Comment \n " ) ;
printf ( " \t --------- ------- \n " ) ;
}
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
for ( i = 0 ; i < count ; i + + ) {
char * sname = p2 ;
int comment_offset = IVAL ( p2 , 22 ) & 0xFFFF ;
printf ( " \t %-16.16s %s \n " , sname ,
comment_offset ? rdata + comment_offset - converter : " " ) ;
ok = True ;
p2 + = 26 ;
1996-05-04 11:50:46 +04:00
}
1998-06-04 22:49:13 +04:00
if ( res = = ERRmoredata )
printf ( " \n NOTE: More data was available, the list was truncated. \n " ) ;
1996-05-04 11:50:46 +04:00
}
1998-06-04 22:49:13 +04:00
}
1996-05-04 11:50:46 +04:00
if ( rparam ) { free ( rparam ) ; rparam = NULL ; }
if ( rdata ) { free ( rdata ) ; rdata = NULL ; }
1996-07-22 16:00:39 +04:00
/* now ask for a list of workgroups */
SIVAL ( svtype_p , 0 , SV_TYPE_DOMAIN_ENUM ) ;
1996-05-04 11:50:46 +04:00
1997-11-01 22:20:29 +03:00
if ( cli_call_api ( PIPE_LANMAN , 0 , PTR_DIFF ( p + 4 , param ) , 0 , 0 ,
1997-10-23 21:54:21 +04:00
8 , BUFFER_SIZE - SAFETY_MARGIN ,
1998-06-04 22:49:13 +04:00
& rprcnt , & rdrcnt ,
param , NULL , NULL ,
& rparam , & rdata ) )
{
int res = SVAL ( rparam , 0 ) ;
int converter = SVAL ( rparam , 2 ) ;
int i ;
if ( res = = 0 | | res = = ERRmoredata ) {
char * p2 = rdata ;
count = SVAL ( rparam , 4 ) ;
if ( count > 0 ) {
printf ( " \n \n This machine has a workgroup list: \n " ) ;
printf ( " \n \t Workgroup Master \n " ) ;
printf ( " \t --------- ------- \n " ) ;
}
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
for ( i = 0 ; i < count ; i + + ) {
char * sname = p2 ;
int comment_offset = IVAL ( p2 , 22 ) & 0xFFFF ;
printf ( " \t %-16.16s %s \n " , sname ,
comment_offset ? rdata + comment_offset - converter : " " ) ;
1996-05-04 11:50:46 +04:00
1998-06-04 22:49:13 +04:00
ok = True ;
p2 + = 26 ;
1996-05-04 11:50:46 +04:00
}
1998-06-04 22:49:13 +04:00
if ( res = = ERRmoredata )
printf ( " \n NOTE: More data was available, the list was truncated. \n " ) ;
1996-05-04 11:50:46 +04:00
}
1998-06-04 22:49:13 +04:00
}
1996-05-04 11:50:46 +04:00
if ( rparam ) free ( rparam ) ;
if ( rdata ) free ( rdata ) ;
1996-06-04 19:14:47 +04:00
return ( ok ) ;
1996-05-04 11:50:46 +04:00
}
/* This defines the commands supported by this client */
struct
{
char * name ;
1998-04-13 23:24:06 +04:00
void ( * fn ) ( char * , char * ) ;
1996-05-04 11:50:46 +04:00
char * description ;
} commands [ ] =
{
{ " ls " , cmd_dir , " <mask> list the contents of the current directory " } ,
{ " dir " , cmd_dir , " <mask> list the contents of the current directory " } ,
{ " lcd " , cmd_lcd , " [directory] change/report the local current working directory " } ,
{ " cd " , cmd_cd , " [directory] change/report the remote directory " } ,
{ " pwd " , cmd_pwd , " show current remote directory (same as 'cd' with no args) " } ,
{ " get " , cmd_get , " <remote name> [local name] get a file " } ,
{ " mget " , cmd_mget , " <mask> get all the matching files " } ,
{ " put " , cmd_put , " <local name> [remote name] put a file " } ,
{ " mput " , cmd_mput , " <mask> put all matching files " } ,
{ " rename " , cmd_rename , " <src> <dest> rename some files " } ,
{ " more " , cmd_more , " <remote name> view a remote file with your pager " } ,
{ " mask " , cmd_select , " <mask> mask all filenames against this " } ,
{ " del " , cmd_del , " <mask> delete all matching files " } ,
{ " rm " , cmd_del , " <mask> delete all matching files " } ,
{ " mkdir " , cmd_mkdir , " <directory> make a directory " } ,
{ " md " , cmd_mkdir , " <directory> make a directory " } ,
{ " rmdir " , cmd_rmdir , " <directory> remove a directory " } ,
{ " rd " , cmd_rmdir , " <directory> remove a directory " } ,
1997-07-01 05:19:13 +04:00
{ " pq " , cmd_p_queue_4 , " enumerate the print queue " } ,
1996-05-04 11:50:46 +04:00
{ " prompt " , cmd_prompt , " toggle prompting for filenames for mget and mput " } ,
{ " recurse " , cmd_recurse , " toggle directory recursion for mget and mput " } ,
{ " translate " , cmd_translate , " toggle text translation for printing " } ,
{ " lowercase " , cmd_lowercase , " toggle lowercasing of filenames for get " } ,
{ " print " , cmd_print , " <file name> print a file " } ,
{ " printmode " , cmd_printmode , " <graphics or text> set the print mode " } ,
{ " queue " , cmd_queue , " show the print queue " } ,
1996-08-13 12:57:55 +04:00
{ " qinfo " , cmd_qinfo , " show print queue information " } ,
1996-05-04 11:50:46 +04:00
{ " cancel " , cmd_cancel , " <jobid> cancel a print queue entry " } ,
1997-10-22 18:28:19 +04:00
{ " quit " , cli_send_logout , " logoff the server " } ,
{ " q " , cli_send_logout , " logoff the server " } ,
{ " exit " , cli_send_logout , " logoff the server " } ,
1996-05-04 11:50:46 +04:00
{ " newer " , cmd_newer , " <file> only mget files newer than the specified local file " } ,
{ " archive " , cmd_archive , " <level> \n 0=ignore archive bit \n 1=only get archive files \n 2=only get archive files and reset archive bit \n 3=get all files and reset archive bit " } ,
{ " tar " , cmd_tar , " tar <c|x>[IXbgNa] current directory to/from <file name> " } ,
{ " blocksize " , cmd_block , " blocksize <number> (default 20) " } ,
{ " tarmode " , cmd_tarmode ,
" <full|inc|reset|noreset> tar's behaviour towards archive bits " } ,
{ " setmode " , cmd_setmode , " filename <setmode string> change modes of file " } ,
{ " help " , cmd_help , " [command] give help on a command " } ,
{ " ? " , cmd_help , " [command] give help on a command " } ,
{ " ! " , NULL , " run a shell command on the local system " } ,
{ " " , NULL , NULL }
} ;
/*******************************************************************
lookup a command string in the list of commands , including
abbreviations
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int process_tok ( fstring tok )
{
int i = 0 , matches = 0 ;
int cmd = 0 ;
int tok_len = strlen ( tok ) ;
while ( commands [ i ] . fn ! = NULL )
{
if ( strequal ( commands [ i ] . name , tok ) )
{
matches = 1 ;
cmd = i ;
break ;
}
1997-12-24 07:32:01 +03:00
else if ( strnequal ( commands [ i ] . name , tok , tok_len ) )
1996-05-04 11:50:46 +04:00
{
matches + + ;
cmd = i ;
}
i + + ;
}
if ( matches = = 0 )
return ( - 1 ) ;
else if ( matches = = 1 )
return ( cmd ) ;
else
return ( - 2 ) ;
}
/****************************************************************************
help
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-04-13 23:24:06 +04:00
void cmd_help ( char * dum_in , char * dum_out )
1996-05-04 11:50:46 +04:00
{
int i = 0 , j ;
fstring buf ;
if ( next_token ( NULL , buf , NULL ) )
{
if ( ( i = process_tok ( buf ) ) > = 0 )
DEBUG ( 0 , ( " HELP %s: \n \t %s \n \n " , commands [ i ] . name , commands [ i ] . description ) ) ;
}
else
while ( commands [ i ] . description )
{
for ( j = 0 ; commands [ i ] . description & & ( j < 5 ) ; j + + ) {
DEBUG ( 0 , ( " %-15s " , commands [ i ] . name ) ) ;
i + + ;
}
DEBUG ( 0 , ( " \n " ) ) ;
}
}
/****************************************************************************
wait for keyboard activity , swallowing network packets
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# ifdef CLIX
static char wait_keyboard ( char * buffer )
# else
static void wait_keyboard ( char * buffer )
# endif
{
fd_set fds ;
int selrtn ;
struct timeval timeout ;
# ifdef CLIX
int delay = 0 ;
# endif
while ( 1 )
{
extern int Client ;
FD_ZERO ( & fds ) ;
FD_SET ( Client , & fds ) ;
# ifndef CLIX
FD_SET ( fileno ( stdin ) , & fds ) ;
# endif
timeout . tv_sec = 20 ;
timeout . tv_usec = 0 ;
# ifdef CLIX
timeout . tv_sec = 0 ;
# endif
selrtn = sys_select ( & fds , & timeout ) ;
# ifndef CLIX
if ( FD_ISSET ( fileno ( stdin ) , & fds ) )
return ;
# else
{
char ch ;
int readret ;
1997-07-24 21:25:11 +04:00
set_blocking ( fileno ( stdin ) , False ) ;
1996-05-04 11:50:46 +04:00
readret = read_data ( fileno ( stdin ) , & ch , 1 ) ;
1997-07-24 21:25:11 +04:00
set_blocking ( fileno ( stdin ) , True ) ;
1996-05-04 11:50:46 +04:00
if ( readret = = - 1 )
{
if ( errno ! = EAGAIN )
{
/* should crash here */
DEBUG ( 1 , ( " readchar stdin failed \n " ) ) ;
}
}
else if ( readret ! = 0 )
{
return ch ;
}
}
# endif
1997-12-20 17:36:11 +03:00
/* We deliberately use receive_smb instead of
client_receive_smb as we want to receive
session keepalives and then drop them here .
*/
1996-05-04 11:50:46 +04:00
if ( FD_ISSET ( Client , & fds ) )
receive_smb ( Client , buffer , 0 ) ;
# ifdef CLIX
delay + + ;
if ( delay > 100000 )
{
delay = 0 ;
chkpath ( " \\ " , False ) ;
}
# else
chkpath ( " \\ " , False ) ;
# endif
}
}
/****************************************************************************
process commands from the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-06-04 10:42:03 +04:00
static BOOL process ( char * base_directory )
1996-05-04 11:50:46 +04:00
{
extern FILE * dbf ;
pstring line ;
1996-05-31 19:13:29 +04:00
char * cmd ;
1996-05-04 11:50:46 +04:00
char * InBuffer = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
char * OutBuffer = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
if ( ( InBuffer = = NULL ) | | ( OutBuffer = = NULL ) )
return ( False ) ;
bzero ( OutBuffer , smb_size ) ;
1998-01-06 01:54:32 +03:00
if ( ! cli_send_login ( InBuffer , OutBuffer , True , True , NULL ) )
1996-05-04 11:50:46 +04:00
return ( False ) ;
if ( * base_directory ) do_cd ( base_directory ) ;
1996-05-31 19:13:29 +04:00
cmd = cmdstr ;
if ( cmd [ 0 ] ! = ' \0 ' ) while ( cmd [ 0 ] ! = ' \0 ' )
{
char * p ;
fstring tok ;
int i ;
if ( ( p = strchr ( cmd , ' ; ' ) ) = = 0 )
{
strncpy ( line , cmd , 999 ) ;
line [ 1000 ] = ' \0 ' ;
cmd + = strlen ( cmd ) ;
}
else
{
if ( p - cmd > 999 ) p = cmd + 999 ;
strncpy ( line , cmd , p - cmd ) ;
line [ p - cmd ] = ' \0 ' ;
cmd = p + 1 ;
}
/* input language code to internal one */
CNV_INPUT ( line ) ;
/* and get the first part of the command */
{
char * ptr = line ;
if ( ! next_token ( & ptr , tok , NULL ) ) continue ;
}
if ( ( i = process_tok ( tok ) ) > = 0 )
commands [ i ] . fn ( InBuffer , OutBuffer ) ;
else if ( i = = - 2 )
DEBUG ( 0 , ( " %s: command abbreviation ambiguous \n " , CNV_LANG ( tok ) ) ) ;
else
DEBUG ( 0 , ( " %s: command not found \n " , CNV_LANG ( tok ) ) ) ;
}
else while ( ! feof ( stdin ) )
1996-05-04 11:50:46 +04:00
{
fstring tok ;
int i ;
bzero ( OutBuffer , smb_size ) ;
/* display a prompt */
1997-07-24 21:25:11 +04:00
DEBUG ( 0 , ( " smb: %s> " , CNV_LANG ( cur_dir ) ) ) ;
1996-05-04 11:50:46 +04:00
fflush ( dbf ) ;
# ifdef CLIX
line [ 0 ] = wait_keyboard ( InBuffer ) ;
/* this might not be such a good idea... */
if ( line [ 0 ] = = EOF )
break ;
# else
wait_keyboard ( InBuffer ) ;
# endif
/* and get a response */
# ifdef CLIX
fgets ( & line [ 1 ] , 999 , stdin ) ;
# else
if ( ! fgets ( line , 1000 , stdin ) )
break ;
# endif
/* input language code to internal one */
CNV_INPUT ( line ) ;
/* special case - first char is ! */
if ( * line = = ' ! ' )
{
system ( line + 1 ) ;
continue ;
}
/* and get the first part of the command */
{
char * ptr = line ;
if ( ! next_token ( & ptr , tok , NULL ) ) continue ;
}
if ( ( i = process_tok ( tok ) ) > = 0 )
commands [ i ] . fn ( InBuffer , OutBuffer ) ;
else if ( i = = - 2 )
DEBUG ( 0 , ( " %s: command abbreviation ambiguous \n " , CNV_LANG ( tok ) ) ) ;
else
DEBUG ( 0 , ( " %s: command not found \n " , CNV_LANG ( tok ) ) ) ;
}
1998-04-13 23:24:06 +04:00
cli_send_logout ( InBuffer , OutBuffer ) ;
1996-05-04 11:50:46 +04:00
return ( True ) ;
}
/****************************************************************************
usage on the program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-06-04 10:42:03 +04:00
static void usage ( char * pname )
1996-05-04 11:50:46 +04:00
{
DEBUG ( 0 , ( " Usage: %s service <password> [-p port] [-d debuglevel] [-l log] " ,
pname ) ) ;
DEBUG ( 0 , ( " \n Version %s \n " , VERSION ) ) ;
1997-12-03 02:32:03 +03:00
DEBUG ( 0 , ( " \t -p port connect to the specified port \n " ) ) ;
1996-05-04 11:50:46 +04:00
DEBUG ( 0 , ( " \t -d debuglevel set the debuglevel \n " ) ) ;
DEBUG ( 0 , ( " \t -l log basename. Basename for log/debug files \n " ) ) ;
DEBUG ( 0 , ( " \t -n netbios name. Use this name as my netbios name \n " ) ) ;
DEBUG ( 0 , ( " \t -N don't ask for a password \n " ) ) ;
DEBUG ( 0 , ( " \t -P connect to service as a printer \n " ) ) ;
DEBUG ( 0 , ( " \t -M host send a winpopup message to the host \n " ) ) ;
DEBUG ( 0 , ( " \t -m max protocol set the max protocol level \n " ) ) ;
DEBUG ( 0 , ( " \t -L host get a list of shares available on a host \n " ) ) ;
DEBUG ( 0 , ( " \t -I dest IP use this IP to connect to \n " ) ) ;
1998-03-16 23:59:47 +03:00
DEBUG ( 0 , ( " \t -R name resolve order use these name resolution services only \n " ) ) ;
1996-05-04 11:50:46 +04:00
DEBUG ( 0 , ( " \t -E write messages to stderr instead of stdout \n " ) ) ;
DEBUG ( 0 , ( " \t -U username set the network username \n " ) ) ;
DEBUG ( 0 , ( " \t -W workgroup set the workgroup name \n " ) ) ;
1996-05-31 19:13:29 +04:00
DEBUG ( 0 , ( " \t -c command string execute semicolon separated commands \n " ) ) ;
1996-05-04 11:50:46 +04:00
DEBUG ( 0 , ( " \t -t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex} \n " ) ) ;
DEBUG ( 0 , ( " \t -T<c|x>IXgbNa command line tar \n " ) ) ;
DEBUG ( 0 , ( " \t -D directory start from directory \n " ) ) ;
DEBUG ( 0 , ( " \n " ) ) ;
}
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-06-04 10:42:03 +04:00
int main ( int argc , char * argv [ ] )
1996-05-04 11:50:46 +04:00
{
fstring base_directory ;
char * pname = argv [ 0 ] ;
1996-06-04 10:42:03 +04:00
int port = SMB_PORT ;
1996-05-04 11:50:46 +04:00
int opt ;
extern FILE * dbf ;
extern char * optarg ;
extern int optind ;
pstring query_host ;
BOOL message = False ;
1997-10-22 21:51:02 +04:00
BOOL nt_domain_logon = False ;
1996-05-04 11:50:46 +04:00
extern char tar_type ;
1996-07-24 10:14:23 +04:00
static pstring servicesf = CONFIGFILE ;
1997-09-12 00:17:32 +04:00
pstring term_code ;
1998-03-16 23:59:47 +03:00
pstring new_name_resolve_order ;
1997-09-19 21:12:08 +04:00
char * p ;
1998-03-26 22:11:31 +03:00
int save_debuglevel = - 1 ;
1997-09-12 00:17:32 +04:00
# ifdef KANJI
1998-05-12 04:55:32 +04:00
pstrcpy ( term_code , KANJI ) ;
1997-09-12 00:17:32 +04:00
# else /* KANJI */
* term_code = 0 ;
# endif /* KANJI */
1996-05-04 11:50:46 +04:00
* query_host = 0 ;
* base_directory = 0 ;
1998-03-16 23:59:47 +03:00
* new_name_resolve_order = 0 ;
1996-05-04 11:50:46 +04:00
DEBUGLEVEL = 2 ;
setup_logging ( pname , True ) ;
TimeInit ( ) ;
1997-07-19 00:21:32 +04:00
charset_initialise ( ) ;
1996-05-04 11:50:46 +04:00
pid = getpid ( ) ;
uid = getuid ( ) ;
gid = getgid ( ) ;
mid = pid + 100 ;
myumask = umask ( 0 ) ;
umask ( myumask ) ;
if ( getenv ( " USER " ) )
1997-09-19 21:12:08 +04:00
{
1998-05-12 04:55:32 +04:00
pstrcpy ( username , getenv ( " USER " ) ) ;
1997-09-19 21:12:08 +04:00
/* modification to support userid%passwd syntax in the USER var
25. Aug .97 , jdblair @ uab . edu */
if ( ( p = strchr ( username , ' % ' ) ) )
1996-05-04 11:50:46 +04:00
{
1997-09-19 21:12:08 +04:00
* p = 0 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( password , p + 1 ) ;
1997-09-19 21:12:08 +04:00
got_pass = True ;
memset ( strchr ( getenv ( " USER " ) , ' % ' ) + 1 , ' X ' , strlen ( password ) ) ;
1996-05-04 11:50:46 +04:00
}
1997-09-19 21:12:08 +04:00
strupper ( username ) ;
}
/* modification to support PASSWD environmental var
25. Aug .97 , jdblair @ uab . edu */
if ( getenv ( " PASSWD " ) )
1998-05-12 04:55:32 +04:00
pstrcpy ( password , getenv ( " PASSWD " ) ) ;
1996-05-04 11:50:46 +04:00
if ( * username = = 0 & & getenv ( " LOGNAME " ) )
{
1998-05-12 04:55:32 +04:00
pstrcpy ( username , getenv ( " LOGNAME " ) ) ;
1996-05-04 11:50:46 +04:00
strupper ( username ) ;
}
if ( argc < 2 )
{
usage ( pname ) ;
exit ( 1 ) ;
}
if ( * argv [ 1 ] ! = ' - ' )
{
1998-05-12 04:55:32 +04:00
pstrcpy ( service , argv [ 1 ] ) ;
1997-05-09 01:17:59 +04:00
/* Convert any '/' characters in the service name to '\' characters */
string_replace ( service , ' / ' , ' \\ ' ) ;
1996-05-04 11:50:46 +04:00
argc - - ;
argv + + ;
if ( count_chars ( service , ' \\ ' ) < 3 )
{
usage ( pname ) ;
printf ( " \n %s: Not enough ' \\ ' characters in service \n " , service ) ;
exit ( 1 ) ;
}
/*
if ( count_chars ( service , ' \\ ' ) > 3 )
{
usage ( pname ) ;
printf ( " \n %s: Too many ' \\ ' characters in service \n " , service ) ;
exit ( 1 ) ;
}
*/
if ( argc > 1 & & ( * argv [ 1 ] ! = ' - ' ) )
{
got_pass = True ;
1998-05-12 04:55:32 +04:00
pstrcpy ( password , argv [ 1 ] ) ;
1996-05-04 11:50:46 +04:00
memset ( argv [ 1 ] , ' X ' , strlen ( argv [ 1 ] ) ) ;
argc - - ;
argv + + ;
}
}
1996-05-31 19:13:29 +04:00
while ( ( opt =
1998-03-16 23:59:47 +03:00
getopt ( argc , argv , " s:B:O:R:M:S:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c: " ) ) ! = EOF )
1996-05-04 11:50:46 +04:00
switch ( opt )
{
case ' m ' :
max_protocol = interpret_protocol ( optarg , max_protocol ) ;
break ;
case ' O ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( user_socket_options , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
1998-03-16 23:59:47 +03:00
case ' R ' :
pstrcpy ( new_name_resolve_order , optarg ) ;
break ;
1997-10-22 21:51:02 +04:00
case ' S ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( desthost , optarg ) ;
1997-10-22 21:51:02 +04:00
strupper ( desthost ) ;
nt_domain_logon = True ;
break ;
1996-05-04 11:50:46 +04:00
case ' M ' :
1997-04-03 20:57:06 +04:00
name_type = 0x03 ; /* messages are sent to NetBIOS name type 0x3 */
1998-05-12 04:55:32 +04:00
pstrcpy ( desthost , optarg ) ;
1996-05-04 11:50:46 +04:00
strupper ( desthost ) ;
message = True ;
break ;
case ' B ' :
1996-06-06 15:43:09 +04:00
iface_set_default ( NULL , optarg , NULL ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' D ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( base_directory , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' T ' :
if ( ! tar_parseargs ( argc , argv , optarg , optind ) ) {
usage ( pname ) ;
exit ( 1 ) ;
}
break ;
case ' i ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( scope , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' L ' :
got_pass = True ;
1998-05-12 04:55:32 +04:00
pstrcpy ( query_host , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' U ' :
{
1997-10-06 21:52:25 +04:00
char * lp ;
1998-05-12 04:55:32 +04:00
pstrcpy ( username , optarg ) ;
1997-10-06 21:52:25 +04:00
if ( ( lp = strchr ( username , ' % ' ) ) )
1996-05-04 11:50:46 +04:00
{
1997-10-06 21:52:25 +04:00
* lp = 0 ;
1998-05-12 04:55:32 +04:00
pstrcpy ( password , lp + 1 ) ;
1996-05-04 11:50:46 +04:00
got_pass = True ;
memset ( strchr ( optarg , ' % ' ) + 1 , ' X ' , strlen ( password ) ) ;
}
}
break ;
case ' W ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( workgroup , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' E ' :
dbf = stderr ;
break ;
case ' I ' :
{
dest_ip = * interpret_addr2 ( optarg ) ;
if ( zero_ip ( dest_ip ) ) exit ( 1 ) ;
have_ip = True ;
}
break ;
case ' n ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( global_myname , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' N ' :
got_pass = True ;
1998-02-26 23:41:05 +03:00
no_pass = True ;
1996-05-04 11:50:46 +04:00
break ;
case ' P ' :
connect_as_printer = True ;
break ;
case ' d ' :
if ( * optarg = = ' A ' )
1998-03-26 22:11:31 +03:00
save_debuglevel = DEBUGLEVEL = 10000 ;
1996-05-04 11:50:46 +04:00
else
1998-03-26 22:11:31 +03:00
save_debuglevel = DEBUGLEVEL = atoi ( optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' l ' :
1998-05-11 10:38:36 +04:00
slprintf ( debugf , sizeof ( debugf ) - 1 , " %s.client " , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
case ' p ' :
port = atoi ( optarg ) ;
break ;
1996-05-31 19:13:29 +04:00
case ' c ' :
cmdstr = optarg ;
got_pass = True ;
break ;
1996-05-04 11:50:46 +04:00
case ' h ' :
usage ( pname ) ;
exit ( 0 ) ;
break ;
1996-07-24 10:14:23 +04:00
case ' s ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( servicesf , optarg ) ;
1996-07-24 10:14:23 +04:00
break ;
1996-05-04 11:50:46 +04:00
case ' t ' :
1998-05-12 04:55:32 +04:00
pstrcpy ( term_code , optarg ) ;
1996-05-04 11:50:46 +04:00
break ;
default :
usage ( pname ) ;
exit ( 1 ) ;
}
if ( ! tar_type & & ! * query_host & & ! * service & & ! message )
{
usage ( pname ) ;
exit ( 1 ) ;
}
DEBUG ( 3 , ( " %s client started (version %s) \n " , timestring ( ) , VERSION ) ) ;
1997-09-06 01:32:32 +04:00
if ( ! get_myname ( myhostname , NULL ) )
{
DEBUG ( 0 , ( " Failed to get my hostname. \n " ) ) ;
}
1998-03-14 11:27:41 +03:00
if ( ! lp_load ( servicesf , True , False , False ) ) {
1996-07-24 10:14:23 +04:00
fprintf ( stderr , " Can't load %s - run testparm to debug it \n " , servicesf ) ;
}
1997-09-12 00:17:32 +04:00
1998-03-26 22:11:31 +03:00
/*
* We need to reset the global debuglevel here , as
* lp_load will reset it from smb . conf .
*/
if ( save_debuglevel ! = - 1 )
DEBUGLEVEL = save_debuglevel ;
1997-09-12 00:17:32 +04:00
codepage_initialise ( lp_client_code_page ( ) ) ;
1998-03-03 23:19:14 +03:00
interpret_coding_system ( term_code ) ;
1996-07-24 10:14:23 +04:00
1996-10-05 06:54:37 +04:00
if ( * workgroup = = 0 )
1998-05-12 04:55:32 +04:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
1996-10-05 06:54:37 +04:00
1996-06-06 15:43:09 +04:00
load_interfaces ( ) ;
1998-04-25 05:12:08 +04:00
get_myname ( ( * global_myname ) ? NULL : global_myname , NULL ) ;
strupper ( global_myname ) ;
1996-05-04 11:50:46 +04:00
1998-03-16 23:59:47 +03:00
if ( * new_name_resolve_order )
lp_set_name_resolve_order ( new_name_resolve_order ) ;
1996-05-04 11:50:46 +04:00
if ( tar_type ) {
recurse = True ;
1997-10-22 18:28:19 +04:00
if ( cli_open_sockets ( port ) ) {
1996-05-04 11:50:46 +04:00
char * InBuffer = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
char * OutBuffer = ( char * ) malloc ( BUFFER_SIZE + SAFETY_MARGIN ) ;
int ret ;
if ( ( InBuffer = = NULL ) | | ( OutBuffer = = NULL ) )
return ( 1 ) ;
bzero ( OutBuffer , smb_size ) ;
1998-01-06 01:54:32 +03:00
if ( ! cli_send_login ( InBuffer , OutBuffer , True , True , NULL ) )
1996-05-04 11:50:46 +04:00
return ( False ) ;
if ( * base_directory ) do_cd ( base_directory ) ;
ret = process_tar ( InBuffer , OutBuffer ) ;
1998-04-13 23:24:06 +04:00
cli_send_logout ( InBuffer , OutBuffer ) ;
1996-05-04 11:50:46 +04:00
close_sockets ( ) ;
return ( ret ) ;
} else
return ( 1 ) ;
}
1997-10-22 21:51:02 +04:00
if ( * query_host & & ! nt_domain_logon )
1996-05-04 11:50:46 +04:00
{
int ret = 0 ;
1998-05-11 10:38:36 +04:00
slprintf ( service , sizeof ( service ) - 1 ,
" \\ \\ %s \\ IPC$ " , query_host ) ;
1996-05-04 11:50:46 +04:00
strupper ( service ) ;
connect_as_ipc = True ;
1997-10-22 18:28:19 +04:00
if ( cli_open_sockets ( port ) )
1996-05-04 11:50:46 +04:00
{
#if 0
* username = 0 ;
# endif
1998-01-06 01:54:32 +03:00
if ( ! cli_send_login ( NULL , NULL , True , True , NULL ) )
1996-05-04 11:50:46 +04:00
return ( 1 ) ;
server_info ( ) ;
if ( ! browse_host ( True ) ) {
sleep ( 1 ) ;
browse_host ( True ) ;
}
1996-07-17 22:33:36 +04:00
if ( ! list_servers ( workgroup ) ) {
1996-05-04 11:50:46 +04:00
sleep ( 1 ) ;
1996-07-17 22:33:36 +04:00
list_servers ( workgroup ) ;
1996-05-04 11:50:46 +04:00
}
1998-04-13 23:24:06 +04:00
cli_send_logout ( NULL , NULL ) ;
1996-05-04 11:50:46 +04:00
close_sockets ( ) ;
}
return ( ret ) ;
}
if ( message )
{
int ret = 0 ;
1997-10-22 18:28:19 +04:00
if ( cli_open_sockets ( port ) )
1996-05-04 11:50:46 +04:00
{
pstring inbuf , outbuf ;
bzero ( outbuf , smb_size ) ;
1997-10-22 18:28:19 +04:00
if ( ! cli_send_session_request ( inbuf , outbuf ) )
1996-05-04 11:50:46 +04:00
return ( 1 ) ;
send_message ( inbuf , outbuf ) ;
close_sockets ( ) ;
}
return ( ret ) ;
}
1997-10-22 18:28:19 +04:00
if ( cli_open_sockets ( port ) )
1996-05-04 11:50:46 +04:00
{
if ( ! process ( base_directory ) )
{
close_sockets ( ) ;
return ( 1 ) ;
}
close_sockets ( ) ;
}
else
return ( 1 ) ;
return ( 0 ) ;
}