s3: libsmb: In struct file_info rename mode -> attr.
[samba.git] / source3 / client / client.c
index e1de711c8e4ced4b438f608e23d7246ddef28a7b..362fd2cc08ba6ea8403cccd185256f5cf2e4c8e3 100644 (file)
@@ -39,6 +39,7 @@
 #include "libsmb/nmblib.h"
 #include "include/ntioctl.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "lib/util/time_basic.h"
 
 #ifndef REGISTER
 #define REGISTER 0
@@ -65,8 +66,6 @@ static int max_protocol = -1;
 static int process_tok(char *tok);
 static int cmd_help(void);
 
-#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
-
 /* value for unused fid field in trans2 secondary request */
 #define FID_UNUSED (0xFFFF)
 
@@ -538,7 +537,7 @@ static bool do_this_one(struct file_info *finfo)
                return false;
        }
 
-       if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
+       if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
                return true;
        }
 
@@ -553,7 +552,7 @@ static bool do_this_one(struct file_info *finfo)
                return false;
        }
 
-       if ((archive_level==1 || archive_level==2) && !(finfo->mode & FILE_ATTRIBUTE_ARCHIVE)) {
+       if ((archive_level==1 || archive_level==2) && !(finfo->attr & FILE_ATTRIBUTE_ARCHIVE)) {
                DEBUG(3,("archive %s failed\n", finfo->name));
                return false;
        }
@@ -580,7 +579,7 @@ static NTSTATUS display_finfo(struct cli_state *cli_state, struct file_info *fin
        if (!showacls) {
                d_printf("  %-30s%7.7s %8.0f  %s",
                         finfo->name,
-                        attrib_string(talloc_tos(), finfo->mode),
+                        attrib_string(talloc_tos(), finfo->attr),
                        (double)finfo->size,
                        time_to_asc(t));
                dir_total += finfo->size;
@@ -602,13 +601,22 @@ static NTSTATUS display_finfo(struct cli_state *cli_state, struct file_info *fin
                }
                /* print file meta date header */
                d_printf( "FILENAME:%s\n", finfo->name);
-               d_printf( "MODE:%s\n", attrib_string(talloc_tos(), finfo->mode));
+               d_printf( "MODE:%s\n", attrib_string(talloc_tos(), finfo->attr));
                d_printf( "SIZE:%.0f\n", (double)finfo->size);
                d_printf( "MTIME:%s", time_to_asc(t));
-               status = cli_ntcreate(cli_state, afname, 0,
-                                     CREATE_ACCESS_READ, 0,
-                                     FILE_SHARE_READ|FILE_SHARE_WRITE,
-                                     FILE_OPEN, 0x0, 0x0, &fnum, NULL);
+               status = cli_ntcreate(
+                       cli_state,            /* cli */
+                       afname,               /* fname */
+                       0,                    /* CreatFlags */
+                       READ_CONTROL_ACCESS,  /* DesiredAccess */
+                       0,                    /* FileAttributes */
+                       FILE_SHARE_READ|
+                       FILE_SHARE_WRITE,     /* ShareAccess */
+                       FILE_OPEN,            /* CreateDisposition */
+                       0x0,                  /* CreateOptions */
+                       0x0,                  /* SecurityFlags */
+                       &fnum,                /* pfid */
+                       NULL);                /* cr */
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
                                   afname, nt_errstr(status)));
@@ -785,7 +793,7 @@ static NTSTATUS do_list_helper(const char *mntpoint, struct file_info *f,
                *dir_end = '\0';
        }
 
-       if (f->mode & FILE_ATTRIBUTE_DIRECTORY) {
+       if (f->attr & FILE_ATTRIBUTE_DIRECTORY) {
                if (do_list_dirs && do_this_one(f)) {
                        status = do_list_fn(cli_state, f, dir);
                        if (!NT_STATUS_IS_OK(status)) {
@@ -1300,7 +1308,7 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
+       if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
                if (asprintf(&quest,
                         "Get directory %s? ",finfo->name) < 0) {
                        return NT_STATUS_NO_MEMORY;
@@ -1318,7 +1326,7 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo,
        }
        SAFE_FREE(quest);
 
-       if (!(finfo->mode & FILE_ATTRIBUTE_DIRECTORY)) {
+       if (!(finfo->attr & FILE_ATTRIBUTE_DIRECTORY)) {
                rname = talloc_asprintf(ctx,
                                "%s%s",
                                client_get_cur_dir(),
@@ -1812,16 +1820,16 @@ static int do_allinfo(const char *name)
                return false;
        }
 
-       tmp = unix_timespec_to_nt_time(b_time);
+       tmp = full_timespec_to_nt_time(&b_time);
        d_printf("create_time:    %s\n", nt_time_string(talloc_tos(), tmp));
 
-       tmp = unix_timespec_to_nt_time(a_time);
+       tmp = full_timespec_to_nt_time(&a_time);
        d_printf("access_time:    %s\n", nt_time_string(talloc_tos(), tmp));
 
-       tmp = unix_timespec_to_nt_time(m_time);
+       tmp = full_timespec_to_nt_time(&m_time);
        d_printf("write_time:     %s\n", nt_time_string(talloc_tos(), tmp));
 
-       tmp = unix_timespec_to_nt_time(c_time);
+       tmp = full_timespec_to_nt_time(&c_time);
        d_printf("change_time:    %s\n", nt_time_string(talloc_tos(), tmp));
 
        d_printf("attributes: %s (%x)\n", attr_str(talloc_tos(), mode), mode);
@@ -2503,7 +2511,7 @@ static NTSTATUS do_del(struct cli_state *cli_state, struct file_info *finfo,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
+       if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
                TALLOC_FREE(mask);
                return NT_STATUS_OK;
        }
@@ -2633,7 +2641,7 @@ static NTSTATUS do_deltree_list(struct cli_state *cli_state,
                return NT_STATUS_NO_MEMORY;
        }
 
-       if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
+       if (finfo->attr & FILE_ATTRIBUTE_DIRECTORY) {
                dt->isdir = true;
        }
 
@@ -3813,7 +3821,7 @@ static int cmd_getfacl(void)
        }
 
        status = cli_posix_stat(targetcli, targetname, &sbuf);
-       if (!NT_STATUS_IS_OK(cli_posix_stat(targetcli, targetname, &sbuf))) {
+       if (!NT_STATUS_IS_OK(status)) {
                d_printf("%s getfacl doing a stat on file %s\n",
                         nt_errstr(status), src);
                return 1;
@@ -4914,10 +4922,6 @@ static bool browse_host(bool sort)
                return true;
        }
 
-       if (lp_client_min_protocol() > PROTOCOL_NT1) {
-               return false;
-       }
-
        if (smbXcli_conn_protocol(cli->conn) > PROTOCOL_NT1) {
                return false;
        }
@@ -5179,35 +5183,6 @@ static int cmd_show_connect( void )
        return 0;
 }
 
-/**
- * set_remote_times - set times of a remote file
- * @filename: path to the file name
- * @create_time: New create time
- * @access_time: New access time
- * @write_time: New write time
- * @change_time: New metadata change time
- *
- * Update the file times with the ones provided.
- */
-static int set_remote_times(const char *filename, time_t create_time,
-                       time_t access_time, time_t write_time,
-                       time_t change_time)
-{
-       extern struct cli_state *cli;
-       NTSTATUS status;
-
-       status = cli_setpathinfo_basic(cli, filename, create_time,
-                                       access_time, write_time,
-                                       change_time, -1);
-       if (!NT_STATUS_IS_OK(status)) {
-               d_printf("cli_setpathinfo_basic failed: %s\n",
-                        nt_errstr(status));
-               return 1;
-       }
-
-       return 0;
-}
-
 /**
  * cmd_utimes - interactive command to set the four times
  *
@@ -5216,14 +5191,16 @@ static int set_remote_times(const char *filename, time_t create_time,
  */
 static int cmd_utimes(void)
 {
-       const extern char *cmd_ptr;
        char *buf;
        char *fname = NULL;
-       time_t times[4] = {0, 0, 0, 0};
+       struct timespec times[4] = {{0}};
+       struct timeval_buf tbuf[4];
        int time_count = 0;
        int err = 0;
        bool ok;
        TALLOC_CTX *ctx = talloc_new(NULL);
+       NTSTATUS status;
+
        if (ctx == NULL) {
                return 1;
        }
@@ -5256,14 +5233,19 @@ static int cmd_utimes(void)
                time_count < 4) {
                const char *s = buf;
                struct tm tm = {0,};
+               time_t t;
                char *ret;
 
                if (strlen(s) == 2 && strcmp(s, "-1") == 0) {
-                       times[time_count] = 0;
+                       times[time_count] = make_omit_timespec();
                        time_count++;
                        continue;
-               } else {
-                       ret = strptime(s, "%y:%m:%d-%H:%M:%S", &tm);
+               }
+
+               ret = strptime(s, "%y:%m:%d-%H:%M:%S", &tm);
+
+               if (ret == NULL) {
+                       ret = strptime(s, "%Y:%m:%d-%H:%M:%S", &tm);
                }
 
                /* We could not match all the chars, so print error */
@@ -5271,14 +5253,15 @@ static int cmd_utimes(void)
                        d_printf("Invalid date format: %s\n", s);
                        d_printf("utimes <filename> <create-time> "
                                "<access-time> <write-time> <change-time>\n");
-                       d_printf("Dates should be in YY:MM:DD-HH:MM:SS format "
-                               "or -1 for no change\n");
+                       d_printf("Dates should be in [YY]YY:MM:DD-HH:MM:SS "
+                                "format or -1 for no change\n");
                        err = 1;
                        goto out;
                }
 
                /* Convert tm to a time_t */
-               times[time_count] = mktime(&tm);
+               t = mktime(&tm);
+               times[time_count] = (struct timespec){.tv_sec = t};
                time_count++;
        }
 
@@ -5293,12 +5276,19 @@ static int cmd_utimes(void)
        }
 
        DEBUG(10, ("times\nCreate: %sAccess: %s Write: %sChange: %s\n",
-               talloc_strdup(ctx, ctime(&times[0])),
-               talloc_strdup(ctx, ctime(&times[1])),
-               talloc_strdup(ctx, ctime(&times[2])),
-               talloc_strdup(ctx, ctime(&times[3]))));
+                  timespec_string_buf(&times[0], false, &tbuf[0]),
+                  timespec_string_buf(&times[1], false, &tbuf[1]),
+                  timespec_string_buf(&times[2], false, &tbuf[2]),
+                  timespec_string_buf(&times[3], false, &tbuf[3])));
 
-       set_remote_times(fname, times[0], times[1], times[2], times[3]);
+       status = cli_setpathinfo_ext(
+               cli, fname, times[0], times[1], times[2], times[3], -1);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("cli_setpathinfo_ext failed: %s\n",
+                        nt_errstr(status));
+               err = 1;
+               goto out;
+       }
 out:
        talloc_free(ctx);
        return err;
@@ -5347,7 +5337,6 @@ int set_remote_attr(const char *filename, uint16_t new_attr, int mode)
  */
 int cmd_setmode(void)
 {
-       const extern char *cmd_ptr;
        char *buf;
        char *fname = NULL;
        uint16_t attr[2] = {0};
@@ -5609,7 +5598,7 @@ static struct {
   {"scopy",cmd_scopy,"<src> <dest> server-side copy file",{COMPL_REMOTE,COMPL_REMOTE}},
   {"stat",cmd_stat,"<file name> Do a UNIX extensions stat call on a file",{COMPL_REMOTE,COMPL_NONE}},
   {"symlink",cmd_symlink,"<oldname> <newname> create a UNIX symlink",{COMPL_REMOTE,COMPL_REMOTE}},
-  {"tar",cmd_tar,"tar <c|x>[IXFqbgNan] current directory to/from <file name>",{COMPL_NONE,COMPL_NONE}},
+  {"tar",cmd_tar,"tar <c|x>[IXFvbgNan] 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}},
   {"timeout",cmd_timeout,"timeout <number> - set the per-operation timeout in seconds (default 20)",{COMPL_NONE,COMPL_NONE}},
   {"translate",cmd_translate,"toggle text translation for printing",{COMPL_NONE,COMPL_NONE}},
@@ -5709,10 +5698,12 @@ static int process_command_string(const char *cmd_in)
                NTSTATUS status;
 
                status = cli_cm_open(talloc_tos(), NULL,
-                                    have_ip ? dest_ss_str : desthost,
+                                    desthost,
                                     service, popt_get_cmdline_auth_info(),
                                     smb_encrypt,
-                                    max_protocol, port, name_type,
+                                    max_protocol,
+                                    have_ip ? &dest_ss : NULL, port,
+                                    name_type,
                                     &cli);
                if (!NT_STATUS_IS_OK(status)) {
                        return 1;
@@ -5780,7 +5771,7 @@ static NTSTATUS completion_remote_filter(const char *mnt,
                return NT_STATUS_OK;
        }
 
-       if ((info->dirmask[0] == 0) && !(f->mode & FILE_ATTRIBUTE_DIRECTORY))
+       if ((info->dirmask[0] == 0) && !(f->attr & FILE_ATTRIBUTE_DIRECTORY))
                info->matches[info->count] = SMB_STRDUP(f->name);
        else {
                TALLOC_CTX *ctx = talloc_stackframe();
@@ -5796,7 +5787,7 @@ static NTSTATUS completion_remote_filter(const char *mnt,
                        TALLOC_FREE(ctx);
                        return NT_STATUS_NO_MEMORY;
                }
-               if (f->mode & FILE_ATTRIBUTE_DIRECTORY) {
+               if (f->attr & FILE_ATTRIBUTE_DIRECTORY) {
                        tmp = talloc_asprintf_append(tmp, "%s",
                                                     CLI_DIRSEP_STR);
                }
@@ -5810,7 +5801,7 @@ static NTSTATUS completion_remote_filter(const char *mnt,
        if (info->matches[info->count] == NULL) {
                return NT_STATUS_OK;
        }
-       if (f->mode & FILE_ATTRIBUTE_DIRECTORY) {
+       if (f->attr & FILE_ATTRIBUTE_DIRECTORY) {
                smb_readline_ca_char(0);
        }
        if (info->count == 1) {
@@ -6152,9 +6143,10 @@ static int process(const char *base_directory)
        NTSTATUS status;
 
        status = cli_cm_open(talloc_tos(), NULL,
-                            have_ip ? dest_ss_str : desthost,
+                            desthost,
                             service, popt_get_cmdline_auth_info(),
-                            smb_encrypt, max_protocol, port,
+                            smb_encrypt, max_protocol,
+                            have_ip ? &dest_ss : NULL, port,
                             name_type, &cli);
        if (!NT_STATUS_IS_OK(status)) {
                return 1;
@@ -6189,9 +6181,10 @@ static int do_host_query(const char *query_host)
        NTSTATUS status;
 
        status = cli_cm_open(talloc_tos(), NULL,
-                            have_ip ? dest_ss_str : query_host,
+                            query_host,
                             "IPC$", popt_get_cmdline_auth_info(),
-                            smb_encrypt, max_protocol, port,
+                            smb_encrypt, max_protocol,
+                            have_ip ? &dest_ss : NULL, port,
                             name_type, &cli);
        if (!NT_STATUS_IS_OK(status)) {
                return 1;
@@ -6235,10 +6228,11 @@ static int do_host_query(const char *query_host)
                cli_shutdown(cli);
                d_printf("Reconnecting with SMB1 for workgroup listing.\n");
                status = cli_cm_open(talloc_tos(), NULL,
-                                    have_ip ? dest_ss_str : query_host,
+                                    query_host,
                                     "IPC$", popt_get_cmdline_auth_info(),
                                     smb_encrypt, max_proto,
-                                    NBT_SMB_PORT, name_type, &cli);
+                                    have_ip ? &dest_ss : NULL, NBT_SMB_PORT,
+                                    name_type, &cli);
                if (!NT_STATUS_IS_OK(status)) {
                        d_printf("Unable to connect with SMB1 "
                                 "-- no workgroup available\n");
@@ -6268,10 +6262,11 @@ static int do_tar_op(const char *base_directory)
                NTSTATUS status;
 
                status = cli_cm_open(talloc_tos(), NULL,
-                                    have_ip ? dest_ss_str : desthost,
+                                    desthost,
                                     service, popt_get_cmdline_auth_info(),
                                     smb_encrypt, max_protocol,
-                                    port, name_type, &cli);
+                                    have_ip ? &dest_ss : NULL, port,
+                                    name_type, &cli);
                if (!NT_STATUS_IS_OK(status)) {
             ret = 1;
             goto out;
@@ -6406,7 +6401,7 @@ int main(int argc,char *argv[])
                        .arg        = NULL,
                        .val        = 'T',
                        .descrip    = "Command line tar",
-                       .argDescrip = "<c|x>IXFqgbNan",
+                       .argDescrip = "<c|x>IXFvgbNan",
                },
                {
                        .longName   = "directory",
@@ -6502,7 +6497,10 @@ int main(int argc,char *argv[])
 
        while ((opt = poptGetNextOpt(pc)) != -1) {
 
-               /* if the tar option has been called previouslt, now we need to eat out the leftovers */
+               /*
+                * if the tar option has been called previously, now
+                * we need to eat out the leftovers
+                */
                /* I see no other way to keep things sane --SSS */
                if (tar_opt == true) {
                        while (poptPeekArg(pc)) {