s3:Add a utimes command to smbclient so we can set the Windows times.
authorRichard Sharpe <realrichardsharpe@gmail.com>
Mon, 16 Oct 2017 20:51:51 +0000 (13:51 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 18 Oct 2017 22:55:24 +0000 (00:55 +0200)
Add an update to the smbclient man page.

Signed-off-by: Richard Sharpe <realrichardsharpe@gmail.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
docs-xml/manpages/smbclient.1.xml
source3/client/client.c

index 432f60da78a8c0aca38736e367659eb60149189f..03259828cbc6b997afa61263f223da19f59bacad 100644 (file)
                </para></listitem>
                </varlistentry>
 
+               <varlistentry>
+               <term>utimes &lt;filename&gt; &lt;create time&gt; &lt;access time&gt; &lt;write time&gt; &lt;
+               change time&gt;</term>
+               <listitem><para>Changes the timestamps on a file by name.
+               Times should be specified in the format YY:MM:DD-HH:MM:SS or -1 for no change.
+               </para></listitem>
+               </varlistentry>
+
        </variablelist>
 </refsect1>
 
index 5ef9ad52151427c16f755314d09b993fb014d169..df16496ff86a862d0a223a2fcc51112007c4d5dc 100644 (file)
@@ -4940,6 +4940,126 @@ 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
+ *
+ * Read a filename and four times from the client command line and update
+ * the file times. A value of -1 for a time means don't change.
+ */
+static int cmd_utimes(void)
+{
+       const extern char *cmd_ptr;
+       char *buf;
+       char *fname = NULL;
+       time_t times[4] = {0, 0, 0, 0};
+       int time_count = 0;
+       int err = 0;
+       bool ok;
+       TALLOC_CTX *ctx = talloc_new(NULL);
+       if (ctx == NULL) {
+               return 1;
+       }
+
+       ok = next_token_talloc(ctx, &cmd_ptr, &buf, NULL);
+       if (!ok) {
+               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");
+               err = 1;
+               goto out;
+       }
+
+       fname = talloc_asprintf(ctx,
+                               "%s%s",
+                               client_get_cur_dir(),
+                               buf);
+       if (fname == NULL) {
+               err = 1;
+               goto out;
+       }
+
+       while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL) &&
+               time_count < 4) {
+               const char *s = buf;
+               struct tm tm = {0,};
+               char *ret;
+
+               if (strlen(s) == 2 && strcmp(s, "-1") == 0) {
+                       times[time_count] = 0;
+                       time_count++;
+                       continue;
+               } else {
+                       ret = strptime(s, "%y:%m:%d-%H:%M:%S", &tm);
+               }
+
+               /* We could not match all the chars, so print error */
+               if (ret == NULL || *ret != 0) {
+                       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");
+                       err = 1;
+                       goto out;
+               }
+
+               /* Convert tm to a time_t */
+               times[time_count] = mktime(&tm);
+               time_count++;
+       }
+
+       if (time_count < 4) {
+               d_printf("Insufficient dates: %d\n", time_count);
+               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");
+               err = 1;
+               goto out;
+       }
+
+       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]))));
+
+       set_remote_times(fname, times[0], times[1], times[2], times[3]);
+out:
+       talloc_free(ctx);
+       return err;
+}
+
 /**
  * set_remote_attr - set DOS attributes of a remote file
  * @filename: path to the file name
@@ -5254,6 +5374,8 @@ static struct {
   {"tcon",cmd_tcon,"connect to a share" ,{COMPL_NONE,COMPL_NONE}},
   {"tdis",cmd_tdis,"disconnect from a share",{COMPL_NONE,COMPL_NONE}},
   {"tid",cmd_tid,"show or set the current tid (tree-id)",{COMPL_NONE,COMPL_NONE}},
+  {"utimes", cmd_utimes,"<file name> <create_time> <access_time> <mod_time> "
+       "<ctime> set times", {COMPL_REMOTE,COMPL_NONE}},
   {"logoff",cmd_logoff,"log off (close the session)",{COMPL_NONE,COMPL_NONE}},
   {"..",cmd_cd_oneup,"change the remote directory (up one level)",{COMPL_REMOTE,COMPL_NONE}},