mount does now work in server and standalone mode.
[gnupg.git] / g13 / runner.c
1 /* runner.c - Run and watch the backend engines
2  * Copyright (C) 2009 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <assert.h>
27 #include <pth.h>
28
29 #include "g13.h"
30 #include "i18n.h"
31 #include "keyblob.h"
32 #include "runner.h"
33 #include "../common/exechelp.h"
34
35
36 /* The runner object.  */
37 struct runner_s
38 {
39   char *name;   /* The name of this runner.  */
40
41   int spawned;  /* True if runner_spawn has been called.  */
42   pth_t threadid; /* The TID of the runner thread.  */
43   runner_t next_running; /* Builds a list of all running threads.  */
44   int canceled;     /* Set if a cancel has already been send once.  */
45
46   int cancel_flag;  /* If set the thread should terminate itself.  */
47
48
49   /* We use a reference counter to know when it is safe to remove the
50      object.  Lackiong an explicit ref fucntion this counter will take
51      only these two values:
52
53      1 = Thread not running or only the thread is still running.
54      2 = Thread is running and someone is holding a reference.  */
55   int refcount; 
56
57   pid_t pid;  /* PID of the backend's process (the engine).  */
58   int in_fd;  /* File descriptors to read from the engine.  */
59   int out_fd; /* File descriptors to write to the engine.  */
60   engine_handler_fnc_t handler;  /* The handler functions.  */
61   engine_handler_cleanup_fnc_t handler_cleanup;
62   void *handler_data;  /* Private data of HANDLER and HANDLER_CLEANUP.  */
63
64   /* Instead of IN_FD we use an estream.  Note that the runner thread
65      may close the stream and set status_fp to NULL at any time.  Thus
66      it won't be a good idea to use it while the runner thread is
67      running.  */
68   estream_t status_fp;
69 };
70
71
72 /* The head of the list of all running threads.  */
73 static runner_t running_threads;
74
75
76
77 \f
78 /* Write NBYTES of BUF to file descriptor FD. */
79 static int
80 writen (int fd, const void *buf, size_t nbytes)
81 {
82   size_t nleft = nbytes;
83   int nwritten;
84   
85   while (nleft > 0)
86     {
87       nwritten = pth_write (fd, buf, nleft);
88       if (nwritten < 0)
89         {
90           if (errno == EINTR)
91             nwritten = 0;
92           else
93             return -1;
94         }
95       nleft -= nwritten;
96       buf = (const char*)buf + nwritten;
97     }
98     
99   return 0;
100 }
101
102
103 static int
104 check_already_spawned (runner_t runner, const char *funcname)
105 {
106   if (runner->spawned)
107     {
108       log_error ("BUG: runner already spawned - ignoring call to %s\n",
109                  funcname);
110       return 1;
111     }
112   else
113     return 0;
114 }
115
116
117 /* Return the number of active threads.  */
118 unsigned int
119 runner_get_threads (void)
120 {
121   unsigned int n = 0;
122   runner_t r;
123
124   for (r = running_threads; r; r = r->next_running)
125     n++;
126   return n;
127 }
128
129
130 /* The public release function. */
131 void
132 runner_release (runner_t runner)
133 {
134   if (!runner)
135     return;
136
137   if (!--runner->refcount)
138     return;
139
140   es_fclose (runner->status_fp);
141   if (runner->in_fd != -1)
142     close (runner->in_fd);
143   if (runner->out_fd != -1)
144     close (runner->out_fd);
145   
146   /* Fixme: close the process. */
147
148   /* Tell the engine to release its data.  */
149   if (runner->handler_cleanup)
150     runner->handler_cleanup (runner->handler_data);
151
152   if (runner->pid != (pid_t)(-1))
153     {
154       /* The process has not been cleaned up - do it now.  */
155       gnupg_kill_process (runner->pid);
156       /* (Actually we should use the program name and not the
157           arbitrary NAME of the runner object.  However it does not
158           matter because that information is only used for
159           diagnostics.)  */
160       gnupg_wait_process (runner->name, runner->pid, NULL);
161     }
162
163   xfree (runner->name);
164   xfree (runner);
165 }
166
167
168 /* Create a new runner context.  On success a new runner object is
169    stored at R_RUNNER.  On failure NULL is stored at this address and
170    an error code returned.  */
171 gpg_error_t 
172 runner_new (runner_t *r_runner, const char *name)
173 {
174   runner_t runner;
175
176   *r_runner = NULL;
177
178   runner = xtrycalloc (1, sizeof *runner);
179   if (!runner)
180     return gpg_error_from_syserror ();
181   runner->name = xtrystrdup (name? name: "[unknown]");
182   if (!runner->name)
183     {
184       xfree (runner);
185       return gpg_error_from_syserror ();
186     }
187   runner->refcount = 1;
188   runner->pid = (pid_t)(-1);
189   runner->in_fd = -1;
190   runner->out_fd = -1;
191   
192
193   *r_runner = runner;
194   return 0;
195 }
196
197
198 /* A runner usually maintaines two file descriptors to control the
199    backend engine.  This function is used to set these file
200    descriptors.  The function takes ownership of these file
201    descriptors.  IN_FD will be used to read from engine and OUT_FD to
202    send data to the engine. */
203 void
204 runner_set_fds (runner_t runner, int in_fd, int out_fd)
205 {
206   if (check_already_spawned (runner, "runner_set_fds"))
207     return;
208
209   if (runner->in_fd != -1)
210     close (runner->in_fd);
211   if (runner->out_fd != -1)
212     close (runner->out_fd);
213   runner->in_fd = in_fd;
214   runner->out_fd = out_fd;
215 }
216
217
218 /* Set the PID of the backend engine.  After this call the engine is
219    owned by the runner object.  */
220 void
221 runner_set_pid (runner_t runner, pid_t pid)
222 {
223   if (check_already_spawned (runner, "runner_set_fds"))
224     return;
225
226   runner->pid = pid;
227 }
228
229
230 /* Register the engine handler fucntions HANDLER and HANDLER_CLEANUP
231    and its private HANDLER_DATA with RUNNER.  */
232 void
233 runner_set_handler (runner_t runner,
234                     engine_handler_fnc_t handler, 
235                     engine_handler_cleanup_fnc_t handler_cleanup, 
236                     void *handler_data)
237 {
238   if (check_already_spawned (runner, "runner_set_handler"))
239     return;
240
241   runner->handler = handler;
242   runner->handler_cleanup = handler_cleanup;
243   runner->handler_data = handler_data;
244 }
245
246
247 /* The thread spawned by runner_spawn.  */
248 static void *
249 runner_thread (void *arg)
250 {
251   runner_t runner = arg;
252   gpg_error_t err = 0;
253
254   log_debug ("starting runner thread\n");
255   /* If a status_fp is available, the thread's main task is to read
256      from that stream and invoke the backend's handler function.  This
257      is done on a line by line base and the line length is limited to
258      a reasonable value (about 1000 characters). Other work will
259      continue either due to an EOF of the stream or by demand of the
260      engine.  */
261   if (runner->status_fp)
262     {
263       int c, cont_line;
264       unsigned int pos;
265       char buffer[1024];
266       estream_t fp = runner->status_fp;
267
268       pos = 0;
269       cont_line = 0;
270       while (!err && !runner->cancel_flag && (c=es_getc (fp)) != EOF)
271         {
272           buffer[pos++] = c;
273           if (pos >= sizeof buffer - 5 || c == '\n')
274             {
275               buffer[pos - (c == '\n')] = 0;
276               if (opt.verbose)
277                 log_info ("%s%s: %s\n", 
278                           runner->name, cont_line? "(cont)":"", buffer);
279               /* We handle only complete lines and ignore any stuff we
280                  possibly had to truncate.  That is - at least for the
281                  encfs engine - not an issue because our changes to
282                  the tool make sure that only relatively short prompt
283                  lines are of interest.  */
284               if (!cont_line && runner->handler) 
285                 err = runner->handler (runner->handler_data,
286                                        runner, buffer);
287               pos = 0;
288               cont_line = (c != '\n');
289             }
290         }
291       if (!err && runner->cancel_flag)
292         log_debug ("runner thread noticed cancel flag\n");
293       else
294         log_debug ("runner thread saw EOF\n");
295       if (pos)
296         {
297           buffer[pos] = 0;
298           if (opt.verbose)
299             log_info ("%s%s: %s\n",
300                       runner->name, cont_line? "(cont)":"", buffer);
301           if (!cont_line && !err && runner->handler) 
302             err = runner->handler (runner->handler_data,
303                                           runner, buffer);
304         }
305       if (!err && es_ferror (fp))
306         {
307           err = gpg_error_from_syserror ();
308           log_error ("error reading from %s: %s\n",
309                      runner->name, gpg_strerror (err));
310         }
311
312       runner->status_fp = NULL;
313       es_fclose (fp);
314       log_debug ("runner thread closed status fp\n");
315     }
316
317   /* Now wait for the process to finish.  */
318   if (!err && runner->pid != (pid_t)(-1))
319     {
320       int exitcode;
321
322       log_debug ("runner thread waiting ...\n");
323       err = gnupg_wait_process (runner->name, runner->pid, &exitcode);
324       runner->pid = (pid_t)(-1);
325       if (err)
326         log_error ("running `%s' failed (exitcode=%d): %s\n",
327                    runner->name, exitcode, gpg_strerror (err));
328       log_debug ("runner thread waiting finished\n");
329     }
330
331   /* Get rid of the runner object (note: it is refcounted).  */
332   log_debug ("runner thread releasing runner ...\n");
333   {
334     runner_t r, rprev;
335     
336     for (r = running_threads, rprev = NULL; r; rprev = r, r = r->next_running)
337       if (r == runner)
338         {
339           if (!rprev)
340             running_threads = r->next_running;
341           else
342             rprev->next_running = r->next_running;
343           r->next_running = NULL;
344           break;
345         }
346   }
347   runner_release (runner);
348   log_debug ("runner thread runner released\n");
349   
350   return NULL;
351 }
352
353
354 /* Spawn a new thread to let RUNNER work as a coprocess.  */
355 gpg_error_t
356 runner_spawn (runner_t runner)
357 {
358   gpg_error_t err;
359   pth_attr_t tattr;
360   pth_t tid;
361   
362   if (check_already_spawned (runner, "runner_spawn"))
363     return gpg_error (GPG_ERR_BUG);
364
365   /* In case we have an input fd, open it as an estream so that the
366      Pth scheduling will work.  The stdio functions don't work with
367      Pth because they don't call the pth counterparts of read and
368      write unless linker tricks are used.  */
369   if (runner->in_fd != -1)
370     {
371       estream_t fp;
372       
373       fp = es_fdopen (runner->in_fd, "r");
374       if (!fp)
375         {
376           err = gpg_error_from_syserror ();
377           log_error ("can't fdopen pipe for reading: %s\n", gpg_strerror (err));
378           return err;
379         }
380       runner->status_fp = fp;
381       runner->in_fd = -1;  /* Now owned by status_fp.  */
382     }
383
384   tattr = pth_attr_new ();
385   pth_attr_set (tattr, PTH_ATTR_JOINABLE, 1);
386   pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
387   pth_attr_set (tattr, PTH_ATTR_NAME, runner->name);
388   
389   tid = pth_spawn (tattr, runner_thread, runner);
390   if (!tid)
391     {
392       err = gpg_error_from_syserror ();
393       log_error ("error spawning runner thread: %s\n", gpg_strerror (err));
394       return err;
395     }
396   /* The scheduler has not yet kicked in, thus we can safely set the
397      spawned flag and the tid.  */
398   runner->spawned = 1;
399   runner->threadid = tid;
400   runner->next_running = running_threads;
401   running_threads = runner;
402
403   pth_attr_destroy (tattr);
404
405   /* The runner thread is now runnable.  */
406
407   return 0;
408 }
409
410
411 /* Cancel a running thread.  */
412 void
413 runner_cancel (runner_t runner)
414 {
415   /* Warning: runner_cancel_all has knowledge of this code.  */
416   if (runner->spawned)
417     {
418       runner->canceled = 1;  /* Mark that we canceled this one already.  */
419       /* FIXME: This does only work if the thread emits status lines.  We
420          need to change the trhead to wait on an event.  */
421       runner->cancel_flag = 1;
422       /* For now we use the brutal way and kill the process. */
423       gnupg_kill_process (runner->pid);
424     }
425 }
426
427
428 /* Cancel all runner threads.  */
429 void
430 runner_cancel_all (void)
431 {
432   runner_t r;
433
434   do 
435     {
436       for (r = running_threads; r; r = r->next_running)
437         if (r->spawned && !r->canceled)
438           {
439             runner_cancel (r);
440             break;
441           }
442     }
443   while (r);
444 }
445
446
447 /* Send a line of data down to the engine.  This line may not contain
448    a binary Nul or a LF character.  This function is used by the
449    engine's handler.  */
450 gpg_error_t 
451 runner_send_line (runner_t runner, const void *data, size_t datalen)
452 {
453   gpg_error_t err = 0;
454
455   if (!runner->spawned)
456     {
457       log_error ("BUG: runner for %s not spawned\n", runner->name);
458       err = gpg_error (GPG_ERR_INTERNAL);
459     }
460   else if (runner->out_fd == -1)
461     {
462       log_error ("no output file descriptor for runner %s\n", runner->name);
463       err = gpg_error (GPG_ERR_EBADF);
464     }
465   else if (data && datalen)
466     {
467       if (memchr (data, '\n', datalen))
468         {
469           log_error ("LF detected in response data\n");
470           err = gpg_error (GPG_ERR_BUG);
471         }
472       else if (memchr (data, 0, datalen))
473         {
474           log_error ("Nul detected in response data\n");
475           err = gpg_error (GPG_ERR_BUG);
476         }
477       else if (writen (runner->out_fd, data, datalen))
478         err = gpg_error_from_syserror ();
479     }
480
481   if (!err)
482     if (writen (runner->out_fd, "\n", 1))
483       err = gpg_error_from_syserror ();
484   
485   return err;
486 }