@@ -76,6 +76,7 @@ struct bitcoin_cli {
7676 int * exitstatus ;
7777 pid_t pid ;
7878 const char * * args ;
79+ const char * * stdinargs ;
7980 struct timeabs start ;
8081 enum bitcoind_prio prio ;
8182 char * output ;
@@ -95,7 +96,8 @@ static void add_arg(const char ***args, const char *arg TAKES)
9596 tal_arr_expand (args , arg );
9697}
9798
98- static const char * * gather_argsv (const tal_t * ctx , const char * cmd , va_list ap )
99+ /* If stdinargs is non-NULL, that is where we put additional args */
100+ static const char * * gather_argsv (const tal_t * ctx , const char * * * stdinargs , const char * cmd , va_list ap )
99101{
100102 const char * * args = tal_arr (ctx , const char * , 1 );
101103 const char * arg ;
@@ -128,23 +130,30 @@ static const char **gather_argsv(const tal_t *ctx, const char *cmd, va_list ap)
128130 // `-rpcpassword` argument - secrets in arguments can leak when listing
129131 // system processes.
130132 add_arg (& args , "-stdinrpcpass" );
133+ /* To avoid giant command lines, we use -stdin (avail since bitcoin 0.13) */
134+ if (stdinargs )
135+ add_arg (& args , "-stdin" );
131136
132137 add_arg (& args , cmd );
133- while ((arg = va_arg (ap , char * )) != NULL )
134- add_arg (& args , arg );
138+ while ((arg = va_arg (ap , char * )) != NULL ) {
139+ if (stdinargs )
140+ add_arg (stdinargs , arg );
141+ else
142+ add_arg (& args , arg );
143+ }
135144 add_arg (& args , NULL );
136145
137146 return args ;
138147}
139148
140149static LAST_ARG_NULL const char * *
141- gather_args (const tal_t * ctx , const char * cmd , ...)
150+ gather_args (const tal_t * ctx , const char * * * stdinargs , const char * cmd , ...)
142151{
143152 va_list ap ;
144153 const char * * ret ;
145154
146155 va_start (ap , cmd );
147- ret = gather_argsv (ctx , cmd , ap );
156+ ret = gather_argsv (ctx , stdinargs , cmd , ap );
148157 va_end (ap );
149158
150159 return ret ;
@@ -170,7 +179,7 @@ static struct io_plan *output_init(struct io_conn *conn, struct bitcoin_cli *bcl
170179static void next_bcli (enum bitcoind_prio prio );
171180
172181/* For printing: simple string of args (no secrets!) */
173- static char * args_string (const tal_t * ctx , const char * * args )
182+ static char * args_string (const tal_t * ctx , const char * * args , const char * * stdinargs )
174183{
175184 size_t i ;
176185 char * ret = tal_strdup (ctx , args [0 ]);
@@ -185,12 +194,16 @@ static char *args_string(const tal_t *ctx, const char **args)
185194 ret = tal_strcat (ctx , take (ret ), args [i ]);
186195 }
187196 }
197+ for (i = 0 ; i < tal_count (stdinargs ); i ++ ) {
198+ ret = tal_strcat (ctx , take (ret ), " " );
199+ ret = tal_strcat (ctx , take (ret ), stdinargs [i ]);
200+ }
188201 return ret ;
189202}
190203
191204static char * bcli_args (const tal_t * ctx , struct bitcoin_cli * bcli )
192205{
193- return args_string (ctx , bcli -> args );
206+ return args_string (ctx , bcli -> args , bcli -> stdinargs );
194207}
195208
196209/* Only set as destructor once bcli is in current. */
@@ -315,7 +328,10 @@ static void next_bcli(enum bitcoind_prio prio)
315328
316329 if (bitcoind -> rpcpass )
317330 write_all (in , bitcoind -> rpcpass , strlen (bitcoind -> rpcpass ));
318-
331+ for (size_t i = 0 ; i < tal_count (bcli -> stdinargs ); i ++ ) {
332+ write_all (in , "\n" , strlen ("\n" ));
333+ write_all (in , bcli -> stdinargs [i ], strlen (bcli -> stdinargs [i ]));
334+ }
319335 close (in );
320336
321337 bcli -> start = time_now ();
@@ -351,7 +367,8 @@ start_bitcoin_cliv(const tal_t *ctx,
351367 else
352368 bcli -> exitstatus = NULL ;
353369
354- bcli -> args = gather_argsv (bcli , method , ap );
370+ bcli -> stdinargs = tal_arr (bcli , const char * , 0 );
371+ bcli -> args = gather_argsv (bcli , & bcli -> stdinargs , method , ap );
355372 bcli -> stash = stash ;
356373
357374 list_add_tail (& bitcoind -> pending [bcli -> prio ], & bcli -> list );
@@ -994,14 +1011,14 @@ static struct command_result *getutxout(struct command *cmd,
9941011
9951012static void bitcoind_failure (struct plugin * p , const char * error_message )
9961013{
997- const char * * cmd = gather_args (bitcoind , "echo" , NULL );
1014+ const char * * cmd = gather_args (bitcoind , NULL , "echo" , NULL );
9981015 plugin_err (p , "\n%s\n\n"
9991016 "Make sure you have bitcoind running and that bitcoin-cli"
10001017 " is able to connect to bitcoind.\n\n"
10011018 "You can verify that your Bitcoin Core installation is"
10021019 " ready for use by running:\n\n"
10031020 " $ %s 'hello world'\n" , error_message ,
1004- args_string (cmd , cmd ));
1021+ args_string (cmd , cmd , NULL ));
10051022}
10061023
10071024/* Do some sanity checks on bitcoind based on the output of `getnetworkinfo`. */
@@ -1016,7 +1033,7 @@ static void parse_getnetworkinfo_result(struct plugin *p, const char *buf)
10161033 if (!result )
10171034 plugin_err (p , "Invalid response to '%s': '%s'. Can not "
10181035 "continue without proceeding to sanity checks." ,
1019- args_string (tmpctx , gather_args (bitcoind , "getnetworkinfo" , NULL )),
1036+ args_string (tmpctx , gather_args (bitcoind , NULL , "getnetworkinfo" , NULL ), NULL ),
10201037 buf );
10211038
10221039 /* Check that we have a fully-featured `estimatesmartfee`. */
@@ -1047,7 +1064,7 @@ static void wait_and_check_bitcoind(struct plugin *p)
10471064 int in , from , status ;
10481065 pid_t child ;
10491066 const char * * cmd = gather_args (
1050- bitcoind , "-rpcwait" , "-rpcwaittimeout=30" , "getnetworkinfo" , NULL );
1067+ bitcoind , NULL , "-rpcwait" , "-rpcwaittimeout=30" , "getnetworkinfo" , NULL );
10511068 char * output = NULL ;
10521069
10531070 child = pipecmdarr (& in , & from , & from , cast_const2 (char * * , cmd ));
0 commit comments