2007-12-07 04:16:33 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1996-05-04 11:50:46 +04:00
SMB client
2005-02-23 20:29:28 +03:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Simo Sorce 2001 - 2002
Copyright ( C ) Jelmer Vernooij 2003
Copyright ( C ) Gerald ( Jerry ) Carter 2004
2007-12-07 04:16:33 +03:00
Copyright ( C ) Jeremy Allison 1994 - 2007
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 11:50:46 +04:00
( at your option ) any later version .
2007-12-07 04:16:33 +03:00
1996-05-04 11:50:46 +04:00
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 .
2007-12-07 04:16:33 +03:00
1996-05-04 11:50:46 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 11:50:46 +04:00
*/
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2010-08-05 12:49:53 +04:00
# include "popt_common.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2004-10-07 08:01:18 +04:00
# include "client/client_proto.h"
2011-01-12 14:56:55 +03:00
# include "../librpc/gen_ndr/ndr_srvsvc_c.h"
2010-10-01 12:08:15 +04:00
# include "../lib/util/select.h"
2010-10-01 12:34:14 +04:00
# include "system/readline.h"
# include "../libcli/smbreadline/smbreadline.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-02-08 19:56:10 +03:00
# include "system/select.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2011-02-24 12:46:55 +03:00
# include "libsmb/clirap.h"
2011-02-25 02:03:01 +03:00
# include "trans2.h"
2011-03-23 16:18:59 +03:00
# include "libsmb/nmblib.h"
2009-11-26 20:21:28 +03:00
1996-05-04 11:50:46 +04:00
# ifndef REGISTER
# define REGISTER 0
# endif
2007-12-18 09:09:09 +03:00
extern int do_smb_browse ( void ) ; /* mDNS browsing */
2007-10-19 04:40:25 +04:00
extern bool override_logfile ;
2005-04-06 20:28:04 +04:00
extern char tar_type ;
2007-12-18 09:09:09 +03:00
2001-08-25 00:11:09 +04:00
static int port = 0 ;
2007-12-07 04:16:33 +03:00
static char * service ;
static char * desthost ;
static char * calling_name ;
static bool grepable = false ;
2003-04-14 08:05:48 +04:00
static char * cmdstr = NULL ;
2008-06-17 23:08:56 +04:00
const char * cmd_ptr = NULL ;
2003-04-14 08:05:48 +04:00
Change default bufsize to 512k
I did not do any scientific tests, but the dummy test on my laptop against a
w2k3 vmware shows that in this specific situation going beyond 512k seems not
to gain anything anymore.
smb: \> iosize 64512
iosize is now 64512
smb: \> lcd /dev
smb: \> get random null
getting file \random of size 104857600 as null (33453,1 kb/s) (average 19718,5 kb/s)
smb: \> get random null
getting file \random of size 104857600 as null (34236,0 kb/s) (average 20509,1 kb/s)
smb: \> iosize 524288
iosize is now 524288
smb: \> get random null
getting file \random of size 104857600 as null (49042,1 kb/s) (average 22521,9 kb/s)
smb: \> get random null
getting file \random of size 104857600 as null (49420,8 kb/s) (average 23432,9 kb/s)
smb: \> iosize 1048576
iosize is now 1048576
smb: \> get random null
getting file \random of size 104857600 as null (49420,8 kb/s) (average 24284,2 kb/s)
smb: \> get random null
getting file \random of size 104857600 as null (49136,3 kb/s) (average 25076,9 kb/s)
(This used to be commit 1bcfef6a9093aa873550a263dc142c8a3f5edffd)
2008-03-01 14:11:22 +03:00
static int io_bufsize = 524288 ;
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
static int name_type = 0x20 ;
2009-01-15 01:26:56 +03:00
static int max_protocol = PROTOCOL_NT1 ;
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
static int process_tok ( char * tok ) ;
2001-10-09 23:12:18 +04:00
static int cmd_help ( void ) ;
1998-09-05 09:07:05 +04:00
2006-11-01 20:18:08 +03:00
# define CREATE_ACCESS_READ READ_CONTROL_ACCESS
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 ;
2002-07-15 14:35:28 +04:00
static int archive_level = 0 ;
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
static bool translation = false ;
2007-10-19 04:40:25 +04: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 ;
2007-10-19 04:40:25 +04:00
extern bool tar_inc ;
extern bool tar_reset ;
1996-05-04 11:50:46 +04:00
/* clitar bits end */
2007-12-07 04:16:33 +03:00
static bool prompt = true ;
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
static bool recurse = false ;
static bool showacls = false ;
bool lowercase = false ;
1996-05-04 11:50:46 +04:00
2007-10-25 01:16:54 +04:00
static struct sockaddr_storage dest_ss ;
2009-01-02 23:49:49 +03:00
static char dest_ss_str [ INET6_ADDRSTRLEN ] ;
1996-05-04 11:50:46 +04:00
# define SEPARATORS " \t\n\r"
2007-12-07 04:16:33 +03:00
static bool abort_mget = true ;
1996-05-04 11:50:46 +04:00
/* timing globals */
2008-10-14 03:59:36 +04:00
uint64_t get_total_size = 0 ;
2002-11-09 19:57:45 +03:00
unsigned int get_total_time_ms = 0 ;
2008-10-14 03:59:36 +04:00
static uint64_t put_total_size = 0 ;
2002-11-09 19:57:45 +03:00
static unsigned int put_total_time_ms = 0 ;
1996-05-04 11:50:46 +04:00
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
2007-12-30 09:39:52 +03:00
/* encrypted state. */
static bool smb_encrypt ;
2005-02-25 00:54:52 +03:00
/* root cli_state connection */
2005-02-22 06:31:22 +03:00
struct cli_state * cli ;
2006-07-12 07:20:53 +04:00
static char CLI_DIRSEP_CHAR = ' \\ ' ;
static char CLI_DIRSEP_STR [ ] = { ' \\ ' , ' \0 ' } ;
2005-02-23 20:29:28 +03:00
2009-03-18 00:53:06 +03:00
/* Authentication for client connections. */
struct user_auth_info * auth_info ;
2007-12-07 04:16:33 +03:00
/* Accessor functions for directory paths. */
static char * fileselection ;
static const char * client_get_fileselection ( void )
{
if ( fileselection ) {
return fileselection ;
}
return " " ;
}
static const char * client_set_fileselection ( const char * new_fs )
{
SAFE_FREE ( fileselection ) ;
if ( new_fs ) {
fileselection = SMB_STRDUP ( new_fs ) ;
}
return client_get_fileselection ( ) ;
}
static char * cwd ;
static const char * client_get_cwd ( void )
{
if ( cwd ) {
return cwd ;
}
return CLI_DIRSEP_STR ;
}
static const char * client_set_cwd ( const char * new_cwd )
{
SAFE_FREE ( cwd ) ;
if ( new_cwd ) {
cwd = SMB_STRDUP ( new_cwd ) ;
}
return client_get_cwd ( ) ;
}
static char * cur_dir ;
const char * client_get_cur_dir ( void )
{
if ( cur_dir ) {
return cur_dir ;
}
return CLI_DIRSEP_STR ;
}
const char * client_set_cur_dir ( const char * newdir )
{
SAFE_FREE ( cur_dir ) ;
if ( newdir ) {
cur_dir = SMB_STRDUP ( newdir ) ;
}
return client_get_cur_dir ( ) ;
}
2010-01-21 14:57:07 +03:00
/****************************************************************************
Put up a yes / no prompt .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static bool yesno ( const char * p )
{
char ans [ 20 ] ;
printf ( " %s " , p ) ;
if ( ! fgets ( ans , sizeof ( ans ) - 1 , stdin ) )
return ( False ) ;
if ( * ans = = ' y ' | | * ans = = ' Y ' )
return ( True ) ;
return ( False ) ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2007-12-07 04:16:33 +03:00
Write to a local file with CR / LF - > LF translation if appropriate . Return the
2003-08-07 00:01:31 +04:00
number taken from the buffer . This may not equal the number written .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
1996-05-04 11:50:46 +04:00
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
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
return ( i ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2007-12-07 04:16:33 +03:00
Read from a file with LF - > CR / LF translation if appropriate . Return the
2003-08-07 00:01:31 +04:00
number read . read approx n bytes .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2008-12-20 01:33:55 +03:00
static int readfile ( uint8_t * 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 ) ;
2007-12-07 04:16:33 +03: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 ;
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
if ( c = = ' \n ' ) { /* change all LFs to CR/LF */
b [ i + + ] = ' \r ' ;
}
2007-12-07 04:16:33 +03:00
1999-12-13 16:27:58 +03:00
b [ i + + ] = c ;
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
return ( i ) ;
1996-05-04 11:50:46 +04:00
}
2007-12-07 04:16:33 +03:00
2008-12-20 01:33:55 +03:00
struct push_state {
XFILE * f ;
SMB_OFF_T nread ;
} ;
2009-03-12 11:02:02 +03:00
static size_t push_source ( uint8_t * buf , size_t n , void * priv )
2008-12-20 01:33:55 +03:00
{
struct push_state * state = ( struct push_state * ) priv ;
int result ;
if ( x_feof ( state - > f ) ) {
return 0 ;
}
2009-03-12 11:02:02 +03:00
result = readfile ( buf , n , state - > f ) ;
2008-12-20 01:33:55 +03:00
state - > nread + = result ;
return result ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Send a message .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2008-12-14 15:06:19 +03:00
static void send_message ( const char * username )
1996-05-04 11:50:46 +04:00
{
2009-11-10 21:49:41 +03:00
char buf [ 1600 ] ;
NTSTATUS status ;
int i ;
1996-05-04 11:50:46 +04:00
2009-11-10 21:49:41 +03:00
d_printf ( " Type your message, ending it with a Control-D \n " ) ;
1996-05-04 11:50:46 +04:00
2009-11-10 21:49:41 +03:00
i = 0 ;
while ( i < sizeof ( buf ) - 2 ) {
int c = fgetc ( stdin ) ;
if ( c = = EOF ) {
2007-09-14 22:31:33 +04:00
break ;
}
2009-11-10 21:49:41 +03:00
if ( c = = ' \n ' ) {
buf [ i + + ] = ' \r ' ;
2007-12-07 04:16:33 +03:00
}
2009-11-10 21:49:41 +03:00
buf [ i + + ] = c ;
1996-05-04 11:50:46 +04:00
}
2009-11-10 21:49:41 +03:00
buf [ i ] = ' \0 ' ;
1996-05-04 11:50:46 +04:00
2009-11-10 21:49:41 +03:00
status = cli_message ( cli , desthost , username , buf ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " cli_message returned %s \n " ,
nt_errstr ( status ) ) ;
2007-12-07 04:16:33 +03:00
}
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Check the space on a device .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
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 ;
2007-12-07 04:16:33 +03:00
struct cli_state * targetcli = NULL ;
char * targetpath = NULL ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2010-08-13 17:08:38 +04:00
NTSTATUS status ;
2005-02-23 20:29:28 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , client_get_cur_dir ( ) , & targetcli , & targetpath ) ) {
2005-02-23 20:29:28 +03:00
d_printf ( " Error in dskattr: %s \n " , cli_errstr ( cli ) ) ;
2005-03-23 02:18:41 +03:00
return 1 ;
2005-02-23 20:29:28 +03:00
}
1996-05-04 11:50:46 +04:00
2010-08-13 17:08:38 +04:00
status = cli_dskattr ( targetcli , & bsize , & total , & avail ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error in dskattr: %s \n " , nt_errstr ( status ) ) ;
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
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Show cd / pwd .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
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 ) ;
2007-12-07 04:16:33 +03:00
d_printf ( " %s \n " , client_get_cur_dir ( ) ) ;
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2008-02-09 03:59:52 +03:00
/****************************************************************************
Ensure name has correct directory separators .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void normalize_name ( char * newdir )
{
2010-04-14 05:41:14 +04:00
if ( ! ( cli - > requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP ) ) {
2008-02-09 03:59:52 +03:00
string_replace ( newdir , ' / ' , ' \\ ' ) ;
}
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Change directory - inner section .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static int do_cd ( const char * new_dir )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
char * newdir = NULL ;
char * saved_dir = NULL ;
char * new_cd = NULL ;
char * targetpath = NULL ;
struct cli_state * targetcli = NULL ;
2005-02-24 22:10:28 +03:00
SMB_STRUCT_STAT sbuf ;
uint32 attributes ;
2005-04-15 04:39:03 +04:00
int ret = 1 ;
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
newdir = talloc_strdup ( ctx , new_dir ) ;
if ( ! newdir ) {
TALLOC_FREE ( ctx ) ;
return 1 ;
}
2008-02-09 03:59:52 +03:00
normalize_name ( newdir ) ;
1998-11-09 06:45:49 +03:00
2005-02-23 20:29:28 +03:00
/* Save the current directory in case the new directory is invalid */
2007-12-07 04:16:33 +03:00
saved_dir = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! saved_dir ) {
TALLOC_FREE ( ctx ) ;
return 1 ;
}
2005-02-23 20:29:28 +03:00
2007-12-07 04:16:33 +03:00
if ( * newdir = = CLI_DIRSEP_CHAR ) {
client_set_cur_dir ( newdir ) ;
new_cd = newdir ;
2007-03-09 02:54:57 +03:00
} else {
2007-12-07 04:16:33 +03:00
new_cd = talloc_asprintf ( ctx , " %s%s " ,
client_get_cur_dir ( ) ,
newdir ) ;
if ( ! new_cd ) {
goto out ;
}
1998-11-09 06:45:49 +03:00
}
2008-02-09 03:59:52 +03:00
/* Ensure cur_dir ends in a DIRSEP */
if ( ( new_cd [ 0 ] ! = ' \0 ' ) & & ( * ( new_cd + strlen ( new_cd ) - 1 ) ! = CLI_DIRSEP_CHAR ) ) {
2009-01-01 03:30:11 +03:00
new_cd = talloc_asprintf_append ( new_cd , " %s " , CLI_DIRSEP_STR ) ;
2008-02-09 03:59:52 +03:00
if ( ! new_cd ) {
goto out ;
}
2007-12-07 04:16:33 +03:00
}
2008-02-09 03:59:52 +03:00
client_set_cur_dir ( new_cd ) ;
2007-12-07 04:16:33 +03:00
new_cd = clean_name ( ctx , new_cd ) ;
client_set_cur_dir ( new_cd ) ;
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , new_cd , & targetcli , & targetpath ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " cd %s: %s \n " , new_cd , cli_errstr ( cli ) ) ;
client_set_cur_dir ( saved_dir ) ;
2005-02-24 22:10:28 +03:00
goto out ;
2005-02-23 20:29:28 +03:00
}
2007-03-09 02:54:57 +03:00
if ( strequal ( targetpath , CLI_DIRSEP_STR ) ) {
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( ctx ) ;
2007-03-09 02:54:57 +03:00
return 0 ;
}
2007-12-07 04:16:33 +03:00
2005-11-18 06:18:54 +03:00
/* Use a trans2_qpathinfo to test directories for modern servers.
2007-12-07 04:16:33 +03:00
Except Win9x doesn ' t support the qpathinfo_basic ( ) call . . . . . */
if ( targetcli - > protocol > PROTOCOL_LANMAN2 & & ! targetcli - > win95 ) {
2010-02-07 16:07:17 +03:00
NTSTATUS status ;
status = cli_qpathinfo_basic ( targetcli , targetpath , & sbuf ,
& attributes ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cd %s: %s \n " , new_cd , nt_errstr ( status ) ) ;
2007-12-07 04:16:33 +03:00
client_set_cur_dir ( saved_dir ) ;
2005-02-24 22:10:28 +03:00
goto out ;
}
2007-12-07 04:16:33 +03:00
if ( ! ( attributes & FILE_ATTRIBUTE_DIRECTORY ) ) {
d_printf ( " cd %s: not a directory \n " , new_cd ) ;
client_set_cur_dir ( saved_dir ) ;
2005-02-24 22:10:28 +03:00
goto out ;
2007-12-07 04:16:33 +03:00
}
2005-04-15 04:39:03 +04:00
} else {
2010-08-13 17:08:38 +04:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
targetpath = talloc_asprintf ( ctx ,
" %s%s " ,
targetpath ,
CLI_DIRSEP_STR ) ;
if ( ! targetpath ) {
client_set_cur_dir ( saved_dir ) ;
goto out ;
}
targetpath = clean_name ( ctx , targetpath ) ;
if ( ! targetpath ) {
client_set_cur_dir ( saved_dir ) ;
goto out ;
}
2010-08-13 17:08:38 +04:00
status = cli_chkpath ( targetcli , targetpath ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cd %s: %s \n " , new_cd , nt_errstr ( status ) ) ;
2007-12-07 04:16:33 +03:00
client_set_cur_dir ( saved_dir ) ;
2005-04-15 04:39:03 +04:00
goto out ;
1998-11-09 06:45:49 +03:00
}
}
2005-02-23 20:29:28 +03:00
2005-04-15 04:39:03 +04:00
ret = 0 ;
2005-02-24 22:10:28 +03:00
out :
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( ctx ) ;
2005-04-15 04:39:03 +04:00
return ret ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Change directory .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_cd ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
char * buf = NULL ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
2007-12-07 04:16:33 +03:00
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( talloc_tos ( ) , & cmd_ptr , & buf , NULL ) ) {
2001-10-09 23:12:18 +04:00
rc = do_cd ( buf ) ;
2007-12-07 04:16:33 +03:00
} else {
d_printf ( " Current directory is %s \n " , client_get_cur_dir ( ) ) ;
}
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}
2007-07-11 12:43:08 +04:00
/****************************************************************************
Change directory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_cd_oneup ( void )
{
2007-12-07 04:16:33 +03:00
return do_cd ( " .. " ) ;
2007-07-11 12:43:08 +04:00
}
1998-11-09 06:45:49 +03:00
/*******************************************************************
2003-08-07 00:01:31 +04:00
Decide if a file should be operated on .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-27 12:59:55 +04:00
static bool do_this_one ( struct file_info * finfo )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
if ( ! finfo - > name ) {
return false ;
}
1998-11-09 06:45:49 +03:00
2011-04-29 05:57:02 +04:00
if ( finfo - > mode & FILE_ATTRIBUTE_DIRECTORY ) {
2007-12-07 04:16:33 +03:00
return true ;
}
if ( * client_get_fileselection ( ) & &
2009-11-23 18:34:07 +03:00
! mask_match ( finfo - > name , client_get_fileselection ( ) , false ) ) {
2002-09-25 19:19:00 +04:00
DEBUG ( 3 , ( " mask_match %s failed \n " , finfo - > name ) ) ;
2007-12-07 04:16:33 +03:00
return false ;
1998-11-09 06:45:49 +03:00
}
2006-08-24 20:44:00 +04:00
if ( newer_than & & finfo - > mtime_ts . tv_sec < newer_than ) {
1998-11-09 06:45:49 +03:00
DEBUG ( 3 , ( " newer_than %s failed \n " , finfo - > name ) ) ;
2007-12-07 04:16:33 +03:00
return false ;
1998-11-09 06:45:49 +03:00
}
2011-04-29 06:00:57 +04:00
if ( ( archive_level = = 1 | | archive_level = = 2 ) & & ! ( finfo - > mode & FILE_ATTRIBUTE_ARCHIVE ) ) {
1998-11-09 06:45:49 +03:00
DEBUG ( 3 , ( " archive %s failed \n " , finfo - > name ) ) ;
2007-12-07 04:16:33 +03:00
return false ;
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
return true ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Display info about a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 22:56:51 +04:00
static NTSTATUS display_finfo ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 18:18:51 +04:00
const char * dir )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
time_t t ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2010-10-29 22:56:51 +04:00
NTSTATUS status = NT_STATUS_OK ;
2006-11-01 20:18:08 +03:00
2007-12-07 04:16:33 +03:00
if ( ! do_this_one ( finfo ) ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2007-12-07 04:16:33 +03:00
}
t = finfo - > mtime_ts . tv_sec ; /* the time is assumed to be passed as GMT */
if ( ! showacls ) {
d_printf ( " %-30s%7.7s %8.0f %s " ,
finfo - > name ,
2011-04-29 06:05:07 +04:00
attrib_string ( talloc_tos ( ) , finfo - > mode ) ,
2007-12-07 04:16:33 +03:00
( double ) finfo - > size ,
time_to_asc ( t ) ) ;
dir_total + = finfo - > size ;
} else {
char * afname = NULL ;
2009-05-01 02:26:43 +04:00
uint16_t fnum ;
2007-12-07 04:16:33 +03:00
/* skip if this is . or .. */
if ( strequal ( finfo - > name , " .. " ) | | strequal ( finfo - > name , " . " ) )
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2009-05-01 02:26:43 +04:00
/* create absolute filename for cli_ntcreate() FIXME */
2007-12-07 04:16:33 +03:00
afname = talloc_asprintf ( ctx ,
" %s%s%s " ,
2008-09-12 03:20:59 +04:00
dir ,
2007-12-07 04:16:33 +03:00
CLI_DIRSEP_STR ,
finfo - > name ) ;
if ( ! afname ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
/* print file meta date header */
2008-09-12 04:32:14 +04:00
d_printf ( " FILENAME:%s \n " , finfo - > name ) ;
2011-04-29 06:05:07 +04:00
d_printf ( " MODE:%s \n " , attrib_string ( talloc_tos ( ) , finfo - > mode ) ) ;
2007-12-07 04:16:33 +03:00
d_printf ( " SIZE:%.0f \n " , ( double ) finfo - > size ) ;
d_printf ( " MTIME:%s " , time_to_asc ( t ) ) ;
2010-08-13 17:08:38 +04:00
status = cli_ntcreate ( cli_state , afname , 0 ,
CREATE_ACCESS_READ , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE ,
FILE_OPEN , 0x0 , 0x0 , & fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-07 04:16:33 +03:00
DEBUG ( 0 , ( " display_finfo() Failed to open %s: %s \n " ,
2010-08-13 17:08:38 +04:00
afname , nt_errstr ( status ) ) ) ;
2007-12-07 04:16:33 +03:00
} else {
2010-05-18 12:29:34 +04:00
struct security_descriptor * sd = NULL ;
2010-07-30 18:18:51 +04:00
sd = cli_query_secdesc ( cli_state , fnum , ctx ) ;
2007-12-07 04:16:33 +03:00
if ( ! sd ) {
DEBUG ( 0 , ( " display_finfo() failed to "
" get security descriptor: %s " ,
2010-07-30 18:18:51 +04:00
cli_errstr ( cli_state ) ) ) ;
2010-10-29 22:56:51 +04:00
status = cli_nt_error ( cli_state ) ;
2006-11-01 20:18:08 +03:00
} else {
2007-12-07 04:16:33 +03:00
display_sec_desc ( sd ) ;
2006-11-01 20:18:08 +03:00
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( sd ) ;
2006-11-01 20:18:08 +03:00
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( afname ) ;
1998-11-09 06:45:49 +03:00
}
2010-10-29 22:56:51 +04:00
return status ;
1996-05-04 11:50:46 +04:00
}
1998-09-21 12:45:11 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Accumulate size of a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 22:56:51 +04:00
static NTSTATUS do_du ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 18:18:51 +04:00
const char * dir )
1998-09-21 12:45:11 +04:00
{
1998-11-09 06:45:49 +03:00
if ( do_this_one ( finfo ) ) {
dir_total + = finfo - > size ;
}
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
1998-09-21 12:45:11 +04:00
}
2007-10-19 04:40:25 +04: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 ;
2010-10-29 22:56:51 +04:00
static NTSTATUS ( * do_list_fn ) ( struct cli_state * cli_state , struct file_info * ,
2010-07-30 18:18:51 +04:00
const char * dir ) ;
1998-09-21 12:45:11 +04:00
1999-12-13 16:27:58 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Functions for do_list_queue .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
/*
* 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 .
*/
2003-08-07 00:01:31 +04:00
1999-12-13 16:27:58 +03:00
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 ;
2006-08-16 21:14:16 +04:00
do_list_queue = ( char * ) SMB_MALLOC ( do_list_queue_size ) ;
2007-12-07 04:16:33 +03:00
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 .
*/
2006-06-18 13:26:05 +04:00
if ( do_list_queue = = NULL ) {
DEBUG ( 4 , ( " do_list_queue is empty \n " ) ) ;
do_list_queue_start = do_list_queue_end = 0 ;
return ;
}
2007-12-07 04:16:33 +03:00
2006-06-18 13:26:05 +04:00
if ( do_list_queue_start = = do_list_queue_end ) {
1999-12-13 16:27:58 +03:00
DEBUG ( 4 , ( " do_list_queue is empty \n " ) ) ;
do_list_queue_start = do_list_queue_end = 0 ;
* do_list_queue = ' \0 ' ;
2003-08-07 00:01:31 +04:00
} else if ( do_list_queue_start > ( do_list_queue_size / 2 ) ) {
1999-12-13 16:27:58 +03:00
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 ;
}
}
2007-12-07 04:16:33 +03:00
static void add_to_do_list_queue ( const char * entry )
1999-12-13 16:27:58 +03:00
{
long new_end = do_list_queue_end + ( ( long ) strlen ( entry ) ) + 1 ;
2003-08-07 00:01:31 +04:00
while ( new_end > do_list_queue_size ) {
1999-12-13 16:27:58 +03:00
do_list_queue_size * = 2 ;
DEBUG ( 4 , ( " enlarging do_list_queue to %d \n " ,
( int ) do_list_queue_size ) ) ;
2006-08-16 21:14:16 +04:00
do_list_queue = ( char * ) SMB_REALLOC ( do_list_queue , do_list_queue_size ) ;
r13915: Fixed a very interesting class of realloc() bugs found by Coverity.
realloc can return NULL in one of two cases - (1) the realloc failed,
(2) realloc succeeded but the new size requested was zero, in which
case this is identical to a free() call.
The error paths dealing with these two cases should be different,
but mostly weren't. Secondly the standard idiom for dealing with
realloc when you know the new size is non-zero is the following :
tmp = realloc(p, size);
if (!tmp) {
SAFE_FREE(p);
return error;
} else {
p = tmp;
}
However, there were *many* *many* places in Samba where we were
using the old (broken) idiom of :
p = realloc(p, size)
if (!p) {
return error;
}
which will leak the memory pointed to by p on realloc fail.
This commit (hopefully) fixes all these cases by moving to
a standard idiom of :
p = SMB_REALLOC(p, size)
if (!p) {
return error;
}
Where if the realloc returns null due to the realloc failing
or size == 0 we *guarentee* that the storage pointed to by p
has been freed. This allows me to remove a lot of code that
was dealing with the standard (more verbose) method that required
a tmp pointer. This is almost always what you want. When a
realloc fails you never usually want the old memory, you
want to free it and get into your error processing asap.
For the 11 remaining cases where we really do need to keep the
old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR,
which can be used as follows :
tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
if (!tmp) {
SAFE_FREE(p);
return error;
} else {
p = tmp;
}
SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the
pointer p, even on size == 0 or realloc fail. All this is
done by a hidden extra argument to Realloc(), BOOL free_old_on_error
which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR
macros (and their array counterparts).
It remains to be seen what this will do to our Coverity bug count :-).
Jeremy.
(This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0)
2006-03-07 09:31:04 +03:00
if ( ! do_list_queue ) {
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 ( ) ;
2003-08-07 00:01:31 +04:00
} else {
1999-12-13 16:27:58 +03:00
memset ( do_list_queue + do_list_queue_size / 2 ,
0 , do_list_queue_size / 2 ) ;
}
}
2003-08-07 00:01:31 +04:00
if ( do_list_queue ) {
2011-05-04 00:14:46 +04:00
strlcpy_base ( do_list_queue + do_list_queue_end ,
2003-07-18 05:36:11 +04:00
entry , do_list_queue , do_list_queue_size ) ;
1999-12-13 16:27:58 +03:00
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 )
{
2003-08-07 00:01:31 +04:00
if ( do_list_queue_end > do_list_queue_start ) {
1999-12-13 16:27:58 +03:00
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
/****************************************************************************
2003-08-07 00:01:31 +04:00
A helper for do_list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 22:56:51 +04:00
static NTSTATUS do_list_helper ( const char * mntpoint , struct file_info * f ,
2010-07-27 12:59:55 +04:00
const char * mask , void * state )
1996-06-04 10:42:03 +04:00
{
2010-07-30 18:18:51 +04:00
struct cli_state * cli_state = ( struct cli_state * ) state ;
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * dir = NULL ;
char * dir_end = NULL ;
2010-10-29 22:56:51 +04:00
NTSTATUS status = NT_STATUS_OK ;
2005-10-13 19:51:25 +04:00
2007-12-07 04:16:33 +03:00
/* Work out the directory. */
dir = talloc_strdup ( ctx , mask ) ;
if ( ! dir ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
if ( ( dir_end = strrchr ( dir , CLI_DIRSEP_CHAR ) ) ! = NULL ) {
2005-10-13 19:51:25 +04:00
* dir_end = ' \0 ' ;
}
2011-04-29 05:57:02 +04:00
if ( f - > mode & FILE_ATTRIBUTE_DIRECTORY ) {
1998-11-09 06:45:49 +03:00
if ( do_list_dirs & & do_this_one ( f ) ) {
2010-10-29 22:56:51 +04:00
status = do_list_fn ( cli_state , f , dir ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
if ( do_list_recurse & &
f - > name & &
! strequal ( f - > name , " . " ) & &
1998-11-09 06:45:49 +03:00
! strequal ( f - > name , " .. " ) ) {
2007-12-07 04:16:33 +03:00
char * mask2 = NULL ;
char * p = NULL ;
1998-11-09 06:45:49 +03:00
2003-07-17 08:17:58 +04:00
if ( ! f - > name [ 0 ] ) {
d_printf ( " Empty dir name returned. Possible server misconfiguration. \n " ) ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( dir ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_UNSUCCESSFUL ;
2003-07-17 08:17:58 +04:00
}
2007-12-07 04:16:33 +03:00
mask2 = talloc_asprintf ( ctx ,
" %s%s " ,
mntpoint ,
mask ) ;
if ( ! mask2 ) {
TALLOC_FREE ( dir ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
2006-07-12 07:20:53 +04:00
p = strrchr_m ( mask2 , CLI_DIRSEP_CHAR ) ;
2009-01-09 02:41:49 +03:00
if ( p ) {
p [ 1 ] = 0 ;
} else {
mask2 [ 0 ] = ' \0 ' ;
2007-12-07 04:16:33 +03:00
}
mask2 = talloc_asprintf_append ( mask2 ,
" %s%s* " ,
f - > name ,
CLI_DIRSEP_STR ) ;
if ( ! mask2 ) {
TALLOC_FREE ( dir ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
1999-12-13 16:27:58 +03:00
add_to_do_list_queue ( mask2 ) ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( mask2 ) ;
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( dir ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
if ( do_this_one ( f ) ) {
2010-10-29 22:56:51 +04:00
status = do_list_fn ( cli_state , f , dir ) ;
1996-06-04 10:42:03 +04:00
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( dir ) ;
2010-10-29 22:56:51 +04:00
return status ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
A wrapper around cli_list that adds recursion .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 22:56:51 +04:00
NTSTATUS do_list ( const char * mask ,
2007-12-07 04:16:33 +03:00
uint16 attribute ,
2010-10-29 22:56:51 +04:00
NTSTATUS ( * fn ) ( struct cli_state * cli_state , struct file_info * ,
2010-07-30 18:18:51 +04:00
const char * dir ) ,
2007-12-07 04:16:33 +03:00
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 ;
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
struct cli_state * targetcli = NULL ;
char * targetpath = NULL ;
2010-10-29 22:56:51 +04:00
NTSTATUS ret_status = NT_STATUS_OK ;
NTSTATUS status = NT_STATUS_OK ;
1999-12-13 16:27:58 +03:00
2003-08-07 00:01:31 +04:00
if ( in_do_list & & rec ) {
1999-12-13 16:27:58 +03:00
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
2003-08-07 00:01:31 +04:00
if ( rec ) {
1999-12-13 16:27:58 +03:00
init_do_list_queue ( ) ;
add_to_do_list_queue ( mask ) ;
2007-12-07 04:16:33 +03:00
while ( ! do_list_queue_empty ( ) ) {
1999-12-13 16:27:58 +03:00
/*
* 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 )
*/
2007-12-07 04:16:33 +03:00
char * head = talloc_strdup ( ctx , do_list_queue_head ( ) ) ;
if ( ! head ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
2005-02-23 20:29:28 +03:00
/* check for dfs */
2007-12-07 04:16:33 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , head , & targetcli , & targetpath ) ) {
2005-02-23 20:29:28 +03:00
d_printf ( " do_list: [%s] %s \n " , head , cli_errstr ( cli ) ) ;
2005-02-26 17:42:55 +03:00
remove_do_list_queue_head ( ) ;
2005-02-23 20:29:28 +03:00
continue ;
}
2007-12-07 04:16:33 +03:00
2010-10-29 22:56:51 +04:00
status = cli_list ( targetcli , targetpath , attribute ,
2010-07-30 18:18:51 +04:00
do_list_helper , targetcli ) ;
2010-10-29 22:56:51 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s listing %s \n " ,
nt_errstr ( status ) , targetpath ) ;
ret_status = status ;
}
1999-12-13 16:27:58 +03:00
remove_do_list_queue_head ( ) ;
2003-08-07 00:01:31 +04:00
if ( ( ! do_list_queue_empty ( ) ) & & ( fn = = display_finfo ) ) {
2007-12-07 04:16:33 +03:00
char * next_file = do_list_queue_head ( ) ;
char * save_ch = 0 ;
1999-12-13 16:27:58 +03:00
if ( ( strlen ( next_file ) > = 2 ) & &
( next_file [ strlen ( next_file ) - 1 ] = = ' * ' ) & &
2006-07-12 07:20:53 +04:00
( next_file [ strlen ( next_file ) - 2 ] = = CLI_DIRSEP_CHAR ) ) {
1999-12-13 16:27:58 +03:00
save_ch = next_file +
strlen ( next_file ) - 2 ;
* save_ch = ' \0 ' ;
2007-12-07 04:16:33 +03:00
if ( showacls ) {
/* cwd is only used if showacls is on */
client_set_cwd ( next_file ) ;
}
1999-12-13 16:27:58 +03:00
}
2006-11-01 20:18:08 +03:00
if ( ! showacls ) /* don't disturbe the showacls output */
d_printf ( " \n %s \n " , next_file ) ;
2003-08-07 00:01:31 +04:00
if ( save_ch ) {
2006-07-12 07:20:53 +04:00
* save_ch = CLI_DIRSEP_CHAR ;
1999-12-13 16:27:58 +03:00
}
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( head ) ;
TALLOC_FREE ( targetpath ) ;
1999-12-13 16:27:58 +03:00
}
2003-08-07 00:01:31 +04:00
} else {
2005-02-23 20:29:28 +03:00
/* check for dfs */
2009-03-18 00:53:06 +03:00
if ( cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetpath ) ) {
2010-08-02 21:22:22 +04:00
status = cli_list ( targetcli , targetpath , attribute ,
do_list_helper , targetcli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " %s listing %s \n " ,
2010-08-02 21:22:22 +04:00
nt_errstr ( status ) , targetpath ) ;
2010-10-29 22:56:51 +04:00
ret_status = status ;
2007-12-07 04:16:33 +03:00
}
TALLOC_FREE ( targetpath ) ;
} else {
2005-02-23 20:29:28 +03:00
d_printf ( " do_list: [%s] %s \n " , mask , cli_errstr ( cli ) ) ;
2010-10-29 22:56:51 +04:00
ret_status = cli_nt_error ( cli ) ;
2007-12-07 04:16:33 +03:00
}
1999-12-13 16:27:58 +03:00
}
in_do_list = 0 ;
reset_do_list_queue ( ) ;
2010-10-29 22:56:51 +04:00
return ret_status ;
1998-11-09 06:45:49 +03:00
}
/****************************************************************************
2003-08-07 00:01:31 +04: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
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2011-04-29 05:57:02 +04:00
uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
2007-12-07 04:16:33 +03:00
char * mask = NULL ;
char * buf = NULL ;
int rc = 1 ;
2010-10-29 22:56:51 +04:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
dir_total = 0 ;
2008-02-09 03:59:52 +03:00
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! mask ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-02-09 03:59:52 +03:00
normalize_name ( buf ) ;
2007-12-07 04:16:33 +03:00
if ( * buf = = CLI_DIRSEP_CHAR ) {
2008-02-09 03:59:52 +03:00
mask = talloc_strdup ( ctx , buf ) ;
2007-12-07 04:16:33 +03:00
} else {
2009-01-01 03:30:11 +03:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-07 04:16:33 +03:00
}
2003-08-07 00:01:31 +04:00
} else {
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf_append ( mask , " * " ) ;
}
if ( ! mask ) {
return 1 ;
1996-06-04 10:42:03 +04:00
}
2007-03-07 05:27:54 +03:00
if ( showacls ) {
/* cwd is only used if showacls is on */
2007-12-07 04:16:33 +03:00
client_set_cwd ( client_get_cur_dir ( ) ) ;
2007-03-07 05:27:54 +03:00
}
2010-10-29 22:56:51 +04:00
status = do_list ( mask , attribute , display_finfo , recurse , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
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
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Get a directory listing .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_du ( void )
1996-06-04 10:42:03 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2011-04-29 05:57:02 +04:00
uint16 attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
2007-12-07 04:16:33 +03:00
char * mask = NULL ;
char * buf = NULL ;
2010-10-29 22:56:51 +04:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
int rc = 1 ;
1998-11-09 06:45:49 +03:00
dir_total = 0 ;
2007-12-07 04:16:33 +03:00
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mask ) {
return 1 ;
}
if ( ( mask [ 0 ] ! = ' \0 ' ) & & ( mask [ strlen ( mask ) - 1 ] ! = CLI_DIRSEP_CHAR ) ) {
2009-01-01 03:30:11 +03:00
mask = talloc_asprintf_append ( mask , " %s " , CLI_DIRSEP_STR ) ;
2007-12-07 04:16:33 +03:00
if ( ! mask ) {
return 1 ;
}
}
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-02-09 03:59:52 +03:00
normalize_name ( buf ) ;
2007-12-07 04:16:33 +03:00
if ( * buf = = CLI_DIRSEP_CHAR ) {
mask = talloc_strdup ( ctx , buf ) ;
} else {
2009-01-01 03:30:11 +03:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-07 04:16:33 +03:00
}
1998-11-09 06:45:49 +03:00
} else {
2007-12-07 04:16:33 +03:00
mask = talloc_strdup ( ctx , " * " ) ;
1996-06-04 10:42:03 +04:00
}
2010-10-29 22:56:51 +04:00
status = do_list ( mask , attribute , do_du , recurse , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
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
2007-07-22 15:18:49 +04:00
static int cmd_echo ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * num ;
char * data ;
2008-08-27 21:30:57 +04:00
NTSTATUS status ;
2007-07-22 15:18:49 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & num , NULL )
| | ! next_token_talloc ( ctx , & cmd_ptr , & data , NULL ) ) {
2007-08-05 00:08:35 +04:00
d_printf ( " echo <num> <data> \n " ) ;
2007-07-22 15:18:49 +04:00
return 1 ;
}
2008-08-27 21:30:57 +04:00
status = cli_echo ( cli , atoi ( num ) , data_blob_const ( data , strlen ( data ) ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " echo failed: %s \n " , nt_errstr ( status ) ) ;
2007-07-22 15:18:49 +04:00
return 1 ;
}
return 0 ;
}
1998-11-09 06:45:49 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Get a file from rname to lname
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-28 17:21:33 +03:00
static NTSTATUS writefile_sink ( char * buf , size_t n , void * priv )
{
int * pfd = ( int * ) priv ;
if ( writefile ( * pfd , buf , n ) = = - 1 ) {
return map_nt_error_from_unix ( errno ) ;
}
return NT_STATUS_OK ;
}
2007-12-07 04:16:33 +03:00
static int do_get ( const char * rname , const char * lname_in , bool reget )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
2009-05-01 02:26:43 +04:00
int handle = 0 ;
uint16_t fnum ;
2007-12-07 04:16:33 +03:00
bool newhandle = false ;
2010-08-30 14:15:54 +04:00
struct timespec tp_start ;
1998-11-09 23:33:37 +03:00
uint16 attr ;
2005-03-23 00:17:01 +03:00
SMB_OFF_T size ;
2002-09-25 19:19:00 +04:00
off_t start = 0 ;
2008-03-28 17:21:14 +03:00
SMB_OFF_T nread = 0 ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
2007-12-07 04:16:33 +03:00
struct cli_state * targetcli = NULL ;
char * targetname = NULL ;
char * lname = NULL ;
2008-02-28 17:21:33 +03:00
NTSTATUS status ;
1998-11-09 06:45:49 +03:00
2007-12-07 04:16:33 +03:00
lname = talloc_strdup ( ctx , lname_in ) ;
if ( ! lname ) {
return 1 ;
}
1998-11-09 06:45:49 +03:00
if ( lowercase ) {
2003-07-03 23:11:31 +04:00
strlower_m ( lname ) ;
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , rname , & targetcli , & targetname ) ) {
2005-02-23 21:27:13 +03:00
d_printf ( " Failed to open %s: %s \n " , rname , cli_errstr ( cli ) ) ;
return 1 ;
}
2010-08-30 14:15:54 +04:00
clock_gettime_mono ( & tp_start ) ;
2007-12-07 04:16:33 +03:00
2010-08-13 17:08:38 +04:00
status = cli_open ( targetcli , targetname , O_RDONLY , DENY_NONE , & fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s opening remote file %s \n " , nt_errstr ( status ) ,
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 {
2002-09-25 19:19:00 +04:00
if ( reget ) {
handle = sys_open ( lname , O_WRONLY | O_CREAT , 0644 ) ;
if ( handle > = 0 ) {
start = sys_lseek ( handle , 0 , SEEK_END ) ;
if ( start = = - 1 ) {
d_printf ( " Error seeking local file \n " ) ;
return 1 ;
}
}
} else {
handle = sys_open ( lname , O_WRONLY | O_CREAT | O_TRUNC , 0644 ) ;
}
2007-12-07 04:16:33 +03:00
newhandle = true ;
1998-11-09 06:45:49 +03:00
}
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
2011-01-20 16:38:30 +03:00
status = cli_qfileinfo_basic ( targetcli , fnum , & attr , & size , NULL , NULL ,
NULL , NULL , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
status = cli_getattrE ( targetcli , fnum , & attr , & size , NULL , NULL ,
NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " getattrib: %s \n " , nt_errstr ( status ) ) ;
return 1 ;
}
1998-11-09 06:45:49 +03:00
}
1996-06-04 10:42:03 +04:00
2007-12-07 04:16:33 +03:00
DEBUG ( 1 , ( " getting file %s of size %.0f as %s " ,
2002-09-25 19:19:00 +04:00
rname , ( double ) size , lname ) ) ;
1996-06-04 10:42:03 +04:00
2008-03-01 14:05:09 +03:00
status = cli_pull ( targetcli , fnum , start , size , io_bufsize ,
2008-02-28 17:21:33 +03:00
writefile_sink , ( void * ) & handle , & nread ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " parallel_read returned %s \n " ,
nt_errstr ( status ) ) ;
2005-02-23 21:27:13 +03:00
cli_close ( targetcli , 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
2010-08-13 17:08:38 +04:00
status = cli_close ( targetcli , fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error %s closing remote file \n " , nt_errstr ( status ) ) ;
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
2011-04-29 06:00:57 +04:00
if ( archive_level > = 2 & & ( attr & FILE_ATTRIBUTE_ARCHIVE ) ) {
cli_setatr ( cli , rname , attr & ~ ( uint16 ) FILE_ATTRIBUTE_ARCHIVE , 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
{
2010-08-30 14:15:54 +04:00
struct timespec tp_end ;
1998-11-09 06:45:49 +03:00
int this_time ;
2007-12-07 04:16:33 +03:00
2010-08-30 14:15:54 +04:00
clock_gettime_mono ( & tp_end ) ;
2010-09-17 15:47:05 +04:00
this_time = nsec_time_diff ( & tp_end , & tp_start ) / 1000000 ;
1998-11-09 06:45:49 +03:00
get_total_time_ms + = this_time ;
get_total_size + = nread ;
2007-12-07 04:16:33 +03:00
2008-08-29 03:06:23 +04:00
DEBUG ( 1 , ( " (%3.1f KiloBytes/sec) (average %3.1f KiloBytes/sec) \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 ) ) ) ;
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( targetname ) ;
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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Get a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_get ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * lname = NULL ;
char * rname = NULL ;
char * fname = NULL ;
2008-02-09 03:59:52 +03:00
rname = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! rname ) {
return 1 ;
}
1996-05-04 11:50:46 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & fname , NULL ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " get <filename> [localname] \n " ) ;
return 1 ;
}
2009-01-01 03:30:11 +03:00
rname = talloc_asprintf_append ( rname , " %s " , fname ) ;
2007-12-07 04:16:33 +03:00
if ( ! rname ) {
return 1 ;
}
rname = clean_name ( ctx , rname ) ;
if ( ! rname ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
next_token_talloc ( ctx , & cmd_ptr , & lname , NULL ) ;
2007-12-07 04:16:33 +03:00
if ( ! lname ) {
lname = fname ;
}
return do_get ( rname , lname , false ) ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Do an mget operation on one file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 22:56:51 +04:00
static NTSTATUS do_mget ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 18:18:51 +04:00
const char * dir )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2010-10-29 22:56:51 +04:00
NTSTATUS status = NT_STATUS_OK ;
2007-12-07 04:16:33 +03:00
char * rname = NULL ;
char * quest = NULL ;
char * saved_curdir = NULL ;
char * mget_mask = NULL ;
char * new_cd = NULL ;
if ( ! finfo - > name ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2007-12-07 04:16:33 +03:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( strequal ( finfo - > name , " . " ) | | strequal ( finfo - > name , " .. " ) )
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
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 " ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_UNSUCCESSFUL ;
1996-05-04 11:50:46 +04:00
}
2011-04-29 05:57:02 +04:00
if ( finfo - > mode & FILE_ATTRIBUTE_DIRECTORY ) {
2007-12-07 04:16:33 +03:00
if ( asprintf ( & quest ,
" Get directory %s? " , finfo - > name ) < 0 ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
} else {
if ( asprintf ( & quest ,
" Get file %s? " , finfo - > name ) < 0 ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
}
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
if ( prompt & & ! yesno ( quest ) ) {
SAFE_FREE ( quest ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2007-12-07 04:16:33 +03:00
}
SAFE_FREE ( quest ) ;
1996-05-04 11:50:46 +04:00
2011-04-29 05:57:02 +04:00
if ( ! ( finfo - > mode & FILE_ATTRIBUTE_DIRECTORY ) ) {
2007-12-07 04:16:33 +03:00
rname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
finfo - > name ) ;
if ( ! rname ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
do_get ( rname , finfo - > name , false ) ;
TALLOC_FREE ( rname ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
/* handle directories */
2007-12-07 04:16:33 +03:00
saved_curdir = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! saved_curdir ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
1998-11-09 06:45:49 +03:00
2007-12-07 04:16:33 +03:00
new_cd = talloc_asprintf ( ctx ,
" %s%s%s " ,
client_get_cur_dir ( ) ,
finfo - > name ,
CLI_DIRSEP_STR ) ;
if ( ! new_cd ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
client_set_cur_dir ( new_cd ) ;
1998-11-09 06:45:49 +03:00
2007-12-07 04:16:33 +03:00
string_replace ( finfo - > name , ' \\ ' , ' / ' ) ;
if ( lowercase ) {
2003-07-03 23:11:31 +04:00
strlower_m ( finfo - > name ) ;
2007-12-07 04:16:33 +03:00
}
2008-10-17 14:48:19 +04:00
if ( ! directory_exist ( finfo - > name ) & &
2000-03-11 01:25:02 +03:00
mkdir ( finfo - > name , 0777 ) ! = 0 ) {
2001-09-07 18:14:57 +04:00
d_printf ( " failed to create directory %s \n " , finfo - > name ) ;
2007-12-07 04:16:33 +03:00
client_set_cur_dir ( saved_curdir ) ;
2010-10-29 22:56:51 +04:00
return map_nt_error_from_unix ( errno ) ;
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
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 ) ;
2007-12-07 04:16:33 +03:00
client_set_cur_dir ( saved_curdir ) ;
2010-10-29 22:56:51 +04:00
return map_nt_error_from_unix ( errno ) ;
2007-12-07 04:16:33 +03:00
}
mget_mask = talloc_asprintf ( ctx ,
" %s* " ,
client_get_cur_dir ( ) ) ;
if ( ! mget_mask ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
}
2011-04-29 05:57:02 +04:00
status = do_list ( mget_mask , FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY , do_mget , false , true ) ;
2010-10-29 22:56:51 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
1996-06-04 10:42:03 +04:00
}
1996-05-04 11:50:46 +04:00
2009-01-01 03:30:11 +03:00
if ( chdir ( " .. " ) = = - 1 ) {
d_printf ( " do_mget: failed to chdir to .. (error %s) \n " ,
strerror ( errno ) ) ;
2010-10-29 22:56:51 +04:00
return map_nt_error_from_unix ( errno ) ;
2009-01-01 03:30:11 +03:00
}
2007-12-07 04:16:33 +03:00
client_set_cur_dir ( saved_curdir ) ;
TALLOC_FREE ( mget_mask ) ;
TALLOC_FREE ( saved_curdir ) ;
TALLOC_FREE ( new_cd ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
1996-06-04 10:42:03 +04:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
View the file using the pager .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_more ( void )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * rname = NULL ;
char * fname = NULL ;
char * lname = NULL ;
char * pager_cmd = NULL ;
const 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
2008-02-09 03:59:52 +03:00
rname = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! rname ) {
return 1 ;
}
lname = talloc_asprintf ( ctx , " %s/smbmore.XXXXXX " , tmpdir ( ) ) ;
if ( ! lname ) {
return 1 ;
}
2009-04-21 01:58:26 +04:00
fd = mkstemp ( lname ) ;
2001-04-12 03:19:08 +04:00
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 ) ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & fname , NULL ) ) {
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
}
2009-01-01 03:30:11 +03:00
rname = talloc_asprintf_append ( rname , " %s " , fname ) ;
2007-12-07 04:16:33 +03:00
if ( ! rname ) {
return 1 ;
}
rname = clean_name ( ctx , rname ) ;
if ( ! rname ) {
return 1 ;
}
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
rc = do_get ( rname , lname , false ) ;
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
2007-12-07 04:16:33 +03:00
pager_cmd = talloc_asprintf ( ctx ,
" %s %s " ,
( pager ? pager : PAGER ) ,
lname ) ;
if ( ! pager_cmd ) {
return 1 ;
}
2009-01-01 03:30:11 +03:00
if ( system ( pager_cmd ) = = - 1 ) {
d_printf ( " system command '%s' returned -1 \n " ,
pager_cmd ) ;
}
2001-04-12 03:19:08 +04:00
unlink ( lname ) ;
2007-12-07 04:16:33 +03:00
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
1998-11-09 06:45:49 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Do a mget command .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_mget ( void )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2011-04-29 07:23:14 +04:00
uint16 attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
2007-12-07 05:08:01 +03:00
char * mget_mask = NULL ;
char * buf = NULL ;
2010-10-29 22:56:51 +04:00
NTSTATUS status = NT_STATUS_OK ;
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
if ( recurse ) {
2011-04-29 05:57:02 +04:00
attribute | = FILE_ATTRIBUTE_DIRECTORY ;
2007-12-07 04:16:33 +03:00
}
abort_mget = false ;
2007-12-19 23:59:28 +03:00
while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2010-10-29 22:56:51 +04:00
2007-12-07 04:16:33 +03:00
mget_mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mget_mask ) {
return 1 ;
}
if ( * buf = = CLI_DIRSEP_CHAR ) {
mget_mask = talloc_strdup ( ctx , buf ) ;
} else {
mget_mask = talloc_asprintf_append ( mget_mask ,
2009-01-01 03:30:11 +03:00
" %s " , buf ) ;
2007-12-07 04:16:33 +03:00
}
if ( ! mget_mask ) {
return 1 ;
}
2010-10-29 22:56:51 +04:00
status = do_list ( mget_mask , attribute , do_mget , false , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
1996-06-04 10:42:03 +04:00
}
1998-11-09 06:45:49 +03:00
2009-01-05 17:47:19 +03:00
if ( mget_mask = = NULL ) {
d_printf ( " nothing to mget \n " ) ;
return 0 ;
}
1998-11-09 06:45:49 +03:00
if ( ! * mget_mask ) {
2008-02-09 03:59:52 +03:00
mget_mask = talloc_asprintf ( ctx ,
" %s* " ,
client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! mget_mask ) {
return 1 ;
}
2010-10-29 22:56:51 +04:00
status = do_list ( mget_mask , attribute , do_mget , false , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
1996-06-04 10:42:03 +04:00
}
2007-12-07 04:16:33 +03:00
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Make a directory of name " name " .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static bool do_mkdir ( const char * name )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetname = NULL ;
2010-08-13 17:08:38 +04:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , name , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " mkdir %s: %s \n " , name , cli_errstr ( cli ) ) ;
2007-12-07 04:16:33 +03:00
return false ;
2005-02-23 22:26:32 +03:00
}
2010-08-13 17:08:38 +04:00
status = cli_mkdir ( targetcli , targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s making remote directory %s \n " ,
2010-08-13 17:08:38 +04:00
nt_errstr ( status ) , name ) ;
2007-12-07 04:16:33 +03:00
return false ;
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
return true ;
1996-05-04 11:50:46 +04:00
}
2001-10-11 11:42:52 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Show 8.3 name of a file .
2001-10-11 11:42:52 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static bool do_altname ( const char * name )
2001-10-11 11:42:52 +04:00
{
2007-12-07 04:16:33 +03:00
fstring altname ;
2010-08-13 17:08:38 +04:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
2010-08-13 17:08:38 +04:00
status = cli_qpathinfo_alt_name ( cli , name , altname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-10-11 11:42:52 +04:00
d_printf ( " %s getting alt name for %s \n " ,
2010-08-13 17:08:38 +04:00
nt_errstr ( status ) , name ) ;
2007-12-07 04:16:33 +03:00
return false ;
2001-10-11 11:42:52 +04:00
}
d_printf ( " %s \n " , altname ) ;
2007-12-07 04:16:33 +03:00
return true ;
2001-10-11 11:42:52 +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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_quit ( void )
1998-09-21 12:45:11 +04:00
{
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
1998-11-09 06:45:49 +03:00
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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Make a directory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_mkdir ( void )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mask ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-07 04:16:33 +03:00
if ( ! recurse ) {
2001-09-07 18:14:57 +04:00
d_printf ( " mkdir <dirname> \n " ) ;
2007-12-07 04:16:33 +03:00
}
return 1 ;
}
2009-01-01 03:30:11 +03:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-07 04:16:33 +03:00
if ( ! mask ) {
2001-10-09 23:12:18 +04:00
return 1 ;
1998-10-24 06:49:09 +04:00
}
1996-05-04 11:50:46 +04:00
1998-11-09 06:45:49 +03:00
if ( recurse ) {
2007-12-07 04:16:33 +03:00
char * ddir = NULL ;
char * ddir2 = NULL ;
2007-03-09 02:54:57 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetname = NULL ;
char * p = NULL ;
2008-01-23 13:04:10 +03:00
char * saveptr ;
2007-12-07 04:16:33 +03:00
ddir2 = talloc_strdup ( ctx , " " ) ;
if ( ! ddir2 ) {
2007-03-09 02:54:57 +03:00
return 1 ;
}
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2007-12-07 04:16:33 +03:00
return 1 ;
}
ddir = talloc_strdup ( ctx , targetname ) ;
if ( ! ddir ) {
return 1 ;
}
2003-09-05 23:59:55 +04:00
trim_char ( ddir , ' . ' , ' \0 ' ) ;
2008-01-23 13:04:10 +03:00
p = strtok_r ( ddir , " / \\ " , & saveptr ) ;
1998-11-09 06:45:49 +03:00
while ( p ) {
2009-01-01 03:30:11 +03:00
ddir2 = talloc_asprintf_append ( ddir2 , " %s " , p ) ;
2007-12-07 04:16:33 +03:00
if ( ! ddir2 ) {
return 1 ;
}
2009-04-22 17:46:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_chkpath ( targetcli , ddir2 ) ) ) {
1998-11-09 06:45:49 +03:00
do_mkdir ( ddir2 ) ;
}
2009-01-01 03:30:11 +03:00
ddir2 = talloc_asprintf_append ( ddir2 , " %s " , CLI_DIRSEP_STR ) ;
2007-12-07 04:16:33 +03:00
if ( ! ddir2 ) {
return 1 ;
}
2008-01-23 13:04:10 +03:00
p = strtok_r ( NULL , " / \\ " , & saveptr ) ;
2007-12-07 04:16:33 +03:00
}
1998-11-09 06:45:49 +03:00
} else {
do_mkdir ( mask ) ;
}
2007-12-07 04:16:33 +03:00
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
/****************************************************************************
2003-08-07 00:01:31 +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
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * name ;
char * buf ;
2001-10-11 11:42:52 +04:00
2007-12-07 04:16:33 +03:00
name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! name ) {
2001-10-11 12:40:42 +04:00
return 1 ;
2001-10-11 11:42:52 +04:00
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " altname <file> \n " ) ;
return 1 ;
}
2009-01-01 03:30:11 +03:00
name = talloc_asprintf_append ( name , " %s " , buf ) ;
2007-12-07 04:16:33 +03:00
if ( ! name ) {
return 1 ;
}
2001-10-11 11:42:52 +04:00
do_altname ( name ) ;
2001-10-11 12:40:42 +04:00
return 0 ;
2001-10-11 11:42:52 +04:00
}
2010-02-23 01:36:40 +03:00
static char * attr_str ( TALLOC_CTX * mem_ctx , uint16_t mode )
{
char * attrs = TALLOC_ZERO_ARRAY ( mem_ctx , char , 17 ) ;
int i = 0 ;
if ( ! ( mode & FILE_ATTRIBUTE_NORMAL ) ) {
2011-03-02 19:55:31 +03:00
if ( mode & FILE_ATTRIBUTE_ENCRYPTED ) {
attrs [ i + + ] = ' E ' ;
}
if ( mode & FILE_ATTRIBUTE_NONINDEXED ) {
attrs [ i + + ] = ' N ' ;
}
if ( mode & FILE_ATTRIBUTE_OFFLINE ) {
attrs [ i + + ] = ' O ' ;
}
if ( mode & FILE_ATTRIBUTE_COMPRESSED ) {
attrs [ i + + ] = ' C ' ;
}
if ( mode & FILE_ATTRIBUTE_REPARSE_POINT ) {
attrs [ i + + ] = ' r ' ;
}
if ( mode & FILE_ATTRIBUTE_SPARSE ) {
attrs [ i + + ] = ' s ' ;
}
if ( mode & FILE_ATTRIBUTE_TEMPORARY ) {
attrs [ i + + ] = ' T ' ;
}
if ( mode & FILE_ATTRIBUTE_NORMAL ) {
attrs [ i + + ] = ' N ' ;
}
2010-02-23 01:36:40 +03:00
if ( mode & FILE_ATTRIBUTE_READONLY ) {
attrs [ i + + ] = ' R ' ;
}
if ( mode & FILE_ATTRIBUTE_HIDDEN ) {
attrs [ i + + ] = ' H ' ;
}
if ( mode & FILE_ATTRIBUTE_SYSTEM ) {
attrs [ i + + ] = ' S ' ;
}
if ( mode & FILE_ATTRIBUTE_DIRECTORY ) {
attrs [ i + + ] = ' D ' ;
}
if ( mode & FILE_ATTRIBUTE_ARCHIVE ) {
attrs [ i + + ] = ' A ' ;
}
}
return attrs ;
}
2008-01-18 13:08:17 +03:00
/****************************************************************************
Show all info we can get
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int do_allinfo ( const char * name )
{
fstring altname ;
struct timespec b_time , a_time , m_time , c_time ;
SMB_OFF_T size ;
uint16_t mode ;
SMB_INO_T ino ;
NTTIME tmp ;
2010-11-29 20:09:49 +03:00
uint16_t fnum ;
2008-01-18 13:08:17 +03:00
unsigned int num_streams ;
struct stream_struct * streams ;
2010-11-29 20:09:49 +03:00
int num_snapshots ;
char * * snapshots ;
2008-01-18 13:08:17 +03:00
unsigned int i ;
2010-07-26 11:21:17 +04:00
NTSTATUS status ;
2008-01-18 13:08:17 +03:00
2010-07-26 11:21:17 +04:00
status = cli_qpathinfo_alt_name ( cli , name , altname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s getting alt name for %s \n " , nt_errstr ( status ) ,
name ) ;
2008-01-18 13:08:17 +03:00
return false ;
}
d_printf ( " altname: %s \n " , altname ) ;
2010-07-26 11:27:11 +04:00
status = cli_qpathinfo2 ( cli , name , & b_time , & a_time , & m_time , & c_time ,
& size , & mode , & ino ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s getting pathinfo for %s \n " , nt_errstr ( status ) ,
name ) ;
2008-01-18 13:08:17 +03:00
return false ;
}
unix_timespec_to_nt_time ( & tmp , b_time ) ;
d_printf ( " create_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
unix_timespec_to_nt_time ( & tmp , a_time ) ;
d_printf ( " access_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
unix_timespec_to_nt_time ( & tmp , m_time ) ;
d_printf ( " write_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
unix_timespec_to_nt_time ( & tmp , c_time ) ;
d_printf ( " change_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2011-03-02 19:55:31 +03:00
d_printf ( " attributes: %s (%x) \n " , attr_str ( talloc_tos ( ) , mode ) , mode ) ;
2010-02-23 01:36:40 +03:00
2010-07-26 12:35:15 +04:00
status = cli_qpathinfo_streams ( cli , name , talloc_tos ( ) , & num_streams ,
& streams ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s getting streams for %s \n " , nt_errstr ( status ) ,
name ) ;
2008-01-18 13:08:17 +03:00
return false ;
}
for ( i = 0 ; i < num_streams ; i + + ) {
d_printf ( " stream: [%s], %lld bytes \n " , streams [ i ] . name ,
( unsigned long long ) streams [ i ] . size ) ;
}
2011-03-30 15:19:46 +04:00
status = cli_ntcreate ( cli , name , 0 ,
CREATE_ACCESS_READ , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE
| FILE_SHARE_DELETE ,
FILE_OPEN , 0x0 , 0x0 , & fnum ) ;
2010-11-29 20:09:49 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
/*
* Ignore failure , it does not hurt if we can ' t list
* snapshots
*/
return 0 ;
}
status = cli_shadow_copy_data ( talloc_tos ( ) , cli , fnum ,
true , & snapshots , & num_snapshots ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
cli_close ( cli , fnum ) ;
return 0 ;
}
for ( i = 0 ; i < num_snapshots ; i + + ) {
char * snap_name ;
d_printf ( " %s \n " , snapshots [ i ] ) ;
snap_name = talloc_asprintf ( talloc_tos ( ) , " %s%s " ,
snapshots [ i ] , name ) ;
status = cli_qpathinfo2 ( cli , snap_name , & b_time , & a_time ,
& m_time , & c_time , & size ,
NULL , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " pathinfo(%s) failed: %s \n " ,
snap_name , nt_errstr ( status ) ) ;
TALLOC_FREE ( snap_name ) ;
continue ;
}
unix_timespec_to_nt_time ( & tmp , b_time ) ;
d_printf ( " create_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
unix_timespec_to_nt_time ( & tmp , a_time ) ;
d_printf ( " access_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
unix_timespec_to_nt_time ( & tmp , m_time ) ;
d_printf ( " write_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
unix_timespec_to_nt_time ( & tmp , c_time ) ;
d_printf ( " change_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
d_printf ( " size: %d \n " , ( int ) size ) ;
}
TALLOC_FREE ( snapshots ) ;
2008-01-18 13:08:17 +03:00
return 0 ;
}
/****************************************************************************
Show all info we can get
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_allinfo ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * name ;
char * buf ;
name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! name ) {
return 1 ;
}
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-01-19 00:47:10 +03:00
d_printf ( " allinfo <file> \n " ) ;
2008-01-18 13:08:17 +03:00
return 1 ;
}
2009-01-01 03:30:11 +03:00
name = talloc_asprintf_append ( name , " %s " , buf ) ;
2008-01-18 13:08:17 +03:00
if ( ! name ) {
return 1 ;
}
do_allinfo ( name ) ;
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Put a single file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-07 04:16:33 +03:00
static int do_put ( const char * rname , const char * lname , bool reput )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2009-05-01 02:26:43 +04:00
uint16_t fnum ;
2001-09-10 15:08:57 +04:00
XFILE * f ;
2005-03-23 00:17:01 +03:00
SMB_OFF_T start = 0 ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
2010-08-30 14:15:54 +04:00
struct timespec tp_start ;
2005-02-23 21:27:13 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetname = NULL ;
2008-12-20 01:33:55 +03:00
struct push_state state ;
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , rname , & targetcli , & targetname ) ) {
2005-02-23 21:27:13 +03:00
d_printf ( " Failed to open %s: %s \n " , rname , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2010-08-30 14:15:54 +04:00
clock_gettime_mono ( & tp_start ) ;
1996-05-04 11:50:46 +04:00
2002-09-25 19:19:00 +04:00
if ( reput ) {
2009-05-01 02:26:43 +04:00
status = cli_open ( targetcli , targetname , O_RDWR | O_CREAT , DENY_NONE , & fnum ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
2011-03-27 13:50:55 +04:00
if ( ! NT_STATUS_IS_OK ( status = cli_qfileinfo_basic (
2010-10-24 00:37:16 +04:00
targetcli , fnum , NULL ,
& start , NULL , NULL ,
NULL , NULL , NULL ) ) & &
2011-03-27 13:50:55 +04:00
! NT_STATUS_IS_OK ( status = cli_getattrE (
targetcli , fnum , NULL ,
& start , NULL , NULL ,
NULL ) ) ) {
d_printf ( " getattrib: %s \n " , nt_errstr ( status ) ) ;
2002-09-25 19:19:00 +04:00
return 1 ;
}
}
} else {
2009-05-01 02:26:43 +04:00
status = cli_open ( targetcli , targetname , O_RDWR | O_CREAT | O_TRUNC , DENY_NONE , & fnum ) ;
2002-09-25 19:19:00 +04:00
}
2007-12-07 04:16:33 +03:00
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-03-27 13:50:55 +04:00
d_printf ( " %s opening remote file %s \n " , nt_errstr ( status ) ,
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
2002-01-29 08:34:16 +03:00
jdblair 24. jun .98
Note that in this case this function will exit ( 0 ) rather
than returning . */
1998-11-09 06:45:49 +03:00
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 ) ;
2002-09-25 19:19:00 +04:00
if ( f & & reput ) {
if ( x_tseek ( f , start , SEEK_SET ) = = - 1 ) {
d_printf ( " Error seeking local file \n " ) ;
2009-06-20 04:26:53 +04:00
x_fclose ( f ) ;
2002-09-25 19:19:00 +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
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
}
2007-12-07 04:16:33 +03: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 ) ) ;
2007-12-07 04:16:33 +03:00
2008-12-20 01:33:55 +03:00
x_setvbuf ( f , NULL , X_IOFBF , io_bufsize ) ;
2008-10-23 19:42:45 +04:00
2008-12-20 01:33:55 +03:00
state . f = f ;
state . nread = 0 ;
2008-10-23 19:42:45 +04:00
2009-03-12 11:02:02 +03:00
status = cli_push ( targetcli , fnum , 0 , 0 , io_bufsize , push_source ,
& state ) ;
2008-12-20 01:33:55 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " cli_push returned %s \n " , nt_errstr ( status ) ) ;
2010-07-16 03:06:11 +04:00
rc = 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2010-08-13 17:08:38 +04:00
status = cli_close ( targetcli , fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s closing remote file %s \n " , nt_errstr ( status ) ,
rname ) ;
2009-06-20 04:26:53 +04:00
if ( f ! = x_stdin ) {
x_fclose ( f ) ;
}
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
2002-07-15 14:35:28 +04:00
if ( f ! = x_stdin ) {
x_fclose ( f ) ;
}
1998-11-09 06:45:49 +03:00
{
2010-08-30 14:15:54 +04:00
struct timespec tp_end ;
1998-11-09 06:45:49 +03:00
int this_time ;
2007-12-07 04:16:33 +03:00
2010-08-30 14:15:54 +04:00
clock_gettime_mono ( & tp_end ) ;
2010-09-17 15:47:05 +04:00
this_time = nsec_time_diff ( & tp_end , & tp_start ) / 1000000 ;
1998-11-09 06:45:49 +03:00
put_total_time_ms + = this_time ;
2008-12-20 01:33:55 +03:00
put_total_size + = state . nread ;
2007-12-07 04:16:33 +03:00
1999-12-21 12:54:24 +03:00
DEBUG ( 1 , ( " (%3.1f kb/s) (average %3.1f kb/s) \n " ,
2008-12-20 01:33:55 +03:00
state . nread / ( 1.024 * this_time + 1.0e-4 ) ,
1998-11-09 06:45:49 +03:00
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 ) {
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
1998-11-09 06:45:49 +03:00
exit ( 0 ) ;
}
2007-12-07 04:16:33 +03:00
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Put a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 23:12:18 +04:00
static int cmd_put ( void )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * lname ;
char * rname ;
char * buf ;
2008-02-09 03:59:52 +03:00
rname = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! rname ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & lname , NULL ) ) {
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
}
2007-12-07 04:16:33 +03:00
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2009-01-01 03:30:11 +03:00
rname = talloc_asprintf_append ( rname , " %s " , buf ) ;
2007-12-07 04:16:33 +03:00
} else {
2009-01-01 03:30:11 +03:00
rname = talloc_asprintf_append ( rname , " %s " , lname ) ;
2007-12-07 04:16:33 +03:00
}
if ( ! rname ) {
return 1 ;
}
rname = clean_name ( ctx , rname ) ;
if ( ! rname ) {
return 1 ;
}
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 */
2009-11-27 15:17:05 +03:00
if ( ! file_exist_stat ( lname , & st , false ) & &
1998-11-09 06:45:49 +03:00
( 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
2007-12-07 04:16:33 +03:00
return do_put ( rname , lname , false ) ;
1998-08-11 06:13:01 +04:00
}
1996-05-04 11:50:46 +04:00
2001-05-07 05:51:56 +04:00
/*************************************
2003-08-07 00:01:31 +04:00
File list structure .
2001-05-07 05:51:56 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct file_list {
struct file_list * prev , * next ;
char * file_path ;
2007-10-19 04:40:25 +04:00
bool isdir ;
2001-05-07 05:51:56 +04:00
} * file_list ;
/****************************************************************************
2003-08-07 00:01:31 +04:00
Free a file_list structure .
2001-05-07 05:51:56 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-02-24 03:22:43 +03:00
static void free_file_list ( struct file_list * l_head )
2001-05-07 05:51:56 +04:00
{
2006-03-14 02:58:58 +03:00
struct file_list * list , * next ;
2007-12-07 04:16:33 +03:00
2009-02-24 03:22:43 +03:00
for ( list = l_head ; list ; list = next ) {
2006-03-14 02:58:58 +03:00
next = list - > next ;
2009-02-24 03:22:43 +03:00
DLIST_REMOVE ( l_head , list ) ;
2006-03-14 02:58:58 +03:00
SAFE_FREE ( list - > file_path ) ;
SAFE_FREE ( list ) ;
2001-05-07 05:51:56 +04:00
}
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Seek in a directory / file list until you get something that doesn ' t start with
the specified name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +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 ) {
2007-12-07 04:16:33 +03:00
return true ;
1998-11-09 06:45:49 +03:00
}
2001-05-07 05:51:56 +04:00
list = list - > next ;
1996-05-04 11:50:46 +04:00
}
2007-12-07 04:16:33 +03:00
return false ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +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
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * new_fs = NULL ;
2007-12-19 23:59:28 +03:00
next_token_talloc ( ctx , & cmd_ptr , & new_fs , NULL )
2007-12-07 04:16:33 +03:00
;
if ( new_fs ) {
client_set_fileselection ( new_fs ) ;
} else {
client_set_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
2007-12-07 04:16:33 +03:00
match must be always set to true when calling this function
2001-05-07 05:51:56 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static int file_find ( struct file_list * * list , const char * directory ,
2007-10-19 04:40:25 +04:00
const char * expression , bool match )
2001-05-07 05:51:56 +04:00
{
2005-08-24 01:29:37 +04:00
SMB_STRUCT_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 ;
2007-10-19 04:40:25 +04:00
bool isdir ;
2003-03-18 12:43:00 +03:00
const char * dname ;
2001-05-07 05:51:56 +04:00
2005-08-24 01:29:37 +04:00
dir = sys_opendir ( directory ) ;
2003-08-07 00:01:31 +04:00
if ( ! dir )
return - 1 ;
2007-12-07 04:16:33 +03:00
2001-05-07 09:19:52 +04:00
while ( ( dname = readdirname ( dir ) ) ) {
2003-08-07 00:01:31 +04:00
if ( ! strcmp ( " .. " , dname ) )
continue ;
if ( ! strcmp ( " . " , dname ) )
continue ;
2007-12-07 04:16:33 +03:00
2001-05-07 05:51:56 +04:00
if ( asprintf ( & path , " %s/%s " , directory , dname ) < = 0 ) {
continue ;
}
2007-12-07 04:16:33 +03:00
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 ) ) {
2007-12-07 04:16:33 +03:00
isdir = true ;
ret = file_find ( list , path , expression , false ) ;
2001-05-07 05:51:56 +04:00
}
} 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
}
2007-12-07 04:16:33 +03:00
2001-05-07 09:19:52 +04:00
if ( ret = = - 1 ) {
2001-09-17 04:47:40 +04:00
SAFE_FREE ( path ) ;
2005-08-24 01:29:37 +04:00
sys_closedir ( dir ) ;
2001-05-07 09:19:52 +04:00
return - 1 ;
2001-05-07 05:51:56 +04:00
}
}
2004-12-07 21:25:53 +03:00
entry = SMB_MALLOC_P ( struct file_list ) ;
2001-05-07 05:51:56 +04:00
if ( ! entry ) {
2001-09-07 18:14:57 +04:00
d_printf ( " Out of memory in file_find \n " ) ;
2005-08-24 01:29:37 +04:00
sys_closedir ( dir ) ;
2001-05-07 09:19:52 +04:00
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
2005-08-24 01:29:37 +04:00
sys_closedir ( dir ) ;
2001-05-07 05:51:56 +04:00
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +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
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * p = NULL ;
2007-12-19 23:59:28 +03:00
while ( next_token_talloc ( ctx , & cmd_ptr , & p , NULL ) ) {
2001-05-07 05:51:56 +04:00
int ret ;
struct file_list * temp_list ;
char * quest , * lname , * rname ;
2007-12-07 04:16:33 +03:00
2001-05-07 05:51:56 +04:00
file_list = NULL ;
2001-04-12 03:19:08 +04:00
2007-12-07 04:16:33 +03:00
ret = file_find ( & file_list , " . " , p , true ) ;
2001-05-07 05:51:56 +04:00
if ( ret ) {
free_file_list ( file_list ) ;
2001-04-12 03:19:08 +04:00
continue ;
}
2007-12-07 04:16:33 +03:00
2001-05-07 05:51:56 +04:00
quest = NULL ;
lname = NULL ;
rname = NULL ;
2007-12-07 04:16:33 +03:00
for ( temp_list = file_list ; temp_list ;
2001-05-07 05:51:56 +04:00
temp_list = temp_list - > next ) {
1998-11-09 06:45:49 +03:00
2001-09-17 04:47:40 +04:00
SAFE_FREE ( lname ) ;
2007-12-07 04:16:33 +03:00
if ( asprintf ( & lname , " %s/ " , temp_list - > file_path ) < = 0 ) {
2001-05-07 05:51:56 +04:00
continue ;
2007-12-07 04:16:33 +03:00
}
2001-05-07 05:51:56 +04:00
trim_string ( lname , " ./ " , " / " ) ;
2007-12-07 04:16:33 +03:00
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; */
2007-12-07 04:16:33 +03:00
2001-09-17 04:47:40 +04:00
SAFE_FREE ( quest ) ;
2007-12-07 04:16:33 +03:00
if ( asprintf ( & quest , " Put directory %s? " , lname ) < 0 ) {
break ;
}
2001-05-07 05:51:56 +04:00
if ( prompt & & ! yesno ( quest ) ) { /* No */
/* Skip the directory */
lname [ strlen ( lname ) - 1 ] = ' / ' ;
if ( ! seek_list ( temp_list , lname ) )
2007-12-07 04:16:33 +03:00
break ;
2001-05-07 05:51:56 +04:00
} else { /* Yes */
2001-09-17 04:47:40 +04:00
SAFE_FREE ( rname ) ;
2008-02-09 03:59:52 +03:00
if ( asprintf ( & rname , " %s%s " , client_get_cur_dir ( ) , lname ) < 0 ) {
2007-12-07 04:16:33 +03:00
break ;
}
2008-02-09 03:59:52 +03:00
normalize_name ( rname ) ;
2009-04-22 17:46:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_chkpath ( cli , rname ) ) & &
2001-05-07 05:51:56 +04:00
! do_mkdir ( rname ) ) {
DEBUG ( 0 , ( " Unable to make dir, skipping... " ) ) ;
/* Skip the directory */
lname [ strlen ( lname ) - 1 ] = ' / ' ;
2007-12-07 04:16:33 +03:00
if ( ! seek_list ( temp_list , lname ) ) {
2001-05-07 05:51:56 +04:00
break ;
2007-12-07 04:16:33 +03:00
}
2001-05-07 05:51:56 +04:00
}
1998-11-09 06:45:49 +03:00
}
continue ;
} else {
2001-09-17 04:47:40 +04:00
SAFE_FREE ( quest ) ;
2007-12-07 04:16:33 +03:00
if ( asprintf ( & quest , " Put file %s? " , lname ) < 0 ) {
break ;
}
if ( prompt & & ! yesno ( quest ) ) {
/* No */
2001-05-07 05:51:56 +04:00
continue ;
2007-12-07 04:16:33 +03:00
}
2001-05-07 05:51:56 +04:00
/* Yes */
2001-09-17 04:47:40 +04:00
SAFE_FREE ( rname ) ;
2008-02-09 03:59:52 +03:00
if ( asprintf ( & rname , " %s%s " , client_get_cur_dir ( ) , lname ) < 0 ) {
2007-12-07 04:16:33 +03:00
break ;
}
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2008-02-09 03:59:52 +03:00
normalize_name ( rname ) ;
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
do_put ( rname , lname , false ) ;
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
}
/****************************************************************************
2003-08-07 00:01:31 +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
}
/****************************************************************************
2003-08-07 00:01:31 +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
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
int job ;
1996-05-04 11:50:46 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
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 ) ;
2007-12-19 23:59:28 +03:00
} while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) ;
2007-12-07 04:16:33 +03:00
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
/****************************************************************************
2003-08-07 00:01:31 +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
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * lname = NULL ;
char * rname = NULL ;
char * p = NULL ;
1996-05-04 11:50:46 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & lname , NULL ) ) {
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
}
2007-12-07 04:16:33 +03:00
rname = talloc_strdup ( ctx , lname ) ;
if ( ! rname ) {
return 1 ;
}
2001-07-04 11:36:09 +04:00
p = strrchr_m ( rname , ' / ' ) ;
1998-11-09 06:45:49 +03:00
if ( p ) {
2007-12-07 04:16:33 +03:00
rname = talloc_asprintf ( ctx ,
" %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 , " - " ) ) {
2007-12-07 04:16:33 +03:00
rname = talloc_asprintf ( ctx ,
" stdin-%d " ,
( int ) sys_getpid ( ) ) ;
}
if ( ! rname ) {
return 1 ;
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
return do_put ( rname , lname , false ) ;
1996-05-04 11:50:46 +04:00
}
1997-07-01 05:19:13 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Show a print queue entry .
1997-07-01 05:19:13 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Show a print queue .
1996-08-13 12:57:55 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Delete some files .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2010-10-29 22:56:51 +04:00
static NTSTATUS do_del ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 18:18:51 +04:00
const char * dir )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
2010-08-13 17:08:38 +04:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%c%s " ,
dir ,
CLI_DIRSEP_CHAR ,
finfo - > name ) ;
if ( ! mask ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
1996-05-04 11:50:46 +04:00
2011-04-29 05:57:02 +04:00
if ( finfo - > mode & FILE_ATTRIBUTE_DIRECTORY ) {
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( mask ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2007-12-07 04:16:33 +03:00
}
1996-05-04 11:50:46 +04:00
2011-04-29 07:23:14 +04:00
status = cli_unlink ( cli_state , mask , FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ) ;
2010-08-13 17:08:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " %s deleting remote file %s \n " ,
2010-08-13 17:08:38 +04:00
nt_errstr ( status ) , mask ) ;
1998-11-09 06:45:49 +03:00
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( mask ) ;
2010-10-29 22:56:51 +04:00
return status ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Delete some files .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_del ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
2010-10-29 22:56:51 +04:00
NTSTATUS status = NT_STATUS_OK ;
2011-04-29 07:23:14 +04:00
uint16 attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
1996-05-04 11:50:46 +04:00
2007-12-07 04:16:33 +03:00
if ( recurse ) {
2011-04-29 05:57:02 +04:00
attribute | = FILE_ATTRIBUTE_DIRECTORY ;
2007-12-07 04:16:33 +03:00
}
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mask ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
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
}
2009-01-01 03:30:11 +03:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-07 04:16:33 +03:00
if ( ! mask ) {
return 1 ;
}
1998-11-09 06:45:49 +03:00
2010-10-29 22:56:51 +04:00
status = do_list ( mask , attribute , do_del , false , false ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2007-03-07 22:45:22 +03:00
/****************************************************************************
Wildcard delete some files .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_wdel ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
2007-03-07 22:45:22 +03:00
uint16 attribute ;
2007-03-09 02:54:57 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetname = NULL ;
2010-08-13 17:08:38 +04:00
NTSTATUS status ;
2007-03-07 22:45:22 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-07 22:45:22 +03:00
d_printf ( " wdel 0x<attrib> <wcard> \n " ) ;
return 1 ;
}
attribute = ( uint16 ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-07 22:45:22 +03:00
d_printf ( " wdel 0x<attrib> <wcard> \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx , " %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2007-03-07 22:45:22 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2007-03-09 02:54:57 +03:00
d_printf ( " cmd_wdel %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2010-08-13 17:08:38 +04:00
status = cli_unlink ( targetcli , targetname , attribute ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s deleting remote files %s \n " , nt_errstr ( status ) ,
targetname ) ;
2007-03-07 22:45:22 +03:00
}
return 0 ;
}
1999-12-13 16:27:58 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_open ( void )
1999-12-13 16:27:58 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2009-05-01 02:26:43 +04:00
uint16_t fnum = ( uint16_t ) - 1 ;
2006-07-12 04:21:14 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2001-10-09 23:12:18 +04:00
d_printf ( " open <filename> \n " ) ;
return 1 ;
1999-12-13 16:27:58 +03:00
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
1999-12-13 16:27:58 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " open %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( cli_ntcreate ( targetcli , targetname , 0 ,
FILE_READ_DATA | FILE_WRITE_DATA , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN , 0x0 , 0x0 , & fnum ) ) ) {
if ( NT_STATUS_IS_OK ( cli_ntcreate ( targetcli , targetname , 0 ,
FILE_READ_DATA , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN , 0x0 , 0x0 , & fnum ) ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " open file %s: for read/write fnum %d \n " , targetname , fnum ) ;
} else {
d_printf ( " Failed to open file %s. %s \n " , targetname , cli_errstr ( cli ) ) ;
}
} else {
d_printf ( " open file %s: for read/write fnum %d \n " , targetname , fnum ) ;
}
2006-07-12 04:21:14 +04:00
return 0 ;
}
2007-12-27 04:12:36 +03:00
static int cmd_posix_encrypt ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
if ( cli - > use_kerberos ) {
status = cli_gss_smb_encryption_start ( cli ) ;
} else {
char * domain = NULL ;
char * user = NULL ;
char * password = NULL ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & domain , NULL ) ) {
d_printf ( " posix_encrypt domain user password \n " ) ;
return 1 ;
}
if ( ! next_token_talloc ( ctx , & cmd_ptr , & user , NULL ) ) {
d_printf ( " posix_encrypt domain user password \n " ) ;
return 1 ;
}
if ( ! next_token_talloc ( ctx , & cmd_ptr , & password , NULL ) ) {
d_printf ( " posix_encrypt domain user password \n " ) ;
return 1 ;
}
status = cli_raw_ntlm_smb_encryption_start ( cli ,
user ,
password ,
domain ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " posix_encrypt failed with error %s \n " , nt_errstr ( status ) ) ;
} else {
d_printf ( " encryption on \n " ) ;
2007-12-30 09:39:52 +03:00
smb_encrypt = true ;
2007-12-27 04:12:36 +03:00
}
return 0 ;
}
2007-03-02 00:56:54 +03:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_posix_open ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-02 00:56:54 +03:00
struct cli_state * targetcli ;
mode_t mode ;
2009-05-21 05:31:36 +04:00
uint16_t fnum ;
2007-03-02 00:56:54 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_open <filename> 0<mode> \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_open <filename> 0<mode> \n " ) ;
return 1 ;
}
mode = ( mode_t ) strtol ( buf , ( char * * ) NULL , 8 ) ;
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_open %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-05-21 05:31:36 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_open ( targetcli , targetname , O_CREAT | O_RDWR , mode , & fnum ) ) ) {
if ( ! NT_STATUS_IS_OK ( cli_posix_open ( targetcli , targetname , O_CREAT | O_RDONLY , mode , & fnum ) ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_open file %s: for read/write fnum %d \n " , targetname , fnum ) ;
} else {
d_printf ( " Failed to open file %s. %s \n " , targetname , cli_errstr ( cli ) ) ;
}
} else {
d_printf ( " posix_open file %s: for read/write fnum %d \n " , targetname , fnum ) ;
}
return 0 ;
}
static int cmd_posix_mkdir ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-02 00:56:54 +03:00
struct cli_state * targetcli ;
mode_t mode ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_mkdir <filename> 0<mode> \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_mkdir <filename> 0<mode> \n " ) ;
return 1 ;
}
mode = ( mode_t ) strtol ( buf , ( char * * ) NULL , 8 ) ;
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_mkdir %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-03-09 02:54:57 +03:00
2009-05-21 05:31:36 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_mkdir ( targetcli , targetname , mode ) ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " Failed to open file %s. %s \n " , targetname , cli_errstr ( cli ) ) ;
} else {
d_printf ( " posix_mkdir created directory %s \n " , targetname ) ;
}
return 0 ;
}
static int cmd_posix_unlink ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-02 00:56:54 +03:00
struct cli_state * targetcli ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_unlink <filename> \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2007-03-02 00:56:54 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_unlink %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-04-29 00:18:51 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_unlink ( targetcli , targetname ) ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " Failed to unlink file %s. %s \n " , targetname , cli_errstr ( cli ) ) ;
} else {
d_printf ( " posix_unlink deleted file %s \n " , targetname ) ;
}
return 0 ;
}
static int cmd_posix_rmdir ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-02 00:56:54 +03:00
struct cli_state * targetcli ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_rmdir <filename> \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2007-03-02 00:56:54 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " posix_rmdir %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-04-29 00:18:51 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_rmdir ( targetcli , targetname ) ) ) {
2007-03-02 00:56:54 +03:00
d_printf ( " Failed to unlink directory %s. %s \n " , targetname , cli_errstr ( cli ) ) ;
} else {
d_printf ( " posix_rmdir deleted directory %s \n " , targetname ) ;
}
return 0 ;
}
2006-07-12 04:21:14 +04:00
static int cmd_close ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
2006-07-12 04:21:14 +04:00
int fnum ;
2001-10-09 23:12:18 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 04:21:14 +04:00
d_printf ( " close <fnum> \n " ) ;
return 1 ;
}
fnum = atoi ( buf ) ;
/* We really should use the targetcli here.... */
2009-05-01 03:57:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_close ( cli , fnum ) ) ) {
2006-07-12 04:21:14 +04:00
d_printf ( " close %d: %s \n " , fnum , cli_errstr ( cli ) ) ;
return 1 ;
}
2001-10-09 23:12:18 +04:00
return 0 ;
1999-12-13 16:27:58 +03:00
}
2006-07-12 04:21:14 +04:00
static int cmd_posix ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2006-07-12 04:21:14 +04:00
uint16 major , minor ;
uint32 caplow , caphigh ;
2007-12-07 04:16:33 +03:00
char * caps ;
2009-11-13 01:07:21 +03:00
NTSTATUS status ;
2006-07-12 04:21:14 +04:00
if ( ! SERVER_HAS_UNIX_CIFS ( cli ) ) {
d_printf ( " Server doesn't support UNIX CIFS extensions. \n " ) ;
return 1 ;
}
2009-11-13 01:07:21 +03:00
status = cli_unix_extensions_version ( cli , & major , & minor , & caplow ,
& caphigh ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Can't get UNIX CIFS extensions version from "
" server: %s \n " , nt_errstr ( status ) ) ;
2006-07-12 04:21:14 +04:00
return 1 ;
}
d_printf ( " Server supports CIFS extensions %u.%u \n " , ( unsigned int ) major , ( unsigned int ) minor ) ;
2007-12-07 04:16:33 +03:00
caps = talloc_strdup ( ctx , " " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 04:21:14 +04:00
if ( caplow & CIFS_UNIX_FCNTL_LOCKS_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " locks " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 04:21:14 +04:00
}
if ( caplow & CIFS_UNIX_POSIX_ACLS_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " acls " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 04:21:14 +04:00
}
if ( caplow & CIFS_UNIX_XATTTR_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " eas " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 04:21:14 +04:00
}
if ( caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " pathnames " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 04:21:14 +04:00
}
2007-03-02 00:56:54 +03:00
if ( caplow & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " posix_path_operations " ) ;
if ( ! caps ) {
return 1 ;
}
2007-03-02 00:56:54 +03:00
}
2007-11-01 00:12:50 +03:00
if ( caplow & CIFS_UNIX_LARGE_READ_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " large_read " ) ;
if ( ! caps ) {
return 1 ;
}
2007-11-01 00:12:50 +03:00
}
if ( caplow & CIFS_UNIX_LARGE_WRITE_CAP ) {
2007-12-07 04:16:33 +03:00
caps = talloc_asprintf_append ( caps , " large_write " ) ;
if ( ! caps ) {
return 1 ;
}
2007-11-01 00:12:50 +03:00
}
2007-12-28 10:51:03 +03:00
if ( caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP ) {
caps = talloc_asprintf_append ( caps , " posix_encrypt " ) ;
if ( ! caps ) {
return 1 ;
}
}
if ( caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP ) {
caps = talloc_asprintf_append ( caps , " mandatory_posix_encrypt " ) ;
if ( ! caps ) {
return 1 ;
}
}
2006-07-12 04:21:14 +04:00
2007-12-07 04:16:33 +03:00
if ( * caps & & caps [ strlen ( caps ) - 1 ] = = ' ' ) {
2006-07-12 04:21:14 +04:00
caps [ strlen ( caps ) - 1 ] = ' \0 ' ;
}
2007-12-28 10:51:03 +03:00
d_printf ( " Server supports CIFS capabilities %s \n " , caps ) ;
2009-11-14 02:40:21 +03:00
status = cli_set_unix_extensions_capabilities ( cli , major , minor ,
caplow , caphigh ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Can't set UNIX CIFS extensions capabilities. %s. \n " ,
nt_errstr ( status ) ) ;
2006-07-12 04:21:14 +04:00
return 1 ;
}
2006-07-12 07:20:53 +04:00
if ( caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP ) {
CLI_DIRSEP_CHAR = ' / ' ;
* CLI_DIRSEP_STR = ' / ' ;
2007-12-07 04:16:33 +03:00
client_set_cur_dir ( CLI_DIRSEP_STR ) ;
2006-07-12 07:20:53 +04:00
}
return 0 ;
}
static int cmd_lock ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
2008-10-14 03:59:36 +04:00
uint64_t start , len ;
2006-07-12 07:20:53 +04:00
enum brl_type lock_type ;
int fnum ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
fnum = atoi ( buf ) ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
if ( * buf = = ' r ' | | * buf = = ' R ' ) {
lock_type = READ_LOCK ;
} else if ( * buf = = ' w ' | | * buf = = ' W ' ) {
lock_type = WRITE_LOCK ;
} else {
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2008-10-14 03:59:36 +04:00
start = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 07:20:53 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2008-10-14 03:59:36 +04:00
len = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 07:20:53 +04:00
2009-07-14 05:43:10 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_lock ( cli , fnum , start , len , true , lock_type ) ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " lock failed %d: %s \n " , fnum , cli_errstr ( cli ) ) ;
}
2006-07-12 04:21:14 +04:00
return 0 ;
}
1996-05-04 11:50:46 +04:00
2006-07-12 07:20:53 +04:00
static int cmd_unlock ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
2008-10-14 03:59:36 +04:00
uint64_t start , len ;
2006-07-12 07:20:53 +04:00
int fnum ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " unlock <fnum> <hex-start> <hex-len> \n " ) ;
return 1 ;
}
fnum = atoi ( buf ) ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " unlock <fnum> <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2008-10-14 03:59:36 +04:00
start = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 07:20:53 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " unlock <fnum> <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2008-10-14 03:59:36 +04:00
len = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 07:20:53 +04:00
2009-07-14 05:43:10 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_unlock ( cli , fnum , start , len ) ) ) {
2006-07-12 07:20:53 +04:00
d_printf ( " unlock failed %d: %s \n " , fnum , cli_errstr ( cli ) ) ;
}
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Remove a directory .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_rmdir ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
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
}
2007-12-07 04:16:33 +03:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
1996-05-04 11:50:46 +04:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , mask , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " rmdir %s: %s \n " , mask , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-04-21 17:52:54 +04:00
if ( ! NT_STATUS_IS_OK ( cli_rmdir ( targetcli , targetname ) ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " %s removing remote directory file %s \n " ,
2005-02-23 22:26:32 +03:00
cli_errstr ( targetcli ) , mask ) ;
2001-10-09 23:12:18 +04:00
}
2007-12-07 04:16:33 +03:00
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2002-01-16 23:13:28 +03:00
/****************************************************************************
UNIX hardlink .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_link ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * oldname = NULL ;
char * newname = NULL ;
char * buf = NULL ;
char * buf2 = NULL ;
char * targetname = NULL ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2004-04-07 03:01:09 +04:00
d_printf ( " link <oldname> <newname> \n " ) ;
2002-01-16 23:13:28 +03:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
oldname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! oldname ) {
return 1 ;
}
newname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! newname ) {
return 1 ;
}
2002-01-16 23:13:28 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , oldname , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " link %s: %s \n " , oldname , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2005-02-23 22:26:32 +03:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-05-28 04:28:23 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_hardlink ( targetcli , targetname , newname ) ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " %s linking files (%s -> %s) \n " , cli_errstr ( targetcli ) , newname , oldname ) ;
2002-01-16 23:13:28 +03:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2002-01-16 23:13:28 +03:00
return 0 ;
}
2009-05-28 09:02:20 +04:00
/****************************************************************************
UNIX readlink .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_readlink ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * name = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
char linkname [ PATH_MAX + 1 ] ;
struct cli_state * targetcli ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
d_printf ( " readlink <name> \n " ) ;
return 1 ;
}
name = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! name ) {
return 1 ;
}
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , name , & targetcli , & targetname ) ) {
d_printf ( " readlink %s: %s \n " , name , cli_errstr ( cli ) ) ;
return 1 ;
}
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
if ( ! NT_STATUS_IS_OK ( cli_posix_readlink ( targetcli , name ,
linkname , PATH_MAX + 1 ) ) ) {
d_printf ( " %s readlink on file %s \n " ,
cli_errstr ( targetcli ) , name ) ;
return 1 ;
}
d_printf ( " %s -> %s \n " , name , linkname ) ;
return 0 ;
}
2002-01-16 23:13:28 +03:00
/****************************************************************************
UNIX symlink .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_symlink ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * oldname = NULL ;
char * newname = NULL ;
char * buf = NULL ;
char * buf2 = NULL ;
2010-08-17 03:31:33 +04:00
struct cli_state * newcli ;
2002-01-16 23:13:28 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2004-04-07 03:01:09 +04:00
d_printf ( " symlink <oldname> <newname> \n " ) ;
2002-01-16 23:13:28 +03:00
return 1 ;
}
2010-08-17 03:31:33 +04:00
/* Oldname (link target) must be an untouched blob. */
oldname = buf ;
2007-12-07 04:16:33 +03:00
newname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! newname ) {
return 1 ;
}
2002-01-16 23:13:28 +03:00
2010-08-17 03:31:33 +04:00
/* New name must be present in share namespace. */
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , newname , & newcli , & newname ) ) {
2007-03-09 02:54:57 +03:00
d_printf ( " link %s: %s \n " , oldname , cli_errstr ( cli ) ) ;
return 1 ;
}
2010-08-17 03:31:33 +04:00
if ( ! SERVER_HAS_UNIX_CIFS ( newcli ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2010-08-17 03:31:33 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_symlink ( newcli , oldname , newname ) ) ) {
2002-01-16 23:13:28 +03:00
d_printf ( " %s symlinking files (%s -> %s) \n " ,
2010-08-17 03:31:33 +04:00
cli_errstr ( newcli ) , newname , newname ) ;
2002-01-16 23:13:28 +03:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2002-01-16 23:13:28 +03:00
return 0 ;
}
/****************************************************************************
UNIX chmod .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_chmod ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * buf = NULL ;
char * buf2 = NULL ;
char * targetname = NULL ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
mode_t mode ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2002-01-16 23:13:28 +03:00
d_printf ( " chmod mode file \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! src ) {
return 1 ;
}
2002-01-16 23:13:28 +03:00
mode = ( mode_t ) strtol ( buf , NULL , 8 ) ;
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " chmod %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2005-02-23 22:26:32 +03:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-05-29 03:15:09 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_chmod ( targetcli , targetname , mode ) ) ) {
2002-01-16 23:13:28 +03:00
d_printf ( " %s chmod file %s 0%o \n " ,
2005-02-23 22:26:32 +03:00
cli_errstr ( targetcli ) , src , ( unsigned int ) mode ) ;
2002-01-16 23:13:28 +03:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2002-01-16 23:13:28 +03:00
return 0 ;
}
2004-09-26 10:27:54 +04:00
static const char * filetype_to_str ( mode_t mode )
{
if ( S_ISREG ( mode ) ) {
return " regular file " ;
} else if ( S_ISDIR ( mode ) ) {
return " directory " ;
2007-12-07 04:16:33 +03:00
} else
2004-09-26 10:27:54 +04:00
# ifdef S_ISCHR
if ( S_ISCHR ( mode ) ) {
return " character device " ;
} else
# endif
# ifdef S_ISBLK
if ( S_ISBLK ( mode ) ) {
return " block device " ;
} else
# endif
# ifdef S_ISFIFO
if ( S_ISFIFO ( mode ) ) {
return " fifo " ;
} else
# endif
# ifdef S_ISLNK
if ( S_ISLNK ( mode ) ) {
return " symbolic link " ;
} else
# endif
# ifdef S_ISSOCK
if ( S_ISSOCK ( mode ) ) {
return " socket " ;
} else
# endif
return " " ;
}
static char rwx_to_str ( mode_t m , mode_t bt , char ret )
{
if ( m & bt ) {
return ret ;
} else {
return ' - ' ;
}
}
static char * unix_mode_to_str ( char * s , mode_t m )
{
char * p = s ;
const char * str = filetype_to_str ( m ) ;
switch ( str [ 0 ] ) {
case ' d ' :
* p + + = ' d ' ;
break ;
case ' c ' :
* p + + = ' c ' ;
break ;
case ' b ' :
* p + + = ' b ' ;
break ;
case ' f ' :
* p + + = ' p ' ;
break ;
case ' s ' :
* p + + = str [ 1 ] = = ' y ' ? ' l ' : ' s ' ;
break ;
case ' r ' :
default :
* p + + = ' - ' ;
break ;
}
* p + + = rwx_to_str ( m , S_IRUSR , ' r ' ) ;
* p + + = rwx_to_str ( m , S_IWUSR , ' w ' ) ;
* p + + = rwx_to_str ( m , S_IXUSR , ' x ' ) ;
* p + + = rwx_to_str ( m , S_IRGRP , ' r ' ) ;
* p + + = rwx_to_str ( m , S_IWGRP , ' w ' ) ;
* p + + = rwx_to_str ( m , S_IXGRP , ' x ' ) ;
* p + + = rwx_to_str ( m , S_IROTH , ' r ' ) ;
* p + + = rwx_to_str ( m , S_IWOTH , ' w ' ) ;
* p + + = rwx_to_str ( m , S_IXOTH , ' x ' ) ;
* p + + = ' \0 ' ;
return s ;
}
2004-11-13 03:35:31 +03:00
/****************************************************************************
Utility function for UNIX getfacl .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * perms_to_string ( fstring permstr , unsigned char perms )
{
fstrcpy ( permstr , " --- " ) ;
if ( perms & SMB_POSIX_ACL_READ ) {
permstr [ 0 ] = ' r ' ;
}
if ( perms & SMB_POSIX_ACL_WRITE ) {
permstr [ 1 ] = ' w ' ;
}
if ( perms & SMB_POSIX_ACL_EXECUTE ) {
permstr [ 2 ] = ' x ' ;
}
return permstr ;
}
2004-11-13 02:42:12 +03:00
/****************************************************************************
UNIX getfacl .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_getfacl ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
2004-11-13 02:42:12 +03:00
uint16 major , minor ;
uint32 caplow , caphigh ;
char * retbuf = NULL ;
2004-11-13 03:35:31 +03:00
size_t rb_size = 0 ;
SMB_STRUCT_STAT sbuf ;
uint16 num_file_acls = 0 ;
uint16 num_dir_acls = 0 ;
uint16 i ;
2009-11-13 01:07:21 +03:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " getfacl filename \n " ) ;
return 1 ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
2004-11-13 02:42:12 +03:00
return 1 ;
}
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " stat %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2005-02-23 22:26:32 +03:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-11-13 01:07:21 +03:00
status = cli_unix_extensions_version ( targetcli , & major , & minor ,
& caplow , & caphigh ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Can't get UNIX CIFS version from server: %s. \n " ,
nt_errstr ( status ) ) ;
2004-11-13 02:42:12 +03:00
return 1 ;
}
if ( ! ( caplow & CIFS_UNIX_POSIX_ACLS_CAP ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " This server supports UNIX extensions "
" but doesn't support POSIX ACLs. \n " ) ;
2004-11-13 02:42:12 +03:00
return 1 ;
}
2009-05-29 00:32:00 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_stat ( targetcli , targetname , & sbuf ) ) ) {
2004-11-13 03:35:31 +03:00
d_printf ( " %s getfacl doing a stat on file %s \n " ,
2005-02-23 22:26:32 +03:00
cli_errstr ( targetcli ) , src ) ;
2004-11-13 03:35:31 +03:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2004-11-13 03:35:31 +03:00
2009-05-29 00:05:50 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_getfacl ( targetcli , targetname , ctx , & rb_size , & retbuf ) ) ) {
2004-11-13 02:42:12 +03:00
d_printf ( " %s getfacl file %s \n " ,
2005-02-23 22:26:32 +03:00
cli_errstr ( targetcli ) , src ) ;
2004-11-13 02:42:12 +03:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2004-11-13 02:42:12 +03:00
/* ToDo : Print out the ACL values. */
2009-05-29 00:05:50 +04:00
if ( rb_size < 6 | | SVAL ( retbuf , 0 ) ! = SMB_POSIX_ACL_VERSION ) {
2004-11-13 03:35:31 +03:00
d_printf ( " getfacl file %s, unknown POSIX acl version %u. \n " ,
src , ( unsigned int ) CVAL ( retbuf , 0 ) ) ;
return 1 ;
}
num_file_acls = SVAL ( retbuf , 2 ) ;
num_dir_acls = SVAL ( retbuf , 4 ) ;
if ( rb_size ! = SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE * ( num_file_acls + num_dir_acls ) ) {
d_printf ( " getfacl file %s, incorrect POSIX acl buffer size (should be %u, was %u). \n " ,
src ,
( unsigned int ) ( SMB_POSIX_ACL_HEADER_SIZE + SMB_POSIX_ACL_ENTRY_SIZE * ( num_file_acls + num_dir_acls ) ) ,
( unsigned int ) rb_size ) ;
return 1 ;
}
d_printf ( " # file: %s \n " , src ) ;
2009-05-14 17:34:42 +04:00
d_printf ( " # owner: %u \n # group: %u \n " , ( unsigned int ) sbuf . st_ex_uid , ( unsigned int ) sbuf . st_ex_gid ) ;
2004-11-13 03:35:31 +03:00
if ( num_file_acls = = 0 & & num_dir_acls = = 0 ) {
d_printf ( " No acls found. \n " ) ;
}
for ( i = 0 ; i < num_file_acls ; i + + ) {
uint32 uorg ;
fstring permstring ;
unsigned char tagtype = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) ) ;
unsigned char perms = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) + 1 ) ;
switch ( tagtype ) {
case SMB_POSIX_ACL_USER_OBJ :
d_printf ( " user:: " ) ;
break ;
case SMB_POSIX_ACL_USER :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
d_printf ( " user:%u: " , uorg ) ;
break ;
case SMB_POSIX_ACL_GROUP_OBJ :
d_printf ( " group:: " ) ;
break ;
case SMB_POSIX_ACL_GROUP :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
2008-09-16 05:25:15 +04:00
d_printf ( " group:%u: " , uorg ) ;
2004-11-13 03:35:31 +03:00
break ;
case SMB_POSIX_ACL_MASK :
d_printf ( " mask:: " ) ;
break ;
case SMB_POSIX_ACL_OTHER :
d_printf ( " other:: " ) ;
break ;
default :
d_printf ( " getfacl file %s, incorrect POSIX acl tagtype (%u). \n " ,
src , ( unsigned int ) tagtype ) ;
SAFE_FREE ( retbuf ) ;
return 1 ;
}
d_printf ( " %s \n " , perms_to_string ( permstring , perms ) ) ;
}
for ( i = 0 ; i < num_dir_acls ; i + + ) {
uint32 uorg ;
fstring permstring ;
unsigned char tagtype = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) ) ;
unsigned char perms = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) + 1 ) ;
switch ( tagtype ) {
case SMB_POSIX_ACL_USER_OBJ :
d_printf ( " default:user:: " ) ;
break ;
case SMB_POSIX_ACL_USER :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
d_printf ( " default:user:%u: " , uorg ) ;
break ;
case SMB_POSIX_ACL_GROUP_OBJ :
d_printf ( " default:group:: " ) ;
break ;
case SMB_POSIX_ACL_GROUP :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
2008-09-16 05:25:15 +04:00
d_printf ( " default:group:%u: " , uorg ) ;
2004-11-13 03:35:31 +03:00
break ;
case SMB_POSIX_ACL_MASK :
d_printf ( " default:mask:: " ) ;
break ;
case SMB_POSIX_ACL_OTHER :
d_printf ( " default:other:: " ) ;
break ;
default :
d_printf ( " getfacl file %s, incorrect POSIX acl tagtype (%u). \n " ,
src , ( unsigned int ) tagtype ) ;
SAFE_FREE ( retbuf ) ;
return 1 ;
}
d_printf ( " %s \n " , perms_to_string ( permstring , perms ) ) ;
}
2004-11-13 02:42:12 +03:00
return 0 ;
}
2010-10-24 15:32:30 +04:00
static void printf_cb ( const char * buf , void * private_data )
{
printf ( " %s " , buf ) ;
}
/****************************************************************************
Get the EA list of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_geteas ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
NTSTATUS status ;
size_t i , num_eas ;
struct ea_struct * eas ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL ) ) {
d_printf ( " geteas filename \n " ) ;
return 1 ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
return 1 ;
}
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli ,
& targetname ) ) {
d_printf ( " stat %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
status = cli_get_ea_list_path ( targetcli , targetname , talloc_tos ( ) ,
& num_eas , & eas ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cli_get_ea_list_path: %s \n " , nt_errstr ( status ) ) ;
return 1 ;
}
for ( i = 0 ; i < num_eas ; i + + ) {
d_printf ( " %s (%d) = \n " , eas [ i ] . name , ( int ) eas [ i ] . flags ) ;
dump_data_cb ( eas [ i ] . value . data , eas [ i ] . value . length , false ,
printf_cb , NULL ) ;
d_printf ( " \n " ) ;
}
TALLOC_FREE ( eas ) ;
return 0 ;
}
2010-10-24 17:43:34 +04:00
/****************************************************************************
Set an EA of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_setea ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * eaname = NULL ;
char * eavalue = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
2010-11-11 17:51:46 +03:00
NTSTATUS status ;
2010-10-24 17:43:34 +04:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL )
| | ! next_token_talloc ( ctx , & cmd_ptr , & eaname , NULL ) ) {
d_printf ( " setea filename eaname value \n " ) ;
return 1 ;
}
if ( ! next_token_talloc ( ctx , & cmd_ptr , & eavalue , NULL ) ) {
eavalue = talloc_strdup ( ctx , " " ) ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
return 1 ;
}
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli ,
& targetname ) ) {
d_printf ( " stat %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
2010-11-11 17:51:46 +03:00
status = cli_set_ea_path ( targetcli , targetname , eaname , eavalue ,
strlen ( eavalue ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " set_ea %s: %s \n " , src , nt_errstr ( status ) ) ;
2010-10-24 17:43:34 +04:00
return 1 ;
}
return 0 ;
}
2004-09-26 10:27:54 +04:00
/****************************************************************************
UNIX stat .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_stat ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
2004-09-26 10:27:54 +04:00
fstring mode_str ;
SMB_STRUCT_STAT sbuf ;
2006-06-15 01:36:49 +04:00
struct tm * lt ;
2009-05-14 17:34:42 +04:00
time_t tmp_time ;
2004-09-26 10:27:54 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL ) ) {
2004-09-26 10:27:54 +04:00
d_printf ( " stat file \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
return 1 ;
}
2004-09-26 10:27:54 +04:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " stat %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2009-05-29 00:32:00 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_stat ( targetcli , targetname , & sbuf ) ) ) {
2004-09-26 10:27:54 +04:00
d_printf ( " %s stat file %s \n " ,
2005-02-23 22:26:32 +03:00
cli_errstr ( targetcli ) , src ) ;
2004-09-26 10:27:54 +04:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2004-09-26 10:27:54 +04:00
/* Print out the stat values. */
d_printf ( " File: %s \n " , src ) ;
d_printf ( " Size: %-12.0f \t Blocks: %u \t %s \n " ,
2009-05-14 17:34:42 +04:00
( double ) sbuf . st_ex_size ,
( unsigned int ) sbuf . st_ex_blocks ,
filetype_to_str ( sbuf . st_ex_mode ) ) ;
2004-09-26 10:27:54 +04:00
# if defined(S_ISCHR) && defined(S_ISBLK)
2009-05-14 17:34:42 +04:00
if ( S_ISCHR ( sbuf . st_ex_mode ) | | S_ISBLK ( sbuf . st_ex_mode ) ) {
2004-09-26 10:27:54 +04:00
d_printf ( " Inode: %.0f \t Links: %u \t Device type: %u,%u \n " ,
2009-05-14 17:34:42 +04:00
( double ) sbuf . st_ex_ino ,
( unsigned int ) sbuf . st_ex_nlink ,
unix_dev_major ( sbuf . st_ex_rdev ) ,
unix_dev_minor ( sbuf . st_ex_rdev ) ) ;
2007-12-07 04:16:33 +03:00
} else
2004-09-26 10:27:54 +04:00
# endif
d_printf ( " Inode: %.0f \t Links: %u \n " ,
2009-05-14 17:34:42 +04:00
( double ) sbuf . st_ex_ino ,
( unsigned int ) sbuf . st_ex_nlink ) ;
2004-09-26 10:27:54 +04:00
d_printf ( " Access: (0%03o/%s) \t Uid: %u \t Gid: %u \n " ,
2009-05-14 17:34:42 +04:00
( ( int ) sbuf . st_ex_mode & 0777 ) ,
unix_mode_to_str ( mode_str , sbuf . st_ex_mode ) ,
( unsigned int ) sbuf . st_ex_uid ,
( unsigned int ) sbuf . st_ex_gid ) ;
2004-09-26 10:27:54 +04:00
2009-05-14 17:34:42 +04:00
tmp_time = convert_timespec_to_time_t ( sbuf . st_ex_atime ) ;
lt = localtime ( & tmp_time ) ;
2006-06-15 01:36:49 +04:00
if ( lt ) {
2007-03-02 18:08:09 +03:00
strftime ( mode_str , sizeof ( mode_str ) , " %Y-%m-%d %T %z " , lt ) ;
2006-06-15 01:36:49 +04:00
} else {
fstrcpy ( mode_str , " unknown " ) ;
}
2004-09-26 10:27:54 +04:00
d_printf ( " Access: %s \n " , mode_str ) ;
2009-05-14 17:34:42 +04:00
tmp_time = convert_timespec_to_time_t ( sbuf . st_ex_mtime ) ;
lt = localtime ( & tmp_time ) ;
2006-06-15 01:36:49 +04:00
if ( lt ) {
2007-03-02 18:08:09 +03:00
strftime ( mode_str , sizeof ( mode_str ) , " %Y-%m-%d %T %z " , lt ) ;
2006-06-15 01:36:49 +04:00
} else {
fstrcpy ( mode_str , " unknown " ) ;
}
2004-09-26 10:27:54 +04:00
d_printf ( " Modify: %s \n " , mode_str ) ;
2009-05-14 17:34:42 +04:00
tmp_time = convert_timespec_to_time_t ( sbuf . st_ex_ctime ) ;
lt = localtime ( & tmp_time ) ;
2006-06-15 01:36:49 +04:00
if ( lt ) {
2007-03-02 18:08:09 +03:00
strftime ( mode_str , sizeof ( mode_str ) , " %Y-%m-%d %T %z " , lt ) ;
2006-06-15 01:36:49 +04:00
} else {
fstrcpy ( mode_str , " unknown " ) ;
}
2004-09-26 10:27:54 +04:00
d_printf ( " Change: %s \n " , mode_str ) ;
2007-12-07 04:16:33 +03:00
2004-09-26 10:27:54 +04:00
return 0 ;
}
2002-01-16 23:13:28 +03:00
/****************************************************************************
UNIX chown .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_chown ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
2002-01-16 23:13:28 +03:00
uid_t uid ;
gid_t gid ;
2007-12-07 04:16:33 +03:00
char * buf , * buf2 , * buf3 ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetname = NULL ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf3 , NULL ) ) {
2002-01-16 23:13:28 +03:00
d_printf ( " chown uid gid file \n " ) ;
return 1 ;
}
uid = ( uid_t ) atoi ( buf ) ;
gid = ( gid_t ) atoi ( buf2 ) ;
2007-12-07 04:16:33 +03:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf3 ) ;
if ( ! src ) {
return 1 ;
}
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli , & targetname ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " chown %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-05-29 03:15:09 +04:00
if ( ! NT_STATUS_IS_OK ( cli_posix_chown ( targetcli , targetname , uid , gid ) ) ) {
2002-01-16 23:13:28 +03:00
d_printf ( " %s chown file %s uid=%d, gid=%d \n " ,
2005-02-23 22:26:32 +03:00
cli_errstr ( targetcli ) , src , ( int ) uid , ( int ) gid ) ;
2002-01-16 23:13:28 +03:00
return 1 ;
2007-12-07 04:16:33 +03:00
}
2002-01-16 23:13:28 +03:00
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Rename some file .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_rename ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src , * dest ;
char * buf , * buf2 ;
2007-03-09 02:54:57 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetsrc ;
char * targetdest ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
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
}
2007-12-07 04:16:33 +03:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! src ) {
return 1 ;
}
dest = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! dest ) {
return 1 ;
}
1998-11-09 06:45:49 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli , & targetsrc ) ) {
2007-07-25 02:28:19 +04:00
d_printf ( " rename %s: %s \n " , src , cli_errstr ( cli ) ) ;
return 1 ;
}
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , dest , & targetcli , & targetdest ) ) {
2007-07-25 02:28:19 +04:00
d_printf ( " rename %s: %s \n " , dest , cli_errstr ( cli ) ) ;
2007-03-09 02:54:57 +03:00
return 1 ;
}
2009-04-29 03:43:16 +04:00
if ( ! NT_STATUS_IS_OK ( cli_rename ( targetcli , targetsrc , targetdest ) ) ) {
2007-07-25 02:28:19 +04:00
d_printf ( " %s renaming files %s -> %s \n " ,
cli_errstr ( targetcli ) ,
targetsrc ,
targetdest ) ;
2001-10-09 23:12:18 +04:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
2005-03-30 04:47:57 +04:00
/****************************************************************************
Print the volume name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_volume ( void )
{
fstring volname ;
uint32 serial_num ;
time_t create_date ;
2010-02-07 14:08:39 +03:00
NTSTATUS status ;
2007-12-07 04:16:33 +03:00
2010-02-07 14:08:39 +03:00
status = cli_get_fs_volume_info ( cli , volname , & serial_num ,
& create_date ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error %s getting volume info \n " , nt_errstr ( status ) ) ;
2005-03-30 04:47:57 +04:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
d_printf ( " Volume: |%s| serial number 0x%x \n " ,
volname , ( unsigned int ) serial_num ) ;
2005-03-30 04:47:57 +04:00
return 0 ;
}
2004-03-03 23:55:59 +03:00
/****************************************************************************
2004-03-04 02:14:23 +03:00
Hard link files using the NT call .
2004-03-03 23:55:59 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-03-04 02:14:23 +03:00
static int cmd_hardlink ( void )
2004-03-03 23:55:59 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src , * dest ;
char * buf , * buf2 ;
2005-02-23 22:26:32 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetname ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2004-03-04 02:14:23 +03:00
d_printf ( " hardlink <src> <dest> \n " ) ;
2004-03-03 23:55:59 +03:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! src ) {
return 1 ;
}
2004-03-03 23:55:59 +03:00
2007-12-07 04:16:33 +03:00
dest = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! dest ) {
2005-02-23 22:26:32 +03:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , src , & targetcli , & targetname ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " hardlink %s: %s \n " , src , cli_errstr ( cli ) ) ;
2005-02-23 22:26:32 +03:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-04-29 21:48:16 +04:00
if ( ! NT_STATUS_IS_OK ( cli_nt_hardlink ( targetcli , targetname , dest ) ) ) {
2005-02-23 22:26:32 +03:00
d_printf ( " %s doing an NT hard link of files \n " , cli_errstr ( targetcli ) ) ;
2004-03-03 23:55:59 +03:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
2004-03-03 23:55:59 +03:00
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Toggle the prompt flag .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
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-10 11:51:20 +04:00
return 1 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Set the newer than time .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_newer ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
2007-10-19 04:40:25 +04:00
bool ok ;
1998-11-09 06:45:49 +03:00
SMB_STRUCT_STAT sbuf ;
2007-12-19 23:59:28 +03:00
ok = next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ;
2009-11-27 14:44:33 +03:00
if ( ok & & ( sys_stat ( buf , & sbuf , false ) = = 0 ) ) {
2009-05-14 17:34:42 +04:00
newer_than = convert_timespec_to_time_t ( sbuf . st_ex_mtime ) ;
1998-11-09 06:45:49 +03:00
DEBUG ( 1 , ( " Getting files newer than %s " ,
2007-03-06 02:40:03 +03:00
time_to_asc ( newer_than ) ) ) ;
1998-11-09 06:45:49 +03:00
} 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
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Set the archive level .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_archive ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
1996-05-04 11:50:46 +04:00
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
1998-11-09 06:45:49 +03:00
archive_level = atoi ( buf ) ;
2007-12-07 04:16:33 +03:00
} else {
2001-09-07 18:14:57 +04:00
d_printf ( " Archive level is %d \n " , archive_level ) ;
2007-12-07 04:16:33 +03:00
}
2001-10-09 23:12:18 +04:00
return 0 ;
1996-05-04 11:50:46 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Toggle the lowercaseflag .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
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
}
2004-06-15 22:36:45 +04:00
/****************************************************************************
Toggle the case sensitive flag .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_setcase ( void )
{
2007-12-07 04:16:33 +03:00
bool orig_case_sensitive = cli_set_case_sensitive ( cli , false ) ;
2004-06-15 22:36:45 +04:00
cli_set_case_sensitive ( cli , ! orig_case_sensitive ) ;
DEBUG ( 2 , ( " filename case sensitivity is now %s \n " , ! orig_case_sensitive ?
" on " : " off " ) ) ;
return 0 ;
}
2006-11-01 20:18:08 +03:00
/****************************************************************************
Toggle the showacls flag .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_showacls ( void )
{
showacls = ! showacls ;
DEBUG ( 2 , ( " showacls is now %s \n " , showacls ? " on " : " off " ) ) ;
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Toggle the recurse flag .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
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
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Toggle the translate flag .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
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
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Do the lcd command .
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_lcd ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
char * d ;
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2009-01-01 03:30:11 +03:00
if ( chdir ( buf ) = = - 1 ) {
d_printf ( " chdir to %s failed (%s) \n " ,
buf , strerror ( errno ) ) ;
}
2007-12-07 04:16:33 +03:00
}
d = TALLOC_ARRAY ( ctx , char , PATH_MAX + 1 ) ;
if ( ! d ) {
return 1 ;
}
1998-11-26 00:17:20 +03:00
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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Get a file restarting at end of local file .
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2002-09-25 19:19:00 +04:00
static int cmd_reget ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * local_name = NULL ;
char * remote_name = NULL ;
char * fname = NULL ;
char * p = NULL ;
2008-02-09 03:59:52 +03:00
remote_name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! remote_name ) {
return 1 ;
}
2002-09-25 19:19:00 +04:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & fname , NULL ) ) {
2002-09-25 19:19:00 +04:00
d_printf ( " reget <filename> \n " ) ;
return 1 ;
}
2009-01-01 03:30:11 +03:00
remote_name = talloc_asprintf_append ( remote_name , " %s " , fname ) ;
2007-12-07 04:16:33 +03:00
if ( ! remote_name ) {
return 1 ;
}
remote_name = clean_name ( ctx , remote_name ) ;
if ( ! remote_name ) {
return 1 ;
}
local_name = fname ;
2007-12-19 23:59:28 +03:00
next_token_talloc ( ctx , & cmd_ptr , & p , NULL ) ;
2007-12-07 04:16:33 +03:00
if ( p ) {
local_name = p ;
}
return do_get ( remote_name , local_name , true ) ;
2002-09-25 19:19:00 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Put a file restarting at end of local file .
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2002-09-25 19:19:00 +04:00
static int cmd_reput ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * local_name = NULL ;
char * remote_name = NULL ;
char * buf ;
2002-09-25 19:19:00 +04:00
SMB_STRUCT_STAT st ;
2007-12-07 04:16:33 +03:00
2008-02-09 03:59:52 +03:00
remote_name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-07 04:16:33 +03:00
if ( ! remote_name ) {
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & local_name , NULL ) ) {
2002-09-25 19:19:00 +04:00
d_printf ( " reput <filename> \n " ) ;
return 1 ;
}
2007-12-07 04:16:33 +03:00
2009-11-27 15:17:05 +03:00
if ( ! file_exist_stat ( local_name , & st , false ) ) {
2002-09-25 19:19:00 +04:00
d_printf ( " %s does not exist \n " , local_name ) ;
return 1 ;
}
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-07 04:16:33 +03:00
remote_name = talloc_asprintf_append ( remote_name ,
2009-01-01 03:30:11 +03:00
" %s " , buf ) ;
2007-12-07 04:16:33 +03:00
} else {
remote_name = talloc_asprintf_append ( remote_name ,
2009-01-01 03:30:11 +03:00
" %s " , local_name ) ;
2007-12-07 04:16:33 +03:00
}
if ( ! remote_name ) {
return 1 ;
}
remote_name = clean_name ( ctx , remote_name ) ;
if ( ! remote_name ) {
return 1 ;
}
2002-09-25 19:19:00 +04:00
2007-12-07 04:16:33 +03:00
return do_put ( remote_name , local_name , true ) ;
2002-09-25 19:19:00 +04:00
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
List a share name .
2002-09-25 19:19:00 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static void browse_fn ( const char * name , uint32 m ,
2001-01-04 14:35:55 +03:00
const char * comment , void * state )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
const char * typestr = " " ;
switch ( m & 7 ) {
case STYPE_DISKTREE :
typestr = " Disk " ;
break ;
case STYPE_PRINTQ :
typestr = " Printer " ;
break ;
case STYPE_DEVICE :
typestr = " Device " ;
break ;
case STYPE_IPC :
typestr = " IPC " ;
break ;
1998-06-04 22:49:13 +04:00
}
2002-01-10 06:53:06 +03:00
/* FIXME: If the remote machine returns non-ascii characters
in any of these fields , they can corrupt the output . We
should remove them . */
2004-01-16 18:01:09 +03:00
if ( ! grepable ) {
2004-03-01 20:40:40 +03:00
d_printf ( " \t %-15s %-10.10s%s \n " ,
2004-01-16 18:01:09 +03:00
name , typestr , comment ) ;
} else {
d_printf ( " %s|%s|%s \n " , typestr , name , comment ) ;
}
1996-05-04 11:50:46 +04:00
}
2007-10-19 04:40:25 +04:00
static bool browse_host_rpc ( bool sort )
2006-04-16 15:47:26 +04:00
{
NTSTATUS status ;
2009-11-13 00:56:33 +03:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2007-12-07 04:16:33 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-10-11 00:34:30 +04:00
WERROR werr ;
2008-03-10 06:33:06 +03:00
struct srvsvc_NetShareInfoCtr info_ctr ;
struct srvsvc_NetShareCtr1 ctr1 ;
uint32_t resume_handle = 0 ;
uint32_t total_entries = 0 ;
2006-04-16 15:47:26 +04:00
int i ;
2011-01-12 14:56:55 +03:00
struct dcerpc_binding_handle * b ;
2006-04-16 15:47:26 +04:00
2008-07-20 13:04:31 +04:00
status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_srvsvc . syntax_id ,
& pipe_hnd ) ;
2006-04-16 15:47:26 +04:00
2008-07-20 13:04:31 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-04-16 15:47:26 +04:00
DEBUG ( 10 , ( " Could not connect to srvsvc pipe: %s \n " ,
nt_errstr ( status ) ) ) ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( frame ) ;
return false ;
2006-04-16 15:47:26 +04:00
}
2011-01-12 14:56:55 +03:00
b = pipe_hnd - > binding_handle ;
2008-03-10 06:33:06 +03:00
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( ctr1 ) ;
info_ctr . level = 1 ;
info_ctr . ctr . ctr1 = & ctr1 ;
2011-01-12 14:56:55 +03:00
status = dcerpc_srvsvc_NetShareEnumAll ( b , frame ,
2008-04-19 23:56:43 +04:00
pipe_hnd - > desthost ,
2008-03-10 06:33:06 +03:00
& info_ctr ,
0xffffffff ,
& total_entries ,
& resume_handle ,
& werr ) ;
2006-04-16 15:47:26 +04:00
2008-03-10 06:33:06 +03:00
if ( ! NT_STATUS_IS_OK ( status ) | | ! W_ERROR_IS_OK ( werr ) ) {
2008-04-20 15:51:46 +04:00
TALLOC_FREE ( pipe_hnd ) ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( frame ) ;
return false ;
2006-04-16 15:47:26 +04:00
}
2008-03-10 06:33:06 +03:00
for ( i = 0 ; i < info_ctr . ctr . ctr1 - > count ; i + + ) {
struct srvsvc_NetShareInfo1 info = info_ctr . ctr . ctr1 - > array [ i ] ;
browse_fn ( info . name , info . type , info . comment , NULL ) ;
2006-04-16 15:47:26 +04:00
}
2008-04-20 15:51:46 +04:00
TALLOC_FREE ( pipe_hnd ) ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( frame ) ;
return true ;
2006-04-16 15:47:26 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Try and browse available connections on a host .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-10-19 04:40:25 +04: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 ;
2004-01-16 18:01:09 +03:00
if ( ! grepable ) {
2004-03-01 20:40:40 +03:00
d_printf ( " \n \t Sharename Type Comment \n " ) ;
d_printf ( " \t --------- ---- ------- \n " ) ;
2004-01-16 18:01:09 +03:00
}
1996-05-04 11:50:46 +04:00
2006-04-16 15:47:26 +04:00
if ( browse_host_rpc ( sort ) ) {
2007-12-07 04:16:33 +03:00
return true ;
2006-04-16 15:47:26 +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
/****************************************************************************
2003-08-07 00:01:31 +04:00
List a server name .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static void server_fn ( const char * name , uint32 m ,
2001-01-04 14:35:55 +03:00
const char * comment , void * state )
1998-11-09 06:45:49 +03:00
{
2007-12-07 04:16:33 +03:00
2004-01-16 18:01:09 +03:00
if ( ! grepable ) {
2004-03-01 20:40:40 +03:00
d_printf ( " \t %-16s %s \n " , name , comment ) ;
2004-01-16 18:01:09 +03:00
} else {
d_printf ( " %s|%s|%s \n " , ( char * ) state , name , comment ) ;
}
1998-11-09 06:45:49 +03:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Try and browse available connections on a host .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-10-19 04:40:25 +04:00
static bool list_servers ( const char * wk_grp )
1996-05-04 11:50:46 +04:00
{
2005-02-22 06:31:22 +03:00
fstring state ;
2003-08-07 00:01:31 +04:00
if ( ! cli - > server_domain )
2007-12-07 04:16:33 +03:00
return false ;
1998-11-09 06:45:49 +03:00
2004-01-16 18:01:09 +03:00
if ( ! grepable ) {
d_printf ( " \n \t Server Comment \n " ) ;
d_printf ( " \t --------- ------- \n " ) ;
} ;
2005-02-22 06:31:22 +03:00
fstrcpy ( state , " Server " ) ;
2004-01-16 18:01:09 +03:00
cli_NetServerEnum ( cli , cli - > server_domain , SV_TYPE_ALL , server_fn ,
2005-02-22 06:31:22 +03:00
state ) ;
1998-11-09 06:45:49 +03:00
2004-01-16 18:01:09 +03:00
if ( ! grepable ) {
d_printf ( " \n \t Workgroup Master \n " ) ;
d_printf ( " \t --------- ------- \n " ) ;
2007-12-07 04:16:33 +03:00
} ;
1998-11-09 06:45:49 +03:00
2005-02-22 06:31:22 +03:00
fstrcpy ( state , " Workgroup " ) ;
2004-01-16 18:01:09 +03:00
cli_NetServerEnum ( cli , cli - > server_domain , SV_TYPE_DOMAIN_ENUM ,
2005-02-22 06:31:22 +03:00
server_fn , state ) ;
2007-12-07 04:16:33 +03:00
return true ;
1996-05-04 11:50:46 +04:00
}
2004-02-12 20:26:34 +03:00
/****************************************************************************
Print or set current VUID
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_vuid ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2004-02-12 20:26:34 +03:00
d_printf ( " Current VUID is %d \n " , cli - > vuid ) ;
return 0 ;
}
cli - > vuid = atoi ( buf ) ;
return 0 ;
}
/****************************************************************************
Setup a new VUID , by issuing a session setup
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_logon ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * l_username , * l_password ;
2011-01-17 14:02:39 +03:00
NTSTATUS nt_status ;
2007-12-07 04:16:33 +03:00
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & l_username , NULL ) ) {
2004-02-12 20:26:34 +03:00
d_printf ( " logon <username> [<password>] \n " ) ;
return 0 ;
}
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & l_password , NULL ) ) {
2004-02-12 20:26:34 +03:00
char * pass = getpass ( " Password: " ) ;
2007-12-07 04:16:33 +03:00
if ( pass ) {
l_password = talloc_strdup ( ctx , pass ) ;
}
}
if ( ! l_password ) {
return 1 ;
}
2004-02-12 20:26:34 +03:00
2011-01-17 14:02:39 +03:00
nt_status = cli_session_setup ( cli , l_username ,
l_password , strlen ( l_password ) ,
l_password , strlen ( l_password ) ,
lp_workgroup ( ) ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
d_printf ( " session setup failed: %s \n " , nt_errstr ( nt_status ) ) ;
2004-02-12 20:26:34 +03:00
return - 1 ;
}
d_printf ( " Current VUID is %d \n " , cli - > vuid ) ;
return 0 ;
}
2005-02-22 06:31:22 +03:00
/****************************************************************************
list active connections
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_list_connect ( void )
{
2009-03-13 03:59:24 +03:00
cli_cm_display ( cli ) ;
2005-02-22 06:31:22 +03:00
return 0 ;
}
/****************************************************************************
2005-02-23 20:29:28 +03:00
display the current active client connection
2005-02-22 06:31:22 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-02-23 20:29:28 +03:00
static int cmd_show_connect ( void )
2005-02-22 06:31:22 +03:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2005-02-23 20:29:28 +03:00
struct cli_state * targetcli ;
2007-12-07 04:16:33 +03:00
char * targetpath ;
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , client_get_cur_dir ( ) ,
2007-12-07 04:16:33 +03:00
& targetcli , & targetpath ) ) {
2005-02-23 20:29:28 +03:00
d_printf ( " showconnect %s: %s \n " , cur_dir , cli_errstr ( cli ) ) ;
2005-02-22 06:31:22 +03:00
return 1 ;
}
2007-12-07 04:16:33 +03:00
2005-02-23 20:29:28 +03:00
d_printf ( " //%s/%s \n " , targetcli - > desthost , targetcli - > share ) ;
2005-02-22 06:31:22 +03:00
return 0 ;
}
2007-11-02 22:21:34 +03:00
/****************************************************************************
iosize command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cmd_iosize ( void )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
2007-11-02 22:21:34 +03:00
int iosize ;
2007-12-19 23:59:28 +03:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-30 09:39:52 +03:00
if ( ! smb_encrypt ) {
d_printf ( " iosize <n> or iosize 0x<n>. "
" Minimum is 16384 (0x4000), "
" max is 16776960 (0xFFFF00) \n " ) ;
} else {
d_printf ( " iosize <n> or iosize 0x<n>. "
" (Encrypted connection) , "
" Minimum is 16384 (0x4000), "
2007-12-31 05:05:33 +03:00
" max is 130048 (0x1FC00) \n " ) ;
2007-12-30 09:39:52 +03:00
}
2007-11-02 22:21:34 +03:00
return 1 ;
}
iosize = strtol ( buf , NULL , 0 ) ;
2007-12-30 09:39:52 +03:00
if ( smb_encrypt & & ( iosize < 0x4000 | | iosize > 0xFC00 ) ) {
d_printf ( " iosize out of range for encrypted "
" connection (min = 16384 (0x4000), "
2007-12-31 05:05:33 +03:00
" max = 130048 (0x1FC00) " ) ;
2007-12-30 09:39:52 +03:00
return 1 ;
} else if ( ! smb_encrypt & & ( iosize < 0x4000 | | iosize > 0xFFFF00 ) ) {
2007-12-07 04:16:33 +03:00
d_printf ( " iosize out of range (min = 16384 (0x4000), "
2007-12-30 09:39:52 +03:00
" max = 16776960 (0xFFFF00) " ) ;
2007-11-02 22:21:34 +03:00
return 1 ;
}
io_bufsize = iosize ;
d_printf ( " iosize is now %d \n " , io_bufsize ) ;
return 0 ;
}
2010-10-01 12:33:32 +04:00
/****************************************************************************
history
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_history ( void )
{
# if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
HIST_ENTRY * * hlist ;
int i ;
hlist = history_list ( ) ;
for ( i = 0 ; hlist & & hlist [ i ] ; i + + ) {
DEBUG ( 0 , ( " %d: %s \n " , i , hlist [ i ] - > line ) ) ;
}
# else
DEBUG ( 0 , ( " no history without readline support \n " ) ) ;
# endif
return 0 ;
}
2007-11-02 22:21:34 +03: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
*/
2007-12-07 04:16:33 +03:00
static struct {
const char * name ;
int ( * fn ) ( void ) ;
const char * description ;
char compl_args [ 2 ] ; /* Completion argument info */
2003-08-07 00:01:31 +04:00
} commands [ ] = {
2002-01-16 23:25:23 +03:00
{ " ? " , cmd_help , " [command] give help on a command " , { COMPL_NONE , COMPL_NONE } } ,
2008-01-18 13:08:17 +03:00
{ " allinfo " , cmd_allinfo , " <file> show all available info " ,
{ COMPL_NONE , COMPL_NONE } } ,
2002-01-16 23:25:23 +03:00
{ " altname " , cmd_altname , " <file> show alt name " , { COMPL_NONE , COMPL_NONE } } ,
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 } } ,
2004-06-15 22:36:45 +04:00
{ " case_sensitive " , cmd_setcase , " toggle the case sensitive flag to server " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " cd " , cmd_cd , " [directory] change/report the remote directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2002-01-16 23:13:28 +03:00
{ " chmod " , cmd_chmod , " <src> <mode> chmod a file using UNIX permission " , { COMPL_REMOTE , COMPL_REMOTE } } ,
{ " chown " , cmd_chown , " <src> <uid> <gid> chown a file using UNIX uids and gids " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2006-07-12 04:21:14 +04:00
{ " close " , cmd_close , " <fid> close a file given a fid " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2001-09-30 10:49:44 +04:00
{ " 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 } } ,
2007-07-22 15:18:49 +04:00
{ " echo " , cmd_echo , " ping the server " , { COMPL_NONE , 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 } } ,
2004-11-13 02:42:12 +03:00
{ " getfacl " , cmd_getfacl , " <file name> get the POSIX ACL on a file (UNIX extensions only) " , { COMPL_REMOTE , COMPL_LOCAL } } ,
2010-10-24 15:32:30 +04:00
{ " geteas " , cmd_geteas , " <file name> get the EA list of a file " ,
{ COMPL_REMOTE , COMPL_LOCAL } } ,
2004-03-04 02:14:23 +03:00
{ " hardlink " , cmd_hardlink , " <src> <dest> create a Windows hard link " , { COMPL_REMOTE , COMPL_REMOTE } } ,
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 } } ,
2007-11-02 22:21:34 +03:00
{ " iosize " , cmd_iosize , " iosize <number> (default 64512) " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " lcd " , cmd_lcd , " [directory] change/report the local current working directory " , { COMPL_LOCAL , COMPL_NONE } } ,
2004-04-07 03:01:09 +04:00
{ " link " , cmd_link , " <oldname> <newname> create a UNIX hard link " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2006-07-12 07:20:53 +04:00
{ " lock " , cmd_lock , " lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2001-09-30 10:49:44 +04:00
{ " 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 } } ,
2007-07-11 12:31:03 +04:00
{ " l " , cmd_dir , " <mask> list the contents of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 10:49:44 +04:00
{ " 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 } } ,
2006-07-12 04:21:14 +04:00
{ " posix " , cmd_posix , " turn on all POSIX capabilities " , { COMPL_REMOTE , COMPL_NONE } } ,
2007-12-27 04:12:36 +03:00
{ " posix_encrypt " , cmd_posix_encrypt , " <domain> <user> <password> start up transport encryption " , { COMPL_REMOTE , COMPL_NONE } } ,
2007-03-02 00:56:54 +03:00
{ " posix_open " , cmd_posix_open , " <name> 0<mode> open_flags mode open a file using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " posix_mkdir " , cmd_posix_mkdir , " <name> 0<mode> creates a directory using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " posix_rmdir " , cmd_posix_rmdir , " <name> removes a directory using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " posix_unlink " , cmd_posix_unlink , " <name> removes a file using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
1998-09-23 04:57:34 +04:00
{ " print " , cmd_print , " <file name> print a file " , { 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 } } ,
2009-05-28 09:02:20 +04:00
{ " readlink " , cmd_readlink , " filename Do a UNIX extensions readlink call on a symlink " , { COMPL_REMOTE , COMPL_REMOTE } } ,
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 } } ,
2002-09-25 19:19:00 +04:00
{ " reget " , cmd_reget , " <remote name> [local name] get a file restarting at end of local file " , { COMPL_REMOTE , COMPL_LOCAL } } ,
2001-09-30 10:49:44 +04:00
{ " rename " , cmd_rename , " <src> <dest> rename some files " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2002-09-25 19:19:00 +04:00
{ " reput " , cmd_reput , " <local name> [remote name] put a file restarting at end of remote file " , { COMPL_LOCAL , COMPL_REMOTE } } ,
2001-09-30 10:49:44 +04:00
{ " rm " , cmd_del , " <mask> delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " rmdir " , cmd_rmdir , " <directory> remove a directory " , { COMPL_NONE , COMPL_NONE } } ,
2006-11-01 20:18:08 +03:00
{ " showacls " , cmd_showacls , " toggle if ACLs are shown or not " , { COMPL_NONE , COMPL_NONE } } ,
2010-10-24 17:43:34 +04:00
{ " setea " , cmd_setea , " <file name> <eaname> <eaval> Set an EA of a file " ,
{ COMPL_REMOTE , COMPL_LOCAL } } ,
1998-09-23 04:57:34 +04:00
{ " setmode " , cmd_setmode , " filename <setmode string> change modes of file " , { COMPL_REMOTE , COMPL_NONE } } ,
2004-09-26 10:27:54 +04:00
{ " stat " , cmd_stat , " filename Do a UNIX extensions stat call on a file " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2004-04-07 03:01:09 +04:00
{ " symlink " , cmd_symlink , " <oldname> <newname> create a UNIX symlink " , { COMPL_REMOTE , COMPL_REMOTE } } ,
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 } } ,
2006-07-12 07:20:53 +04:00
{ " unlock " , cmd_unlock , " unlock <fnum> <hex-start> <hex-len> : remove a POSIX lock " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2005-03-30 04:47:57 +04:00
{ " volume " , cmd_volume , " print the volume name " , { COMPL_NONE , COMPL_NONE } } ,
2004-02-12 20:26:34 +03:00
{ " vuid " , cmd_vuid , " change current vuid " , { COMPL_NONE , COMPL_NONE } } ,
2007-03-07 22:45:22 +03:00
{ " wdel " , cmd_wdel , " <attrib> <mask> wildcard delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
2004-02-12 20:26:34 +03:00
{ " logon " , cmd_logon , " establish new logon " , { COMPL_NONE , COMPL_NONE } } ,
2005-02-22 06:31:22 +03:00
{ " listconnect " , cmd_list_connect , " list open connections " , { COMPL_NONE , COMPL_NONE } } ,
2005-02-23 20:29:28 +03:00
{ " showconnect " , cmd_show_connect , " display the current active connection " , { COMPL_NONE , COMPL_NONE } } ,
2007-07-11 12:43:08 +04:00
{ " .. " , cmd_cd_oneup , " change the remote directory (up one level) " , { COMPL_REMOTE , COMPL_NONE } } ,
2002-01-17 10:14:21 +03:00
/* Yes, this must be here, see crh's comment above. */
{ " ! " , NULL , " run a shell command on the local system " , { COMPL_NONE , COMPL_NONE } } ,
2003-06-11 10:23:53 +04:00
{ NULL , NULL , NULL , { COMPL_NONE , COMPL_NONE } }
1996-05-04 11:50:46 +04:00
} ;
/*******************************************************************
2007-12-07 04:16:33 +03:00
Lookup a command string in the list of commands , including
2003-08-07 00:01:31 +04:00
abbreviations .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-07 04:16:33 +03:00
static int process_tok ( char * tok )
1996-05-04 11:50:46 +04:00
{
1998-11-09 06:45:49 +03:00
int i = 0 , matches = 0 ;
int cmd = 0 ;
int tok_len = strlen ( tok ) ;
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
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
}
2007-12-07 04:16:33 +03: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
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Help .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-10-09 23:12:18 +04:00
static int cmd_help ( void )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
1998-11-09 06:45:49 +03:00
int i = 0 , j ;
2007-12-07 04:16:33 +03:00
char * buf ;
2007-12-19 23:59:28 +03:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
1998-11-09 06:45:49 +03:00
if ( ( i = process_tok ( buf ) ) > = 0 )
2007-12-07 04:16:33 +03: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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Process a - c command string .
1998-09-18 16:47:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static int process_command_string ( const char * cmd_in )
1998-09-18 16:47:46 +04:00
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * cmd = talloc_strdup ( ctx , cmd_in ) ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
1998-09-18 16:47:46 +04:00
2007-12-07 04:16:33 +03:00
if ( ! cmd ) {
return 1 ;
}
2002-07-15 14:35:28 +04:00
/* establish the connection if not already */
2007-12-07 04:16:33 +03:00
2002-07-15 14:35:28 +04:00
if ( ! cli ) {
2009-01-02 23:49:49 +03:00
cli = cli_cm_open ( talloc_tos ( ) , NULL ,
have_ip ? dest_ss_str : desthost ,
2009-03-18 00:53:06 +03:00
service , auth_info ,
true , smb_encrypt ,
2009-01-15 03:08:19 +03:00
max_protocol , port , name_type ) ;
2007-12-07 04:16:33 +03:00
if ( ! cli ) {
return 1 ;
}
2002-07-15 14:35:28 +04:00
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
while ( cmd [ 0 ] ! = ' \0 ' ) {
2007-12-07 04:16:33 +03:00
char * line ;
1998-11-09 06:45:49 +03:00
char * p ;
2007-12-07 04:16:33 +03:00
char * tok ;
1998-11-09 06:45:49 +03:00
int i ;
2007-12-07 04:16:33 +03:00
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( cmd , ' ; ' ) ) = = 0 ) {
2007-12-07 04:16:33 +03:00
line = cmd ;
1998-11-09 06:45:49 +03:00
cmd + = strlen ( cmd ) ;
} else {
2007-12-07 04:16:33 +03:00
* p = ' \0 ' ;
line = cmd ;
1998-11-09 06:45:49 +03:00
cmd = p + 1 ;
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
/* and get the first part of the command */
2007-12-19 23:59:28 +03:00
cmd_ptr = line ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & tok , NULL ) ) {
2007-12-07 04:16:33 +03:00
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
}
}
2007-12-07 04:16:33 +03:00
2001-10-09 23:12:18 +04:00
return rc ;
2007-12-07 04:16:33 +03:00
}
1998-09-18 16:47:46 +04:00
2001-03-19 03:22:52 +03:00
# define MAX_COMPLETIONS 100
2010-02-16 01:53:18 +03:00
struct completion_remote {
2007-12-07 04:16:33 +03:00
char * dirmask ;
2003-05-12 22:12:31 +04:00
char * * matches ;
int count , samelen ;
const char * text ;
int len ;
2010-02-16 01:53:18 +03:00
} ;
2001-03-19 03:22:52 +03:00
2010-10-29 22:56:51 +04:00
static NTSTATUS completion_remote_filter ( const char * mnt ,
2010-07-27 12:59:55 +04:00
struct file_info * f ,
2007-12-07 04:16:33 +03:00
const char * mask ,
void * state )
2003-05-12 22:12:31 +04:00
{
2010-02-16 01:53:18 +03:00
struct completion_remote * info = ( struct completion_remote * ) state ;
2001-03-19 03:22:52 +03:00
2010-02-19 00:52:41 +03:00
if ( info - > count > = MAX_COMPLETIONS - 1 ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2010-02-19 00:52:41 +03:00
}
if ( strncmp ( info - > text , f - > name , info - > len ) ! = 0 ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2010-02-19 00:52:41 +03:00
}
if ( ISDOT ( f - > name ) | | ISDOTDOT ( f - > name ) ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2010-02-19 00:52:41 +03:00
}
2011-04-29 05:57:02 +04:00
if ( ( info - > dirmask [ 0 ] = = 0 ) & & ! ( f - > mode & FILE_ATTRIBUTE_DIRECTORY ) )
2010-02-19 00:52:41 +03:00
info - > matches [ info - > count ] = SMB_STRDUP ( f - > name ) ;
else {
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
char * tmp ;
tmp = talloc_strdup ( ctx , info - > dirmask ) ;
if ( ! tmp ) {
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( ctx ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2001-03-19 03:22:52 +03:00
}
2010-02-19 00:52:41 +03:00
tmp = talloc_asprintf_append ( tmp , " %s " , f - > name ) ;
if ( ! tmp ) {
TALLOC_FREE ( ctx ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2007-12-07 04:16:33 +03:00
}
2011-04-29 05:57:02 +04:00
if ( f - > mode & FILE_ATTRIBUTE_DIRECTORY ) {
2010-02-19 00:52:41 +03:00
tmp = talloc_asprintf_append ( tmp , " %s " ,
CLI_DIRSEP_STR ) ;
2007-12-07 04:16:33 +03:00
}
2010-02-19 00:52:41 +03:00
if ( ! tmp ) {
TALLOC_FREE ( ctx ) ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_NO_MEMORY ;
2010-02-19 00:52:41 +03:00
}
info - > matches [ info - > count ] = SMB_STRDUP ( tmp ) ;
TALLOC_FREE ( ctx ) ;
}
if ( info - > matches [ info - > count ] = = NULL ) {
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2010-02-19 00:52:41 +03:00
}
2011-04-29 05:57:02 +04:00
if ( f - > mode & FILE_ATTRIBUTE_DIRECTORY ) {
2010-02-19 00:52:41 +03:00
smb_readline_ca_char ( 0 ) ;
}
if ( info - > count = = 1 ) {
info - > samelen = strlen ( info - > matches [ info - > count ] ) ;
} else {
while ( strncmp ( info - > matches [ info - > count ] ,
info - > matches [ info - > count - 1 ] ,
info - > samelen ) ! = 0 ) {
info - > samelen - - ;
2007-12-07 04:16:33 +03:00
}
2001-03-19 03:22:52 +03:00
}
2010-02-19 00:52:41 +03:00
info - > count + + ;
2010-10-29 22:56:51 +04:00
return NT_STATUS_OK ;
2003-05-12 22:12:31 +04:00
}
2001-03-19 03:22:52 +03:00
2003-05-12 22:12:31 +04:00
static char * * remote_completion ( const char * text , int len )
{
2007-12-07 04:16:33 +03:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
char * dirmask = NULL ;
char * targetpath = NULL ;
struct cli_state * targetcli = NULL ;
2003-05-12 22:12:31 +04:00
int i ;
2010-02-16 01:53:18 +03:00
struct completion_remote info = { NULL , NULL , 1 , 0 , NULL , 0 } ;
2010-08-02 21:22:22 +04:00
NTSTATUS status ;
2003-05-12 22:12:31 +04:00
2010-02-16 01:52:51 +03:00
/* can't have non-static initialisation on Sun CC, so do it
2003-05-13 10:13:36 +04:00
at run time here */
info . samelen = len ;
info . text = text ;
info . len = len ;
2003-05-12 22:12:31 +04:00
2004-12-07 21:25:53 +03:00
info . matches = SMB_MALLOC_ARRAY ( char * , MAX_COMPLETIONS ) ;
2006-03-14 01:49:56 +03:00
if ( ! info . matches ) {
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( ctx ) ;
2006-03-14 01:49:56 +03:00
return NULL ;
}
2006-09-12 01:33:53 +04:00
/*
* We ' re leaving matches [ 0 ] free to fill it later with the text to
* display : Either the one single match or the longest common subset
* of the matches .
*/
2003-05-12 22:12:31 +04:00
info . matches [ 0 ] = NULL ;
2006-09-12 01:33:53 +04:00
info . count = 1 ;
2003-05-12 22:12:31 +04:00
2006-03-14 01:49:56 +03:00
for ( i = len - 1 ; i > = 0 ; i - - ) {
2006-07-12 07:20:53 +04:00
if ( ( text [ i ] = = ' / ' ) | | ( text [ i ] = = CLI_DIRSEP_CHAR ) ) {
2003-05-12 22:12:31 +04:00
break ;
2006-03-14 01:49:56 +03:00
}
}
2003-05-12 22:12:31 +04:00
info . text = text + i + 1 ;
info . samelen = info . len = len - i - 1 ;
if ( i > 0 ) {
2007-12-08 13:21:08 +03:00
info . dirmask = SMB_MALLOC_ARRAY ( char , i + 2 ) ;
2007-12-07 04:16:33 +03:00
if ( ! info . dirmask ) {
goto cleanup ;
}
2003-05-12 22:12:31 +04:00
strncpy ( info . dirmask , text , i + 1 ) ;
info . dirmask [ i + 1 ] = 0 ;
2007-12-07 04:16:33 +03:00
dirmask = talloc_asprintf ( ctx ,
" %s%*s* " ,
client_get_cur_dir ( ) ,
i - 1 ,
text ) ;
2006-03-14 01:49:56 +03:00
} else {
2007-12-07 04:16:33 +03:00
info . dirmask = SMB_STRDUP ( " " ) ;
if ( ! info . dirmask ) {
goto cleanup ;
}
dirmask = talloc_asprintf ( ctx ,
" %s* " ,
client_get_cur_dir ( ) ) ;
}
if ( ! dirmask ) {
goto cleanup ;
2006-03-14 01:49:56 +03:00
}
2003-05-12 22:12:31 +04:00
2009-03-18 00:53:06 +03:00
if ( ! cli_resolve_path ( ctx , " " , auth_info , cli , dirmask , & targetcli , & targetpath ) ) {
2007-12-07 04:16:33 +03:00
goto cleanup ;
}
2011-04-29 05:57:02 +04:00
status = cli_list ( targetcli , targetpath , FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ,
2010-08-02 21:22:22 +04:00
completion_remote_filter , ( void * ) & info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-05-12 22:12:31 +04:00
goto cleanup ;
2007-12-07 04:16:33 +03:00
}
2003-05-12 22:12:31 +04:00
2006-09-12 01:33:53 +04:00
if ( info . count = = 1 ) {
/*
* No matches at all , NULL indicates there is nothing
*/
SAFE_FREE ( info . matches [ 0 ] ) ;
SAFE_FREE ( info . matches ) ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( ctx ) ;
2006-09-12 01:33:53 +04:00
return NULL ;
}
if ( info . count = = 2 ) {
/*
* Exactly one match in matches [ 1 ] , indicate this is the one
* in matches [ 0 ] .
*/
info . matches [ 0 ] = info . matches [ 1 ] ;
info . matches [ 1 ] = NULL ;
info . count - = 1 ;
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( ctx ) ;
2006-09-12 01:33:53 +04:00
return info . matches ;
2001-03-19 03:22:52 +03:00
}
2006-09-12 01:33:53 +04:00
/*
* We got more than one possible match , set the result to the maximum
* common subset
*/
info . matches [ 0 ] = SMB_STRNDUP ( info . matches [ 1 ] , info . samelen ) ;
2003-05-12 22:12:31 +04:00
info . matches [ info . count ] = NULL ;
return info . matches ;
cleanup :
2007-12-07 04:16:33 +03:00
for ( i = 0 ; i < info . count ; i + + ) {
SAFE_FREE ( info . matches [ i ] ) ;
}
SAFE_FREE ( info . matches ) ;
SAFE_FREE ( info . dirmask ) ;
TALLOC_FREE ( ctx ) ;
2003-05-12 22:12:31 +04:00
return NULL ;
2001-03-19 03:22:52 +03:00
}
2003-05-12 22:12:31 +04:00
static char * * completion_fn ( const char * text , int start , int end )
{
smb_readline_ca_char ( ' ' ) ;
if ( start ) {
const char * buf , * sp ;
int i ;
char compl_type ;
buf = smb_readline_get_line_buffer ( ) ;
if ( buf = = NULL )
return NULL ;
2007-12-07 04:16:33 +03:00
2003-05-12 22:12:31 +04:00
sp = strchr ( buf , ' ' ) ;
if ( sp = = NULL )
return NULL ;
2006-09-12 01:33:53 +04:00
for ( i = 0 ; commands [ i ] . name ; i + + ) {
if ( ( strncmp ( commands [ i ] . name , buf , sp - buf ) = = 0 ) & &
( commands [ i ] . name [ sp - buf ] = = 0 ) ) {
2003-05-12 22:12:31 +04:00
break ;
2006-09-12 01:33:53 +04:00
}
}
2003-05-12 22:12:31 +04:00
if ( commands [ i ] . name = = NULL )
return NULL ;
while ( * sp = = ' ' )
sp + + ;
if ( sp = = ( buf + start ) )
compl_type = commands [ i ] . compl_args [ 0 ] ;
else
compl_type = commands [ i ] . compl_args [ 1 ] ;
if ( compl_type = = COMPL_REMOTE )
return remote_completion ( text , end - start ) ;
else /* fall back to local filename completion */
return NULL ;
} else {
char * * matches ;
2004-11-24 04:03:23 +03:00
int i , len , samelen = 0 , count = 1 ;
2003-05-12 22:12:31 +04:00
2004-12-07 21:25:53 +03:00
matches = SMB_MALLOC_ARRAY ( char * , MAX_COMPLETIONS ) ;
2004-11-24 04:03:23 +03:00
if ( ! matches ) {
return NULL ;
}
2003-05-12 22:12:31 +04:00
matches [ 0 ] = NULL ;
len = strlen ( text ) ;
for ( i = 0 ; commands [ i ] . fn & & count < MAX_COMPLETIONS - 1 ; i + + ) {
if ( strncmp ( text , commands [ i ] . name , len ) = = 0 ) {
2004-12-07 21:25:53 +03:00
matches [ count ] = SMB_STRDUP ( commands [ i ] . name ) ;
2003-05-12 22:12:31 +04:00
if ( ! matches [ count ] )
goto cleanup ;
if ( count = = 1 )
samelen = strlen ( matches [ count ] ) ;
else
while ( strncmp ( matches [ count ] , matches [ count - 1 ] , samelen ) ! = 0 )
samelen - - ;
count + + ;
}
}
switch ( count ) {
case 0 : /* should never happen */
case 1 :
goto cleanup ;
case 2 :
2004-12-07 21:25:53 +03:00
matches [ 0 ] = SMB_STRDUP ( matches [ 1 ] ) ;
2003-05-12 22:12:31 +04:00
break ;
default :
2006-08-16 21:14:16 +04:00
matches [ 0 ] = ( char * ) SMB_MALLOC ( samelen + 1 ) ;
2003-05-12 22:12:31 +04:00
if ( ! matches [ 0 ] )
goto cleanup ;
strncpy ( matches [ 0 ] , matches [ 1 ] , samelen ) ;
matches [ 0 ] [ samelen ] = 0 ;
}
matches [ count ] = NULL ;
return matches ;
cleanup :
2003-11-05 01:38:58 +03:00
for ( i = 0 ; i < count ; i + + )
2003-05-12 22:12:31 +04:00
free ( matches [ i ] ) ;
2003-11-05 01:38:58 +03:00
2003-05-12 22:12:31 +04:00
free ( matches ) ;
return NULL ;
}
}
2001-03-18 16:24:57 +03:00
2008-10-04 01:58:41 +04:00
static bool finished ;
2001-03-19 02:41:53 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Make sure we swallow keepalives during idle time .
2001-03-19 02:41:53 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2001-03-19 02:41:53 +03:00
static void readline_callback ( void )
{
static time_t last_t ;
2010-08-30 14:15:54 +04:00
struct timespec now ;
2001-03-19 02:41:53 +03:00
time_t t ;
2011-02-08 19:56:10 +03:00
int ret , revents ;
2001-03-19 02:41:53 +03:00
2010-08-30 14:15:54 +04:00
clock_gettime_mono ( & now ) ;
t = now . tv_sec ;
2001-03-19 02:41:53 +03:00
2003-08-07 00:01:31 +04:00
if ( t - last_t < 5 )
return ;
2001-03-19 02:41:53 +03:00
last_t = t ;
2003-05-10 04:30:47 +04:00
again :
2003-03-18 13:56:37 +03:00
if ( cli - > fd = = - 1 )
return ;
2008-01-04 23:56:23 +03:00
/* We deliberately use receive_smb_raw instead of
2001-03-19 02:41:53 +03:00
client_receive_smb as we want to receive
session keepalives and then drop them here .
*/
2011-02-08 19:56:10 +03:00
ret = poll_intr_one_fd ( cli - > fd , POLLIN | POLLHUP , 0 , & revents ) ;
if ( ( ret > 0 ) & & ( revents & ( POLLIN | POLLHUP | POLLERR ) ) ) {
2008-01-26 01:54:22 +03:00
NTSTATUS status ;
size_t len ;
set_smb_read_error ( & cli - > smb_rw_error , SMB_READ_OK ) ;
2008-05-28 20:31:42 +04:00
status = receive_smb_raw ( cli - > fd , cli - > inbuf , cli - > bufsize , 0 , 0 , & len ) ;
2008-01-26 01:54:22 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Read from server failed, maybe it closed "
" the connection \n " ) ) ;
2008-10-04 01:58:41 +04:00
finished = true ;
smb_readline_done ( ) ;
2008-01-26 01:54:22 +03:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_END_OF_FILE ) ) {
set_smb_read_error ( & cli - > smb_rw_error ,
SMB_READ_EOF ) ;
return ;
}
if ( NT_STATUS_EQUAL ( status , NT_STATUS_IO_TIMEOUT ) ) {
set_smb_read_error ( & cli - > smb_rw_error ,
SMB_READ_TIMEOUT ) ;
return ;
}
set_smb_read_error ( & cli - > smb_rw_error , SMB_READ_ERROR ) ;
2005-11-30 20:56:50 +03:00
return ;
}
2008-01-04 23:56:23 +03:00
if ( CVAL ( cli - > inbuf , 0 ) ! = SMBkeepalive ) {
DEBUG ( 0 , ( " Read from server "
" returned unexpected packet! \n " ) ) ;
return ;
}
2001-03-19 02:41:53 +03:00
goto again ;
}
2007-12-07 04:16:33 +03:00
2005-11-30 20:53:21 +03:00
/* Ping the server to keep the connection alive using SMBecho. */
{
2008-10-04 04:57:37 +04:00
NTSTATUS status ;
2005-11-30 20:53:21 +03:00
unsigned char garbage [ 16 ] ;
memset ( garbage , 0xf0 , sizeof ( garbage ) ) ;
2008-10-04 04:57:37 +04:00
status = cli_echo ( cli , 1 , data_blob_const ( garbage , sizeof ( garbage ) ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-10-04 01:58:41 +04:00
DEBUG ( 0 , ( " SMBecho failed. Maybe server has closed "
" the connection \n " ) ) ;
finished = true ;
smb_readline_done ( ) ;
}
2005-11-30 20:53:21 +03:00
}
2001-03-19 02:41:53 +03:00
}
1998-11-09 06:45:49 +03:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Process commands on stdin .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2004-07-02 00:20:06 +04:00
static int process_stdin ( void )
1998-09-18 16:47:46 +04:00
{
2004-07-02 00:20:06 +04:00
int rc = 0 ;
1998-09-18 16:47:46 +04:00
2008-10-04 01:58:41 +04:00
while ( ! finished ) {
2007-11-30 04:25:41 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-12-07 04:16:33 +03:00
char * tok = NULL ;
char * the_prompt = NULL ;
char * line = NULL ;
1998-11-09 06:45:49 +03:00
int i ;
2007-11-30 04:25:41 +03:00
2001-03-18 16:24:57 +03:00
/* display a prompt */
2007-12-07 04:16:33 +03:00
if ( asprintf ( & the_prompt , " smb: %s> " , client_get_cur_dir ( ) ) < 0 ) {
TALLOC_FREE ( frame ) ;
break ;
}
line = smb_readline ( the_prompt , readline_callback , completion_fn ) ;
SAFE_FREE ( the_prompt ) ;
if ( ! line ) {
2007-11-30 04:25:41 +03:00
TALLOC_FREE ( frame ) ;
break ;
}
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 = = ' ! ' ) {
2009-01-01 03:30:11 +03:00
if ( system ( line + 1 ) = = - 1 ) {
d_printf ( " system() command %s failed. \n " ,
line + 1 ) ;
}
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2007-11-30 04:25:41 +03:00
TALLOC_FREE ( frame ) ;
1998-11-09 06:45:49 +03:00
continue ;
}
2007-11-30 04:25:41 +03:00
1998-11-09 06:45:49 +03:00
/* and get the first part of the command */
2007-12-19 23:59:28 +03:00
cmd_ptr = line ;
if ( ! next_token_talloc ( frame , & cmd_ptr , & tok , NULL ) ) {
2007-11-30 04:25:41 +03:00
TALLOC_FREE ( frame ) ;
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2007-11-30 04:25:41 +03:00
continue ;
}
1998-11-09 06:45:49 +03:00
if ( ( i = process_tok ( tok ) ) > = 0 ) {
2004-07-02 00:20:06 +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
}
2007-12-07 04:16:33 +03:00
SAFE_FREE ( line ) ;
2007-11-30 04:25:41 +03:00
TALLOC_FREE ( frame ) ;
1998-11-09 06:45:49 +03:00
}
2004-07-02 00:20:06 +04:00
return rc ;
1998-09-18 16:47:46 +04:00
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
2003-08-07 00:01:31 +04:00
Process commands from the client .
1996-05-04 11:50:46 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static int process ( const char * base_directory )
1996-05-04 11:50:46 +04:00
{
2001-10-09 23:12:18 +04:00
int rc = 0 ;
2007-12-30 09:39:52 +03:00
cli = cli_cm_open ( talloc_tos ( ) , NULL ,
2009-01-02 23:49:49 +03:00
have_ip ? dest_ss_str : desthost ,
2009-03-18 00:53:06 +03:00
service , auth_info , true , smb_encrypt ,
2009-01-15 03:08:19 +03:00
max_protocol , port , name_type ) ;
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
2007-12-08 01:43:31 +03:00
if ( base_directory & & * base_directory ) {
2005-04-15 04:39:03 +04:00
rc = do_cd ( base_directory ) ;
if ( rc ) {
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
2005-04-15 04:39:03 +04:00
return rc ;
}
}
2007-12-07 04:16:33 +03: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
}
2007-12-07 04:16:33 +03:00
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
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
/****************************************************************************
2003-08-07 00:01:31 +04:00
Handle a - L query .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static int do_host_query ( const char * query_host )
1998-11-09 06:45:49 +03:00
{
2007-12-30 09:39:52 +03:00
cli = cli_cm_open ( talloc_tos ( ) , NULL ,
2010-08-21 02:57:08 +04:00
have_ip ? dest_ss_str : query_host , " IPC$ " , auth_info , true , smb_encrypt ,
2009-01-15 03:08:19 +03:00
max_protocol , port , name_type ) ;
1998-11-17 04:44:25 +03:00
if ( ! cli )
return 1 ;
1998-11-09 06:45:49 +03:00
2007-12-07 04:16:33 +03:00
browse_host ( true ) ;
2003-08-11 01:43:28 +04:00
2009-05-16 03:13:59 +04:00
/* Ensure that the host can do IPv4 */
if ( ! interpret_addr ( query_host ) ) {
struct sockaddr_storage ss ;
if ( interpret_string_addr ( & ss , query_host , 0 ) & &
( ss . ss_family ! = AF_INET ) ) {
d_printf ( " %s is an IPv6 address -- no workgroup available \n " ,
query_host ) ;
return 1 ;
}
2008-04-17 20:24:54 +04:00
}
2003-08-11 01:43:28 +04:00
if ( port ! = 139 ) {
/* Workgroups simply don't make sense over anything
else but port 139. . . */
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
2007-12-30 09:39:52 +03:00
cli = cli_cm_open ( talloc_tos ( ) , NULL ,
2010-08-21 02:57:08 +04:00
have_ip ? dest_ss_str : query_host , " IPC$ " ,
auth_info , true , smb_encrypt ,
2009-01-15 03:08:19 +03:00
max_protocol , 139 , name_type ) ;
2003-08-11 01:43:28 +04:00
}
if ( cli = = NULL ) {
d_printf ( " NetBIOS over TCP disabled -- no workgroup available \n " ) ;
return 1 ;
}
2003-04-28 10:54:49 +04:00
list_servers ( lp_workgroup ( ) ) ;
1998-11-09 06:45:49 +03:00
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
return ( 0 ) ;
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Handle a tar operation .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2007-12-07 04:16:33 +03:00
static int do_tar_op ( const char * base_directory )
1998-11-09 06:45:49 +03:00
{
int ret ;
2002-07-15 14:35:28 +04:00
/* do we already have a connection? */
if ( ! cli ) {
2007-12-30 09:39:52 +03:00
cli = cli_cm_open ( talloc_tos ( ) , NULL ,
2009-01-02 23:49:49 +03:00
have_ip ? dest_ss_str : desthost ,
2009-03-18 00:53:06 +03:00
service , auth_info , true , smb_encrypt ,
2009-01-15 03:08:19 +03:00
max_protocol , port , name_type ) ;
2002-07-15 14:35:28 +04:00
if ( ! cli )
return 1 ;
}
1998-11-09 06:45:49 +03:00
2007-12-07 04:16:33 +03:00
recurse = true ;
1998-11-09 06:45:49 +03:00
2007-12-08 01:43:31 +03:00
if ( base_directory & & * base_directory ) {
2005-04-15 04:39:03 +04:00
ret = do_cd ( base_directory ) ;
if ( ret ) {
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
2005-04-15 04:39:03 +04:00
return ret ;
}
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
ret = process_tar ( ) ;
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
1998-11-09 06:45:49 +03:00
return ( ret ) ;
}
/****************************************************************************
2003-08-07 00:01:31 +04:00
Handle a message operation .
1998-11-09 06:45:49 +03:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
2009-03-18 00:53:06 +03:00
static int do_message_op ( struct user_auth_info * a_info )
1998-11-09 06:45:49 +03:00
{
2007-10-25 01:16:54 +04:00
struct sockaddr_storage ss ;
1998-11-09 06:45:49 +03:00
struct nmb_name called , calling ;
2002-09-25 19:19:00 +04:00
fstring server_name ;
char name_type_hex [ 10 ] ;
2005-04-11 07:34:27 +04:00
int msg_port ;
2007-06-20 21:38:42 +04:00
NTSTATUS status ;
1998-11-09 06:45:49 +03:00
2005-02-24 03:11:42 +03:00
make_nmb_name ( & calling , calling_name , 0x0 ) ;
2000-01-07 09:55:36 +03:00
make_nmb_name ( & called , desthost , name_type ) ;
1998-11-09 06:45:49 +03:00
2011-05-04 22:38:26 +04:00
strlcpy ( server_name , desthost , sizeof ( server_name ) ) ;
2002-09-25 19:19:00 +04:00
snprintf ( name_type_hex , sizeof ( name_type_hex ) , " #%X " , name_type ) ;
2011-05-04 22:38:26 +04:00
strlcat ( server_name , name_type_hex , sizeof ( server_name ) ) ;
2002-09-25 19:19:00 +04:00
2008-12-03 10:29:57 +03:00
zero_sockaddr ( & ss ) ;
2007-10-25 01:16:54 +04:00
if ( have_ip )
ss = dest_ss ;
1998-11-09 06:45:49 +03:00
2005-04-11 07:34:27 +04:00
/* we can only do messages over port 139 (to windows clients at least) */
msg_port = port ? port : 139 ;
2009-01-15 03:08:19 +03:00
if ( ! ( cli = cli_initialise ( ) ) ) {
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 ;
2007-06-20 21:38:42 +04:00
}
2009-01-15 03:08:19 +03:00
cli_set_port ( cli , msg_port ) ;
2007-06-20 21:38:42 +04:00
2007-10-25 01:16:54 +04:00
status = cli_connect ( cli , server_name , & ss ) ;
2007-06-20 21:38:42 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Connection to %s failed. Error %s \n " , desthost , nt_errstr ( status ) ) ;
return 1 ;
1998-11-09 06:45:49 +03:00
}
if ( ! cli_session_request ( cli , & calling , & called ) ) {
2001-09-07 18:14:57 +04:00
d_printf ( " session request failed \n " ) ;
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
1998-11-09 06:45:49 +03:00
return 1 ;
}
2009-03-18 00:53:06 +03:00
send_message ( get_cmdline_auth_info_username ( a_info ) ) ;
2009-03-13 03:59:24 +03:00
cli_shutdown ( cli ) ;
1998-11-09 06:45:49 +03:00
return 0 ;
}
1996-05-04 11:50:46 +04:00
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-07 00:01:31 +04:00
1996-06-04 10:42:03 +04:00
int main ( int argc , char * argv [ ] )
1996-05-04 11:50:46 +04:00
{
2007-12-07 04:16:33 +03:00
char * base_directory = NULL ;
1998-11-09 06:45:49 +03:00
int opt ;
2007-12-07 04:16:33 +03:00
char * query_host = NULL ;
bool message = false ;
2003-04-14 08:05:48 +04:00
static const char * new_name_resolve_order = NULL ;
poptContext pc ;
1998-11-09 06:45:49 +03:00
char * p ;
2001-10-09 23:12:18 +04:00
int rc = 0 ;
2003-08-25 21:55:33 +04:00
fstring new_workgroup ;
2007-12-07 04:16:33 +03:00
bool tar_opt = false ;
bool service_opt = false ;
2003-04-14 08:05:48 +04:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
{ " name-resolve " , ' R ' , POPT_ARG_STRING , & new_name_resolve_order , ' R ' , " Use these name resolution services only " , " NAME-RESOLVE-ORDER " } ,
{ " message " , ' M ' , POPT_ARG_STRING , NULL , ' M ' , " Send message " , " HOST " } ,
{ " ip-address " , ' I ' , POPT_ARG_STRING , NULL , ' I ' , " Use this IP to connect to " , " IP " } ,
{ " stderr " , ' E ' , POPT_ARG_NONE , NULL , ' E ' , " Write messages to stderr instead of stdout " } ,
{ " list " , ' L ' , POPT_ARG_STRING , NULL , ' L ' , " Get a list of shares available on a host " , " HOST " } ,
{ " max-protocol " , ' m ' , POPT_ARG_STRING , NULL , ' m ' , " Set the max protocol level " , " LEVEL " } ,
{ " tar " , ' T ' , POPT_ARG_STRING , NULL , ' T ' , " Command line tar " , " <c|x>IXFqgbNan " } ,
{ " directory " , ' D ' , POPT_ARG_STRING , NULL , ' D ' , " Start from directory " , " DIR " } ,
{ " command " , ' c ' , POPT_ARG_STRING , & cmdstr , ' c ' , " Execute semicolon separated commands " } ,
2003-06-11 10:10:10 +04:00
{ " send-buffer " , ' b ' , POPT_ARG_INT , & io_bufsize , ' b ' , " Changes the transmit/send buffer " , " BYTES " } ,
2003-04-14 08:05:48 +04:00
{ " port " , ' p ' , POPT_ARG_INT , & port , ' p ' , " Port to connect to " , " PORT " } ,
2004-01-16 18:01:09 +03:00
{ " grepable " , ' g ' , POPT_ARG_NONE , NULL , ' g ' , " Produce grepable output " } ,
2007-12-18 09:09:09 +03:00
{ " browse " , ' B ' , POPT_ARG_NONE , NULL , ' B ' , " Browse SMB servers using DNS " } ,
2003-04-14 08:05:48 +04:00
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
POPT_TABLEEND
} ;
2007-11-16 01:19:52 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-11-30 04:25:41 +03:00
2007-12-07 04:16:33 +03:00
if ( ! client_set_cur_dir ( " \\ " ) ) {
exit ( ENOMEM ) ;
}
1997-09-12 00:17:32 +04:00
2007-12-07 04:16:33 +03:00
/* initialize the workgroup name so we can determine whether or
2003-08-25 21:55:33 +04:00
not it was set by a command line option */
2007-12-07 04:16:33 +03:00
2003-08-25 21:55:33 +04:00
set_global_myworkgroup ( " " ) ;
2005-02-24 03:11:42 +03:00
set_global_myname ( " " ) ;
1996-05-04 11:50:46 +04:00
2008-01-08 21:21:26 +03:00
/* set default debug level to 1 regardless of what smb.conf sets */
2010-10-29 07:19:32 +04:00
setup_logging ( " smbclient " , DEBUG_DEFAULT_STDERR ) ;
2007-12-10 00:22:19 +03:00
load_case_tables ( ) ;
2010-10-29 14:10:31 +04:00
lp_set_cmdline ( " log level " , " 1 " ) ;
2008-12-14 15:06:19 +03:00
auth_info = user_auth_info_init ( frame ) ;
if ( auth_info = = NULL ) {
exit ( 1 ) ;
}
popt_common_set_auth_info ( auth_info ) ;
2007-03-28 18:16:34 +04:00
/* skip argv(0) */
pc = poptGetContext ( " smbclient " , argc , ( const char * * ) argv , long_options , 0 ) ;
2003-04-14 08:05:48 +04:00
poptSetOtherOptionHelp ( pc , " service <password> " ) ;
1998-09-29 08:43:40 +04:00
2008-03-06 18:41:42 +03:00
lp_set_in_client ( true ) ; /* Make sure that we tell lp_load we are */
1998-06-16 02:02:14 +04:00
2003-04-14 08:05:48 +04:00
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
2007-03-28 18:16:34 +04:00
/* if the tar option has been called previouslt, now we need to eat out the leftovers */
/* I see no other way to keep things sane --SSS */
2007-12-07 04:16:33 +03:00
if ( tar_opt = = true ) {
2007-03-28 18:16:34 +04:00
while ( poptPeekArg ( pc ) ) {
poptGetArg ( pc ) ;
}
2007-12-07 04:16:33 +03:00
tar_opt = false ;
2007-03-28 18:16:34 +04:00
}
/* if the service has not yet been specified lets see if it is available in the popt stack */
if ( ! service_opt & & poptPeekArg ( pc ) ) {
2007-12-07 04:16:33 +03:00
service = talloc_strdup ( frame , poptGetArg ( pc ) ) ;
if ( ! service ) {
exit ( ENOMEM ) ;
}
service_opt = true ;
2007-03-28 18:16:34 +04:00
}
/* if the service has already been retrieved then check if we have also a password */
2008-12-14 15:06:19 +03:00
if ( service_opt
& & ( ! get_cmdline_auth_info_got_pass ( auth_info ) )
& & poptPeekArg ( pc ) ) {
set_cmdline_auth_info_password ( auth_info ,
poptGetArg ( pc ) ) ;
2007-03-28 18:16:34 +04:00
}
2007-12-07 04:16:33 +03:00
1998-11-09 06:45:49 +03:00
switch ( opt ) {
case ' M ' :
2003-01-07 07:26:37 +03:00
/* Messages are sent to NetBIOS name type 0x3
* ( Messenger Service ) . Make sure we default
* to port 139 instead of port 445. srl , crh
*/
2007-12-07 04:16:33 +03:00
name_type = 0x03 ;
desthost = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! desthost ) {
exit ( ENOMEM ) ;
}
2005-02-25 00:54:52 +03:00
if ( ! port )
2009-01-15 03:08:19 +03:00
port = 139 ;
2007-12-07 04:16:33 +03:00
message = true ;
2003-01-14 11:53:59 +03:00
break ;
1998-11-09 06:45:49 +03:00
case ' I ' :
1998-10-29 05:18:17 +03:00
{
2007-10-25 01:16:54 +04:00
if ( ! interpret_string_addr ( & dest_ss , poptGetOptArg ( pc ) , 0 ) ) {
1998-11-09 06:45:49 +03:00
exit ( 1 ) ;
2007-10-25 01:16:54 +04:00
}
2007-12-07 04:16:33 +03:00
have_ip = true ;
2009-01-02 23:49:49 +03:00
print_sockaddr ( dest_ss_str , sizeof ( dest_ss_str ) , & dest_ss ) ;
1998-10-29 05:18:17 +03:00
}
1998-11-09 06:45:49 +03:00
break ;
case ' E ' :
2010-10-29 07:19:32 +04:00
setup_logging ( " smbclient " , DEBUG_STDERR ) ;
2003-04-14 08:05:48 +04:00
display_set_stderr ( ) ;
2000-08-29 18:35:31 +04:00
break ;
1998-11-09 06:45:49 +03:00
case ' L ' :
2007-12-07 04:16:33 +03:00
query_host = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! query_host ) {
exit ( ENOMEM ) ;
}
1998-11-09 06:45:49 +03:00
break ;
case ' m ' :
2003-04-14 08:05:48 +04:00
max_protocol = interpret_protocol ( poptGetOptArg ( pc ) , max_protocol ) ;
1998-11-09 06:45:49 +03:00
break ;
case ' T ' :
2003-08-02 01:09:10 +04:00
/* We must use old option processing for this. Find the
* position of the - T option in the raw argv [ ] . */
{
2007-04-10 22:21:37 +04:00
int i ;
2003-08-02 01:09:10 +04:00
for ( i = 1 ; i < argc ; i + + ) {
if ( strncmp ( " -T " , argv [ i ] , 2 ) = = 0 )
break ;
}
i + + ;
2007-04-10 22:21:37 +04:00
if ( ! tar_parseargs ( argc , argv , poptGetOptArg ( pc ) , i ) ) {
2003-08-02 01:09:10 +04:00
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
}
1998-11-09 06:45:49 +03:00
}
2007-03-28 18:16:34 +04:00
/* this must be the last option, mark we have parsed it so that we know we have */
2007-12-07 04:16:33 +03:00
tar_opt = true ;
1998-11-09 06:45:49 +03:00
break ;
case ' D ' :
2007-12-07 04:16:33 +03:00
base_directory = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! base_directory ) {
exit ( ENOMEM ) ;
}
1998-11-09 06:45:49 +03:00
break ;
2004-01-16 18:01:09 +03:00
case ' g ' :
2007-12-07 04:16:33 +03:00
grepable = true ;
2004-01-16 18:01:09 +03:00
break ;
2007-12-30 09:39:52 +03:00
case ' e ' :
smb_encrypt = true ;
break ;
2007-12-18 09:09:09 +03:00
case ' B ' :
return ( do_smb_browse ( ) ) ;
2003-04-14 08:05:48 +04:00
}
}
2007-03-28 18:16:34 +04:00
/* We may still have some leftovers after the last popt option has been called */
2007-12-07 04:16:33 +03:00
if ( tar_opt = = true ) {
2007-03-28 18:16:34 +04:00
while ( poptPeekArg ( pc ) ) {
poptGetArg ( pc ) ;
}
2007-12-07 04:16:33 +03:00
tar_opt = false ;
2007-03-28 18:16:34 +04:00
}
/* if the service has not yet been specified lets see if it is available in the popt stack */
if ( ! service_opt & & poptPeekArg ( pc ) ) {
2007-12-07 04:16:33 +03:00
service = talloc_strdup ( frame , poptGetArg ( pc ) ) ;
if ( ! service ) {
exit ( ENOMEM ) ;
}
service_opt = true ;
2007-03-28 18:16:34 +04:00
}
2005-02-25 00:54:52 +03:00
2007-03-28 18:16:34 +04:00
/* if the service has already been retrieved then check if we have also a password */
2008-12-14 15:06:19 +03:00
if ( service_opt
& & ! get_cmdline_auth_info_got_pass ( auth_info )
& & poptPeekArg ( pc ) ) {
set_cmdline_auth_info_password ( auth_info ,
poptGetArg ( pc ) ) ;
2007-03-28 18:16:34 +04:00
}
2007-12-07 04:16:33 +03:00
2003-08-25 21:55:33 +04:00
/* save the workgroup...
2007-12-07 04:16:33 +03:00
FIXME ! ! do we need to do this for other options as well
( or maybe a generic way to keep lp_load ( ) from overwriting
2003-08-25 21:55:33 +04:00
everything ) ? */
2007-12-07 04:16:33 +03:00
2004-03-26 18:40:06 +03:00
fstrcpy ( new_workgroup , lp_workgroup ( ) ) ;
2007-12-07 04:16:33 +03:00
calling_name = talloc_strdup ( frame , global_myname ( ) ) ;
if ( ! calling_name ) {
exit ( ENOMEM ) ;
}
2004-03-26 18:40:06 +03:00
if ( override_logfile )
2010-10-29 07:19:32 +04:00
setup_logging ( lp_logfile ( ) , DEBUG_FILE ) ;
2007-12-07 04:16:33 +03:00
2007-12-10 22:30:37 +03:00
if ( ! lp_load ( get_dyn_CONFIGFILE ( ) , true , false , false , true ) ) {
2003-08-07 02:45:46 +04:00
fprintf ( stderr , " %s: Can't load %s - run testparm to debug it \n " ,
2007-12-10 22:30:37 +03:00
argv [ 0 ] , get_dyn_CONFIGFILE ( ) ) ;
2003-08-07 02:45:46 +04:00
}
2007-12-07 04:16:33 +03:00
2008-12-14 15:06:19 +03:00
if ( get_cmdline_auth_info_use_machine_account ( auth_info ) & &
! set_cmdline_auth_info_machine_account_creds ( auth_info ) ) {
2008-05-05 18:58:24 +04:00
exit ( - 1 ) ;
}
2003-04-14 08:05:48 +04:00
load_interfaces ( ) ;
2007-06-21 21:05:59 +04:00
2007-12-08 01:43:31 +03:00
if ( service_opt & & service ) {
2007-12-07 04:16:33 +03:00
size_t len ;
2007-06-21 21:05:59 +04:00
/* Convert any '/' characters in the service name to '\' characters */
string_replace ( service , ' / ' , ' \\ ' ) ;
if ( count_chars ( service , ' \\ ' ) < 3 ) {
d_printf ( " \n %s: Not enough ' \\ ' characters in service \n " , service ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
}
2007-12-06 14:29:52 +03:00
/* Remove trailing slashes */
len = strlen ( service ) ;
while ( len > 0 & & service [ len - 1 ] = = ' \\ ' ) {
- - len ;
service [ len ] = ' \0 ' ;
}
2007-06-21 21:05:59 +04:00
}
2007-12-07 04:16:33 +03:00
if ( strlen ( new_workgroup ) ! = 0 ) {
2003-08-25 21:55:33 +04:00
set_global_myworkgroup ( new_workgroup ) ;
2007-12-07 04:16:33 +03:00
}
2003-04-14 08:05:48 +04:00
2007-12-07 04:16:33 +03:00
if ( strlen ( calling_name ) ! = 0 ) {
2005-02-24 03:11:42 +03:00
set_global_myname ( calling_name ) ;
2007-12-07 04:16:33 +03:00
} else {
TALLOC_FREE ( calling_name ) ;
calling_name = talloc_strdup ( frame , global_myname ( ) ) ;
}
2005-02-24 03:11:42 +03:00
2008-12-14 15:06:19 +03:00
smb_encrypt = get_cmdline_auth_info_smb_encrypt ( auth_info ) ;
2008-03-15 01:26:28 +03:00
if ( ! init_names ( ) ) {
fprintf ( stderr , " init_names() failed \n " ) ;
exit ( 1 ) ;
}
1998-09-18 16:47:46 +04:00
2003-04-14 08:05:48 +04:00
if ( new_name_resolve_order )
1998-11-09 06:45:49 +03:00
lp_set_name_resolve_order ( new_name_resolve_order ) ;
1998-09-18 16:47:46 +04:00
2007-12-08 01:35:04 +03:00
if ( ! tar_type & & ! query_host & & ! service & & ! message ) {
2003-04-14 08:05:48 +04:00
poptPrintUsage ( pc , stderr , 0 ) ;
1998-11-09 06:45:49 +03:00
exit ( 1 ) ;
}
1996-05-04 11:50:46 +04:00
2003-04-14 08:05:48 +04:00
poptFreeContext ( pc ) ;
2009-01-16 00:27:52 +03:00
DEBUG ( 3 , ( " Client started (version %s). \n " , samba_version_string ( ) ) ) ;
1996-05-04 11:50:46 +04:00
2009-03-18 00:53:06 +03:00
/* Ensure we have a password (or equivalent). */
set_cmdline_auth_info_getpass ( auth_info ) ;
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
2007-12-08 01:43:31 +03:00
if ( query_host & & * query_host ) {
2004-03-11 17:39:32 +03:00
char * qhost = query_host ;
char * slash ;
while ( * qhost = = ' \\ ' | | * qhost = = ' / ' )
qhost + + ;
if ( ( slash = strchr_m ( qhost , ' / ' ) )
| | ( slash = strchr_m ( qhost , ' \\ ' ) ) ) {
* slash = 0 ;
}
if ( ( p = strchr_m ( qhost , ' # ' ) ) ) {
* p = 0 ;
p + + ;
sscanf ( p , " %x " , & name_type ) ;
}
2005-02-25 00:54:52 +03:00
2004-03-11 17:39:32 +03:00
return do_host_query ( qhost ) ;
1996-05-04 11:50:46 +04:00
}
1998-11-09 06:45:49 +03:00
if ( message ) {
2008-12-14 15:06:19 +03:00
return do_message_op ( auth_info ) ;
1996-05-04 11:50:46 +04:00
}
2007-11-30 04:25:41 +03:00
2001-10-09 23:12:18 +04:00
if ( process ( base_directory ) ) {
return 1 ;
1996-05-04 11:50:46 +04:00
}
2007-12-07 04:16:33 +03:00
TALLOC_FREE ( frame ) ;
2001-10-09 23:12:18 +04:00
return rc ;
1996-05-04 11:50:46 +04:00
}