2003-08-13 05:53:07 +04:00
/*
* Unix SMB / CIFS implementation .
* SMB parameters and setup
* Copyright ( C ) Andrew Tridgell 1992 - 1998 Modified by Jeremy Allison 1995.
*
* 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"
2004-11-02 03:24:21 +03:00
# include "system/shmem.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
2003-08-13 05:53:07 +04:00
/*************************************************************************
gets a line out of a file .
line is of format " xxxx:xxxxxx:xxxxx: " .
lines with " # " at the front are ignored .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int getfileline ( void * vp , char * linebuf , int linebuf_size )
{
/* Static buffers we will return. */
FILE * fp = ( FILE * ) vp ;
2004-05-29 12:11:46 +04:00
uint8_t c ;
uint8_t * p ;
2003-08-13 05:53:07 +04:00
size_t linebuf_len ;
if ( fp = = NULL )
{
DEBUG ( 0 , ( " getfileline: Bad file pointer. \n " ) ) ;
return - 1 ;
}
/*
* Scan the file , a line at a time .
*/
while ( ! feof ( fp ) )
{
linebuf [ 0 ] = ' \0 ' ;
fgets ( linebuf , linebuf_size , fp ) ;
if ( ferror ( fp ) )
{
return - 1 ;
}
/*
* Check if the string is terminated with a newline - if not
* then we must keep reading and discard until we get one .
*/
linebuf_len = strlen ( linebuf ) ;
if ( linebuf_len = = 0 )
{
linebuf [ 0 ] = ' \0 ' ;
return 0 ;
}
if ( linebuf [ linebuf_len - 1 ] ! = ' \n ' )
{
c = ' \0 ' ;
while ( ! ferror ( fp ) & & ! feof ( fp ) )
{
c = fgetc ( fp ) ;
if ( c = = ' \n ' )
{
break ;
}
}
}
else
{
linebuf [ linebuf_len - 1 ] = ' \0 ' ;
}
# ifdef DEBUG_PASSWORD
DEBUG ( 100 , ( " getfileline: got line |%s| \n " , linebuf ) ) ;
# endif
if ( ( linebuf [ 0 ] = = 0 ) & & feof ( fp ) )
{
DEBUG ( 4 , ( " getfileline: end of file reached \n " ) ) ;
return 0 ;
}
if ( linebuf [ 0 ] = = ' # ' | | linebuf [ 0 ] = = ' \0 ' )
{
DEBUG ( 6 , ( " getfileline: skipping comment or blank line \n " ) ) ;
continue ;
}
2004-05-29 12:11:46 +04:00
p = ( uint8_t * ) strchr_m ( linebuf , ' : ' ) ;
2003-08-13 05:53:07 +04:00
if ( p = = NULL )
{
DEBUG ( 0 , ( " getfileline: malformed line entry (no :) \n " ) ) ;
continue ;
}
return linebuf_len ;
}
return - 1 ;
}
/****************************************************************************
read a line from a file with possible \ continuation chars .
Blanks at the start or end of a line are stripped .
The string will be allocated if s2 is NULL
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-06-16 10:39:41 +04:00
char * fgets_slash ( char * s2 , int maxlen , XFILE * f )
2003-08-13 05:53:07 +04:00
{
char * s = s2 ;
int len = 0 ;
int c ;
BOOL start_of_line = True ;
if ( x_feof ( f ) )
return ( NULL ) ;
if ( maxlen < 2 ) return ( NULL ) ;
if ( ! s2 )
{
maxlen = MIN ( maxlen , 8 ) ;
s = ( char * ) malloc ( maxlen ) ;
}
if ( ! s ) return ( NULL ) ;
* s = 0 ;
while ( len < maxlen - 1 )
{
c = x_getc ( f ) ;
switch ( c )
{
case ' \r ' :
break ;
case ' \n ' :
while ( len > 0 & & s [ len - 1 ] = = ' ' )
{
s [ - - len ] = 0 ;
}
if ( len > 0 & & s [ len - 1 ] = = ' \\ ' )
{
s [ - - len ] = 0 ;
start_of_line = True ;
break ;
}
return ( s ) ;
case EOF :
if ( len < = 0 & & ! s2 )
SAFE_FREE ( s ) ;
return ( len > 0 ? s : NULL ) ;
case ' ' :
if ( start_of_line )
break ;
default :
start_of_line = False ;
s [ len + + ] = c ;
s [ len ] = 0 ;
}
if ( ! s2 & & len > maxlen - 3 )
{
char * t ;
maxlen * = 2 ;
2004-12-03 09:42:06 +03:00
t = realloc_p ( s , char , maxlen ) ;
2003-08-13 05:53:07 +04:00
if ( ! t ) {
DEBUG ( 0 , ( " fgets_slash: failed to expand buffer! \n " ) ) ;
SAFE_FREE ( s ) ;
return ( NULL ) ;
} else s = t ;
}
}
return ( s ) ;
}
/****************************************************************************
load a file into memory from a fd .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-10 05:10:09 +04:00
char * fd_load ( int fd , size_t * size , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
2004-11-01 23:21:54 +03:00
struct stat sbuf ;
2003-08-13 05:53:07 +04:00
char * p ;
2004-11-01 23:21:54 +03:00
if ( fstat ( fd , & sbuf ) ! = 0 ) return NULL ;
2003-08-13 05:53:07 +04:00
2005-07-10 05:10:09 +04:00
p = ( char * ) talloc_size ( mem_ctx , sbuf . st_size + 1 ) ;
2003-08-13 05:53:07 +04:00
if ( ! p ) return NULL ;
if ( read ( fd , p , sbuf . st_size ) ! = sbuf . st_size ) {
2005-07-10 05:10:09 +04:00
talloc_free ( p ) ;
2003-08-13 05:53:07 +04:00
return NULL ;
}
p [ sbuf . st_size ] = 0 ;
if ( size ) * size = sbuf . st_size ;
return p ;
}
/****************************************************************************
load a file into memory
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-10 05:10:09 +04:00
char * file_load ( const char * fname , size_t * size , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
int fd ;
char * p ;
if ( ! fname | | ! * fname ) return NULL ;
fd = open ( fname , O_RDONLY ) ;
if ( fd = = - 1 ) return NULL ;
2005-07-10 05:10:09 +04:00
p = fd_load ( fd , size , mem_ctx ) ;
2003-08-13 05:53:07 +04:00
close ( fd ) ;
return p ;
}
/*******************************************************************
mmap ( if possible ) or read a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void * map_file ( char * fname , size_t size )
{
size_t s2 = 0 ;
void * p = NULL ;
# ifdef HAVE_MMAP
2004-08-31 12:21:29 +04:00
int fd ;
fd = open ( fname , O_RDONLY , 0 ) ;
if ( fd = = - 1 ) {
DEBUG ( 2 , ( " Failed to load %s - %s \n " , fname , strerror ( errno ) ) ) ;
return NULL ;
}
p = mmap ( NULL , size , PROT_READ , MAP_SHARED | MAP_FILE , fd , 0 ) ;
close ( fd ) ;
if ( p = = MAP_FAILED ) {
DEBUG ( 1 , ( " Failed to mmap %s - %s \n " , fname , strerror ( errno ) ) ) ;
return NULL ;
2003-08-13 05:53:07 +04:00
}
# endif
if ( ! p ) {
2005-07-10 05:10:09 +04:00
p = file_load ( fname , & s2 , talloc_autofree_context ( ) ) ;
2003-08-13 05:53:07 +04:00
if ( ! p ) return NULL ;
if ( s2 ! = size ) {
DEBUG ( 1 , ( " incorrect size for %s - got %d expected %d \n " ,
2005-07-17 13:20:52 +04:00
fname , ( int ) s2 , ( int ) size ) ) ;
2005-07-10 05:10:09 +04:00
talloc_free ( p ) ;
2003-08-13 05:53:07 +04:00
return NULL ;
}
}
return p ;
}
/****************************************************************************
parse a buffer into lines
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-08-30 21:21:41 +04:00
static char * * file_lines_parse ( char * p , size_t size , int * numlines , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
int i ;
char * s , * * ret ;
if ( ! p ) return NULL ;
for ( s = p , i = 0 ; s < p + size ; s + + ) {
if ( s [ 0 ] = = ' \n ' ) i + + ;
}
2005-08-30 21:21:41 +04:00
ret = talloc_array ( mem_ctx , char * , i + 2 ) ;
2003-08-13 05:53:07 +04:00
if ( ! ret ) {
2005-08-30 21:21:41 +04:00
talloc_free ( p ) ;
2003-08-13 05:53:07 +04:00
return NULL ;
}
2005-08-30 21:21:41 +04:00
talloc_reference ( ret , p ) ;
2003-08-13 05:53:07 +04:00
memset ( ret , 0 , sizeof ( ret [ 0 ] ) * ( i + 2 ) ) ;
if ( numlines ) * numlines = i ;
ret [ 0 ] = p ;
for ( s = p , i = 0 ; s < p + size ; s + + ) {
if ( s [ 0 ] = = ' \n ' ) {
s [ 0 ] = 0 ;
i + + ;
ret [ i ] = s + 1 ;
}
if ( s [ 0 ] = = ' \r ' ) s [ 0 ] = 0 ;
}
return ret ;
}
/****************************************************************************
load a file into memory and return an array of pointers to lines in the file
2005-08-30 21:21:41 +04:00
must be freed with talloc_free ( ) .
2003-08-13 05:53:07 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-10 05:10:09 +04:00
char * * file_lines_load ( const char * fname , int * numlines , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
char * p ;
2005-08-30 21:21:41 +04:00
char * * lines ;
2003-08-13 05:53:07 +04:00
size_t size ;
2005-07-10 05:10:09 +04:00
p = file_load ( fname , & size , mem_ctx ) ;
2003-08-13 05:53:07 +04:00
if ( ! p ) return NULL ;
2005-08-30 21:21:41 +04:00
lines = file_lines_parse ( p , size , numlines , mem_ctx ) ;
talloc_free ( p ) ;
return lines ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
load a fd into memory and return an array of pointers to lines in the file
2005-08-30 21:21:41 +04:00
must be freed with talloc_free ( ) . If convert is true calls unix_to_dos on
2003-08-13 05:53:07 +04:00
the list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-07-10 05:10:09 +04:00
char * * fd_lines_load ( int fd , int * numlines , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
char * p ;
2005-08-30 21:21:41 +04:00
char * * lines ;
2003-08-13 05:53:07 +04:00
size_t size ;
2005-07-10 05:10:09 +04:00
p = fd_load ( fd , & size , mem_ctx ) ;
2003-08-13 05:53:07 +04:00
if ( ! p ) return NULL ;
2005-08-30 21:21:41 +04:00
lines = file_lines_parse ( p , size , numlines , mem_ctx ) ;
talloc_free ( p ) ;
return lines ;
2003-08-13 05:53:07 +04:00
}
/****************************************************************************
take a lislist of lines and modify them to produce a list where \ continues
a line
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void file_lines_slashcont ( char * * lines )
{
int i , j ;
for ( i = 0 ; lines [ i ] ; ) {
int len = strlen ( lines [ i ] ) ;
if ( lines [ i ] [ len - 1 ] = = ' \\ ' ) {
lines [ i ] [ len - 1 ] = ' ' ;
if ( lines [ i + 1 ] ) {
char * p = & lines [ i ] [ len ] ;
while ( p < lines [ i + 1 ] ) * p + + = ' ' ;
for ( j = i + 1 ; lines [ j ] ; j + + ) lines [ j ] = lines [ j + 1 ] ;
}
} else {
i + + ;
}
}
}
/*
save a lump of data into a file . Mostly used for debugging
*/
BOOL file_save ( const char * fname , void * packet , size_t length )
{
int fd ;
fd = open ( fname , O_WRONLY | O_CREAT | O_TRUNC , 0644 ) ;
if ( fd = = - 1 ) {
return False ;
}
if ( write ( fd , packet , length ) ! = ( size_t ) length ) {
return False ;
}
close ( fd ) ;
return True ;
}
2005-04-14 12:24:36 +04:00
/*
see if a file exists
*/
BOOL file_exists ( const char * path )
{
struct stat st ;
return ( stat ( path , & st ) = = 0 ) ;
}