r25026: Move param/param.h out of includes.h
[kai/samba-autobuild/.git] / source4 / client / client.c
index 2f03ca09727a8407a16bd86eef9bb505175bfa6f..eaa8fe48a0dd5703604320452d4de31b7759d84e 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,
    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"
 #include "version.h"
 #include "libcli/libcli.h"
 #include "lib/cmdline/popt_common.h"
-#include "librpc/gen_ndr/ndr_srvsvc.h"
 #include "librpc/gen_ndr/ndr_srvsvc_c.h"
 #include "librpc/gen_ndr/ndr_lsa.h"
+#include "librpc/gen_ndr/ndr_security.h"
 #include "libcli/raw/libcliraw.h"
 #include "libcli/util/clilsa.h"
 #include "system/dir.h"
 #include "system/filesys.h"
-#include "dlinklist.h"
+#include "lib/util/dlinklist.h"
 #include "system/readline.h"
+#include "auth/credentials/credentials.h"
 #include "auth/gensec/gensec.h"
 #include "system/time.h" /* needed by some systems for asctime() */
 #include "libcli/resolve/resolve.h"
-#include "libcli/security/proto.h"
-#include "lib/replace/readline.h"
+#include "libcli/security/security.h"
+#include "lib/smbreadline/smbreadline.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
-#include "librpc/gen_ndr/ndr_security.h"
+#include "param/param.h"
 
 static int io_bufsize = 64512;
 
@@ -287,9 +287,9 @@ BOOL mask_match(struct smbcli_state *c, const char *string, const char *pattern,
        char *p2, *s2;
        BOOL ret;
 
-       if (strcmp(string,"..") == 0)
+       if (ISDOTDOT(string))
                string = ".";
-       if (strcmp(pattern,".") == 0)
+       if (ISDOT(pattern))
                return False;
        
        if (is_case_sensitive)
@@ -409,11 +409,13 @@ static void init_do_list_queue(void)
 
 static void adjust_do_list_queue(void)
 {
+       if (do_list_queue == NULL) return;
+
        /*
         * 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_start == do_list_queue_end)
        {
                DEBUG(4,("do_list_queue is empty\n"));
                do_list_queue_start = do_list_queue_end = 0;
@@ -496,8 +498,8 @@ static void do_list_helper(struct clilist_file_info *f, const char *mask, void *
                        do_list_fn(ctx, f);
                }
                if (do_list_recurse && 
-                   !strequal(f->name,".") && 
-                   !strequal(f->name,"..")) {
+                   !ISDOT(f->name) &&
+                   !ISDOTDOT(f->name)) {
                        char *mask2;
                        char *p;
 
@@ -837,7 +839,7 @@ static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *fin
        char *mget_mask;
        char *saved_curdir;
 
-       if (strequal(finfo->name,".") || strequal(finfo->name,".."))
+       if (ISDOT(finfo->name) || ISDOTDOT(finfo->name))
                return;
 
        if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY)
@@ -934,7 +936,7 @@ do a mget command
 static int cmd_mget(struct smbclient_context *ctx, const char **args)
 {
        uint16_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
-       char *mget_mask;
+       char *mget_mask = NULL;
        int i;
 
        if (ctx->recurse)
@@ -949,14 +951,15 @@ static int cmd_mget(struct smbclient_context *ctx, const char **args)
                if (mget_mask[0] != '\\')
                        mget_mask = talloc_append_string(ctx, mget_mask, "\\");
                do_list(ctx, mget_mask, attribute,do_mget,False,True);
+
+               talloc_free(mget_mask);
        }
 
-       if (!*mget_mask) {
+       if (mget_mask == NULL) {
                mget_mask = talloc_asprintf(ctx, "%s\\*", ctx->remote_cur_dir);
                do_list(ctx, mget_mask, attribute,do_mget,False,True);
+               talloc_free(mget_mask);
        }
-
-       talloc_free(mget_mask);
        
        return 0;
 }
@@ -1192,16 +1195,16 @@ static int cmd_put(struct smbclient_context *ctx, const char **args)
        char *rname;
        
        if (!args[1]) {
-               d_printf("put <filename>\n");
+               d_printf("put <filename> [<remotename>]\n");
                return 1;
        }
 
-       lname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, args[1]);
+       lname = talloc_strdup(ctx, args[1]);
   
        if (args[2])
                rname = talloc_strdup(ctx, args[2]);
        else
-               rname = talloc_strdup(ctx, lname);
+               rname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, lname);
        
        dos_clean_name(rname);
 
@@ -1326,8 +1329,9 @@ static int file_find(struct smbclient_context *ctx, struct file_list **list, con
        if (!dir) return -1;
        
         while ((dname = readdirname(dir))) {
-               if (!strcmp("..", dname)) continue;
-               if (!strcmp(".", dname)) continue;
+               if (ISDOT(dname) || ISDOTDOT(dname)) {
+                       continue;
+               }
                
                if (asprintf(&path, "%s/%s", directory, dname) <= 0) {
                        continue;
@@ -1700,11 +1704,11 @@ static int cmd_fsinfo(struct smbclient_context *ctx, const char **args)
                         GUID_string(ctx,&fsinfo.objectid_information.out.guid));
                d_printf("\tunknown[6]:                 [%llu,%llu,%llu,%llu,%llu,%llu]\n", 
                         (unsigned long long) fsinfo.objectid_information.out.unknown[0],
+                        (unsigned long long) fsinfo.objectid_information.out.unknown[1],
                         (unsigned long long) fsinfo.objectid_information.out.unknown[2],
                         (unsigned long long) fsinfo.objectid_information.out.unknown[3],
                         (unsigned long long) fsinfo.objectid_information.out.unknown[4],
-                        (unsigned long long) fsinfo.objectid_information.out.unknown[5],
-                        (unsigned long long) fsinfo.objectid_information.out.unknown[6] );
+                        (unsigned long long) fsinfo.objectid_information.out.unknown[5] );
                break;
        case RAW_QFS_GENERIC:
                d_printf("\twrong level returned\n");
@@ -1722,6 +1726,7 @@ static int cmd_allinfo(struct smbclient_context *ctx, const char **args)
        char *fname;
        union smb_fileinfo finfo;
        NTSTATUS status;
+       int fnum;
 
        if (!args[1]) {
                d_printf("allinfo <filename>\n");
@@ -1805,6 +1810,41 @@ static int cmd_allinfo(struct smbclient_context *ctx, const char **args)
                d_printf("\tcluster_shift   %ld\n", (long)finfo.compression_info.out.cluster_shift);
        }
 
+       /* shadow copies if available */
+       fnum = smbcli_open(ctx->cli->tree, fname, O_RDONLY, DENY_NONE);
+       if (fnum != -1) {
+               struct smb_shadow_copy info;
+               int i;
+               info.in.file.fnum = fnum;
+               info.in.max_data = ~0;
+               status = smb_raw_shadow_data(ctx->cli->tree, ctx, &info);
+               if (NT_STATUS_IS_OK(status)) {
+                       d_printf("\tshadow_copy: %u volumes  %u names\n",
+                                info.out.num_volumes, info.out.num_names);
+                       for (i=0;i<info.out.num_names;i++) {
+                               d_printf("\t%s\n", info.out.names[i]);
+                               finfo.generic.level = RAW_FILEINFO_ALL_INFO;
+                               finfo.generic.in.file.path = talloc_asprintf(ctx, "%s%s", 
+                                                                            info.out.names[i], fname); 
+                               status = smb_raw_pathinfo(ctx->cli->tree, ctx, &finfo);
+                               if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
+                                   NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
+                                       continue;
+                               }
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       d_printf("%s - %s\n", finfo.generic.in.file.path, 
+                                                nt_errstr(status));
+                                       return 1;
+                               }
+                               
+                               d_printf("\t\tcreate_time:    %s\n", nt_time_string(ctx, finfo.all_info.out.create_time));
+                               d_printf("\t\twrite_time:     %s\n", nt_time_string(ctx, finfo.all_info.out.write_time));
+                               d_printf("\t\tchange_time:    %s\n", nt_time_string(ctx, finfo.all_info.out.change_time));
+                               d_printf("\t\tsize:           %lu\n", (unsigned long)finfo.all_info.out.size);
+                       }
+               }
+       }
+       
        return 0;
 }
 
@@ -2184,7 +2224,7 @@ static int cmd_chmod(struct smbclient_context *ctx, const char **args)
 
        if (NT_STATUS_IS_ERR(smbcli_unix_chmod(ctx->cli->tree, src, mode))) {
                d_printf("%s chmod file %s 0%o\n",
-                       smbcli_errstr(ctx->cli->tree), src, (uint_t)mode);
+                       smbcli_errstr(ctx->cli->tree), src, (mode_t)mode);
                return 1;
        } 
 
@@ -2385,7 +2425,7 @@ history
 ****************************************************************************/
 static int cmd_history(struct smbclient_context *ctx, const char **args)
 {
-#if defined(HAVE_LIBREADLINE)
+#if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
        HIST_ENTRY **hlist;
        int i;
 
@@ -2509,7 +2549,7 @@ static BOOL browse_host(const char *query_host)
        binding = talloc_asprintf(mem_ctx, "ncacn_np:%s", query_host);
 
        status = dcerpc_pipe_connect(mem_ctx, &p, binding, 
-                                        &dcerpc_table_srvsvc,
+                                        &ndr_table_srvsvc,
                                     cmdline_credentials, NULL);
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Failed to connect to %s - %s\n", 
@@ -2724,7 +2764,7 @@ static void completion_remote_filter(struct clilist_file_info *f, const char *ma
 {
        completion_remote_t *info = (completion_remote_t *)state;
 
-       if ((info->count < MAX_COMPLETIONS - 1) && (strncmp(info->text, f->name, info->len) == 0) && (strcmp(f->name, ".") != 0) && (strcmp(f->name, "..") != 0)) {
+       if ((info->count < MAX_COMPLETIONS - 1) && (strncmp(info->text, f->name, info->len) == 0) && (!ISDOT(f->name)) && (!ISDOTDOT(f->name))) {
                if ((info->dirmask[0] == 0) && !(f->attrib & FILE_ATTRIBUTE_DIRECTORY))
                        info->matches[info->count] = strdup(f->name);
                else {
@@ -2883,9 +2923,10 @@ static char **completion_fn(const char *text, int start, int end)
                return matches;
 
 cleanup:
-               while (i >= 0) {
-                       free(matches[i]);
-                       i--;
+               count--;
+               while (count >= 0) {
+                       free(matches[count]);
+                       count--;
                }
                free(matches);
                return NULL;
@@ -2967,25 +3008,31 @@ static int process_stdin(struct smbclient_context *ctx)
 return a connection to a server
 *******************************************************/
 static struct smbclient_context *do_connect(TALLOC_CTX *mem_ctx, 
-                                      const char *server, const char *share, struct cli_credentials *cred)
+                                      const char *specified_server, const char *specified_share, struct cli_credentials *cred)
 {
        NTSTATUS status;
        struct smbclient_context *ctx = talloc_zero(mem_ctx, struct smbclient_context);
+       char *server, *share;
+
        if (!ctx) {
                return NULL;
        }
 
        rl_ctx = ctx; /* Ugly hack */
 
-       if (strncmp(share, "\\\\", 2) == 0 ||
-           strncmp(share, "//", 2) == 0) {
-               smbcli_parse_unc(share, ctx, &server, &share);
+       if (strncmp(specified_share, "\\\\", 2) == 0 ||
+           strncmp(specified_share, "//", 2) == 0) {
+               smbcli_parse_unc(specified_share, ctx, &server, &share);
+       } else {
+               share = talloc_strdup(ctx, specified_share);
+               server = talloc_strdup(ctx, specified_server);
        }
 
        ctx->remote_cur_dir = talloc_strdup(ctx, "\\");
        
        status = smbcli_full_connection(ctx, &ctx->cli, server,
-                                       share, NULL, cred, NULL);
+                                       share, NULL, cred, 
+                                       cli_credentials_get_event_context(cred));
        if (!NT_STATUS_IS_OK(status)) {
                d_printf("Connection to \\\\%s\\%s failed - %s\n", 
                         server, share, nt_errstr(status));
@@ -2999,10 +3046,10 @@ static struct smbclient_context *do_connect(TALLOC_CTX *mem_ctx,
 /****************************************************************************
 handle a -L query
 ****************************************************************************/
-static int do_host_query(const char *query_host)
+static int do_host_query(const char *query_host, const char *workgroup)
 {
        browse_host(query_host);
-       list_servers(lp_workgroup());
+       list_servers(workgroup);
        return(0);
 }
 
@@ -3046,11 +3093,11 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
  int main(int argc,char *argv[])
 {
        const char *base_directory = NULL;
-       const char *dest_ip;
+       const char *dest_ip = NULL;
        int opt;
        const char *query_host = NULL;
        BOOL message = False;
-       const char *desthost;
+       const char *desthost = NULL;
 #ifdef KANJI
        const char *term_code = KANJI;
 #else
@@ -3082,7 +3129,7 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
                POPT_COMMON_CONNECTION
                POPT_COMMON_CREDENTIALS
                POPT_COMMON_VERSION
-               POPT_TABLEEND
+               { NULL }
        };
        
        mem_ctx = talloc_init("client.c/main");
@@ -3163,7 +3210,7 @@ static int do_message_op(const char *desthost, const char *destip, int name_type
        }
   
        if (query_host) {
-               return do_host_query(query_host);
+               return do_host_query(query_host, lp_workgroup());
        }
 
        if (message) {