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