1996-05-04 11:50:46 +04:00
/*
Unix SMB / Netbios implementation .
2001-10-09 23:12:18 +04:00
Version 3.0 .
1996-05-04 11:50:46 +04:00
SMB client
1998-01-22 16:27:43 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
2001-10-09 23:12:18 +04:00
Copyright ( C ) Simo Sorce 2001
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 .
*/
1998-07-29 07:08:05 +04:00
# define NO_SYSLOG
1996-05-04 11:50:46 +04:00
# include "includes.h"
# ifndef REGISTER
# define REGISTER 0
# endif
2001-11-19 05:49:53 +03:00
const char prog_name [ ] = " smbclient " ;
1998-11-09 06:45:49 +03:00
struct cli_state * cli ;
1998-10-07 03:46:01 +04:00
extern BOOL in_client ;
2001-08-25 00:11:09 +04:00
static int port = 0 ;
1996-05-04 11:50:46 +04:00
pstring cur_dir = " \\ " ;
pstring cd_path = " " ;
1998-11-09 06:45:49 +03:00
static pstring service ;
static pstring desthost ;
1998-04-25 05:12:08 +04:00
extern pstring global_myname ;
1998-11-09 06:45:49 +03:00
static pstring password ;
static pstring username ;
static pstring workgroup ;
static char * cmdstr ;
static BOOL got_pass ;
2001-01-25 09:40:44 +03:00
static int io_bufsize = 64512 ;
2001-10-11 11:42:52 +04:00
static BOOL use_kerberos ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
static int name_type = 0x20 ;
2001-02-26 02:45:06 +03:00
static int max_protocol = PROTOCOL_NT1 ;
1996-05-04 11:50:46 +04:00
extern pstring user_socket_options ;
1998-09-05 09:07:05 +04:00
static int process_tok ( fstring tok ) ;
2001-10-09 23:12:18 +04:00
static int cmd_help ( void ) ;
1998-09-05 09:07:05 +04:00
1996-05-04 11:50:46 +04:00
/* 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)
time_t newer_than = 0 ;
int archive_level = 0 ;
BOOL translation = False ;
1998-11-09 06:45:49 +03:00
static BOOL have_ip ;
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 */
1998-09-29 01:43:48 +04:00
mode_t myumask = 0755 ;
1996-05-04 11:50:46 +04:00
BOOL prompt = True ;
int printmode = 1 ;
1998-11-09 06:45:49 +03:00
static BOOL recurse = False ;
1996-05-04 11:50:46 +04:00
BOOL lowercase = False ;
struct in_addr dest_ip ;
# define SEPARATORS " \t\n\r"
BOOL abort_mget = True ;
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 */
1999-03-30 14:25:20 +04:00
static double dir_total ;
1996-05-04 11:50:46 +04:00
# define USENMB
/****************************************************************************
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 )
{
1998-11-09 06:45:49 +03:00
int i ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! translation ) {
return write ( f , b , n ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
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 + + ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
return ( i ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
read from a file with LF - > CR / LF translation if appropriate . return the
number read . read approx n bytes .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-09-10 15:08:57 +04:00
static int readfile ( char * b , int n , XFILE * f )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
int i ;
int c ;
1996-05-04 11:50:46 +04:00
2001-09-09 07:18:23 +04:00
if ( ! translation )
2001-09-10 15:08:57 +04:00
return x_fread ( b , 1 , n , f ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
i = 0 ;
1999-12-13 16:27:58 +03:00
while ( i < ( n - 1 ) & & ( i < BUFFER_SIZE ) ) {
2001-09-10 15:08:57 +04:00
if ( ( c = x_getc ( f ) ) = = EOF ) {
1998-11-09 06:45:49 +03:00
break ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( c = = ' \n ' ) { /* change all LFs to CR/LF */
b [ i + + ] = ' \r ' ;
}
1996-05-04 11:50:46 +04:00
1999-12-13 16:27:58 +03:00
b [ i + + ] = c ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
return ( i ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
send a message
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-09 06:45:49 +03:00
static void send_message ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
int total_len = 0 ;
int grp_id ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_message_start ( cli , desthost , username , & grp_id ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " message start: %s \n " , cli_errstr ( cli ) ) ;
1998-11-09 06:45:49 +03:00
return ;
}
1996-05-04 11:50:46 +04:00
2001-09-07 18:14:57 +04:00
d_printf ( " Connected. Type your message, ending it with a Control-D \n " ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
while ( ! feof ( stdin ) & & total_len < 1600 ) {
int maxlen = MIN ( 1600 - total_len , 127 ) ;
pstring msg ;
int l = 0 ;
int c ;
1996-05-04 11:50:46 +04:00
1998-11-13 06:37:01 +03:00
ZERO_ARRAY ( msg ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
for ( l = 0 ; l < maxlen & & ( c = fgetc ( stdin ) ) ! = EOF ; l + + ) {
if ( c = = ' \n ' )
msg [ l + + ] = ' \r ' ;
msg [ l ] = c ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_message_text ( cli , msg , l , grp_id ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " SMBsendtxt failed (%s) \n " , cli_errstr ( cli ) ) ;
1998-11-09 06:45:49 +03:00
return ;
}
total_len + = l ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( total_len > = 1600 )
2001-09-07 18:14:57 +04:00
d_printf ( " the message was truncated to 1600 bytes \n " ) ;
1998-11-09 06:45:49 +03:00
else
2001-09-07 18:14:57 +04:00
d_printf ( " sent %d bytes \n " , total_len ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_message_end ( cli , grp_id ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " SMBsendend failed (%s) \n " , cli_errstr ( cli ) ) ;
1998-11-09 06:45:49 +03:00
return ;
1996-05-04 11:50:46 +04:00
}
}
/****************************************************************************
check the space on a device
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int do_dskattr ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
int total , bsize , avail ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_dskattr ( cli , & bsize , & total , & avail ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error in dskattr: %s \n " , cli_errstr ( cli ) ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2001-09-07 18:14:57 +04:00
d_printf ( " \n \t \t %d blocks of size %d. %d blocks available \n " ,
total , bsize , avail ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
show cd / pwd
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_pwd ( void )
1996-05-04 11:50:46 +04:00
{
2001-09-07 18:14:57 +04:00
d_printf ( " Current directory is %s " , service ) ;
d_printf ( " %s \n " , cur_dir ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
change directory - inner section
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int do_cd ( char * newdir )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
char * p = newdir ;
pstring saved_dir ;
pstring dname ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
dos_format ( newdir ) ;
/* Save the current directory in case the
new directory is invalid */
pstrcpy ( saved_dir , cur_dir ) ;
if ( * p = = ' \\ ' )
pstrcpy ( cur_dir , p ) ;
else
pstrcat ( cur_dir , p ) ;
if ( * ( cur_dir + strlen ( cur_dir ) - 1 ) ! = ' \\ ' ) {
pstrcat ( cur_dir , " \\ " ) ;
}
dos_clean_name ( cur_dir ) ;
pstrcpy ( dname , cur_dir ) ;
pstrcat ( cur_dir , " \\ " ) ;
dos_clean_name ( cur_dir ) ;
if ( ! strequal ( cur_dir , " \\ " ) ) {
if ( ! cli_chkpath ( cli , dname ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " cd %s: %s \n " , dname , cli_errstr ( cli ) ) ;
1998-11-09 06:45:49 +03:00
pstrcpy ( cur_dir , saved_dir ) ;
}
}
pstrcpy ( cd_path , cur_dir ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
change directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_cd ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring buf ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) )
2001-10-09 23:12:18 +04:00
rc = do_cd ( buf ) ;
1998-11-09 06:45:49 +03:00
else
2001-09-07 18:14:57 +04:00
d_printf ( " Current directory is %s \n " , cur_dir ) ;
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
/*******************************************************************
decide if a file should be operated on
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL do_this_one ( file_info * finfo )
{
if ( finfo - > mode & aDIR ) return ( True ) ;
if ( * fileselection & &
2000-04-30 15:04:28 +04:00
! mask_match ( finfo - > name , fileselection , False ) ) {
1998-11-09 06:45:49 +03:00
DEBUG ( 3 , ( " match_match %s failed \n " , finfo - > name ) ) ;
return False ;
}
if ( newer_than & & finfo - > mtime < newer_than ) {
DEBUG ( 3 , ( " newer_than %s failed \n " , finfo - > name ) ) ;
return ( False ) ;
}
if ( ( archive_level = = 1 | | archive_level = = 2 ) & & ! ( finfo - > mode & aARCH ) ) {
DEBUG ( 3 , ( " archive %s failed \n " , finfo - > name ) ) ;
return ( False ) ;
}
return ( True ) ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
display info about a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void display_finfo ( file_info * finfo )
{
1998-11-09 06:45:49 +03:00
if ( do_this_one ( finfo ) ) {
time_t t = finfo - > mtime ; /* the time is assumed to be passed as GMT */
2001-09-07 18:14:57 +04:00
d_printf ( " %-30s%7.7s %8.0f %s " ,
2000-01-05 22:59:42 +03:00
finfo - > name ,
1998-11-09 06:45:49 +03:00
attrib_string ( finfo - > mode ) ,
( double ) finfo - > size ,
2001-09-07 18:14:57 +04:00
asctime ( LocalTime ( & t ) ) ) ;
1998-11-09 06:45:49 +03:00
dir_total + = finfo - > size ;
}
1996-05-04 11:50:46 +04:00
}
1996-06-04 10:42:03 +04:00
1998-09-21 12:45:11 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
accumulate size of a file
1998-09-21 12:45:11 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_du ( file_info * finfo )
{
1998-11-09 06:45:49 +03:00
if ( do_this_one ( finfo ) ) {
dir_total + = finfo - > size ;
}
1998-09-21 12:45:11 +04:00
}
1998-11-09 06:45:49 +03:00
static BOOL do_list_recurse ;
static BOOL do_list_dirs ;
1999-12-13 16:27:58 +03:00
static char * do_list_queue = 0 ;
static long do_list_queue_size = 0 ;
static long do_list_queue_start = 0 ;
static long do_list_queue_end = 0 ;
1998-11-09 06:45:49 +03:00
static void ( * do_list_fn ) ( file_info * ) ;
1998-09-21 12:45:11 +04:00
1999-12-13 16:27:58 +03:00
/****************************************************************************
functions for do_list_queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* The do_list_queue is a NUL - separated list of strings stored in a
* char * . Since this is a FIFO , we keep track of the beginning and
* ending locations of the data in the queue . When we overflow , we
* double the size of the char * . When the start of the data passes
* the midpoint , we move everything back . This is logically more
* complex than a linked list , but easier from a memory management
* angle . In any memory error condition , do_list_queue is reset .
* Functions check to ensure that do_list_queue is non - NULL before
* accessing it .
*/
static void reset_do_list_queue ( void )
{
2001-09-17 04:47:40 +04:00
SAFE_FREE ( do_list_queue ) ;
1999-12-13 16:27:58 +03:00
do_list_queue_size = 0 ;
do_list_queue_start = 0 ;
do_list_queue_end = 0 ;
}
static void init_do_list_queue ( void )
{
reset_do_list_queue ( ) ;
do_list_queue_size = 1024 ;
do_list_queue = malloc ( do_list_queue_size ) ;
if ( do_list_queue = = 0 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " malloc fail for size %d \n " ,
( int ) do_list_queue_size ) ;
1999-12-13 16:27:58 +03:00
reset_do_list_queue ( ) ;
} else {
memset ( do_list_queue , 0 , do_list_queue_size ) ;
}
}
static void adjust_do_list_queue ( void )
{
/*
* If the starting point of the queue is more than half way through ,
* move everything toward the beginning .
*/
if ( do_list_queue & & ( do_list_queue_start = = do_list_queue_end ) )
{
DEBUG ( 4 , ( " do_list_queue is empty \n " ) ) ;
do_list_queue_start = do_list_queue_end = 0 ;
* do_list_queue = ' \0 ' ;
}
else if ( do_list_queue_start > ( do_list_queue_size / 2 ) )
{
DEBUG ( 4 , ( " sliding do_list_queue backward \n " ) ) ;
memmove ( do_list_queue ,
do_list_queue + do_list_queue_start ,
do_list_queue_end - do_list_queue_start ) ;
do_list_queue_end - = do_list_queue_start ;
do_list_queue_start = 0 ;
}
}
static void add_to_do_list_queue ( const char * entry )
{
2001-08-12 21:30:01 +04:00
char * dlq ;
1999-12-13 16:27:58 +03:00
long new_end = do_list_queue_end + ( ( long ) strlen ( entry ) ) + 1 ;
while ( new_end > do_list_queue_size )
{
do_list_queue_size * = 2 ;
DEBUG ( 4 , ( " enlarging do_list_queue to %d \n " ,
( int ) do_list_queue_size ) ) ;
2001-08-12 21:30:01 +04:00
dlq = Realloc ( do_list_queue , do_list_queue_size ) ;
if ( ! dlq ) {
2001-09-07 18:14:57 +04:00
d_printf ( " failure enlarging do_list_queue to %d bytes \n " ,
( int ) do_list_queue_size ) ;
1999-12-13 16:27:58 +03:00
reset_do_list_queue ( ) ;
}
else
{
2001-08-12 21:30:01 +04:00
do_list_queue = dlq ;
1999-12-13 16:27:58 +03:00
memset ( do_list_queue + do_list_queue_size / 2 ,
0 , do_list_queue_size / 2 ) ;
}
}
if ( do_list_queue )
{
pstrcpy ( do_list_queue + do_list_queue_end , entry ) ;
do_list_queue_end = new_end ;
DEBUG ( 4 , ( " added %s to do_list_queue (start=%d, end=%d) \n " ,
entry , ( int ) do_list_queue_start , ( int ) do_list_queue_end ) ) ;
}
}
static char * do_list_queue_head ( void )
{
return do_list_queue + do_list_queue_start ;
}
static void remove_do_list_queue_head ( void )
{
if ( do_list_queue_end > do_list_queue_start )
{
do_list_queue_start + = strlen ( do_list_queue_head ( ) ) + 1 ;
adjust_do_list_queue ( ) ;
DEBUG ( 4 , ( " removed head of do_list_queue (start=%d, end=%d) \n " ,
( int ) do_list_queue_start , ( int ) do_list_queue_end ) ) ;
}
}
static int do_list_queue_empty ( void )
{
return ( ! ( do_list_queue & & * do_list_queue ) ) ;
}
1996-06-04 10:42:03 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
a helper for do_list
1996-06-04 10:42:03 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-05 16:11:29 +03:00
static void do_list_helper ( file_info * f , const char * mask , void * state )
1996-06-04 10:42:03 +04:00
{
1998-11-09 06:45:49 +03:00
if ( f - > mode & aDIR ) {
if ( do_list_dirs & & do_this_one ( f ) ) {
do_list_fn ( f ) ;
}
if ( do_list_recurse & &
! strequal ( f - > name , " . " ) & &
! strequal ( f - > name , " .. " ) ) {
pstring mask2 ;
char * p ;
pstrcpy ( mask2 , mask ) ;
2001-07-04 11:36:09 +04:00
p = strrchr_m ( mask2 , ' \\ ' ) ;
1998-11-09 06:45:49 +03:00
if ( ! p ) return ;
p [ 1 ] = 0 ;
pstrcat ( mask2 , f - > name ) ;
1998-11-14 06:34:44 +03:00
pstrcat ( mask2 , " \\ * " ) ;
1999-12-13 16:27:58 +03:00
add_to_do_list_queue ( mask2 ) ;
1998-11-09 06:45:49 +03:00
}
return ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
if ( do_this_one ( f ) ) {
do_list_fn ( f ) ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
a wrapper around cli_list that adds recursion
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-09 23:33:37 +03:00
void do_list ( const char * mask , uint16 attribute , void ( * fn ) ( file_info * ) , BOOL rec , BOOL dirs )
1998-11-09 06:45:49 +03:00
{
1999-12-13 16:27:58 +03:00
static int in_do_list = 0 ;
if ( in_do_list & & rec )
{
fprintf ( stderr , " INTERNAL ERROR: do_list called recursively when the recursive flag is true \n " ) ;
exit ( 1 ) ;
}
in_do_list = 1 ;
1998-11-09 06:45:49 +03:00
do_list_recurse = rec ;
do_list_dirs = dirs ;
do_list_fn = fn ;
1996-06-04 10:42:03 +04:00
1999-12-13 16:27:58 +03:00
if ( rec )
{
init_do_list_queue ( ) ;
add_to_do_list_queue ( mask ) ;
while ( ! do_list_queue_empty ( ) )
{
/*
* Need to copy head so that it doesn ' t become
* invalid inside the call to cli_list . This
* would happen if the list were expanded
* during the call .
* Fix from E . Jay Berkenbilt ( ejb @ ql . org )
*/
pstring head ;
pstrcpy ( head , do_list_queue_head ( ) ) ;
2001-01-05 16:11:29 +03:00
cli_list ( cli , head , attribute , do_list_helper , NULL ) ;
1999-12-13 16:27:58 +03:00
remove_do_list_queue_head ( ) ;
if ( ( ! do_list_queue_empty ( ) ) & & ( fn = = display_finfo ) )
{
char * next_file = do_list_queue_head ( ) ;
char * save_ch = 0 ;
if ( ( strlen ( next_file ) > = 2 ) & &
( next_file [ strlen ( next_file ) - 1 ] = = ' * ' ) & &
( next_file [ strlen ( next_file ) - 2 ] = = ' \\ ' ) )
{
save_ch = next_file +
strlen ( next_file ) - 2 ;
* save_ch = ' \0 ' ;
}
2001-09-07 18:14:57 +04:00
d_printf ( " \n %s \n " , next_file ) ;
1999-12-13 16:27:58 +03:00
if ( save_ch )
{
* save_ch = ' \\ ' ;
}
}
}
}
else
{
2001-01-05 16:11:29 +03:00
if ( cli_list ( cli , mask , attribute , do_list_helper , NULL ) = = - 1 )
1999-12-13 16:27:58 +03:00
{
2001-09-07 18:14:57 +04:00
d_printf ( " %s listing %s \n " , cli_errstr ( cli ) , mask ) ;
1999-12-13 16:27:58 +03:00
}
}
in_do_list = 0 ;
reset_do_list_queue ( ) ;
1998-11-09 06:45:49 +03:00
}
/****************************************************************************
get a directory listing
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_dir ( void )
1998-11-09 06:45:49 +03:00
{
1998-11-09 23:33:37 +03:00
uint16 attribute = aDIR | aSYSTEM | aHIDDEN ;
1998-11-09 06:45:49 +03:00
pstring mask ;
fstring buf ;
char * p = buf ;
2001-10-09 23:12:18 +04:00
int rc ;
1998-11-09 06:45:49 +03:00
dir_total = 0 ;
pstrcpy ( mask , cur_dir ) ;
if ( mask [ strlen ( mask ) - 1 ] ! = ' \\ ' )
pstrcat ( mask , " \\ " ) ;
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
dos_format ( p ) ;
if ( * p = = ' \\ ' )
pstrcpy ( mask , p ) ;
else
pstrcat ( mask , p ) ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
else {
1998-11-14 06:34:44 +03:00
pstrcat ( mask , " * " ) ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
do_list ( mask , attribute , display_finfo , recurse , True ) ;
1996-06-04 10:42:03 +04:00
2001-10-09 23:12:18 +04:00
rc = do_dskattr ( ) ;
1996-06-04 10:42:03 +04:00
1999-03-30 14:25:20 +04:00
DEBUG ( 3 , ( " Total bytes listed: %.0f \n " , dir_total ) ) ;
2001-10-09 23:12:18 +04:00
return rc ;
1996-06-04 10:42:03 +04:00
}
/****************************************************************************
1998-11-09 06:45:49 +03:00
get a directory listing
1996-06-04 10:42:03 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_du ( void )
1996-06-04 10:42:03 +04:00
{
1998-11-09 23:33:37 +03:00
uint16 attribute = aDIR | aSYSTEM | aHIDDEN ;
1998-11-09 06:45:49 +03:00
pstring mask ;
fstring buf ;
char * p = buf ;
2001-10-09 23:12:18 +04:00
int rc ;
1998-11-09 06:45:49 +03:00
dir_total = 0 ;
pstrcpy ( mask , cur_dir ) ;
if ( mask [ strlen ( mask ) - 1 ] ! = ' \\ ' )
pstrcat ( mask , " \\ " ) ;
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
dos_format ( p ) ;
if ( * p = = ' \\ ' )
pstrcpy ( mask , p ) ;
else
pstrcat ( mask , p ) ;
} else {
1998-11-14 06:34:44 +03:00
pstrcat ( mask , " * " ) ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
do_list ( mask , attribute , do_du , recurse , True ) ;
1996-06-04 10:42:03 +04:00
2001-10-09 23:12:18 +04:00
rc = do_dskattr ( ) ;
1996-06-04 10:42:03 +04:00
2001-09-07 18:14:57 +04:00
d_printf ( " Total number of bytes: %.0f \n " , dir_total ) ;
2001-10-09 23:12:18 +04:00
return rc ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
get a file from rname to lname
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int do_get ( char * rname , char * lname )
1998-11-09 06:45:49 +03:00
{
int handle = 0 , fnum ;
BOOL newhandle = False ;
char * data ;
struct timeval tp_start ;
1999-12-13 16:27:58 +03:00
int read_size = io_bufsize ;
1998-11-09 23:33:37 +03:00
uint16 attr ;
1998-11-09 06:45:49 +03:00
size_t size ;
off_t nread = 0 ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1998-11-09 06:45:49 +03:00
GetTimeOfDay ( & tp_start ) ;
if ( lowercase ) {
strlower ( lname ) ;
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
fnum = cli_open ( cli , rname , O_RDONLY , DENY_NONE ) ;
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
if ( fnum = = - 1 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s opening remote file %s \n " , cli_errstr ( cli ) , rname ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
if ( ! strcmp ( lname , " - " ) ) {
handle = fileno ( stdout ) ;
} else {
1998-11-17 23:50:07 +03:00
handle = sys_open ( lname , O_WRONLY | O_CREAT | O_TRUNC , 0644 ) ;
1998-11-09 06:45:49 +03:00
newhandle = True ;
}
if ( handle < 0 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error opening local file %s \n " , lname ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-14 06:53:24 +03:00
if ( ! cli_qfileinfo ( cli , fnum ,
& attr , & size , NULL , NULL , NULL , NULL , NULL ) & &
! cli_getattrE ( cli , fnum ,
& attr , & size , NULL , NULL , NULL ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " getattrib: %s \n " , cli_errstr ( cli ) ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
DEBUG ( 2 , ( " getting file %s of size %.0f as %s " ,
lname , ( double ) size , lname ) ) ;
1996-06-04 10:42:03 +04:00
1999-12-13 16:27:58 +03:00
if ( ! ( data = ( char * ) malloc ( read_size ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " malloc fail for size %d \n " , read_size ) ;
1999-12-13 16:27:58 +03:00
cli_close ( cli , fnum ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1999-12-13 16:27:58 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
while ( 1 ) {
int n = cli_read ( cli , fnum , data , nread , read_size ) ;
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
if ( n < = 0 ) break ;
if ( writefile ( handle , data , n ) ! = n ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error writing local file \n " ) ;
2001-10-09 23:12:18 +04:00
rc = 1 ;
1998-11-09 06:45:49 +03:00
break ;
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
nread + = n ;
}
1999-12-13 16:27:58 +03:00
if ( nread < size ) {
DEBUG ( 0 , ( " Short read when getting file %s. Only got %ld bytes. \n " ,
2001-10-09 23:12:18 +04:00
rname , ( long ) nread ) ) ;
rc = 1 ;
1999-12-13 16:27:58 +03:00
}
2001-09-17 04:47:40 +04:00
SAFE_FREE ( data ) ;
1998-11-09 06:45:49 +03:00
if ( ! cli_close ( cli , fnum ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error %s closing remote file \n " , cli_errstr ( cli ) ) ;
2001-10-09 23:12:18 +04:00
rc = 1 ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
if ( newhandle ) {
close ( handle ) ;
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
if ( archive_level > = 2 & & ( attr & aARCH ) ) {
1998-11-09 23:33:37 +03:00
cli_setatr ( cli , rname , attr & ~ ( uint16 ) aARCH , 0 ) ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03: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 + = nread ;
1999-12-21 12:54:24 +03:00
DEBUG ( 2 , ( " (%3.1f kb/s) (average %3.1f kb/s) \n " ,
1998-11-09 06:45:49 +03:00
nread / ( 1.024 * this_time + 1.0e-4 ) ,
get_total_size / ( 1.024 * get_total_time_ms ) ) ) ;
}
2001-10-09 23:12:18 +04:00
return rc ;
1996-06-04 10:42:03 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
get a file
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_get ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring lname ;
pstring rname ;
char * p ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , " \\ " ) ;
p = rname + strlen ( rname ) ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , p , NULL , sizeof ( rname ) - strlen ( rname ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " get <filename> \n " ) ;
2001-10-10 11:51:20 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
pstrcpy ( lname , p ) ;
dos_clean_name ( rname ) ;
2001-06-21 13:10:42 +04:00
next_token_nr ( NULL , lname , NULL , sizeof ( lname ) ) ;
1998-11-09 06:45:49 +03:00
2001-10-09 23:12:18 +04:00
return do_get ( rname , lname ) ;
1996-05-04 11:50:46 +04:00
}
1996-08-13 12:57:55 +04:00
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
do a mget operation on one file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_mget ( file_info * finfo )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring rname ;
pstring quest ;
pstring saved_curdir ;
pstring mget_mask ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( strequal ( finfo - > name , " . " ) | | strequal ( finfo - > name , " .. " ) )
return ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( abort_mget ) {
2001-09-07 18:14:57 +04:00
d_printf ( " mget aborted \n " ) ;
1998-11-09 06:45:49 +03:00
return ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( finfo - > mode & aDIR )
slprintf ( quest , sizeof ( pstring ) - 1 ,
2000-01-05 22:59:42 +03:00
" Get directory %s? " , finfo - > name ) ;
1998-11-09 06:45:49 +03:00
else
slprintf ( quest , sizeof ( pstring ) - 1 ,
2000-01-05 22:59:42 +03:00
" Get file %s? " , finfo - > name ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( prompt & & ! yesno ( quest ) ) return ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! ( finfo - > mode & aDIR ) ) {
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , finfo - > name ) ;
do_get ( rname , finfo - > name ) ;
return ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
/* handle directories */
pstrcpy ( saved_curdir , cur_dir ) ;
pstrcat ( cur_dir , finfo - > name ) ;
pstrcat ( cur_dir , " \\ " ) ;
unix_format ( finfo - > name ) ;
if ( lowercase )
strlower ( finfo - > name ) ;
2000-03-11 01:25:02 +03:00
if ( ! directory_exist ( finfo - > name , NULL ) & &
mkdir ( finfo - > name , 0777 ) ! = 0 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " failed to create directory %s \n " , finfo - > name ) ;
1998-11-09 06:45:49 +03:00
pstrcpy ( cur_dir , saved_curdir ) ;
return ;
}
2000-03-11 01:25:02 +03:00
if ( chdir ( finfo - > name ) ! = 0 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " failed to chdir to directory %s \n " , finfo - > name ) ;
1998-11-09 06:45:49 +03:00
pstrcpy ( cur_dir , saved_curdir ) ;
return ;
1996-06-04 10:42:03 +04:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
pstrcpy ( mget_mask , cur_dir ) ;
1998-11-14 06:34:44 +03:00
pstrcat ( mget_mask , " * " ) ;
1998-11-09 06:45:49 +03:00
do_list ( mget_mask , aSYSTEM | aHIDDEN | aDIR , do_mget , False , True ) ;
chdir ( " .. " ) ;
pstrcpy ( cur_dir , saved_curdir ) ;
1996-06-04 10:42:03 +04:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
view the file using the pager
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_more ( void )
1998-11-09 06:45:49 +03:00
{
2001-04-12 03:19:08 +04:00
fstring rname , lname , pager_cmd ;
1998-11-09 06:45:49 +03:00
char * pager ;
2001-04-12 03:19:08 +04:00
int fd ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
fstrcpy ( rname , cur_dir ) ;
fstrcat ( rname , " \\ " ) ;
2001-04-12 03:19:08 +04:00
slprintf ( lname , sizeof ( lname ) - 1 , " %s/smbmore.XXXXXX " , tmpdir ( ) ) ;
fd = smb_mkstemp ( lname ) ;
if ( fd = = - 1 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " failed to create temporary file for more \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
2001-04-12 03:19:08 +04:00
}
close ( fd ) ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , rname + strlen ( rname ) , NULL , sizeof ( rname ) - strlen ( rname ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " more <filename> \n " ) ;
2001-04-12 03:19:08 +04:00
unlink ( lname ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
dos_clean_name ( rname ) ;
1996-05-04 11:50:46 +04:00
2001-10-09 23:12:18 +04:00
rc = do_get ( rname , lname ) ;
1998-04-11 11:52:13 +04:00
1998-11-09 06:45:49 +03:00
pager = getenv ( " PAGER " ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
slprintf ( pager_cmd , sizeof ( pager_cmd ) - 1 ,
2001-04-12 03:19:08 +04:00
" %s %s " , ( pager ? pager : PAGER ) , lname ) ;
1998-11-09 06:45:49 +03:00
system ( pager_cmd ) ;
2001-04-12 03:19:08 +04:00
unlink ( lname ) ;
2001-10-09 23:12:18 +04:00
return rc ;
1998-11-09 06:45:49 +03:00
}
1998-04-11 11:52:13 +04:00
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
do a mget command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_mget ( void )
1998-11-09 06:45:49 +03:00
{
1998-11-09 23:33:37 +03:00
uint16 attribute = aSYSTEM | aHIDDEN ;
1998-11-09 06:45:49 +03:00
pstring mget_mask ;
fstring buf ;
char * p = buf ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
* mget_mask = 0 ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( recurse )
attribute | = aDIR ;
abort_mget = False ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
while ( next_token_nr ( NULL , p , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
pstrcpy ( mget_mask , cur_dir ) ;
if ( mget_mask [ strlen ( mget_mask ) - 1 ] ! = ' \\ ' )
pstrcat ( mget_mask , " \\ " ) ;
if ( * p = = ' \\ ' )
pstrcpy ( mget_mask , p ) ;
else
pstrcat ( mget_mask , p ) ;
do_list ( mget_mask , attribute , do_mget , False , True ) ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
if ( ! * mget_mask ) {
pstrcpy ( mget_mask , cur_dir ) ;
if ( mget_mask [ strlen ( mget_mask ) - 1 ] ! = ' \\ ' )
pstrcat ( mget_mask , " \\ " ) ;
1998-11-14 06:34:44 +03:00
pstrcat ( mget_mask , " * " ) ;
1998-11-09 06:45:49 +03:00
do_list ( mget_mask , attribute , do_mget , False , True ) ;
1996-06-04 10:42:03 +04:00
}
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
1996-06-04 10:42:03 +04:00
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
make a directory of name " name "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL do_mkdir ( char * name )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
if ( ! cli_mkdir ( cli , name ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s making remote directory %s \n " ,
cli_errstr ( cli ) , name ) ;
1998-11-09 06:45:49 +03:00
return ( False ) ;
}
return ( True ) ;
1996-05-04 11:50:46 +04:00
}
2001-10-11 11:42:52 +04:00
/****************************************************************************
show 8.3 name of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL do_altname ( char * name )
{
fstring altname ;
if ( ! NT_STATUS_IS_OK ( cli_qpathinfo_alt_name ( cli , name , altname ) ) ) {
d_printf ( " %s getting alt name for %s \n " ,
cli_errstr ( cli ) , name ) ;
return ( False ) ;
}
d_printf ( " %s \n " , altname ) ;
return ( True ) ;
}
1996-05-04 11:50:46 +04:00
1998-09-21 12:45:11 +04:00
/****************************************************************************
1999-12-13 16:27:58 +03:00
Exit client .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_quit ( void )
1998-09-21 12:45:11 +04:00
{
1998-11-09 06:45:49 +03:00
cli_shutdown ( cli ) ;
exit ( 0 ) ;
2001-10-19 04:02:36 +04:00
/* NOTREACHED */
return 0 ;
1998-09-21 12:45:11 +04:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
make a directory
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_mkdir ( void )
1998-11-09 06:45:49 +03:00
{
pstring mask ;
fstring buf ;
char * p = buf ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
pstrcpy ( mask , cur_dir ) ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , p , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
if ( ! recurse )
2001-09-07 18:14:57 +04:00
d_printf ( " mkdir <dirname> \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-10-24 06:49:09 +04:00
}
1998-11-09 06:45:49 +03:00
pstrcat ( mask , p ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( recurse ) {
pstring ddir ;
pstring ddir2 ;
* ddir2 = 0 ;
pstrcpy ( ddir , mask ) ;
trim_string ( ddir , " . " , NULL ) ;
p = strtok ( ddir , " / \\ " ) ;
while ( p ) {
pstrcat ( ddir2 , p ) ;
if ( ! cli_chkpath ( cli , ddir2 ) ) {
do_mkdir ( ddir2 ) ;
}
pstrcat ( ddir2 , " \\ " ) ;
p = strtok ( NULL , " / \\ " ) ;
}
} else {
do_mkdir ( mask ) ;
}
2001-10-09 23:12:18 +04:00
return 0 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2001-10-11 11:42:52 +04:00
/****************************************************************************
show alt name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-11 12:40:42 +04:00
static int cmd_altname ( void )
2001-10-11 11:42:52 +04:00
{
pstring name ;
fstring buf ;
char * p = buf ;
pstrcpy ( name , cur_dir ) ;
if ( ! next_token_nr ( NULL , p , NULL , sizeof ( buf ) ) ) {
d_printf ( " altname <file> \n " ) ;
2001-10-11 12:40:42 +04:00
return 1 ;
2001-10-11 11:42:52 +04:00
}
pstrcat ( name , p ) ;
do_altname ( name ) ;
2001-10-11 12:40:42 +04:00
return 0 ;
2001-10-11 11:42:52 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
put a single file
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int do_put ( char * rname , char * lname )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
int fnum ;
2001-09-10 15:08:57 +04:00
XFILE * f ;
1998-11-09 06:45:49 +03:00
int nread = 0 ;
char * buf = NULL ;
1999-12-13 16:27:58 +03:00
int maxwrite = io_bufsize ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1998-11-09 06:45:49 +03:00
struct timeval tp_start ;
GetTimeOfDay ( & tp_start ) ;
1996-05-04 11:50:46 +04:00
2000-01-08 13:15:53 +03:00
fnum = cli_open ( cli , rname , O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( fnum = = - 1 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s opening remote file %s \n " , cli_errstr ( cli ) , rname ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
/* allow files to be piped into smbclient
jdblair 24. jun .98 */
if ( ! strcmp ( lname , " - " ) ) {
2001-09-10 15:08:57 +04:00
f = x_stdin ;
1998-11-09 06:45:49 +03:00
/* size of file is not known */
} else {
2001-09-10 15:08:57 +04:00
f = x_fopen ( lname , O_RDONLY , 0 ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! f ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error opening local file %s \n " , lname ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
DEBUG ( 1 , ( " putting file %s as %s " , lname ,
2000-01-05 22:59:42 +03:00
rname ) ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
buf = ( char * ) malloc ( maxwrite ) ;
2001-08-08 20:54:16 +04:00
if ( ! buf ) {
2001-09-07 18:14:57 +04:00
d_printf ( " ERROR: Not enough memory! \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
2001-08-08 20:54:16 +04:00
}
2001-09-10 15:08:57 +04:00
while ( ! x_feof ( f ) ) {
1998-11-09 06:45:49 +03:00
int n = maxwrite ;
int ret ;
1996-05-04 11:50:46 +04:00
2001-09-09 06:43:30 +04:00
if ( ( n = readfile ( buf , n , f ) ) < 1 ) {
2001-09-10 15:08:57 +04:00
if ( ( n = = 0 ) & & x_feof ( f ) )
2000-01-07 00:23:49 +03:00
break ; /* Empty local file. */
2001-09-07 18:14:57 +04:00
d_printf ( " Error reading local file: %s \n " , strerror ( errno ) ) ;
2001-10-09 23:12:18 +04:00
rc = 1 ;
1998-11-09 06:45:49 +03:00
break ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
ret = cli_write ( cli , fnum , 0 , buf , nread , n ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( n ! = ret ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error writing file: %s \n " , cli_errstr ( cli ) ) ;
2001-10-09 23:12:18 +04:00
rc = 1 ;
1998-11-09 06:45:49 +03:00
break ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
nread + = n ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_close ( cli , fnum ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s closing remote file %s \n " , cli_errstr ( cli ) , rname ) ;
2001-09-10 15:08:57 +04:00
x_fclose ( f ) ;
2001-09-17 04:47:40 +04:00
SAFE_FREE ( buf ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
2001-09-10 15:08:57 +04:00
x_fclose ( f ) ;
2001-09-17 04:47:40 +04:00
SAFE_FREE ( buf ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03: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 ;
put_total_time_ms + = this_time ;
put_total_size + = nread ;
1999-12-21 12:54:24 +03:00
DEBUG ( 1 , ( " (%3.1f kb/s) (average %3.1f kb/s) \n " ,
1998-11-09 06:45:49 +03:00
nread / ( 1.024 * this_time + 1.0e-4 ) ,
put_total_size / ( 1.024 * put_total_time_ms ) ) ) ;
}
1996-05-04 11:50:46 +04:00
2001-09-10 15:08:57 +04:00
if ( f = = x_stdin ) {
1998-11-09 06:45:49 +03:00
cli_shutdown ( cli ) ;
exit ( 0 ) ;
}
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
1996-05-04 11:50:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
put a file
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_put ( void )
1998-11-09 06:45:49 +03:00
{
pstring lname ;
pstring rname ;
fstring buf ;
char * p = buf ;
pstrcpy ( rname , cur_dir ) ;
pstrcat ( rname , " \\ " ) ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , p , NULL , sizeof ( buf ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " put <filename> \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
pstrcpy ( lname , p ) ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , p , NULL , sizeof ( buf ) ) )
1998-11-09 06:45:49 +03:00
pstrcat ( rname , p ) ;
else
pstrcat ( rname , lname ) ;
dos_clean_name ( rname ) ;
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
SMB_STRUCT_STAT st ;
/* allow '-' to represent stdin
jdblair , 24. jun .98 */
if ( ! file_exist ( lname , & st ) & &
( strcmp ( lname , " - " ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s does not exist \n " , lname ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
}
1996-05-04 11:50:46 +04:00
2001-10-09 23:12:18 +04:00
return do_put ( rname , lname ) ;
1998-08-11 06:13:01 +04:00
}
1996-05-04 11:50:46 +04:00
2001-05-07 05:51:56 +04:00
/*************************************
File list structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct file_list {
struct file_list * prev , * next ;
char * file_path ;
BOOL isdir ;
} * file_list ;
/****************************************************************************
Free a file_list structure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void free_file_list ( struct file_list * list )
{
struct file_list * tmp ;
while ( list )
{
tmp = list ;
DLIST_REMOVE ( list , list ) ;
2001-09-17 04:47:40 +04:00
SAFE_FREE ( tmp - > file_path ) ;
SAFE_FREE ( tmp ) ;
2001-05-07 05:51:56 +04:00
}
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
seek in a directory / file list until you get something that doesn ' t start with
the specified name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-05-07 05:51:56 +04:00
static BOOL seek_list ( struct file_list * list , char * name )
1996-05-04 11:50:46 +04:00
{
2001-05-07 05:51:56 +04:00
while ( list ) {
trim_string ( list - > file_path , " ./ " , " \n " ) ;
if ( strncmp ( list - > file_path , name , strlen ( name ) ) ! = 0 ) {
1998-11-09 06:45:49 +03:00
return ( True ) ;
}
2001-05-07 05:51:56 +04:00
list = list - > next ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
return ( False ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
set the file selection mask
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_select ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstrcpy ( fileselection , " " ) ;
2001-06-21 13:10:42 +04:00
next_token_nr ( NULL , fileselection , NULL , sizeof ( fileselection ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2001-05-07 05:51:56 +04:00
/****************************************************************************
Recursive file matching function act as find
match must be always set to True when calling this function
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int file_find ( struct file_list * * list , const char * directory ,
const char * expression , BOOL match )
{
2001-05-07 09:19:52 +04:00
DIR * dir ;
2001-05-07 05:51:56 +04:00
struct file_list * entry ;
struct stat statbuf ;
2001-05-07 09:19:52 +04:00
int ret ;
2001-05-07 05:51:56 +04:00
char * path ;
BOOL isdir ;
2001-05-07 09:19:52 +04:00
char * dname ;
2001-05-07 05:51:56 +04:00
2001-05-07 09:19:52 +04:00
dir = opendir ( directory ) ;
if ( ! dir ) return - 1 ;
2001-05-07 05:51:56 +04:00
2001-05-07 09:19:52 +04:00
while ( ( dname = readdirname ( dir ) ) ) {
2001-05-07 05:51:56 +04:00
if ( ! strcmp ( " .. " , dname ) ) continue ;
if ( ! strcmp ( " . " , dname ) ) continue ;
if ( asprintf ( & path , " %s/%s " , directory , dname ) < = 0 ) {
continue ;
}
isdir = False ;
2001-08-20 09:15:26 +04:00
if ( ! match | | ! gen_fnmatch ( expression , dname ) ) {
2001-05-07 05:51:56 +04:00
if ( recurse ) {
ret = stat ( path , & statbuf ) ;
2001-05-07 09:19:52 +04:00
if ( ret = = 0 ) {
2001-05-07 05:51:56 +04:00
if ( S_ISDIR ( statbuf . st_mode ) ) {
isdir = True ;
ret = file_find ( list , path , expression , False ) ;
}
} else {
2001-09-07 18:14:57 +04:00
d_printf ( " file_find: cannot stat file %s \n " , path ) ;
2001-05-07 05:51:56 +04:00
}
2001-05-07 09:19:52 +04:00
if ( ret = = - 1 ) {
2001-09-17 04:47:40 +04:00
SAFE_FREE ( path ) ;
2001-05-07 09:19:52 +04:00
closedir ( dir ) ;
return - 1 ;
2001-05-07 05:51:56 +04:00
}
}
entry = ( struct file_list * ) malloc ( sizeof ( struct file_list ) ) ;
if ( ! entry ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Out of memory in file_find \n " ) ;
2001-05-07 09:19:52 +04:00
closedir ( dir ) ;
return - 1 ;
2001-05-07 05:51:56 +04:00
}
entry - > file_path = path ;
entry - > isdir = isdir ;
DLIST_ADD ( * list , entry ) ;
} else {
2001-09-17 04:47:40 +04:00
SAFE_FREE ( path ) ;
2001-05-07 05:51:56 +04:00
}
}
2001-05-07 09:19:52 +04:00
closedir ( dir ) ;
2001-05-07 05:51:56 +04:00
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
mput some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_mput ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring buf ;
char * p = buf ;
2001-06-21 13:10:42 +04:00
while ( next_token_nr ( NULL , p , NULL , sizeof ( buf ) ) ) {
2001-05-07 05:51:56 +04:00
int ret ;
struct file_list * temp_list ;
char * quest , * lname , * rname ;
file_list = NULL ;
2001-04-12 03:19:08 +04:00
2001-05-07 05:51:56 +04:00
ret = file_find ( & file_list , " . " , p , True ) ;
if ( ret ) {
free_file_list ( file_list ) ;
2001-04-12 03:19:08 +04:00
continue ;
}
1998-11-09 06:45:49 +03:00
2001-05-07 05:51:56 +04:00
quest = NULL ;
lname = NULL ;
rname = NULL ;
for ( temp_list = file_list ; temp_list ;
temp_list = temp_list - > next ) {
1998-11-09 06:45:49 +03:00
2001-09-17 04:47:40 +04:00
SAFE_FREE ( lname ) ;
2001-05-07 05:51:56 +04:00
if ( asprintf ( & lname , " %s/ " , temp_list - > file_path ) < = 0 )
continue ;
trim_string ( lname , " ./ " , " / " ) ;
1998-11-09 06:45:49 +03:00
/* check if it's a directory */
2001-05-07 05:51:56 +04:00
if ( temp_list - > isdir ) {
/* if (!recurse) continue; */
2001-09-17 04:47:40 +04:00
SAFE_FREE ( quest ) ;
2001-05-07 05:51:56 +04:00
asprintf ( & quest , " Put directory %s? " , lname ) ;
if ( prompt & & ! yesno ( quest ) ) { /* No */
/* Skip the directory */
lname [ strlen ( lname ) - 1 ] = ' / ' ;
if ( ! seek_list ( temp_list , lname ) )
break ;
} else { /* Yes */
2001-09-17 04:47:40 +04:00
SAFE_FREE ( rname ) ;
2001-05-07 05:51:56 +04:00
asprintf ( & rname , " %s%s " , cur_dir , lname ) ;
dos_format ( rname ) ;
if ( ! cli_chkpath ( cli , rname ) & &
! do_mkdir ( rname ) ) {
DEBUG ( 0 , ( " Unable to make dir, skipping... " ) ) ;
/* Skip the directory */
lname [ strlen ( lname ) - 1 ] = ' / ' ;
if ( ! seek_list ( temp_list , lname ) )
break ;
}
1998-11-09 06:45:49 +03:00
}
continue ;
} else {
2001-09-17 04:47:40 +04:00
SAFE_FREE ( quest ) ;
2001-05-07 05:51:56 +04:00
asprintf ( & quest , " Put file %s? " , lname ) ;
if ( prompt & & ! yesno ( quest ) ) /* No */
continue ;
1998-11-09 06:45:49 +03:00
2001-05-07 05:51:56 +04:00
/* Yes */
2001-09-17 04:47:40 +04:00
SAFE_FREE ( rname ) ;
2001-05-07 05:51:56 +04:00
asprintf ( & rname , " %s%s " , cur_dir , lname ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
dos_format ( rname ) ;
1996-05-04 11:50:46 +04:00
2001-05-07 05:51:56 +04:00
do_put ( rname , lname ) ;
1996-05-04 11:50:46 +04:00
}
2001-05-07 05:51:56 +04:00
free_file_list ( file_list ) ;
2001-09-17 04:47:40 +04:00
SAFE_FREE ( quest ) ;
SAFE_FREE ( lname ) ;
SAFE_FREE ( rname ) ;
1996-05-04 11:50:46 +04:00
}
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
1996-05-04 11:50:46 +04:00
/****************************************************************************
cancel a print job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int do_cancel ( int job )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
if ( cli_printjob_del ( cli , job ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Job %d cancelled \n " , job ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1998-11-09 06:45:49 +03:00
} else {
2001-09-07 18:14:57 +04:00
d_printf ( " Error cancelling job %d : %s \n " , job , cli_errstr ( cli ) ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
cancel a print job
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_cancel ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring buf ;
int job ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " cancel <jobid> ... \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
do {
job = atoi ( buf ) ;
do_cancel ( job ) ;
2001-06-21 13:10:42 +04:00
} while ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
print a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_print ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring lname ;
pstring rname ;
char * p ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , lname , NULL , sizeof ( lname ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " print <filename> \n " ) ;
2001-10-10 11:51:20 +04:00
return 1 ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
pstrcpy ( rname , lname ) ;
2001-07-04 11:36:09 +04:00
p = strrchr_m ( rname , ' / ' ) ;
1998-11-09 06:45:49 +03:00
if ( p ) {
2000-05-02 06:23:41 +04:00
slprintf ( rname , sizeof ( rname ) - 1 , " %s-%d " , p + 1 , ( int ) sys_getpid ( ) ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( strequal ( lname , " - " ) ) {
2000-05-02 06:23:41 +04:00
slprintf ( rname , sizeof ( rname ) - 1 , " stdin-%d " , ( int ) sys_getpid ( ) ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2001-10-09 23:12:18 +04:00
return do_put ( rname , lname ) ;
1996-05-04 11:50:46 +04:00
}
1997-07-01 05:19:13 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
show a print queue entry
1997-07-01 05:19:13 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-09 06:45:49 +03:00
static void queue_fn ( struct print_job_info * p )
1997-07-01 05:19:13 +04:00
{
2001-09-07 18:14:57 +04:00
d_printf ( " %-6d %-9d %s \n " , ( int ) p - > id , ( int ) p - > size , p - > name ) ;
1997-07-01 05:19:13 +04:00
}
1996-08-13 12:57:55 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
show a print queue
1996-08-13 12:57:55 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_queue ( void )
1996-08-13 12:57:55 +04:00
{
2001-10-09 23:12:18 +04:00
cli_print_queue ( cli , queue_fn ) ;
return 0 ;
1996-08-13 12:57:55 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
delete some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void do_del ( file_info * finfo )
{
1998-11-09 06:45:49 +03:00
pstring mask ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
pstrcpy ( mask , cur_dir ) ;
pstrcat ( mask , finfo - > name ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( finfo - > mode & aDIR )
return ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_unlink ( cli , mask ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s deleting remote file %s \n " , cli_errstr ( cli ) , mask ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
delete some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_del ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring mask ;
fstring buf ;
1998-11-09 23:33:37 +03:00
uint16 attribute = aSYSTEM | aHIDDEN ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( recurse )
attribute | = aDIR ;
pstrcpy ( mask , cur_dir ) ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " del <filename> \n " ) ;
2001-10-10 11:51:20 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
pstrcat ( mask , buf ) ;
do_list ( mask , attribute , do_del , False , False ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
1999-12-13 16:27:58 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_open ( void )
1999-12-13 16:27:58 +03:00
{
pstring mask ;
fstring buf ;
pstrcpy ( mask , cur_dir ) ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
2001-10-09 23:12:18 +04:00
d_printf ( " open <filename> \n " ) ;
return 1 ;
1999-12-13 16:27:58 +03:00
}
pstrcat ( mask , buf ) ;
cli_open ( cli , mask , O_RDWR , DENY_ALL ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1999-12-13 16:27:58 +03:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
remove a directory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_rmdir ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring mask ;
fstring buf ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
pstrcpy ( mask , cur_dir ) ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " rmdir <dirname> \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
pstrcat ( mask , buf ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! cli_rmdir ( cli , mask ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s removing remote directory file %s \n " ,
cli_errstr ( cli ) , mask ) ;
2001-10-09 23:12:18 +04:00
}
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
rename some files
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_rename ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring src , dest ;
fstring buf , buf2 ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
pstrcpy ( src , cur_dir ) ;
pstrcpy ( dest , cur_dir ) ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) | |
! next_token_nr ( NULL , buf2 , NULL , sizeof ( buf2 ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " rename <src> <dest> \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
1998-11-09 06:45:49 +03:00
}
pstrcat ( src , buf ) ;
pstrcat ( dest , buf2 ) ;
if ( ! cli_rename ( cli , src , dest ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s renaming files \n " , cli_errstr ( cli ) ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
}
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
toggle the prompt flag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_prompt ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
prompt = ! prompt ;
DEBUG ( 2 , ( " prompting is now %s \n " , prompt ? " on " : " off " ) ) ;
2001-10-09 23:12:18 +04:00
2001-10-10 11:51:20 +04:00
return 1 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
set the newer than time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_newer ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring buf ;
BOOL ok ;
SMB_STRUCT_STAT sbuf ;
2001-06-21 13:10:42 +04:00
ok = next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ;
2000-03-11 01:25:02 +03:00
if ( ok & & ( sys_stat ( buf , & sbuf ) = = 0 ) ) {
1998-11-09 06:45:49 +03:00
newer_than = sbuf . st_mtime ;
DEBUG ( 1 , ( " Getting files newer than %s " ,
asctime ( LocalTime ( & newer_than ) ) ) ) ;
} else {
newer_than = 0 ;
}
2001-10-09 23:12:18 +04:00
if ( ok & & newer_than = = 0 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Error setting newer-than time \n " ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
}
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
set the archive level
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_archive ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring buf ;
1996-05-04 11:50:46 +04:00
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
archive_level = atoi ( buf ) ;
} else
2001-09-07 18:14:57 +04:00
d_printf ( " Archive level is %d \n " , archive_level ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
toggle the lowercaseflag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_lowercase ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
lowercase = ! lowercase ;
DEBUG ( 2 , ( " filename lowercasing is now %s \n " , lowercase ? " on " : " off " ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
toggle the recurse flag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_recurse ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
recurse = ! recurse ;
DEBUG ( 2 , ( " directory recursion is now %s \n " , recurse ? " on " : " off " ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
toggle the translate flag
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_translate ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
translation = ! translation ;
DEBUG ( 2 , ( " CR/LF<->LF and print text translation now %s \n " ,
translation ? " on " : " off " ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
do a printmode command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_printmode ( void )
1998-11-09 06:45:49 +03:00
{
fstring buf ;
fstring mode ;
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
if ( strequal ( buf , " text " ) ) {
printmode = 0 ;
} else {
if ( strequal ( buf , " graphics " ) )
printmode = 1 ;
else
printmode = atoi ( buf ) ;
}
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
switch ( printmode )
{
case 0 :
fstrcpy ( mode , " text " ) ;
break ;
case 1 :
fstrcpy ( mode , " graphics " ) ;
break ;
default :
slprintf ( mode , sizeof ( mode ) - 1 , " %d " , printmode ) ;
break ;
}
DEBUG ( 2 , ( " the printmode is now %s \n " , mode ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
1998-11-09 06:45:49 +03:00
do the lcd command
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_lcd ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring buf ;
pstring d ;
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) )
1998-11-26 00:17:20 +03:00
chdir ( buf ) ;
DEBUG ( 2 , ( " the local directory is now %s \n " , sys_getwd ( d ) ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
list a share name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-04 14:35:55 +03:00
static void browse_fn ( const char * name , uint32 m ,
const char * comment , void * state )
1998-11-09 06:45:49 +03:00
{
1998-06-04 22:49:13 +04:00
fstring typestr ;
1999-12-13 16:27:58 +03:00
1998-06-04 22:49:13 +04:00
* typestr = 0 ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
switch ( m )
1998-06-04 22:49:13 +04:00
{
case STYPE_DISKTREE :
fstrcpy ( typestr , " Disk " ) ; break ;
case STYPE_PRINTQ :
1998-11-09 06:45:49 +03:00
fstrcpy ( typestr , " Printer " ) ; break ;
1998-06-04 22:49:13 +04:00
case STYPE_DEVICE :
fstrcpy ( typestr , " Device " ) ; break ;
case STYPE_IPC :
1998-11-09 06:45:49 +03:00
fstrcpy ( typestr , " IPC " ) ; break ;
1998-06-04 22:49:13 +04:00
}
2001-09-07 18:14:57 +04:00
d_printf ( " \t %-15.15s%-10.10s%s \n " ,
2001-07-04 11:15:53 +04:00
name , typestr , comment ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
1998-11-09 06:45:49 +03:00
try and browse available connections on a host
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-11-09 06:45:49 +03:00
static BOOL browse_host ( BOOL sort )
1996-05-04 11:50:46 +04:00
{
2000-02-26 01:25:25 +03:00
int ret ;
2001-09-07 18:14:57 +04:00
d_printf ( " \n \t Sharename Type Comment \n " ) ;
d_printf ( " \t --------- ---- ------- \n " ) ;
1996-05-04 11:50:46 +04:00
2001-01-04 14:35:55 +03:00
if ( ( ret = cli_RNetShareEnum ( cli , browse_fn , NULL ) ) = = - 1 )
2001-09-07 18:14:57 +04:00
d_printf ( " Error returning browse list: %s \n " , cli_errstr ( cli ) ) ;
2000-02-26 01:25:25 +03:00
return ( ret ! = - 1 ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
/****************************************************************************
list a server name
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-01-04 14:35:55 +03:00
static void server_fn ( const char * name , uint32 m ,
const char * comment , void * state )
1998-11-09 06:45:49 +03:00
{
2001-09-07 18:14:57 +04:00
d_printf ( " \t %-16.16s %s \n " , name , comment ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
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
{
1999-12-13 16:27:58 +03:00
if ( ! cli - > server_domain ) return False ;
2001-07-04 11:15:53 +04:00
2001-09-07 18:14:57 +04:00
d_printf ( " \n \t Server Comment \n " ) ;
d_printf ( " \t --------- ------- \n " ) ;
1998-11-09 06:45:49 +03:00
2001-01-04 14:35:55 +03:00
cli_NetServerEnum ( cli , cli - > server_domain , SV_TYPE_ALL , server_fn , NULL ) ;
1998-11-09 06:45:49 +03:00
2001-09-07 18:14:57 +04:00
d_printf ( " \n \t Workgroup Master \n " ) ;
d_printf ( " \t --------- ------- \n " ) ;
1998-11-09 06:45:49 +03:00
2001-01-04 14:35:55 +03:00
cli_NetServerEnum ( cli , cli - > server_domain , SV_TYPE_DOMAIN_ENUM , server_fn , NULL ) ;
1998-11-09 06:45:49 +03:00
return True ;
1996-05-04 11:50:46 +04:00
}
1998-09-18 16:47:46 +04:00
/* Some constants for completing filename arguments */
# define COMPL_NONE 0 /* No completions */
# define COMPL_REMOTE 1 /* Complete remote filename */
# define COMPL_LOCAL 2 /* Complete local filename */
2001-09-30 10:49:44 +04:00
/* This defines the commands supported by this client.
* NOTE : The " ! " must be the last one in the list because it ' s fn pointer
* field is NULL , and NULL in that field is used in process_tok ( )
* ( below ) to indicate the end of the list . crh
*/
1996-05-04 11:50:46 +04:00
struct
{
char * name ;
2001-10-09 23:12:18 +04:00
int ( * fn ) ( void ) ;
1996-05-04 11:50:46 +04:00
char * description ;
1998-09-18 16:47:46 +04:00
char compl_args [ 2 ] ; /* Completion argument info */
1996-05-04 11:50:46 +04:00
} commands [ ] =
{
2001-09-30 10:49:44 +04:00
{ " 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 " , { COMPL_NONE , COMPL_NONE } } ,
{ " blocksize " , cmd_block , " blocksize <number> (default 20) " , { COMPL_NONE , COMPL_NONE } } ,
{ " cancel " , cmd_cancel , " <jobid> cancel a print queue entry " , { COMPL_NONE , COMPL_NONE } } ,
{ " cd " , cmd_cd , " [directory] change/report the remote directory " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " del " , cmd_del , " <mask> delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " dir " , cmd_dir , " <mask> list the contents of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " du " , cmd_du , " <mask> computes the total size of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " exit " , cmd_quit , " logoff the server " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " get " , cmd_get , " <remote name> [local name] get a file " , { COMPL_REMOTE , COMPL_LOCAL } } ,
2001-09-30 10:49:44 +04:00
{ " help " , cmd_help , " [command] give help on a command " , { COMPL_NONE , COMPL_NONE } } ,
{ " history " , cmd_history , " displays the command history " , { COMPL_NONE , COMPL_NONE } } ,
{ " lcd " , cmd_lcd , " [directory] change/report the local current working directory " , { COMPL_LOCAL , COMPL_NONE } } ,
{ " lowercase " , cmd_lowercase , " toggle lowercasing of filenames for get " , { COMPL_NONE , COMPL_NONE } } ,
{ " ls " , cmd_dir , " <mask> list the contents of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " mask " , cmd_select , " <mask> mask all filenames against this " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " md " , cmd_mkdir , " <directory> make a directory " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " mget " , cmd_mget , " <mask> get all the matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " mkdir " , cmd_mkdir , " <directory> make a directory " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " more " , cmd_more , " <remote name> view a remote file with your pager " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " mput " , cmd_mput , " <mask> put all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " newer " , cmd_newer , " <file> only mget files newer than the specified local file " , { COMPL_LOCAL , COMPL_NONE } } ,
1999-12-13 16:27:58 +03:00
{ " open " , cmd_open , " <mask> open a file " , { COMPL_REMOTE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " print " , cmd_print , " <file name> print a file " , { COMPL_NONE , COMPL_NONE } } ,
{ " printmode " , cmd_printmode , " <graphics or text> set the print mode " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " prompt " , cmd_prompt , " toggle prompting for filenames for mget and mput " , { COMPL_NONE , COMPL_NONE } } ,
{ " put " , cmd_put , " <local name> [remote name] put a file " , { COMPL_LOCAL , COMPL_REMOTE } } ,
{ " pwd " , cmd_pwd , " show current remote directory (same as 'cd' with no args) " , { COMPL_NONE , COMPL_NONE } } ,
{ " q " , cmd_quit , " logoff the server " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " queue " , cmd_queue , " show the print queue " , { COMPL_NONE , COMPL_NONE } } ,
1998-11-09 06:45:49 +03:00
{ " quit " , cmd_quit , " logoff the server " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " rd " , cmd_rmdir , " <directory> remove a directory " , { COMPL_NONE , COMPL_NONE } } ,
{ " recurse " , cmd_recurse , " toggle directory recursion for mget and mput " , { COMPL_NONE , COMPL_NONE } } ,
{ " rename " , cmd_rename , " <src> <dest> rename some files " , { COMPL_REMOTE , COMPL_REMOTE } } ,
{ " rm " , cmd_del , " <mask> delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " rmdir " , cmd_rmdir , " <directory> remove a directory " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " setmode " , cmd_setmode , " filename <setmode string> change modes of file " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " tar " , cmd_tar , " tar <c|x>[IXFqbgNan] current directory to/from <file name> " , { COMPL_NONE , COMPL_NONE } } ,
{ " tarmode " , cmd_tarmode , " <full|inc|reset|noreset> tar's behaviour towards archive bits " , { COMPL_NONE , COMPL_NONE } } ,
{ " translate " , cmd_translate , " toggle text translation for printing " , { COMPL_NONE , COMPL_NONE } } ,
2001-10-11 11:42:52 +04:00
{ " altname " , cmd_altname , " <file> show alt name " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " ? " , cmd_help , " [command] give help on a command " , { COMPL_NONE , COMPL_NONE } } ,
{ " ! " , NULL , " run a shell command on the local system " , { COMPL_NONE , COMPL_NONE } } ,
{ " " , NULL , NULL , { COMPL_NONE , COMPL_NONE } }
1996-05-04 11:50:46 +04:00
} ;
/*******************************************************************
lookup a command string in the list of commands , including
abbreviations
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int process_tok ( fstring tok )
{
1998-11-09 06:45:49 +03:00
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 ;
} else if ( strnequal ( commands [ i ] . name , tok , tok_len ) ) {
matches + + ;
cmd = i ;
}
i + + ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( matches = = 0 )
return ( - 1 ) ;
else if ( matches = = 1 )
return ( cmd ) ;
else
return ( - 2 ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
help
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_help ( void )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
int i = 0 , j ;
fstring buf ;
2001-06-21 13:10:42 +04:00
if ( next_token_nr ( NULL , buf , NULL , sizeof ( buf ) ) ) {
1998-11-09 06:45:49 +03:00
if ( ( i = process_tok ( buf ) ) > = 0 )
2001-09-07 18:14:57 +04:00
d_printf ( " HELP %s: \n \t %s \n \n " , commands [ i ] . name , commands [ i ] . description ) ;
1998-11-09 06:45:49 +03:00
} else {
while ( commands [ i ] . description ) {
for ( j = 0 ; commands [ i ] . description & & ( j < 5 ) ; j + + ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %-15s " , commands [ i ] . name ) ;
1998-11-09 06:45:49 +03:00
i + + ;
}
2001-09-07 18:14:57 +04:00
d_printf ( " \n " ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
}
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
1998-09-18 16:47:46 +04:00
/****************************************************************************
1998-11-09 06:45:49 +03:00
process a - c command string
1998-09-18 16:47:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int process_command_string ( char * cmd )
1998-09-18 16:47:46 +04:00
{
1998-11-09 06:45:49 +03:00
pstring line ;
char * ptr ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1998-09-18 16:47:46 +04:00
1998-11-09 06:45:49 +03:00
while ( cmd [ 0 ] ! = ' \0 ' ) {
char * p ;
fstring tok ;
int i ;
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( cmd , ' ; ' ) ) = = 0 ) {
1998-11-09 06:45:49 +03:00
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 ;
}
/* and get the first part of the command */
ptr = line ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( & ptr , tok , NULL , sizeof ( tok ) ) ) continue ;
1998-11-09 06:45:49 +03:00
if ( ( i = process_tok ( tok ) ) > = 0 ) {
2001-10-09 23:12:18 +04:00
rc = commands [ i ] . fn ( ) ;
1998-11-09 06:45:49 +03:00
} else if ( i = = - 2 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s: command abbreviation ambiguous \n " , tok ) ;
1998-11-09 06:45:49 +03:00
} else {
2001-09-07 18:14:57 +04:00
d_printf ( " %s: command not found \n " , tok ) ;
1998-11-09 06:45:49 +03:00
}
}
2001-10-09 23:12:18 +04:00
return rc ;
1998-11-09 06:45:49 +03:00
}
1998-09-18 16:47:46 +04:00
2001-03-19 03:22:52 +03:00
/****************************************************************************
handle completion of commands for readline
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * * completion_fn ( char * text , int start , int end )
{
# define MAX_COMPLETIONS 100
char * * matches ;
int i , count = 0 ;
/* for words not at the start of the line fallback to filename completion */
if ( start ) return NULL ;
matches = ( char * * ) malloc ( sizeof ( matches [ 0 ] ) * MAX_COMPLETIONS ) ;
if ( ! matches ) return NULL ;
matches [ count + + ] = strdup ( text ) ;
if ( ! matches [ 0 ] ) return NULL ;
for ( i = 0 ; commands [ i ] . fn & & count < MAX_COMPLETIONS - 1 ; i + + ) {
if ( strncmp ( text , commands [ i ] . name , strlen ( text ) ) = = 0 ) {
matches [ count ] = strdup ( commands [ i ] . name ) ;
if ( ! matches [ count ] ) return NULL ;
count + + ;
}
}
if ( count = = 2 ) {
2001-09-17 04:47:40 +04:00
SAFE_FREE ( matches [ 0 ] ) ;
2001-03-19 03:22:52 +03:00
matches [ 0 ] = strdup ( matches [ 1 ] ) ;
}
matches [ count ] = NULL ;
return matches ;
}
2001-03-18 16:24:57 +03:00
2001-03-19 02:41:53 +03:00
/****************************************************************************
make sure we swallow keepalives during idle time
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void readline_callback ( void )
{
fd_set fds ;
struct timeval timeout ;
static time_t last_t ;
time_t t ;
t = time ( NULL ) ;
if ( t - last_t < 5 ) return ;
last_t = t ;
again :
FD_ZERO ( & fds ) ;
FD_SET ( cli - > fd , & fds ) ;
timeout . tv_sec = 0 ;
timeout . tv_usec = 0 ;
sys_select_intr ( cli - > fd + 1 , & fds , & timeout ) ;
/* We deliberately use receive_smb instead of
client_receive_smb as we want to receive
session keepalives and then drop them here .
*/
if ( FD_ISSET ( cli - > fd , & fds ) ) {
receive_smb ( cli - > fd , cli - > inbuf , 0 ) ;
goto again ;
}
cli_chkpath ( cli , " \\ " ) ;
}
1998-11-09 06:45:49 +03:00
/****************************************************************************
process commands on stdin
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void process_stdin ( void )
1998-09-18 16:47:46 +04:00
{
1998-11-09 06:45:49 +03:00
char * ptr ;
1998-09-18 16:47:46 +04:00
2001-03-19 02:41:53 +03:00
while ( 1 ) {
1998-11-09 06:45:49 +03:00
fstring tok ;
2001-04-16 06:35:35 +04:00
fstring the_prompt ;
2001-07-04 11:15:53 +04:00
char * cline ;
pstring line ;
1998-11-09 06:45:49 +03:00
int i ;
1999-12-13 16:27:58 +03:00
2001-03-18 16:24:57 +03:00
/* display a prompt */
2001-04-16 06:35:35 +04:00
slprintf ( the_prompt , sizeof ( the_prompt ) - 1 , " smb: %s> " , cur_dir ) ;
2001-07-04 11:15:53 +04:00
cline = smb_readline ( the_prompt , readline_callback , completion_fn ) ;
if ( ! cline ) break ;
pstrcpy ( line , cline ) ;
1999-12-13 16:27:58 +03:00
1998-11-09 06:45:49 +03:00
/* special case - first char is ! */
2001-03-19 02:41:53 +03:00
if ( * line = = ' ! ' ) {
system ( line + 1 ) ;
1998-11-09 06:45:49 +03:00
continue ;
}
/* and get the first part of the command */
2001-03-19 02:41:53 +03:00
ptr = line ;
2001-06-21 13:10:42 +04:00
if ( ! next_token_nr ( & ptr , tok , NULL , sizeof ( tok ) ) ) continue ;
1998-11-09 06:45:49 +03:00
if ( ( i = process_tok ( tok ) ) > = 0 ) {
commands [ i ] . fn ( ) ;
} else if ( i = = - 2 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s: command abbreviation ambiguous \n " , tok ) ;
1998-11-09 06:45:49 +03:00
} else {
2001-09-07 18:14:57 +04:00
d_printf ( " %s: command not found \n " , tok ) ;
1998-11-09 06:45:49 +03:00
}
}
1998-09-18 16:47:46 +04:00
}
1998-11-09 06:45:49 +03:00
/*****************************************************
return a connection to a server
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-07-04 11:15:53 +04:00
struct cli_state * do_connect ( const char * server , const char * share )
1998-09-18 16:47:46 +04:00
{
1999-12-13 16:27:58 +03:00
struct cli_state * c ;
struct nmb_name called , calling ;
2001-07-04 11:15:53 +04:00
const char * server_n ;
1998-11-09 06:45:49 +03:00
struct in_addr ip ;
2000-08-29 18:35:31 +04:00
fstring servicename ;
char * sharename ;
/* make a copy so we don't modify the global string 'service' */
safe_strcpy ( servicename , share , sizeof ( servicename ) - 1 ) ;
sharename = servicename ;
if ( * sharename = = ' \\ ' ) {
server = sharename + 2 ;
2001-07-04 11:36:09 +04:00
sharename = strchr_m ( server , ' \\ ' ) ;
2000-08-29 18:35:31 +04:00
if ( ! sharename ) return NULL ;
* sharename = 0 ;
sharename + + ;
1998-11-09 06:45:49 +03:00
}
1998-09-18 16:47:46 +04:00
1998-11-09 06:45:49 +03:00
server_n = server ;
2001-11-26 06:11:44 +03:00
zero_ip ( & ip ) ;
1998-09-18 16:47:46 +04:00
2000-01-07 09:55:36 +03:00
make_nmb_name ( & calling , global_myname , 0x0 ) ;
make_nmb_name ( & called , server , name_type ) ;
1999-01-25 04:46:14 +03:00
1999-12-13 16:27:58 +03:00
again :
2001-11-26 06:11:44 +03:00
zero_ip ( & ip ) ;
1998-11-09 06:45:49 +03:00
if ( have_ip ) ip = dest_ip ;
1998-09-18 16:47:46 +04:00
1999-12-13 16:27:58 +03:00
/* have to open a new connection */
2001-08-25 00:11:09 +04:00
if ( ! ( c = cli_initialise ( NULL ) ) | | ( cli_set_port ( c , port ) ! = port ) | |
1999-12-13 16:27:58 +03:00
! cli_connect ( c , server_n , & ip ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Connection to %s failed \n " , server_n ) ;
1998-11-09 06:45:49 +03:00
return NULL ;
}
1998-09-18 16:47:46 +04:00
2001-02-26 02:45:06 +03:00
c - > protocol = max_protocol ;
2001-10-12 08:49:42 +04:00
c - > use_kerberos = use_kerberos ;
2001-10-11 11:42:52 +04:00
1999-12-13 16:27:58 +03:00
if ( ! cli_session_request ( c , & calling , & called ) ) {
char * p ;
2001-09-07 18:14:57 +04:00
d_printf ( " session request to %s failed (%s) \n " ,
called . name , cli_errstr ( c ) ) ;
1999-12-13 16:27:58 +03:00
cli_shutdown ( c ) ;
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( called . name , ' . ' ) ) ) {
1999-12-13 16:27:58 +03:00
* p = 0 ;
goto again ;
1998-11-09 06:45:49 +03:00
}
1999-12-13 16:27:58 +03:00
if ( strcmp ( called . name , " *SMBSERVER " ) ) {
2000-01-07 09:55:36 +03:00
make_nmb_name ( & called , " *SMBSERVER " , 0x20 ) ;
1999-12-13 16:27:58 +03:00
goto again ;
1998-11-09 06:45:49 +03:00
}
1999-12-13 16:27:58 +03:00
return NULL ;
1998-11-09 06:45:49 +03:00
}
1999-12-13 16:27:58 +03:00
DEBUG ( 4 , ( " session request ok \n " ) ) ;
if ( ! cli_negprot ( c ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " protocol negotiation failed \n " ) ;
1999-12-13 16:27:58 +03:00
cli_shutdown ( c ) ;
return NULL ;
1998-11-09 06:45:49 +03:00
}
1998-09-18 16:47:46 +04:00
1999-12-13 16:27:58 +03:00
if ( ! got_pass ) {
char * pass = getpass ( " Password: " ) ;
if ( pass ) {
pstrcpy ( password , pass ) ;
}
}
1998-11-13 01:17:51 +03:00
1999-12-13 16:27:58 +03:00
if ( ! cli_session_setup ( c , username ,
password , strlen ( password ) ,
password , strlen ( password ) ,
workgroup ) ) {
/* if a password was not supplied then try again with a null username */
2001-11-24 17:16:41 +03:00
if ( password [ 0 ] | | ! username [ 0 ] | | use_kerberos | |
1999-12-13 16:27:58 +03:00
! cli_session_setup ( c , " " , " " , 0 , " " , 0 , workgroup ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " session setup failed: %s \n " , cli_errstr ( c ) ) ;
2000-05-02 11:50:33 +04:00
cli_shutdown ( c ) ;
1999-12-13 16:27:58 +03:00
return NULL ;
}
2001-09-07 18:14:57 +04:00
d_printf ( " Anonymous login successful \n " ) ;
1999-12-13 16:27:58 +03:00
}
1998-09-18 16:47:46 +04:00
1999-12-13 16:27:58 +03:00
/*
* These next two lines are needed to emulate
* old client behaviour for people who have
* scripts based on client output .
* QUESTION ? Do we want to have a ' client compatibility
* mode to turn these on / off ? JRA .
*/
2001-07-04 11:15:53 +04:00
if ( * c - > server_domain | | * c - > server_os | | * c - > server_type ) {
1999-12-13 16:27:58 +03:00
DEBUG ( 1 , ( " Domain=[%s] OS=[%s] Server=[%s] \n " ,
c - > server_domain , c - > server_os , c - > server_type ) ) ;
2001-07-04 11:15:53 +04:00
}
1999-12-13 16:27:58 +03:00
DEBUG ( 4 , ( " session setup ok \n " ) ) ;
2000-08-29 18:35:31 +04:00
if ( ! cli_send_tconX ( c , sharename , " ????? " ,
1999-12-13 16:27:58 +03:00
password , strlen ( password ) + 1 ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " tree connect failed: %s \n " , cli_errstr ( c ) ) ;
1999-12-13 16:27:58 +03:00
cli_shutdown ( c ) ;
1998-11-09 06:45:49 +03:00
return NULL ;
1998-09-18 16:47:46 +04:00
}
1999-12-13 16:27:58 +03:00
DEBUG ( 4 , ( " tconx ok \n " ) ) ;
return c ;
1998-09-18 16:47:46 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
process commands from the client
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int process ( char * base_directory )
1996-05-04 11:50:46 +04:00
{
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1999-12-13 16:27:58 +03:00
cli = do_connect ( desthost , service ) ;
1998-11-09 06:45:49 +03:00
if ( ! cli ) {
2001-11-02 14:31:49 +03:00
return 1 ;
1996-05-31 19:13:29 +04:00
}
1998-11-13 01:17:51 +03:00
1998-11-09 06:45:49 +03:00
if ( * base_directory ) do_cd ( base_directory ) ;
1998-09-18 16:47:46 +04:00
1998-11-09 06:45:49 +03:00
if ( cmdstr ) {
2001-10-09 23:12:18 +04:00
rc = process_command_string ( cmdstr ) ;
1998-11-09 06:45:49 +03:00
} else {
process_stdin ( ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
cli_shutdown ( cli ) ;
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
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
{
2001-09-07 18:14:57 +04:00
d_printf ( " Usage: %s service <password> [options] " , pname ) ;
d_printf ( " \n Version %s \n " , VERSION ) ;
d_printf ( " \t -s smb.conf pathname to smb.conf file \n " ) ;
d_printf ( " \t -O socket_options socket options to use \n " ) ;
d_printf ( " \t -R name resolve order use these name resolution services only \n " ) ;
d_printf ( " \t -M host send a winpopup message to the host \n " ) ;
d_printf ( " \t -i scope use this NetBIOS scope \n " ) ;
d_printf ( " \t -N don't ask for a password \n " ) ;
d_printf ( " \t -n netbios name. Use this name as my netbios name \n " ) ;
d_printf ( " \t -d debuglevel set the debuglevel \n " ) ;
d_printf ( " \t -P connect to service as a printer \n " ) ;
d_printf ( " \t -p port connect to the specified port \n " ) ;
d_printf ( " \t -l log basename. Basename for log/debug files \n " ) ;
d_printf ( " \t -h Print this help message. \n " ) ;
d_printf ( " \t -I dest IP use this IP to connect to \n " ) ;
d_printf ( " \t -E write messages to stderr instead of stdout \n " ) ;
2001-10-11 11:42:52 +04:00
d_printf ( " \t -k use kerberos (active directory) authentication \n " ) ;
2001-09-07 18:14:57 +04:00
d_printf ( " \t -U username set the network username \n " ) ;
d_printf ( " \t -L host get a list of shares available on a host \n " ) ;
d_printf ( " \t -t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex} \n " ) ;
d_printf ( " \t -m max protocol set the max protocol level \n " ) ;
d_printf ( " \t -A filename get the credentials from a file \n " ) ;
d_printf ( " \t -W workgroup set the workgroup name \n " ) ;
d_printf ( " \t -T<c|x>IXFqgbNan command line tar \n " ) ;
d_printf ( " \t -D directory start from directory \n " ) ;
d_printf ( " \t -c command string execute semicolon separated commands \n " ) ;
d_printf ( " \t -b xmit/send buffer changes the transmit/send buffer (default: 65520) \n " ) ;
d_printf ( " \n " ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
/****************************************************************************
get a password from a a file or file descriptor
exit on failure
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void get_password_file ( void )
{
int fd = - 1 ;
char * p ;
BOOL close_it = False ;
pstring spec ;
char pass [ 128 ] ;
if ( ( p = getenv ( " PASSWD_FD " ) ) ! = NULL ) {
pstrcpy ( spec , " descriptor " ) ;
pstrcat ( spec , p ) ;
sscanf ( p , " %d " , & fd ) ;
close_it = False ;
} else if ( ( p = getenv ( " PASSWD_FILE " ) ) ! = NULL ) {
1998-11-17 23:50:07 +03:00
fd = sys_open ( p , O_RDONLY , 0 ) ;
1998-11-09 06:45:49 +03:00
pstrcpy ( spec , p ) ;
if ( fd < 0 ) {
fprintf ( stderr , " Error opening PASSWD_FILE %s: %s \n " ,
spec , strerror ( errno ) ) ;
exit ( 1 ) ;
}
close_it = True ;
}
for ( p = pass , * p = ' \0 ' ; /* ensure that pass is null-terminated */
p & & p - pass < sizeof ( pass ) ; ) {
switch ( read ( fd , p , 1 ) ) {
case 1 :
if ( * p ! = ' \n ' & & * p ! = ' \0 ' ) {
* + + p = ' \0 ' ; /* advance p, and null-terminate pass */
break ;
}
case 0 :
if ( p - pass ) {
* p = ' \0 ' ; /* null-terminate it, just in case... */
p = NULL ; /* then force the loop condition to become false */
break ;
} else {
fprintf ( stderr , " Error reading password from file %s: %s \n " ,
spec , " empty password \n " ) ;
exit ( 1 ) ;
}
default :
fprintf ( stderr , " Error reading password from file %s: %s \n " ,
spec , strerror ( errno ) ) ;
exit ( 1 ) ;
}
}
pstrcpy ( password , pass ) ;
if ( close_it )
close ( fd ) ;
}
/****************************************************************************
handle a - L query
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
static int do_host_query ( char * query_host )
1998-11-09 06:45:49 +03:00
{
1999-12-13 16:27:58 +03:00
cli = do_connect ( query_host , " IPC$ " ) ;
1998-11-17 04:44:25 +03:00
if ( ! cli )
return 1 ;
1998-11-09 06:45:49 +03:00
browse_host ( True ) ;
list_servers ( workgroup ) ;
cli_shutdown ( cli ) ;
return ( 0 ) ;
}
/****************************************************************************
handle a tar operation
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
static int do_tar_op ( char * base_directory )
1998-11-09 06:45:49 +03:00
{
int ret ;
1999-12-13 16:27:58 +03:00
cli = do_connect ( desthost , service ) ;
1998-11-17 04:44:25 +03:00
if ( ! cli )
return 1 ;
1998-11-09 06:45:49 +03:00
recurse = True ;
if ( * base_directory ) do_cd ( base_directory ) ;
ret = process_tar ( ) ;
cli_shutdown ( cli ) ;
return ( ret ) ;
}
/****************************************************************************
handle a message operation
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int do_message_op ( void )
{
struct in_addr ip ;
struct nmb_name called , calling ;
2001-11-26 06:11:44 +03:00
zero_ip ( & ip ) ;
1998-11-09 06:45:49 +03:00
2000-01-07 09:55:36 +03:00
make_nmb_name ( & calling , global_myname , 0x0 ) ;
make_nmb_name ( & called , desthost , name_type ) ;
1998-11-09 06:45:49 +03:00
2001-11-26 06:11:44 +03:00
zero_ip ( & ip ) ;
1998-11-09 06:45:49 +03:00
if ( have_ip ) ip = dest_ip ;
2001-08-25 00:11:09 +04:00
if ( ! ( cli = cli_initialise ( NULL ) ) | | ( cli_set_port ( cli , port ) ! = port ) | | ! cli_connect ( cli , desthost , & ip ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Connection to %s failed \n " , desthost ) ;
1998-11-09 06:45:49 +03:00
return 1 ;
}
if ( ! cli_session_request ( cli , & calling , & called ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " session request failed \n " ) ;
1998-11-09 06:45:49 +03:00
cli_shutdown ( cli ) ;
return 1 ;
}
send_message ( ) ;
cli_shutdown ( cli ) ;
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1996-06-04 10:42:03 +04:00
int main ( int argc , char * argv [ ] )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
fstring base_directory ;
char * pname = argv [ 0 ] ;
int opt ;
extern char * optarg ;
extern int optind ;
2001-04-22 07:16:04 +04:00
int old_debug ;
1998-11-09 06:45:49 +03:00
pstring query_host ;
BOOL message = False ;
extern char tar_type ;
pstring term_code ;
pstring new_name_resolve_order ;
2001-12-21 01:27:05 +03:00
pstring logfile ;
1998-11-09 06:45:49 +03:00
char * p ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1997-09-12 00:17:32 +04:00
# ifdef KANJI
1998-11-09 06:45:49 +03:00
pstrcpy ( term_code , KANJI ) ;
1997-09-12 00:17:32 +04:00
# else /* KANJI */
1998-11-09 06:45:49 +03:00
* term_code = 0 ;
1997-09-12 00:17:32 +04:00
# endif /* KANJI */
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
* query_host = 0 ;
* base_directory = 0 ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
* new_name_resolve_order = 0 ;
1998-03-16 23:59:47 +03:00
1998-11-09 06:45:49 +03:00
DEBUGLEVEL = 2 ;
2001-03-18 16:24:57 +03:00
1998-11-09 06:45:49 +03:00
setup_logging ( pname , True ) ;
1996-05-04 11:50:46 +04:00
1999-12-13 16:27:58 +03:00
/*
* If the - E option is given , be careful not to clobber stdout
* before processing the options . 28.F eb .99 , richard @ hacom . nl .
* Also pre - parse the - s option to get the service file name .
*/
1996-05-04 11:50:46 +04:00
1999-12-13 16:27:58 +03:00
for ( opt = 1 ; opt < argc ; opt + + ) {
if ( strcmp ( argv [ opt ] , " -E " ) = = 0 )
2001-09-10 15:08:57 +04:00
dbf = x_stderr ;
1999-12-13 16:27:58 +03:00
else if ( strncmp ( argv [ opt ] , " -s " , 2 ) = = 0 ) {
if ( argv [ opt ] [ 2 ] ! = ' \0 ' )
2001-11-19 05:49:53 +03:00
pstrcpy ( dyn_CONFIGFILE , & argv [ opt ] [ 2 ] ) ;
1999-12-13 16:27:58 +03:00
else if ( argv [ opt + 1 ] ! = NULL ) {
/*
* At least one more arg left .
*/
2001-11-19 05:49:53 +03:00
pstrcpy ( dyn_CONFIGFILE , argv [ opt + 1 ] ) ;
1999-12-13 16:27:58 +03:00
} else {
usage ( pname ) ;
exit ( 1 ) ;
}
}
1998-11-09 06:45:49 +03:00
}
1998-09-29 08:43:40 +04:00
1998-11-09 06:45:49 +03:00
in_client = True ; /* Make sure that we tell lp_load we are */
1998-06-16 02:02:14 +04:00
2001-04-22 07:16:04 +04:00
old_debug = DEBUGLEVEL ;
2001-11-19 05:49:53 +03:00
if ( ! lp_load ( dyn_CONFIGFILE , True , False , False ) ) {
fprintf ( stderr , " %s: Can't load %s - run testparm to debug it \n " ,
prog_name , dyn_CONFIGFILE ) ;
1998-11-09 06:45:49 +03:00
}
2001-04-22 07:16:04 +04:00
DEBUGLEVEL = old_debug ;
1998-11-09 06:45:49 +03:00
1998-07-29 07:08:05 +04:00
# ifdef WITH_SSL
1998-11-09 06:45:49 +03:00
sslutil_init ( 0 ) ;
1998-06-16 05:35:52 +04:00
# endif
1998-11-09 06:45:49 +03:00
pstrcpy ( workgroup , lp_workgroup ( ) ) ;
1998-09-21 12:45:11 +04:00
1998-11-09 06:45:49 +03:00
load_interfaces ( ) ;
myumask = umask ( 0 ) ;
umask ( myumask ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( getenv ( " USER " ) ) {
pstrcpy ( username , getenv ( " USER " ) ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
/* modification to support userid%passwd syntax in the USER var
25. Aug .97 , jdblair @ uab . edu */
1996-05-04 11:50:46 +04:00
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( username , ' % ' ) ) ) {
1998-11-09 06:45:49 +03:00
* p = 0 ;
pstrcpy ( password , p + 1 ) ;
got_pass = True ;
2001-07-04 11:36:09 +04:00
memset ( strchr_m ( getenv ( " USER " ) , ' % ' ) + 1 , ' X ' , strlen ( password ) ) ;
1998-11-09 06:45:49 +03:00
}
strupper ( username ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
/* modification to support PASSWD environmental var
25. Aug .97 , jdblair @ uab . edu */
if ( getenv ( " PASSWD " ) ) {
pstrcpy ( password , getenv ( " PASSWD " ) ) ;
got_pass = True ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( getenv ( " PASSWD_FD " ) | | getenv ( " PASSWD_FILE " ) ) {
get_password_file ( ) ;
1998-10-29 05:18:17 +03:00
got_pass = True ;
1998-11-09 06:45:49 +03:00
}
if ( * username = = 0 & & getenv ( " LOGNAME " ) ) {
pstrcpy ( username , getenv ( " LOGNAME " ) ) ;
strupper ( username ) ;
}
if ( * username = = 0 ) {
pstrcpy ( username , " GUEST " ) ;
}
if ( argc < 2 ) {
1998-10-29 05:18:17 +03:00
usage ( pname ) ;
1998-11-09 06:45:49 +03:00
exit ( 1 ) ;
}
if ( * argv [ 1 ] ! = ' - ' ) {
pstrcpy ( service , argv [ 1 ] ) ;
/* Convert any '/' characters in the service name to '\' characters */
string_replace ( service , ' / ' , ' \\ ' ) ;
argc - - ;
argv + + ;
if ( count_chars ( service , ' \\ ' ) < 3 ) {
usage ( pname ) ;
2001-09-07 18:14:57 +04:00
d_printf ( " \n %s: Not enough ' \\ ' characters in service \n " , service ) ;
1998-11-09 06:45:49 +03:00
exit ( 1 ) ;
1998-10-29 05:18:17 +03:00
}
1998-11-09 06:45:49 +03:00
if ( argc > 1 & & ( * argv [ 1 ] ! = ' - ' ) ) {
got_pass = True ;
pstrcpy ( password , argv [ 1 ] ) ;
memset ( argv [ 1 ] , ' X ' , strlen ( argv [ 1 ] ) ) ;
argc - - ;
argv + + ;
}
}
while ( ( opt =
2001-10-11 11:42:52 +04:00
getopt ( argc , argv , " s:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:b:A:k " ) ) ! = EOF ) {
1998-11-09 06:45:49 +03:00
switch ( opt ) {
case ' s ' :
2001-11-19 05:49:53 +03:00
pstrcpy ( dyn_CONFIGFILE , optarg ) ;
1998-11-09 06:45:49 +03:00
break ;
case ' O ' :
pstrcpy ( user_socket_options , optarg ) ;
break ;
case ' R ' :
pstrcpy ( new_name_resolve_order , optarg ) ;
break ;
case ' M ' :
name_type = 0x03 ; /* messages are sent to NetBIOS name type 0x3 */
pstrcpy ( desthost , optarg ) ;
message = True ;
break ;
case ' i ' :
2000-01-07 09:55:36 +03:00
{
extern pstring global_scope ;
pstrcpy ( global_scope , optarg ) ;
strupper ( global_scope ) ;
}
1998-11-09 06:45:49 +03:00
break ;
case ' N ' :
got_pass = True ;
break ;
case ' n ' :
pstrcpy ( global_myname , optarg ) ;
break ;
case ' d ' :
if ( * optarg = = ' A ' )
DEBUGLEVEL = 10000 ;
else
DEBUGLEVEL = atoi ( optarg ) ;
break ;
case ' P ' :
/* not needed anymore */
break ;
case ' p ' :
port = atoi ( optarg ) ;
break ;
case ' l ' :
2001-12-21 01:27:05 +03:00
slprintf ( logfile , sizeof ( logfile ) - 1 , " %s.client " , optarg ) ;
lp_set_logfile ( logfile ) ;
1998-11-09 06:45:49 +03:00
break ;
case ' h ' :
usage ( pname ) ;
exit ( 0 ) ;
break ;
case ' I ' :
1998-10-29 05:18:17 +03:00
{
1998-11-09 06:45:49 +03:00
dest_ip = * interpret_addr2 ( optarg ) ;
2001-11-26 06:11:44 +03:00
if ( is_zero_ip ( dest_ip ) )
1998-11-09 06:45:49 +03:00
exit ( 1 ) ;
have_ip = True ;
1998-10-29 05:18:17 +03:00
}
1998-11-09 06:45:49 +03:00
break ;
case ' E ' :
2001-09-07 18:14:57 +04:00
display_set_stderr ( ) ;
2001-09-10 15:08:57 +04:00
dbf = x_stderr ;
1998-11-09 06:45:49 +03:00
break ;
case ' U ' :
{
char * lp ;
pstrcpy ( username , optarg ) ;
2001-07-04 11:36:09 +04:00
if ( ( lp = strchr_m ( username , ' % ' ) ) ) {
1998-11-09 06:45:49 +03:00
* lp = 0 ;
pstrcpy ( password , lp + 1 ) ;
got_pass = True ;
2001-07-04 11:36:09 +04:00
memset ( strchr_m ( optarg , ' % ' ) + 1 , ' X ' , strlen ( password ) ) ;
1998-11-09 06:45:49 +03:00
}
}
break ;
2000-08-29 18:35:31 +04:00
case ' A ' :
{
2001-09-10 15:08:57 +04:00
XFILE * auth ;
2000-08-29 18:35:31 +04:00
fstring buf ;
uint16 len = 0 ;
char * ptr , * val , * param ;
2001-09-10 15:08:57 +04:00
if ( ( auth = x_fopen ( optarg , O_RDONLY , 0 ) ) = = NULL )
2000-08-29 18:35:31 +04:00
{
/* fail if we can't open the credentials file */
2001-09-07 18:14:57 +04:00
d_printf ( " ERROR: Unable to open credentials file! \n " ) ;
2000-08-29 18:35:31 +04:00
exit ( - 1 ) ;
}
2001-09-10 15:08:57 +04:00
while ( ! x_feof ( auth ) )
2000-08-29 18:35:31 +04:00
{
/* get a line from the file */
2001-09-10 15:08:57 +04:00
if ( ! x_fgets ( buf , sizeof ( buf ) , auth ) )
2000-08-29 18:35:31 +04:00
continue ;
len = strlen ( buf ) ;
if ( ( len ) & & ( buf [ len - 1 ] = = ' \n ' ) )
{
buf [ len - 1 ] = ' \0 ' ;
len - - ;
}
if ( len = = 0 )
continue ;
/* break up the line into parameter & value.
will need to eat a little whitespace possibly */
param = buf ;
2001-07-04 11:36:09 +04:00
if ( ! ( ptr = strchr_m ( buf , ' = ' ) ) )
2000-08-29 18:35:31 +04:00
continue ;
val = ptr + 1 ;
* ptr = ' \0 ' ;
/* eat leading white space */
while ( ( * val ! = ' \0 ' ) & & ( ( * val = = ' ' ) | | ( * val = = ' \t ' ) ) )
val + + ;
if ( strwicmp ( " password " , param ) = = 0 )
{
pstrcpy ( password , val ) ;
got_pass = True ;
}
else if ( strwicmp ( " username " , param ) = = 0 )
pstrcpy ( username , val ) ;
2001-12-19 05:50:44 +03:00
else if ( strwicmp ( " domain " , param ) = = 0 )
pstrcpy ( workgroup , val ) ;
2000-08-29 18:35:31 +04:00
memset ( buf , 0 , sizeof ( buf ) ) ;
}
2001-09-10 15:08:57 +04:00
x_fclose ( auth ) ;
2000-08-29 18:35:31 +04:00
}
break ;
1998-11-09 06:45:49 +03:00
case ' L ' :
1999-12-13 16:27:58 +03:00
p = optarg ;
while ( * p = = ' \\ ' | | * p = = ' / ' )
p + + ;
pstrcpy ( query_host , p ) ;
1998-11-09 06:45:49 +03:00
break ;
case ' t ' :
pstrcpy ( term_code , optarg ) ;
break ;
case ' m ' :
2001-02-26 02:45:06 +03:00
max_protocol = interpret_protocol ( optarg , max_protocol ) ;
1998-11-09 06:45:49 +03:00
break ;
case ' W ' :
pstrcpy ( workgroup , optarg ) ;
break ;
case ' T ' :
if ( ! tar_parseargs ( argc , argv , optarg , optind ) ) {
usage ( pname ) ;
exit ( 1 ) ;
}
break ;
case ' D ' :
pstrcpy ( base_directory , optarg ) ;
break ;
case ' c ' :
cmdstr = optarg ;
break ;
1999-12-13 16:27:58 +03:00
case ' b ' :
io_bufsize = MAX ( 1 , atoi ( optarg ) ) ;
break ;
2001-10-11 11:42:52 +04:00
case ' k ' :
2001-11-29 02:54:07 +03:00
# ifdef HAVE_KRB5
2001-10-11 11:42:52 +04:00
use_kerberos = True ;
got_pass = True ;
# else
d_printf ( " No kerberos support compiled in \n " ) ;
exit ( 1 ) ;
# endif
break ;
1998-11-09 06:45:49 +03:00
default :
2001-10-10 11:51:20 +04:00
usage ( pname ) ;
1998-10-29 05:18:17 +03:00
exit ( 1 ) ;
}
1996-05-04 11:50:46 +04:00
}
1999-12-13 16:27:58 +03:00
get_myname ( ( * global_myname ) ? NULL : global_myname ) ;
1998-09-18 16:47:46 +04:00
1998-11-09 06:45:49 +03:00
if ( * new_name_resolve_order )
lp_set_name_resolve_order ( new_name_resolve_order ) ;
1998-09-18 16:47:46 +04:00
1998-11-09 06:45:49 +03:00
if ( ! tar_type & & ! * query_host & & ! * service & & ! message ) {
usage ( pname ) ;
exit ( 1 ) ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
DEBUG ( 3 , ( " Client started (version %s). \n " , VERSION ) ) ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( tar_type ) {
2000-11-23 02:06:29 +03:00
if ( cmdstr )
process_command_string ( cmdstr ) ;
1999-12-13 16:27:58 +03:00
return do_tar_op ( base_directory ) ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( query_host , ' # ' ) ) ) {
1998-11-09 06:45:49 +03:00
* p = 0 ;
p + + ;
sscanf ( p , " %x " , & name_type ) ;
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( * query_host ) {
1999-12-13 16:27:58 +03:00
return do_host_query ( query_host ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( message ) {
return do_message_op ( ) ;
1996-05-04 11:50:46 +04:00
}
2001-03-18 16:24:57 +03:00
2001-10-09 23:12:18 +04:00
if ( process ( base_directory ) ) {
return 1 ;
1996-05-04 11:50:46 +04:00
}
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}