source: trunk/third/openssh/sftp.c @ 18759

Revision 18759, 6.3 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2001,2002 Damien Miller.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "includes.h"
26
27RCSID("$OpenBSD: sftp.c,v 1.31 2002/07/25 01:16:59 mouring Exp $");
28
29/* XXX: short-form remote directory listings (like 'ls -C') */
30
31#include "buffer.h"
32#include "xmalloc.h"
33#include "log.h"
34#include "pathnames.h"
35#include "misc.h"
36
37#include "sftp.h"
38#include "sftp-common.h"
39#include "sftp-client.h"
40#include "sftp-int.h"
41
42#ifdef HAVE___PROGNAME
43extern char *__progname;
44#else
45char *__progname;
46#endif
47
48FILE* infile;
49size_t copy_buffer_len = 32768;
50size_t num_requests = 16;
51
52static void
53connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
54{
55        int c_in, c_out;
56
57#ifdef USE_PIPES
58        int pin[2], pout[2];
59
60        if ((pipe(pin) == -1) || (pipe(pout) == -1))
61                fatal("pipe: %s", strerror(errno));
62        *in = pin[0];
63        *out = pout[1];
64        c_in = pout[0];
65        c_out = pin[1];
66#else /* USE_PIPES */
67        int inout[2];
68
69        if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
70                fatal("socketpair: %s", strerror(errno));
71        *in = *out = inout[0];
72        c_in = c_out = inout[1];
73#endif /* USE_PIPES */
74
75        if ((*sshpid = fork()) == -1)
76                fatal("fork: %s", strerror(errno));
77        else if (*sshpid == 0) {
78                if ((dup2(c_in, STDIN_FILENO) == -1) ||
79                    (dup2(c_out, STDOUT_FILENO) == -1)) {
80                        fprintf(stderr, "dup2: %s\n", strerror(errno));
81                        exit(1);
82                }
83                close(*in);
84                close(*out);
85                close(c_in);
86                close(c_out);
87                execv(path, args);
88                fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
89                exit(1);
90        }
91
92        close(c_in);
93        close(c_out);
94}
95
96static void
97usage(void)
98{
99        extern char *__progname;
100
101        fprintf(stderr,
102            "usage: %s [-vC1] [-b batchfile] [-o option] [-s subsystem|path] [-B buffer_size]\n"
103            "            [-F config] [-P direct server path] [-S program]\n"
104            "            [user@]host[:file [file]]\n", __progname);
105        exit(1);
106}
107
108int
109main(int argc, char **argv)
110{
111        int in, out, ch;
112        pid_t sshpid;
113        char *host, *userhost, *cp, *file2;
114        int debug_level = 0, sshver = 2;
115        char *file1 = NULL, *sftp_server = NULL;
116        char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
117        LogLevel ll = SYSLOG_LEVEL_INFO;
118        arglist args;
119        extern int optind;
120        extern char *optarg;
121
122        __progname = get_progname(argv[0]);
123        args.list = NULL;
124        addargs(&args, "ssh");          /* overwritten with ssh_program */
125        addargs(&args, "-oForwardX11 no");
126        addargs(&args, "-oForwardAgent no");
127        addargs(&args, "-oClearAllForwardings yes");
128        ll = SYSLOG_LEVEL_INFO;
129        infile = stdin;         /* Read from STDIN unless changed by -b */
130
131        while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
132                switch (ch) {
133                case 'C':
134                        addargs(&args, "-C");
135                        break;
136                case 'v':
137                        if (debug_level < 3) {
138                                addargs(&args, "-v");
139                                ll = SYSLOG_LEVEL_DEBUG1 + debug_level;
140                        }
141                        debug_level++;
142                        break;
143                case 'F':
144                case 'o':
145                        addargs(&args, "-%c%s", ch, optarg);
146                        break;
147                case '1':
148                        sshver = 1;
149                        if (sftp_server == NULL)
150                                sftp_server = _PATH_SFTP_SERVER;
151                        break;
152                case 's':
153                        sftp_server = optarg;
154                        break;
155                case 'S':
156                        ssh_program = optarg;
157                        break;
158                case 'b':
159                        if (infile == stdin) {
160                                infile = fopen(optarg, "r");
161                                if (infile == NULL)
162                                        fatal("%s (%s).", strerror(errno), optarg);
163                        } else
164                                fatal("Filename already specified.");
165                        break;
166                case 'P':
167                        sftp_direct = optarg;
168                        break;
169                case 'B':
170                        copy_buffer_len = strtol(optarg, &cp, 10);
171                        if (copy_buffer_len == 0 || *cp != '\0')
172                                fatal("Invalid buffer size \"%s\"", optarg);
173                        break;
174                case 'R':
175                        num_requests = strtol(optarg, &cp, 10);
176                        if (num_requests == 0 || *cp != '\0')
177                                fatal("Invalid number of requests \"%s\"",
178                                    optarg);
179                        break;
180                case 'h':
181                default:
182                        usage();
183                }
184        }
185
186        log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
187
188        if (sftp_direct == NULL) {
189                if (optind == argc || argc > (optind + 2))
190                        usage();
191
192                userhost = xstrdup(argv[optind]);
193                file2 = argv[optind+1];
194
195                if ((cp = colon(userhost)) != NULL) {
196                        *cp++ = '\0';
197                        file1 = cp;
198                }
199
200                if ((host = strchr(userhost, '@')) == NULL)
201                        host = userhost;
202                else {
203                        *host++ = '\0';
204                        if (!userhost[0]) {
205                                fprintf(stderr, "Missing username\n");
206                                usage();
207                        }
208                        addargs(&args, "-l%s",userhost);
209                }
210
211                host = cleanhostname(host);
212                if (!*host) {
213                        fprintf(stderr, "Missing hostname\n");
214                        usage();
215                }
216
217                addargs(&args, "-oProtocol %d", sshver);
218
219                /* no subsystem if the server-spec contains a '/' */
220                if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
221                        addargs(&args, "-s");
222
223                addargs(&args, "%s", host);
224                addargs(&args, "%s", (sftp_server != NULL ?
225                    sftp_server : "sftp"));
226                args.list[0] = ssh_program;
227
228                fprintf(stderr, "Connecting to %s...\n", host);
229                connect_to_server(ssh_program, args.list, &in, &out,
230                    &sshpid);
231        } else {
232                args.list = NULL;
233                addargs(&args, "sftp-server");
234
235                fprintf(stderr, "Attaching to %s...\n", sftp_direct);
236                connect_to_server(sftp_direct, args.list, &in, &out,
237                    &sshpid);
238        }
239
240        interactive_loop(in, out, file1, file2);
241
242#if !defined(USE_PIPES)
243        shutdown(in, SHUT_RDWR);
244        shutdown(out, SHUT_RDWR);
245#endif
246
247        close(in);
248        close(out);
249        if (infile != stdin)
250                fclose(infile);
251
252        while (waitpid(sshpid, NULL, 0) == -1)
253                if (errno != EINTR)
254                        fatal("Couldn't wait for ssh process: %s",
255                            strerror(errno));
256
257        exit(0);
258}
Note: See TracBrowser for help on using the repository browser.