1998-11-05 19:51:34 +03:00
/*
2002-01-30 09:08:46 +03:00
* Unix SMB / CIFS implementation .
* SMB parameters and setup
1998-11-05 19:51:34 +03:00
* Copyright ( C ) Andrew Tridgell 1992 - 1998 Modified by Jeremy Allison 1995.
2016-02-16 16:59:53 +03:00
*
1998-11-05 19:51:34 +03:00
* 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
2007-07-09 23:25:36 +04:00
* Software Foundation ; either version 3 of the License , or ( at your option )
1998-11-05 19:51:34 +03:00
* any later version .
2016-02-16 16:59:53 +03:00
*
1998-11-05 19:51:34 +03:00
* 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 .
2016-02-16 16:59:53 +03:00
*
1998-11-05 19:51:34 +03:00
* You should have received a copy of the GNU General Public License along with
2007-07-10 09:23:25 +04:00
* this program ; if not , see < http : //www.gnu.org/licenses/>.
1998-11-05 19:51:34 +03:00
*/
2016-02-16 19:09:43 +03:00
# include "replace.h"
# include "lib/util_file.h"
# include "lib/util/debug.h"
# include "lib/util/samba_util.h"
2015-10-12 16:57:34 +03:00
# include "lib/util/sys_rw.h"
2018-12-27 12:18:28 +03:00
# include "lib/util/sys_popen.h"
2016-02-16 19:01:04 +03:00
# include "lib/async_req/async_sock.h"
# include "lib/util/tevent_unix.h"
struct file_pload_state {
struct tevent_context * ev ;
size_t maxsize ;
int fd ;
uint8_t * buf ;
} ;
static int file_pload_state_destructor ( struct file_pload_state * s ) ;
static void file_pload_readable ( struct tevent_req * subreq ) ;
struct tevent_req * file_pload_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
const char * syscmd , size_t maxsize )
{
struct tevent_req * req , * subreq ;
struct file_pload_state * state ;
req = tevent_req_create ( mem_ctx , & state , struct file_pload_state ) ;
if ( req = = NULL ) {
return NULL ;
}
state - > ev = ev ;
state - > maxsize = maxsize ;
state - > fd = sys_popen ( syscmd ) ;
if ( state - > fd = = - 1 ) {
tevent_req_error ( req , errno ) ;
return tevent_req_post ( req , ev ) ;
}
talloc_set_destructor ( state , file_pload_state_destructor ) ;
subreq = wait_for_read_send ( state , state - > ev , state - > fd , false ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , file_pload_readable , req ) ;
return req ;
}
static int file_pload_state_destructor ( struct file_pload_state * s )
{
if ( s - > fd ! = - 1 ) {
sys_pclose ( s - > fd ) ;
s - > fd = - 1 ;
}
return 0 ;
}
static void file_pload_readable ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct file_pload_state * state = tevent_req_data (
req , struct file_pload_state ) ;
uint8_t buf [ 1024 ] ;
uint8_t * tmp ;
ssize_t nread ;
size_t bufsize ;
int err ;
bool ok ;
ok = wait_for_read_recv ( subreq , & err ) ;
TALLOC_FREE ( subreq ) ;
if ( ! ok ) {
tevent_req_error ( req , err ) ;
return ;
}
nread = sys_read ( state - > fd , buf , sizeof ( buf ) ) ;
if ( nread = = - 1 ) {
tevent_req_error ( req , errno ) ;
return ;
}
if ( nread = = 0 ) {
tevent_req_done ( req ) ;
return ;
}
bufsize = talloc_get_size ( state - > buf ) ;
if ( ( ( bufsize + nread ) < bufsize ) | |
( ( bufsize + nread + 1 ) < bufsize ) ) {
/* overflow */
tevent_req_error ( req , EMSGSIZE ) ;
return ;
}
if ( ( state - > maxsize ! = 0 ) & & ( ( bufsize + nread ) > state - > maxsize ) ) {
tevent_req_error ( req , EMSGSIZE ) ;
return ;
}
tmp = talloc_realloc ( state , state - > buf , uint8_t , bufsize + nread + 1 ) ;
if ( tevent_req_nomem ( tmp , req ) ) {
return ;
}
state - > buf = tmp ;
memcpy ( state - > buf + bufsize , buf , nread ) ;
state - > buf [ bufsize + nread ] = ' \0 ' ;
subreq = wait_for_read_send ( state , state - > ev , state - > fd , false ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , file_pload_readable , req ) ;
}
int file_pload_recv ( struct tevent_req * req , TALLOC_CTX * mem_ctx ,
uint8_t * * buf )
{
struct file_pload_state * state = tevent_req_data (
req , struct file_pload_state ) ;
int err ;
if ( tevent_req_is_unix_error ( req , & err ) ) {
return err ;
}
* buf = talloc_move ( mem_ctx , & state - > buf ) ;
tevent_req_received ( req ) ;
return 0 ;
}
1998-11-05 19:51:34 +03:00
2001-04-13 04:37:00 +04:00
2008-10-12 19:34:43 +04:00
/**
2004-09-01 05:33:55 +04:00
Load a pipe into memory and return an array of pointers to lines in the data
2014-12-26 17:42:40 +03:00
must be freed with TALLOC_FREE .
2008-10-12 19:34:43 +04:00
* */
2004-09-01 05:33:55 +04:00
2016-02-16 18:29:01 +03:00
char * * file_lines_pload ( TALLOC_CTX * mem_ctx , const char * syscmd ,
int * numlines )
2000-04-16 15:00:21 +04:00
{
char * p ;
size_t size ;
p = file_pload ( syscmd , & size ) ;
2004-09-01 05:33:55 +04:00
if ( ! p ) {
return NULL ;
}
2000-04-16 15:00:21 +04:00
2016-02-16 18:29:01 +03:00
return file_lines_parse ( p , size , numlines , mem_ctx ) ;
2001-10-11 11:42:52 +04:00
}