/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- connectToRemotePeer
- dummySshdProcess
- main
1 #include <unistd.h>
2 #include <sys/stat.h>
3 #include <sys/fcntl.h>
4 #include <sys/types.h>
5 #include <sys/wait.h>
6 #include <sys/errno.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <assert.h>
12 #include <string.h>
13 #include "ssh.h"
14 #include "util_ipc.h"
15
16 using dmtcp::Util::sendFd;
17
18 static pid_t childPid = -1;
19 static int remotePeerSock = -1;
20
21 // Connect to dmtcp_ssh process
22 static void connectToRemotePeer(char *host, int port)
23 {
24 struct sockaddr_in saddr;
25 int sock = socket(AF_INET, SOCK_STREAM, 0);
26 if (sock == -1) {
27 perror("Error creating socket: ");
28 exit(0);
29 }
30 memset(&saddr, 0, sizeof(saddr));
31 saddr.sin_family = AF_INET;
32 if (inet_aton(host, &saddr.sin_addr) == -1) {
33 perror("inet_aton failed");
34 exit(0);
35 }
36 saddr.sin_port = htons(port);
37
38 if (connect(sock, (sockaddr *)&saddr, sizeof saddr) == -1) {
39 perror("Error connecting");
40 exit(0);
41 }
42 remotePeerSock = sock;
43 }
44
45 static void dummySshdProcess(char *listenAddr)
46 {
47 int fd;
48 struct sockaddr_un addr;
49 socklen_t len;
50 addr.sun_family = AF_UNIX;
51 addr.sun_path[0] = '\0';
52 strcpy(&addr.sun_path[1], listenAddr);
53 len = sizeof(addr.sun_family) + strlen(listenAddr) + 1;
54 int pipefd[2];
55 char buf[16];
56 ssize_t ret;
57
58 if (pipe(pipefd) == -1) {
59 perror("pipe failed.");
60 abort();
61 }
62
63 int sendfd = socket(AF_UNIX, SOCK_DGRAM, 0);
64 fd = STDIN_FILENO;
65 if (sendFd(sendfd, fd, &fd, sizeof(fd), addr, len) == -1) {
66 perror("sendFd failed.");
67 abort();
68 };
69 fd = STDOUT_FILENO;
70 if (sendFd(sendfd, fd, &fd, sizeof(fd), addr, len) == -1) {
71 perror("sendFd failed.");
72 abort();
73 };
74 fd = STDERR_FILENO;
75 if (sendFd(sendfd, fd, &fd, sizeof(fd), addr, len) == -1) {
76 perror("sendFd failed.");
77 abort();
78 };
79 fd = pipefd[1];
80 if (sendFd(sendfd, fd, &fd, sizeof(fd), addr, len) == -1) {
81 perror("sendFd failed.");
82 abort();
83 };
84 close(sendfd);
85
86 close(pipefd[1]);
87
88 do {
89 // When the original dmtcp_sshd process quits, read would return '0'.
90 ret = read(pipefd[0], buf, sizeof(buf));
91 } while (ret == -1 && errno == EINTR);
92 exit(0);
93 }
94
95 int main(int argc, char *argv[], char *envp[])
96 {
97 int in[2], out[2], err[2];
98 char *host;
99 int port;
100
101 if (argc < 2) {
102 printf("***ERROR: This program shouldn't be used directly.\n");
103 exit(1);
104 }
105
106 if (strcmp(argv[1], "--listenAddr") == 0) {
107 dummySshdProcess(argv[2]);
108 printf("ERROR: Not Implemented\n");
109 assert(0);
110 }
111
112 if (strcmp(argv[1], "--host") != 0) {
113 printf("Missing --host argument");
114 assert(0);
115 }
116 host = argv[2];
117
118 if (strcmp(argv[3], "--port") != 0) {
119 printf("Missing --port argument");
120 exit(0);
121 }
122 port = atoi(argv[4]);
123
124 connectToRemotePeer(host, port);
125
126 if (pipe(in) != 0) {
127 perror("Error creating pipe: ");
128 }
129 if (pipe(out) != 0) {
130 perror("Error creating pipe: ");
131 }
132 if (pipe(err) != 0) {
133 perror("Error creating pipe: ");
134 }
135
136 childPid = fork();
137 if (childPid == 0) {
138 close(remotePeerSock);
139 close(in[1]);
140 close(out[0]);
141 close(err[0]);
142 dup2(in[0], STDIN_FILENO);
143 dup2(out[1], STDOUT_FILENO);
144 dup2(err[1], STDERR_FILENO);
145 close(in[0]);
146 close(out[1]);
147 close(err[1]);
148
149 execvp(argv[5], &argv[5]);
150 printf("%s:%d DMTCP Error detected. Failed to exec.", __FILE__, __LINE__);
151 abort();
152 }
153
154 close(in[0]);
155 close(out[1]);
156 close(err[1]);
157
158 int child_stdinfd = in[1];
159 int child_stdoutfd = out[0];
160 int child_stderrfd = err[0];
161
162 assert(dmtcp_ssh_register_fds);
163 dmtcp_ssh_register_fds(true, child_stdinfd, child_stdoutfd, child_stderrfd,
164 remotePeerSock, 0);
165
166 client_loop(child_stdinfd, child_stdoutfd, child_stderrfd, remotePeerSock);
167 int status;
168 pid_t ret = wait(&status);
169 assert(ret == childPid);
170 return status;
171 }