comparison lib/pty.c @ 210:82ebd1b05345

2003-7-6 Brian Masney <masneyb@gftp.org> * lib/pty.c lib/gftp.h - added gftp_exec_with_new_pty() and gftp_exec_without_new_pty() * lib/sshv2.c - use the 2 new functions above * lib/pty.c lib/gftp.h - split open_ptys() to _gftp_ptym_open() and _gftp_ptys_open() * lib/sslcommon.c - don't do thread setup if we are compiling against glib 1.2. I do not want to link against the pthread library because that would make the text port dependant on pthreads being installed on the box
author masneyb
date Sun, 06 Jul 2003 13:52:43 +0000
parents 8d933999bba6
children b8d14c2c3097
comparison
equal deleted inserted replaced
209:d79e2782eb1b 210:82ebd1b05345
22 #include "gftp.h" 22 #include "gftp.h"
23 23
24 #ifdef __sgi 24 #ifdef __sgi
25 25
26 char * 26 char *
27 get_pty_impl (void) 27 gftp_get_pty_impl (void)
28 { 28 {
29 return ("sgi"); 29 return ("sgi");
30 } 30 }
31 31
32 32
33 int 33 static int
34 open_ptys (gftp_request * request, int *fdm, int *fds) 34 _gftp_ptym_open (char *pts_name, size_t len, int *fds)
35 { 35 {
36 char *pts_name; 36 char *new_pts_name;
37 37 int fdm;
38 if ((pts_name = _getpty (fdm, O_RDWR, 0600, 0)) == NULL) 38
39 if ((new_pts_name = _getpty (&fdm, O_RDWR, 0600, 0)) == NULL)
39 return (GFTP_ERETRYABLE); 40 return (GFTP_ERETRYABLE);
40 41
41 if ((*fds = open (pts_name, O_RDWR)) < 0) 42 strncpy (pts_name, new_pts_name, len);
42 { 43
43 close (*fdm); 44 return (fdm);
45 }
46
47
48 static int
49 _gftp_ptys_open (int fdm, int fds, char *pts_name)
50 {
51 int new_fds;
52
53 if ((new_fds = open (pts_name, O_RDWR)) < 0)
54 {
55 close (fdm);
56 return (-1);
57 }
58
59 return (new_fds);
60 }
61
62 #elif HAVE_GRANTPT
63
64 char *
65 gftp_get_pty_impl (void)
66 {
67 return ("unix98");
68 }
69
70
71 static int
72 _gftp_ptym_open (char *pts_name, size_t len, int *fds)
73 {
74 char *new_pts_name;
75 int fdm;
76
77 if ((fdm = open ("/dev/ptmx", O_RDWR)) < 0)
78 return (GFTP_ERETRYABLE);
79
80 if (grantpt (fdm) < 0)
81 {
82 close (fdm);
44 return (GFTP_ERETRYABLE); 83 return (GFTP_ERETRYABLE);
45 } 84 }
46 85
47 return (0); 86 if (unlockpt (fdm) < 0)
48 } 87 {
49 88 close (fdm);
50 #elif HAVE_GRANTPT
51
52 char *
53 get_pty_impl (void)
54 {
55 return ("unix98");
56 }
57
58
59 int
60 open_ptys (gftp_request * request, int *fdm, int *fds)
61 {
62 char *pts_name;
63
64 if ((*fdm = open ("/dev/ptmx", O_RDWR)) < 0)
65 return (GFTP_ERETRYABLE);
66
67 if (grantpt (*fdm) < 0)
68 {
69 close (*fdm);
70 return (GFTP_ERETRYABLE); 89 return (GFTP_ERETRYABLE);
71 } 90 }
72 91
73 if (unlockpt (*fdm) < 0) 92 if ((new_pts_name = ptsname (fdm)) == NULL)
74 { 93 {
75 close (*fdm); 94 close (fdm);
76 return (GFTP_ERETRYABLE); 95 return (GFTP_ERETRYABLE);
77 } 96 }
78 97
79 if ((pts_name = ptsname (*fdm)) == NULL) 98 strncpy (pts_name, new_pts_name, len);
80 { 99
81 close (*fdm); 100 return (fdm);
82 return (GFTP_ERETRYABLE); 101 }
83 } 102
84 103
85 if ((*fds = open (pts_name, O_RDWR)) < 0) 104 static int
86 { 105 _gftp_ptys_open (int fdm, int fds, char *pts_name)
87 close (*fdm); 106 {
88 return (GFTP_ERETRYABLE); 107 int new_fds;
108
109 if ((new_fds = open (pts_name, O_RDWR)) < 0)
110 {
111 close (fdm);
112 return (-1);
89 } 113 }
90 114
91 #ifdef SYSV 115 #ifdef SYSV
92 /* I intentionally ignore these errors */ 116 /* I intentionally ignore these errors */
93 ioctl (*fds, I_PUSH, "ptem"); 117 ioctl (new_fds, I_PUSH, "ptem");
94 ioctl (*fds, I_PUSH, "ldterm"); 118 ioctl (new_fds, I_PUSH, "ldterm");
95 ioctl (*fds, I_PUSH, "ttcompat"); 119 ioctl (new_fds, I_PUSH, "ttcompat");
96 #endif 120 #endif
97 121
98 return (0); 122 return (new_fds);
99 } 123 }
100 124
101 #elif HAVE_OPENPTY 125 #elif HAVE_OPENPTY
102 126
103 char * 127 char *
104 get_pty_impl (void) 128 gftp_get_pty_impl (void)
105 { 129 {
106 return ("openpty"); 130 return ("openpty");
107 } 131 }
108 132
109 133
110 int 134 static int
111 open_ptys (gftp_request * request, int *fdm, int *fds) 135 _gftp_ptym_open (char *pts_name, size_t len, int *fds)
112 { 136 {
113 char *pts_name; 137 int fdm;
114 138
115 if (openpty (fdm, fds, &pts_name, NULL, NULL ) < 0) 139 if (openpty (&fdm, fds, pts_name, NULL, NULL) < 0)
116 return (GFTP_ERETRYABLE); 140 return (GFTP_ERETRYABLE);
117 141
118 ioctl (*fds, TIOCSCTTY, NULL); 142 ioctl (*fds, TIOCSCTTY, NULL);
119 143
120 return (0); 144 return (fdm);
145 }
146
147
148 static int
149 _gftp_ptys_open (int fdm, int fds, char *pts_name)
150 {
151 if (login_tty (fds) < 0)
152 return (GFTP_EFATAL);
153
154 return (fds);
121 } 155 }
122 156
123 #else /* !HAVE_OPENPTY */ 157 #else /* !HAVE_OPENPTY */
124 158
125 /* Fall back to *BSD... */ 159 /* Fall back to *BSD... */
126 160
127 char * 161 char *
128 get_pty_impl (void) 162 gftp_get_pty_impl (void)
129 { 163 {
130 return ("bsd"); 164 return ("bsd");
131 } 165 }
132 166
133 167
134 int 168 static int
135 open_ptys (gftp_request * request, int *fdm, int *fds) 169 _gftp_ptym_open (char *pts_name, size_t len, int *fds)
136 { 170 {
137 char pts_name[20], *pos1, *pos2; 171 char *pos1, *pos2;
138 172 int fdm;
139 strncpy (pts_name, "/dev/ptyXY", sizeof (pts_name)); 173
174 g_return_val_if_fail (len >= 10, GFTP_EFATAL);
175
176 strncpy (pts_name, "/dev/ptyXY", len);
140 for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++) 177 for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++)
141 { 178 {
142 pts_name[8] = *pos1; 179 pts_name[8] = *pos1;
143 for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++) 180 for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++)
144 { 181 {
145 pts_name[9] = *pos2; 182 pts_name[9] = *pos2;
146 if ((*fdm = open (pts_name, O_RDWR)) < 0) 183 if ((fdm = open (pts_name, O_RDWR)) < 0)
147 continue; 184 continue;
148 185
149 pts_name[5] = 't'; 186 pts_name[5] = 't';
150 chmod (pts_name, S_IRUSR | S_IWUSR); 187 chmod (pts_name, S_IRUSR | S_IWUSR);
151 chown (pts_name, getuid (), -1); 188 chown (pts_name, getuid (), -1);
152 189
153 if ((*fds = open (pts_name, O_RDWR)) < 0) 190 return (fdm);
154 { 191 }
155 pts_name[5] = 'p'; 192 }
156 continue; 193
157 } 194 return (GFTP_ERETRYABLE);
195 }
196
197
198 static int
199 _gftp_ptys_open (int fdm, int fds, char *pts_name)
200 {
201 int new_fds;
202
203 if ((new_fds = open (pts_name, O_RDWR)) < 0)
204 {
205 close (fdm);
206 return (-1);
207 }
158 208
159 #if defined(TIOCSCTTY) && !defined(CIBAUD) 209 #if defined(TIOCSCTTY) && !defined(CIBAUD)
160 ioctl (*fds, TIOCSCTTY, NULL); 210 ioctl (new_fds, TIOCSCTTY, NULL);
161 #endif 211 #endif
162 212
163 return (0); 213 return (new_fds);
164 }
165 }
166
167 return (GFTP_ERETRYABLE);
168 } 214 }
169 215
170 #endif /* __sgi */ 216 #endif /* __sgi */
171 217
172 218
173 int 219 static int
174 tty_raw (int fd) 220 _gftp_tty_raw (int fd)
175 { 221 {
176 struct termios buf; 222 struct termios buf;
177 223
178 if (tcgetattr (fd, &buf) < 0) 224 if (tcgetattr (fd, &buf) < 0)
179 return (-1); 225 return (-1);
193 return (-1); 239 return (-1);
194 return (0); 240 return (0);
195 } 241 }
196 242
197 243
244 static void
245 _gftp_close_all_fds (void)
246 {
247 int i, maxfds;
248
249 #ifdef HAVE_GETDTABLESIZE
250 maxfds = getdtablesize () - 1;
251 #elif defined (OPEN_MAX)
252 maxfds = OPEN_MAX;
253 #else
254 maxfds = -1;
255 #endif
256
257 for (i=3; i<maxfds; i++)
258 close (i);
259 }
260
261
262 pid_t
263 gftp_exec_without_new_pty (gftp_request * request, int *fdm, char **args)
264 {
265 pid_t child;
266 int s[2];
267
268 if (socketpair (AF_LOCAL, SOCK_STREAM, 0, s) < 0)
269 {
270 request->logging_function (gftp_logging_error, request,
271 _("Cannot create a socket pair: %s\n"),
272 g_strerror (errno));
273 return (-1);
274 }
275
276 if ((child = fork ()) == 0)
277 {
278 setsid ();
279
280 close (s[0]);
281
282 _gftp_tty_raw (s[1]);
283 dup2 (s[1], 0);
284 dup2 (s[1], 1);
285 dup2 (s[1], 2);
286 _gftp_close_all_fds ();
287
288 execvp (args[0], args);
289
290 printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno));
291 exit (1);
292 }
293 else if (child > 0)
294 {
295 close (s[1]);
296 _gftp_tty_raw (s[0]);
297 *fdm = s[0];
298 return (child);
299 }
300 else
301 {
302 request->logging_function (gftp_logging_error, request->user_data,
303 _("Cannot fork another process: %s\n"),
304 g_strerror (errno));
305 return (-1);
306 }
307 }
308
309
310 pid_t
311 gftp_exec_with_new_pty (gftp_request * request, int *fdm, char **args)
312 {
313 char pts_name[64];
314 pid_t child;
315 int fds;
316
317 *pts_name = '\0';
318 if ((*fdm = _gftp_ptym_open (pts_name, sizeof (pts_name), &fds)) < 0)
319 {
320 request->logging_function (gftp_logging_error, request->user_data,
321 _("Cannot open master pty %s: %s\n"), pts_name,
322 g_strerror (errno));
323 return (-1);
324 }
325
326 if ((child = fork ()) == 0)
327 {
328 setsid ();
329
330 if ((fds = _gftp_ptys_open (*fdm, fds, pts_name)) < 0)
331 {
332 printf ("Cannot open slave pts %s: %s\n", pts_name,
333 g_strerror (errno));
334 return (-1);
335 }
336
337 close (*fdm);
338
339 _gftp_tty_raw (fds);
340 dup2 (fds, 0);
341 dup2 (fds, 1);
342 dup2 (fds, 2);
343 _gftp_close_all_fds ();
344
345 execvp (args[0], args);
346
347 printf (_("Error: Cannot execute ssh: %s\n"), g_strerror (errno));
348 exit (1);
349 }
350 else if (child > 0)
351 {
352 _gftp_tty_raw (*fdm);
353 return (child);
354 }
355 else
356 {
357 request->logging_function (gftp_logging_error, request->user_data,
358 _("Cannot fork another process: %s\n"),
359 g_strerror (errno));
360 return (-1);
361 }
362 }
363