Add API: set-wrappid-path.
[wrappi.git] / lib / proto-ssh.c
1 /* wrappi
2  * Copyright (C) 2011-2012 Red Hat Inc.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include <config.h>
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/wait.h>
26
27 #include "wrappi.h"
28 #include "internal.h"
29
30 void
31 wrap_int_connect_ssh (wrap_h *w)
32 {
33   int rfd[2];
34   int wfd[2];
35
36   if (pipe (rfd) == -1) {
37     set_error_errno ("pipe");
38     return;
39   }
40
41   if (pipe (wfd) == -1) {
42     set_error_errno ("pipe");
43     close (rfd[0]);
44     close (rfd[1]);
45     return;
46   }
47
48   w->pid = fork ();
49   if (w->pid == -1) {
50     set_error_errno ("fork");
51     close (rfd[0]);
52     close (rfd[1]);
53     close (wfd[0]);
54     close (wfd[1]);
55     return;
56   }
57
58   if (w->pid == 0) {
59     /* Child process. */
60     close (wfd[1]);
61     close (rfd[0]);
62
63     close (0);
64     close (1);
65     dup2 (rfd[1], 1);
66     dup2 (wfd[0], 0);
67
68     execlp ("ssh",
69             "ssh",
70             "-T", "-o", "BatchMode=yes", "-e", "none",
71             w->hostname,
72             "sh", "-c", w->wrappid_path ? : "wrappid",
73             NULL);
74     perror ("ssh");
75     _exit (EXIT_FAILURE);
76   }
77
78   /* Parent process. */
79   close (wfd[0]);
80   close (rfd[1]);
81
82   if (w->rfp) {
83     fclose (w->rfp);
84     w->rfp = NULL;
85   }
86
87   if (w->wfp) {
88     fclose (w->wfp);
89     w->wfp = NULL;
90   }
91
92   w->rfp = fdopen (rfd[0], "r");
93   if (w->rfp == NULL) {
94     set_error_errno ("fdopen: rfp");
95     close (rfd[0]);
96     close (wfd[1]);
97     waitpid (w->pid, NULL, 0);
98     w->pid = 0;
99     return;
100   }
101
102   w->wfp = fdopen (wfd[1], "w");
103   if (w->wfp == NULL) {
104     set_error_errno ("fdopen: wfp");
105     fclose (w->rfp);
106     w->rfp = NULL;
107     close (wfd[1]);
108     waitpid (w->pid, NULL, 0);
109     w->pid = 0;
110     return;
111   }
112 }