Mercurial > gftp.yaz
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 |