diff options
author | Colin Watson <cjwatson@debian.org> | 2005-01-04 13:07:27 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2005-01-04 13:07:27 +0000 |
commit | fd0f611b70a83d80fe8793af785542ee5541b7cd (patch) | |
tree | bededd22bb7eeec52e20083237ab7e4113445a16 /sftp.c | |
parent | c44fe9a5b9d3db96a7249b04d915f17e4a3a3b04 (diff) | |
parent | ebd2ce335af5861020c79fddb1ae35c03bf036cf (diff) |
Merge 3.9p1 to the trunk.
Diffstat (limited to 'sftp.c')
-rw-r--r-- | sftp.c | 188 |
1 files changed, 136 insertions, 52 deletions
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | #include "includes.h" | 17 | #include "includes.h" |
18 | 18 | ||
19 | RCSID("$OpenBSD: sftp.c,v 1.45 2004/03/03 09:31:20 djm Exp $"); | 19 | RCSID("$OpenBSD: sftp.c,v 1.56 2004/07/11 17:48:47 deraadt Exp $"); |
20 | 20 | ||
21 | #include "buffer.h" | 21 | #include "buffer.h" |
22 | #include "xmalloc.h" | 22 | #include "xmalloc.h" |
@@ -46,21 +46,32 @@ static pid_t sshpid = -1; | |||
46 | /* This is set to 0 if the progressmeter is not desired. */ | 46 | /* This is set to 0 if the progressmeter is not desired. */ |
47 | int showprogress = 1; | 47 | int showprogress = 1; |
48 | 48 | ||
49 | /* SIGINT received during command processing */ | ||
50 | volatile sig_atomic_t interrupted = 0; | ||
51 | |||
52 | /* I wish qsort() took a separate ctx for the comparison function...*/ | ||
53 | int sort_flag; | ||
54 | |||
49 | int remote_glob(struct sftp_conn *, const char *, int, | 55 | int remote_glob(struct sftp_conn *, const char *, int, |
50 | int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ | 56 | int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */ |
51 | 57 | ||
52 | #ifdef HAVE___PROGNAME | ||
53 | extern char *__progname; | 58 | extern char *__progname; |
54 | #else | ||
55 | char *__progname; | ||
56 | #endif | ||
57 | 59 | ||
58 | /* Separators for interactive commands */ | 60 | /* Separators for interactive commands */ |
59 | #define WHITESPACE " \t\r\n" | 61 | #define WHITESPACE " \t\r\n" |
60 | 62 | ||
61 | /* Define what type of ls view (0 - multi-column) */ | 63 | /* ls flags */ |
62 | #define LONG_VIEW 1 /* Full view ala ls -l */ | 64 | #define LS_LONG_VIEW 0x01 /* Full view ala ls -l */ |
63 | #define SHORT_VIEW 2 /* Single row view ala ls -1 */ | 65 | #define LS_SHORT_VIEW 0x02 /* Single row view ala ls -1 */ |
66 | #define LS_NUMERIC_VIEW 0x04 /* Long view with numeric uid/gid */ | ||
67 | #define LS_NAME_SORT 0x08 /* Sort by name (default) */ | ||
68 | #define LS_TIME_SORT 0x10 /* Sort by mtime */ | ||
69 | #define LS_SIZE_SORT 0x20 /* Sort by file size */ | ||
70 | #define LS_REVERSE_SORT 0x40 /* Reverse sort order */ | ||
71 | #define LS_SHOW_ALL 0x80 /* Don't skip filenames starting with '.' */ | ||
72 | |||
73 | #define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW) | ||
74 | #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) | ||
64 | 75 | ||
65 | /* Commands for interactive mode */ | 76 | /* Commands for interactive mode */ |
66 | #define I_CHDIR 1 | 77 | #define I_CHDIR 1 |
@@ -131,6 +142,24 @@ static const struct CMD cmds[] = { | |||
131 | int interactive_loop(int fd_in, int fd_out, char *file1, char *file2); | 142 | int interactive_loop(int fd_in, int fd_out, char *file1, char *file2); |
132 | 143 | ||
133 | static void | 144 | static void |
145 | killchild(int signo) | ||
146 | { | ||
147 | if (sshpid > 1) | ||
148 | kill(sshpid, SIGTERM); | ||
149 | |||
150 | _exit(1); | ||
151 | } | ||
152 | |||
153 | static void | ||
154 | cmd_interrupt(int signo) | ||
155 | { | ||
156 | const char msg[] = "\rInterrupt \n"; | ||
157 | |||
158 | write(STDERR_FILENO, msg, sizeof(msg) - 1); | ||
159 | interrupted = 1; | ||
160 | } | ||
161 | |||
162 | static void | ||
134 | help(void) | 163 | help(void) |
135 | { | 164 | { |
136 | printf("Available commands:\n"); | 165 | printf("Available commands:\n"); |
@@ -254,13 +283,13 @@ path_append(char *p1, char *p2) | |||
254 | static char * | 283 | static char * |
255 | make_absolute(char *p, char *pwd) | 284 | make_absolute(char *p, char *pwd) |
256 | { | 285 | { |
257 | char *abs; | 286 | char *abs_str; |
258 | 287 | ||
259 | /* Derelativise */ | 288 | /* Derelativise */ |
260 | if (p && p[0] != '/') { | 289 | if (p && p[0] != '/') { |
261 | abs = path_append(pwd, p); | 290 | abs_str = path_append(pwd, p); |
262 | xfree(p); | 291 | xfree(p); |
263 | return(abs); | 292 | return(abs_str); |
264 | } else | 293 | } else |
265 | return(p); | 294 | return(p); |
266 | } | 295 | } |
@@ -313,15 +342,41 @@ parse_ls_flags(const char **cpp, int *lflag) | |||
313 | { | 342 | { |
314 | const char *cp = *cpp; | 343 | const char *cp = *cpp; |
315 | 344 | ||
345 | /* Defaults */ | ||
346 | *lflag = LS_NAME_SORT; | ||
347 | |||
316 | /* Check for flags */ | 348 | /* Check for flags */ |
317 | if (cp++[0] == '-') { | 349 | if (cp++[0] == '-') { |
318 | for(; strchr(WHITESPACE, *cp) == NULL; cp++) { | 350 | for(; strchr(WHITESPACE, *cp) == NULL; cp++) { |
319 | switch (*cp) { | 351 | switch (*cp) { |
320 | case 'l': | 352 | case 'l': |
321 | *lflag = LONG_VIEW; | 353 | *lflag &= ~VIEW_FLAGS; |
354 | *lflag |= LS_LONG_VIEW; | ||
322 | break; | 355 | break; |
323 | case '1': | 356 | case '1': |
324 | *lflag = SHORT_VIEW; | 357 | *lflag &= ~VIEW_FLAGS; |
358 | *lflag |= LS_SHORT_VIEW; | ||
359 | break; | ||
360 | case 'n': | ||
361 | *lflag &= ~VIEW_FLAGS; | ||
362 | *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; | ||
363 | break; | ||
364 | case 'S': | ||
365 | *lflag &= ~SORT_FLAGS; | ||
366 | *lflag |= LS_SIZE_SORT; | ||
367 | break; | ||
368 | case 't': | ||
369 | *lflag &= ~SORT_FLAGS; | ||
370 | *lflag |= LS_TIME_SORT; | ||
371 | break; | ||
372 | case 'r': | ||
373 | *lflag |= LS_REVERSE_SORT; | ||
374 | break; | ||
375 | case 'f': | ||
376 | *lflag &= ~SORT_FLAGS; | ||
377 | break; | ||
378 | case 'a': | ||
379 | *lflag |= LS_SHOW_ALL; | ||
325 | break; | 380 | break; |
326 | default: | 381 | default: |
327 | error("Invalid flag -%c", *cp); | 382 | error("Invalid flag -%c", *cp); |
@@ -369,7 +424,7 @@ get_pathname(const char **cpp, char **path) | |||
369 | i++; | 424 | i++; |
370 | if (cp[i] != '\'' && cp[i] != '\"' && | 425 | if (cp[i] != '\'' && cp[i] != '\"' && |
371 | cp[i] != '\\') { | 426 | cp[i] != '\\') { |
372 | error("Bad escaped character '\%c'", | 427 | error("Bad escaped character '\\%c'", |
373 | cp[i]); | 428 | cp[i]); |
374 | goto fail; | 429 | goto fail; |
375 | } | 430 | } |
@@ -465,7 +520,7 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) | |||
465 | goto out; | 520 | goto out; |
466 | } | 521 | } |
467 | 522 | ||
468 | for (i = 0; g.gl_pathv[i]; i++) { | 523 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
469 | if (infer_path(g.gl_pathv[i], &tmp)) { | 524 | if (infer_path(g.gl_pathv[i], &tmp)) { |
470 | err = -1; | 525 | err = -1; |
471 | goto out; | 526 | goto out; |
@@ -534,7 +589,7 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag) | |||
534 | goto out; | 589 | goto out; |
535 | } | 590 | } |
536 | 591 | ||
537 | for (i = 0; g.gl_pathv[i]; i++) { | 592 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
538 | if (!is_reg(g.gl_pathv[i])) { | 593 | if (!is_reg(g.gl_pathv[i])) { |
539 | error("skipping non-regular file %s", | 594 | error("skipping non-regular file %s", |
540 | g.gl_pathv[i]); | 595 | g.gl_pathv[i]); |
@@ -582,8 +637,17 @@ sdirent_comp(const void *aa, const void *bb) | |||
582 | { | 637 | { |
583 | SFTP_DIRENT *a = *(SFTP_DIRENT **)aa; | 638 | SFTP_DIRENT *a = *(SFTP_DIRENT **)aa; |
584 | SFTP_DIRENT *b = *(SFTP_DIRENT **)bb; | 639 | SFTP_DIRENT *b = *(SFTP_DIRENT **)bb; |
640 | int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1; | ||
641 | |||
642 | #define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1)) | ||
643 | if (sort_flag & LS_NAME_SORT) | ||
644 | return (rmul * strcmp(a->filename, b->filename)); | ||
645 | else if (sort_flag & LS_TIME_SORT) | ||
646 | return (rmul * NCMP(a->a.mtime, b->a.mtime)); | ||
647 | else if (sort_flag & LS_SIZE_SORT) | ||
648 | return (rmul * NCMP(a->a.size, b->a.size)); | ||
585 | 649 | ||
586 | return (strcmp(a->filename, b->filename)); | 650 | fatal("Unknown ls sort type"); |
587 | } | 651 | } |
588 | 652 | ||
589 | /* sftp ls.1 replacement for directories */ | 653 | /* sftp ls.1 replacement for directories */ |
@@ -596,14 +660,16 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) | |||
596 | if ((n = do_readdir(conn, path, &d)) != 0) | 660 | if ((n = do_readdir(conn, path, &d)) != 0) |
597 | return (n); | 661 | return (n); |
598 | 662 | ||
599 | if (!(lflag & SHORT_VIEW)) { | 663 | if (!(lflag & LS_SHORT_VIEW)) { |
600 | int m = 0, width = 80; | 664 | int m = 0, width = 80; |
601 | struct winsize ws; | 665 | struct winsize ws; |
602 | char *tmp; | 666 | char *tmp; |
603 | 667 | ||
604 | /* Count entries for sort and find longest filename */ | 668 | /* Count entries for sort and find longest filename */ |
605 | for (n = 0; d[n] != NULL; n++) | 669 | for (n = 0; d[n] != NULL; n++) { |
606 | m = MAX(m, strlen(d[n]->filename)); | 670 | if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL)) |
671 | m = MAX(m, strlen(d[n]->filename)); | ||
672 | } | ||
607 | 673 | ||
608 | /* Add any subpath that also needs to be counted */ | 674 | /* Add any subpath that also needs to be counted */ |
609 | tmp = path_strip(path, strip_path); | 675 | tmp = path_strip(path, strip_path); |
@@ -619,24 +685,33 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) | |||
619 | colspace = MIN(colspace, width); | 685 | colspace = MIN(colspace, width); |
620 | } | 686 | } |
621 | 687 | ||
622 | qsort(d, n, sizeof(*d), sdirent_comp); | 688 | if (lflag & SORT_FLAGS) { |
689 | sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT); | ||
690 | qsort(d, n, sizeof(*d), sdirent_comp); | ||
691 | } | ||
623 | 692 | ||
624 | for (n = 0; d[n] != NULL; n++) { | 693 | for (n = 0; d[n] != NULL && !interrupted; n++) { |
625 | char *tmp, *fname; | 694 | char *tmp, *fname; |
626 | 695 | ||
696 | if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL)) | ||
697 | continue; | ||
698 | |||
627 | tmp = path_append(path, d[n]->filename); | 699 | tmp = path_append(path, d[n]->filename); |
628 | fname = path_strip(tmp, strip_path); | 700 | fname = path_strip(tmp, strip_path); |
629 | xfree(tmp); | 701 | xfree(tmp); |
630 | 702 | ||
631 | if (lflag & LONG_VIEW) { | 703 | if (lflag & LS_LONG_VIEW) { |
632 | char *lname; | 704 | if (lflag & LS_NUMERIC_VIEW) { |
633 | struct stat sb; | 705 | char *lname; |
706 | struct stat sb; | ||
634 | 707 | ||
635 | memset(&sb, 0, sizeof(sb)); | 708 | memset(&sb, 0, sizeof(sb)); |
636 | attrib_to_stat(&d[n]->a, &sb); | 709 | attrib_to_stat(&d[n]->a, &sb); |
637 | lname = ls_file(fname, &sb, 1); | 710 | lname = ls_file(fname, &sb, 1); |
638 | printf("%s\n", lname); | 711 | printf("%s\n", lname); |
639 | xfree(lname); | 712 | xfree(lname); |
713 | } else | ||
714 | printf("%s\n", d[n]->longname); | ||
640 | } else { | 715 | } else { |
641 | printf("%-*s", colspace, fname); | 716 | printf("%-*s", colspace, fname); |
642 | if (c >= columns) { | 717 | if (c >= columns) { |
@@ -649,7 +724,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) | |||
649 | xfree(fname); | 724 | xfree(fname); |
650 | } | 725 | } |
651 | 726 | ||
652 | if (!(lflag & LONG_VIEW) && (c != 1)) | 727 | if (!(lflag & LS_LONG_VIEW) && (c != 1)) |
653 | printf("\n"); | 728 | printf("\n"); |
654 | 729 | ||
655 | free_sftp_dirents(d); | 730 | free_sftp_dirents(d); |
@@ -673,6 +748,9 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
673 | return (-1); | 748 | return (-1); |
674 | } | 749 | } |
675 | 750 | ||
751 | if (interrupted) | ||
752 | goto out; | ||
753 | |||
676 | /* | 754 | /* |
677 | * If the glob returns a single match, which is the same as the | 755 | * If the glob returns a single match, which is the same as the |
678 | * input glob, and it is a directory, then just list its contents | 756 | * input glob, and it is a directory, then just list its contents |
@@ -690,7 +768,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
690 | } | 768 | } |
691 | } | 769 | } |
692 | 770 | ||
693 | if (!(lflag & SHORT_VIEW)) { | 771 | if (!(lflag & LS_SHORT_VIEW)) { |
694 | int m = 0, width = 80; | 772 | int m = 0, width = 80; |
695 | struct winsize ws; | 773 | struct winsize ws; |
696 | 774 | ||
@@ -706,12 +784,12 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
706 | colspace = width / columns; | 784 | colspace = width / columns; |
707 | } | 785 | } |
708 | 786 | ||
709 | for (i = 0; g.gl_pathv[i]; i++) { | 787 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
710 | char *fname; | 788 | char *fname; |
711 | 789 | ||
712 | fname = path_strip(g.gl_pathv[i], strip_path); | 790 | fname = path_strip(g.gl_pathv[i], strip_path); |
713 | 791 | ||
714 | if (lflag & LONG_VIEW) { | 792 | if (lflag & LS_LONG_VIEW) { |
715 | char *lname; | 793 | char *lname; |
716 | struct stat sb; | 794 | struct stat sb; |
717 | 795 | ||
@@ -740,9 +818,10 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, | |||
740 | xfree(fname); | 818 | xfree(fname); |
741 | } | 819 | } |
742 | 820 | ||
743 | if (!(lflag & LONG_VIEW) && (c != 1)) | 821 | if (!(lflag & LS_LONG_VIEW) && (c != 1)) |
744 | printf("\n"); | 822 | printf("\n"); |
745 | 823 | ||
824 | out: | ||
746 | if (g.gl_pathc) | 825 | if (g.gl_pathc) |
747 | globfree(&g); | 826 | globfree(&g); |
748 | 827 | ||
@@ -952,7 +1031,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
952 | case I_RM: | 1031 | case I_RM: |
953 | path1 = make_absolute(path1, *pwd); | 1032 | path1 = make_absolute(path1, *pwd); |
954 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); | 1033 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); |
955 | for (i = 0; g.gl_pathv[i]; i++) { | 1034 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
956 | printf("Removing %s\n", g.gl_pathv[i]); | 1035 | printf("Removing %s\n", g.gl_pathv[i]); |
957 | err = do_rm(conn, g.gl_pathv[i]); | 1036 | err = do_rm(conn, g.gl_pathv[i]); |
958 | if (err != 0 && err_abort) | 1037 | if (err != 0 && err_abort) |
@@ -1041,7 +1120,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1041 | a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; | 1120 | a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS; |
1042 | a.perm = n_arg; | 1121 | a.perm = n_arg; |
1043 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); | 1122 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); |
1044 | for (i = 0; g.gl_pathv[i]; i++) { | 1123 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
1045 | printf("Changing mode on %s\n", g.gl_pathv[i]); | 1124 | printf("Changing mode on %s\n", g.gl_pathv[i]); |
1046 | err = do_setstat(conn, g.gl_pathv[i], &a); | 1125 | err = do_setstat(conn, g.gl_pathv[i], &a); |
1047 | if (err != 0 && err_abort) | 1126 | if (err != 0 && err_abort) |
@@ -1052,7 +1131,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, | |||
1052 | case I_CHGRP: | 1131 | case I_CHGRP: |
1053 | path1 = make_absolute(path1, *pwd); | 1132 | path1 = make_absolute(path1, *pwd); |
1054 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); | 1133 | remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); |
1055 | for (i = 0; g.gl_pathv[i]; i++) { | 1134 | for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
1056 | if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { | 1135 | if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { |
1057 | if (err != 0 && err_abort) | 1136 | if (err != 0 && err_abort) |
1058 | break; | 1137 | break; |
@@ -1180,6 +1259,8 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) | |||
1180 | for (;;) { | 1259 | for (;;) { |
1181 | char *cp; | 1260 | char *cp; |
1182 | 1261 | ||
1262 | signal(SIGINT, SIG_IGN); | ||
1263 | |||
1183 | printf("sftp> "); | 1264 | printf("sftp> "); |
1184 | 1265 | ||
1185 | /* XXX: use libedit */ | 1266 | /* XXX: use libedit */ |
@@ -1195,6 +1276,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) | |||
1195 | if (cp) | 1276 | if (cp) |
1196 | *cp = '\0'; | 1277 | *cp = '\0'; |
1197 | 1278 | ||
1279 | /* Handle user interrupts gracefully during commands */ | ||
1280 | interrupted = 0; | ||
1281 | signal(SIGINT, cmd_interrupt); | ||
1282 | |||
1198 | err = parse_dispatch_command(conn, cmd, &pwd, batchmode); | 1283 | err = parse_dispatch_command(conn, cmd, &pwd, batchmode); |
1199 | if (err != 0) | 1284 | if (err != 0) |
1200 | break; | 1285 | break; |
@@ -1206,15 +1291,6 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2) | |||
1206 | } | 1291 | } |
1207 | 1292 | ||
1208 | static void | 1293 | static void |
1209 | killchild(int signo) | ||
1210 | { | ||
1211 | if (sshpid > 1) | ||
1212 | kill(sshpid, signo); | ||
1213 | |||
1214 | _exit(1); | ||
1215 | } | ||
1216 | |||
1217 | static void | ||
1218 | connect_to_server(char *path, char **args, int *in, int *out) | 1294 | connect_to_server(char *path, char **args, int *in, int *out) |
1219 | { | 1295 | { |
1220 | int c_in, c_out; | 1296 | int c_in, c_out; |
@@ -1243,15 +1319,23 @@ connect_to_server(char *path, char **args, int *in, int *out) | |||
1243 | if ((dup2(c_in, STDIN_FILENO) == -1) || | 1319 | if ((dup2(c_in, STDIN_FILENO) == -1) || |
1244 | (dup2(c_out, STDOUT_FILENO) == -1)) { | 1320 | (dup2(c_out, STDOUT_FILENO) == -1)) { |
1245 | fprintf(stderr, "dup2: %s\n", strerror(errno)); | 1321 | fprintf(stderr, "dup2: %s\n", strerror(errno)); |
1246 | exit(1); | 1322 | _exit(1); |
1247 | } | 1323 | } |
1248 | close(*in); | 1324 | close(*in); |
1249 | close(*out); | 1325 | close(*out); |
1250 | close(c_in); | 1326 | close(c_in); |
1251 | close(c_out); | 1327 | close(c_out); |
1252 | execv(path, args); | 1328 | |
1329 | /* | ||
1330 | * The underlying ssh is in the same process group, so we must | ||
1331 | * ignore SIGINT if we want to gracefully abort commands, | ||
1332 | * otherwise the signal will make it to the ssh process and | ||
1333 | * kill it too | ||
1334 | */ | ||
1335 | signal(SIGINT, SIG_IGN); | ||
1336 | execvp(path, args); | ||
1253 | fprintf(stderr, "exec: %s: %s\n", path, strerror(errno)); | 1337 | fprintf(stderr, "exec: %s: %s\n", path, strerror(errno)); |
1254 | exit(1); | 1338 | _exit(1); |
1255 | } | 1339 | } |
1256 | 1340 | ||
1257 | signal(SIGTERM, killchild); | 1341 | signal(SIGTERM, killchild); |
@@ -1280,7 +1364,7 @@ int | |||
1280 | main(int argc, char **argv) | 1364 | main(int argc, char **argv) |
1281 | { | 1365 | { |
1282 | int in, out, ch, err; | 1366 | int in, out, ch, err; |
1283 | char *host, *userhost, *cp, *file2; | 1367 | char *host, *userhost, *cp, *file2 = NULL; |
1284 | int debug_level = 0, sshver = 2; | 1368 | int debug_level = 0, sshver = 2; |
1285 | char *file1 = NULL, *sftp_server = NULL; | 1369 | char *file1 = NULL, *sftp_server = NULL; |
1286 | char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; | 1370 | char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL; |
@@ -1331,7 +1415,7 @@ main(int argc, char **argv) | |||
1331 | fatal("Batch file already specified."); | 1415 | fatal("Batch file already specified."); |
1332 | 1416 | ||
1333 | /* Allow "-" as stdin */ | 1417 | /* Allow "-" as stdin */ |
1334 | if (strcmp(optarg, "-") != 0 && | 1418 | if (strcmp(optarg, "-") != 0 && |
1335 | (infile = fopen(optarg, "r")) == NULL) | 1419 | (infile = fopen(optarg, "r")) == NULL) |
1336 | fatal("%s (%s).", strerror(errno), optarg); | 1420 | fatal("%s (%s).", strerror(errno), optarg); |
1337 | showprogress = 0; | 1421 | showprogress = 0; |