Mercurial > gftp.yaz
annotate lib/misc.c @ 91:8c37d73d3f1f
2003-1-21 Brian Masney <masneyb@gftp.org>
* lib/gftp.h - added server type defines. Added server_type field to
gftp_request
* lib/local.c - use S_ISDIR and S_ISLINK macros
* lib/protocols.c - (gftp_parse_ls*) - use hints from server_type for
parsing directory listing
* lib/rfc959.c - added function rfc959_syst. Call this on startup
* lib/protocols.c lib/rfc959.c lib/sshv2.c - pass request structure
to gftp_parse_ls
* lib/sshv2.c - set server_type to be GFTP_TYPE_UNIX
author | masneyb |
---|---|
date | Tue, 21 Jan 2003 23:46:03 +0000 |
parents | 6df043359b41 |
children | 3b573c8ef706 |
rev | line source |
---|---|
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" | |
33 | 22 static const char cvsid[] = "$Id$"; |
1 | 23 |
87 | 24 /* FIXME - this isn't right for all locales. Use glib's printf instead */ |
1 | 25 char * |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
13
diff
changeset
|
26 insert_commas (off_t number, char *dest_str, size_t dest_len) |
1 | 27 { |
28 char *frompos, *topos, src[50], *dest; | |
29 int len, num, rem, i; | |
30 | |
31 if (dest_str != NULL) | |
32 *dest_str = '\0'; | |
56 | 33 len = (number > 0 ? log10 (number) : 0) + 2; |
1 | 34 |
35 if (len <= 0) | |
36 { | |
37 if (dest_str != NULL) | |
38 strncpy (dest_str, "0", dest_len); | |
39 else | |
56 | 40 dest_str = g_strdup ("0"); |
1 | 41 return (dest_str); |
42 } | |
43 | |
44 len += len / 3; | |
45 if (dest_str != NULL && len > dest_len) | |
46 { | |
47 | |
48 for (i=0; i<dest_len - 1; i++) | |
49 dest_str[i] = 'X'; | |
50 dest_str[dest_len - 1] = '\0'; | |
51 return (dest_str); | |
52 } | |
53 | |
54 if (dest_str == NULL) | |
55 dest = g_malloc0 (len); | |
56 else | |
57 dest = dest_str; | |
58 | |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
13
diff
changeset
|
59 #if defined (_LARGEFILE_SOURCE) |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
13
diff
changeset
|
60 g_snprintf (src, sizeof (src), "%lld", number); |
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
13
diff
changeset
|
61 #else |
1 | 62 g_snprintf (src, sizeof (src), "%ld", number); |
14
83090328581e
* More largefile support. Hopefully all that is left is the configure stuff
masneyb
parents:
13
diff
changeset
|
63 #endif |
1 | 64 |
65 num = strlen (src) / 3 - 1; | |
66 rem = strlen (src) % 3; | |
67 frompos = src; | |
68 topos = dest; | |
69 for (i = 0; i < rem; i++) | |
70 *topos++ = *frompos++; | |
71 | |
72 if (*frompos != '\0') | |
73 { | |
74 if (rem != 0) | |
75 *topos++ = ','; | |
76 while (num > 0) | |
77 { | |
78 for (i = 0; i < 3; i++) | |
79 *topos++ = *frompos++; | |
80 *topos++ = ','; | |
81 num--; | |
82 } | |
83 for (i = 0; i < 3; i++) | |
84 *topos++ = *frompos++; | |
85 } | |
86 *topos = '\0'; | |
87 return (dest); | |
88 } | |
89 | |
90 | |
91 char * | |
92 alltrim (char *str) | |
93 { | |
94 char *pos, *newpos; | |
95 int diff; | |
96 | |
97 pos = str + strlen (str) - 1; | |
87 | 98 while (pos >= str && (*pos == ' ' || *pos == '\t')) |
1 | 99 *pos-- = '\0'; |
100 | |
101 pos = str; | |
102 diff = 0; | |
103 while (*pos++ == ' ') | |
104 diff++; | |
105 | |
106 if (diff == 0) | |
107 return (str); | |
108 | |
109 pos = str + diff; | |
110 newpos = str; | |
111 while (*pos != '\0') | |
112 *newpos++ = *pos++; | |
113 *newpos = '\0'; | |
114 | |
115 return (str); | |
116 } | |
117 | |
118 | |
119 char * | |
120 expand_path (const char *src) | |
121 { | |
122 char *str, *pos, *endpos, *prevpos, *newstr, *tempstr, tempchar; | |
123 struct passwd *pw; | |
124 | |
125 pw = NULL; | |
126 str = g_malloc (strlen (src) + 1); | |
127 strcpy (str, src); | |
128 | |
129 if (*str == '~') | |
130 { | |
131 if (*(str + 1) == '/' || *(str + 1) == '\0') | |
132 pw = getpwuid (geteuid ()); | |
133 else | |
134 { | |
135 if ((pos = strchr (str, '/')) != NULL) | |
136 *pos = '\0'; | |
137 | |
138 pw = getpwnam (str + 1); | |
139 | |
140 if (pos != NULL) | |
141 *pos = '/'; | |
142 } | |
143 } | |
144 | |
145 endpos = str; | |
146 newstr = NULL; | |
147 while ((pos = strchr (endpos, '/')) != NULL) | |
148 { | |
149 pos++; | |
150 while (*pos == '/') | |
151 pos++; | |
152 if ((endpos = strchr (pos, '/')) == NULL) | |
153 endpos = pos + strlen (pos); | |
154 tempchar = *endpos; | |
155 *endpos = '\0'; | |
156 if (strcmp (pos, "..") == 0) | |
157 { | |
158 *(pos - 1) = '\0'; | |
159 if (newstr != NULL && (prevpos = strrchr (newstr, '/')) != NULL) | |
160 *prevpos = '\0'; | |
161 } | |
162 else if (strcmp (pos, ".") != 0) | |
163 { | |
164 if (newstr == NULL) | |
56 | 165 newstr = g_strdup (pos - 1); |
1 | 166 else |
167 { | |
168 tempstr = g_strconcat (newstr, pos - 1, NULL); | |
169 g_free (newstr); | |
170 newstr = tempstr; | |
171 } | |
172 } | |
173 *endpos = tempchar; | |
174 if (*endpos == '\0') | |
175 break; | |
176 endpos = pos + 1; | |
177 } | |
178 | |
179 if (newstr == NULL || *newstr == '\0') | |
180 { | |
181 if (newstr != NULL) | |
182 g_free (newstr); | |
183 newstr = g_malloc0 (2); | |
184 *newstr = '/'; | |
185 } | |
186 | |
187 g_free (str); | |
188 | |
189 if (pw != NULL) | |
190 { | |
191 if ((pos = strchr (newstr, '/')) == NULL) | |
192 { | |
193 str = g_malloc (strlen (pw->pw_dir) + 1); | |
194 strcpy (str, pw->pw_dir); | |
195 } | |
196 else | |
197 str = g_strconcat (pw->pw_dir, pos, NULL); | |
198 | |
199 g_free (newstr); | |
200 newstr = str; | |
201 } | |
202 | |
203 return (newstr); | |
204 } | |
205 | |
206 | |
207 void | |
208 remove_double_slashes (char *string) | |
209 { | |
210 char *newpos, *oldpos; | |
87 | 211 size_t len; |
1 | 212 |
213 oldpos = newpos = string; | |
214 while (*oldpos != '\0') | |
215 { | |
216 *newpos++ = *oldpos++; | |
217 if (*oldpos == '\0') | |
218 break; | |
219 while (*(newpos - 1) == '/' && *(oldpos) == '/') | |
220 oldpos++; | |
221 } | |
222 *newpos = '\0'; | |
87 | 223 |
224 len = strlen (string); | |
225 if (string[len - 1] == '/') | |
226 string[len - 1] = '\0'; | |
1 | 227 } |
228 | |
229 | |
230 void | |
231 make_nonnull (char **str) | |
232 { | |
233 if (*str == NULL) | |
234 *str = g_malloc0 (1); | |
235 } | |
236 | |
237 | |
238 int | |
239 copyfile (char *source, char *dest) | |
240 { | |
58 | 241 int srcfd, destfd; |
1 | 242 char buf[8192]; |
58 | 243 ssize_t n; |
1 | 244 |
58 | 245 if ((srcfd = open (source, O_RDONLY)) == -1) |
246 { | |
247 printf (_("Error: Cannot open local file %s: %s\n"), | |
248 source, g_strerror (errno)); | |
249 exit (1); | |
250 } | |
1 | 251 |
58 | 252 if ((destfd = open (dest, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)) == -1) |
1 | 253 { |
58 | 254 printf (_("Error: Cannot open local file %s: %s\n"), |
255 dest, g_strerror (errno)); | |
256 close (srcfd); | |
257 exit (1); | |
1 | 258 } |
259 | |
58 | 260 while ((n = read (srcfd, buf, sizeof (buf))) > 0) |
261 { | |
262 if (write (destfd, buf, n) == -1) | |
263 { | |
264 printf (_("Error: Could not write to socket: %s\n"), | |
265 g_strerror (errno)); | |
266 exit (1); | |
267 } | |
268 } | |
1 | 269 |
58 | 270 if (n == -1) |
271 { | |
272 printf (_("Error: Could not read from socket: %s\n"), g_strerror (errno)); | |
273 exit (1); | |
274 } | |
275 | |
87 | 276 if (close (srcfd) == -1) |
277 { | |
278 printf (_("Error closing file descriptor: %s\n"), g_strerror (errno)); | |
279 exit (1); | |
280 } | |
281 | |
282 if (close (destfd) == -1) | |
283 { | |
284 printf (_("Error closing file descriptor: %s\n"), g_strerror (errno)); | |
285 exit (1); | |
286 } | |
1 | 287 |
288 return (1); | |
289 } | |
290 | |
291 | |
87 | 292 /* FIXME - is there a replacement for this */ |
1 | 293 int |
294 gftp_match_filespec (char *filename, char *filespec) | |
295 { | |
296 char *filepos, *wcpos, *pos, *newpos, search_str[20]; | |
297 size_t len, curlen; | |
298 | |
299 if (filename == NULL || *filename == '\0' || | |
300 filespec == NULL || *filespec == '\0') | |
301 return(1); | |
302 | |
303 filepos = filename; | |
304 wcpos = filespec; | |
305 while(1) | |
306 { | |
307 if (*wcpos == '\0') | |
308 return (1); | |
309 else if (*filepos == '\0') | |
310 return(0); | |
311 else if(*wcpos == '?') | |
312 { | |
313 wcpos++; | |
314 filepos++; | |
315 } | |
316 else if(*wcpos == '*' && *(wcpos+1) == '\0') | |
317 return(1); | |
318 else if(*wcpos == '*') | |
319 { | |
320 len = sizeof (search_str); | |
321 for (pos = wcpos + 1, newpos = search_str, curlen = 0; | |
322 *pos != '*' && *pos != '?' && *pos != '\0' && curlen < len; | |
323 curlen++, *newpos++ = *pos++); | |
324 *newpos = '\0'; | |
325 | |
326 if ((filepos = strstr (filepos, search_str)) == NULL) | |
327 return(0); | |
328 wcpos += curlen + 1; | |
329 filepos += curlen; | |
330 } | |
331 else if(*wcpos++ != *filepos++) | |
332 return(0); | |
333 } | |
334 return (1); | |
335 } | |
336 | |
337 | |
338 int | |
339 gftp_parse_command_line (int *argc, char ***argv) | |
340 { | |
341 if (*argc > 1) | |
342 { | |
87 | 343 if (strcmp (argv[0][1], "--help") == 0 || |
344 strcmp (argv[0][1], "-h") == 0) | |
1 | 345 gftp_usage (); |
87 | 346 else if (strcmp (argv[0][1], "--version") == 0 || |
347 strcmp (argv[0][1], "-v") == 0) | |
1 | 348 { |
349 printf ("%s\n", version); | |
350 exit (0); | |
351 } | |
352 } | |
353 return (0); | |
354 } | |
355 | |
356 | |
357 void | |
358 gftp_usage (void) | |
359 { | |
87 | 360 printf (_("usage: gftp [[protocol://][user:[pass]@]site[:port][/directory]]\n")); |
1 | 361 exit (0); |
362 } | |
363 | |
364 | |
365 char * | |
366 get_xpm_path (char *filename, int quit_on_err) | |
367 { | |
368 char *tempstr, *exfile; | |
369 | |
370 tempstr = g_strconcat (BASE_CONF_DIR, "/", filename, NULL); | |
371 exfile = expand_path (tempstr); | |
372 g_free (tempstr); | |
373 if (access (exfile, F_OK) != 0) | |
374 { | |
375 g_free (exfile); | |
376 tempstr = g_strconcat (SHARE_DIR, "/", filename, NULL); | |
377 exfile = expand_path (tempstr); | |
378 g_free (tempstr); | |
379 if (access (exfile, F_OK) != 0) | |
380 { | |
381 g_free (exfile); | |
382 exfile = g_strconcat ("/usr/share/icons/", filename, NULL); | |
383 if (access (exfile, F_OK) != 0) | |
384 { | |
385 g_free (exfile); | |
386 if (!quit_on_err) | |
387 return (NULL); | |
87 | 388 |
1 | 389 printf (_("gFTP Error: Cannot find file %s in %s or %s\n"), |
390 filename, SHARE_DIR, BASE_CONF_DIR); | |
87 | 391 exit (1); |
1 | 392 } |
393 } | |
394 } | |
395 return (exfile); | |
396 } | |
397 | |
398 | |
399 gint | |
400 string_hash_compare (gconstpointer path1, gconstpointer path2) | |
401 { | |
402 return (strcmp ((char *) path1, (char *) path2) == 0); | |
403 } | |
404 | |
405 | |
406 guint | |
407 string_hash_function (gconstpointer key) | |
408 { | |
59 | 409 guint ret; |
410 int i; | |
411 | |
412 ret = 0; | |
87 | 413 for (i=0; ((char *) key)[i] != '\0' && i < 3; i++) |
59 | 414 ret += ((char *) key)[i]; |
415 | |
416 return (ret); | |
1 | 417 } |
418 | |
419 | |
420 void | |
421 free_file_list (GList * filelist) | |
422 { | |
423 gftp_file * tempfle; | |
424 GList * templist; | |
425 | |
426 templist = filelist; | |
427 while (templist != NULL) | |
428 { | |
429 tempfle = templist->data; | |
430 free_fdata (tempfle); | |
431 templist = templist->next; | |
432 } | |
433 g_list_free (filelist); | |
434 } | |
435 | |
436 | |
437 void | |
438 free_fdata (gftp_file * fle) | |
439 { | |
440 if (fle->file) | |
441 g_free (fle->file); | |
442 if (fle->user) | |
443 g_free (fle->user); | |
444 if (fle->group) | |
445 g_free (fle->group); | |
446 if (fle->attribs) | |
447 g_free (fle->attribs); | |
448 if (fle->destfile) | |
449 g_free (fle->destfile); | |
58 | 450 if (fle->fd > 0) |
87 | 451 close (fle->fd); /* FIXME - need to log a failure */ |
1 | 452 g_free (fle); |
453 } | |
454 | |
455 | |
456 gftp_file * | |
457 copy_fdata (gftp_file * fle) | |
458 { | |
459 gftp_file * newfle; | |
460 | |
461 newfle = g_malloc0 (sizeof (*newfle)); | |
462 memcpy (newfle, fle, sizeof (*newfle)); | |
463 | |
464 if (fle->file) | |
87 | 465 newfle->file = g_strdup (fle->file); |
1 | 466 |
467 if (fle->user) | |
87 | 468 newfle->user = g_strdup (fle->user); |
1 | 469 |
470 if (fle->group) | |
87 | 471 newfle->group = g_strdup (fle->group); |
1 | 472 |
473 if (fle->attribs) | |
87 | 474 newfle->attribs = g_strdup (fle->attribs); |
1 | 475 |
476 if (fle->destfile) | |
87 | 477 newfle->destfile = g_strdup (fle->destfile); |
478 | |
1 | 479 return (newfle); |
480 } | |
481 | |
482 | |
483 int | |
484 compare_request (gftp_request * request1, gftp_request * request2, | |
485 int compare_dirs) | |
486 { | |
487 char *strarr[3][2]; | |
488 int i, ret; | |
489 | |
490 ret = 1; | |
87 | 491 if (request1->protonum == request2->protonum && |
1 | 492 request1->port == request2->port) |
493 { | |
494 strarr[0][0] = request1->hostname; | |
495 strarr[0][1] = request2->hostname; | |
496 strarr[1][0] = request1->username; | |
497 strarr[1][1] = request2->username; | |
498 if (compare_dirs) | |
499 { | |
500 strarr[2][0] = request1->directory; | |
501 strarr[2][1] = request2->directory; | |
502 } | |
503 else | |
504 strarr[2][0] = strarr[2][1] = ""; | |
505 | |
506 for (i = 0; i < 3; i++) | |
507 { | |
508 if ((strarr[i][0] && !strarr[i][1]) || | |
509 (!strarr[i][0] && strarr[i][1])) | |
510 { | |
511 ret = 0; | |
512 break; | |
513 } | |
514 | |
515 if (strarr[i][0] && strarr[i][1] && | |
516 strcmp (strarr[i][0], strarr[i][1]) != 0) | |
517 { | |
518 ret = 0; | |
519 break; | |
520 } | |
521 } | |
522 } | |
523 else | |
524 ret = 0; | |
525 return (ret); | |
526 } | |
527 | |
528 | |
529 void | |
530 free_tdata (gftp_transfer * tdata) | |
531 { | |
532 if (tdata->statmutex) | |
533 g_free (tdata->statmutex); | |
534 if (tdata->structmutex) | |
535 g_free (tdata->structmutex); | |
536 if (tdata->fromreq != NULL) | |
67 | 537 gftp_request_destroy (tdata->fromreq, 1); |
1 | 538 if (tdata->toreq != NULL) |
67 | 539 gftp_request_destroy (tdata->toreq, 1); |
1 | 540 free_file_list (tdata->files); |
541 g_free (tdata); | |
542 } | |
543 | |
544 | |
545 gftp_request * | |
546 copy_request (gftp_request * req) | |
547 { | |
548 gftp_request * newreq; | |
549 | |
66 | 550 newreq = gftp_request_new (); |
1 | 551 |
552 if (req->hostname) | |
56 | 553 newreq->hostname = g_strdup (req->hostname); |
1 | 554 if (req->username) |
56 | 555 newreq->username = g_strdup (req->username); |
1 | 556 if (req->password) |
56 | 557 newreq->password = g_strdup (req->password); |
1 | 558 if (req->account) |
56 | 559 newreq->account = g_strdup (req->account); |
1 | 560 if (req->directory) |
56 | 561 newreq->directory = g_strdup (req->directory); |
66 | 562 newreq->port = req->port; |
563 newreq->data_type = req->data_type; | |
564 newreq->use_proxy = req->use_proxy; | |
565 gftp_set_proxy_config (newreq, req->proxy_config); | |
566 newreq->transfer_type = req->transfer_type; | |
567 newreq->network_timeout = req->network_timeout; | |
568 newreq->retries = req->retries; | |
569 newreq->sleep_time = req->sleep_time; | |
570 newreq->passive_transfer = req->passive_transfer; | |
571 newreq->maxkbs = req->maxkbs; | |
572 newreq->logging_function = req->logging_function; | |
1 | 573 |
66 | 574 if (req->sftpserv_path != NULL) |
575 newreq->sftpserv_path = g_strdup (req->sftpserv_path); | |
1 | 576 |
577 req->init (newreq); | |
578 | |
579 return (newreq); | |
580 } | |
581 | |
582 | |
583 int | |
584 ptym_open (char *pts_name) | |
585 { | |
586 int fd; | |
587 | |
588 #ifdef __sgi | |
589 char *tempstr; | |
590 | |
591 if ((tempstr = _getpty (&fd, O_RDWR, 0600, 0)) == NULL) | |
592 return (-1); | |
593 | |
594 strcpy (pts_name, tempstr); | |
595 return (fd); | |
596 | |
597 #else /* !__sgi */ | |
598 | |
80 | 599 #ifdef HAVE_GRANTPT |
1 | 600 |
601 char *tempstr; | |
602 | |
603 strcpy (pts_name, "/dev/ptmx"); | |
604 if ((fd = open (pts_name, O_RDWR)) < 0) | |
605 return (-1); | |
606 | |
607 if (grantpt (fd) < 0) | |
608 { | |
609 close (fd); | |
610 return (-1); | |
611 } | |
612 | |
613 if (unlockpt (fd) < 0) | |
614 { | |
615 close (fd); | |
616 return (-1); | |
617 } | |
618 | |
619 if ((tempstr = ptsname (fd)) == NULL) | |
620 { | |
621 close (fd); | |
622 return (-1); | |
623 } | |
624 | |
625 strcpy (pts_name, tempstr); | |
626 return (fd); | |
627 | |
80 | 628 #else /* !GRANTPT */ |
1 | 629 |
630 char *pos1, *pos2; | |
631 | |
632 strcpy (pts_name, "/dev/ptyXY"); | |
633 for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++) | |
634 { | |
635 pts_name[8] = *pos1; | |
636 for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++) | |
637 { | |
638 pts_name[9] = *pos2; | |
639 if ((fd = open (pts_name, O_RDWR)) < 0) | |
640 continue; | |
641 pts_name[5] = 't'; | |
642 return (fd); | |
643 } | |
644 } | |
645 return (-1); | |
646 | |
87 | 647 #endif /* GRANTPT */ |
1 | 648 |
87 | 649 #endif /* __sgi */ |
1 | 650 |
651 } | |
652 | |
653 | |
654 int | |
655 ptys_open (int fdm, char *pts_name) | |
656 { | |
657 int fds; | |
658 | |
80 | 659 #if !defined (HAVE_GRANTPT) && !defined (__sgi) |
1 | 660 |
661 chmod (pts_name, S_IRUSR | S_IWUSR); | |
662 chown (pts_name, getuid (), -1); | |
663 | |
664 #endif | |
665 | |
666 if ((fds = open (pts_name, O_RDWR)) < 0) | |
667 { | |
668 close (fdm); | |
669 return (-1); | |
670 } | |
671 | |
80 | 672 #ifdef HAVE_GRANTPT |
673 /* I intentionally ignore these errors */ | |
674 ioctl (fds, I_PUSH, "ptem"); | |
675 ioctl (fds, I_PUSH, "ldterm"); | |
676 ioctl (fds, I_PUSH, "ttcompat"); | |
1 | 677 #endif |
678 | |
80 | 679 #if !defined(HAVE_GRANTPT) && !defined (__sgi) && defined(TIOCSCTTY) && !defined(CIBAUD) |
1 | 680 |
681 if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0) | |
682 { | |
683 close (fdm); | |
684 return (-1); | |
685 } | |
686 | |
687 #endif | |
688 | |
689 return (fds); | |
690 } | |
691 | |
692 | |
693 int | |
694 tty_raw (int fd) | |
695 { | |
696 struct termios buf; | |
697 | |
698 if (tcgetattr (fd, &buf) < 0) | |
699 return (-1); | |
700 | |
701 buf.c_iflag |= IGNPAR; | |
702 buf.c_iflag &= ~(ICRNL | ISTRIP | IXON | IGNCR | IXANY | IXOFF | INLCR); | |
703 buf.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL); | |
704 #ifdef IEXTEN | |
705 buf.c_lflag &= ~(IEXTEN); | |
706 #endif | |
707 | |
708 buf.c_oflag &= ~(OPOST); | |
709 buf.c_cc[VMIN] = 1; | |
710 buf.c_cc[VTIME] = 0; | |
711 | |
712 if (tcsetattr (fd, TCSADRAIN, &buf) < 0) | |
713 return (-1); | |
714 return (0); | |
715 } | |
716 | |
717 | |
718 /* We have the caller send us a pointer to a string so we can write the port | |
719 into it. It makes it easier so we don't have to worry about freeing it | |
720 later on, the caller can just send us an auto variable, The string | |
721 should be at least 6 chars. I know this is messy... */ | |
722 | |
723 char ** | |
724 make_ssh_exec_args (gftp_request * request, char *execname, | |
725 int use_sftp_subsys, char *portstring) | |
726 { | |
727 char **args, *oldstr, *tempstr; | |
56 | 728 struct servent serv_struct; |
1 | 729 int i, j; |
730 | |
56 | 731 args = g_malloc (sizeof (char *) * (num_ssh_extra_params + 15)); |
1 | 732 |
733 args[0] = ssh_prog_name != NULL && *ssh_prog_name != '\0' ? | |
734 ssh_prog_name : "ssh"; | |
735 i = 1; | |
56 | 736 tempstr = g_strdup (args[0]); |
1 | 737 |
738 if (ssh_extra_params_list != NULL) | |
739 { | |
740 for (j=0; ssh_extra_params_list[j] != NULL; j++) | |
741 { | |
742 oldstr = tempstr; | |
743 args[i++] = ssh_extra_params_list[j]; | |
744 tempstr = g_strconcat (oldstr, " ", ssh_extra_params_list[j], NULL); | |
745 g_free (oldstr); | |
746 } | |
747 } | |
748 | |
749 oldstr = tempstr; | |
750 tempstr = g_strconcat (oldstr, " -e none", NULL); | |
751 g_free (oldstr); | |
752 args[i++] = "-e"; | |
753 args[i++] = "none"; | |
754 | |
755 if (request->username && *request->username != '\0') | |
756 { | |
757 oldstr = tempstr; | |
758 tempstr = g_strconcat (oldstr, " -l ", request->username, NULL); | |
759 g_free (oldstr); | |
760 args[i++] = "-l"; | |
761 args[i++] = request->username; | |
762 } | |
763 | |
764 if (request->port != 0) | |
765 { | |
766 g_snprintf (portstring, 6, "%d", request->port); | |
767 oldstr = tempstr; | |
768 tempstr = g_strconcat (oldstr, " -p ", portstring, NULL); | |
769 g_free (oldstr); | |
770 args[i++] = "-p"; | |
771 args[i++] = portstring; | |
772 } | |
56 | 773 else |
774 { | |
775 if (!r_getservbyname ("ssh", "tcp", &serv_struct, NULL)) | |
776 request->port = 22; | |
777 else | |
778 request->port = ntohs (serv_struct.s_port); | |
779 } | |
1 | 780 |
781 if (use_sftp_subsys) | |
782 { | |
783 oldstr = tempstr; | |
784 tempstr = g_strconcat (oldstr, " ", request->hostname, " -s sftp", NULL); | |
785 g_free (oldstr); | |
786 args[i++] = request->hostname; | |
787 args[i++] = "-s"; | |
788 args[i++] = "sftp"; | |
789 args[i] = NULL; | |
790 } | |
791 else | |
792 { | |
793 oldstr = tempstr; | |
794 tempstr = g_strconcat (oldstr, " ", request->hostname, " \"", execname, | |
795 "\"", NULL); | |
796 g_free (oldstr); | |
797 args[i++] = request->hostname; | |
798 args[i++] = execname; | |
799 args[i] = NULL; | |
800 } | |
801 | |
802 request->logging_function (gftp_logging_misc, request->user_data, | |
803 _("Running program %s\n"), tempstr); | |
804 g_free (tempstr); | |
805 return (args); | |
806 } | |
807 | |
61 | 808 #define SSH_LOGIN_BUFSIZE 200 |
809 #define SSH_ERROR_BADPASS -1 | |
810 #define SSH_ERROR_QUESTION -2 | |
77 | 811 #define SSH_WARNING -3 |
1 | 812 |
813 char * | |
814 ssh_start_login_sequence (gftp_request * request, int fd) | |
815 { | |
65 | 816 char *tempstr, *pwstr, *tmppos; |
817 size_t rem, len, diff, lastdiff, key_pos; | |
58 | 818 int wrotepw, ok; |
1 | 819 ssize_t rd; |
820 | |
61 | 821 rem = len = SSH_LOGIN_BUFSIZE; |
65 | 822 tempstr = g_malloc0 (len + 1); |
823 key_pos = diff = lastdiff = 0; | |
1 | 824 wrotepw = 0; |
825 ok = 1; | |
826 | |
61 | 827 if (gftp_set_sockblocking (request, fd, 1) == -1) |
58 | 828 return (NULL); |
1 | 829 |
58 | 830 pwstr = g_strconcat (request->password, "\n", NULL); |
1 | 831 |
41 | 832 errno = 0; |
1 | 833 while (1) |
834 { | |
61 | 835 if ((rd = gftp_read (request, tempstr + diff, rem - 1, fd)) <= 0) |
1 | 836 { |
837 ok = 0; | |
838 break; | |
839 } | |
840 rem -= rd; | |
841 diff += rd; | |
65 | 842 tempstr[diff] = '\0'; |
1 | 843 |
61 | 844 if (diff > 11 && strcmp (tempstr + diff - 10, "password: ") == 0) |
1 | 845 { |
61 | 846 if (wrotepw) |
847 { | |
848 ok = SSH_ERROR_BADPASS; | |
849 break; | |
850 } | |
77 | 851 |
852 if (strstr (tempstr, "WARNING") != NULL || | |
853 strstr (tempstr, _("WARNING")) != NULL) | |
854 { | |
855 ok = SSH_WARNING; | |
856 break; | |
857 } | |
61 | 858 |
1 | 859 wrotepw = 1; |
58 | 860 if (gftp_write (request, pwstr, strlen (pwstr), fd) < 0) |
861 { | |
862 ok = 0; | |
863 break; | |
864 } | |
1 | 865 } |
65 | 866 else if (diff > 2 && strcmp (tempstr + diff - 2, ": ") == 0 && |
867 ((tmppos = strstr (tempstr + key_pos, "Enter passphrase for RSA key")) != NULL || | |
868 ((tmppos = strstr (tempstr + key_pos, "Enter passphrase for key '")) != NULL))) | |
61 | 869 { |
65 | 870 key_pos = diff; |
61 | 871 if (wrotepw) |
872 { | |
873 ok = SSH_ERROR_BADPASS; | |
874 break; | |
875 } | |
1 | 876 |
77 | 877 if (strstr (tempstr, "WARNING") != NULL || |
878 strstr (tempstr, _("WARNING")) != NULL) | |
879 { | |
880 ok = SSH_WARNING; | |
881 break; | |
882 } | |
883 | |
1 | 884 wrotepw = 1; |
58 | 885 if (gftp_write (request, pwstr, strlen (pwstr), fd) < 0) |
886 { | |
887 ok = 0; | |
888 break; | |
889 } | |
1 | 890 } |
65 | 891 else if (diff > 10 && strcmp (tempstr + diff - 10, "(yes/no)? ") == 0) |
61 | 892 { |
893 ok = SSH_ERROR_QUESTION; | |
894 break; | |
895 } | |
896 else if (diff >= 5 && strcmp (tempstr + diff - 5, "xsftp") == 0) | |
1 | 897 break; |
65 | 898 else if (rem <= 1) |
899 { | |
900 request->logging_function (gftp_logging_recv, request->user_data, | |
901 "%s", tempstr + lastdiff); | |
902 len += SSH_LOGIN_BUFSIZE; | |
903 rem += SSH_LOGIN_BUFSIZE; | |
904 lastdiff = diff; | |
905 tempstr = g_realloc (tempstr, len); | |
906 continue; | |
907 } | |
1 | 908 } |
909 | |
58 | 910 g_free (pwstr); |
61 | 911 |
912 if (*(tempstr + lastdiff) != '\0') | |
913 request->logging_function (gftp_logging_recv, request->user_data, | |
914 "%s\n", tempstr + lastdiff); | |
1 | 915 |
61 | 916 if (ok <= 0) |
1 | 917 { |
61 | 918 if (ok == SSH_ERROR_BADPASS) |
919 request->logging_function (gftp_logging_error, request->user_data, | |
920 _("Error: An incorrect password was entered\n")); | |
921 else if (ok == SSH_ERROR_QUESTION) | |
922 request->logging_function (gftp_logging_error, request->user_data, | |
923 _("Please connect to this host with the command line SSH utility and answer this question appropriately.\n")); | |
77 | 924 else if (ok == SSH_WARNING) |
925 request->logging_function (gftp_logging_error, request->user_data, | |
926 _("Please correct the above warning to connect to this host.\n")); | |
61 | 927 |
1 | 928 g_free (tempstr); |
929 return (NULL); | |
930 } | |
931 | |
932 return (tempstr); | |
933 } | |
934 | |
935 | |
936 #ifdef G_HAVE_GINT64 | |
937 | |
938 gint64 | |
939 hton64 (gint64 val) | |
940 { | |
941 gint64 num; | |
942 char *pos; | |
943 | |
944 num = 0; | |
945 pos = (char *) # | |
946 pos[0] = (val >> 56) & 0xff; | |
947 pos[1] = (val >> 48) & 0xff; | |
948 pos[2] = (val >> 40) & 0xff; | |
949 pos[3] = (val >> 32) & 0xff; | |
950 pos[4] = (val >> 24) & 0xff; | |
951 pos[5] = (val >> 16) & 0xff; | |
952 pos[6] = (val >> 8) & 0xff; | |
953 pos[7] = val & 0xff; | |
954 return (num); | |
955 } | |
956 | |
957 #endif | |
958 | |
16 | 959 |
960 static gint | |
961 gftp_file_sort_function_as (gconstpointer a, gconstpointer b) | |
962 { | |
963 const gftp_file * f1, * f2; | |
964 | |
965 f1 = a; | |
966 f2 = b; | |
967 return (strcmp (f1->file, f2->file)); | |
968 } | |
969 | |
970 | |
971 static gint | |
972 gftp_file_sort_function_ds (gconstpointer a, gconstpointer b) | |
973 { | |
974 const gftp_file * f1, * f2; | |
975 gint ret; | |
976 | |
977 f1 = a; | |
978 f2 = b; | |
979 ret = strcmp (f1->file, f2->file); | |
84 | 980 return (ret * -1); |
16 | 981 } |
982 | |
983 | |
984 static gint | |
985 gftp_user_sort_function_as (gconstpointer a, gconstpointer b) | |
986 { | |
987 const gftp_file * f1, * f2; | |
988 | |
989 f1 = a; | |
990 f2 = b; | |
991 return (strcmp (f1->user, f2->user)); | |
992 } | |
993 | |
994 | |
995 static gint | |
996 gftp_user_sort_function_ds (gconstpointer a, gconstpointer b) | |
997 { | |
998 const gftp_file * f1, * f2; | |
999 gint ret; | |
1000 | |
1001 f1 = a; | |
1002 f2 = b; | |
1003 ret = strcmp (f1->user, f2->user); | |
84 | 1004 return (ret * -1); |
16 | 1005 } |
1006 | |
1007 | |
1008 static gint | |
1009 gftp_group_sort_function_as (gconstpointer a, gconstpointer b) | |
1010 { | |
1011 const gftp_file * f1, * f2; | |
1012 | |
1013 f1 = a; | |
1014 f2 = b; | |
1015 return (strcmp (f1->group, f2->group)); | |
1016 } | |
1017 | |
1018 | |
1019 static gint | |
1020 gftp_group_sort_function_ds (gconstpointer a, gconstpointer b) | |
1021 { | |
1022 const gftp_file * f1, * f2; | |
1023 gint ret; | |
1024 | |
1025 f1 = a; | |
1026 f2 = b; | |
1027 ret = strcmp (f1->group, f2->group); | |
84 | 1028 return (ret * -1); |
16 | 1029 } |
1030 | |
1031 | |
1032 static gint | |
1033 gftp_attribs_sort_function_as (gconstpointer a, gconstpointer b) | |
1034 { | |
1035 const gftp_file * f1, * f2; | |
1036 | |
1037 f1 = a; | |
1038 f2 = b; | |
1039 return (strcmp (f1->attribs, f2->attribs)); | |
1040 } | |
1041 | |
1042 | |
1043 static gint | |
1044 gftp_attribs_sort_function_ds (gconstpointer a, gconstpointer b) | |
1045 { | |
1046 const gftp_file * f1, * f2; | |
1047 gint ret; | |
1048 | |
1049 f1 = a; | |
1050 f2 = b; | |
1051 ret = strcmp (f1->attribs, f2->attribs); | |
84 | 1052 return (ret * -1); |
16 | 1053 } |
1054 | |
1055 | |
1056 static gint | |
1057 gftp_size_sort_function_as (gconstpointer a, gconstpointer b) | |
1058 { | |
1059 const gftp_file * f1, * f2; | |
1060 | |
1061 f1 = a; | |
1062 f2 = b; | |
1063 if (f1->size < f2->size) | |
1064 return (-1); | |
1065 else if (f1->size == f2->size) | |
1066 return (0); | |
1067 else | |
1068 return (1); | |
1069 } | |
1070 | |
1071 | |
1072 static gint | |
1073 gftp_size_sort_function_ds (gconstpointer a, gconstpointer b) | |
1074 { | |
1075 const gftp_file * f1, * f2; | |
1076 | |
1077 f1 = a; | |
1078 f2 = b; | |
1079 if (f1->size < f2->size) | |
1080 return (1); | |
1081 else if (f1->size == f2->size) | |
1082 return (0); | |
1083 else | |
1084 return (-1); | |
1085 } | |
1086 | |
1087 | |
1088 static gint | |
1089 gftp_datetime_sort_function_as (gconstpointer a, gconstpointer b) | |
1090 { | |
1091 const gftp_file * f1, * f2; | |
1092 | |
1093 f1 = a; | |
1094 f2 = b; | |
1095 if (f1->datetime < f2->datetime) | |
1096 return (-1); | |
1097 else if (f1->datetime == f2->datetime) | |
1098 return (0); | |
1099 else | |
1100 return (1); | |
1101 } | |
1102 | |
1103 | |
1104 static gint | |
1105 gftp_datetime_sort_function_ds (gconstpointer a, gconstpointer b) | |
1106 { | |
1107 const gftp_file * f1, * f2; | |
1108 | |
1109 f1 = a; | |
1110 f2 = b; | |
1111 if (f1->datetime < f2->datetime) | |
1112 return (1); | |
1113 else if (f1->datetime == f2->datetime) | |
1114 return (0); | |
1115 else | |
1116 return (-1); | |
1117 } | |
1118 | |
1119 | |
1120 GList * | |
1121 gftp_sort_filelist (GList * filelist, int column, int asds) | |
1122 { | |
1123 GList * files, * dirs, * dotdot, * tempitem, * insitem; | |
1124 GCompareFunc sortfunc; | |
1125 gftp_file * tempfle; | |
1126 | |
1127 files = dirs = dotdot = NULL; | |
1128 | |
1129 if (column == GFTP_SORT_COL_FILE) | |
1130 sortfunc = asds ? gftp_file_sort_function_as : gftp_file_sort_function_ds; | |
1131 else if (column == GFTP_SORT_COL_SIZE) | |
1132 sortfunc = asds ? gftp_size_sort_function_as : gftp_size_sort_function_ds; | |
1133 else if (column == GFTP_SORT_COL_USER) | |
1134 sortfunc = asds ? gftp_user_sort_function_as : gftp_user_sort_function_ds; | |
1135 else if (column == GFTP_SORT_COL_GROUP) | |
1136 sortfunc = asds ? | |
1137 gftp_group_sort_function_as : gftp_group_sort_function_ds; | |
1138 else if (column == GFTP_SORT_COL_DATETIME) | |
1139 sortfunc = asds ? | |
1140 gftp_datetime_sort_function_as : gftp_datetime_sort_function_ds; else /* GFTP_SORT_COL_ATTRIBS */ | |
1141 sortfunc = asds ? | |
1142 gftp_attribs_sort_function_as : gftp_attribs_sort_function_ds; | |
1143 | |
1144 for (tempitem = filelist; tempitem != NULL; ) | |
1145 { | |
1146 tempfle = tempitem->data; | |
1147 insitem = tempitem; | |
1148 tempitem = tempitem->next; | |
1149 insitem->next = NULL; | |
1150 | |
1151 if (dotdot == NULL && strcmp (tempfle->file, "..") == 0) | |
1152 dotdot = insitem; | |
1153 else if (sort_dirs_first && tempfle->isdir) | |
1154 { | |
1155 insitem->next = dirs; | |
1156 dirs = insitem; | |
1157 } | |
1158 else | |
1159 { | |
1160 insitem->next = files; | |
1161 files = insitem; | |
1162 } | |
1163 } | |
1164 | |
1165 if (dirs != NULL) | |
1166 dirs = g_list_sort (dirs, sortfunc); | |
1167 if (files != NULL) | |
1168 files = g_list_sort (files, sortfunc); | |
1169 | |
1170 filelist = dotdot; | |
1171 | |
1172 if (filelist == NULL) | |
1173 filelist = dirs; | |
1174 else | |
1175 filelist = g_list_concat (filelist, dirs); | |
1176 | |
1177 if (filelist == NULL) | |
1178 filelist = files; | |
1179 else | |
1180 filelist = g_list_concat (filelist, files); | |
1181 | |
39 | 1182 /* I haven't check this, but I'm pretty sure some older versions of glib |
1183 had a bug that the prev pointer wasn't being sent to NULL */ | |
1184 filelist->prev = NULL; | |
16 | 1185 return (filelist); |
1186 } | |
1187 |