--- samba-3.4.7/source3/smbd/reply.c 2010-03-08 20:53:38.000000000 +0100 +++ samba-3.4.7-patched/source3/smbd/reply.c 2010-03-29 14:28:59.000000000 +0200 @@ -3636,6 +3636,11 @@ void reply_writebraw(struct smb_request startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0); write_through = BITSETW(req->vwv+7,0); + if (fsp->print_file) { + /* Print files ignore the offset - use end of file. */ + startpos = (SMB_OFF_T)-1; + } + /* We have to deal with slightly different formats depending on whether we are using the core+ or lanman1.0 protocol */ @@ -3655,15 +3660,17 @@ void reply_writebraw(struct smb_request return; } - init_strict_lock_struct(fsp, (uint32)req->smbpid, - (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK, - &lock); + if (!fsp->print_file) { + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK, + &lock); - if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); - error_to_writebrawerr(req); - END_PROFILE(SMBwritebraw); - return; + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { + reply_doserror(req, ERRDOS, ERRlock); + error_to_writebrawerr(req); + END_PROFILE(SMBwritebraw); + return; + } } if (numtowrite>0) { @@ -3741,7 +3748,11 @@ void reply_writebraw(struct smb_request exit_server_cleanly("secondary writebraw failed"); } - nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite); + if (fsp->print_file) { + nwritten = write_file(req,fsp,buf+4,(SMB_OFF_T)-1,numtowrite); + } else { + nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite); + } if (nwritten == -1) { TALLOC_FREE(buf); reply_unixerror(req, ERRHRD, ERRdiskfull); @@ -3776,7 +3787,9 @@ void reply_writebraw(struct smb_request fsp->fnum, (double)startpos, (int)numtowrite, (int)total_written)); - SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + if (!fsp->print_file) { + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + } /* We won't return a status if write through is not selected - this * follows what WfWg does */ @@ -3800,7 +3813,9 @@ void reply_writebraw(struct smb_request return; strict_unlock: - SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + if (!fsp->print_file) { + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + } END_PROFILE(SMBwritebraw); return; @@ -3849,7 +3864,10 @@ void reply_writeunlock(struct smb_reques startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); data = (const char *)req->buf + 3; - if (numtowrite) { + if (fsp->print_file) { + /* Print files ignore the offset - use end of file. */ + startpos = (SMB_OFF_T)-1; + } else if (numtowrite) { init_strict_lock_struct(fsp, (uint32)req->smbpid, (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, &lock); @@ -3883,7 +3901,7 @@ void reply_writeunlock(struct smb_reques goto strict_unlock; } - if (numtowrite) { + if (numtowrite && !fsp->print_file) { status = do_unlock(smbd_messaging_context(), fsp, req->smbpid, @@ -3905,7 +3923,7 @@ void reply_writeunlock(struct smb_reques fsp->fnum, (int)numtowrite, (int)nwritten)); strict_unlock: - if (numtowrite) { + if (numtowrite && !fsp->print_file) { SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); } @@ -3930,7 +3948,7 @@ void reply_write(struct smb_request *req files_struct *fsp; struct lock_struct lock; NTSTATUS status; - + static bool hit = false; START_PROFILE(SMBwrite); if (req->wct < 5) { @@ -3963,14 +3981,40 @@ void reply_write(struct smb_request *req startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); data = (const char *)req->buf + 3; - init_strict_lock_struct(fsp, (uint32)req->smbpid, - (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, - &lock); - - if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { - reply_doserror(req, ERRDOS, ERRlock); + if (fsp->print_file) { + struct stat64 s; + + if(fstat64(fsp->fh->fd,&s)==-1) + { + reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBwrite); return; + } + + off64_t o = s.st_size; + + /* Print files ignore the offset - use end of file. */ + startpos = (o & 0xffffffff00000000LL) + startpos; + + + if( (o>>32)!=0) { + DEBUG(2,("%s: ST=%llx NW=%llx ST+NW=%llx FS=%llx\n",__PRETTY_FUNCTION__, + (unsigned long long)startpos, + (unsigned long long)numtowrite, + (unsigned long long)startpos + (unsigned long long)numtowrite, + (unsigned long long)o + )); + } + } + + init_strict_lock_struct(fsp, (uint32)req->smbpid, + (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, + &lock); + + if (!SMB_VFS_STRICT_LOCK(conn, fsp, &lock)) { + reply_doserror(req, ERRDOS, ERRlock); + END_PROFILE(SMBwrite); + return; } /* @@ -4023,7 +4067,9 @@ void reply_write(struct smb_request *req DEBUG(3,("write fnum=%d num=%d wrote=%d\n", fsp->fnum, (int)numtowrite, (int)nwritten)); strict_unlock: - SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + if (!fsp->print_file) { + SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); + } END_PROFILE(SMBwrite); return; @@ -4555,7 +4601,10 @@ void reply_writeclose(struct smb_request mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4)); data = (const char *)req->buf + 1; - if (numtowrite) { + if (fsp->print_file) { + /* Print files ignore the offset - use end of file. */ + startpos = (SMB_OFF_T)-1; + } else if (numtowrite) { init_strict_lock_struct(fsp, (uint32)req->smbpid, (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK, &lock); @@ -4601,7 +4650,7 @@ void reply_writeclose(struct smb_request SSVAL(req->outbuf,smb_vwv0,nwritten); strict_unlock: - if (numtowrite) { + if (numtowrite && !fsp->print_file) { SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock); } @@ -5057,7 +5106,7 @@ void reply_printwrite(struct smb_request data = (const char *)req->buf + 3; - if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) { + if (write_file(req,fsp,data,(SMB_OFF_T)-1,numtowrite) != numtowrite) { reply_unixerror(req, ERRHRD, ERRdiskfull); END_PROFILE(SMBsplwr); return;