From 19e94da7602a69fa2dce33b64fadfbb1fce40c95 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 5 Mar 2004 17:21:45 +0000 Subject: Add -O (write downloaded files to stdout), based on patch from Bas van Sisseren (This used to be commit a90df1c170a168092e0c90f684ea968bd1f6f768) --- source3/utils/smbget.c | 145 +++++++++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 65 deletions(-) diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index ab6e368c70..64630bba8f 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -41,7 +41,7 @@ off_t total_bytes = 0; #define SMB_DEFAULT_BLOCKSIZE 64000 const char *username = NULL, *password = NULL, *workgroup = NULL; -int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0; +int nonprompt = 0, quiet = 0, dots = 0, keep_permissions = 0, verbose = 0, send_stdout = 0; int blocksize = SMB_DEFAULT_BLOCKSIZE; int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile); @@ -51,7 +51,6 @@ int get_num_cols(void) #ifdef TIOCGWINSZ struct winsize ws; if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0) { - perror("ioctl"); return 0; } return ws.ws_col; @@ -300,74 +299,81 @@ int smb_download_file(const char *base, const char *name, int recursive, int res if(newpath[0] == '/')newpath++; /* Open local file and, if necessary, resume */ - localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); - if(localhandle < 0) { - fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); - smbc_close(remotehandle); - return 0; - } + if(!send_stdout) { + localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); + if(localhandle < 0) { + fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); + smbc_close(remotehandle); + return 0; + } - fstat(localhandle, &localstat); + fstat(localhandle, &localstat); - start_offset = localstat.st_size; + start_offset = localstat.st_size; - if(localstat.st_size && localstat.st_size == remotestat.st_size) { - if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path); - else if(!quiet)fprintf(stderr, "%s\n", path); - smbc_close(remotehandle); - close(localhandle); - return 1; - } - - if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) { - offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; - offset_check = localstat.st_size - RESUME_CHECK_OFFSET; - if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n" - "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check, - localstat.st_size, remotestat.st_size); - } - - if(offset_check) { - off_t off1, off2; - /* First, check all bytes from offset_check to offset_download */ - off1 = lseek(localhandle, offset_check, SEEK_SET); - if(off1 < 0) { - fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath); - smbc_close(remotehandle); close(localhandle); - return 0; + if(localstat.st_size && localstat.st_size == remotestat.st_size) { + if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path); + else if(!quiet)fprintf(stderr, "%s\n", path); + smbc_close(remotehandle); + close(localhandle); + return 1; } - off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET); - if(off2 < 0) { - fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath); - smbc_close(remotehandle); close(localhandle); - return 0; + if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) { + offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; + offset_check = localstat.st_size - RESUME_CHECK_OFFSET; + if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n" + "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check, + localstat.st_size, remotestat.st_size); } - if(off1 != off2) { - fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2); - return 0; - } + if(offset_check) { + off_t off1, off2; + /* First, check all bytes from offset_check to offset_download */ + off1 = lseek(localhandle, offset_check, SEEK_SET); + if(off1 < 0) { + fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath); + smbc_close(remotehandle); close(localhandle); + return 0; + } - if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { - fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path); - smbc_close(remotehandle); close(localhandle); - return 0; - } + off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET); + if(off2 < 0) { + fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath); + smbc_close(remotehandle); close(localhandle); + return 0; + } - if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { - fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name); - smbc_close(remotehandle); close(localhandle); - return 0; - } + if(off1 != off2) { + fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2); + return 0; + } - if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { - if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download); - } else { - fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path); - smbc_close(remotehandle); close(localhandle); - return 0; + if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { + fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { + fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name); + smbc_close(remotehandle); close(localhandle); + return 0; + } + + if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { + if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download); + } else { + fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path); + smbc_close(remotehandle); close(localhandle); + return 0; + } } + } else { + localhandle = STDOUT_FILENO; + start_offset = 0; + offset_download = 0; + offset_check = 0; } readbuf = malloc(blocksize); @@ -377,7 +383,8 @@ int smb_download_file(const char *base, const char *name, int recursive, int res ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize); if(bytesread < 0) { fprintf(stderr, "Can't read %d bytes at offset "OFF_T_FORMAT", file %s\n", blocksize, curpos, path); - smbc_close(remotehandle); close(localhandle); + smbc_close(remotehandle); + if (localhandle != STDOUT_FILENO) close(localhandle); free(readbuf); return 0; } @@ -387,7 +394,8 @@ int smb_download_file(const char *base, const char *name, int recursive, int res if(write(localhandle, readbuf, bytesread) < 0) { fprintf(stderr, "Can't write %d bytes to local file %s at offset "OFF_T_FORMAT"\n", bytesread, path, curpos); free(readbuf); - smbc_close(remotehandle); close(localhandle); + smbc_close(remotehandle); + if (localhandle != STDOUT_FILENO) close(localhandle); return 0; } @@ -413,7 +421,7 @@ int smb_download_file(const char *base, const char *name, int recursive, int res fputc('\n', stderr); } - if(keep_permissions) { + if(keep_permissions && !send_stdout) { if(fchmod(localhandle, remotestat.st_mode) < 0) { fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode); smbc_close(remotehandle); @@ -421,8 +429,9 @@ int smb_download_file(const char *base, const char *name, int recursive, int res return 0; } } + smbc_close(remotehandle); - close(localhandle); + if (localhandle != STDOUT_FILENO) close(localhandle); return 1; } @@ -514,6 +523,7 @@ int main(int argc, const char **argv) {"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" }, @@ -549,8 +559,13 @@ int main(int argc, const char **argv) } } - if(outputfile && recursive) { - fprintf(stderr, "The -o and -R options can not be used together.\n"); + if((send_stdout || outputfile) && recursive) { + fprintf(stderr, "The -o or -O and -R options can not be used together.\n"); + return 1; + } + + if(outputfile && send_stdout) { + fprintf(stderr, "The -o and -O options cannot be used together.\n"); return 1; } -- cgit