diff -urN samba-3.0.8/source/client/client.c samba-3.0.8-intelps/source/client/client.c --- samba-3.0.8/source/client/client.c 2004-11-08 04:43:24.000000000 +0800 +++ samba-3.0.8-intelps/source/client/client.c 2004-11-10 12:06:04.000000000 +0800 @@ -1052,6 +1052,134 @@ } /**************************************************************************** + Spool a single file. +****************************************************************************/ + +static int do_spl(char *rname, char *lname, BOOL reput) +{ + int fnum; + XFILE *f; + size_t start = 0; + off_t nread = 0; + char *buf = NULL; + int maxwrite = io_bufsize; + int rc = 0; + + struct timeval tp_start; + GetTimeOfDay(&tp_start); + + if (reput) { + fnum = cli_spl_open(cli, rname, O_RDWR|O_CREAT, DENY_NONE); + if (fnum >= 0) { + if (!cli_qfileinfo(cli, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL) && + !cli_getattrE(cli, fnum, NULL, &start, NULL, NULL, NULL)) { + d_printf("getattrib: %s\n",cli_errstr(cli)); + return 1; + } + } + } else { + fnum = cli_spl_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); + } + + if (fnum == -1) { + d_printf("%s opening remote spool %s\n",cli_errstr(cli),rname); + return 1; + } + + /* allow files to be piped into smbclient + jdblair 24.jun.98 + + Note that in this case this function will exit(0) rather + than returning. */ + if (!strcmp(lname, "-")) { + f = x_stdin; + /* size of file is not known */ + } else { + f = x_fopen(lname,O_RDONLY, 0); + if (f && reput) { + if (x_tseek(f, start, SEEK_SET) == -1) { + d_printf("Error seeking local file\n"); + return 1; + } + } + } + + if (!f) { + d_printf("Error opening local file %s\n",lname); + return 1; + } + + DEBUG(1,("putting file as spool %s ",lname, + rname)); + + buf = (char *)malloc(maxwrite); + if (!buf) { + d_printf("ERROR: Not enough memory!\n"); + return 1; + } + while (!x_feof(f)) { + int n = maxwrite; + int ret; + + if ((n = readfile(buf,n,f)) < 1) { + if((n == 0) && x_feof(f)) + break; /* Empty local file. */ + + d_printf("Error reading local file: %s\n", strerror(errno)); + rc = 1; + break; + } + + ret = cli_write(cli, fnum, 0, buf, nread + start, n); + + if (n != ret) { + d_printf("Error writing spool: %s\n", cli_errstr(cli)); + rc = 1; + break; + } + + nread += n; + } + + if (!cli_spl_close(cli, fnum)) { + d_printf("%s closing remote spool %s\n",cli_errstr(cli),rname); + x_fclose(f); + SAFE_FREE(buf); + return 1; + } + + + if (f != x_stdin) { + x_fclose(f); + } + + SAFE_FREE(buf); + + { + 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; + put_total_time_ms += this_time; + put_total_size += nread; + + DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n", + nread / (1.024*this_time + 1.0e-4), + put_total_size / (1.024*put_total_time_ms))); + } + + if (f == x_stdin) { + cli_shutdown(cli); + exit(0); + } + + return rc; +} + +/**************************************************************************** Put a single file. ****************************************************************************/ @@ -1487,7 +1615,7 @@ slprintf(rname, sizeof(rname)-1, "stdin-%d", (int)sys_getpid()); } - return do_put(rname, lname, False); + return do_spl(rname, lname, False); } /**************************************************************************** diff -urN samba-3.0.8/source/client/smbspool.c samba-3.0.8-intelps/source/client/smbspool.c --- samba-3.0.8/source/client/smbspool.c 2004-11-08 04:43:24.000000000 +0800 +++ samba-3.0.8-intelps/source/client/smbspool.c 2004-11-10 12:07:15.000000000 +0800 @@ -337,9 +337,9 @@ * Open the printer device... */ - if ((fnum = cli_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1) + if ((fnum = cli_spl_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1) { - fprintf(stderr, "ERROR: %s opening remote file %s\n", + fprintf(stderr, "ERROR: %s opening remote spool %s\n", cli_errstr(cli), title); return (1); } @@ -357,16 +357,16 @@ { if (cli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes) { - fprintf(stderr, "ERROR: Error writing file: %s\n", cli_errstr(cli)); + fprintf(stderr, "ERROR: Error writing spool: %s\n", cli_errstr(cli)); break; } tbytes += nbytes; } - if (!cli_close(cli, fnum)) + if (!cli_spl_close(cli, fnum)) { - fprintf(stderr, "ERROR: %s closing remote file %s\n", + fprintf(stderr, "ERROR: %s closing remote spool %s\n", cli_errstr(cli), title); return (1); } diff -urN samba-3.0.8/source/libsmb/cliprint.c samba-3.0.8-intelps/source/libsmb/cliprint.c --- samba-3.0.8/source/libsmb/cliprint.c 2004-10-26 05:05:01.000000000 +0800 +++ samba-3.0.8-intelps/source/libsmb/cliprint.c 2004-11-10 12:00:04.000000000 +0800 @@ -156,3 +156,108 @@ } +/**************************************************************************** + Open a spool file +****************************************************************************/ + +int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn=0; + unsigned accessmode=0; + + if (flags & O_CREAT) + openfn |= (1<<4); + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) + openfn |= (1<<1); + else + openfn |= (1<<0); + } + + accessmode = (share_mode<<4); + + if ((flags & O_ACCMODE) == O_RDWR) { + accessmode |= 2; + } else if ((flags & O_ACCMODE) == O_WRONLY) { + accessmode |= 1; + } + +#if defined(O_SYNC) + if ((flags & O_SYNC) == O_SYNC) { + accessmode |= (1<<14); + } +#endif /* O_SYNC */ + + if (share_mode == DENY_FCB) { + accessmode = 0xFF; + } + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,15,0,True); + + SCVAL(cli->outbuf,smb_com,SMBsplopen); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + SSVAL(cli->outbuf,smb_vwv3,accessmode); + SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,0); + SSVAL(cli->outbuf,smb_vwv8,openfn); + + if (cli->use_oplocks) { + /* if using oplocks then ask for a batch oplock via + core and extended methods */ + SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)| + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); + SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); + } + + p = smb_buf(cli->outbuf); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (cli_is_error(cli)) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2); +} + +/**************************************************************************** + Close a file. +****************************************************************************/ + +BOOL cli_spl_close(struct cli_state *cli, int fnum) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,3,0,True); + + SCVAL(cli->outbuf,smb_com,SMBsplclose); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVALS(cli->outbuf,smb_vwv1,-1); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + return !cli_is_error(cli); +} + +