1998-08-17 11:15:54 +04:00
/*
Unix SMB / Netbios implementation .
Version 1.9 .
read / write to a files_struct
Copyright ( C ) Andrew Tridgell 1992 - 1998
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
/****************************************************************************
seek a file . Try to avoid the seek if possible
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 05:24:30 +04:00
1998-09-03 22:40:31 +04:00
SMB_OFF_T seek_file ( files_struct * fsp , SMB_OFF_T pos )
1998-08-17 11:15:54 +04:00
{
1998-09-03 22:40:31 +04:00
SMB_OFF_T offset = 0 ;
1998-08-17 11:15:54 +04:00
if ( fsp - > print_file & & lp_postscript ( fsp - > conn - > service ) )
offset = 3 ;
1998-09-03 22:40:31 +04:00
fsp - > pos = ( sys_lseek ( fsp - > fd_ptr - > fd , pos + offset , SEEK_SET ) - offset ) ;
1998-08-17 11:15:54 +04:00
return ( fsp - > pos ) ;
}
/****************************************************************************
read from a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 05:24:30 +04:00
ssize_t read_file ( files_struct * fsp , char * data , SMB_OFF_T pos , size_t n )
1998-08-17 11:15:54 +04:00
{
1998-09-11 05:24:30 +04:00
ssize_t ret = 0 , readret ;
1998-08-17 11:15:54 +04:00
# if USE_READ_PREDICTION
1998-09-11 05:24:30 +04:00
if ( ! fsp - > can_write ) {
ret = read_predict ( fsp - > fd_ptr - > fd , pos , data , NULL , n ) ;
1998-08-17 11:15:54 +04:00
1998-09-11 05:24:30 +04:00
data + = ret ;
n - = ret ;
pos + = ret ;
}
1998-08-17 11:15:54 +04:00
# endif
# if WITH_MMAP
1998-09-11 05:24:30 +04:00
if ( fsp - > mmap_ptr ) {
SMB_OFF_T num = ( fsp - > mmap_size > pos ) ? ( fsp - > mmap_size - pos ) : - 1 ;
num = MIN ( n , num ) ;
# ifdef LARGE_SMB_OFF_T
if ( ( num > 0 ) & & ( num < ( 1 < < ( sizeof ( size_t ) * 8 ) ) ) {
# else /* LARGE_SMB_OFF_T */
if ( num > 0 ) {
# endif /* LARGE_SMB_OFF_T */
memcpy ( data , fsp - > mmap_ptr + pos , num ) ;
data + = num ;
pos + = num ;
n - = num ;
ret + = num ;
1998-08-17 11:15:54 +04:00
}
1998-09-11 05:24:30 +04:00
}
1998-08-17 11:15:54 +04:00
# endif
1998-09-11 05:24:30 +04:00
if ( seek_file ( fsp , pos ) ! = pos ) {
DEBUG ( 3 , ( " Failed to seek to %.0f \n " , ( double ) pos ) ) ;
1998-08-17 11:15:54 +04:00
return ( ret ) ;
1998-09-11 05:24:30 +04:00
}
1998-08-17 11:15:54 +04:00
if ( n > 0 ) {
readret = read ( fsp - > fd_ptr - > fd , data , n ) ;
if ( readret > 0 ) ret + = readret ;
}
return ( ret ) ;
}
/****************************************************************************
write to a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 05:24:30 +04:00
ssize_t write_file ( files_struct * fsp , char * data , size_t n )
1998-08-17 11:15:54 +04:00
{
if ( ! fsp - > can_write ) {
errno = EPERM ;
return ( 0 ) ;
}
if ( ! fsp - > modified ) {
1998-09-02 00:11:54 +04:00
SMB_STRUCT_STAT st ;
1998-08-17 11:15:54 +04:00
fsp - > modified = True ;
1998-09-03 22:40:31 +04:00
if ( sys_fstat ( fsp - > fd_ptr - > fd , & st ) = = 0 ) {
1998-08-17 11:15:54 +04:00
int dosmode = dos_mode ( fsp - > conn , fsp - > fsp_name , & st ) ;
if ( MAP_ARCHIVE ( fsp - > conn ) & & ! IS_DOS_ARCHIVE ( dosmode ) ) {
1998-09-02 00:11:54 +04:00
file_chmod ( fsp - > conn , fsp - > fsp_name , dosmode | aARCH , & st ) ;
1998-08-17 11:15:54 +04:00
}
}
}
return ( write_data ( fsp - > fd_ptr - > fd , data , n ) ) ;
}
1998-08-17 11:40:06 +04:00
/*******************************************************************
sync a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 05:24:30 +04:00
1998-08-17 11:40:06 +04:00
void sync_file ( connection_struct * conn , files_struct * fsp )
{
# ifdef HAVE_FSYNC
if ( lp_strict_sync ( SNUM ( conn ) ) )
fsync ( fsp - > fd_ptr - > fd ) ;
# endif
}