Improved smbclient resume support.

Rex Tsai chihchun at kalug.linux.org.tw
Tue Jun 12 08:34:31 GMT 2001


        Sorry, I'm newbie. :(
        send this again.

        This patch added "reget" "hash" and "tick" commands.
        It's very useful when download big files from internet. :-)

-Rex
Best Regards, <chihchun_at_kalug.linux.org.tw>

--
--- samba-2.0.9.orig/source/client/client.c     Wed Apr 18 07:00:52 2001
+++ samba-2.0.9/source/client/client.c  Mon Jun 11 21:37:16 2001
@@ -49,6 +49,8 @@
 
 static int process_tok(fstring tok);
 static void cmd_help(void);
+static void cmd_hash(void);
+static void cmd_tick(void);
 
 /* 30 second timeout on most commands */
 #define CLIENT_TIMEOUT (30*1000)
@@ -57,6 +59,9 @@
 /* value for unused fid field in trans2 secondary request */
 #define FID_UNUSED (0xFFFF)
 
+#define HASHBYTES 1024
+#define TICKBYTES 10240
+
 time_t newer_than = 0;
 int archive_level = 0;
 
@@ -77,6 +82,8 @@
 mode_t myumask = 0755;
 
 BOOL prompt = True;
+BOOL hash = False;
+BOOL tick = False;
 
 int printmode = 1;
 
@@ -651,6 +658,7 @@
        uint16 attr;
        size_t size;
        off_t nread = 0;
+       off_t hashbytes = HASHBYTES;
 
        GetTimeOfDay(&tp_start);
 
@@ -703,10 +711,29 @@
                        DEBUG(0,("Error writing local file\n"));
                        break;
                }
-      
+                       
+               if (hash) {
+                   while (nread >= hashbytes) {
+                       (void) putchar('#');
+                       hashbytes += HASHBYTES;
+                   }
+                   (void) fflush(stdout);
+               }
+               if (tick && (nread >= hashbytes)) {
+                   printf("\rBytes transferred: %ld", nread);
+                   (void) fflush(stdout);
+                   while (nread >= hashbytes)
+                       hashbytes += TICKBYTES;
+               }
+
                nread += n;
        }
 
+       if (hash || tick) {
+           (void) putchar('\n');
+           (void) fflush(stdout);
+       }
+
        if (nread < size) {
                DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
                rname, (long)nread));
@@ -770,6 +797,198 @@
        do_get(rname, lname);
 }
 
+/****************************************************************************
+  get a file from rname to lname
+  ****************************************************************************/
+static void do_reget(char *rname,char *lname)
+{  
+       int handle=0,fnum;
+       BOOL newhandle = False;
+       char *data;
+       struct timeval tp_start;
+       int read_size = io_bufsize;
+       uint16 attr;
+       size_t size;
+       off_t nread = 0;
+       off_t hashbytes = HASHBYTES;
+
+       GetTimeOfDay(&tp_start);
+
+       if (lowercase) {
+               strlower(lname);
+       }
+
+       fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
+
+       if (fnum == -1) {
+               DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),rname));
+               return;
+       }
+
+       if(!strcmp(lname,"-")) {
+               handle = fileno(stdout);
+       } else {
+           struct stat stbuf;
+           int ret;
+
+           ret = stat(lname, &stbuf);
+           if (ret < 0) {
+               DEBUG(2, ("local: %s: %s\n", lname, strerror(errno)));
+               return;
+           }
+               
+           nread = stbuf.st_size;
+           handle = sys_open(lname, O_RDWR, 0);
+           lseek(handle, (long)nread, 0);
+           newhandle = True;
+       }
+       if (handle < 0) {
+               DEBUG(0,("Error opening local file %s\n",lname));
+               return;
+       }
+
+
+       if (!cli_qfileinfo(cli, fnum, 
+                          &attr, &size, NULL, NULL, NULL, NULL, NULL) &&
+           !cli_getattrE(cli, fnum, 
+                         &attr, &size, NULL, NULL, NULL)) {
+               DEBUG(0,("getattrib: %s\n",cli_errstr(cli)));
+               return;
+       }
+
+       DEBUG(2,("regetting file %s of size %.0f as %s ", 
+                lname, (double)size, lname));
+
+       if(!(data = (char *)malloc(read_size))) { 
+               DEBUG(0,("malloc fail for size %d\n", read_size));
+               cli_close(cli, fnum);
+               return;
+       }
+
+       while (1) {
+               int n = cli_read(cli, fnum, data, nread, read_size);
+
+               if (n <= 0) break;
+ 
+               if (writefile(handle,data, n) != n) {
+                       DEBUG(0,("\nError writing local file: %s\n", strerror(errno)));
+                       break;
+               }
+                       
+               if (hash) {
+                   while (nread >= hashbytes) {
+                       (void) putchar('#');
+                       hashbytes += HASHBYTES;
+                   }
+                   (void) fflush(stdout);
+               }
+               if (tick && (nread >= hashbytes)) {
+                   printf("\rBytes transferred: %ld", nread);
+                   (void) fflush(stdout);
+                   while (nread >= hashbytes)
+                       hashbytes += TICKBYTES;
+               }
+      
+               nread += n;
+       }
+
+       if (hash || tick) {
+           (void) putchar('\n');
+           (void) fflush(stdout);
+       }
+
+       if (nread < size) {
+               DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
+               rname, (long)nread));
+       }
+
+       free(data);
+       
+       if (!cli_close(cli, fnum)) {
+               DEBUG(0,("Error %s closing remote file\n",cli_errstr(cli)));
+       }
+
+       if (newhandle) {
+               close(handle);
+       }
+
+       if (archive_level >= 2 && (attr & aARCH)) {
+               cli_setatr(cli, rname, attr & ~(uint16)aARCH, 0);
+       }
+
+       {
+               struct timeval tp_end;
+               int this_time;
+               
+               GetTimeOfDay(&tp_end);
+               this_time = 
+                       (tp_end.tv_sec - tp_start.tv_sec)*1000 +
+                       (tp_end.tv_usec - tp_start.tv_usec)/1000;
+               get_total_time_ms += this_time;
+               get_total_size += nread;
+               
+               DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
+                        nread / (1.024*this_time + 1.0e-4),
+                        get_total_size / (1.024*get_total_time_ms)));
+       }
+}
+
+
+/****************************************************************************
+  get file restarting at end of local file
+  ****************************************************************************/
+static void cmd_reget(void)
+{
+       pstring lname;
+       pstring rname;
+       char *p;
+
+       pstrcpy(rname,cur_dir);
+       pstrcat(rname,"\\");
+       
+       p = rname + strlen(rname);
+       
+       if (!next_token(NULL,p,NULL,sizeof(rname)-strlen(rname))) {
+               DEBUG(0,("reget <filename>\n"));
+               return;
+       }
+       pstrcpy(lname,p);
+       dos_clean_name(rname);
+       
+       next_token(NULL,lname,NULL,sizeof(lname));
+       
+       do_reget(rname, lname);
+}
+
+/****************************************************************************
+ toggle hash mark printing during transfers.
+ ****************************************************************************/
+static void cmd_hash(void)
+{
+    hash = !hash;
+    if (hash && tick)
+       cmd_tick();
+
+    DEBUG(2,("Hash mark printint %s", hash ? "on" : "off" ));
+    if (hash)
+       DEBUG(2,(" (%d bytes/hash mark)", HASHBYTES));
+    DEBUG(2,("\n"));
+}
+
+/****************************************************************************
+ toggle printing byte counter during transfers
+ ****************************************************************************/
+static void cmd_tick(void)
+{
+    tick = !tick;
+    if (hash && tick)
+       cmd_hash();
+
+    DEBUG(2, ("Tick counter printing %s", tick ? "on" : "off"));
+    if (tick)
+       DEBUG(2,(" (%d bytes/tick increment)", TICKBYTES));
+    DEBUG(2,("\n"));
+}
 
 /****************************************************************************
   do a mget operation on one file
@@ -988,6 +1207,7 @@
        int fnum;
        FILE *f;
        int nread=0;
+       int hashbytes = HASHBYTES;
        char *buf=NULL;
        int maxwrite=io_bufsize;
        
@@ -1039,9 +1259,28 @@
                        break;
                } 
 
+               if (hash) {
+                   while (nread >= hashbytes) {
+                       (void) putchar('#');
+                       hashbytes += HASHBYTES;
+                   }
+                   (void) fflush(stdout);
+               }
+               if (tick && (nread >= hashbytes)) {
+                   printf("\rBytes transferred: %ld", nread);
+                   (void) fflush(stdout);
+                   while (nread >= hashbytes)
+                       hashbytes += TICKBYTES;
+               }
+
                nread += n;
        }
 
+       if (hash || tick) {
+           (void) putchar('\n');
+           (void) fflush(stdout);
+       }
+
        if (!cli_close(cli, fnum)) {
                DEBUG(0,("%s closing remote file %s\n",cli_errstr(cli),rname));
                fclose(f);
@@ -1658,6 +1897,9 @@
   {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},
   {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)",{COMPL_NONE,COMPL_NONE}},
   {"get",cmd_get,"<remote name> [local name] get a file",{COMPL_REMOTE,COMPL_LOCAL}},
+  {"reget",cmd_reget,"get file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}},
+  {"hash",cmd_hash,"toggle printing `#' for each buffer transferred",{COMPL_REMOTE,COMPL_LOCAL}},
+  {"tick",cmd_tick,"toggle printing byte counter during transfers",{COMPL_REMOTE,COMPL_LOCAL}},
   {"mget",cmd_mget,"<mask> get all the matching files",{COMPL_REMOTE,COMPL_NONE}},
   {"put",cmd_put,"<local name> [remote name] put a file",{COMPL_LOCAL,COMPL_REMOTE}},
   {"mput",cmd_mput,"<mask> put all matching files",{COMPL_REMOTE,COMPL_NONE}},






More information about the samba-technical mailing list