diff options
author | Andreas Schneider <asn@samba.org> | 2015-10-28 12:37:36 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2016-01-28 09:58:26 +0100 |
commit | e1548c5bf77186c72f0257592e9084e3b039b87c (patch) | |
tree | 7c91407699e8aaf337a4edc0a3a2be0f81c7ac47 /source3/utils/smbget.c | |
parent | 526a3878382582d2f83aee900d9afeadfc53462a (diff) | |
download | samba-e1548c5bf77186c72f0257592e9084e3b039b87c.tar.gz |
s3-utils/smbget: Fix option parsing and apply samba defaults
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Christian Ambach <ambi@samba.org>
Diffstat (limited to 'source3/utils/smbget.c')
-rw-r--r-- | source3/utils/smbget.c | 173 |
1 files changed, 104 insertions, 69 deletions
diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index f596a8ca855..3ced8df9e3c 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -23,10 +23,6 @@ static int columns = 0; -static int debuglevel; -static char *outputfile; - - static time_t total_start_time = 0; static off_t total_bytes = 0; @@ -42,11 +38,26 @@ static off_t total_bytes = 0; /* Number of bytes to read at once */ #define SMB_DEFAULT_BLOCKSIZE 64000 -static const char *username = NULL, *password = NULL, *workgroup = NULL; -static bool nonprompt = false, quiet = false, dots = false, - keep_permissions = false, verbose = false, send_stdout = false, - update = false; -static unsigned int blocksize = SMB_DEFAULT_BLOCKSIZE; +struct opt { + char *workgroup; + bool username_specified; + char *username; + bool password_specified; + char *password; + + char *outputfile; + size_t blocksize; + + bool nonprompt; + bool quiet; + bool dots; + bool keep_permissions; + bool verbose; + bool send_stdout; + bool update; + int debuglevel; +}; +static struct opt opt; static bool smb_download_file(const char *base, const char *name, bool recursive, bool resume, bool toplevel, @@ -105,7 +116,7 @@ static void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, } hasasked = true; - if (!nonprompt && !username) { + if (!opt.nonprompt && !opt.username_specified) { printf("Username for %s at %s [guest] ", shr, srv); if (fgets(tmp, sizeof(tmp), stdin) == NULL) { return; @@ -114,11 +125,11 @@ static void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, tmp[strlen(tmp) - 1] = '\0'; } strncpy(un, tmp, unlen - 1); - } else if (username) { - strncpy(un, username, unlen - 1); + } else if (opt.username != NULL) { + strncpy(un, opt.username, unlen - 1); } - if (!nonprompt && !password) { + if (!opt.nonprompt && !opt.password_specified) { char *prompt; if (asprintf(&prompt, "Password for %s at %s: ", shr, srv) == -1) { @@ -126,12 +137,12 @@ static void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, } (void)samba_getpass(prompt, pw, pwlen, false, false); free(prompt); - } else if (password) { - strncpy(pw, password, pwlen - 1); + } else if (opt.password != NULL) { + strncpy(pw, opt.password, pwlen-1); } - if (workgroup) { - strncpy(wg, workgroup, wglen - 1); + if (opt.workgroup != NULL) { + strncpy(wg, opt.workgroup, wglen-1); } /* save the values found for later */ @@ -139,12 +150,14 @@ static void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, savedun = SMB_STRDUP(un); savedpw = SMB_STRDUP(pw); - if (!quiet) { + if (!opt.quiet) { char *wgtmp, *usertmp; wgtmp = SMB_STRNDUP(wg, wglen); usertmp = SMB_STRNDUP(un, unlen); - printf("Using workgroup %s, %s%s\n", wgtmp, - *usertmp ? "user " : "guest user", usertmp); + printf("Using workgroup %s, %s%s\n", + wgtmp, + *usertmp ? "user " : "guest user", + usertmp); free(wgtmp); free(usertmp); } @@ -218,21 +231,21 @@ static int smb_download_dir(const char *base, const char *name, int resume) break; case SMBC_PRINTER_SHARE: - if (!quiet) { + if (!opt.quiet) { printf("Ignoring printer share %s\n", dirent->name); } break; case SMBC_COMMS_SHARE: - if (!quiet) { + if (!opt.quiet) { printf("Ignoring comms share %s\n", dirent->name); } break; case SMBC_IPC_SHARE: - if (!quiet) { + if (!opt.quiet) { printf("Ignoring ipc$ share %s\n", dirent->name); } @@ -247,7 +260,7 @@ static int smb_download_dir(const char *base, const char *name, int resume) } free(tmpname); - if (keep_permissions) { + if (opt.keep_permissions) { if (smbc_fstat(dirhandle, &remotestat) < 0) { fprintf(stderr, "Unable to get stats on %s on remote server\n", @@ -420,11 +433,11 @@ static bool smb_download_file(const char *base, const char *name, } /* Open local file according to the mode */ - if (update) { + if (opt.update) { /* if it is up-to-date, skip */ if (stat(newpath, &localstat) == 0 && localstat.st_mtime >= remotestat.st_mtime) { - if (verbose) { + if (opt.verbose) { printf("%s is up-to-date, skipping\n", newpath); } smbc_close(remotehandle); @@ -440,7 +453,7 @@ static bool smb_download_file(const char *base, const char *name, return false; } /* no offset */ - } else if (!send_stdout) { + } else if (!opt.send_stdout) { localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume ? O_EXCL : 0), 0755); @@ -463,11 +476,11 @@ static bool smb_download_file(const char *base, const char *name, if (localstat.st_size && localstat.st_size == remotestat.st_size) { - if (verbose) { + if (opt.verbose) { fprintf(stderr, "%s is already downloaded " "completely.\n", path); - } else if (!quiet) { + } else if (!opt.quiet) { fprintf(stderr, "%s\n", path); } smbc_close(remotehandle); @@ -480,7 +493,7 @@ static bool smb_download_file(const char *base, const char *name, offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; offset_check = localstat.st_size - RESUME_CHECK_OFFSET; - if (verbose) { + if (opt.verbose) { printf("Trying to start resume of %s at %jd\n" "At the moment %jd of %jd bytes have " "been retrieved\n", @@ -546,7 +559,7 @@ static bool smb_download_file(const char *base, const char *name, if (memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { - if (verbose) { + if (opt.verbose) { printf("Current local and remote file " "appear to be the same. " "Starting download from " @@ -570,7 +583,7 @@ static bool smb_download_file(const char *base, const char *name, offset_check = 0; } - readbuf = (char *)SMB_MALLOC(blocksize); + readbuf = (char *)SMB_MALLOC(opt.blocksize); if (!readbuf) { if (localhandle != STDOUT_FILENO) { close(localhandle); @@ -580,12 +593,14 @@ static bool smb_download_file(const char *base, const char *name, /* Now, download all bytes from offset_download to the end */ for (curpos = offset_download; curpos < remotestat.st_size; - curpos += blocksize) { - ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize); + curpos += opt.blocksize) { + ssize_t bytesread = smbc_read(remotehandle, + readbuf, + opt.blocksize); if(bytesread < 0) { fprintf(stderr, - "Can't read %u bytes at offset %jd, file %s\n", - blocksize, (intmax_t)curpos, path); + "Can't read %zu bytes at offset %jd, file %s\n", + opt.blocksize, (intmax_t)curpos, path); smbc_close(remotehandle); if (localhandle != STDOUT_FILENO) { close(localhandle); @@ -609,9 +624,9 @@ static bool smb_download_file(const char *base, const char *name, return false; } - if (dots) { + if (opt.dots) { fputc('.', stderr); - } else if (!quiet) { + } else if (!opt.quiet) { print_progress(newpath, start_time, time_mono(NULL), start_offset, curpos, remotestat.st_size); @@ -620,10 +635,10 @@ static bool smb_download_file(const char *base, const char *name, free(readbuf); - if (dots) { + if (opt.dots) { fputc('\n', stderr); printf("%s downloaded\n", path); - } else if (!quiet) { + } else if (!opt.quiet) { int i; fprintf(stderr, "\r%s", path); if (columns) { @@ -634,7 +649,7 @@ static bool smb_download_file(const char *base, const char *name, fputc('\n', stderr); } - if (keep_permissions && !send_stdout) { + if (opt.keep_permissions && !opt.send_stdout) { if (fchmod(localhandle, remotestat.st_mode) < 0) { fprintf(stderr, "Unable to change mode of local " "file %s to %o\n", @@ -656,7 +671,7 @@ static void clean_exit(void) { char bs[100]; human_readable(total_bytes, bs, sizeof(bs)); - if (!quiet) { + if (!opt.quiet) { fprintf(stderr, "Downloaded %s in %lu seconds\n", bs, (unsigned long)(time_mono(NULL) - total_start_time)); } @@ -744,7 +759,7 @@ static int readrcfile(const char *name, const struct poptOption long_options[]) return 0; } -int main(int argc, const char **argv) +int main(int argc, char **argv) { int c = 0; const char *file = NULL; @@ -753,26 +768,32 @@ int main(int argc, const char **argv) int resume = 0, recursive = 0; TALLOC_CTX *frame = talloc_stackframe(); bool ret = true; + char *p; + const char **argv_const = discard_const_p(const char *, argv); struct poptOption long_options[] = { - {"guest", 'a', POPT_ARG_NONE, NULL, 'a', "Work as user guest" }, - {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport" }, - {"resume", 'r', POPT_ARG_NONE, &resume, 0, "Automatically resume aborted files" }, - {"update", 'U', POPT_ARG_NONE, &update, 0, "Download only when remote file is newer than local file or local file is missing"}, - {"recursive", 'R', POPT_ARG_NONE, &recursive, 0, "Recursively download files" }, - {"username", 'u', POPT_ARG_STRING, &username, 'u', "Username to use" }, - {"password", 'p', POPT_ARG_STRING, &password, 'p', "Password to use" }, - {"workgroup", 'w', POPT_ARG_STRING, &workgroup, 'w', "Workgroup to use (optional)" }, - {"nonprompt", 'n', POPT_ARG_NONE, &nonprompt, 'n', "Don't ask anything (non-interactive)" }, - {"debuglevel", 'd', POPT_ARG_INT, &debuglevel, 'd', "Debuglevel to use" }, - {"outputfile", 'o', POPT_ARG_STRING, &outputfile, 'o', "Write downloaded data to specified file" }, - {"stdout", 'O', POPT_ARG_NONE, &send_stdout, 'O', "Write data to stdout" }, - {"dots", 'D', POPT_ARG_NONE, &dots, 'D', "Show dots as progress indication" }, - {"quiet", 'q', POPT_ARG_NONE, &quiet, 'q', "Be quiet" }, - {"verbose", 'v', POPT_ARG_NONE, &verbose, 'v', "Be verbose" }, - {"keep-permissions", 'P', POPT_ARG_NONE, &keep_permissions, 'P', "Keep permissions" }, - {"blocksize", 'b', POPT_ARG_INT, &blocksize, 'b', "Change number of bytes in a block"}, - {"rcfile", 'f', POPT_ARG_STRING, NULL, 'f', "Use specified rc file"}, POPT_AUTOHELP + + {"workgroup", 'w', POPT_ARG_STRING, &opt.workgroup, 'w', "Workgroup to use (optional)" }, + {"user", 'U', POPT_ARG_STRING, &opt.username, 'U', "Username to use" }, + {"guest", 'a', POPT_ARG_NONE, NULL, 'a', "Work as user guest" }, + + {"nonprompt", 'n', POPT_ARG_NONE, &opt.nonprompt, 'n', "Don't ask anything (non-interactive)" }, + {"debuglevel", 'd', POPT_ARG_INT, &opt.debuglevel, 'd', "Debuglevel to use" }, + + {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport" }, + {"resume", 'r', POPT_ARG_NONE, &resume, 0, "Automatically resume aborted files" }, + {"update", 'u', POPT_ARG_NONE, &opt.update, 0, "Download only when remote file is newer than local file or local file is missing"}, + {"recursive", 'R', POPT_ARG_NONE, &recursive, 0, "Recursively download files" }, + {"keep-permissions", 'P', POPT_ARG_NONE, &opt.keep_permissions, 'P', "Keep permissions" }, + {"blocksize", 'b', POPT_ARG_INT, &opt.blocksize, 'b', "Change number of bytes in a block"}, + + {"outputfile", 'o', POPT_ARG_STRING, &opt.outputfile, 'o', "Write downloaded data to specified file" }, + {"stdout", 'O', POPT_ARG_NONE, &opt.send_stdout, 'O', "Write data to stdout" }, + {"dots", 'D', POPT_ARG_NONE, &opt.dots, 'D', "Show dots as progress indication" }, + {"quiet", 'q', POPT_ARG_NONE, &opt.quiet, 'q', "Be quiet" }, + {"verbose", 'v', POPT_ARG_NONE, &opt.verbose, 'v', "Be verbose" }, + {"rcfile", 'f', POPT_ARG_STRING, NULL, 'f', "Use specified rc file"}, + POPT_TABLEEND }; poptContext pc; @@ -794,7 +815,7 @@ int main(int argc, const char **argv) signal(SIGINT, signal_quit); signal(SIGTERM, signal_quit); - pc = poptGetContext(argv[0], argc, argv, long_options, 0); + pc = poptGetContext(argv[0], argc, argv_const, long_options, 0); while ((c = poptGetNextOpt(pc)) >= 0) { switch (c) { @@ -802,33 +823,47 @@ int main(int argc, const char **argv) readrcfile(poptGetOptArg(pc), long_options); break; case 'a': - username = ""; - password = ""; + opt.username_specified = true; + opt.username = talloc_strdup(frame, ""); + opt.password_specified = true; + opt.password = talloc_strdup(frame, ""); break; case 'e': smb_encrypt = true; break; + case 'U': + opt.username_specified = true; + opt.username = talloc_strdup(frame, opt.username); + p = strchr(opt.username,'%'); + if (p != NULL) { + *p = '\0'; + opt.password = p + 1; + opt.password_specified = true; + } + break; } } - if ((send_stdout || resume || outputfile) && update) { + if ((opt.send_stdout || resume || opt.outputfile) && opt.update) { fprintf(stderr, "The -o, -R or -O and -U options can not be " "used together.\n"); return 1; } - if ((send_stdout || outputfile) && recursive) { + if ((opt.send_stdout || opt.outputfile) && recursive) { fprintf(stderr, "The -o or -O and -R options can not be " "used together.\n"); return 1; } - if (outputfile && send_stdout) { + if (opt.outputfile && opt.send_stdout) { fprintf(stderr, "The -o and -O options can not be " "used together.\n"); return 1; } - if (smbc_init(get_auth_data, debuglevel) < 0) { + popt_burn_cmdline_password(argc, argv); + + if (smbc_init(get_auth_data, opt.debuglevel) < 0) { fprintf(stderr, "Unable to initialize libsmbclient\n"); return 1; } @@ -847,7 +882,7 @@ int main(int argc, const char **argv) while ((file = poptGetArg(pc))) { if (!recursive) { ret = smb_download_file(file, "", recursive, resume, - true, outputfile); + true, opt.outputfile); } else { ret = smb_download_dir(file, "", resume); } |