1998-08-17 07:15:54 +00: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 01:24:30 +00:00
1998-09-03 18:40:31 +00:00
SMB_OFF_T seek_file ( files_struct * fsp , SMB_OFF_T pos )
1998-08-17 07:15:54 +00:00
{
1998-09-03 18:40:31 +00:00
SMB_OFF_T offset = 0 ;
1998-10-18 22:06:35 +00:00
SMB_OFF_T seek_ret ;
1998-08-17 07:15:54 +00:00
if ( fsp - > print_file & & lp_postscript ( fsp - > conn - > service ) )
offset = 3 ;
1999-04-04 07:05:03 +00:00
seek_ret = fsp - > conn - > vfs_ops . lseek ( fsp - > fd_ptr - > fd , pos + offset , SEEK_SET ) ;
1998-10-18 22:06:35 +00:00
if ( ( seek_ret = = - 1 ) | | ( seek_ret ! = pos + offset ) ) {
DEBUG ( 0 , ( " seek_file: sys_lseek failed. Error was %s \n " , strerror ( errno ) ) ) ;
fsp - > pos = - 1 ;
return - 1 ;
}
fsp - > pos = seek_ret - offset ;
1998-09-11 21:42:18 +00:00
DEBUG ( 10 , ( " seek_file: requested pos = %.0f, new pos = %.0f \n " ,
( double ) ( pos + offset ) , ( double ) fsp - > pos ) ) ;
1998-08-17 07:15:54 +00:00
return ( fsp - > pos ) ;
}
/****************************************************************************
read from a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 01:24:30 +00:00
ssize_t read_file ( files_struct * fsp , char * data , SMB_OFF_T pos , size_t n )
1998-08-17 07:15:54 +00:00
{
1998-09-11 01:24:30 +00:00
ssize_t ret = 0 , readret ;
1998-08-17 07:15:54 +00:00
# if USE_READ_PREDICTION
1998-09-11 01:24:30 +00:00
if ( ! fsp - > can_write ) {
1999-04-04 07:05:03 +00:00
ret = read_predict ( fsp , fsp - > fd_ptr - > fd , pos , data , NULL , n ) ;
1998-08-17 07:15:54 +00:00
1998-09-11 01:24:30 +00:00
data + = ret ;
n - = ret ;
pos + = ret ;
}
1998-08-17 07:15:54 +00:00
# endif
# if WITH_MMAP
1998-09-11 01:24:30 +00:00
if ( fsp - > mmap_ptr ) {
1998-10-15 00:55:17 +00:00
SMB_OFF_T num = ( fsp - > mmap_size > pos ) ? ( fsp - > mmap_size - pos ) : 0 ;
1998-09-18 03:00:20 +00:00
num = MIN ( n , num ) ;
if ( num > 0 ) {
memcpy ( data , fsp - > mmap_ptr + pos , num ) ;
data + = num ;
pos + = num ;
n - = num ;
ret + = num ;
}
1998-09-11 01:24:30 +00:00
}
1998-08-17 07:15:54 +00:00
# endif
1998-10-18 22:06:35 +00:00
if ( seek_file ( fsp , pos ) = = - 1 ) {
1998-09-11 21:42:18 +00:00
DEBUG ( 3 , ( " read_file: Failed to seek to %.0f \n " , ( double ) pos ) ) ;
1998-08-17 07:15:54 +00:00
return ( ret ) ;
1998-09-11 01:24:30 +00:00
}
1999-04-04 07:05:03 +00:00
1998-08-17 07:15:54 +00:00
if ( n > 0 ) {
1999-04-04 07:05:03 +00:00
readret = fsp - > conn - > vfs_ops . read ( fsp - > fd_ptr - > fd , data , n ) ;
1998-08-17 07:15:54 +00:00
if ( readret > 0 ) ret + = readret ;
}
return ( ret ) ;
}
/****************************************************************************
write to a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 01:24:30 +00:00
ssize_t write_file ( files_struct * fsp , char * data , size_t n )
1998-08-17 07:15:54 +00:00
{
if ( ! fsp - > can_write ) {
errno = EPERM ;
return ( 0 ) ;
}
if ( ! fsp - > modified ) {
1998-09-01 20:11:54 +00:00
SMB_STRUCT_STAT st ;
1998-08-17 07:15:54 +00:00
fsp - > modified = True ;
1999-04-04 07:05:03 +00:00
if ( fsp - > conn - > vfs_ops . fstat ( fsp - > fd_ptr - > fd , & st ) = = 0 ) {
1998-08-17 07:15:54 +00:00
int dosmode = dos_mode ( fsp - > conn , fsp - > fsp_name , & st ) ;
if ( MAP_ARCHIVE ( fsp - > conn ) & & ! IS_DOS_ARCHIVE ( dosmode ) ) {
1998-09-01 20:11:54 +00:00
file_chmod ( fsp - > conn , fsp - > fsp_name , dosmode | aARCH , & st ) ;
1998-08-17 07:15:54 +00:00
}
}
}
1999-04-04 07:05:03 +00:00
return ( vfs_write_data ( fsp , data , n ) ) ;
1998-08-17 07:15:54 +00:00
}
1998-08-17 07:40:06 +00:00
/*******************************************************************
sync a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1998-09-11 01:24:30 +00:00
1999-04-04 07:05:03 +00:00
void sys_sync_file ( struct connection_struct * conn , files_struct * fsp )
1998-08-17 07:40:06 +00:00
{
# ifdef HAVE_FSYNC
if ( lp_strict_sync ( SNUM ( conn ) ) )
fsync ( fsp - > fd_ptr - > fd ) ;
# endif
}