diff options
Diffstat (limited to 'sftp-int.c')
-rw-r--r-- | sftp-int.c | 133 |
1 files changed, 98 insertions, 35 deletions
diff --git a/sftp-int.c b/sftp-int.c index 6f5b3677a..d350e398d 100644 --- a/sftp-int.c +++ b/sftp-int.c | |||
@@ -22,13 +22,13 @@ | |||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | /* XXX: finish implementation of all commands */ | ||
26 | /* XXX: do fnmatch() instead of using raw pathname */ | ||
27 | /* XXX: globbed ls */ | 25 | /* XXX: globbed ls */ |
28 | /* XXX: recursive operations */ | 26 | /* XXX: recursive operations */ |
29 | 27 | ||
30 | #include "includes.h" | 28 | #include "includes.h" |
31 | RCSID("$OpenBSD: sftp-int.c,v 1.26 2001/03/07 10:11:23 djm Exp $"); | 29 | RCSID("$OpenBSD: sftp-int.c,v 1.27 2001/03/13 22:42:54 djm Exp $"); |
30 | |||
31 | #include <glob.h> | ||
32 | 32 | ||
33 | #include "buffer.h" | 33 | #include "buffer.h" |
34 | #include "xmalloc.h" | 34 | #include "xmalloc.h" |
@@ -37,6 +37,7 @@ RCSID("$OpenBSD: sftp-int.c,v 1.26 2001/03/07 10:11:23 djm Exp $"); | |||
37 | 37 | ||
38 | #include "sftp.h" | 38 | #include "sftp.h" |
39 | #include "sftp-common.h" | 39 | #include "sftp-common.h" |
40 | #include "sftp-glob.h" | ||
40 | #include "sftp-client.h" | 41 | #include "sftp-client.h" |
41 | #include "sftp-int.h" | 42 | #include "sftp-int.h" |
42 | 43 | ||
@@ -283,8 +284,6 @@ infer_path(const char *p, char **ifp) | |||
283 | { | 284 | { |
284 | char *cp; | 285 | char *cp; |
285 | 286 | ||
286 | debug("XXX: P = \"%s\"", p); | ||
287 | |||
288 | cp = strrchr(p, '/'); | 287 | cp = strrchr(p, '/'); |
289 | if (cp == NULL) { | 288 | if (cp == NULL) { |
290 | *ifp = xstrdup(p); | 289 | *ifp = xstrdup(p); |
@@ -360,9 +359,6 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg, | |||
360 | /* Try to get second pathname (optional) */ | 359 | /* Try to get second pathname (optional) */ |
361 | if (get_pathname(&cp, path2)) | 360 | if (get_pathname(&cp, path2)) |
362 | return(-1); | 361 | return(-1); |
363 | /* Otherwise try to guess it from first path */ | ||
364 | if (*path2 == NULL && infer_path(*path1, path2)) | ||
365 | return(-1); | ||
366 | break; | 362 | break; |
367 | case I_RENAME: | 363 | case I_RENAME: |
368 | case I_SYMLINK: | 364 | case I_SYMLINK: |
@@ -451,11 +447,12 @@ int | |||
451 | parse_dispatch_command(int in, int out, const char *cmd, char **pwd) | 447 | parse_dispatch_command(int in, int out, const char *cmd, char **pwd) |
452 | { | 448 | { |
453 | char *path1, *path2, *tmp; | 449 | char *path1, *path2, *tmp; |
454 | int pflag, cmdnum; | 450 | int pflag, cmdnum, i; |
455 | unsigned long n_arg; | 451 | unsigned long n_arg; |
456 | Attrib a, *aa; | 452 | Attrib a, *aa; |
457 | char path_buf[MAXPATHLEN]; | 453 | char path_buf[MAXPATHLEN]; |
458 | int err = 0; | 454 | int err = 0; |
455 | glob_t g; | ||
459 | 456 | ||
460 | path1 = path2 = NULL; | 457 | path1 = path2 = NULL; |
461 | cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2); | 458 | cmdnum = parse_args(&cmd, &pflag, &n_arg, &path1, &path2); |
@@ -465,14 +462,63 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) | |||
465 | case -1: | 462 | case -1: |
466 | break; | 463 | break; |
467 | case I_GET: | 464 | case I_GET: |
468 | path1 = make_absolute(path1, *pwd); | 465 | memset(&g, 0, sizeof(g)); |
469 | err = do_download(in, out, path1, path2, pflag); | 466 | if (!remote_glob(in, out, path1, 0, NULL, &g)) { |
467 | if (path2) { | ||
468 | /* XXX: target should be directory */ | ||
469 | error("You cannot specify a target when " | ||
470 | "downloading multiple files"); | ||
471 | err = -1; | ||
472 | break; | ||
473 | } | ||
474 | for(i = 0; g.gl_pathv[i]; i++) { | ||
475 | if (!infer_path(g.gl_pathv[i], &path2)) { | ||
476 | printf("Fetching %s\n", g.gl_pathv[i]); | ||
477 | if (do_download(in, out, g.gl_pathv[i], | ||
478 | path2, pflag) == -1) | ||
479 | err = -1; | ||
480 | free(path2); | ||
481 | path2 = NULL; | ||
482 | } else | ||
483 | err = -1; | ||
484 | } | ||
485 | } else { | ||
486 | if (!path2 && infer_path(path1, &path2)) { | ||
487 | err = -1; | ||
488 | break; | ||
489 | } | ||
490 | err = do_download(in, out, path1, path2, pflag); | ||
491 | } | ||
470 | break; | 492 | break; |
471 | case I_PUT: | 493 | case I_PUT: |
472 | path2 = make_absolute(path2, *pwd); | 494 | if (!glob(path1, 0, NULL, &g)) { |
473 | err = do_upload(in, out, path1, path2, pflag); | 495 | if (path2) { |
474 | break; | 496 | error("You cannot specify a target when " |
475 | case I_RENAME: | 497 | "uploading multiple files"); |
498 | err = -1; | ||
499 | break; | ||
500 | } | ||
501 | for(i = 0; g.gl_pathv[i]; i++) { | ||
502 | if (!infer_path(g.gl_pathv[i], &path2)) { | ||
503 | path2 = make_absolute(path2, *pwd); | ||
504 | printf("Uploading %s\n", g.gl_pathv[i]); | ||
505 | if (do_upload(in, out, g.gl_pathv[i], | ||
506 | path2, pflag) == -1) | ||
507 | err = -1; | ||
508 | free(path2); | ||
509 | path2 = NULL; | ||
510 | } else | ||
511 | err = -1; | ||
512 | } | ||
513 | } else { | ||
514 | if (!path2 && infer_path(path1, &path2)) { | ||
515 | err = -1; | ||
516 | break; | ||
517 | } | ||
518 | err = do_upload(in, out, path1, path2, pflag); | ||
519 | } | ||
520 | break; | ||
521 | case I_RENAME: | ||
476 | path1 = make_absolute(path1, *pwd); | 522 | path1 = make_absolute(path1, *pwd); |
477 | path2 = make_absolute(path2, *pwd); | 523 | path2 = make_absolute(path2, *pwd); |
478 | err = do_rename(in, out, path1, path2); | 524 | err = do_rename(in, out, path1, path2); |
@@ -489,7 +535,12 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) | |||
489 | break; | 535 | break; |
490 | case I_RM: | 536 | case I_RM: |
491 | path1 = make_absolute(path1, *pwd); | 537 | path1 = make_absolute(path1, *pwd); |
492 | err = do_rm(in, out, path1); | 538 | remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); |
539 | for(i = 0; g.gl_pathv[i]; i++) { | ||
540 | printf("Removing %s\n", g.gl_pathv[i]); | ||
541 | if (do_rm(in, out, g.gl_pathv[i]) == -1) | ||
542 | err = -1; | ||
543 | } | ||
493 | break; | 544 | break; |
494 | case I_MKDIR: | 545 | case I_MKDIR: |
495 | path1 = make_absolute(path1, *pwd); | 546 | path1 = make_absolute(path1, *pwd); |
@@ -577,33 +628,45 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd) | |||
577 | attrib_clear(&a); | 628 | attrib_clear(&a); |
578 | a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; | 629 | a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; |
579 | a.perm = n_arg; | 630 | a.perm = n_arg; |
580 | do_setstat(in, out, path1, &a); | 631 | remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); |
632 | for(i = 0; g.gl_pathv[i]; i++) { | ||
633 | printf("Changing mode on %s\n", g.gl_pathv[i]); | ||
634 | do_setstat(in, out, g.gl_pathv[i], &a); | ||
635 | } | ||
581 | break; | 636 | break; |
582 | case I_CHOWN: | 637 | case I_CHOWN: |
583 | path1 = make_absolute(path1, *pwd); | 638 | path1 = make_absolute(path1, *pwd); |
584 | if (!(aa = do_stat(in, out, path1))) | 639 | remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); |
585 | break; | 640 | for(i = 0; g.gl_pathv[i]; i++) { |
586 | if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { | 641 | if (!(aa = do_stat(in, out, g.gl_pathv[i]))) |
587 | error("Can't get current ownership of " | 642 | continue; |
588 | "remote file \"%s\"", path1); | 643 | if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { |
589 | break; | 644 | error("Can't get current ownership of " |
645 | "remote file \"%s\"", g.gl_pathv[i]); | ||
646 | continue; | ||
647 | } | ||
648 | printf("Changing owner on %s\n", g.gl_pathv[i]); | ||
649 | aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; | ||
650 | aa->uid = n_arg; | ||
651 | do_setstat(in, out, g.gl_pathv[i], aa); | ||
590 | } | 652 | } |
591 | aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; | ||
592 | aa->uid = n_arg; | ||
593 | do_setstat(in, out, path1, aa); | ||
594 | break; | 653 | break; |
595 | case I_CHGRP: | 654 | case I_CHGRP: |
596 | path1 = make_absolute(path1, *pwd); | 655 | path1 = make_absolute(path1, *pwd); |
597 | if (!(aa = do_stat(in, out, path1))) | 656 | remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g); |
598 | break; | 657 | for(i = 0; g.gl_pathv[i]; i++) { |
599 | if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { | 658 | if (!(aa = do_stat(in, out, g.gl_pathv[i]))) |
600 | error("Can't get current ownership of " | 659 | continue; |
601 | "remote file \"%s\"", path1); | 660 | if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { |
602 | break; | 661 | error("Can't get current ownership of " |
662 | "remote file \"%s\"", g.gl_pathv[i]); | ||
663 | continue; | ||
664 | } | ||
665 | printf("Changing group on %s\n", g.gl_pathv[i]); | ||
666 | aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; | ||
667 | aa->gid = n_arg; | ||
668 | do_setstat(in, out, g.gl_pathv[i], aa); | ||
603 | } | 669 | } |
604 | aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; | ||
605 | aa->gid = n_arg; | ||
606 | do_setstat(in, out, path1, aa); | ||
607 | break; | 670 | break; |
608 | case I_PWD: | 671 | case I_PWD: |
609 | printf("Remote working directory: %s\n", *pwd); | 672 | printf("Remote working directory: %s\n", *pwd); |