diff options
-rw-r--r-- | source/client/client.c | 100 | ||||
-rw-r--r-- | source/client/clitar.c | 46 |
2 files changed, 141 insertions, 5 deletions
diff --git a/source/client/client.c b/source/client/client.c index 684a2502b54..b9b146fc94d 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -477,6 +477,17 @@ static void display_finfo(file_info *finfo) /**************************************************************************** + calculate size of a file + ****************************************************************************/ +static void do_du(file_info *finfo) +{ + if (do_this_one(finfo)) { + dir_total += finfo->size; + } +} + + +/**************************************************************************** do a directory listing, calling fn on each file found. Use the TRANSACT2 call for long filenames ****************************************************************************/ @@ -1056,6 +1067,38 @@ static void cmd_dir(char *inbuf,char *outbuf) } +/**************************************************************************** + get a directory listing + ****************************************************************************/ +static void cmd_du(char *inbuf,char *outbuf) +{ + int attribute = aDIR | aSYSTEM | aHIDDEN; + pstring mask; + fstring buf; + char *p=buf; + + dir_total = 0; + pstrcpy(mask,cur_dir); + if(mask[strlen(mask)-1]!='\\') + pstrcat(mask,"\\"); + + if (next_token(NULL,buf,NULL,sizeof(buf))) + { + if (*p == '\\') + pstrcpy(mask,p); + else + pstrcat(mask,p); + } + else { + pstrcat(mask,"*"); + } + + do_dir(inbuf,outbuf,mask,attribute,do_du,recurse,False); + + do_dskattr(); + + DEBUG(0, ("Total number of bytes: %d\n", dir_total)); +} /**************************************************************************** get a file from rname to lname @@ -3226,6 +3269,7 @@ struct { {"ls",cmd_dir,"<mask> list the contents of the current directory",COMPL_REMOTE}, {"dir",cmd_dir,"<mask> list the contents of the current directory",COMPL_REMOTE}, + {"du",cmd_du,"<mask> computes the total size of the current directory",COMPL_REMOTE}, {"lcd",cmd_lcd,"[directory] change/report the local current working directory",COMPL_LOCAL}, {"cd",cmd_cd,"[directory] change/report the remote directory",COMPL_REMOTE}, {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)"}, @@ -3257,7 +3301,7 @@ struct {"exit",cli_send_logout,"logoff the server"}, {"newer",cmd_newer,"<file> only mget files newer than the specified local file",COMPL_LOCAL}, {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit"}, - {"tar",cmd_tar,"tar <c|x>[IXbgNa] current directory to/from <file name>" }, + {"tar",cmd_tar,"tar <c|x>[IXbgNan] current directory to/from <file name>" }, {"blocksize",cmd_block,"blocksize <number> (default 20)" }, {"tarmode",cmd_tarmode, "<full|inc|reset|noreset> tar's behaviour towards archive bits" }, @@ -3694,7 +3738,7 @@ static void usage(char *pname) DEBUG(0,("\t-W workgroup set the workgroup name\n")); DEBUG(0,("\t-c command string execute semicolon separated commands\n")); DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n")); - DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n")); + DEBUG(0,("\t-T<c|x>IXgbNan command line tar\n")); DEBUG(0,("\t-D directory start from directory\n")); DEBUG(0,("\n")); } @@ -3791,6 +3835,58 @@ static void usage(char *pname) got_pass = True; } + if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) { + int fd = -1; + BOOL close_it; + pstring spec; + char pass[128]; + char *p; + if ((p = getenv("PASSWD_FD")) != NULL) { + pstrcpy(spec, "descriptor "); + pstrcat(spec, p); + sscanf(p, "%d", &fd); + close_it = False; + } else if ((p = getenv("PASSWD_FILE")) != NULL) { + fd = open(p, O_RDONLY); + pstrcpy(spec, p); + if (fd < 0) { + fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n", + spec, strerror(errno)); + exit(1); + } + close_it = True; + } + for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */ + p && p - pass < sizeof(pass);) { + switch (read(fd, p, 1)) { + case 1: + if (*p != '\n' && *p != '\0') { + *++p = '\0'; /* advance p, and null-terminate pass */ + break; + } + case 0: + if (p - pass) { + *p = '\0'; /* null-terminate it, just in case... */ + p = NULL; /* then force the loop condition to become false */ + break; + } else { + fprintf(stderr, "Error reading password from file %s: %s\n", + spec, "empty password\n"); + exit(1); + } + + default: + fprintf(stderr, "Error reading password from file %s: %s\n", + spec, strerror(errno)); + exit(1); + } + } + pstrcpy(password, pass); + got_pass = True; + if (close_it) + close(fd); + } + if (*username == 0 && getenv("LOGNAME")) { pstrcpy(username,getenv("LOGNAME")); diff --git a/source/client/clitar.c b/source/client/clitar.c index e7ab1808362..0ce5c205fab 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -98,6 +98,8 @@ BOOL tar_re_search=False; #ifdef HAVE_REGEX_H regex_t *preg; #endif +/* Do not dump anything, just calculate sizes */ +BOOL dry_run=False; /* Dump files with System attribute */ BOOL tar_system=True; /* Dump files with Hidden attribute */ @@ -374,6 +376,9 @@ static int dotarbuf(int f, char *b, int n) { int fail=1, writ=n; + if (dry_run) { + return writ; + } /* This routine and the next one should be the only ones that do write()s */ if (tp + n >= tbufsiz) { @@ -410,6 +415,9 @@ static void dozerobuf(int f, int n) * used to round files to nearest block * and to do tar EOFs */ + if (dry_run) + return; + if (n+tp >= tbufsiz) { memset(tarbuf+tp, 0, tbufsiz-tp); @@ -445,6 +453,9 @@ static void dotareof(int f) SMB_STRUCT_STAT stbuf; /* Two zero blocks at end of file, write out full buffer */ + if (dry_run) + return; + (void) dozerobuf(f, TBLOCK); (void) dozerobuf(f, TBLOCK); @@ -1034,7 +1045,17 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) finfo.ctime = def_finfo.ctime; } - + if (dry_run) + { + DEBUG(3,("skipping file %s of size %d bytes\n", + finfo.name, + finfo.size)); + shallitime=0; + ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK); + ntarf++; + return; + } + inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -1403,7 +1424,8 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) int this_time; /* if shallitime is true then we didn't skip */ - if (tar_reset) (void) do_setrattr(finfo.name, aARCH, ATTRRESET); + if (tar_reset && !dry_run) + (void) do_setrattr(finfo.name, aARCH, ATTRRESET); GetTimeOfDay(&tp_end); this_time = @@ -2381,7 +2403,7 @@ void cmd_tar(char *inbuf, char *outbuf) if (!next_token(NULL,buf,NULL,sizeof(buf))) { - DEBUG(0,("tar <c|x>[IXbga] <filename>\n")); + DEBUG(0,("tar <c|x>[IXbgan] <filename>\n")); return; } @@ -2618,6 +2640,7 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) */ tar_type='\0'; tar_excl=True; + dry_run=False; while (*Optarg) switch(*Optarg++) { @@ -2689,6 +2712,15 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) DEBUG(0, ("tar_re_search set\n")); tar_re_search = True; break; + case 'n': + if (tar_type == 'c') { + DEBUG(0, ("dry_run set\n")); + dry_run = True; + } else { + DEBUG(0, ("n is only meaningful when creating a tar-file\n")); + return 0; + } + break; default: DEBUG(0,("Unknown tar option\n")); return 0; @@ -2779,6 +2811,14 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) /* Sets tar handle to either 0 or 1, as appropriate */ tarhandle=(tar_type=='c'); } else { + if (tar_type=='c' && (dry_run || strcmp(argv[Optind], "/dev/null")==0)) + { + if (!dry_run) { + DEBUG(0,("Output is /dev/null, assuming dry_run")); + dry_run = True; + } + tarhandle=-1; + } else if ((tar_type=='x' && (tarhandle = open(argv[Optind], O_RDONLY)) == -1) || (tar_type=='c' && (tarhandle=creat(argv[Optind], 0644)) < 0)) { |