r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[vlendec/samba-autobuild/.git] / source3 / client / client.c
index 886af863e470a66ff0da2870acd45ee25e9ea94a..99fffa712321cf921dcffdc173297be0371c886a 100644 (file)
@@ -269,7 +269,7 @@ static int do_cd(char *newdir)
        else
                pstrcat(cur_dir,p);
 
-       if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
+       if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != '\\')) {
                pstrcat(cur_dir, "\\");
        }
        
@@ -379,7 +379,7 @@ static void display_finfo(file_info *finfo)
                         finfo->name,
                         attrib_string(finfo->mode),
                         (double)finfo->size,
-                        asctime(localtime(&t)));
+                        time_to_asc(&t));
                dir_total += finfo->size;
        }
 }
@@ -447,7 +447,14 @@ static void adjust_do_list_queue(void)
         * If the starting point of the queue is more than half way through,
         * move everything toward the beginning.
         */
-       if (do_list_queue && (do_list_queue_start == do_list_queue_end)) {
+
+       if (do_list_queue == NULL) {
+               DEBUG(4,("do_list_queue is empty\n"));
+               do_list_queue_start = do_list_queue_end = 0;
+               return;
+       }
+               
+       if (do_list_queue_start == do_list_queue_end) {
                DEBUG(4,("do_list_queue is empty\n"));
                do_list_queue_start = do_list_queue_end = 0;
                *do_list_queue = '\0';
@@ -647,7 +654,7 @@ static int cmd_dir(void)
        dir_total = 0;
        if (strcmp(cur_dir, "\\") != 0) {
                pstrcpy(mask,cur_dir);
-               if(mask[strlen(mask)-1]!='\\')
+               if ((mask[0] != '\0') && (mask[strlen(mask)-1]!='\\'))
                        pstrcat(mask,"\\");
        } else {
                pstrcpy(mask, "\\");
@@ -686,7 +693,7 @@ static int cmd_du(void)
        
        dir_total = 0;
        pstrcpy(mask,cur_dir);
-       if(mask[strlen(mask)-1]!='\\')
+       if ((mask[0] != '\0') && (mask[strlen(mask)-1]!='\\'))
                pstrcat(mask,"\\");
        
        if (next_token_nr(NULL,buf,NULL,sizeof(buf))) {
@@ -1008,7 +1015,7 @@ static int cmd_mget(void)
 
        while (next_token_nr(NULL,p,NULL,sizeof(buf))) {
                pstrcpy(mget_mask,cur_dir);
-               if(mget_mask[strlen(mget_mask)-1]!='\\')
+               if ((mget_mask[0] != '\0') && (mget_mask[strlen(mget_mask)-1]!='\\'))
                        pstrcat(mget_mask,"\\");
                
                if (*p == '\\')
@@ -2111,6 +2118,7 @@ static int cmd_stat(void)
        fstring mode_str;
        SMB_STRUCT_STAT sbuf;
        struct cli_state *targetcli;
+       struct tm *lt;
        pstring targetname;
  
        if (!SERVER_HAS_UNIX_CIFS(cli)) {
@@ -2165,13 +2173,28 @@ static int cmd_stat(void)
                (unsigned int)sbuf.st_uid, 
                (unsigned int)sbuf.st_gid);
 
-       strftime(mode_str, sizeof(mode_str), "%F %T %z", localtime(&sbuf.st_atime));
+       lt = localtime(&sbuf.st_atime);
+       if (lt) {
+               strftime(mode_str, sizeof(mode_str), "%F %T %z", lt);
+       } else {
+               fstrcpy(mode_str, "unknown");
+       }
        d_printf("Access: %s\n", mode_str);
 
-       strftime(mode_str, sizeof(mode_str), "%F %T %z", localtime(&sbuf.st_mtime));
+       lt = localtime(&sbuf.st_mtime);
+       if (lt) {
+               strftime(mode_str, sizeof(mode_str), "%F %T %z", lt);
+       } else {
+               fstrcpy(mode_str, "unknown");
+       }
        d_printf("Modify: %s\n", mode_str);
 
-       strftime(mode_str, sizeof(mode_str), "%F %T %z", localtime(&sbuf.st_ctime));
+       lt = localtime(&sbuf.st_ctime);
+       if (lt) {
+               strftime(mode_str, sizeof(mode_str), "%F %T %z", lt);
+       } else {
+               fstrcpy(mode_str, "unknown");
+       }
        d_printf("Change: %s\n", mode_str);
        
        return 0;
@@ -2339,7 +2362,7 @@ static int cmd_newer(void)
        if (ok && (sys_stat(buf,&sbuf) == 0)) {
                newer_than = sbuf.st_mtime;
                DEBUG(1,("Getting files newer than %s",
-                        asctime(localtime(&newer_than))));
+                        time_to_asc(&newer_than)));
        } else {
                newer_than = 0;
        }
@@ -2510,7 +2533,7 @@ static void browse_fn(const char *name, uint32 m,
 
         *typestr=0;
 
-        switch (m)
+        switch (m & 7)
         {
           case STYPE_DISKTREE:
             fstrcpy(typestr,"Disk"); break;
@@ -2532,6 +2555,57 @@ static void browse_fn(const char *name, uint32 m,
        }
 }
 
+static BOOL browse_host_rpc(BOOL sort)
+{
+       NTSTATUS status;
+       struct rpc_pipe_client *pipe_hnd;
+       TALLOC_CTX *mem_ctx;
+       ENUM_HND enum_hnd;
+       WERROR werr;
+       SRV_SHARE_INFO_CTR ctr;
+       int i;
+
+       mem_ctx = talloc_new(NULL);
+       if (mem_ctx == NULL) {
+               DEBUG(0, ("talloc_new failed\n"));
+               return False;
+       }
+
+       init_enum_hnd(&enum_hnd, 0);
+
+       pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &status);
+
+       if (pipe_hnd == NULL) {
+               DEBUG(10, ("Could not connect to srvsvc pipe: %s\n",
+                          nt_errstr(status)));
+               TALLOC_FREE(mem_ctx);
+               return False;
+       }
+
+       werr = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, 1, &ctr,
+                                           0xffffffff, &enum_hnd);
+
+       if (!W_ERROR_IS_OK(werr)) {
+               TALLOC_FREE(mem_ctx);
+               cli_rpc_pipe_close(pipe_hnd);
+               return False;
+       }
+
+       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);
+       cli_rpc_pipe_close(pipe_hnd);
+       return True;
+}
+
 /****************************************************************************
  Try and browse available connections on a host.
 ****************************************************************************/
@@ -2544,6 +2618,10 @@ static BOOL browse_host(BOOL sort)
                d_printf("\t---------       ----      -------\n");
        }
 
+       if (browse_host_rpc(sort)) {
+               return True;
+       }
+
        if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1)
                d_printf("Error returning browse list: %s\n", cli_errstr(cli));
 
@@ -3274,7 +3352,7 @@ static int do_message_op(void)
 
        msg_port = port ? port : 139;
 
-       if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, msg_port) != msg_port) ||
+       if (!(cli=cli_initialise()) || (cli_set_port(cli, msg_port) != msg_port) ||
            !cli_connect(cli, server_name, &ip)) {
                d_printf("Connection to %s failed\n", desthost);
                return 1;
@@ -3351,8 +3429,9 @@ static int do_message_op(void)
         /* set default debug level to 0 regardless of what smb.conf sets */
        setup_logging( "smbclient", True );
        DEBUGLEVEL_CLASS[DBGC_ALL] = 1;
-       dbf = x_stderr;
-       x_setbuf( x_stderr, NULL );
+       if ((dbf = x_fdup(x_stderr))) {
+               x_setbuf( dbf, NULL );
+       }
 
        pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 
                                POPT_CONTEXT_KEEP_FIRST);
@@ -3385,6 +3464,9 @@ static int do_message_op(void)
                        }
                        break;
                case 'E':
+                       if (dbf) {
+                               x_fclose(dbf);
+                       }
                        dbf = x_stderr;
                        display_set_stderr();
                        break;