1
|
1 /*****************************************************************************/
|
|
2 /* misc.c - general purpose routines */
|
|
3 /* Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org> */
|
|
4 /* */
|
|
5 /* This program is free software; you can redistribute it and/or modify */
|
|
6 /* it under the terms of the GNU General Public License as published by */
|
|
7 /* the Free Software Foundation; either version 2 of the License, or */
|
|
8 /* (at your option) any later version. */
|
|
9 /* */
|
|
10 /* This program is distributed in the hope that it will be useful, */
|
|
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
|
13 /* GNU General Public License for more details. */
|
|
14 /* */
|
|
15 /* You should have received a copy of the GNU General Public License */
|
|
16 /* along with this program; if not, write to the Free Software */
|
|
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */
|
|
18 /*****************************************************************************/
|
|
19
|
|
20 #include "gftp.h"
|
|
21 #include "options.h"
|
|
22
|
|
23 char *
|
|
24 insert_commas (unsigned long number, char *dest_str, size_t dest_len)
|
|
25 {
|
|
26 char *frompos, *topos, src[50], *dest;
|
|
27 int len, num, rem, i;
|
|
28
|
|
29 if (dest_str != NULL)
|
|
30 *dest_str = '\0';
|
13
|
31 len = (number > 0 ? log10 (number) : 0) + 1;
|
1
|
32
|
|
33 if (len <= 0)
|
|
34 {
|
|
35 if (dest_str != NULL)
|
|
36 strncpy (dest_str, "0", dest_len);
|
|
37 else
|
|
38 dest_str = g_strconcat ("0", NULL);
|
|
39 return (dest_str);
|
|
40 }
|
|
41
|
|
42 len += len / 3;
|
|
43 if (dest_str != NULL && len > dest_len)
|
|
44 {
|
|
45
|
|
46 for (i=0; i<dest_len - 1; i++)
|
|
47 dest_str[i] = 'X';
|
|
48 dest_str[dest_len - 1] = '\0';
|
|
49 return (dest_str);
|
|
50 }
|
|
51
|
|
52 if (dest_str == NULL)
|
|
53 dest = g_malloc0 (len);
|
|
54 else
|
|
55 dest = dest_str;
|
|
56
|
|
57 g_snprintf (src, sizeof (src), "%ld", number);
|
|
58
|
|
59 num = strlen (src) / 3 - 1;
|
|
60 rem = strlen (src) % 3;
|
|
61 frompos = src;
|
|
62 topos = dest;
|
|
63 for (i = 0; i < rem; i++)
|
|
64 *topos++ = *frompos++;
|
|
65
|
|
66 if (*frompos != '\0')
|
|
67 {
|
|
68 if (rem != 0)
|
|
69 *topos++ = ',';
|
|
70 while (num > 0)
|
|
71 {
|
|
72 for (i = 0; i < 3; i++)
|
|
73 *topos++ = *frompos++;
|
|
74 *topos++ = ',';
|
|
75 num--;
|
|
76 }
|
|
77 for (i = 0; i < 3; i++)
|
|
78 *topos++ = *frompos++;
|
|
79 }
|
|
80 *topos = '\0';
|
|
81 return (dest);
|
|
82 }
|
|
83
|
|
84
|
|
85 long
|
|
86 file_countlf (int filefd, long endpos)
|
|
87 {
|
|
88 char tempstr[255];
|
|
89 long num, mypos;
|
|
90 ssize_t n;
|
|
91 int i;
|
|
92
|
|
93 mypos = num = 0;
|
|
94 lseek (filefd, 0, SEEK_SET);
|
|
95 while ((n = read (filefd, tempstr, sizeof (tempstr))) > 0)
|
|
96 {
|
|
97 for (i = 0; i < n; i++)
|
|
98 {
|
|
99 if ((tempstr[i] == '\n') && (i > 0) && (tempstr[i - 1] != '\r')
|
|
100 && (endpos == 0 || mypos + i <= endpos))
|
|
101 ++num;
|
|
102 }
|
|
103 mypos += n;
|
|
104 }
|
|
105 lseek (filefd, 0, SEEK_SET);
|
|
106 return (num);
|
|
107 }
|
|
108
|
|
109
|
|
110 char *
|
|
111 alltrim (char *str)
|
|
112 {
|
|
113 char *pos, *newpos;
|
|
114 int diff;
|
|
115
|
|
116 pos = str + strlen (str) - 1;
|
|
117 while (pos >= str && *pos == ' ')
|
|
118 *pos-- = '\0';
|
|
119
|
|
120 pos = str;
|
|
121 diff = 0;
|
|
122 while (*pos++ == ' ')
|
|
123 diff++;
|
|
124
|
|
125 if (diff == 0)
|
|
126 return (str);
|
|
127
|
|
128 pos = str + diff;
|
|
129 newpos = str;
|
|
130 while (*pos != '\0')
|
|
131 *newpos++ = *pos++;
|
|
132 *newpos = '\0';
|
|
133
|
|
134 return (str);
|
|
135 }
|
|
136
|
|
137
|
|
138 char *
|
|
139 expand_path (const char *src)
|
|
140 {
|
|
141 char *str, *pos, *endpos, *prevpos, *newstr, *tempstr, tempchar;
|
|
142 struct passwd *pw;
|
|
143
|
|
144 pw = NULL;
|
|
145 str = g_malloc (strlen (src) + 1);
|
|
146 strcpy (str, src);
|
|
147
|
|
148 if (*str == '~')
|
|
149 {
|
|
150 if (*(str + 1) == '/' || *(str + 1) == '\0')
|
|
151 pw = getpwuid (geteuid ());
|
|
152 else
|
|
153 {
|
|
154 if ((pos = strchr (str, '/')) != NULL)
|
|
155 *pos = '\0';
|
|
156
|
|
157 pw = getpwnam (str + 1);
|
|
158
|
|
159 if (pos != NULL)
|
|
160 *pos = '/';
|
|
161 }
|
|
162 }
|
|
163
|
|
164 endpos = str;
|
|
165 newstr = NULL;
|
|
166 while ((pos = strchr (endpos, '/')) != NULL)
|
|
167 {
|
|
168 pos++;
|
|
169 while (*pos == '/')
|
|
170 pos++;
|
|
171 if ((endpos = strchr (pos, '/')) == NULL)
|
|
172 endpos = pos + strlen (pos);
|
|
173 tempchar = *endpos;
|
|
174 *endpos = '\0';
|
|
175 if (strcmp (pos, "..") == 0)
|
|
176 {
|
|
177 *(pos - 1) = '\0';
|
|
178 if (newstr != NULL && (prevpos = strrchr (newstr, '/')) != NULL)
|
|
179 *prevpos = '\0';
|
|
180 }
|
|
181 else if (strcmp (pos, ".") != 0)
|
|
182 {
|
|
183 if (newstr == NULL)
|
|
184 newstr = g_strconcat (pos - 1, NULL);
|
|
185 else
|
|
186 {
|
|
187 tempstr = g_strconcat (newstr, pos - 1, NULL);
|
|
188 g_free (newstr);
|
|
189 newstr = tempstr;
|
|
190 }
|
|
191 }
|
|
192 *endpos = tempchar;
|
|
193 if (*endpos == '\0')
|
|
194 break;
|
|
195 endpos = pos + 1;
|
|
196 }
|
|
197
|
|
198 if (newstr == NULL || *newstr == '\0')
|
|
199 {
|
|
200 if (newstr != NULL)
|
|
201 g_free (newstr);
|
|
202 newstr = g_malloc0 (2);
|
|
203 *newstr = '/';
|
|
204 }
|
|
205
|
|
206 g_free (str);
|
|
207
|
|
208 if (pw != NULL)
|
|
209 {
|
|
210 if ((pos = strchr (newstr, '/')) == NULL)
|
|
211 {
|
|
212 str = g_malloc (strlen (pw->pw_dir) + 1);
|
|
213 strcpy (str, pw->pw_dir);
|
|
214 }
|
|
215 else
|
|
216 str = g_strconcat (pw->pw_dir, pos, NULL);
|
|
217
|
|
218 g_free (newstr);
|
|
219 newstr = str;
|
|
220 }
|
|
221
|
|
222 return (newstr);
|
|
223 }
|
|
224
|
|
225
|
|
226 void
|
|
227 remove_double_slashes (char *string)
|
|
228 {
|
|
229 char *newpos, *oldpos;
|
|
230
|
|
231 oldpos = newpos = string;
|
|
232 while (*oldpos != '\0')
|
|
233 {
|
|
234 *newpos++ = *oldpos++;
|
|
235 if (*oldpos == '\0')
|
|
236 break;
|
|
237 while (*(newpos - 1) == '/' && *(oldpos) == '/')
|
|
238 oldpos++;
|
|
239 }
|
|
240 *newpos = '\0';
|
|
241 if (string[strlen (string) - 1] == '/')
|
|
242 string[strlen (string) - 1] = '\0';
|
|
243 }
|
|
244
|
|
245
|
|
246 void
|
|
247 make_nonnull (char **str)
|
|
248 {
|
|
249 if (*str == NULL)
|
|
250 *str = g_malloc0 (1);
|
|
251 }
|
|
252
|
|
253
|
|
254 int
|
|
255 copyfile (char *source, char *dest)
|
|
256 {
|
|
257 FILE *srcfd, *destfd;
|
|
258 char buf[8192];
|
|
259 size_t n;
|
|
260
|
|
261 if ((srcfd = fopen (source, "rb")) == NULL)
|
|
262 return (0);
|
|
263
|
|
264 if ((destfd = fopen (dest, "wb")) == NULL)
|
|
265 {
|
|
266 fclose (srcfd);
|
|
267 return (0);
|
|
268 }
|
|
269
|
|
270 while ((n = fread (buf, 1, sizeof (buf), srcfd)) > 0)
|
|
271 fwrite (buf, 1, n, destfd);
|
|
272
|
|
273 fclose (srcfd);
|
|
274 fclose (destfd);
|
|
275
|
|
276 return (1);
|
|
277 }
|
|
278
|
|
279
|
|
280 int
|
|
281 gftp_match_filespec (char *filename, char *filespec)
|
|
282 {
|
|
283 char *filepos, *wcpos, *pos, *newpos, search_str[20];
|
|
284 size_t len, curlen;
|
|
285
|
|
286 if (filename == NULL || *filename == '\0' ||
|
|
287 filespec == NULL || *filespec == '\0')
|
|
288 return(1);
|
|
289
|
|
290 filepos = filename;
|
|
291 wcpos = filespec;
|
|
292 while(1)
|
|
293 {
|
|
294 if (*wcpos == '\0')
|
|
295 return (1);
|
|
296 else if (*filepos == '\0')
|
|
297 return(0);
|
|
298 else if(*wcpos == '?')
|
|
299 {
|
|
300 wcpos++;
|
|
301 filepos++;
|
|
302 }
|
|
303 else if(*wcpos == '*' && *(wcpos+1) == '\0')
|
|
304 return(1);
|
|
305 else if(*wcpos == '*')
|
|
306 {
|
|
307 len = sizeof (search_str);
|
|
308 for (pos = wcpos + 1, newpos = search_str, curlen = 0;
|
|
309 *pos != '*' && *pos != '?' && *pos != '\0' && curlen < len;
|
|
310 curlen++, *newpos++ = *pos++);
|
|
311 *newpos = '\0';
|
|
312
|
|
313 if ((filepos = strstr (filepos, search_str)) == NULL)
|
|
314 return(0);
|
|
315 wcpos += curlen + 1;
|
|
316 filepos += curlen;
|
|
317 }
|
|
318 else if(*wcpos++ != *filepos++)
|
|
319 return(0);
|
|
320 }
|
|
321 return (1);
|
|
322 }
|
|
323
|
|
324
|
|
325 int
|
|
326 gftp_parse_command_line (int *argc, char ***argv)
|
|
327 {
|
|
328 if (*argc > 1)
|
|
329 {
|
|
330 if (strcmp (argv[0][1], "--help") == 0 || strcmp (argv[0][1], "-h") == 0)
|
|
331 gftp_usage ();
|
|
332 else if (strcmp (argv[0][1], "--version") == 0 || strcmp (argv[0][1], "-v") == 0)
|
|
333 {
|
|
334 printf ("%s\n", version);
|
|
335 exit (0);
|
|
336 }
|
|
337 }
|
|
338 return (0);
|
|
339 }
|
|
340
|
|
341
|
|
342 void
|
|
343 gftp_usage (void)
|
|
344 {
|
|
345 printf (_("usage: gftp [[ftp://][user:[pass]@]ftp-site[:port][/directory]]\n"));
|
|
346 exit (0);
|
|
347 }
|
|
348
|
|
349
|
|
350 char *
|
|
351 get_xpm_path (char *filename, int quit_on_err)
|
|
352 {
|
|
353 char *tempstr, *exfile;
|
|
354
|
|
355 tempstr = g_strconcat (BASE_CONF_DIR, "/", filename, NULL);
|
|
356 exfile = expand_path (tempstr);
|
|
357 g_free (tempstr);
|
|
358 if (access (exfile, F_OK) != 0)
|
|
359 {
|
|
360 g_free (exfile);
|
|
361 tempstr = g_strconcat (SHARE_DIR, "/", filename, NULL);
|
|
362 exfile = expand_path (tempstr);
|
|
363 g_free (tempstr);
|
|
364 if (access (exfile, F_OK) != 0)
|
|
365 {
|
|
366 g_free (exfile);
|
|
367 exfile = g_strconcat ("/usr/share/icons/", filename, NULL);
|
|
368 if (access (exfile, F_OK) != 0)
|
|
369 {
|
|
370 g_free (exfile);
|
|
371 if (!quit_on_err)
|
|
372 return (NULL);
|
|
373 printf (_("gFTP Error: Cannot find file %s in %s or %s\n"),
|
|
374 filename, SHARE_DIR, BASE_CONF_DIR);
|
|
375 exit (-1);
|
|
376 }
|
|
377 }
|
|
378 }
|
|
379 return (exfile);
|
|
380 }
|
|
381
|
|
382
|
|
383 gint
|
|
384 string_hash_compare (gconstpointer path1, gconstpointer path2)
|
|
385 {
|
|
386 return (strcmp ((char *) path1, (char *) path2) == 0);
|
|
387 }
|
|
388
|
|
389
|
|
390 guint
|
|
391 string_hash_function (gconstpointer key)
|
|
392 {
|
|
393 return (((char *) key)[0] + ((char *) key)[1] + ((char *) key)[2]);
|
|
394 }
|
|
395
|
|
396
|
|
397 void
|
|
398 free_file_list (GList * filelist)
|
|
399 {
|
|
400 gftp_file * tempfle;
|
|
401 GList * templist;
|
|
402
|
|
403 templist = filelist;
|
|
404 while (templist != NULL)
|
|
405 {
|
|
406 tempfle = templist->data;
|
|
407 free_fdata (tempfle);
|
|
408 templist = templist->next;
|
|
409 }
|
|
410 g_list_free (filelist);
|
|
411 }
|
|
412
|
|
413
|
|
414 void
|
|
415 free_fdata (gftp_file * fle)
|
|
416 {
|
|
417 if (fle->file)
|
|
418 g_free (fle->file);
|
|
419 if (fle->user)
|
|
420 g_free (fle->user);
|
|
421 if (fle->group)
|
|
422 g_free (fle->group);
|
|
423 if (fle->attribs)
|
|
424 g_free (fle->attribs);
|
|
425 if (fle->destfile)
|
|
426 g_free (fle->destfile);
|
|
427 if (fle->fd)
|
|
428 fclose (fle->fd);
|
|
429 g_free (fle);
|
|
430 }
|
|
431
|
|
432
|
|
433 gftp_file *
|
|
434 copy_fdata (gftp_file * fle)
|
|
435 {
|
|
436 gftp_file * newfle;
|
|
437
|
|
438 newfle = g_malloc0 (sizeof (*newfle));
|
|
439 memcpy (newfle, fle, sizeof (*newfle));
|
|
440
|
|
441 if (fle->file)
|
|
442 {
|
|
443 newfle->file = g_malloc (strlen (fle->file) + 1);
|
|
444 strcpy (newfle->file, fle->file);
|
|
445 }
|
|
446
|
|
447 if (fle->user)
|
|
448 {
|
|
449 newfle->user = g_malloc (strlen (fle->user) + 1);
|
|
450 strcpy (newfle->user, fle->user);
|
|
451 }
|
|
452
|
|
453 if (fle->group)
|
|
454 {
|
|
455 newfle->group = g_malloc (strlen (fle->group) + 1);
|
|
456 strcpy (newfle->group, fle->group);
|
|
457 }
|
|
458
|
|
459 if (fle->attribs)
|
|
460 {
|
|
461 newfle->attribs = g_malloc (strlen (fle->attribs) + 1);
|
|
462 strcpy (newfle->attribs, fle->attribs);
|
|
463 }
|
|
464
|
|
465 if (fle->destfile)
|
|
466 {
|
|
467 newfle->destfile = g_malloc (strlen (fle->destfile) + 1);
|
|
468 strcpy (newfle->destfile, fle->destfile);
|
|
469 }
|
|
470 return (newfle);
|
|
471 }
|
|
472
|
|
473
|
|
474 void
|
|
475 swap_socks (gftp_request * dest, gftp_request * source)
|
|
476 {
|
|
477 dest->sockfd = source->sockfd;
|
|
478 dest->datafd = source->datafd;
|
|
479 dest->sockfd_write = source->sockfd_write;
|
|
480 dest->cached = 0;
|
|
481 if (!source->always_connected)
|
|
482 {
|
|
483 source->sockfd = NULL;
|
|
484 source->datafd = NULL;
|
|
485 source->sockfd_write = NULL;
|
|
486 source->cached = 1;
|
|
487 }
|
|
488 }
|
|
489
|
|
490
|
|
491 int
|
|
492 compare_request (gftp_request * request1, gftp_request * request2,
|
|
493 int compare_dirs)
|
|
494 {
|
|
495 char *strarr[3][2];
|
|
496 int i, ret;
|
|
497
|
|
498 ret = 1;
|
|
499 if (strcmp (request1->protocol_name, request2->protocol_name) == 0 &&
|
|
500 request1->port == request2->port)
|
|
501 {
|
|
502 strarr[0][0] = request1->hostname;
|
|
503 strarr[0][1] = request2->hostname;
|
|
504 strarr[1][0] = request1->username;
|
|
505 strarr[1][1] = request2->username;
|
|
506 if (compare_dirs)
|
|
507 {
|
|
508 strarr[2][0] = request1->directory;
|
|
509 strarr[2][1] = request2->directory;
|
|
510 }
|
|
511 else
|
|
512 strarr[2][0] = strarr[2][1] = "";
|
|
513
|
|
514 for (i = 0; i < 3; i++)
|
|
515 {
|
|
516 if ((strarr[i][0] && !strarr[i][1]) ||
|
|
517 (!strarr[i][0] && strarr[i][1]))
|
|
518 {
|
|
519 ret = 0;
|
|
520 break;
|
|
521 }
|
|
522
|
|
523 if (strarr[i][0] && strarr[i][1] &&
|
|
524 strcmp (strarr[i][0], strarr[i][1]) != 0)
|
|
525 {
|
|
526 ret = 0;
|
|
527 break;
|
|
528 }
|
|
529 }
|
|
530 }
|
|
531 else
|
|
532 ret = 0;
|
|
533 return (ret);
|
|
534 }
|
|
535
|
|
536
|
|
537 void
|
|
538 free_tdata (gftp_transfer * tdata)
|
|
539 {
|
|
540 if (tdata->statmutex)
|
|
541 g_free (tdata->statmutex);
|
|
542 if (tdata->structmutex)
|
|
543 g_free (tdata->structmutex);
|
|
544 if (tdata->fromreq != NULL)
|
|
545 gftp_request_destroy (tdata->fromreq);
|
|
546 if (tdata->toreq != NULL)
|
|
547 gftp_request_destroy (tdata->toreq);
|
|
548 free_file_list (tdata->files);
|
|
549 g_free (tdata);
|
|
550 }
|
|
551
|
|
552
|
|
553 gftp_request *
|
|
554 copy_request (gftp_request * req)
|
|
555 {
|
|
556 gftp_request * newreq;
|
|
557
|
|
558 newreq = g_malloc0 (sizeof (*newreq));
|
|
559 memcpy (newreq, req, sizeof (*newreq));
|
|
560
|
|
561 if (req->hostname)
|
|
562 newreq->hostname = g_strconcat (req->hostname, NULL);
|
|
563 if (req->username)
|
|
564 newreq->username = g_strconcat (req->username, NULL);
|
|
565 if (req->password)
|
|
566 newreq->password = g_strconcat (req->password, NULL);
|
|
567 if (req->account)
|
|
568 newreq->account = g_strconcat (req->account, NULL);
|
|
569 if (req->directory)
|
|
570 newreq->directory = g_strconcat (req->directory, NULL);
|
|
571
|
|
572 newreq->url_prefix = NULL;
|
|
573 newreq->protocol_name = NULL;
|
|
574 newreq->sftpserv_path = NULL;
|
|
575 newreq->proxy_config = NULL;
|
|
576 newreq->proxy_hostname = NULL;
|
|
577 newreq->proxy_username = NULL;
|
|
578 newreq->proxy_password = NULL;
|
|
579 newreq->proxy_account = NULL;
|
|
580 newreq->last_ftp_response = NULL;
|
|
581 newreq->last_dir_entry = NULL;
|
|
582 newreq->sockfd = NULL;
|
|
583 newreq->sockfd_write = NULL;
|
|
584 newreq->datafd = NULL;
|
|
585 newreq->cachefd = NULL;
|
|
586 newreq->hostp = NULL;
|
|
587 newreq->protocol_data = NULL;
|
|
588
|
|
589 if (req->proxy_config != NULL)
|
|
590 newreq->proxy_config = g_strconcat (req->proxy_config, NULL);
|
|
591
|
|
592 req->init (newreq);
|
|
593
|
|
594 return (newreq);
|
|
595 }
|
|
596
|
|
597
|
|
598 int
|
|
599 ptym_open (char *pts_name)
|
|
600 {
|
|
601 int fd;
|
|
602
|
|
603 #ifdef __sgi
|
|
604 char *tempstr;
|
|
605
|
|
606 if ((tempstr = _getpty (&fd, O_RDWR, 0600, 0)) == NULL)
|
|
607 return (-1);
|
|
608
|
|
609 strcpy (pts_name, tempstr);
|
|
610 return (fd);
|
|
611
|
|
612 #else /* !__sgi */
|
|
613
|
|
614 #ifdef SYSV
|
|
615
|
|
616 char *tempstr;
|
|
617
|
|
618 strcpy (pts_name, "/dev/ptmx");
|
|
619 if ((fd = open (pts_name, O_RDWR)) < 0)
|
|
620 return (-1);
|
|
621
|
|
622 if (grantpt (fd) < 0)
|
|
623 {
|
|
624 close (fd);
|
|
625 return (-1);
|
|
626 }
|
|
627
|
|
628 if (unlockpt (fd) < 0)
|
|
629 {
|
|
630 close (fd);
|
|
631 return (-1);
|
|
632 }
|
|
633
|
|
634 if ((tempstr = ptsname (fd)) == NULL)
|
|
635 {
|
|
636 close (fd);
|
|
637 return (-1);
|
|
638 }
|
|
639
|
|
640 strcpy (pts_name, tempstr);
|
|
641 return (fd);
|
|
642
|
|
643 #else /* !SYSV */
|
|
644
|
|
645 char *pos1, *pos2;
|
|
646
|
|
647 strcpy (pts_name, "/dev/ptyXY");
|
|
648 for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++)
|
|
649 {
|
|
650 pts_name[8] = *pos1;
|
|
651 for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++)
|
|
652 {
|
|
653 pts_name[9] = *pos2;
|
|
654 if ((fd = open (pts_name, O_RDWR)) < 0)
|
|
655 continue;
|
|
656 pts_name[5] = 't';
|
|
657 return (fd);
|
|
658 }
|
|
659 }
|
|
660 return (-1);
|
|
661
|
|
662 #endif
|
|
663
|
|
664 #endif
|
|
665
|
|
666 }
|
|
667
|
|
668
|
|
669 int
|
|
670 ptys_open (int fdm, char *pts_name)
|
|
671 {
|
|
672 int fds;
|
|
673
|
|
674 #if !defined (SYSV) && !defined (__sgi)
|
|
675
|
|
676 chmod (pts_name, S_IRUSR | S_IWUSR);
|
|
677 chown (pts_name, getuid (), -1);
|
|
678
|
|
679 #endif
|
|
680
|
|
681 if ((fds = open (pts_name, O_RDWR)) < 0)
|
|
682 {
|
|
683 close (fdm);
|
|
684 return (-1);
|
|
685 }
|
|
686
|
|
687 #ifdef SYSV
|
|
688
|
|
689 if (ioctl (fds, I_PUSH, "ptem") < 0)
|
|
690 {
|
|
691 close (fdm);
|
|
692 close (fds);
|
|
693 return (-1);
|
|
694 }
|
|
695
|
|
696 if (ioctl (fds, I_PUSH, "ldterm") < 0)
|
|
697 {
|
|
698 close (fdm);
|
|
699 close (fds);
|
|
700 return (-1);
|
|
701 }
|
|
702
|
|
703 if (ioctl (fds, I_PUSH, "ttcompat") < 0)
|
|
704 {
|
|
705 close (fdm);
|
|
706 close (fds);
|
|
707 return (-1);
|
|
708 }
|
|
709
|
|
710 #endif
|
|
711
|
|
712 #if !defined(SYSV) && !defined (__sgi) && defined(TIOCSCTTY) && !defined(CIBAUD)
|
|
713
|
|
714 if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0)
|
|
715 {
|
|
716 close (fdm);
|
|
717 return (-1);
|
|
718 }
|
|
719
|
|
720 #endif
|
|
721
|
|
722 return (fds);
|
|
723 }
|
|
724
|
|
725
|
|
726 int
|
|
727 tty_raw (int fd)
|
|
728 {
|
|
729 struct termios buf;
|
|
730
|
|
731 if (tcgetattr (fd, &buf) < 0)
|
|
732 return (-1);
|
|
733
|
|
734 buf.c_iflag |= IGNPAR;
|
|
735 buf.c_iflag &= ~(ICRNL | ISTRIP | IXON | IGNCR | IXANY | IXOFF | INLCR);
|
|
736 buf.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL);
|
|
737 #ifdef IEXTEN
|
|
738 buf.c_lflag &= ~(IEXTEN);
|
|
739 #endif
|
|
740
|
|
741 buf.c_oflag &= ~(OPOST);
|
|
742 buf.c_cc[VMIN] = 1;
|
|
743 buf.c_cc[VTIME] = 0;
|
|
744
|
|
745 if (tcsetattr (fd, TCSADRAIN, &buf) < 0)
|
|
746 return (-1);
|
|
747 return (0);
|
|
748 }
|
|
749
|
|
750
|
|
751 /* We have the caller send us a pointer to a string so we can write the port
|
|
752 into it. It makes it easier so we don't have to worry about freeing it
|
|
753 later on, the caller can just send us an auto variable, The string
|
|
754 should be at least 6 chars. I know this is messy... */
|
|
755
|
|
756 char **
|
|
757 make_ssh_exec_args (gftp_request * request, char *execname,
|
|
758 int use_sftp_subsys, char *portstring)
|
|
759 {
|
|
760 char **args, *oldstr, *tempstr;
|
|
761 int i, j;
|
|
762
|
|
763 args = g_malloc (sizeof (char *) * (num_ssh_extra_params + 10));
|
|
764
|
|
765 args[0] = ssh_prog_name != NULL && *ssh_prog_name != '\0' ?
|
|
766 ssh_prog_name : "ssh";
|
|
767 i = 1;
|
|
768 tempstr = g_strconcat (args[0], NULL);
|
|
769
|
|
770 if (ssh_extra_params_list != NULL)
|
|
771 {
|
|
772 for (j=0; ssh_extra_params_list[j] != NULL; j++)
|
|
773 {
|
|
774 oldstr = tempstr;
|
|
775 args[i++] = ssh_extra_params_list[j];
|
|
776 tempstr = g_strconcat (oldstr, " ", ssh_extra_params_list[j], NULL);
|
|
777 g_free (oldstr);
|
|
778 }
|
|
779 }
|
|
780
|
|
781 oldstr = tempstr;
|
|
782 tempstr = g_strconcat (oldstr, " -e none", NULL);
|
|
783 g_free (oldstr);
|
|
784 args[i++] = "-e";
|
|
785 args[i++] = "none";
|
|
786
|
|
787 if (request->username && *request->username != '\0')
|
|
788 {
|
|
789 oldstr = tempstr;
|
|
790 tempstr = g_strconcat (oldstr, " -l ", request->username, NULL);
|
|
791 g_free (oldstr);
|
|
792 args[i++] = "-l";
|
|
793 args[i++] = request->username;
|
|
794 }
|
|
795
|
|
796 if (request->port != 0)
|
|
797 {
|
|
798 g_snprintf (portstring, 6, "%d", request->port);
|
|
799 oldstr = tempstr;
|
|
800 tempstr = g_strconcat (oldstr, " -p ", portstring, NULL);
|
|
801 g_free (oldstr);
|
|
802 args[i++] = "-p";
|
|
803 args[i++] = portstring;
|
|
804 }
|
|
805
|
|
806 if (use_sftp_subsys)
|
|
807 {
|
|
808 oldstr = tempstr;
|
|
809 tempstr = g_strconcat (oldstr, " ", request->hostname, " -s sftp", NULL);
|
|
810 g_free (oldstr);
|
|
811 args[i++] = request->hostname;
|
|
812 args[i++] = "-s";
|
|
813 args[i++] = "sftp";
|
|
814 args[i] = NULL;
|
|
815 }
|
|
816 else
|
|
817 {
|
|
818 oldstr = tempstr;
|
|
819 tempstr = g_strconcat (oldstr, " ", request->hostname, " \"", execname,
|
|
820 "\"", NULL);
|
|
821 g_free (oldstr);
|
|
822 args[i++] = request->hostname;
|
|
823 args[i++] = execname;
|
|
824 args[i] = NULL;
|
|
825 }
|
|
826
|
|
827 request->logging_function (gftp_logging_misc, request->user_data,
|
|
828 _("Running program %s\n"), tempstr);
|
|
829 g_free (tempstr);
|
|
830 return (args);
|
|
831 }
|
|
832
|
|
833
|
|
834 char *
|
|
835 ssh_start_login_sequence (gftp_request * request, int fd)
|
|
836 {
|
|
837 size_t rem, len, diff, lastdiff;
|
|
838 int flags, wrotepw, ok;
|
|
839 struct timeval tv;
|
|
840 char *tempstr;
|
|
841 fd_set rdfds;
|
|
842 ssize_t rd;
|
|
843
|
|
844 rem = len = 100;
|
|
845 tempstr = g_malloc0 (len);
|
|
846 diff = lastdiff = 0;
|
|
847 wrotepw = 0;
|
|
848 ok = 1;
|
|
849
|
|
850 if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
|
|
851 {
|
|
852 g_free (tempstr);
|
|
853 return (NULL);
|
|
854 }
|
|
855
|
|
856 if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
|
|
857 {
|
|
858 g_free (tempstr);
|
|
859 return (NULL);
|
|
860 }
|
|
861
|
|
862 while (1)
|
|
863 {
|
|
864 FD_ZERO (&rdfds);
|
|
865 FD_SET (fd, &rdfds);
|
|
866 tv.tv_sec = 5;
|
|
867 tv.tv_usec = 0;
|
|
868 if (select (fd + 1, &rdfds, NULL, NULL, &tv) < 0)
|
|
869 {
|
|
870 if (errno == EINTR)
|
|
871 continue;
|
|
872 ok = 0;
|
|
873 break;
|
|
874 }
|
|
875
|
|
876 if ((rd = read (fd, tempstr + diff, rem - 1)) < 0)
|
|
877 {
|
|
878 if (errno == EINTR)
|
|
879 continue;
|
|
880 ok = 0;
|
|
881 break;
|
|
882 }
|
|
883 else if (rd == 0)
|
|
884 {
|
|
885 ok = 0;
|
|
886 break;
|
|
887 }
|
|
888 tempstr[diff + rd] = '\0';
|
|
889 rem -= rd;
|
|
890 diff += rd;
|
|
891 if (rem <= 1)
|
|
892 {
|
|
893 tempstr = g_realloc (tempstr, len + 100);
|
|
894 tempstr[diff] = '\0';
|
|
895 request->logging_function (gftp_logging_recv, request->user_data,
|
|
896 "%s", tempstr + lastdiff);
|
|
897 lastdiff = diff;
|
|
898 len += 100;
|
|
899 rem = 100;
|
|
900 }
|
|
901
|
|
902 if (!wrotepw &&
|
|
903 strlen (tempstr) > 11 && strcmp (tempstr + strlen (tempstr) - 10,
|
|
904 "password: ") == 0)
|
|
905 {
|
|
906 wrotepw = 1;
|
|
907 write (fd, request->password, strlen (request->password));
|
|
908 write (fd, "\n", 1);
|
|
909 }
|
|
910
|
|
911 else if (!wrotepw &&
|
|
912 (strstr (tempstr, "Enter passphrase for RSA key") != NULL ||
|
|
913 strstr (tempstr, "Enter passphrase for key '") != NULL))
|
|
914 {
|
|
915 wrotepw = 1;
|
|
916 write (fd, request->password, strlen (request->password));
|
|
917 write (fd, "\n", 1);
|
|
918 }
|
|
919 else if (strlen (tempstr) >= 5 &&
|
|
920 strcmp (tempstr + strlen (tempstr) - 5, "xsftp") == 0)
|
|
921 break;
|
|
922 }
|
|
923
|
|
924 tempstr[diff] = '\0';
|
|
925 request->logging_function (gftp_logging_recv, request->user_data,
|
|
926 "%s\n", tempstr + lastdiff);
|
|
927
|
|
928 if (ok && fcntl (fd, F_SETFL, flags) < 0)
|
|
929 ok = 0;
|
|
930
|
|
931 if (!ok)
|
|
932 {
|
|
933 g_free (tempstr);
|
|
934 return (NULL);
|
|
935 }
|
|
936
|
|
937 return (tempstr);
|
|
938 }
|
|
939
|
|
940
|
|
941 #ifdef G_HAVE_GINT64
|
|
942
|
|
943 gint64
|
|
944 hton64 (gint64 val)
|
|
945 {
|
|
946 gint64 num;
|
|
947 char *pos;
|
|
948
|
|
949 num = 0;
|
|
950 pos = (char *) #
|
|
951 pos[0] = (val >> 56) & 0xff;
|
|
952 pos[1] = (val >> 48) & 0xff;
|
|
953 pos[2] = (val >> 40) & 0xff;
|
|
954 pos[3] = (val >> 32) & 0xff;
|
|
955 pos[4] = (val >> 24) & 0xff;
|
|
956 pos[5] = (val >> 16) & 0xff;
|
|
957 pos[6] = (val >> 8) & 0xff;
|
|
958 pos[7] = val & 0xff;
|
|
959 return (num);
|
|
960 }
|
|
961
|
|
962 #endif
|
|
963
|