@ -7,7 +7,6 @@
# include <ccan/read_write_all/read_write_all.h>
# include <ccan/short_types/short_types.h>
# include <ccan/str/hex/hex.h>
# include <ccan/tal/grab_file/grab_file.h>
# include <ccan/tal/path/path.h>
# include <ccan/tal/str/str.h>
# include <common/configdir.h>
@ -44,38 +43,12 @@
# include <wire/wire.h>
bool deprecated_apis = true ;
static bool opt_table_alloced = false ;
/* Declare opt_add_addr here, because we we call opt_add_addr
* and opt_announce_addr vice versa
*/
static char * opt_add_addr ( const char * arg , struct lightningd * ld ) ;
/* Tal wrappers for opt. */
static void * opt_allocfn ( size_t size )
{
return tal_arr_label ( NULL , char , size , TAL_LABEL ( " opt_allocfn " , " " ) ) ;
}
static void * tal_reallocfn ( void * ptr , size_t size )
{
if ( ! ptr ) {
/* realloc(NULL) call is to allocate opt_table */
if ( ! opt_table_alloced ) {
opt_table_alloced = true ;
return notleak ( opt_allocfn ( size ) ) ;
}
return opt_allocfn ( size ) ;
}
tal_resize_ ( & ptr , 1 , size , false ) ;
return ptr ;
}
static void tal_freefn ( void * ptr )
{
tal_free ( ptr ) ;
}
/* FIXME: Put into ccan/time. */
# define TIME_FROM_SEC(sec) { { .tv_nsec = 0, .tv_sec = sec } }
# define TIME_FROM_MSEC(msec) \
@ -250,38 +223,6 @@ static void opt_show_s32(char buf[OPT_SHOW_LEN], const s32 *u)
snprintf ( buf , OPT_SHOW_LEN , " % " PRIi32 , * u ) ;
}
static char * opt_set_network ( const char * arg , struct lightningd * ld )
{
assert ( arg ! = NULL ) ;
/* Set the global chainparams instance */
chainparams = chainparams_for_network ( arg ) ;
if ( ! chainparams )
return tal_fmt ( NULL , " Unknown network name '%s' " , arg ) ;
return NULL ;
}
static char * opt_set_testnet ( struct lightningd * ld )
{
return opt_set_network ( " testnet " , ld ) ;
}
static char * opt_set_signet ( struct lightningd * ld )
{
return opt_set_network ( " signet " , ld ) ;
}
static char * opt_set_mainnet ( struct lightningd * ld )
{
return opt_set_network ( " bitcoin " , ld ) ;
}
static void opt_show_network ( char buf [ OPT_SHOW_LEN ] ,
const struct lightningd * ld )
{
snprintf ( buf , OPT_SHOW_LEN , " %s " , chainparams - > network_name ) ;
}
static char * opt_set_rgb ( const char * arg , struct lightningd * ld )
{
assert ( arg ! = NULL ) ;
@ -688,121 +629,6 @@ static void check_config(struct lightningd *ld)
fatal ( " --always-use-proxy needs --proxy " ) ;
}
static void setup_default_config ( struct lightningd * ld )
{
if ( chainparams - > testnet )
ld - > config = testnet_config ;
else
ld - > config = mainnet_config ;
/* Set default PID file name to be per-network */
tal_free ( ld - > pidfile ) ;
ld - > pidfile = tal_fmt ( ld , " lightningd-%s.pid " , chainparams - > network_name ) ;
}
static int config_parse_line_number ;
static void config_log_stderr_exit ( const char * fmt , . . . )
{
char * msg ;
va_list ap ;
va_start ( ap , fmt ) ;
/* This is the format we expect:*/
if ( streq ( fmt , " %s: %.*s: %s " ) ) {
const char * argv0 = va_arg ( ap , const char * ) ;
unsigned int len = va_arg ( ap , unsigned int ) ;
const char * arg = va_arg ( ap , const char * ) ;
const char * problem = va_arg ( ap , const char * ) ;
assert ( argv0 ! = NULL ) ;
assert ( arg ! = NULL ) ;
assert ( problem ! = NULL ) ;
/*mangle it to remove '--' and add the line number.*/
msg = tal_fmt ( NULL , " %s line %d: %.*s: %s " ,
argv0 ,
config_parse_line_number , len - 2 , arg + 2 , problem ) ;
} else {
msg = tal_vfmt ( NULL , fmt , ap ) ;
}
va_end ( ap ) ;
fatal ( " %s " , msg ) ;
}
static void parse_include ( struct lightningd * ld ,
const char * filename ,
bool must_exist ,
bool early )
{
char * contents , * * lines ;
char * * all_args ; /*For each line: either `--`argument, include file, or NULL*/
char * argv [ 3 ] ;
int i , argc ;
contents = grab_file ( ld , filename ) ;
/* The default config doesn't have to exist, but if the config was
* specified on the command line it has to exist . */
if ( ! contents ) {
if ( must_exist )
fatal ( " Opening and reading %s: %s " ,
filename , strerror ( errno ) ) ;
return ;
}
lines = tal_strsplit ( contents , contents , " \r \n " , STR_EMPTY_OK ) ;
/* We have to keep all_args around, since opt will point into it */
all_args = notleak ( tal_arr ( ld , char * , tal_count ( lines ) - 1 ) ) ;
for ( i = 0 ; i < tal_count ( lines ) - 1 ; i + + ) {
if ( strstarts ( lines [ i ] , " # " ) ) {
all_args [ i ] = NULL ;
} else if ( strstarts ( lines [ i ] , " include " ) ) {
/* If relative, it's relative to current config file */
all_args [ i ] = path_join ( all_args ,
take ( path_dirname ( NULL ,
filename ) ) ,
lines [ i ] + strlen ( " include " ) ) ;
} else {
/* Only valid forms are "foo" and "foo=bar" */
all_args [ i ] = tal_fmt ( all_args , " --%s " , lines [ i ] ) ;
}
}
/*
For each line we construct a fake argc , argv commandline .
argv [ 1 ] is the only element that changes between iterations .
*/
argc = 2 ;
argv [ 0 ] = cast_const ( char * , filename ) ;
argv [ argc ] = NULL ;
for ( i = 0 ; i < tal_count ( all_args ) ; i + + ) {
if ( all_args [ i ] = = NULL )
continue ;
if ( ! strstarts ( all_args [ i ] , " -- " ) ) {
parse_include ( ld , all_args [ i ] , true , early ) ;
continue ;
}
config_parse_line_number = i + 1 ;
argv [ 1 ] = all_args [ i ] ;
if ( early ) {
opt_early_parse_incomplete ( argc , argv ,
config_log_stderr_exit ) ;
} else {
opt_parse ( & argc , argv , config_log_stderr_exit ) ;
argc = 2 ; /* opt_parse might have changed it */
}
}
tal_free ( contents ) ;
}
/**
* We turn the config file into cmdline arguments . @ early tells us
* whether to parse early options only ( and ignore any unknown ones ) ,
@ -819,7 +645,7 @@ static void opt_parse_from_config(struct lightningd *ld, bool early)
else
filename = path_join ( tmpctx , ld - > config_dir , " config " ) ;
parse_include ( ld , filename , ld - > config_filename ! = NULL , early ) ;
parse_include ( filename , ld - > config_filename ! = NULL , early ) ;
}
static char * test_subdaemons_and_exit ( struct lightningd * ld )
@ -839,9 +665,6 @@ static char *list_features_and_exit(struct lightningd *ld)
static char * opt_lightningd_usage ( struct lightningd * ld )
{
/* Reload config so that --help has the correct network defaults
* to display before it exits */
setup_default_config ( ld ) ;
char * extra = tal_fmt ( NULL , " \n A bitcoin lightning daemon (default "
" values shown for network: %s). " , chainparams - > network_name ) ;
opt_usage_and_exit ( extra ) ;
@ -884,73 +707,6 @@ static char *opt_start_daemon(struct lightningd *ld)
errx ( 1 , " Died with signal %u " , WTERMSIG ( exitcode ) ) ;
}
static char * opt_ignore_talstr ( const char * arg , char * * p )
{
return NULL ;
}
static char * opt_set_conf ( const char * arg , struct lightningd * ld )
{
/* This is a pass-through if arg is absolute */
tal_free ( ld - > config_filename ) ;
ld - > config_filename = path_join ( ld , path_cwd ( tmpctx ) , arg ) ;
return NULL ;
}
/* Just enough parsing to find config file, and other maintenance options
* which don ' t want us to create the lightning dir */
static void handle_minimal_config_opts ( struct lightningd * ld ,
int argc , char * argv [ ] )
{
/* First, they could specify a config, which specifies a lightning dir */
opt_register_early_arg ( " --conf=<file> " , opt_set_conf , NULL ,
ld ,
" Specify configuration file (default: <lightning-dir>/config) " ) ;
ld - > config_dir = NULL ;
opt_register_early_arg ( " --lightning-dir=<dir> " ,
opt_set_talstr , NULL ,
& ld - > config_dir ,
" Set working directory. All other files are relative to this " ) ;
/* List features immediately, before doing anything interesting */
opt_register_early_noarg ( " --list-features-only " ,
list_features_and_exit ,
ld , opt_hidden ) ;
/* Handle --version (and exit) here too: don't create lightning-dir for this */
opt_register_version ( ) ;
opt_early_parse_incomplete ( argc , argv , opt_log_stderr_exit ) ;
/* Corner case: if they specified a config filename, and didn't set
* set lightning - dir , read config file to get it ! */
if ( ld - > config_filename & & ! ld - > config_dir )
opt_parse_from_config ( ld , true ) ;
if ( ! ld - > config_dir )
ld - > config_dir = default_configdir ( ld ) ;
/* Now, reset and ignore those options from now on. */
opt_free_table ( ) ;
opt_table_alloced = false ;
opt_register_early_arg ( " --conf=<file> " , opt_ignore_talstr , NULL ,
& ld - > config_filename ,
" Specify configuration file (default: <lightning-dir>/config) " ) ;
opt_register_early_arg ( " --lightning-dir=<dir> " ,
opt_ignore_talstr , opt_show_charp ,
& ld - > config_dir ,
" Set working directory. All other files are relative to this " ) ;
ld - > config_dir = path_join ( ld , path_cwd ( tmpctx ) , take ( ld - > config_dir ) ) ;
ld - > wallet_dsn = tal_fmt ( ld , " sqlite3://%s/lightningd.sqlite3 " , ld - > config_dir ) ;
opt_register_early_arg ( " --wallet " , opt_set_talstr , NULL ,
& ld - > wallet_dsn ,
" Location of the wallet database. " ) ;
}
static void register_opts ( struct lightningd * ld )
{
/* This happens before plugins started */
@ -971,19 +727,6 @@ static void register_opts(struct lightningd *ld)
NULL , ld ,
" Disable a particular plugin by filename/name " ) ;
/* We need to know network early, so we can set defaults (which normal
* options can change ) */
opt_register_early_arg ( " --network " , opt_set_network , opt_show_network ,
ld ,
" Select the network parameters (bitcoin, testnet, "
" regtest, litecoin or litecoin-testnet) " ) ;
opt_register_early_noarg ( " --testnet " , opt_set_testnet , ld ,
" Alias for --network=testnet " ) ;
opt_register_early_noarg ( " --signet " , opt_set_signet , ld ,
" Alias for --network=signet " ) ;
opt_register_early_noarg ( " --mainnet " , opt_set_mainnet , ld ,
" Alias for --network=bitcoin " ) ;
/* This can effect commandline parsing */
opt_register_early_arg ( " --allow-deprecated-apis " ,
opt_set_bool_arg , opt_show_bool ,
@ -998,10 +741,10 @@ static void register_opts(struct lightningd *ld)
/* This immediately makes is a daemon. */
opt_register_early_noarg ( " --daemon " , opt_start_daemon , ld ,
" Run in the background, suppress stdout/stderr " ) ;
opt_register_early_arg ( " --wallet " , opt_set_talstr , NULL ,
& ld - > wallet_dsn ,
" Location of the wallet database. " ) ;
opt_register_arg ( " --rpc-file " , opt_set_talstr , opt_show_charp ,
& ld - > rpc_filename ,
" Set JSON-RPC socket (or /dev/tty) " ) ;
opt_register_noarg ( " --help|-h " , opt_lightningd_usage , ld ,
" Print this message. " ) ;
opt_register_arg ( " --bitcoin-datadir " , opt_set_talstr , NULL ,
@ -1177,11 +920,33 @@ void setup_color_and_alias(struct lightningd *ld)
void handle_early_opts ( struct lightningd * ld , int argc , char * argv [ ] )
{
/*~ These functions make ccan/opt use tal for allocations */
opt_set_alloc ( opt_allocfn , tal_reallocfn , tal_freefn ) ;
/* Make ccan/opt use tal for allocations */
setup_option_allocators ( ) ;
/*~ List features immediately, before doing anything interesting */
opt_register_early_noarg ( " --list-features-only " ,
list_features_and_exit ,
ld , opt_hidden ) ;
/*~ This does enough parsing to get us the base configuration options */
initial_config_opts ( ld , argc , argv ,
& ld - > config_filename ,
& ld - > config_dir ,
& ld - > rpc_filename ) ;
/* Copy in default config, to be modified by further options */
if ( chainparams - > testnet )
ld - > config = testnet_config ;
else
ld - > config = mainnet_config ;
/*~ Handle --conf and --lightning-dir super-early. */
handle_minimal_config_opts ( ld , argc , argv ) ;
/* Now we can initialize wallet_dsn */
ld - > wallet_dsn = tal_fmt ( ld , " sqlite3://%s/lightningd.sqlite3 " ,
ld - > config_dir ) ;
/* Set default PID file name to be per-network */
ld - > pidfile = tal_fmt ( ld , " lightningd-%s.pid " ,
chainparams - > network_name ) ;
/*~ Move into config dir: this eases path manipulation and also
* gives plugins a good place to store their stuff . */
@ -1207,9 +972,6 @@ void handle_early_opts(struct lightningd *ld, int argc, char *argv[])
/* Early cmdline options now override config file options. */
opt_early_parse_incomplete ( argc , argv , opt_log_stderr_exit ) ;
/* Now we know what network we're on, initialize defaults. */
setup_default_config ( ld ) ;
/* Finalize the logging subsystem now. */
logging_options_parsed ( ld - > log_book ) ;
}
@ -1282,10 +1044,7 @@ static void add_config(struct lightningd *ld,
/* Ignore hidden options (deprecated) */
} else if ( opt - > cb = = ( void * ) opt_usage_and_exit
| | opt - > cb = = ( void * ) version_and_exit
/* These two show up as --network= */
| | opt - > cb = = ( void * ) opt_set_testnet
| | opt - > cb = = ( void * ) opt_set_signet
| | opt - > cb = = ( void * ) opt_set_mainnet
| | opt - > cb = = ( void * ) opt_ignore_noarg
| | opt - > cb = = ( void * ) opt_lightningd_usage
| | opt - > cb = = ( void * ) test_subdaemons_and_exit
/* FIXME: we can't recover this. */
@ -1335,7 +1094,7 @@ static void add_config(struct lightningd *ld,
answer = buf ;
} else if ( opt - > cb_arg = = ( void * ) opt_set_talstr
| | opt - > cb_arg = = ( void * ) opt_set_charp
| | opt - > cb_arg = = ( void * ) opt_ignore_talstr ) {
| | opt - > cb_arg = = ( void * ) opt_ignore ) {
const char * arg = * ( char * * ) opt - > u . carg ;
if ( arg )
answer = tal_fmt ( name0 , " %s " , arg ) ;