[GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch.
[samba.git] / source / client / client.c
index 35716ab13cb4017982ef0db2b932e226ac2beda3..171d413b0ae546031058dc6485ff9fecf7126df6 100644 (file)
@@ -8,7 +8,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -17,8 +17,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -194,6 +193,10 @@ static void send_message(void)
                        msg[l] = c;   
                }
 
+               if ((total_len > 0) && (strlen(msg) == 0)) {
+                       break;
+               }
+
                if (!cli_message_text(cli, msg, l, grp_id)) {
                        d_printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
                        return;
@@ -344,6 +347,19 @@ static int cmd_cd(void)
        return rc;
 }
 
+/****************************************************************************
+ Change directory.
+****************************************************************************/
+
+static int cmd_cd_oneup(void)
+{
+       pstring buf;
+
+       pstrcpy(buf, "..");
+       return do_cd(buf);
+}
+
+
 /*******************************************************************
  Decide if a file should be operated on.
 ********************************************************************/
@@ -763,6 +779,26 @@ static int cmd_du(void)
        return rc;
 }
 
+static int cmd_echo(void)
+{
+       fstring num;
+       pstring data;
+
+       if (!next_token_nr(NULL, num, NULL, sizeof(num))
+           || !next_token_nr(NULL, data, NULL, sizeof(data))) {
+               d_printf("echo <num> <data>\n");
+               return 1;
+       }
+
+       if (!cli_echo(cli, atoi(num), (uint8 *)data, strlen(data))) {
+               d_printf("echo failed: %s\n",
+                        nt_errstr(cli_get_nt_error(cli)));
+               return 1;
+       }
+
+       return 0;
+}
+
 /****************************************************************************
  Get a file from rname to lname
 ****************************************************************************/
@@ -1787,54 +1823,6 @@ static int cmd_open(void)
 /****************************************************************************
 ****************************************************************************/
 
-static int cmd_posix_encrypt(void)
-{
-       NTSTATUS status;
-
-       if (cli->use_kerberos) {
-               status = cli_gss_smb_encryption_start(cli);
-       } else {        
-               fstring buf;
-               fstring domain;
-               fstring user;
-               fstring password;
-
-               if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
-                       d_printf("posix_encrypt domain user password\n");
-                       return 1;
-               }
-               fstrcpy(domain,buf);
-
-               if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
-                       d_printf("posix_encrypt domain user password\n");
-                       return 1;
-               }
-               fstrcpy(user,buf);
-
-               if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
-                       d_printf("posix_encrypt domain user password\n");
-                       return 1;
-               }
-               fstrcpy(password,buf);
-
-               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");
-       }
-
-       return 0;
-}
-
-/****************************************************************************
-****************************************************************************/
-
 static int cmd_posix_open(void)
 {
        pstring mask;
@@ -2697,7 +2685,8 @@ static int cmd_rename(void)
        pstring src,dest;
        pstring buf,buf2;
        struct cli_state *targetcli;
-       pstring targetname;
+       pstring targetsrc;
+       pstring targetdest;
   
        pstrcpy(src,cur_dir);
        pstrcpy(dest,cur_dir);
@@ -2711,13 +2700,21 @@ static int cmd_rename(void)
        pstrcat(src,buf);
        pstrcat(dest,buf2);
 
-       if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
-               d_printf("chown %s: %s\n", src, cli_errstr(cli));
+       if ( !cli_resolve_path( "", cli, src, &targetcli, targetsrc ) ) {
+               d_printf("rename %s: %s\n", src, cli_errstr(cli));
+               return 1;
+       }
+
+       if ( !cli_resolve_path( "", cli, dest, &targetcli, targetdest ) ) {
+               d_printf("rename %s: %s\n", dest, cli_errstr(cli));
                return 1;
        }
 
-       if (!cli_rename(targetcli, targetname, dest)) {
-               d_printf("%s renaming files\n",cli_errstr(targetcli));
+       if (!cli_rename(targetcli, targetsrc, targetdest)) {
+               d_printf("%s renaming files %s -> %s \n",
+                       cli_errstr(targetcli),
+                       targetsrc,
+                       targetdest);
                return 1;
        }
        
@@ -3027,12 +3024,10 @@ static BOOL browse_host_rpc(BOOL sort)
        NTSTATUS status;
        struct rpc_pipe_client *pipe_hnd;
        TALLOC_CTX *mem_ctx;
-       uint32 enum_hnd = 0;
-       struct srvsvc_NetShareCtr1 ctr1;
-       union srvsvc_NetShareCtr ctr;
+       ENUM_HND enum_hnd;
+       WERROR werr;
+       SRV_SHARE_INFO_CTR ctr;
        int i;
-       uint32 level;
-       uint32 numentries;
 
        mem_ctx = talloc_new(NULL);
        if (mem_ctx == NULL) {
@@ -3040,6 +3035,8 @@ static BOOL browse_host_rpc(BOOL sort)
                return False;
        }
 
+       init_enum_hnd(&enum_hnd, 0);
+
        pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
 
        if (pipe_hnd == NULL) {
@@ -3049,23 +3046,23 @@ static BOOL browse_host_rpc(BOOL sort)
                return False;
        }
 
-       ZERO_STRUCT(ctr1);
-       level = 1;
-       ctr.ctr1 = &ctr1;
-
-       status = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, "", &level,
-                                           &ctr, 0xffffffff, &numentries,
-                                           &enum_hnd);
+       werr = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, 1, &ctr,
+                                           0xffffffff, &enum_hnd);
 
-       if (!NT_STATUS_IS_OK(status)) {
+       if (!W_ERROR_IS_OK(werr)) {
                TALLOC_FREE(mem_ctx);
                cli_rpc_pipe_close(pipe_hnd);
                return False;
        }
 
-       for (i=0; i<numentries; i++) {
-               struct srvsvc_NetShareInfo1 *info = &ctr.ctr1->array[i];
-               browse_fn(info->name, info->type, info->comment, NULL);
+       for (i=0; i<ctr.num_entries; i++) {
+               SRV_SHARE_INFO_1 *info = &ctr.share.info1[i];
+               char *name, *comment;
+               name = rpcstr_pull_unistr2_talloc(
+                       mem_ctx, &info->info_1_str.uni_netname);
+               comment = rpcstr_pull_unistr2_talloc(
+                       mem_ctx, &info->info_1_str.uni_remark);
+               browse_fn(name, info->info_1.type, comment, NULL);
        }
 
        TALLOC_FREE(mem_ctx);
@@ -3255,6 +3252,7 @@ static struct
   {"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
   {"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}},
+  {"echo",cmd_echo,"ping the server",{COMPL_NONE,COMPL_NONE}},
   {"exit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
   {"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
   {"getfacl",cmd_getfacl,"<file name> get the POSIX ACL on a file (UNIX extensions only)",{COMPL_REMOTE,COMPL_LOCAL}},
@@ -3266,6 +3264,7 @@ static struct
   {"lock",cmd_lock,"lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock",{COMPL_REMOTE,COMPL_REMOTE}},
   {"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}},
+  {"l",cmd_dir,"<mask> list the contents of the current directory",{COMPL_REMOTE,COMPL_NONE}},
   {"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
   {"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
   {"mget",cmd_mget,"<mask> get all the matching files",{COMPL_REMOTE,COMPL_NONE}},
@@ -3275,7 +3274,6 @@ static struct
   {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
   {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
   {"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}},
-  {"posix_encrypt",cmd_posix_encrypt,"<domain> <user> <password> start up transport encryption",{COMPL_REMOTE,COMPL_NONE}},
   {"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}},
@@ -3308,7 +3306,8 @@ static struct
   {"logon",cmd_logon,"establish new logon",{COMPL_NONE,COMPL_NONE}},
   {"listconnect",cmd_list_connect,"list open connections",{COMPL_NONE,COMPL_NONE}},
   {"showconnect",cmd_show_connect,"display the current active connection",{COMPL_NONE,COMPL_NONE}},
-  
+  {"..",cmd_cd_oneup,"change the remote directory (up one level)",{COMPL_REMOTE,COMPL_NONE}},
+
   /* Yes, this must be here, see crh's comment above. */
   {"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
   {NULL,NULL,NULL,{COMPL_NONE,COMPL_NONE}}
@@ -3671,12 +3670,12 @@ static void readline_callback(void)
        timeout.tv_usec = 0;
        sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
                
-       /* We deliberately use cli_receive_smb_return_keepalive instead of
+       /* We deliberately use receive_smb instead of
           client_receive_smb as we want to receive
           session keepalives and then drop them here.
        */
        if (FD_ISSET(cli->fd,&fds)) {
-               if (!cli_receive_smb_return_keepalive(cli)) {
+               if (!receive_smb(cli->fd,cli->inbuf,0)) {
                        DEBUG(0, ("Read from server failed, maybe it closed the "
                                "connection\n"));
                        return;
@@ -3688,7 +3687,7 @@ static void readline_callback(void)
        {
                unsigned char garbage[16];
                memset(garbage, 0xf0, sizeof(garbage));
-               cli_echo(cli, garbage, sizeof(garbage));
+               cli_echo(cli, 1, garbage, sizeof(garbage));
        }
 }
 
@@ -3970,14 +3969,6 @@ static int do_message_op(void)
                /* if the service has not yet been specified lets see if it is available in the popt stack */
                if (!service_opt && poptPeekArg(pc)) {
                        pstrcpy(service, poptGetArg(pc));
-                       /* 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);
-                       }
                        service_opt = True;
                }
 
@@ -4065,14 +4056,6 @@ static int do_message_op(void)
        /* if the service has not yet been specified lets see if it is available in the popt stack */
        if (!service_opt && poptPeekArg(pc)) {
                pstrcpy(service, poptGetArg(pc));
-               /* 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);
-               }
                service_opt = True;
        }
 
@@ -4111,6 +4094,16 @@ static int do_message_op(void)
        }
        
        load_interfaces();
+
+       if (service_opt) {
+               /* 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);
+               }
+       }
        
        if ( strlen(new_workgroup) != 0 )
                set_global_myworkgroup( new_workgroup );